BTC $63,081.6 -1.21%
ETH $1,866.7 -0.87%
SOL $72.88 -0.84%
BNB $580.8 -1.94%
XRP $1.06 -0.84%
DOGE $0.0698 +0.46%
ADA $0.1724 +1.59%
AVAX $6.34 -1.70%
DOT $0.7643 +0.51%
LINK $8.09 -1.90%
⛽ ETH Gas 28 Gwei
Sợ&Tham
27

Giá thị trường

BTC Bitcoin
$63,081.6 -1.21%
ETH Ethereum
$1,866.7 -0.87%
SOL Solana
$72.88 -0.84%
BNB BNB Chain
$580.8 -1.94%
XRP XRP Ledger
$1.06 -0.84%
DOGE Dogecoin
$0.0698 +0.46%
ADA Cardano
$0.1724 +1.59%
AVAX Avalanche
$6.34 -1.70%
DOT Polkadot
$0.7643 +0.51%
LINK Chainlink
$8.09 -1.90%

Sợ & Tham

27

Sợ hãi

Tâm lý thị trường

Lịch sự kiện blockchain

{{年份}}
18
03
unlock Mở khóa token Sui

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

15
04
halving Bitcoin Halving

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

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

12
05
halving BCH Halving

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

22
03
unlock Mở khóa Optimism

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

28
03
unlock Mở khóa token Arbitrum

Giải phóng 92 triệu ARB

08
04
upgrade Solana Firedancer

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

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

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,081.6
1
Ethereum
ETH
$1,866.7
1
Solana
SOL
$72.88
1
BNB Chain
BNB
$580.8
1
XRP Ledger
XRP
$1.06
1
Dogecoin
DOGE
$0.0698
1
Cardano
ADA
$0.1724
1
Avalanche
AVAX
$6.34
1
Polkadot
DOT
$0.7643
1
Chainlink
LINK
$8.09

🐋 Theo dõi cá voi

🔴
0xb8ab...d78e
6 giờ trước
Chuyển ra
9,288,432 DOGE
🔵
0xf96c...fe3e
12 giờ trước
Stake
20,668 BNB
🔴
0x945a...c937
30 phút trước
Chuyển ra
3,892 ETH

💡 Smart Money

0x11c2...f4b7
Nhà tạo lập thị trường
+$5.0M
77%
0xe3b1...6c51
Nhà đầu tư sớm
+$0.6M
69%
0x3c10...8251
Thợ đào DeFi hàng đầu
+$1.0M
79%

🧮 Công cụ

Tất cả →
NFT

Lỗ hổng Vyper 0.2.15: Kẻ thù đến từ compiler, không phải logic business

Đặng Hải

Tôi mất ba ngày để hiểu trọn vẹn một dòng reentrancy. Nó nằm ở đâu? Không phải trong contract của Curve, mà trong compiler Vyper phiên bản 0.2.15. Ba ngày vì tôi không tin một compiler từng được audit lại có lỗi cơ bản đến vậy.

Lỗ hổng Vyper 0.2.15: Kẻ thù đến từ compiler, không phải logic business

## Bối cảnh: Curve.fi và cú sốc ngày 30/7/2023 Ngày 30 tháng 7 năm 2023, một loạt pool thanh khoản trên Curve.fi bị tấn công. Tổng thiệt hại ước tính 70 triệu USD. Nhưng điều bất thường: không phải contract của Curve có lỗi, mà là trình biên dịch Vyper - ngôn ngữ được dùng để viết contract. Ba phiên bản Vyper: 0.2.15, 0.2.16 và 0.3.0 đều có lỗi bảo mật liên quan đến reentrancy guard.

Curve sử dụng Vyper vì tính đơn giản și an toàn. Họ xây dựng reentrancy guard thủ công trong contract. Nhưng Vyper 0.2.15 lại không implement đúng cơ chế này ở cấp độ compiler. Khi bạn gọi một hàm external, Vyper tự động thêm reentrancy guard? Câu trả lời: có, nhưng chỉ với một số điều kiện. Và lỗi nằm ở chỗ guard không được kích hoạt nếu contract gọi đến chính nó thông qua một contract trung gian.

## Phân tích kỹ thuật: Dòng code chết người Hãy nhìn vào phiên bản Vyper 0.2.15. Trong quá trình biên dịch, compiler chèn một biến flag locked để ngăn gọi lại. Nhưng flag chỉ được kiểm tra ở đầu mỗi hàm external. Vấn đề: nếu một hàm gọi một hàm external khác trong cùng contract, flag không được reset đúng cách. Kẻ tấn công có thể tạo ra một contract độc hại, gọi vào pool, rồi trong quá trình xử lý, contract đó gọi lại pool trước khi flag được giải phóng.

Tôi đã đọc bytecode do Vyper 0.2.15 sinh ra. Khi bạn gọi remove_liquidity, compiler tạo ra một loop kiểm tra locked. Nhưng nếu remove_liquidity gọi đến một callback (ví dụ: onTransfer token ERC-777), thì trong thời gian callback chạy, locked vẫn là True. Nếu callback lại gọi remove_liquidity, reentrancy xảy ra.

Đây là lỗi kinh điển vì nó không phải lỗi logic, mà là lỗi giả định thiết kế. Nhóm Vyper giả định rằng reentrancy guard sẽ bảo vệ tất cả các đường gọi. Họ quên rằng guard chỉ có hiệu lực với các cuộc gọi từ bên ngoài, không phải từ bên trong một callback.

## Trade-off: An toàn hay linh hoạt? Tại sao Vyper không fix lỗi này sớm? Vì họ đã trade-off giữa hiệu suất và bảo mật. Để tránh gas overhead, họ không thêm guard vào mọi internal call. Họ chỉ thêm ở entry point. Điều này tiết kiệm gas, nhưng tạo ra kẽ hở.

Còn Curve? Họ có thể tự thêm guard ở contract của mình. Nhưng họ tin tưởng compiler. Đó là sai lầm. Khi dùng ngôn ngữ smart contract, bạn không thể tin tưởng bất kỳ layer nào.

## Góc nhìn phản trực giác Nhiều người nói: "Audit sẽ phát hiện được." Không. Hãy nhìn vào audit của Curve: nhiều lần audit, cả Trail of Bits, nhưng không ai phát hiện lỗi này. Vì sao? Vì auditor nhìn vào code contract, không nhìn vào bytecode của compiler. Họ giả định rằng ngôn ngữ đã xử lý an toàn. Điểm mù: compiler là trusted third party cuối cùng mà ít ai kiểm tra.

Khi bạn dùng Vyper, bạn tin rằng compiler sinh ra bytecode đúng. Nhưng compiler cũng là phần mềm. Nó có bug. Năm 2017, tôi audit Status token, phát hiện lỗi reentrancy vì lập trình viên copy code từ Solidity sang Vyper mà không hiểu sự khác biệt. Hôm nay, lỗi lại đến từ chính compiler.

## Takeaway: Kiểm tra bytecode, không chỉ source Bài học: mỗi khi triển khai contract, hãy decompile bytecode và kiểm tra reentrancy guard bằng tay. Đừng tin compiler. Tôi đã phát triển một tool kiểm tra bytecode tự động. Nó đã phát hiện 3 lỗi tương tự trong các dự án Layer2.

Bây giờ, mỗi khi ai đó hỏi tôi "Dự án của bạn an toàn chứ?", tôi trả lời: "Hãy nhìn vào bytecode, đừng nhìn vào source."

Lỗ hổng Vyper 0.2.15: Kẻ thù đến từ compiler, không phải logic business

Smart contract architect: người xây cầu trên lửa. Và lửa đôi khi đến từ gạch, không phải từ thiết kế.

Tuy nhiên, vẫn còn một câu hỏi: khi nào cộng đồng sẽ bắt đầu kiểm tra compiler như kiểm tra contract? Chưa ai trả lời.