Một dòng lệnh call không kiểm soát trạng thái. Một mô hình thanh khoản tưởng chừng hoàn hảo. Và một kẻ tấn công đã rút 2.000 ETH từ pool thanh khoản của dự án DeFi Việt Nam chỉ trong ba block. Tôi đã đọc mã nguồn của dự án X – một AMM được quảng bá rầm rộ trong cộng đồng Crypto Việt suốt quý II/2024 – và phát hiện một lỗ hổng reentrancy cổ điển, nhưng được che giấu bởi lớp marketing dày đặc về “tính bảo mật hàng đầu”. Đây không phải là một vụ hack mới. Đây là sự tái diễn của The DAO 2016, nhưng trong bối cảnh thị trường tăng 2025, nơi FOMO khiến mọi người quên kiểm tra code gốc.
Bối cảnh: Dự án X ra mắt vào tháng 3/2025, huy động 50 triệu USD từ các quỹ đầu tư trong nước và quốc tế. Họ tự hào về cơ chế “liquidity bootstrapping” độc quyền, cho phép người dùng cung cấp thanh khoản đơn biên và nhận phí giao dịch siêu cao. Tôi bắt đầu audit vào ngày thứ hai sau khi hợp đồng được deploy, vì một điều bất thường: whitepaper không có link đến mã nguồn trên Etherscan. Một red flag. Khi tôi yêu cầu, đội ngũ đưa ra một repo GitHub với hàng nghìn dòng code, nhưng thiếu comment và test coverage. Trong ba ngày đọc, tôi tìm thấy lỗ hổng trong hàm swap – nơi _updateBalances được gọi sau khi gửi token, thay vì trước. Điều này tạo ra reentrancy lock cơ bản, cho phép kẻ tấn công gọi lại hàm swap trước khi trạng thái pool được cập nhật.
Phân tích kỹ thuật: Hãy nhìn vào đoạn mã giả từ hợp đồng của họ. Hàm swap nhận đầu vào amountIn và tokenIn, sau đó thực hiện:
IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);uint256 amountOut = getAmountOut(amountIn, reserveIn, reserveOut);IERC20(tokenOut).safeTransfer(msg.sender, amountOut);_updateBalances();
Lỗi nằm ở bước 3: safeTransfer gọi callback của token nhận (nếu token là ERC777 hoặc có hook), cho phép kẻ tấn công gọi lại swap trong cùng một giao dịch. Khi đó, reserveIn và reserveOut chưa được cập nhật, dẫn đến getAmountOut tính toán dựa trên dữ liệu cũ. Kẻ tấn công có thể rút nhiều token hơn so với dự kiến, tới mức cạn kiệt pool. Tôi đã mô phỏng kịch bản này trong môi trường Hardhat: với 100 ETH ban đầu, kẻ tấn công chỉ cần 1 ETH để gọi 10 lần đệ quy, rút tổng cộng 85 ETH. Một con số khổng lồ. Điểm mù ở đây là giả định rằng token không có callback, nhưng thực tế nhiều token ERC20 trong hệ sinh thái Việt Nam (như VNDC, USDT trên BSC) có hành vi không chuẩn, dễ bị khai thác.
Góc nhìn phản trực giác: Cộng đồng thường nghĩ rằng audit từ các công ty lớn như CertiK là đủ. Nhưng trong trường hợp này, dự án X đã trả 200.000 USD cho một audit, nhưng báo cáo chỉ kiểm tra 70% code coverage, bỏ qua các hàm callback. Tôi cho rằng các audit truyền thống thất bại vì họ kiểm tra theo checklist, không theo tư duy kẻ tấn công. Một hacker giỏi không cần tìm lỗi mới; họ chỉ cần áp dụng lại các pattern cũ trong bối cảnh mới. Thị trường tăng 2025 càng làm trầm trọng vấn đề: các dự án vội vã ra mắt, bỏ qua kiểm tra entropy trong random number generation, bỏ qua reentrancy guard, và dựa vào “audit” như một tấm khiên giấy. Kinh nghiệm của tôi từ năm 2017 cho thấy, chỉ có đọc từng dòng code mới phát hiện được lỗi. Một lớp bảo vệ duy nhất: luôn kiểm tra thứ tự cập nhật trạng thái.

Takeaway: Dự án X hiện đã đóng băng pool và hứa bồi thường, nhưng niềm tin đã mất. Câu hỏi đặt ra: Liệu cộng đồng Việt Nam có học được bài học này, hay chúng ta sẽ chứng kiến một vụ hack tương tự trong quý tiếp theo? Khi tôi đọc hợp đồng của dự án Y – một lending protocol mới – tôi thấy cùng một pattern: transfer trước, cập nhật sau. Thị trường tăng che giấu mọi thứ, nhưng entropy không bao giờ ngừng tăng. Tôi sẽ tiếp tục audit, và bạn, nếu đang FOMO, hãy tự hỏi: bạn đã đọc code chưa?