Hook
20 ETH. Không phải số tiền lớn với quỹ đầu tư, nhưng với một kỹ sư risk management ở tuổi 37, đó là bài học đắt giá nhất. Tôi vẫn nhớ cái cảm giác cay đắng khi nhìn token YAM sụp đổ sau 36 giờ. Nhưng câu chuyện hôm nay không phải về YAM. Mà về một dự án DeFi Việt Nam tên là 'LendingFi' – vừa huy động 500 ETH trong private sale. Tôi tình cờ xem qua hợp đồng thông minh của họ. Và tôi thấy một backdoor. Một cái backdoor còn lộ liễu hơn cả BlockVault năm 2017.
Backdoor không bao giờ là lỗi, là chủ ý.
Context
LendingFi là một giao thức cho vay phi tập trung, hứa hẹn lãi suất ổn định 18% APR cho người gửi token. Họ có website đẹp, roadmap chi tiết, và đội ngũ gồm ba người từng làm ở các công ty blockchain có tiếng. Private sale diễn ra suôn sẻ, với sự tham gia của một số quỹ đầu tư nhỏ tại Việt Nam. Tuy nhiên, khi tôi đọc code (đã được 'audit' bởi một công ty kiểm toán không tên tuổi), tôi nhận ra ngay vấn đề.
Hợp đồng chính là LendingPool.sol, viết bằng Solidity 0.8.9. Có một hàm lạ: emergencyWithdraw(address token, uint amount) với modifier onlyOwner. Nhưng point mấu chốt là owner không phải là một multisig hay contract mà là một EOA (Externally Owned Account) – một ví riêng. Hàm này có thể rút bất kỳ token nào trong pool mà không cần kiểm tra số dư hay lịch sử vay. Về mặt kỹ thuật, 'emergency' thường dùng để thu hồi token lỗi, nhưng ở đây không có cơ chế freeze hoặc pause. Đơn giản là một cánh cửa mở.
Core: Mổ xẻ kỹ thuật
Tôi dành ba ngày cuối tuần để phân tích từng dòng mã. Dưới đây là những phát hiện chính: