Ngày 3 tháng 8 năm 2024, thị trường crypto ghi nhận đợt thanh lý hơn 1,5 tỷ USD chỉ trong 24 giờ. Một con số ấn tượng, nhưng nó không phải là tin tức. Tin tức thực sự nằm ở chỗ: không ai thấy nó đến, và cũng không ai hiểu tại sao nó lại xảy ra theo cách này.
Tôi đã dành 3 ngày qua để đọc từng dòng mã của các giao thức lending chính — Aave, Compound, và một số giao thức mới hơn như Morpho Blue. Kết quả? Một bức tranh tối tăm về sự phụ thuộc vào cấu trúc thanh lý mà tôi gọi là 'lời nguyền của người đi sau'. Đây không phải là một đợt thanh lý bình thường. Đây là một vụ giết người có hệ thống được thực hiện bởi chính cấu trúc code.
Context: Cơ chế thanh lý và sự bất cân xứng thông tin
Hầu hết mọi người nghĩ thanh lý là một quá trình đơn giản: giá giảm, collateral giảm, vị thế bị thanh lý. Nhưng thực tế, nó là một trò chơi thông tin bất cân xứng giữa:
- Người dùng retail: Họ chỉ thấy giá và TVL, không thấy các vị thế lớn đang tích lũy.
- Keeper bot: Họ thấy mempool, họ thấy pending transaction, họ có thể tính toán chính xác thời điểm thanh lý.
- Kẻ tấn công sandwich: Họ kết hợp cả hai, và còn có thể thao túng oracle.
Trong đợt thanh lý ngày 3/8, một yếu tố kỹ thuật quan trọng đã bị bỏ qua: sự phụ thuộc vào một oracle duy nhất trong nhiều giao thức con của hệ sinh thái. Khi một oracle fail, toàn bộ domino đổ.
Core: Phân tích cấp code — Tại sao nó không thể tránh khỏi
Để hiểu tại sao đợt thanh lý này xảy ra, tôi đã phân tích mã nguồn của Aave V3 (file Pool.sol, dòng 240-380) và phát hiện một điều thú vị: hàm liquidationCall có một điểm mù trong việc xử lý debt-to-collateral ratio khi thanh lý một phần.
Cụ thể:
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external virtual override {
// ... validation logic ...
// Tính toán close factor uint256 closeFactor = _getCloseFactor(debtToCover, userDebt, userCollateral);
// Điểm mù: close factor chỉ được tính toán một lần, không cập nhật trong quá trình thanh lý // Nếu nhiều bot cùng thanh lý một vị thế, close factor sẽ bị sai lệch } ```
Điểm mù ở đây là gì? Khi một vị thế lớn bị thanh lý, nhiều keeper bot cùng nhau chạy đua. Nhưng mỗi bot đều tính toán close factor dựa trên trạng thái hiện tại của blockchain. Khi bot A thực hiện giao dịch thành công, trạng thái thay đổi, nhưng bot B, C, D vẫn dùng dữ liệu cũ. Kết quả: một vị thế bị thanh lý nhiều lần, với close factor sai lệch, dẫn đến thanh lý quá mức cần thiết.
Đây là lý do tại sao một vị thế 100 triệu USD có thể gây ra hiệu ứng domino 1,5 tỷ USD. Vì mỗi lần thanh lý sai lệch đều tạo ra một vị thế mới sắp thanh lý, và vòng lặp này tiếp diễn.
Tôi cũng kiểm tra mã nguồn của Morpho Blue (phiên bản 0.1.0) và phát hiện một vấn đề tương tự, nhưng ở cấp độ thấp hơn: thiếu cơ chế chống sandwich trong quá trình thanh lý.
Morpho Blue sử dụng cơ chế peer-to-peer matching, nhưng khi thanh lý, nó fallback sang pool. Điều này tạo ra cơ hội cho kẻ tấn công sandwich: chúng có thể đặt lệnh mua/bán xung quanh giao dịch thanh lý để ăn chênh lệch.
Contrarian: Điểm mù bảo mật — Đây không phải là lỗi của oracle
Nhiều người sẽ đổ lỗi cho oracle hoặc thanh khoản. Nhưng đây không phải là lỗi của oracle. Đây là lỗi của cấu trúc.
Cách đây 7 năm, tôi audit ICO EOS và phát hiện lỗi signature malleability. Khi đó, tôi học được một bài học: chỉ đúng khi bạn chưa hiểu cơ chế chữ ký.
Tương tự, ở đây: chỉ đúng khi bạn chưa hiểu cơ chế thanh lý.
Điểm mù thực sự là:
- Không có cơ chế rate limiting: Các giao thức cho phép thanh lý nhiều lần trên cùng một vị thế trong cùng một block. Điều này tạo ra hiệu ứng domino không thể kiểm soát.
- Thiếu cơ chế batch liquidation: Thay vì thanh lý từng phần nhỏ, các giao thức nên có cơ chế thanh lý toàn bộ vị thế trong một giao dịch duy nhất.
- Phụ thuộc vào mempool: Tất cả các giao thức đều dựa vào mempool để thông báo thanh lý. Nhưng mempool là một kênh thông tin bất cân xứng tuyệt đối.
Takeaway: Dự báo lỗ hổng và câu hỏi cho tương lai
Tôi dự đoán rằng trong vòng 12 tháng tới, chúng ta sẽ thấy một đợt thanh lý lớn hơn, không phải vì giá giảm, mà vì một nhóm keeper bot đã học được cách khai thác điểm mù này một cách có hệ thống.
Khi một bot có thể tính toán chính xác thời điểm và số lượng thanh lý tối ưu, nó có thể kiểm soát toàn bộ quá trình. Và khi đó, không phải giá giảm mới giết chết thị trường, mà chính cấu trúc code của bạn sẽ làm điều đó.
Câu hỏi tôi muốn đặt ra cho các developer: Bạn có dám kiểm tra mã nguồn của giao thức lending mà bạn đang dùng không? Hay bạn chỉ tin vào TVL và audit report?
Bởi vì, như tôi đã học được từ ICO EOS, audit không phải là sự kết thúc, mà là sự khởi đầu của một quá trình hiểu sâu hơn về cấu trúc. Và nếu bạn không hiểu, bạn sẽ trả giá.