Tuần trước, tôi kiểm tra hợp đồng thông minh của một lending protocol mới trên Arbitrum. Họ vừa gọi vốn 50 triệu USD từ các quỹ lớn. TVL đã chạm 200 triệu USD sau ba ngày. Tôi mở hàm withdraw ra, đọc dòng thứ 47: require(balances[msg.sender] >= amount); - OK. Dòng 48: balances[msg.sender] -= amount; - OK. Dòng 49: (bool success, ) = msg.sender.call{value: amount}(""); - đây rồi. Họ để external call trước cập nhật trạng thái. Một lỗi reentrancy cổ điển từ năm 2017, giống hệt lỗi tôi từng phát hiện trong ICO Hà Nội. Chỉ khác là bây giờ số tiền lớn hơn 500 ETH nhiều lần.
Bối cảnh thị trường hiện tại đang tăng nóng. Mỗi ngày có 5-10 dự án mới ra mắt, tất cả đều chạy đua thời gian. Áp lực từ VC và cộng đồng FOMO khiến các team bỏ qua audit kỹ thuật. Họ dùng template OpenZeppelin, sửa vài tham số rồi deploy. Nhưng template chỉ an toàn nếu bạn hiểu cách dùng. Lending protocol này lấy code gốc từ Compound, thêm tính năng flash loan và cross-chain bridge. Trong quá trình merge, họ vô tình đặt hàm withdraw sai thứ tự. Tôi đã thấy điều này ít nhất năm lần trong sự nghiệp.
Cơ chế của lỗi rất đơn giản: Khi người dùng gọi withdraw, hợp đồng gửi ETH trước khi cập nhật số dư. Kẻ tấn công có thể triển khai một hợp đồng tấn công với fallback function gọi lại withdraw. Vì balances chưa giảm, họ có thể rút nhiều lần. Gas cost cho mỗi lần gọi chỉ khoảng 45.000 gas, thấp hơn 20% so với swap Uniswap v2. Tôi đã thử nghiệm trên testnet Goerli với 10 ETH ảo: chỉ cần 3 cuộc gọi lồng nhau là rút hết pool. Chi phí gas tổng cộng dưới 200.000 gas, tương đương 0.006 ETH ở mức gas price 30 gwei. Rẻ hơn một ly cà phê.
Điều trớ trêu là team đã khoe trên Twitter rằng họ sử dụng ReentrancyGuard của OpenZeppelin. Tôi kiểm tra: họ import đúng contract ReentrancyGuard, nhưng quên áp dụng modifier nonReentrant vào hàm withdraw. Một lỗi ngớ ngẩn, nhưng lặp đi lặp lại. Hồi 2021, tôi từng viết bài phân tích batch minting cho NFT, và chỉ ra rằng 30% dự án mới có lỗi tương tự. Bây giờ tỷ lệ ấy vẫn không đổi. Thị trường tăng tạo ra ảo tưởng rằng code an toàn, nhưng thực tế: càng vội vàng, càng nhiều lỗ hổng.
Nhiều người nghĩ reentrancy đã là chuyện cũ, bị khắc phục từ lâu. Nhưng góc nhìn phản trực giác: Chính vì ai cũng nghĩ vậy, nên các dự án mới không kiểm tra kỹ. Họ dựa vào thư viện tiêu chuẩn, tin rằng nó tự động bảo vệ. Tôi gọi đây là 'bẫy niềm tin mù quáng'. Thực tế, khi tôi fork Uniswap v2 năm 2020, tôi cũng mắc lỗi tương tự: tôi dùng safeTransfer nhưng quên kiểm tra return value. Chỉ khi deploy testnet và chạy edge case tôi mới phát hiện. Vấn đề không phải công cụ, mà là quy trình.
Điểm mù thứ hai: Các nhà đầu tư VC thường không đọc code. Họ dựa vào audit bên thứ ba. Nhưng audit cũng có hạn chế: thời gian ngắn, phạm vi hẹp, và thường bỏ qua các tương tác cross-chain. Lending protocol này có bridge kết nối với Ethereum mainnet. Tôi phát hiện thêm một lỗ hổng trong contract bridge: hàm receive không kiểm tra nguồn gốc message. Kẻ tấn công có thể giả mạo tin nhắn từ chain khác để mint token giả. Đây là kịch bản phức tạp hơn, nhưng nếu kết hợp với reentrancy, hậu quả có thể lên đến 10 triệu USD. Dựa trên kinh nghiệm audit của tôi, 80% lỗ hổng nghiêm trọng đến từ sự kết hợp giữa các module, không phải từ module đơn lẻ.
Tôi đã báo cáo lỗi cho team qua Discord. Họ phản hồi sau 6 giờ, nói 'đã ghi nhận'. Hai ngày sau, họ deploy bản vá. Nhưng TVL đã giảm 30%. Người dùng rút tiền vì mất niềm tin. Thiệt hại không chỉ là số tiền có thể mất, mà còn là uy tín. Trong thị trường tăng, một ngày delay có thể mất hàng triệu USD cơ hội.
Bài học rõ ràng: Cơn sốt thị trường che giấu lỗi kỹ thuật, nhưng chúng vẫn tồn tại. Là người dùng, bạn nên kiểm tra mã nguồn trước khi deposit. Nếu không đọc được code, ít nhất hãy xem họ có audit công khai không, và audit đó có bao gồm kiểm tra reentrancy không. Còn các team: đừng để deadline giết chết sản phẩm của bạn. Một ngày test thêm có thể cứu bạn khỏi thảm họa.
Khi tôi viết những dòng này, thị trường vẫn đang tăng. Bitcoin chạm 100.000 USD, altcoin bay cao. Nhưng tôi nhìn thấy một làn sóng hack sắp tới. Lịch sử lặp lại: 2017, 2021, và bây giờ là 2025. Mỗi chu kỳ đều có những dự án triệu đô sụp đổ vì lỗi code cơ bản. Bạn có chắc dự án mình đầu tư đã được kiểm tra kỹ? Hay bạn chỉ đang dựa vào niềm tin?