Không deploy chính là deploy vụng về.
Vào 3h sáng ngày 14 tháng 6, một giao thức cross-chain chưa được kiểm toán đã mất 8 triệu USD từ pool thanh khoản. Kẻ tấn công không brute force private key, không khai thác oracle drift – chỉ đọc source code trên Etherscan mà tôi đã đọc từ 2 tháng trước. 0x7f…c3a2 là ví deployer, và nó vẫn còn rỗng cho đến ngày hôm nay.
Bối cảnh: năm 2025, cross-chain vẫn là mảnh đất màu mỡ cho rug pull và hack. Sau Dencun, phí giảm 90% nhưng UX cross-rollup vẫn là một mớ hỗn độn. Các đội dev thường copy code từ các dự án thành công, thay vài biến, rồi deploy mà không hiểu cơ chế bảo mật. Dự án này – tạm gọi là BridgeX – tự nhận là “giải pháp cross-chain siêu nhanh”, huy động 20 triệu TVL trong 3 tuần từ các nhà đầu tư retail. Họ không publish audit, nhưng có một dòng commit trên GitHub: “fix critical bug – remove admin backdoor”. Dòng đó được push vào lúc 23h tối thứ Sáu, khi không ai kiểm tra.
Core: Tôi đã đọc bytecode của BridgeX từ ngày thứ hai sau khi mainnet launch. Hàm finalizeTransfer trong contract BridgeLogic.sol có 3 modifier: onlyValidator, onlyGuardian, và onlyPauser. Quét qua 50 dòng đầu, thấy gọi _verifySignatures(… ). Nhưng dòng 112: require(… , “SIG_FAILED”). Phía trên dòng đó, một biến _executed[txHash] được set thành true trước khi kiểm tra chữ ký. Đây là lỗi “check-effects-interaction” cổ điển: ghi trạng thái trước khi verify.

Kẻ tấn công đã gọi finalizeTransfer với chữ ký giả – nhưng điều đó không quan trọng vì contract đã chấp nhận giao dịch trước khi kiểm tra. Họ rút 8 triệu USDC chỉ với 3 giao dịch, mỗi giao dịch 100k gas. Tôi đã gửi issue lên GitHub của BridgeX vào ngày 12 tháng 5, kèm PoC code. Đến ngày 1 tháng 6 (hai tuần trước hack) tôi nhận được reply: “We will fix in next upgrade.” Họ không bao giờ deploy bản fix.

Contrarian: Phe bò của BridgeX sẽ nói: “Nó được kiểm toán không chính thức bởi cộng đồng, và kẻ tấn công chỉ là may mắn.” Sai. Cộng đồng audit không thể thay thế một báo cáo chuyên nghiệp. Và không phải may mắn – chính sự thiếu trách nhiệm khi deploy mà không kiểm tra lại flow mới. Thậm chí, nếu team không set _executed sớm, lỗi vẫn tồn tại ở chỗ signature verification yếu: họ dùng ECDSA từ OpenZeppelin nhưng allow mọi signer trong whitelist mà không kiểm tra nonce hoặc expiration. Điều đó có nghĩa là dù không có lỗi check-effects, bất kỳ ai có quyền truy cập vào một trong 5 validator keys (có thể mua từ dark web) đều có thể rút tiền. Team đã chọn sai vấn đề để tập trung.

Takeaway: Một dòng revert là đủ. Code không biết nói dối, nhưng người deploy thì có. Các nhà đầu tư retail cần học đọc ít nhất 20 dòng source code trước khi deposit. Và nếu team không fix lỗi trong 2 tuần sau khi được báo cáo, đó là tín hiệu. Họ không thiếu thời gian – họ thiếu trách nhiệm.