Tuần trước, một dự án AMM thanh khoản tập trung mới ra mắt trên Arbitrum, huy động được 2.5 triệu USD từ các quỹ đầu tư mạo hiểm. Tôi mở etherscan, đọc contract ngay lập tức. Trong 48 giờ, tôi phát hiện một lỗi logic trong hàm swap() khiến bất kỳ ai cũng có thể rút cạn pool thanh khoản nếu biết cách khai thác. Lỗ hổng ở đây, không phải hype ở kia.
Context Dự án này là một AMM clone từ Uniswap v3, nhưng họ thêm tính năng “dynamic fee” dựa trên biến động giá. Họ quảng cáo rằng phí sẽ tự động điều chỉnh để bảo vệ LP khỏi impermanent loss. Nghe có vẻ thông minh, nhưng khi đọc code, tôi thấy họ implement dynamic fee bằng cách cho phép người dùng gọi một hàm updateFee() trước mỗi swap. Hàm này kiểm tra oracle giá từ Chainlink, tính toán phí mới, và ghi vào storage. Vấn đề: họ không giới hạn ai có thể gọi updateFee(), và họ không kiểm tra tính toàn vẹn của tham số đầu vào.
Core Tôi viết một script mô phỏng bằng Hardhat. Đầu tiên, tôi tạo một pool với token A và token B, thanh khoản ban đầu 100 ETH. Sau đó, tôi gọi updateFee() với một giá trị phí cực kỳ thấp (0.01%) – thấp hơn nhiều so với phí tối thiểu mà họ công bố (0.3%). Hàm chấp nhận mà không kiểm tra. Tiếp theo, tôi thực hiện một swap lớn: đổi 10 ETH lấy token B. Với phí gần như bằng 0, tôi nhận được gần như toàn bộ token B trong pool. Sau đó, tôi swap ngược lại với phí bình thường (0.3%) và lợi nhuận ròng của tôi là ~9.5 ETH sau một vài giao dịch.
Lý do kỹ thuật: updateFee() không có modifier chỉ admin, không có kiểm tra minFee và maxFee. Họ dựa vào oracle để tính phí, nhưng oracle không được gọi trong cùng transaction – họ cho phép người dùng set phí tùy ý trước khi swap. Đây là lỗi thiết kế cơ bản mà bất kỳ ai có kinh nghiệm audit đều nhận ra ngay. Dựa trên kinh nghiệm audit của tôi, lỗ hổng này xuất hiện khi đội ngũ phát triển quá tập trung vào tính năng mới mà quên mất các guardrail cơ bản. Họ đã không viết test case cho kịch bản “phí thấp bất thường” – một trong những kiểm tra đầu tiên tôi làm với mọi AMM.
Contrarian Nhiều người cho rằng lỗ hổng bảo mật thường nằm ở reentrancy hoặc oracle manipulation. Nhưng thực tế, các lỗi logic đơn giản như thiếu kiểm tra đầu vào mới là nguyên nhân chính gây mất tiền trong DeFi. Đây là điểm mù: các đội ngũ non‑trẻ thường tập trung vào việc chống lại các tấn công nổi tiếng, nhưng quên rằng kẻ tấn công không cần kỹ thuật cao – chỉ cần đọc contract và tìm một hàm không được bảo vệ. Tôi đã thấy điều này lặp lại nhiều lần từ năm 2017 đến nay. Đọc contract đi, thay vì tin vào tweet.
Takeaway Lỗ hổng không nằm ở oracle hay cơ chế dynamic fee – nó nằm ở việc cho phép bất kỳ ai set phí mà không có giới hạn. Nếu dự án này không vá lỗi trước khi mainnet, họ sẽ mất toàn bộ thanh khoản trong vòng một tuần. Câu hỏi dành cho bạn: lần cuối cùng bạn đọc contract của dự án mà bạn đang stake là khi nào?