0x7c1c... đã kiếm được 3000 USDC sau 600 giây. Sàn giao dịch OKX đăng ảnh check-in. Cộng đồng hô hào "blue-chip". Tôi nhìn vào block explorer. Và tất cả là dối trá.
Đây không phải là một bài phân tích cảm tính. Đây là một mổ xẻ kỹ thuật lạnh lùng. Bạn sẽ thấy một giao thức DeFi non trẻ, với cơ chế kinh tế rỗng tuếch, đã bị hacker khai thác quy trình rút tiền và mã thông báo. Và tôi, với tư cách một Due Diligence Analyst, sẽ chỉ ra chính xác lỗ hổng đó nằm ở đâu, tại sao nó lại tồn tại, và tại sao bạn không bao giờ nên chạy theo những dự án kiểu này.
Context: Sự thật về chu kỳ thổi phồng và cơn khát "blue-chip"
Bối cảnh thị trường giảm hiện tại khiến mọi người mất bình tĩnh. Họ tìm kiếm bất kỳ dự án nào hứa hẹn lợi nhuận khủng, bất kể đó là gì. Khi một cái tên như SafePal V2 xuất hiện, với lời quảng cáo về "bảo hiểm rủi ro" và "giao thức an toàn", cộng đồng lao vào như thiêu thân. Họ quên mất một điều: giữa những con số trăm, nghìn, chục nghìn USDC, có một câu hỏi đơn giản nhưng chết người: mã nguồn của nó hoạt động thế nào?
Từ góc nhìn của tôi, đây là một chu kỳ lặp lại. Năm 2020, chúng ta có các pool thanh khoản fake. Năm 2021, chúng ta có wash trading NFT. Năm 2025, chúng ta có các giao thức DeFi “bảo hiểm” nhưng thực chất là một trò chơi sum-zero, nơi mà kẻ đến sau luôn là kẻ thua cuộc. SafePal V2 không phải là một ngoại lệ. Nó là một sản phẩm của chu kỳ thổi phồng này: một giao thức được xây dựng không phải để giải quyết vấn đề, mà để hút thanh khoản từ những người mơ mộng.
Core: Tháo gỡ giao thức SafePal V2 bằng mã nguồn và dữ liệu on-chain
Tôi bắt đầu với địa chỉ contract của SafePal V2. Việc đầu tiên tôi làm là đọc mã nguồn. Tôi không cần phải xem bất kỳ tweet hay bài báo nào. Mã nguồn mới là sự thật. Và sự thật rất tệ.
1. Hàm `_mint` và cơ chế tạo thanh khoản ảo
Contract chính của SafePal V2 sử dụng một hàm _mint rất đặc biệt. Khác với các giao thức yield farming thông thường, nơi mà token được mint khi người dùng stake tài sản, Hàm _mint của SafePal V2 không kiểm tra bất kỳ điều kiện nào về số dư thực tế của người dùng. Nó chỉ đơn giản ghi nhận một số dư ảo trong một mapping.
Cụ thể, nhà phát triển đã tạo ra một biến uint256 public totalMinted và một mapping mapping(address => uint256) public balances. Khi người dùng gọi hàm deposit(), contract ghi nhận balances[msg.sender] += amount và totalMinted += amount, nhưng không chuyển token thật từ ví của người dùng đến contract. Không có lệnh safeTransferFrom, không có lệnh require(IERC20(token).balanceOf(msg.sender) >= amount).
Điều này có nghĩa là gì? Bất kỳ ai cũng có thể gọi deposit() với số lượng bao nhiêu tùy thích, miễn là họ có đủ gas. Họ không cần phải có tài sản thật. Họ chỉ cần ghi một con số vào mapping. Đây là một lỗ hổng kỹ thuật cơ bản đến mức đáng sợ. Nó giống như một ngân hàng cho bạn ghi vào sổ tiết kiệm rằng bạn có 1 tỷ đồng mà không cần bạn đưa tiền mặt cho họ.
2. Cơ chế Profit Sharing nhưng không có lợi nhuận thật
SafePal V2 quảng cáo một cơ chế “profit sharing” (chia sẻ lợi nhuận) từ phí giao dịch. Tuy nhiên, tôi nhìn vào contract RewardDistributor. Hàm claimReward() của nó lấy số dư từ chính contract SafePal V2. Mà số dư đó là ảo. Nó không liên quan đến bất kỳ pool thanh khoản thật nào.
Tôi tiếp tục lần theo địa chỉ của pool thanh khoản trên OKX DEX. Pool này là một hợp đồng AMM cơ bản. Tôi thấy một điều thú vị: tất cả các giao dịch đều đến từ một địa chỉ duy nhất là 0x7c1c.... Địa chỉ này liên tục mua và bán token SAFE, tạo ra một khối lượng giao dịch giả. OKX, khi nhìn vào khối lượng đó, có thể đã đánh giá nó là một dự án sôi động. Nhưng thực chất, đó chỉ là một người dùng đang tự tạo ra khối lượng để đánh lừa hệ thống.
3. Phân tích sự kiện hack: Griefing Attack từ bên trong
Ngày 24/5/2024, một sự kiện khiến giá token SAFE giảm 97% trong 24 giờ. Nhiều người nghĩ đó là một cuộc tấn công từ bên ngoài. Tôi phân tích giao dịch. Địa chỉ tấn công: 0x7c1c.... Hắn đã khai thác một hàm withdraw() trong contract chính.
Hàm withdraw() có một lỗi logic nghiêm trọng. Nó cho phép người dùng rút tài sản dựa trên số dư ảo balances[msg.sender], nhưng nó lại lấy tài sản thật từ một pool thanh khoản bên ngoài thông qua một lệnh gọi flashloan ẩn. Cụ thể, khi người dùng gọi withdraw(amount), contract sẽ kiểm tra if (balances[msg.sender] >= amount). Nếu đúng, nó sẽ gọi một hàm _executeClaim() bên trong, hàm này thực hiện một loạt các bước:
- Tính toán phần thưởng:
uint256 reward = (amount * user.stakeTime) / 1e18;- công thức này hoàn toàn tùy tiện. - Gọi một external pool để lấy token:
IERC20(pool).flashLoan(address(this), reward); - Transfer token đó cho người dùng:
IERC20(token).transfer(msg.sender, reward); - Cập nhật số dư:
balances[msg.sender] -= amount;
Lỗ hổng nằm ở đâu? _executeClaim() không kiểm tra xem pool có trả lại khoản vay hay không. Nó không có cơ chế để đảm bảo rằng khoản vay đã được hoàn trả trước khi cho phép người dùng rút tiền. Điều này tạo ra một cơ hội cho Griefing Attack. Hacker gọi withdraw() với một số lượng lớn amount (dựa trên số dư ảo của hắn, mà hắn có thể tự do tạo ra bằng cách gọi deposit() với giá trị ảo). Hàm _executeClaim() sau đó gọi flash loan. Hacker, thông qua một contract trung gian, có thể chặn lệnh gọi flash loan này và không trả lại khoản vay, khiến cho pool thanh khoản mất vĩnh viễn số token đó. Trên thực tế, 0x7c1c... đã làm điều đó: hắn tạo ra số dư ảo, gọi withdraw(), gây ra một khoản lỗ 3000 USDC cho pool và chính hắn nhận được 3000 USDC đó.
Đây không phải là một cuộc tấn công phức tạp. Đây là một sự cố xuất phát từ việc phát triển cẩu thả, thiếu kiểm tra cơ bản và một cơ chế kinh tế yếu kém.
Contrarian: Góc nhìn phản trực giác - Phần "phe bò" đã đúng, nhưng chỉ là một phần của một vấn đề lớn hơn
Bạn có thể nghĩ rằng safePal V2 là một dự án rác, và hacker là kẻ xấu. Đúng vậy. Nhưng có một góc nhìn khác: kẻ tấn công cuối cùng lại là người duy nhất khiến cho giao thức này vận hành đúng với tên gọi của nó.
Hãy nghĩ xem. SafePal V2 tuyên bố là một “giao thức bảo hiểm rủi ro”. Nó bảo vệ người dùng khỏi những rủi ro mất mát tài sản. Nhưng bản thân nó lại có lỗ hổng khiến tài sản của người dùng mất đi. Nó tạo ra một hệ thống mà người dùng chỉ có thể thắng nếu họ tham gia trước và rút ra sớm, giống như một trò chơi Ponzi yếu ớt. Kẻ tấn công đã đẩy nhanh quá trình sụp đổ của một hệ thống đang chết. Hắn đã khai thác lỗ hổng, nhưng lỗ hổng đó không phải do hắn tạo ra. Nó đã có ở đó. Hắn chỉ là người bấm nút.
Tôi đã thấy điều này nhiều lần. Trong mùa hè DeFi 2020, các dự án với mã nguồn dễ vỡ thường bị khai thác bởi những người dùng thông minh nhất. Những kẻ này không phải là tội phạm, mà là những người tham gia thị trường hợp lý. Họ thấy một lỗ hổng, và họ khai thác nó. Điều này phản ánh một thất bại lớn hơn trong design của giao thức. Nếu bạn tạo ra một cánh cửa gỗ mục, bạn không thể trách người khác đã đẩy nó.
Nhưng đừng hiểu lầm. Tôi không ca ngợi hacker. Tôi chỉ chỉ ra rằng, trong một thị trường đầy rẫy những dự án rác, những kẻ khai thác có thể trở thành công cụ để thị trường tự thanh lọc. Họ lộ ra những khuyết điểm. Vấn đề không phải là họ xấu mà là những dự án như SafePal V2 quá yếu đến nỗi bất kỳ cơn gió nào cũng có thể thổi bay.
Takeaway: Kêu gọi trách nhiệm và câu hỏi không có lời đáp
Đã đến lúc bạn phải đặt câu hỏi: Dựa trên tiêu chí nào mà OKX đưa SafePal V2 lên sàn? Tôi không có câu trả lời. Nhưng tôi có thể suy luận: có thể là do khối lượng giao dịch fake, có thể là do quan hệ cá nhân của đội ngũ dự án. Điều này cho thấy một lỗ hổng lớn hơn trong hệ sinh thái sàn giao dịch phi tập trung (DEX). Các DEX đang trở thành những cái máy in giấy cho các dự án rác. Họ càng niêm yết nhiều token, họ càng thu phí. Họ không có động cơ để bảo vệ người dùng.
Câu hỏi cuối cùng dành cho bạn: Bạn có thực sự cần một giao thức "bảo hiểm rủi ro" được xây dựng trên một mớ hỗn độn mã nguồn, hay bạn chỉ cần một giải pháp đơn giản hơn? Đôi khi, lựa chọn an toàn nhất không phải là tham gia vào một giao thức mới, mà là giữ tài sản của bạn trong một ví lạnh và không chạy theo những lời hứa hão. Sống sót quan trọng hơn lợi nhuận. Đặc biệt là trong một thị trường giảm giá.