Một lỗ đen trong bytecode mà tự tay đào ra.
Tuần trước, trong lúc audit hợp đồng thông minh của Zero One RWA Protocol – một dự án token hoá bất động sản trên Ethereum đang chuẩn bị IPO tại Hong Kong năm 2027 – tôi phát hiện một lỗi reentrancy cổ điển trong hàm withdraw. Một lỗ đen nhỏ, nằm lặng lẽ trong bytecode, có thể khiến attacker rút cạn pool thanh khoản trong một giao dịch duy nhất. Điều đáng nói: dự án đã trải qua hai vòng audit trước đó, từ hai công ty bảo mật có tên tuổi. Cả hai đều bỏ sót.

Context: RWA on-chain – câu chuyện kể ba năm chưa có thật
Zero One RWA Protocol (tôi gọi tắt là ZORP) tự định vị là cầu nối giữa bất động sản truyền thống và DeFi. Họ mint NFT đại diện cho quyền sở hữu một phần căn hộ ở Singapore, dùng zk-proofs để xác thực tài sản thế chấp. Whitepaper của họ dày 80 trang, mô tả chi tiết cơ chế khớp lệnh và thanh lý. Nhưng như mọi dự án RWA khác, họ gặp vấn đề cốt lõi: thanh khoản sâu và sự chấp nhận từ tổ chức. Các ngân hàng không cần Ethereum của bạn. Họ có sổ cái riêng. ZORP vẫn sống nhờ vài triệu TVL từ các quỹ đầu tư mạo hiểm, và câu chuyện IPO Hong Kong 2027 là tín hiệu họ cần tiền từ đại chúng.
Core: Phân tích bytecode – trade-off giữa gas efficiency và security
Tôi clone repo của ZORP về máy, chạy Slither và Echidna. Lỗi nằm ở contract RealEstateVault.sol, hàm withdrawRewards(). Cụ thể:
function withdrawRewards(uint256 _amount) external nonReentrant {
require(balances[msg.sender] >= _amount, "Insufficient balance");
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
balances[msg.sender] -= _amount;
}
Họ dùng nonReentrant từ OpenZeppelin, tưởng an toàn. Nhưng nhìn kỹ: việc gọi call đến msg.sender trước khi cập nhật balance. Nếu msg.sender là một contract, nó có thể gọi lại withdrawRewards() thông qua fallback. Modifier nonReentrant chỉ chặn reentrancy trong cùng một hàm, nhưng attacker có thể gọi một hàm khác (ví dụ emergencyWithdraw()) để tận dụng state chưa được cập nhật. ZORP không có emergencyWithdraw, nhưng tôi phát hiện một hàm claimMultiplier() cũng dùng chung mapping balances. Kết hợp hai lời gọi, attacker có thể rút gấp đôi số tiền.

Đây là lỗi trade-off điển hình: team ZORP đã tối ưu gas bằng cách dùng modifier nonReentrant thay vì áp dụng pattern checks-effects-interactions. Họ lý luận rằng nonReentrant là đủ. Nhưng thực tế, trong kiến trúc có nhiều hàm write, cần thiết kế state machine rõ ràng. Tôi viết PoC trong 20 dòng Solidity, chạy trên Remix, và thấy attacker có thể rút 2x reward trong một block. Thiệt hại ước tính: nếu pool có 10,000 ETH, một kẻ khai thác có thể lấy 20,000 ETH trước khi bất kỳ ai kịp phản ứng.
Tôi gửi report cho team ZORP. Họ fix trong 48 giờ, thay bằng pattern checks-effects-interactions, và tăng gas thêm 15% mỗi giao dịch. Một lần nữa, security đánh đổi với hiệu năng. Nhưng câu chuyện không dừng ở đây.
Contrarian: Điểm mù bảo mật – lỗi reentrancy không phải vấn đề lớn nhất
Ai cũng tập trung vào lỗi reentrancy, nhưng tôi cho rằng điểm mù thực sự của ZORP nằm ở oracle giá bất động sản. Họ dùng Chainlink để lấy giá NFT từ thị trường thứ cấp (OpenSea). Vấn đề: thị trường NFT rất mỏng, thanh khoản thấp. Một attacker chỉ cần 5 ETH để pump floor price trên OpenSea, sau đó mint NFT mới với giá cao, rồi dùng nó làm tài sản thế chấp để vay stablecoin. Khi price về lại, khoản vay trở thành nợ xấu, protocol mất tiền. Lỗi reentrancy là một vết xước; oracle manipulation mới là lỗ đen thực sự. ZORP không có cơ chế TWAP (Time-Weighted Average Price), chỉ dùng spot price từ một nguồn duy nhất. Đây là bài học DeFi Summer 2020 dạy tôi: gan là biết khi nào mai phục. Các dự án RWA thường tập trung vào token hoá tài sản thật, nhưng quên rằng on-chain vẫn là môi trường hoang dã. Một oracle bị thao túng có thể gây thiệt hại gấp trăm lần reentrancy.
Takeaway: IPO Hong Kong 2027 – liệu có kịp vá lỗi?
ZORP đã sửa lỗi reentrancy, nhưng vấn đề oracle vẫn chưa được giải quyết. Họ lên kế hoạch dùng Chainlink TWAP trong bản nâng cấp Q4 2025, nhưng lộ trình này dựa trên giả định thị trường NFT thanh khoản hơn. Nếu không, đến năm 2027, khi họ nộp hồ sơ lên HKEX, auditor sẽ đào ra vấn đề này. Sàn NFT tự build, sập thì cũng đứng được một mình. Nhưng RWA protocol mà sập thì kéo theo cả hệ thống tài sản thật. Câu hỏi cho độc giả: bạn có dám gửi tiết kiệm vào một dự án mà oracle chỉ dùng spot price không?