Hook
Một giao dịch. Một hợp đồng thông minh mới deploy. 8.000.000 USDC biến mất khỏi pool thanh khoản chính trong 3 phút 27 giây. Không phải oracle hack, không phải flash loan tấn công. Đây là lỗi tái nhập cổ điển – nhưng được ngụy trang bằng một cơ chế callback tưởng chừng vô hại: migrate liquidity.
Tôi nhìn vào block 18.472.095 trên mạng Ethereum, nơi một địa chỉ ví mới – 0x3f9…b2a – thực hiện 47 cuộc gọi liên tiếp đến cùng một hàm withdrawAndMigrate. Mỗi lần gọi, số dư trong pool giảm đi một lượng tương ứng, nhưng số dư nội bộ của hợp đồng không được cập nhật kịp. Kết quả: kẻ tấn công rút được nhiều hơn số LP token mà họ sở hữu, gấp 12 lần.
Context
SonicSwap là một DEX aggregator mới nổi trên Arbitrum, hứa hẹn "thanh khoản sâu nhất" nhờ cơ chế liquidity migration tự động. Khi một pool thanh khoản bị mất cân bằng, giao thức cho phép bất kỳ ai – kể cả người dùng thông thường – kích hoạt quá trình migrate: chuyển tài sản từ pool cũ sang pool mới với tỷ giá tốt hơn. Ý tưởng ban đầu: giảm tổn thất tạm thời cho LP và tối ưu hoá vốn.
Nhưng hợp đồng thông minh của họ lại có một lỗi thiết kế tinh vi. Hàm withdrawAndMigrate sử dụng một callback tới token LP trước khi cập nhật số dư nội bộ. Cụ thể, khi người dùng gọi hàm này, hợp đồng sẽ gửi token LP đến một địa chỉ trung gian (để đốt), sau đó gọi hàm onMigration trên token LP đó. Nếu token LP là hợp đồng thông minh (ERC-1155 trong trường hợp này), hàm onMigration có thể gọi lại withdrawAndMigrate một lần nữa – trước khi số dư của người dùng được đánh dấu là đã rút.
Core
Tôi bắt đầu phân tích bằng cách trace lại 47 giao dịch con. Mỗi giao dịch chỉ rút một lượng nhỏ – khoảng 170.000 USDC – nhưng tổng cộng vượt xa giới hạn. Kẻ tấn công đã sử dụng một hợp đồng tấn công riêng, với logic callback được viết tinh vi: