Hook
Sáng ngày 15/10/2024, một quỹ đầu tư có tên “AlphaYield Capital” đã báo cáo mất 2.3 triệu USD từ pool thanh khoản tập trung trên Uniswap V4. Giao dịch đầu tiên diễn ra lúc 03:47 UTC: một hợp đồng hook trên chuỗi Ethereum mainnet đã chuyển toàn bộ số dư WETH và USDC ra một địa chỉ lạ. Phân tích cluster ví cho thấy kẻ tấn công đã triển khai một hook giả mạo, lợi dụng chức năng beforeSwap để đánh cắp tài sản mà không cần phê duyệt thêm.
Context
Uniswap V4 giới thiệu khái niệm “hook” – các hợp đồng thông minh có thể can thiệp vào mọi bước của quá trình giao dịch, từ việc thêm thanh khoản, trao đổi cho đến thu phí. Đây là một bước tiến lớn so với V3, cho phép các nhà phát triển tạo ra các chiến lược tùy chỉnh mà không cần fork toàn bộ pool. Tuy nhiên, kiến trúc này cũng mở ra một bề mặt tấn công mới. Trên lý thuyết, mỗi hook đều phải được kiểm tra kỹ lưỡng về quyền truy cập và logic. Nhưng theo bằng chứng on-chain từ sự cố này, hook của AlphaYield có một lỗ hổng cơ bản: hàm withdraw không kiểm tra msg.sender là owner của pool, cho phép bất kỳ ai gọi nó khi hook được kích hoạt.
Core (60-70% nội dung)
Hãy cùng trace execution path của giao dịch tấn công. Bước 1: Kẻ tấn công deploy một hook giả với địa chỉ tương tự hook thật (front-run bằng cách đặt gas cao để transaction của họ được xử lý trước). Bước 2: Họ gọi modifyLiquidity trên pool, kích hoạt beforeModifyLiquidity của hook giả. Trong hook này, có một hàm emergencyWithdraw được thiết kế để rút token khi pool bị lỗi. Vấn đề là hàm này không có modifier onlyOwner hay onlyPool. Đây là lỗ hổng kiến trúc: nhà phát triển hook đã tin tưởng rằng chỉ pool mới gọi hook, nhưng thực tế hook có thể được gọi trực tiếp từ bên ngoài.
Phân tích cluster ví của kẻ tấn công cho thấy họ đã chuẩn bị sẵn 0.5 ETH để trả gas, và thực hiện 12 giao dịch liên tiếp trong 3 block. Mỗi giao dịch rút ra khoảng 190,000 USDC và 60 WETH. Tổng cộng 2.3 triệu USD đã được chuyển qua một router ẩn danh, sau đó đưa vào Tornado Cash. Điều này giải thích tại sao việc truy vết hiện tại gần như bất khả thi.
Theo kinh nghiệm kiểm tra mã nguồn của tôi – từng xử lý các pool thanh khoản tập trung trên V3 suốt 8 tháng – tôi nhận thấy lỗi này cực kỳ phổ biến trong cộng đồng developer mới. Họ thường copy-paste mã hook mẫu từ GitHub, nhưng quên thêm các kiểm tra quyền. Ở cấp độ hợp đồng, chỉ cần một dòng require(msg.sender == address(pool)) cũng đủ ngăn chặn vụ hack này. Nhưng vì hook được triển khai với quyền admin bị bỏ trống, mọi thứ trở nên thảm họa.
Contrarian
Thị trường đang rất phấn khích về Uniswap V4. Hàng loạt bài viết ca ngợi “sự linh hoạt vô hạn” và “DeFi Lego thế hệ mới”. Nhưng góc nhìn phản trực giác ở đây là: chính sự linh hoạt này đã biến DEX thành một mớ hỗn độn khó kiểm soát. Hầu hết các nhà đầu tư bán lẻ đều tin rằng nếu một pool được triển khai bởi Uniswap, nó sẽ an toàn. Họ không nhận ra rằng bảo mật của pool phụ thuộc hoàn toàn vào chất lượng code của hook. Khi bạn chuẩn hóa wash trading và các chiến lược yield farming, bạn cũng chuẩn hóa cả rủi ro về lỗi hook.
Tôi đã từng bị thanh lý 11 lần vào năm 2021 khi học giao dịch perpetual. Mỗi lần đều vì thiếu kiểm tra các điều kiện biên. AlphaYield Capital chỉ là một trường hợp điển hình khác của cùng một bài học: trong bull market, mọi người đều FOMO vào các tính năng mới mà bỏ qua audit cơ bản. Đây là lỗ hổng kiến trúc của toàn bộ hệ sinh thái DeFi: chúng ta xây dựng những tòa nhà chọc trời trên nền móng cát.
Takeaway
Vậy bạn sẽ làm gì vào tuần tới? Nếu bạn đang quản lý một pool thanh khoản trên V4, hãy kiểm tra ngay hook của mình. Hãy trace execution path từ entry point đến withdraw. Nếu bạn thấy bất kỳ hàm nào không có onlyPool hoặc onlyOwner, hãy gỡ nó xuống ngay lập tức. Câu hỏi cuối cùng: trong khi bạn đọc bài viết này, có bao nhiêu hook khác đang âm thầm chờ bị khai thác?