Tôi vừa kết thúc một cuộc audit. Dự án là một giao thức cho vay mới trên Layer2, TVL chưa tới 10 triệu USD, nhưng cấu trúc mã nguồn khiến tôi nhớ ngay đến năm 2017. Một lỗ hổng re-entrancy trong hàm withdraw – giống hệt TokenHub, nhưng được ngụy trang tinh vi hơn. Điều đáng nói: đội ngũ phát triển đã khoe trên Twitter rằng họ 'kế thừa code từ Aave', một trong những giao thức được audit nhiều nhất. Nhưng họ quên rằng mỗi mô hình mới đều mang theo vết nứt từ quá khứ.
Bối cảnh: giao thức này sử dụng pool thanh khoản đơn giản, cho phép người dùng gửi tài sản và vay với lãi suất thay đổi. Hợp đồng thông minh được fork từ phiên bản cũ của Compound, nhưng đội ngũ đã thêm một lớp tối ưu hoá gas: thay vì cập nhật số dư ngay trong hàm withdraw, họ ghi nợ vào một mảng tạm và chỉ cập nhật cuối cùng. Đây là một pattern phổ biến trong các bản fork không hiểu rõ rủi ro.
Phân tích cốt lõi: khi tôi đọc dòng call.value(amount) trong vòng lặp, tôi dừng lại. Trong code gốc của Compound, có một modifier nonReentrant. Nhưng trong bản fork này, modifier đó bị bỏ qua vì 'tiết kiệm gas'. Hậu quả: một kẻ tấn công có thể gọi hàm withdraw nhiều lần trước khi số dư được cập nhật, rút toàn bộ pool. Tôi ước tính thiệt hại tiềm năng ít nhất 2 triệu USD với TVL hiện tại. Điều trớ trêu: đội ngũ đã tự hào về 'tối ưu hoá gas', nhưng chính điều đó tạo ra lỗ hổng.
Góc nhìn phản trực giác: cộng đồng thường nghĩ fork từ các giao thức lớn là an toàn. Nhưng thực tế, các bản fork thường loại bỏ những cơ chế bảo vệ mà họ cho là 'thừa'. Tôi gọi đây là hội chứng kế thừa mù quáng. Trong DeFi, mỗi dòng code thừa thường là kết quả của một lỗ hổng trong quá khứ. Bỏ nó đi giống như tháo phanh xe hơi vì 'không cần thiết'.
Kết luận: tôi tin rằng trong 6 tháng tới, chúng ta sẽ chứng kiến ít nhất ba vụ khai thác tương tự trên các bản fork của Aave và Compound. Không phải vì code gốc có lỗi, mà vì sự thiếu hiểu biết về lịch sử bảo mật. Từ DeFi sang NFT, bản chất rủi ro vẫn không đổi. Bạn có muốn trở thành nạn nhân tiếp theo không?