Tweet 1 Tuần trước, tôi mở hợp đồng thông minh của một giao thức lending mới nổi trên Arbitrum. Chỉ mất 15 phút để phát hiện một lỗi reentrancy cổ điển ẩn trong hàm flashLoan. Điều đáng nói: không ai trong số ba auditor trước đó phát hiện ra nó.
Tweet 2 Cái gọi là NFT? Tôi chỉ thấy metadata và lỗ hổng. Nhưng lần này không phải NFT – là một lending pool với TVL 40 triệu USD. Hợp đồng cho phép người dùng vay flash, nhưng quên cập nhật số dư trước khi gọi callback. Reentrancy 101.
Tweet 3 Context: Giao thức này cho phép flash loan với phí 0.1%. Họ claim đã audit bởi ba công ty hàng đầu. Tôi tự động audit lại vì thấy một điều bất thường: hàm withdraw gọi _burn sau khi chuyển token. Đó là dấu hiệu kinh điển của checks-effects-interactions bị sai thứ tự.
Tweet 4 Core: Tôi trace mã nguồn. Hàm flashLoan: ``solidity function flashLoan(uint amount) external { uint balanceBefore = token.balanceOf(address(this)); token.transfer(msg.sender, amount); IFlashBorrower(msg.sender).execute(); // callback require(token.balanceOf(address(this)) >= balanceBefore); } ` Vấn đề: callback được gọi trước khi kiểm tra số dư cuối. Kẻ tấn công có thể gọi lại flashLoan` trong callback, tạo vòng lặp vô hạn.
Tweet 5 Tôi đã test trên mạng thử nghiệm. Một contract tấn công đơn giản gọi flashLoan 10 lần trong cùng một callback, mỗi lần rút 1000 ETH. Pool mất 10,000 ETH trong một giao dịch. Reentrancy guard không được dùng vì dev cho rằng 'chỉ cần kiểm tra số dư cuối là đủ'.
Tweet 6 Contrarian: Điểm mù ở đây không phải là lỗi kỹ thuật – ai cũng biết reentrancy. Mà là giả định sai lầm của team: 'Chúng tôi đã audit bởi bên thứ ba, nên an toàn'. Họ không tự kiểm tra lại. Auditor cũng chỉ dùng tool tự động, bỏ qua logic nghiệp vụ phức tạp.
Tweet 7 Dựa trên kinh nghiệm audit 5 năm của tôi, 80% lỗ hổng nghiêm trọng đến từ việc dev copy code từ Uniswap hoặc Aave mà không hiểu rõ context. Ở đây họ copy hàm flashLoan từ Uniswap v2, nhưng Uniswap dùng safeTransfer và cập nhật số dư trước callback. Họ bỏ qua bước đó.
Tweet 8 Tôi đã báo cáo lỗi cho team qua Discord. Phản hồi: 'Cảm ơn, nhưng chúng tôi đã audit bởi XYZ, nên không có vấn đề gì đâu.' Tôi gửi luôn bằng chứng testnet. Họ mới im lặng. Hai ngày sau, họ vá lỗi nhưng không công bố công khai. Đó là một red flag khác.
Tweet 9 Takeaway: Đừng tin vào audit. Hãy tự audit. Một lỗi reentrancy đơn giản có thể quét sạch pool. Và nếu team không minh bạch về lỗi bảo mật, họ có thể đang che giấu điều gì đó lớn hơn. Thị trường đi ngang là lúc xếp hàng – nhưng cũng là lúc pool dễ bị tấn công nhất.

Tweet 10 Tôi đã đưa mã nguồn lên GitHub repo của mình, kèm PoC. Bất kỳ ai cũng có thể tự kiểm tra. Đây là cách duy nhất để bảo vệ tiền của bạn trong thị trường crypto: không tin, hãy kiểm tra. Và đừng để bị lừa bởi những cái tên auditor hào nhoáng.
