Cơ bản
Giao ngay
Giao dịch tiền điện tử một cách tự do
Giao dịch ký quỹ
Tăng lợi nhuận của bạn với đòn bẩy
Chuyển đổi và Đầu tư định kỳ
0 Fees
Giao dịch bất kể khối lượng không mất phí không trượt giá
ETF
Sản phẩm ETF có thuộc tính đòn bẩy giao dịch giao ngay không cần vay không cháy tải khoản
Giao dịch trước giờ mở cửa
Giao dịch token mới trước niêm yết
Futures
Truy cập hàng trăm hợp đồng vĩnh cửu
TradFi
Vàng
Một nền tảng cho tài sản truyền thống
Quyền chọn
Hot
Giao dịch với các quyền chọn kiểu Châu Âu
Tài khoản hợp nhất
Tối đa hóa hiệu quả sử dụng vốn của bạn
Giao dịch demo
Giới thiệu về Giao dịch hợp đồng tương lai
Nắm vững kỹ năng giao dịch hợp đồng từ đầu
Sự kiện tương lai
Tham gia sự kiện để nhận phần thưởng
Giao dịch demo
Sử dụng tiền ảo để trải nghiệm giao dịch không rủi ro
Launch
CandyDrop
Sưu tập kẹo để kiếm airdrop
Launchpool
Thế chấp nhanh, kiếm token mới tiềm năng
HODLer Airdrop
Nắm giữ GT và nhận được airdrop lớn miễn phí
Launchpad
Đăng ký sớm dự án token lớn tiếp theo
Điểm Alpha
Giao dịch trên chuỗi và nhận airdrop
Điểm Futures
Kiếm điểm futures và nhận phần thưởng airdrop
Đầu tư
Simple Earn
Kiếm lãi từ các token nhàn rỗi
Đầu tư tự động
Đầu tư tự động một cách thường xuyên.
Sản phẩm tiền kép
Kiếm lợi nhuận từ biến động thị trường
Soft Staking
Kiếm phần thưởng với staking linh hoạt
Vay Crypto
0 Fees
Thế chấp một loại tiền điện tử để vay một loại khác
Trung tâm cho vay
Trung tâm cho vay một cửa
50 triệu USDT đổi lấy 3.5 vạn đô la AAVE: Thảm họa đã xảy ra như thế nào? Chúng ta nên đổ lỗi cho ai?
本文来自:@Ehsan1579
编译|Odaily 星球日报(@OdailyChina);译者| Ethan(__@ethanzhang_web 3)
Chỉ nhìn tiêu đề sự kiện, nhiều người có thể nhầm đây là một vụ tấn công khai thác lỗ hổng.
Nội dung chính của sự kiện là: Có người đã chuyển giá trị 50,4 triệu USD USDT, cuối cùng chỉ đổi được 3,59 vạn USD AAVE.
Lần đầu nghe về vụ việc này, tôi thực sự sốc. Vì vậy, tôi đã phân tích toàn diện toàn bộ sự kiện: theo dõi giao dịch, đường dẫn giải quyết, gọi hợp đồng, dự trữ lịch sử, dữ liệu thanh toán, quy trình adapter, mã giao diện Aave, SDK flash loan của CoW, và mã routing để đánh giá xem báo giá có “hợp lý” hay không.
**Đây không phải là một cuộc tấn công hacker.** Hợp đồng cốt lõi của Aave không có lỗi. Giao dịch settlement của CoW không có lỗi. Uniswap không có lỗi. SushiSwap không có lỗi. Giao dịch hợp lệ, chữ ký hợp lệ, tất cả hợp đồng đều thực thi theo mã lệnh. Tuy nhiên, gần như toàn bộ giá trị kinh tế đã bị phá hủy, chỉ vì nó được phép đi theo một route vô lý cực kỳ.
Chuỗi chính của blockchain không gặp vấn đề, vấn đề nằm ở route.
Theo tôi, việc xem nhẹ gọi là “sự cố của người dùng” là thái độ thiếu khách quan, cẩn trọng. Quả thật, người dùng đã ký xác nhận đơn hàng, nhưng toàn bộ hệ thống phần mềm lại cho phép một thao tác liên quan đến gần 50 triệu USD thế chấp, hoàn tất báo giá, ký, lập route và thực thi, tất cả đều hướng tới một pool thanh khoản có khoảng 331 AAVE thấp. Điều này vốn không thể xảy ra, ít nhất phải bị hệ thống chặn lại trước khi bước vào giai đoạn settlement.
Nguồn gốc của sự cố
Hash giao dịch bất thường này là: 0x9fa9feab3c1989a33424728c23e6de07a40a26a98ff7ff5139f3492ce430801f, xác nhận vào block cao nhất 24643151 trên mạng chính Ethereum ngày 12/3/2026, chỉ số giao dịch là 1, tiêu thụ gas 3,780,570 đơn vị, giao dịch thành công. Địa chỉ ví chủ sở hữu đơn hàng bắt đầu bằng 0x98b9, địa chỉ solver (người gửi giao dịch) thực thi là 0x3980, được đánh dấu trong dữ liệu của CoW là tsolver.
Trước tiên, cần hiểu rõ đây không chỉ là một đổi USDT sang AAVE đơn thuần tại ví. Token bán ra là aEthUSDT, chứng nhận gửi tiền USDT sinh lãi trên nền tảng Aave. Token mua vào là aEthAAVE, chứng nhận gửi AAVE sinh lãi. Thực chất, đây là một thao tác đổi thế chấp Aave qua hệ thống settlement của CoW và adapter flash loan.
Trước giao dịch, ví này nắm khoảng 50,432,693.075254 aEthUSDT và 0 aEthAAVE. Sau giao dịch, còn lại 4.980399 aEthUSDT và nhận về 327.241335505966487788 aEthAAVE. Thực tế, ví đã bán gần như toàn bộ vị thế.
Dữ liệu meta rõ ràng hơn, cho thấy route đã “độc hại” ngay từ trước khi thực thi. Đơn hàng xuất phát từ quy trình aave-v3-interface-collateral-swap. API của CoW hiển thị đó là đơn bán đã ký, trong khi metadata của ứng dụng đánh dấu là swap thế chấp theo giá thị trường với slippage thông minh 121 điểm cơ bản. Số tiền bán ký là 50,432,688.41618 aEthUSDT. Số tiền mua tối thiểu ký là 324.949260918413591035 aEthAAVE. Thực tế, settlement đã thanh toán 327.241335505966487788 aEthAAVE.
Điều này cực kỳ quan trọng. Đơn hàng này vốn dĩ không mong đợi nhận hàng nghìn AAVE rồi bị phá hủy giữa chừng. Ngay từ lúc xây dựng, nó đã hướng tới kết quả chỉ khoảng 300 AAVE.
Chuỗi đứt gãy route
Khi theo dõi giao dịch, toàn bộ quá trình trở nên rõ ràng và tàn nhẫn.
Nguồn dòng tiền chính dựa vào hợp đồng settlement của CoW bắt đầu bằng địa chỉ 0x9008 (GPv2Settlement). Đầu tiên, hợp đồng HooksTrampoline bắt đầu ủy quyền aEthUSDT từ địa chỉ 0x60bf, cho phép trung gian của CoW rút tài sản người dùng mà không cần ủy quyền riêng; sau đó, hợp đồng GPv2VaultRelayer (bắt đầu bằng 0xc92e) rút 50,432,688.41618 aEthUSDT từ ví người dùng để đưa vào quy trình settlement. Tại bước này, mọi thao tác đều hợp lý.
Tiếp theo, hợp đồng settlement cấp quyền thao tác aEthUSDT cho hợp đồng phụ chưa mã nguồn mở bắt đầu bằng 0xd524, qua hàm chọn 0x494b3137; hợp đồng phụ này lại chuyển quyền thực thi cho hợp đồng executor chưa mã nguồn mở bắt đầu bằng 0x699c. Toàn bộ quá trình lộ rõ đường đi của route độc hại.
Giao dịch hợp lệ đầu tiên hướng tới hợp đồng pool của Aave bắt đầu bằng 0x87870, dùng hàm withdraw (chọn 0x69328dec) để đốt aEthUSDT, rút USDT gốc; sau đó route chuyển sang pool Uniswap V3 USDT/WETH bắt đầu bằng 0x4e68, đổi toàn bộ 50,432,688.41618 USDT thành 17,957.810805702142342238 WETH.
Giai đoạn này hoàn toàn bình thường: tỷ lệ đổi khoảng 2808.4 USDT = 1 WETH, phù hợp thị trường, không thiếu thanh khoản, không sai lệch tính toán, không có gì bất thường trong chuỗi giao dịch đầu tiên.
Vấn đề nằm ở bước thứ hai, khi xem xét dự trữ thanh khoản, câu chuyện đã rõ ràng hơn nhiều.
Sau khi hợp đồng executor nhận 17,957.810805702142342238 WETH, toàn bộ số WETH này được chuyển vào pool SushiSwap V2 AAVE/WETH bắt đầu bằng 0xd75ea151a61d06868e31f8988d28dfe5e9df57b4.
Tôi đã kiểm tra dữ liệu dự trữ của pool này ngay trước thời điểm giao dịch bất thường (block 24643150), thì trong pool chỉ có:
331.631982538108027323 AAVE và 17.653276196397688066 WETH
Không phải do nhập sai dữ liệu, mà là sự thật rõ ràng.
Route này, gần 17,958 WETH được đổ vào một pool nhỏ chỉ có 17.65 WETH dự trữ, tổng AAVE trong pool chỉ khoảng 331.63, lượng WETH đầu vào gấp khoảng 1017 lần dự trữ WETH của pool.
Điều này không phải là “slippage cao” hay “thanh khoản yếu” thông thường, mà là một đường đi thực thi lệnh thị trường cực kỳ vô lý, ép một pool AMM nhỏ bé, có quy mô cố định nhân, phải xử lý một khối lượng giao dịch vượt quá hàng nghìn lần.
Theo thuật toán cố định nhân, pool này gần như đã cạn kiệt toàn bộ dự trữ AAVE.
Pool của SushiSwap kích hoạt swap chính: chuyển 17,957.810805702142342238 WETH, chỉ đổi lấy 331.305315608938235428 AAVE. Sau giao dịch, dự trữ còn lại của pool là:
0.326666929169791895 AAVE và 17,975.464081898540030304 WETH
Nói cách khác, khoảng 99.9% lượng AAVE trong pool bị rút sạch trong một bước.
Dựa trên dự trữ trước đó, giá AAVE trong pool ước tính khoảng 149.50 USD. Giá thực tế người dùng thực thi là khoảng 154,114.66 USDT cho 1 AAVE, chênh lệch hơn 1000 lần so với giá spot ban đầu.
Sau đó, AAVE này được cung cấp trở lại vào pool của Aave, qua hàm supply (chọn 0x617ba037), tức là tạo mới aEthAAVE gửi về hợp đồng settlement. Kết quả, 327.241335505966487788 aEthAAVE được chuyển cho người dùng. Khoảng 4.06398010297174764 aEthAAVE còn lại trong hợp đồng settlement như phần lợi nhuận của người dùng so với giá trị đã trả.
Vậy, settlement không làm méo mó kết quả tốt thành xấu, mà chỉ xác nhận kết quả đã hình thành từ route sẵn rồi.
Điều then chốt, cần rõ ràng: thảm họa này đã “tiền định” trong route từ trước.
Trong dữ liệu gọi hợp đồng phụ của route, mục tiêu mua là khoảng 331.272185078031026739 AAVE, trong khi ký ký là tối thiểu 324.949260918413591035 AAVE, và thực tế settlement là 327.241335505966487788 AAVE, tất cả đều đã khóa trước trong vòng vài trăm AAVE.
Route này vốn đã xấu từ sinh ra.
Vấn đề ở đâu?
Câu trả lời là: các cơ chế kiểm tra của hệ thống đều kiểm tra sai khía cạnh.
Các lớp kiểm tra chỉ xác nhận giao dịch có thể thực thi, chữ ký hợp lệ, số tiền không bằng 0, nhưng hầu như không có kiểm tra nào về tính hợp lý của route về mặt kinh tế — đây chính là nguyên nhân cơ bản của cơ chế thất thủ.
Lỗi trong mã code của đường dẫn báo giá adapter của giao diện Aave
Điểm bất thường rõ ràng đầu tiên xuất hiện trong quy trình báo giá của adapter CoW trên giao diện Aave: hàm yêu cầu báo giá, vốn dùng để đính kèm dữ liệu ứng dụng riêng của adapter, bị vô hiệu hóa hoàn toàn.
Nguồn: rates.helpers.ts:93 và adapters.helpers.ts:194
Điều này có nghĩa là, khi giao diện Aave gửi yêu cầu báo giá tới CoW, không đính kèm dữ liệu metadata của flash loan và hook như khi đặt lệnh thật. Nói cách khác, thứ được báo giá không hoàn toàn là thứ sẽ được thực thi. Thậm chí, chú thích của mã còn nói mục đích của hàm này là để giúp báo giá adapter chính xác hơn, nhưng lại bị vô hiệu hóa cứng.
Logic cạnh tranh báo giá của CoW quá yếu (lỗ hổng chính)
Vấn đề thứ hai, nghiêm trọng hơn, nằm ở logic cạnh tranh báo giá của hệ thống CoW: trong mã dịch vụ công, chỉ cần báo giá có gas phí dương, kết quả đầu ra không zero là được xem là “hợp lý”.
Nguồn: quote.rs:31
Với một hệ thống xử lý đơn hàng tám chữ số, đây là một định nghĩa “hợp lý” cực kỳ yếu ớt.
Hệ thống không tích hợp oracle để kiểm tra tính hợp lý của giá, không có cơ chế chặn “báo giá lệch hơn 500 lần so với giá spot”, không có cảnh báo “route sẽ rút sạch thanh khoản”, không có cảnh báo “bước cuối cùng không phù hợp lớn nhỏ của thanh khoản và đơn hàng”; chỉ cần solver trả về route khả thi, không zero, hệ thống chấp nhận, đây chính là lỗ hổng chính của sự kiện này.
Thiếu sót trong mô hình thanh khoản của Uniswap V2
Vấn đề thứ ba, liên quan đến mô hình pool của Uniswap V2: mã chỉ dùng thuật toán cố định nhân, từ chối dự trữ bằng 0, tràn số, tràn dự trữ, nhưng không kiểm tra tính khả thi về mặt kinh tế.
Nguồn: pool_fetching.rs:118 và pool_fetching.rs:153
Mã này không kiểm tra xem quy mô pool có đủ để xử lý giao dịch hay không, chỉ kiểm tra tính hợp lệ về mặt toán học. Do đó, ngay cả pool nhỏ chỉ có 331 AAVE, vẫn có thể bị coi là phù hợp để xử lý yêu cầu mua 17,958 WETH, chỉ vì thuật toán cố định nhân tính ra kết quả không zero, trong khi thực tế, kết quả này có thể gây thiệt hại tài sản cực lớn.
SDK flash loan và cơ chế xác thực đơn hàng bị lỗi lần hai
Tiếp theo, SDK flash loan đã cố định hóa báo giá sai này vào payload của đơn hàng và hook, mà không có biện pháp kiểm tra rủi ro thứ hai.
Tiếp đó:
Nguồn: index.js:484 và index.js:591
Điều này lý giải vì sao tôi luôn nói route này “sinh ra đã xấu”. Adapter không “phát hiện” ra số tiền xấu mới trong quá trình thực thi, mà đã serialize số tiền xấu đó vào dữ liệu hook và địa chỉ instance đã xác định. Một khi báo giá xấu tồn tại, các cơ chế khác sẽ trung thành truyền nó đi.
Thậm chí, logic xác thực đơn hàng của CoW cũng không thực sự bảo vệ người dùng, vì chỉ kiểm tra xem đơn hàng có vượt quá giá thị trường khi báo hay không, chứ không kiểm tra xem báo giá có vô lý so với thanh khoản thực tế hay không.
Nguồn: order_validation.rs:694
Đây là kiểm tra tính nhất quán. Nếu báo giá đã là vô lý, đơn hàng vẫn có thể qua.
Cảnh báo frontend UI gần như vô dụng
Giao diện Aave có cảnh báo tác động giá cao, nhưng chỉ là một checkbox xác nhận, không phải cơ chế cắt đứt tự động.
Khi người dùng tick vào, mọi rào cản đều bị gỡ bỏ:
Nguồn: helpers.ts:24 và HighPriceImpactWarning.tsx:35
Vì vậy, ngay cả khi giao dịch này gần như xóa sạch toàn bộ giá trị tài sản, hệ thống chỉ coi đó là thao tác người dùng cần xác nhận, chứ không phải giao dịch nguy hiểm cần bị từ chối cứng rắn. Cảnh báo này hoàn toàn mất tác dụng phòng ngừa rủi ro.
Với tất cả các cơ chế đều thất thủ như vậy, tôi không đồng tình với kết luận “chỉ là người dùng ngu”. Người dùng đã ký xác nhận, nhưng toàn bộ hệ thống phần mềm có vô số cơ hội chặn đứng thảm họa này, đều chỉ thực hiện kiểm tra cơ bản như “không zero, có thể thực thi, đã ký”, rồi thả lỏng, dẫn đến hậu quả thảm khốc.
Route không bị sửa đổi
Điều này cực kỳ quan trọng, loại bỏ các giả thuyết sai lầm: quy trình của giao diện chính thức của Aave, trong file useSwapOrderAmounts.ts, tại dòng 139, sẽ tính toán số tiền mua sau khi điều chỉnh slippage dựa trên báo giá, phí mạng, phí đối tác, phí flash loan; dòng 331 chuyển sang dạng buyAmountBigInt; rồi tại dòng 191 của file CollateralSwapActionsViaCoWAdapters.tsx, sẽ ký chính xác số tiền này.
Các adapter sau đó, trong hợp đồng AaveV3BaseAdapter.sol, tại dòng 141, sẽ kiểm tra ký ký khớp hoàn toàn với dữ liệu đã lưu; hợp đồng settlement của CoW, trong GPv2Settlement.sol, tại dòng 337, sẽ bắt buộc thực thi giới hạn ký ký. Do đó, kết quả thực thi trên chain không vượt quá phạm vi ký ký, tài sản người dùng nhận được thậm chí còn cao hơn mức tối thiểu ký.
Điều này chứng minh rõ ràng: thảm họa xảy ra trước bước settlement, chứ không phải trong quá trình settlement, lỗi chết người nằm ở chính route.
Giá trị bị mất đi đâu?
Cùng trong block, giao dịch tiếp theo (hash bắt đầu 0x45388b0f) thực hiện arbitrage trên pool SushiSwap AAVE/WETH bị phá hỏng. Giao dịch bất thường đổ đầy WETH vào pool, rút sạch phần lớn AAVE, rồi arbitrageer bán AAVE trở lại pool, thu lợi từ chênh lệch giá.
Giao dịch này đã rút khoảng 17,929.77 WETH, rồi trả khoảng 13,087.73 ETH cho nhà tạo lập block, và khoảng 4,824.31 ETH cho địa chỉ thực thi arbitrage.
Toàn bộ giá trị kinh tế mất của người dùng cuối cùng gần như biến thành lợi nhuận MEV trong cùng block, và lợi nhuận của nhà tạo lập block.
Ngoài ra, kiểm tra thời gian của block xác nhận rõ ràng: trước giao dịch không có ai thao túng pool SushiSwap để lừa người dùng, lần đầu tiên pool AAVE/WETH bị tác động là chính giao dịch bất thường này (giao dịch index 1); tiếp theo, giao dịch thứ hai (index 2) thực hiện arbitrage dựa trên giá bị biến dạng; giao dịch thứ ba (index 3) trong quá trình thị trường phục hồi cũng chạm tới cặp này. Thời gian rõ ràng chứng minh: giao dịch bất thường này đã tạo ra mức giá cực kỳ lệch lạc, các giao dịch sau đó tận dụng chênh lệch này để thu lợi.
Vậy ai là thủ phạm?
Nếu hỏi liệu Aave V3 core có sập hay không, câu trả lời là không. Các pool của Aave vẫn hoạt động bình thường theo lệnh, hoàn tất rút USDT và gửi AAVE.
Nếu hỏi hợp đồng settlement của CoW có sập không, câu trả lời là không. Nó thực thi hợp lệ một đơn ký, và thanh toán vượt mức tối thiểu ký.
Nếu hỏi các pool của Uniswap V3 hoặc SushiSwap có lỗi không, câu trả lời cũng là không. Các pool này đều theo đúng thuật toán của riêng mình.
Thật ra, thất bại hệ thống nằm ở tầng cao hơn, ở phần route và kiểm soát rủi ro:
Trách nhiệm chính thuộc về module route, báo giá và solver của hệ thống CoW: toàn bộ hệ thống quá yếu trong việc xác định “route hợp lý”, cho phép các đơn hàng hàng chục triệu USD cuối cùng chảy vào các pool thanh khoản nhỏ bé, chỉ cần route khả thi, không zero là chấp nhận, bỏ qua các cảnh báo về tính cực kỳ vô lý của các giao dịch này.
Trách nhiệm phụ thuộc về giao diện frontend của Aave: khi yêu cầu báo giá adapter, không đính kèm dữ liệu hook liên quan, truyền kết quả sai vào ký, chỉ dựa vào cảnh báo, không có cơ chế cứng để từ chối, quá yếu để phòng ngừa các giao dịch cực lớn như vậy.
Đây là thất bại cực kỳ nghiêm trọng của chất lượng route và cơ chế kiểm soát rủi ro, biến một thao tác thế chấp hợp lệ thành thảm họa phá sản tài sản.