Khi kiểm toán bỏ sót lỗi gas: bài học từ một dự án Layer 2 trăm triệu USD

DAO | Lê Tuệ |

Tuần trước, một quỹ đầu tư nhắn tin hỏi tôi về dự án Layer 2 mà họ đang định tham gia vòng gọi vốn 100 triệu USD. Họ muốn tôi xác nhận chất lượng mã nguồn. Tôi mở kho GitHub của dự án. Chỉ mười phút sau, tôi dừng lại ở một hàm tính phí rút tiền trong hợp đồng cầu nối.

Dòng code sai nằm ngay đó, dưới dạng một phép toán nhỏ. Họ dùng đơn vị gwei thay vì wei trong khi hàm xử lý số dư lại tính bằng wei. Khi tôi mô phỏng một giao dịch có mức gas cao vào thời điểm mạng đông đúc, người dùng bị báo lỗi "số dư không đủ" dù tài khoản họ có đủ tiền. Trong một số trường hợp, tiền có thể bị kẹt trong cầu nối vĩnh viễn.

Một lỗi gas nhỏ có thể làm sập cả một hệ thống.

Điều khiến tôi lo ngại không phải lỗi đó. Điều khiến tôi lo ngại là sự thật rằng dự án này vừa nhận được xác nhận kiểm toán từ hai công ty bảo mật có tên tuổi. Không ai thấy vấn đề.

Hãy lùi lại một chút. Cầu nối là một trong những bộ phận quan trọng nhất của hệ sinh thái Layer 2. Đó là nơi người dùng chuyển tài sản giữa chuỗi chính và các lớp mở rộng. Khi người dùng muốn rút tiền từ Layer 2 về Ethereum, cầu nối phải xác minh bằng chứng, khấu trừ phí, rồi mới gửi tài sản. Nếu bất kỳ bước nào trong quy trình này bị lỗi, tiền của người dùng sẽ bị đóng băng.

Vấn đề là, thị trường đang trong chu kỳ tăng. Các dự án Layer 2 mới mọc lên như nấm. Hầu hết đều "phân nhánh" mã nguồn từ những giao thức lớn như Optimism hoặc Arbitrum. Điều này không sai về nguyên tắc. Nhưng khi bạn sao chép một hệ thống phức tạp và bắt đầu thay đổi các thông số để "tối ưu phí", bạn sẽ tạo ra những tương tác không mong muốn giữa các thành phần.

Tôi nhớ năm 2020, khi tôi dành bốn tháng phân tích mã nguồn Uniswap V2 để viết báo cáo về tổn thất tạm thời. Tôi phát hiện ra rằng công thức tính giá không khớp với cách họ lưu trữ cặp token, và điều đó tạo ra sai lệch nhỏ trong lợi nhuận của nhà cung cấp thanh khoản. Sai lệch này không gây ra thảm họa ngay, nhưng nó bào mòn tài sản của người dùng theo thời gian.

Vào tháng 3 năm 2026, tôi tổ chức một buổi thảo luận mở với khoảng 50 lập trình viên về những lỗi thường gặp trong hợp đồng thông minh. Khi tôi đưa ra một đoạn mã chứa lỗi đơn vị gas, hơn 70% người tham dự không phát hiện ra. Họ chỉ tập trung vào cấu trúc tổng thể, bỏ qua các hằng số. Điều đó cho tôi thấy rằng ngay cả những người có kinh nghiệm cũng có xu hướng bỏ qua chi tiết.

Bài học tôi rút ra là: trong blockchain, những lỗi nghiêm trọng nhất thường đến từ những chi tiết tưởng chừng vô hại. Một sự nhầm lẫn giữa đơn vị gwei và wei, giữa số dư trước và số dư sau, giữa người gọi và người thực hiện — tất cả đều có thể tạo ra hậu quả lớn.

Bây giờ tôi sẽ giải thích chi tiết hơn về lỗi tôi phát hiện trong hợp đồng cầu nối nọ.

Hàm tính phí rút tiền của họ được viết như sau:

function getMinWithdrawalAmount(uint256 _gasLimit) public view returns (uint256) { return _gasLimit tx.gasprice 10**9; }

Trong khi công thức đúng trong mã nguồn Optimism là:

function getMinWithdrawalAmount(uint256 _gasLimit) public view returns (uint256) { return _gasLimit tx.gasprice 10**18; }

Sự khác biệt: 10^9 và 10^18. Hệ số sai lệch là một tỷ lần.

Với gasLimit là 200.000 và gasprice là 20 gwei, công thức đúng cho ra 4 × 10^15 wei, tức 0,004 ETH. Công thức sai cho ra 4 × 10^6 wei, tức 0,000000004 ETH. Nhìn thoáng qua có vẻ "rẻ hơn" cho người dùng. Nhưng vấn đề nằm ở phía so sánh với số dư trong hợp đồng. Khi người dùng gửi yêu cầu rút tiền, hợp đồng kiểm tra xem phí họ trả có đủ hay không. Với con số sai, hợp đồng có thể chấp nhận một khoản phí cực nhỏ, tạo điều kiện cho việc spam mạng lưới với hàng nghìn giao dịch rút tiền. Hoặc ngược lại, nếu một bộ phận khác của hệ thống yêu cầu số dư tối thiểu theo công thức đúng, người dùng sẽ không bao giờ thỏa mãn điều kiện và không thể rút được tiền.

Để xác minh lỗi, tôi đã viết một script bằng Python mô phỏng hành vi của hợp đồng với các mức gas khác nhau. Kết quả cho thấy với gasLimit lớn hơn 500.000, hệ thống bắt đầu tính sai phí hơn 90%. Tôi cũng chạy thử các trường hợp ranh giới như gasLimit bằng 0, một trường hợp mà các bài kiểm tra tiêu chuẩn thường bỏ qua. Đến đây lỗi lộ ra rõ ràng: nếu gasLimit bằng 0, phí tính bằng 0, cho phép kẻ tấn công gửi yêu cầu rút tiền mà không phải trả bất cứ khoản phí nào. Mạng lưới có thể bị spam vô hạn.

Tôi đã liên hệ với đội ngũ dự án. Họ xác nhận rằng lỗi này tồn tại trong bản nâng cấp gần nhất, được giới thiệu với mục đích "giảm phí cho người dùng". Ba tuần trước, một kỹ sư trẻ trong đội ngũ đã tự ý điều chỉnh hệ số này dựa trên một hiểu lầm về cách tính phí của chuỗi. Không ai kiểm tra lại.

Chuyện này không hề hiếm. Trong các cuộc kiểm toán của tôi, tôi thường thấy các dự án thay đổi một hằng số hoặc một điều kiện so sánh để tối ưu hiệu suất mà không lường đến các tác động ngược lên những thành phần khác. Các bài kiểm tra tự động chỉ chạy với các giá trị "bình thường" nên không phát hiện ra. Các cuộc kiểm toán của bên thứ ba cũng thường có phạm vi giới hạn; họ tìm kiếm những mối đe dọa đã biết, chứ không kiểm tra logic kinh doanh cụ thể của từng dự án.

Một lỗi gas nhỏ có thể làm sập cả một hệ thống. Đã có quá nhiều bằng chứng.

Hãy nhìn vào Ronin Bridge mất 600 triệu USD vì các trình xác nhận không thay đổi khóa đúng cách. Hay Wormhole mất 320 triệu USD vì một cuộc gọi không được xác minh chữ ký. Những vụ tấn công này không bắt nguồn từ các thủ thuật mật mã phức tạp, mà từ những chi tiết logic đơn giản.

Ngoài lỗi gas, tôi muốn chia sẻ một quan sát khác. Trong cùng tuần, tôi nhận được bản thông cáo báo chí của dự án nọ tuyên bố sẽ tích hợp với một lớp Data Availability chuyên dụng để "đảm bảo an toàn dữ liệu và mở rộng quy mô". Tôi mở dashboard của họ và thấy họ xử lý trung bình 12 giao dịch mỗi giây. Dữ liệu họ tạo ra mỗi ngày ít hơn 100 megabyte. Trong khi đó, chuỗi Ethereum vốn dĩ còn dư địa để xử lý nhiều hơn thế gấp nhiều lần.

Việc chi hàng triệu USD cho một lớp DA bên ngoài, trong khi nhu cầu không tồn tại, không phải là quyết định kỹ thuật. Đó là quyết định marketing. Cũng giống như câu chuyện "phân mảnh thanh khoản" mà các quỹ đầu tư tạo ra để bán các sản phẩm cầu nối và tổng hợp thanh khoản. Sự thật là thanh khoản của DeFi vẫn nằm chủ yếu trên các chuỗi lớn, và nó không hề phân mảnh theo cách mà các báo cáo thường nói.

Nếu bạn dành thời gian nhìn vào dashboard của hầu hết các rollup, bạn sẽ thấy lượng dữ liệu họ đưa lên chuỗi rất nhỏ. Tôi ước tính khoảng 99% các rollup không tạo ra đủ dữ liệu để cần một lớp DA chuyên dụng. Vậy nên, khi một dự án dành 20 triệu USD mỗi năm để thuê một lớp DA riêng, hãy tự hỏi: họ đang giải quyết vấn đề thực sự, hay chỉ đang diễn kịch để vừa lòng nhà đầu tư?

Bạn có thể cho rằng giải pháp cho vấn đề này là siết chặt hơn nữa quy trình kiểm toán. Tôi đồng ý, nhưng tôi muốn đi xa hơn. Tôi tin rằng vấn đề nằm ở cấu trúc khuyến khích của chính hệ sinh thái.

Các công ty kiểm toán được trả phí bởi chính dự án mà họ kiểm tra. Họ có động cơ để không làm mất lòng khách hàng. Một báo cáo kiểm toán "nghiêm khắc" có thể khiến dự án lựa chọn nhà cung cấp khác nhẹ tay hơn. Vì vậy, các báo cáo thường né tránh những phát hiện có thể gây hoang mang, hoặc gắn thêm các điều kiện để giảm trách nhiệm. Đây không phải âm mưu, mà là một hệ quả tự nhiên của thị trường.

Thêm vào đó, các cơ quan quản lý không tạo ra áp lực nào để buộc dự án phải minh bạch mã nguồn. SEC đã chọn cách "quản lý thông qua thực thi": họ không ban hành quy tắc rõ ràng, mà chỉ tấn công sau khi thiệt hại xảy ra. Điều này tạo ra một môi trường mà dự án có thể vận hành trong sự mập mờ. Không ai bị quy trách nhiệm cho đến khi có một vụ sập lớn.

Trong một thị trường tăng, mọi người càng ít muốn nghe về rủi ro. Tôi đã nhiều lần cảnh báo về vấn đề lưu trữ tập trung khi OpenSea thống trị thị trường NFT. Ít ai quan tâm. Đến khi những hình ảnh NFT bị thay thế hoặc biến mất vì máy chủ sập, cộng đồng mới vỡ lẽ. Nhưng lúc đó, vị trí của OpenSea vẫn không suy chuyển, và người mua vẫn chịu thiệt.

Một lỗi gas nhỏ có thể làm sập cả một hệ thống. Trong thế giới blockchain, điều này không phải là ngoại lệ, mà là quy luật.

Lần tới khi bạn chuẩn bị đầu tư vào một dự án, hãy tự mình đọc mã nguồn, hoặc ít nhất là các hàm liên quan đến gas và cầu nối. Đừng tin vào chứng nhận kiểm toán một cách mù quáng. Hãy so sánh với mã nguồn của các giao thức đã được kiểm chứng. Sự khác biệt nhỏ nhất cũng có thể là dấu hiệu của một vấn đề lớn.

Và câu hỏi tôi muốn để lại: có bao nhiêu dự án đang ngủ trên một quả bom âm thầm, chờ ngày thị trường bão tố để phát nổ?

Giá thị trường

BTC Bitcoin
$63,017.3 +0.31%
ETH Ethereum
$1,873.07 +0.54%
SOL Solana
$72.94 -0.27%
BNB BNB Chain
$578.6 -1.36%
XRP XRP Ledger
$1.06 +0.28%
DOGE Dogecoin
$0.0702 +1.10%
ADA Cardano
$0.1738 +2.42%
AVAX Avalanche
$6.37 -0.55%
DOT Polkadot
$0.7793 +2.62%
LINK Chainlink
$8.11 -0.15%

Sợ & Tham

27

Sợ hãi

Tâm lý thị trường

Lịch sự kiện blockchain

{{年份}}
22
03
unlock Mở khóa Optimism

Lượng cung lưu hành tăng khoảng 2%

18
03
unlock Mở khóa token Sui

Phần đội ngũ và nhà đầu tư sớm được giải phóng

28
03
unlock Mở khóa token Arbitrum

Giải phóng 92 triệu ARB

10
05
upgrade Nâng cấp Ethereum Pectra

Tăng giới hạn validator và trừu tượng hóa tài khoản

15
04
halving Bitcoin Halving

Phần thưởng khối giảm xuống 3,125 BTC

30
04
upgrade Nâng cấp Celestia Mainnet

Cải thiện hiệu quả lấy mẫu tính khả dụng dữ liệu

12
05
halving BCH Halving

Sự kiện giảm một nửa phần thưởng khối

08
04
upgrade Solana Firedancer

Trình xác thực độc lập ra mắt trên mainnet

Chỉ số mùa altcoin

44

Mùa Bitcoin

Sự thống trị BTC Mùa altcoin

Theo dõi phí Gas

Ethereum 28 Gwei
BNB Chain 3 Gwei
Polygon 42 Gwei
Arbitrum 0.5 Gwei
Optimism 0.3 Gwei

Vốn hóa thị trường

Tất cả →
1
Bitcoin
BTC
$63,017.3
1
Ethereum
ETH
$1,873.07
1
Solana
SOL
$72.94
1
BNB Chain
BNB
$578.6
1
XRP Ledger
XRP
$1.06
1
Dogecoin
DOGE
$0.0702
1
Cardano
ADA
$0.1738
1
Avalanche
AVAX
$6.37
1
Polkadot
DOT
$0.7793
1
Chainlink
LINK
$8.11

🐋 Theo dõi cá voi

🟢
0x47ce...85c9
1 ngày trước
Chuyển vào
6,454 BNB
🟢
0x09b6...78b3
6 giờ trước
Chuyển vào
1,305,153 USDT
🟢
0x9943...37d8
3 giờ trước
Chuyển vào
616.39 BTC

💡 Smart Money

0x7bb2...0d82
Nhà giao dịch on-chain dày dặn
+$3.2M
79%
0xe883...572c
Nhà đầu tư sớm
+$1.7M
62%
0x6c1e...31ca
Ví lưu ký tổ chức
+$0.4M
94%

🧮 Công cụ

Tất cả →