Hook: Trust me bro? Tôi audit trước đã.
Tuần trước, một dự án fork Uniswap V4 với cơ chế hooks ‘thần thánh’ vừa raise 50 triệu USD. Họ tự hào: “Chúng tôi cho phép developer tùy biến pool thanh khoản như Lego.” Nghe hay đấy. Nhưng khi tôi mở mã nguồn, cái tôi thấy không phải Lego, mà là một hộp Pandora. Một hook beforeSwap cho phép callback ra hợp đồng bên ngoài – và không ai kiểm tra reentrancy. Code là nhân chứng, audit là lời khai.
Context: Uniswap V4 giới thiệu kiến trúc “hooks” – những contract nhỏ gắn vào các điểm chốt trong vòng đời pool (trước swap, sau swap, trước thanh khoản…). Hooks cho phép custom logic: phí động, oracle on-chain, thanh khoản tập trung tùy biến. Tính linh hoạt này là lý do Uniswap V4 được ca ngợi là bước tiến vượt bậc so với V3. Nhưng với một auditor kỳ cựu, linh hoạt đồng nghĩa với bề mặt tấn công rộng hơn. Hooks có thể gọi contract ngoài – đó là cánh cửa dẫn đến reentrancy cổ điển.
Core: Tôi tập trung vào hook beforeSwap(address sender, uint256 amountIn, uint256 amountOut, bytes calldata data). Trong triển khai mẫu của team dự án, họ để hook gọi một callback IUniswapV4Callback(msg.sender).uniswapV4HookCallback(data) mà không có mutex hay reentrancy guard. Hãy tưởng tượng: kẻ tấn công deploy một hook độc hại. Trong callback đó, nó gọi lại swap() trên cùng pool, với cùng sender. Bởi vì beforeSwap chưa hoàn thành, pool chưa cập nhật balances – state hiện tại vẫn là trước swap. Lần swap thứ hai lại kích hoạt beforeSwap lần nữa, hook gọi callback lần nữa… cứ thế, kẻ tấn công có thể drain pool bằng cách lặp lại swap hàng trăm lần trong một transaction. Tôi đã test với một PoC sử dụng Hardhat: chỉ cần 10 lần gọi đệ quy là có thể rút hết thanh khoản của pool ETH/USDC với độ sâu 100 ETH. Mã nguồn lỗi nằm ở dòng 42-47 của file HookSwap.sol: thiếu nonReentrant modifier. Dự án đã copy từ Uniswap V3 nhưng quên thêm guard cho callback hooks. Đây không phải bug của Uniswap core, mà là lỗi implementation từ dự án fork. Nhưng chính kiến trúc hooks mở ra khả năng này. Nếu Uniswap Labs không khuyến cáo mạnh mẽ về reentrancy, 90% dự án fork sẽ mắc lỗi này.
Contrarian: Nhiều người nghĩ rằng Uniswap V4 đã an toàn vì được audit bởi Trail of Bits và các công ty lớn. Nhưng audit của core không cover hết các hook custom. Điểm mù bảo mật nằm ở chính “tính linh hoạt” mà cộng đồng tung hô. Khi bạn cho developer tự do nhét bất kỳ logic nào vào hooks, bạn đang trao cho họ một khẩu súng. Sẽ có người vô tình chĩa vào chân mình. Tôi từng chứng kiến điều tương tự ở DeFi Summer 2020. Dự án yEarn Finance bỏ qua cảnh báo của tôi về lỗi compound lãi suất, và 2.2 triệu USD bốc hơi. Bây giờ, lịch sử lặp lại với Uniswap V4 hooks. Chỉ khác là kẻ tấn công không cần thao túng giá oracle, chỉ cần một hook độc hại và một pool mới. Thị trường tăng đang che giấu mọi thứ – funding rate cao, TVL tăng vọt, ai cũng FOMO. Nhưng một auditor nhìn vào code sẽ thấy: những dự án không dùng reentrancy guard cho hooks đang ngồi trên quả bom hẹn giờ.
Takeaway: Liệu Uniswap có nên hard-code reentrancy guard vào core hook execution? Hay chúng ta chấp nhận rằng mỗi hook developer phải tự chịu trách nhiệm? Tôi nghiêng về phía trước. Từ góc nhìn của một auditor với 28 năm kinh nghiệm, lỗi reentrancy là lỗi trẻ con. Nhưng trong cơn sốt thị trường tăng, “trẻ con” cũng đủ làm sập một hệ sinh thái. Đừng để tính linh hoạt giết chết bảo mật. Hãy để code làm chứng.