Ngày 13 tháng 3 năm 2023, lúc 08:50 UTC, một kẻ tấn công chỉ được biết đến với tên "Jacob" đã thực hiện exploit DeFi lớn nhất trong năm – rút 197 triệu đô la từ Euler Finance, một giao thức cho vay trên Ethereum. Điều khiến cuộc tấn công này trở nên đặc biệt không chỉ là số tiền, mà còn là sự chính xác tuyệt đối: một chức năng bị bỏ qua, được đưa vào thông qua một Governance proposal, kết hợp với một cơ chế tăng cường mới để tạo ra một cơn bão hoàn hảo. Thậm chí còn đáng kinh ngạc hơn, kẻ tấn công đã trả lại từng xu có thể thu hồi trong vòng ba tuần.
Đây là câu chuyện về cách một chức năng "tặng quà" đã phá vỡ một quy trình trị giá 264 triệu USD, tại sao quá trình quản trị không thể phát hiện ra nó, và mọi nhà phát triển DeFi phải học hỏi từ lỗ hổng donateToReserves.
Điều gì đã xảy ra: lịch trình của cuộc tấn công
Sự tấn công diễn ra trong vài phút nhưng đã được chuẩn bị trong nhiều tháng kể từ khi Euler Improvement Proposal 14 (eIP-14) được phát hành.
| Thời gian (UTC) | Lịch sự kiện |
|---|---|
| 08:50 | Người tấn công lấy 30 triệu DAI Flash loan từ AAVE |
| 08:51 | Nạp tiền vào Euler, tăng mức đòn bẩy 10 lần, gọi là donateToReserves |
| 08:52 | Tự thanh toán trên 5 nhóm (DAI, USDC, wBTC, stETH, WETH) |
| 08:53 | Trả lại Flash loan, thu được lợi nhuận ~$197 triệu |
| 08:55 | Tiền được phân phối đến nhiều địa chỉ |
| 25–28 tháng 3 | Người tấn công trả lại toàn bộ số tiền sau khi đàm phán |
| 3 tháng 4 | Kịp thời khôi phục hoàn toàn; các kế hoạch theo quy trình đã được thực hiện lại |
Tốc độ thực sự đáng kinh ngạc. Trong vòng chưa đầy ba phút, một DAI Flash loan có giá trị 30 triệu đô la – vốn mà kẻ tấn công không sở hữu – đã tạo ra một cuộc tấn công trị giá 197 triệu đô la. Đó là một tỷ suất đòn bẩy 6.500 lần với không có vốn khởi đầu bị rủi ro. Flash loan không phải là điểm yếu; nó là nhân tố tăng cường sức mạnh.
Nguyên nhân chính: donateToReserves và eIP-14
Cuộc chiến định mệnh Governance proposal
Dự án cải tiến Euler 14 (eIP-14) là một dự án cộng đồng Governance proposal được thiết kế để thêm chức năng "đóng góp cho dự trữ". Ý định của nó rất cao cả: cho phép người dùng tự nguyện đóng góp tài sản thế chấp vào dự trữ của giao thức, tăng cường hệ thống. Chức năng eToken::donateToReserves đã được thêm vào hợp đồng Euler Token (eToken)
`solidity // Simplified vulnerable function function donateToReserves(uint256 amount) external { _burn(msg.sender, amount); // Burns eTokens (collateral) totalReserves += amount; // Adds to protocol reserves // NO healthFactor() check! // NO dToken (debt) burning! } `
Tác dụng thực sự của chức năng đó là gì
Công cụ này có hai lỗi nghiêm trọng, nếu được phát hiện một cách riêng lẻ, có thể đã bị phát hiện – nhưng kết hợp lại, chúng là một thảm họa:
- Thanh toán bảo đảm (sổ hồng) (eTokens) mà không có kiểm tra sức khỏe — Nguyên tắc cơ bản của giao thức là mỗi vị trí phải duy trì Health factor ≥ 1.0 (giá trị bảo đảm ≥ giá trị nợ).
donateToReservesđã giảm giá trị bảo đảm nhưng không bao giờ xác minh rằng vị trí vẫn có khả năng thanh toán.
- Không đốt cháy nợ (dTokens) — Khi bạn gửi tài sản thế chấp, bạn nhận được eTokens. Khi bạn vay, bạn nhận được dTokens (tiền điện tử nợ). Tính năng đã đốt cháy eTokens nhưng để lại dTokens nguyên vẹn. Điều này tạo ra sự thay đổi trạng thái không đối xứng: tài sản thế chấp giảm, nợ không thay đổi = Bad debt tức thời.
Tại sao bài đánh giá này được thông qua
eIP-14 đã vượt qua quản trị cộng đồng vì các lý do sau:
- Tính năng nghe có vẻ có lợi (tăng cường dự trữ)
- Kiểm tra mã tập trung vào "lối đi hạnh phúc" (người dùng cống hiến tài sản đảm bảo vượt quá số cần thiết)
- Không ai mô hình hóa "lối đi đối kháng" (người dùng cống hiến để cố tình phá vỡ vị thế của họ)
- Formal verification không cần thiết cho Governance proposal
- Cạnh tranh với
mint()(Self-collateralized leverage) chưa được phân tích
Lời dạy: Phê duyệt quản trị ≠ kiểm tra bảo mật. DAOs phải phân biệt phê duyệt tính năng với kiểm tra Invariant.
Self-collateralized leverage: nhân tố tăng cường sức mạnh
Hàm mint() của Euler cho phép một nguyên tố mới: vay tiền dựa trên khoản gửi của bạn trong cùng một giao dịch. Đây không phải là hình thức cho vay có bảo đảm quá mức truyền thống – nó là Recursive leverage.
Mint() hoạt động như thế nào
`solidity function mint(uint256 assets) external returns (uint256 shares) { // User deposits assets, receives eTokens // Then immediately borrows against those SAME eTokens // Creates recursive loop: deposit → borrow → deposit → borrow... _mint(msg.sender, shares); } `
Khuôn khổ 10x Leverage
Người tấn công đã tận dụng điều này để đạt được hiệu quả 10 lần trong một giao dịch duy nhất:
- Nạp 20M DAI → Nhận 20M eDAI (đầu tư bảo đảm)
- Call mint() → Vay dựa trên eDAI → Nhận dDAI (nợ) → Chuyển đổi thành nhiều hơn DAI → Nạp lại → Lặp lại
Đây là Self-collateralized leverage. Không có nó, kẻ tấn công không thể tạo ra một vị trí lớn đủ để làm cho donateToReserves có lợi. Với nó, một DAI Flash loan trị giá 30 triệu USD đã trở thành một vũ khí trị giá 197 triệu USD.
Soft liquidation: Cơ chế khai thác
Euler sử dụng một cơ chế "Soft liquidation" - một chiết khấu dần dần tăng lên khi tỷ lệ tài sản thế chấp giảm. Nó được thiết kế để dễ sử dụng (tránh giải quyết đột ngột) nhưng tạo ra một giá dễ bị khai thác Oracle cho các kẻ tấn công.
Cách hoạt động của Soft liquidation
- Chế độ an toàn (tỷ lệ bảo đảm > 1,2 lần): ~5% Liquidation discount
- Rủi ro trung bình (1,0–1,2 lần): giảm giá 10–25%
Lý luận của kẻ tấn công
Với cú gọi donateToReserves(100M eDAI), kẻ tấn công cố tình đẩy vị trí của họ từ lành mạnh (195,6M tài sản thế chấp so với 200M nợ) xuống dưới nước sâu (95,6M tài sản thế chấp so với 200M nợ).
Giảm giá động có nghĩa là:
- Người thanh lý (nhà tấn công) có thể mua 200 triệu dDAI nợ với tài sản đảm bảo trị giá ~100 triệu DAI
- Chi phí của nhà tấn công: 100 triệu eDAI được quyên góp + phí gas
- Lợi ích của nhà tấn công: ~190 triệu DAI tài sản từ thanh lý
- Tỷ lệ lợi nhuận trung bình cho từng nhóm: ~8,9 triệu DAI
Thông tin quan trọng: Người tấn công không cần một nhà thanh lý bên ngoài – họ đã thanh lý chính mình thông qua một hợp đồng riêng biệt. Cơ chế của giao thức đã trả tiền cho họ để khai thác nó.
Hướng dẫn tấn công bước-by-bước
Chúng ta hãy theo dõi quá trình thực thi chính xác trên một pool (DAI), sau đó nhân với 5.
Khoản 1: Hợp nhất vốn (Flash loan)
` AAVE Flash Loan → 30M DAI (no collateral, single transaction) ` Chi phí: chỉ cần khí gas. Rủi ro: bằng 0 – nếu cuộc tấn công thất bại, khoản vay sẽ bị hủy.
Bước 2: Tạo vị trí
` Deposit 20M DAI → 20M eDAI (collateral tokens) mint() × 10 iterations → 195.6M eDAI collateral, 200M dDAI debt ` Hàm mint() cho phép vay tiền dựa trên các eToken vừa được tạo trong cùng một giao dịch. Mỗi lần lặp: nạp tiền → vay → nạp tiền → vay.
Khoản 3: cuộc gọi dễ bị tấn công
` donateToReserves(100M eDAI) `
- Đốt 100M eDAI (mã thế chấp giảm xuống 95.6M)
- Nợ dDAI vẫn là 200M (không thay đổi)
- Health factor: 95.6M / 200M = 0.478 (< 1.0 = dưới nước)
- Trữ lượng của quy trình tăng thêm 100M eDAI (nhân vật tấn công "đóng góp" cho quy trình)
Khoản 4: Tự giải thể
` Liquidate own position via separate contract Receive discounted collateral: ~190M DAI value for 200M dDAI debt ` Người thanh lý (hợp đồng của người tấn công) thanh toán khoản nợ 200M dDAI và nhận được tài sản thế chấp dưới nước với chiết khấu động (~50%+).
Khoản 5: Sử dụng lợi nhuận
` Withdraw ~38.9M DAI from liquidation Repay 30M DAI flash loan + fees Keep ~8.9M DAI profit ` Lặp lại trên các pool USDC, wBTC, stETH, WETH → 197 triệu đô la tổng cộng.
Cuộc phục hồi chưa từng có
Điều xảy ra tiếp theo khiến ngành công nghiệp kinh ngạc. Thay vì biến mất trong các máy trộn, kẻ tấn công – "Jacob" – bắt đầu đàm phán.
Lịch trình đàm phán
- 14 tháng 3: Euler cung cấp 10% thưởng White-hat (19,7 triệu USD) cho việc hoàn trả toàn bộ số tiền bị đánh cắp
- 20 tháng 3: Người tấn công liên hệ với nhóm thông qua tin nhắn trên chuỗi
- 25–28 tháng 3: Tiền được hoàn trả theo từng đợt:
- 84.951 ETH (tương đương 147,8 triệu USD vào thời điểm đó)
- 29,9 triệu USD DAI
- 3 tháng 4: Euler xác nhận hoàn toàn khôi phục được tất cả các khoản tiền có thể khôi phục
Tại sao họ lại trả lại nó?
Các giả thuyết nhiều như cát bụi:
- White-hat tuyên bố: Nhà tấn công cho rằng họ tiết lộ lỗi để bảo vệ người dùng (có tranh cãi – họ đã khai thác 5 pool đầu tiên)
- Tính theo dõi: Tiền được theo dõi rất kỹ; việc trộn lẫn 197 triệu đô la gần như là không thể
- Căng thẳng pháp lý: Euler đã liên hệ với cơ quan thực thi pháp luật; nhà tấn công có thể đã bị xác định danh tính
Dù có động cơ gì, điều này đã tạo ra một trường hợp tiên phong mới: đàm phán sau khi bị tấn công có thể thành công. Nhưng đó không phải là một chiến lược phòng vệ – đó là một kết quả may mắn.
Những bài học rút ra: Ngoài ra khỏi quy tắc
1. Mô hình "Tặng quà" (Donation)
_TERM_1_ đại diện cho một mô hình nguy hiểm: *sự thay đổi trạng thái mà không được kiểm tra Invariant. Mọi hàm giảm thiệt hại, tăng nợ hoặc chỉnh sửa cơ sở kế toán phải xác minh Invariant sau* khi thay đổi. Mô hình này xuất hiện ở các nơi khác:
Quy tắc kiểm toán: Mỗi lần burn, transfer hoặc mint ảnh hưởng đến tài sản đảm bảo/ngân hàng phải được theo sau bởi require(healthFactor() >= 1).
2. Self-collateralized leverage = Rủi ro quy hồi
mint() của Euler đã tạo ra một nguyên tử tăng cường vượt qua Overcollateralization truyền thống. Sự kết hợp của:
...là một loại lỗ hổng, chứ không phải là lỗi một lần. Các giao thức có cơ chế tương tự (Gearbox, Morpho, Notional) nên kiểm tra các vòng lặp tác động của chúng đối với các chức năng giảm tài sản đảm bảo.
3. Thất bại trong quá trình quản trị
eIP-14 đã được thực hiện mà không có: - Formal verification các Invariant mới - Thử nghiệm Invariant (bảo quản Health factor theo tất cả các đường đi) - Xây dựng mô hình tấn công kinh tế (nếu người dùng muốn đi dưới nước?) - Thử nghiệm tích hợp với các chức năng hiện có
DAOs phải yêu cầu: Kiểm tra bảo mật + bộ kiểm tra Invariant + đánh giá kinh tế trước khi bất kỳ chức năng thay đổi trạng thái nào được đưa vào hoạt động.
4. Soft liquidation Khuyết điểm trong thiết kế
Máy cơ chế giảm giá động, tuy là thân thiện với người dùng, nhưng đã tạo ra một Oracle được kiểm soát bởi kẻ tấn công. Kẻ tấn công có thể tính toán chính xác mức giới hạn thanh lý có lợi vì công thức giảm giá là công khai và xác định.
Xử lý thanh toán cứng (phạt cố định, ví dụ, 10% cố định) sẽ có khả năng chống lại hơn – kẻ tấn công không thể "tùy chỉnh" mức chiết khấu phù hợp với vị trí của họ.
5. Flash loan là các nhân tố tăng cường sức mạnh
Sự tấn công này không yêu cầu ngân sách nào – một DAI có sức mạnh 30M đã tạo ra một lỗ hổng trị giá 197 triệu USD. Mọi giao thức có:
...cần điều tra kỹ lưỡng hơn. Các Flash loan không gây ra lỗi; chúng làm tăng chúng lên 6.500 lần.
Hỏi đáp
Câu hỏi: Hack Euler Finance là gì?
A: Hành động tấn công Euler Finance là một vụ khai thác trị giá 197 triệu đô la vào ngày 13 tháng 3 năm 2023, trong đó một kẻ tấn công đã sử dụng một lỗ hổng trong hàm donateToReserves (được giới thiệu thông qua eIP-14) kết hợp với Self-collateralized leverage để cạn kiệt 5 nhóm vay trên Ethereum.
Câu hỏi: Vùng lỗ hổng donateToReserves hoạt động như thế nào?
A: Hàm donateToReserves đã đốt các token đảm bảo (eToken) mà không kiểm tra xem vị thế còn có khả năng thanh toán hay không, và không đốt các token nợ tương ứng (dToken). Điều này tạo ra Bad debt tức thời mà kẻ tấn công có thể khai thác thông qua tự thanh lý với chiết khấu lớn.
Câu hỏi: Self-collateralized leverage là gì trong DeFi?
A: Self-collateralized leverage cho phép người dùng vay dựa trên khoản gửi của họ trong cùng một giao dịch, tạo ra các chu trình Recursive leverage. Cấu trúc hàm mint() của Euler cho phép tăng mức đòn bẩy 10 lần từ khoản gửi 20 triệu DAI, biến một khoản gửi 30 triệu DAI thành một cuộc tấn công trị giá 197 triệu đô la.
Câu hỏi: Tổng số tiền được lấy lại từ vụ tấn công Euler là bao nhiêu?
A: Tất cả các khoản tiền có thể khôi phục đã được trả lại vào ngày 3 tháng 4 năm 2023 - 84.951 ETH (~ 147,8 triệu USD) và 29,9 triệu USD trong DAI, tổng cộng khoảng 197 triệu USD. Đây là một trong những vụ khôi phục lớn nhất trong lịch sử tiền điện tử.
Câu hỏi: Các giao thức DeFi nên rút ra những bài học nào từ vụ tấn công Euler?
A: 1) Mỗi chức năng thay đổi trạng thái phải kiểm tra sau khi thực hiện Invariant. 2) Governance proposal cần kiểm tra bảo mật, không chỉ là bình chọn của cộng đồng. 3) Recursive leverage + giảm tài sản đảm bảo = rủi ro nghiêm trọng. 4) Liquidation discount động có thể tạo ra các Oracle tấn công. 5) Flash loan có thể làm tăng nguy cơ lỗi biến đổi trạng thái theo cấp số nhân.
