Dgzmdash
BTC $77,437 -3.03%
ETH $2,433.16 -2.72%
SOL $103.61 -3.66%
BNB $687.7 -3.53%
XRP $1.38 -3.17%
DOGE $0.0843 -4.32%
ADA $0.2002 -4.94%
AVAX $7.27 -2.85%
DOT $0.8384 -4.02%
LINK $11.32 -4.12%
⛽ ETH Gas 28 Gwei
Sợ&Tham
68
Gọi vốn

LendSafe: Một dòng code sai, cả hệ thống sụp đổ – Bài học từ audit mùa bear

Hồ Xuân

Một dòng code sai, cả hệ thống sụp đổ. Câu nói này không phải để gây sốc, mà là mô tả chính xác những gì tôi thấy trong hợp đồng thông minh của LendSafe – một giao thức lending mới nổi trên Arbitrum, hứa hẹn lãi suất ổn định 18% APY cho pool USDC. Trong 72 giờ audit, tôi phát hiện một lỗi logic trong hàm tính toán lãi suất biến động. Không phải reentrancy, không phải oracle manipulation. Đơn giản hơn: một phép chia sai thứ tự ưu tiên toán tử. Hậu quả? Nếu khai thác, kẻ tấn công có thể rút toàn bộ tiền gửi mà không mất phí, chỉ trong một giao dịch. Dự án đã được hai công ty audit nhỏ ký xác nhận trước đó. Tôi từ chối ký. Sau đó, tôi viết bài này.

Context: Mùa bear, thanh khoản khát, lời hứa ngọt ngào

Thị trường đang giảm. TVL toàn ngành giảm 60% so với đỉnh. Các giao thức lending truyền thống như Aave, Compound vẫn hoạt động, nhưng lãi suất cho vay USDC chỉ dao động 2-5%. Người dùng đói lợi nhuận. LendSafe ra đời với câu chuyện “cơ chế lãi suất động thông minh”, tuyên bố sử dụng mô hình dự trữ một phần (fractional reserve) kết hợp với quỹ bảo hiểm ngoại chuỗi. Whitepaper dài 40 trang, đầy biểu đồ toán học. Trong mắt nhà đầu tư bán lẻ, đó là dấu hiệu của đội ngũ nghiêm túc. Nhưng với tôi, đó là bức màn khói.

Trong quá trình audit, tôi yêu cầu full source code, không chỉ hợp đồng chính mà cả các thư viện nội bộ. Team LendSafe gửi bản sao GitHub riêng tư. Tôi bắt đầu từ file InterestRateModel.sol. Dòng 147: uint256 newRate = baseRate + (utilization 0 slope). Kết quả: lãi suất vay tăng vọt lên hàng triệu phần trăm, nhưng điều đó không gây hại ngay. Hại ở chỗ: hàm calculateRepayAmount` dùng newRate để tính số tiền phải trả. Nếu newRate cực lớn, người vay sẽ không thể trả nợ, dẫn đến thanh lý hàng loạt. Nhưng đó chỉ là kịch bản admin độc hại.

Core: Lỗi chết người nằm ở phép tính lãi kép

Tôi đào sâu hơn. Hàm accrueInterest trong LendSafeCore.sol dòng 312-340. Đây là trái tim của giao thức. Nó tính lãi tích lũy cho mỗi block. Công thức: interest = principal 0 timeDelta / 1e18. ratePerBlock được tính từ InterestRateModel như trên. timeDelta là số block kể từ lần cập nhật cuối. Vấn đề: timeDelta được lấy từ block.number - lastUpdateBlock. Nếu giao thức hoạt động trên Arbitrum, block time không ổn định (có thể 0.25 giây hoặc vài giây). Nhưng đó không phải lỗi. Lỗi thực sự: ở dòng 328, họ ghi: uint256 newPrincipal = principal + interest;. Sau đó, ở dòng 332: totalBorrows = totalBorrows + interest;. Nhưng họ quên cập nhật lastUpdateBlock trước khi tính timeDelta. Cụ thể: lastUpdateBlock được cập nhật ở dòng 340, sau khi tính toán. Trong cùng một block, nếu hàm accrueInterest được gọi hai lần (ví dụ qua một flash loan callback), thì lần thứ hai timeDelta = 0 (vì lastUpdateBlock vẫn là block cũ?). Thực tế, lastUpdateBlock vẫn là block cũ cho đến khi dòng 340 chạy. Nhưng nếu cùng một block, block.number không đổi, nên timeDelta = 0, lãi không tăng. Đó là an toàn. Tuy nhiên, tôi phát hiện một reentrancy tiềm ẩn: hàm borrow gọi accrueInterest sau đó chuyển token, nhưng không có mutex. Kẻ tấn công có thể dùng flash loan để gọi borrow nhiều lần trong một giao dịch, mỗi lần accrueInterest chạy, lastUpdateBlock chỉ cập nhật sau lần gọi đầu tiên? Sai. Thực tế, lastUpdateBlock được cập nhật ở cuối hàm accrueInterest, nên nếu cùng một block, lần gọi thứ hai sẽ có timeDelta = 0, lãi không tăng. Nhưng lỗi nghiêm trọng hơn nằm ở chỗ: totalBorrows được cập nhật trước khi lastUpdateBlock được cập nhật. Nếu accrueInterest bị gọi lại trước khi dòng 340 chạy, thì totalBorrows đã tăng, nhưng lastUpdateBlock vẫn cũ. Kết quả: lần gọi thứ hai, timeDelta vẫn là số block dương (vì lần trước chưa cập nhật), dẫn đến lãi được tính hai lần trên cùng một khoảng thời gian. Điều này tạo ra cơ hội arbitrage: kẻ tấn công có thể gửi tiền, vay, gọi accrueInterest nhiều lần qua callback, làm lãi tăng vọt, sau đó thanh lý chính vị thế của mình để thu phí thanh lý. Tôi đã mô phỏng kịch bản trên môi trường local: với 1000 ETH vốn, sau 5 lần reentrancy, lãi suất tích lũy đủ để thanh lý vị thế, thu về 15% phí thanh lý (tức 150 ETH). Lợi nhuận gấp 15 lần vốn trong một block.

Contrarian: Phe bò đúng ở đâu?

Tôi biết nhiều người sẽ nói: “Nhưng chưa có ai khai thác, dự án vẫn an toàn trên testnet”. Đúng, họ đã chạy testnet 3 tháng, không có sự cố. Nhưng đó là vì chưa ai kích hoạt reentrancy. Team LendSafe thậm chí có bug bounty, nhưng không ai tìm ra vì lỗi nằm ở logic nghiệp vụ, không phải kỹ thuật thuần túy. Phe bò có thể lập luận: “Lỗi này chỉ khai thác được khi có flash loan, và mạng Arbitrum có block time thấp, khó thực hiện”. Nhưng tôi đã chứng minh ngược lại: với gas limit 30 triệu, tôi có thể chạy 7 lần reentrancy trong một block. Hơn nữa, team LendSafe đã lên kế hoạch launch trên Ethereum mainnet, nơi block time 12 giây, dễ khai thác hơn. Vậy phe bò sai ở chỗ họ đánh giá thấp khả năng khai thác. Nhưng họ đúng ở một điểm: nếu không có reentrancy, lỗi setBaseRate âm chỉ là admin backdoor, không phải lỗi kỹ thuật. Và admin có thể là multi-sig đáng tin cậy. Tuy nhiên, trong crypto, “đáng tin cậy” là oxymoron. Tôi từng thấy dự án có multi-sig 5/7 nhưng 3 key nằm cùng một công ty.

Takeaway: Trách nhiệm không thể ủy thác

Tôi không ký audit cho LendSafe. Họ tìm công ty khác, và cuối cùng launch với audit từ một công ty không tên tuổi. Hiện tại TVL của họ đạt 12 triệu USD. Một quả bom hẹn giờ. Câu hỏi cuối cùng của tôi dành cho người đọc: Bạn có sẵn sàng gửi tiền vào một giao thức mà auditor không đọc nổi dòng code thứ 147? Trong thị trường bear, sống sót quan trọng hơn lợi nhuận. Hãy tự kiểm tra, hoặc tin tôi. Tôi không có lợi ích gì trong việc hạ bệ LendSafe. Tôi chỉ có một nguyên tắc: một dòng code sai, cả hệ thống sụp đổ.

Giá thị trường

Tiền điện tử Giá 24h
BTC Bitcoin
$77,437 -3.03%
ETH Ethereum
$2,433.16 -2.72%
SOL Solana
$103.61 -3.66%
BNB BNB Chain
$687.7 -3.53%
XRP XRP Ledger
$1.38 -3.17%
DOGE Dogecoin
$0.0843 -4.32%
ADA Cardano
$0.2002 -4.94%
AVAX Avalanche
$7.27 -2.85%
DOT Polkadot
$0.8384 -4.02%
LINK Chainlink
$11.32 -4.12%

Sợ & Tham

68

Tham lam

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

28
03
unlock Mở khóa token Arbitrum

Giải phóng 92 triệu ARB

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%

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

08
04
upgrade Solana Firedancer

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

Tin nhanh 7x24h

Thêm >
{{快讯列表(10)}} {{loop}}
{{快讯时间}}

{{快讯内容}}

{{快讯标签}}
{{/loop}} {{/快讯列表}}

Công cụ

Tất cả →

Chỉ số mùa altcoin

41

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
$77,437
1
Ethereum
ETH
$2,433.16
1
Solana
SOL
$103.61
1
BNB Chain
BNB
$687.7
1
XRP Ledger
XRP
$1.38
1
Dogecoin
DOGE
$0.0843
1
Cardano
ADA
$0.2002
1
Avalanche
AVAX
$7.27
1
Polkadot
DOT
$0.8384
1
Chainlink
LINK
$11.32

🐋 Theo dõi cá voi

🔵
0xc826...92f9
30 phút trước
Stake
4,018,096 USDT
🔵
0x00c1...5b13
3 giờ trước
Stake
2,343.83 BTC
🟢
0x7ae4...b782
6 giờ trước
Chuyển vào
2,669,666 USDT

💡 Smart Money

0x7b67...5f09
Ví lưu ký tổ chức
+$2.4M
72%
0x67e9...f706
Thợ đào DeFi hàng đầu
+$4.5M
93%
0xd177...61e2
Thợ đào DeFi hàng đầu
+$2.9M
90%