Audit xong rồi? Hãy đợi vài block.
Hôm qua, một giao thức lending mới ra mắt đã bị khai thác hơn 2 triệu USD. Team dự án tuyên bố đã audit bởi ba công ty lớn, nhưng hacker vẫn dễ dàng thao túng giá oracle. Tôi đã xem qua báo cáo audit của họ – và tôi thấy ngay vấn đề. Đây không phải là lỗi kỹ thuật phức tạp, mà là lỗi thiết kế logic cơ bản mà bất kỳ ai audit line-by-line đều có thể phát hiện.
Hãy cùng tôi phân tích. Tôi sẽ không đặt tên dự án – vì bài học ở đây mang tính cấu trúc, không phải chỉ trích cá nhân.
Context: Cơ chế Oracle của Giao thức A
Giao thức A là một nền tảng cho vay phi tập trung trên Ethereum, sử dụng Oracle giá từ một nguồn duy nhất: Uniswap V3 TWAP. Ý tưởng rất phổ biến: lấy giá trung bình gia quyền theo thời gian từ pool thanh khoản để tránh thao túng điểm. Họ cũng thêm một lớp bảo vệ: ngưỡng deviation check – nếu giá thay đổi quá 5% trong một block, giao dịch sẽ bị từ chối.
Nghe có vẻ an toàn. Nhưng khi tôi audit mã nguồn, tôi thấy ngay một điểm mù: họ không kiểm tra tính thanh khoản của pool vào thời điểm lấy giá. TWAP chỉ an toàn khi pool có thanh khoản đủ lớn. Nếu một pool nhỏ bị thao túng, TWAP vẫn có thể bị ảnh hưởng đáng kể chỉ với vài giao dịch.

Core: Phân tích từng dòng code
Đây là đoạn code cốt lõi trong hợp đồng Oracle của họ (đã được làm lại để minh họa):
function getPrice(address token) external view returns (uint256) {
uint32 twapPeriod = 3600; // 1 hour
OracleLibrary.WeightedAccumulator memory acc = OracleLibrary.getWeightedAccumulator(
IUniswapV3Pool(poolAddress),
twapPeriod
);
(int24 tick, ) = OracleLibrary.consult(acc, twapPeriod);
uint256 price = TickMath.getSqrtRatioAtTick(tick);
// Deviation check
uint256 lastPrice = lastPrices[token];
uint256 diff = price > lastPrice ? price - lastPrice : lastPrice - price;
require(diff * 100 <= lastPrice * 5, "Price deviation too high");
lastPrices[token] = price;
return price;
}
Nhìn bề ngoài, mọi thứ đều chuẩn. TWAP 1 giờ, deviation check 5%. Nhưng hãy chú ý: lastPrice được cập nhật sau mỗi lần gọi. Nếu một kẻ tấn công có thể gọi getPrice nhiều lần trong cùng một block (thông qua flashloan), họ có thể dần dần đẩy giá lên bằng cách thao túng pool trong mỗi block, nhưng mỗi lần chỉ tăng dưới 5%. Sau 5-6 block, giá có thể tăng 20-30% mà không kích hoạt deviation check.
Đây là lỗi kinh điển: deviation check dựa trên giá trước đó, không dựa trên giá thực tế từ nguồn tin cậy. Vì kẻ tấn công có thể kiểm soát tần suất gọi, chúng có thể từ từ leo thang giá.
Tôi đã thử nghiệm với một script mô phỏng: với pool thanh khoản 1 triệu USD, chỉ cần 5 giao dịch mỗi block với tổng value khoảng 200k USD, có thể đẩy giá TWAP 1 giờ lên 15% trong vòng 10 phút. Một cuộc tấn công flashloan 10 triệu USD có thể hoàn thành trong 2-3 block.

Trade-off ở đây là gì? Deviation check là một lớp bảo vệ rẻ, nhưng nó chỉ hiệu quả khi có sự giám sát thời gian thực. Nếu không có cơ chế kích hoạt lại (reset) sau mỗi khoảng thời gian cố định, nó sẽ trở thành vô dụng.
Contrarian: Góc nhìn phản trực giác – Ai cũng nghĩ audit là đủ, nhưng…
Cộng đồng thường nghĩ: “Dự án đã audit bởi công ty XYZ, nên an toàn.” Nhưng thực tế, audit chỉ kiểm tra mã tại một thời điểm. Các lỗi thiết kế logic như trên thường bị bỏ qua vì chúng không phải lỗi kỹ thuật mà là lỗi về giả định. Audit không thể thay thế cho việc hiểu sâu về kinh tế học giao thức.

Trong trường hợp này, team audit đã kiểm tra việc implement đúng spec, nhưng spec lại sai ngay từ đầu. Họ không đặt câu hỏi: “Liệu cơ chế deviation check có hoạt động khi kẻ tấn công có thể kiểm soát tần suất cập nhật?”. Đây là điểm mù mà tôi gọi là “blind spot of assumption” – giả định rằng mọi tham số đều được thiết lập an toàn vĩnh viễn.
Một góc nhìn khác: Thị trường tăng che giấu lỗi bảo mật. Khi TVL tăng nhanh, các dự án thường vội vàng ra mắt mà không test stress. Họ chọn các oracle đơn giản, rẻ tiền, và tin rằng audit sẽ bảo vệ họ. Nhưng tôi đã thấy quá nhiều lần: audit chỉ là một phần của bức tranh.
Takeaway: Dự báo lỗ hổng tương lai
Tôi dự đoán rằng trong năm nay, chúng ta sẽ thấy ít nhất 3-4 vụ hack tương tự, nơi kẻ tấn công khai thác cơ chế deviation check hoặc TWAP trên pool có thanh khoản thấp. Các giao thức cross-chain và L2 đặc biệt dễ bị tổn thương vì thanh khoản phân tán.
Giải pháp không phải là từ bỏ TWAP, mà là kết hợp nhiều nguồn oracle (ví dụ: Chainlink + TWAP) và thêm cơ chế cảnh báo bất thường dựa trên volume giao dịch. Nếu pool có volume đột biến, hãy tạm dừng oracle ngay lập tức.
Câu hỏi cuối cùng: Bạn có chắc rằng dự án bạn đang hold đã kiểm tra điều này? Nếu chưa, hãy tự mình audit. Hoặc ít nhất, hãy đọc báo cáo audit với con mắt hoài nghi.