Mỗi dòng code đều có một lỗ hổng: Vụ án 'Nghị sĩ Iran' trong thế giới DeFi

Trương Cường Tài chính

Một dự án lending vừa gọi vốn 100 triệu USD — và tôi phát hiện ra nó chứa một backdoor được thiết kế tinh vi. Không phải lỗi kỹ thuật, mà là một 'cánh cửa sau' có chủ đích, ẩn trong hàm setApprovalForAll. Nếu bạn nghĩ đây chỉ là một lỗi lập trình, hãy nghĩ lại. Mỗi dòng code đều có một lỗ hổng, và lỗ hổng này là một vũ khí chính trị.

Mỗi dòng code đều có một lỗ hổng: Vụ án 'Nghị sĩ Iran' trong thế giới DeFi

Bối cảnh: thị trường đang trong chu kỳ tăng, FOMO lan tràn. Dự án 'LendIran' (tên giả định) tự hào là giao thức cho vay phi tập trung đầu tiên có tích hợp 'quản trị nghị viện' — nơi token holder bỏ phiếu cho các admin. Họ huy động 100 triệu USD từ các quỹ đầu tư mạo hiểm, hứa hẹn lợi nhuận 20% APR. Nhưng khi tôi mổ xẻ mã nguồn trên GitHub, tôi thấy một pattern quen thuộc: hàm setApprovalForAll được gọi từ một contract admin không có bất kỳ kiểm tra quyền nào. —lỗ hổng mà chỉ người đào sâu mới thấy.

Mỗi dòng code đều có một lỗ hổng: Vụ án 'Nghị sĩ Iran' trong thế giới DeFi

Phân tích kỹ thuật: Hợp đồng chính LendIranPool.sol có hàm setApprovalForAll(address spender, bool approved) public, nhưng không có modifier onlyOwner hay onlyAdmin. Trong thực tế, bất kỳ ai cũng có thể gọi hàm này và set approval cho chính mình? Không, vì có một mapping isAdmin kiểm tra. Nhưng mapping này được khởi tạo trong constructor với một địa chỉ admin duy nhất. Vấn đề: admin có thể thay đổi mapping này thông qua một hàm updateAdmin không được public, nhưng lại có một backdoor: nếu msg.sender == address(this), thì ai cũng có thể gọi. Điều này cho phép admin (hoặc bất kỳ ai chiếm được private key của admin) rút toàn bộ token của người dùng mà không cần approval riêng lẻ. Dựa trên kinh nghiệm audit của tôi với Uniswap v2, tôi từng phát hiện lỗi tương tự trong logic tính phí — nhưng ở đây, nó có chủ đích. Dòng code require(isAdmin[msg.sender] || msg.sender == address(this), 'Not authorized'); là một cạm bẫy. Nếu admin contract bị tấn công, hoặc admin cố tình lạm dụng, toàn bộ thanh khoản sẽ biến mất.

Mỗi dòng code đều có một lỗ hổng: Vụ án 'Nghị sĩ Iran' trong thế giới DeFi

Góc nhìn phản trực giác: Phe bò đúng rằng admin cần quyền này để migrate liquidity trong trường hợp khẩn cấp. Nhưng không có cơ chế rút lui an toàn, không có timelock, không có multi-sig. Đây là backdoor thuần túy. Tôi gọi đây là 'Nghị sĩ Iran' — giống như một nghị sĩ Iran cầm súng bắn vào người biểu tình, admin của LendIran cầm quyền setApprovalForAll bắn vào tài sản của người dùng. Cả hai đều là hành vi vượt quá thẩm quyền được cho phép, và đều được biện minh bằng 'bảo vệ hệ thống'. Nhưng sự thật: đó là sự độc tài được mã hóa.

Takeaway: Mỗi dòng code đều có một lỗ hổng, và lỗ hổng này là một vũ khí chính trị. Đừng để FOMO làm mờ mắt. Hãy yêu cầu audit từ bên thứ ba, hãy kiểm tra hàm setApprovalForAll trong bất kỳ dự án nào bạn đầu tư. Nếu họ từ chối, hãy rút tiền ngay. —lỗ hổng mà chỉ người đào sâu mới thấy.