Với sự phát triển nhanh chóng của hệ sinh thái DeFi, Complex Finance V2, với tư cách là một trong những công ty tiên phong trong lĩnh vực này, đã thu hút được một lượng lớn người dùng với mô hình cho vay sáng tạo. Tuy nhiên, bất kỳ ứng dụng phân tán phức tạp nào cũng phải đối mặt với các mối đe dọa bảo mật tiềm ẩn, đặc biệt khi nó liên quan đến dòng tiền trị giá hàng triệu hoặc thậm chí hàng trăm triệu đô la. Do đó, điều đặc biệt quan trọng là phải tiến hành kiểm tra bảo mật toàn diện và chi tiết đối với Complex Finance V2 và các dự án phân nhánh của nó. Hướng dẫn này nhằm mục đích cung cấp cho các nhà phát triển, nhà nghiên cứu bảo mật và những người đam mê DeFi hướng dẫn kiểm tra bảo mật chi tiết để giúp mọi người xác định và ngăn chặn các rủi ro tiềm ẩn hiệu quả hơn.
1. Tổng quan về dự án
Hợp chất tài chính V2 là một nền tảng cho vay mở được xây dựng trên chuỗi khối Ethereum, cho phép người dùng gửi nhiều mã thông báo cơ bản ERC-20 khác nhau và kiếm lãi từ chúng, đồng thời cho phép người dùng vay mã thông báo trên thị trường dưới hình thức thanh toán lãi. Bằng cách đưa ra khái niệm "thị trường lãi suất", nó hiện thực hóa việc quản lý nhóm quỹ phi tập trung và cơ chế điều chỉnh lãi suất tự động.
2. Phân tích cấu trúc dự án
Các thành phần kiến trúc cốt lõi của Complex Finance V2 bao gồm:
- Comptroller: Kiểm soát toàn bộ logic hệ thống, chẳng hạn như tính toán lãi suất, duy trì trạng thái tài khoản, v.v.
- cToken: Mã thông báo tùy chỉnh triển khai tiêu chuẩn ERC-20 và thể hiện quyền và lợi ích của người dùng trong hệ thống.
- InterestRateModel: Mô hình tính toán lãi suất tiền gửi và lãi vay.
- PriceOracle: Cung cấp lời tiên tri về giá tài sản.
- Quản trị: Chịu trách nhiệm về các chức năng liên quan đến quản trị cộng đồng.
2.1 Bộ điều khiển
Hợp đồng Comptroller là hệ thống thần kinh trung ương của Complex Finance V2, chịu trách nhiệm điều phối hành vi của từng phiên bản cToken. Các trách nhiệm chính là:
- Quản lý danh sách thị trường và xác định thị trường nào đang hoạt động.
- Thực hiện các hoạt động kiểm tra khác nhau cho các hoạt động trên nhiều thị trường, chẳng hạn như kiểm tra tình trạng vị trí của người dùng, v.v.
- Thiết lập và cập nhật các thông số chung như giới hạn vay, yếu tố tài sản thế chấp, ngưỡng thanh lý, v.v.
2.2 cToken
Mỗi mã thông báo ERC-20 được hỗ trợ có một phiên bản cToken tương ứng (tức là hợp đồng CErc20 / CEther), được sử dụng để xử lý tất cả các tương tác giữa mã thông báo và dự án. Ngoài việc triển khai chức năng chuyển mã thông báo cơ bản, mỗi cToken còn bổ sung thêm một số chức năng dành riêng cho Hợp chất, chẳng hạn như cho vay, tích lũy lãi và phân phối phần thưởng. Vì vậy, chúng ta có thể coi cToken là chứng chỉ của người dùng để gửi tài sản trên Hợp chất và là lối vào để người dùng thực hiện các hoạt động cho vay.
Khi người dùng gửi mã thông báo tài sản cơ bản vào hợp đồng, mã thông báo cToken tương ứng có thể được tạo ra. Tỷ lệ trao đổi giữa cToken và tài sản cơ bản được tính theo công thức sau:
Lưu ý: khoản vay thể hiện số tiền vay, tiền mặt thể hiện số dư của quỹ và dự trữ thể hiện dự trữ. Lãi suất vay được xác định theo lãi suất sử dụng, lãi suất tiền gửi được xác định theo lãi suất vay.
Người dùng thường thực hiện các hoạt động cho vay token ở các thị trường khác nhau bằng cách tương tác với các hợp đồng cToken khác nhau:
2.3 Mô hình lãi suất
Hợp đồng InterestRateModel xác định phương pháp tính lãi suất. Các thị trường khác nhau có thể sử dụng các loại mô hình lãi suất khác nhau để phù hợp với khẩu vị rủi ro và nhu cầu thanh khoản tương ứng.
Có hai mô hình lãi suất chính được sử dụng trên thị trường Hợp chất V2, một là loại đường thẳng và hai là loại điểm uốn.
Công thức tính lãi suất vay vốn theo mô hình đường thẳng như sau:
Công thức tính tỷ lệ sử dụng vốn như sau:
Lãi suất tiền gửi thay đổi tuyến tính với lãi suất đi vay:
Tỷ lệ sử dụng tăng dần có nghĩa là số tiền trong quỹ đang giảm dần. Khi đạt đến một mức cao nhất nhất định, có thể khiến người dùng không thể gửi và vay bình thường. Để cố gắng tránh tình trạng này, Hợp chất đã giới thiệu mô hình lãi suất thứ hai - loại điểm uốn.
Công thức tính lãi suất vay bước ngoặt như sau:
Khi tỷ lệ sử dụng đạt đến một mức cao nhất nhất định, lãi suất vay và lãi suất tiền gửi sẽ tăng lên rất nhiều ngay lập tức, khuyến khích người dùng gửi nhiều hơn và vay ít hơn, từ đó kiểm soát tỷ lệ sử dụng trong một phạm vi thích hợp. thường khi tỷ lệ sử dụng đạt 80%).
2.4 GiáOracle
Hợp đồng PriceOracle chịu trách nhiệm thu thập thông tin về giá thị trường bên ngoài và chuyển đổi nó thành các giá trị được hệ thống sử dụng nội bộ, điều này rất quan trọng để tính toán chính xác giá trị vị thế của người dùng.
2.5 Cơ chế quản trị và mô hình khuyến khích
Hợp chất giới thiệu một cơ chế quản trị độc đáo cho phép người dùng nắm giữ mã thông báo quản trị (COMP) tham gia bỏ phiếu cho các quyết định quan trọng, chẳng hạn như thay đổi một số tham số nhất định hoặc thêm loại tài sản mới. Bằng cách phát hành mã thông báo quản trị (COMP), Hợp chất khuyến khích người dùng tích cực tham gia vào các hoạt động của nền tảng và trao phần thưởng cho những người đóng góp. Để biết chi tiết, vui lòng tham khảo kho lưu trữ mã và tài liệu chính thức của Hợp chất. (https://docs.comound.finance/v2/; https://github.com/comound-finance/comound-protocol)
3. Quá trình tương tác
Tiếp theo, chúng tôi sử dụng một ví dụ đơn giản để minh họa quy trình tương tác chung của người dùng trên Complex Finance V2:
3.1 Quy trình gửi và rút tiền
Nếu người dùng Alice cần gửi 1 WBTC vào Hợp chất thì cô ấy sẽ gọi hàm đúc tiền của hợp đồng cWBTC để thực hiện gửi tiền. Hợp đồng này kế thừa hợp đồng cToken. Đầu tiên, nó sẽ gọi hàm lũy tích nội bộ thông qua hàm mintInternal để cập nhật lãi suất vay và lãi suất gửi, sau đó gọi mintFresh để thực hiện các hoạt động truyền cụ thể.
Hàm mintFresh sẽ gọi bên ngoài hàm mintAllowed của hợp đồng Comptroller để kiểm tra xem thị trường hiện tại có cho phép gửi tiền hay không, sau đó chuyển 1 WBTC của người dùng vào hợp đồng thông qua hàm doTransferIn, sau đó đúc số lượng mã thông báo cToken tương ứng cho người dùng dựa trên tỷ giá hối đoái mới nhất tại thời điểm đó (giả sử tỷ giá hối đoái mới nhất hiện tại là 0,1 thì Alice sẽ nhận được 10 token cWBTC).
Nếu Alice quyết định đổi khoản tiền gửi của mình trong tương lai, cô ấy có thể đổi cWBTC trở lại WBTC bằng cách gọi hàm quy đổi. Tỷ giá hối đoái có thể đã thay đổi (giả sử là 0,15), có nghĩa là Alice có thể đổi 1,5 WBTC, trong đó. 0,5 WBTC là thu nhập từ lãi.
3.2 Quy trình vay và trả nợ
Trước tiên, Alice cần gọi hàm enterMarkets của hợp đồng Comptroller để đặt cWBTC của cô ấy ở trạng thái có thể được sử dụng làm tài sản thế chấp và sau đó cô ấy có thể vay tiền.
Giả sử Alice chọn cho vay 70 USDC. Vì hệ số thế chấp của WBTC là 0,75, Alice có thể cho vay tới 75% giá trị của WBTC, vì vậy số tiền này sẽ không vượt quá số tiền vay tối đa của cô ấy.
Lưu ý: Để tránh rủi ro bị thanh lý, Alice nên giữ lại một khoản đệm và không sử dụng hết hạn mức vay của mình.
Alice gọi hàm vay của hợp đồng cUSDC, trước tiên hàm này gọi hàm lũy tích bên trong hàm loanInternal để cập nhật lãi suất vay và lãi suất tiền gửi, sau đó gọi loanFresh để thực hiện các hoạt động vay cụ thể.
Sau khi kiểm tra giá trị vị thế của người dùng thông qua chức năng loanAllowed của hợp đồng Comptroller, dữ liệu khoản vay trước tiên được ghi lại và sau đó mã thông báo được chuyển đến người dùng thông qua chức năng doTransferOut.
Sau khi kiểm tra giá trị vị thế của người dùng thông qua chức năng loanAllowed của hợp đồng Comptroller, dữ liệu khoản vay trước tiên được ghi lại và sau đó mã thông báo được chuyển đến người dùng thông qua chức năng doTransferOut.
Nếu Alice cần trả nợ, cô ấy có thể tự mình trả nợ bằng cách gọi hàm returnBorrow của hợp đồng cUSDC hoặc để người khác gọi hàm returnBorrowBehalf để trả nợ thay cô ấy.
3.3 Quá trình thanh lý
Nếu giá WBTC giảm đáng kể khiến giá trị tài sản thế chấp của Alice giảm xuống dưới 75% số tiền vay của cô ấy, vị thế khoản vay của Alice sẽ bị thanh lý.
Người thanh lý bên ngoài (chẳng hạn như Bob) có thể gọi hàm thanh lý LiquidateBorrow trong hợp đồng cUSDC để giúp Alice trả hết một phần nợ của mình. Trước tiên, nó sẽ cập nhật lãi suất của cUSDC và cToken thế chấp được sử dụng để trả nợ cùng lúc thông qua chức năng LiquidateBorrowInternal, sau đó gọi LiquidateBorrowFresh để thực hiện các hoạt động thanh lý cụ thể.
Sau khi kiểm tra xem có cho phép thanh lý thông qua chức năng LiquidateBorrowAllowed của hợp đồng Comptroller hay không, trước tiên, chức năng hoàn trảBorrowFresh sẽ được gọi để chuyển USDC vào hợp đồng để trả nợ và cập nhật dữ liệu khoản vay của người được thanh lý. Sau đó, hàm LiquidateCalculateSeizeTokens của hợp đồng Comptroller được gọi để tính toán số lượng tài sản thế chấp mà Bob có thể nhận được giá trị tương ứng của Alice dựa trên giá trị thanh lý. Cuối cùng, chức năng thu giữ của hợp đồng cToken (chẳng hạn như cWBTC) trong thị trường tài sản thế chấp được chỉ định sẽ được sử dụng. để chuyển cTokens cho Bob và Alice.
Mở liên kết này để xem phiên bản độ nét cao của hình ảnh trên. Nhấp để đọc văn bản gốc để chuyển trực tiếp: https://www.figma.com/board/POkJlvKlWWc7jSccYMddet/Compound-V2?node-id=0-1&node -type=canvas.
Bob trả hết một phần khoản vay của Alice (ví dụ: 20 USDC) và do đó nhận được giá trị tài sản thế chấp tương ứng của Alice (chẳng hạn như WBTC). Đồng thời, Bob cũng có thể nhận được ưu đãi thanh lý bổ sung (giả định là 5%). Kết quả cuối cùng là Bob nhận được WBTC trị giá 21 USDC (khoản vay 20 USDC + ưu đãi thanh lý 1 USDC).
4. Danh sách kiểm tra lỗ hổng bảo mật
4.1 Lỗ hổng làm tròn do thị trường trống rỗng
4. Danh sách kiểm tra lỗ hổng bảo mật
4.1 Lỗ hổng làm tròn do thị trường trống rỗng
Nếu cToken là một thị trường trống (nghĩa là không có người dùng nào cho vay trên thị trường), vì giá trị của ExchangeRate trong hàm ExchangeRateStoredInternal phụ thuộc vào số lượng token tài sản cơ sở tương ứng với hợp đồng, nên một lượng lớn tài sản cơ bản có thể được chuyển giao vào hợp đồng cToken để thao túng giá của cToken.
Do đó, bạn có thể sử dụng một lượng nhỏ cToken để cho vay một lượng lớn mã thông báo khác, sau đó gọi chức năng chuộc lại của cToken để rút mã thông báo tài sản cơ bản. Khi tính toán số tiền quy đổi, số lượng cToken cần được khấu trừ dẫn đến kết quả ít hơn nhiều so với dự kiến (gần một nửa) do làm tròn số chia.
Giả sử rằng số lượng cToken được giữ tại thời điểm này là 2 (cũng là tổng nguồn cung) và ExchangeRate được nâng lên 25.015.031.908.500.000.000.000.000.000 sau khi thao tác và số lượng mã thông báo tài sản cơ bản cần được đổi là 50.030.063.815. Khi đó, số lượng cToken dự kiến sẽ được khấu trừ sẽ là:
Tuy nhiên, số lượng cToken được tính toán thực tế là:
Tuy nhiên, số lượng cToken được tính toán thực tế là:
Do đó, cuối cùng chỉ cần thanh lý một số lượng rất nhỏ cToken để có được số lượng lớn mã thông báo tài sản được vay từ các thị trường khác.
Bạn có thể tham khảo giao dịch bị hack của dự án Complex fork Hundred Finance do lỗ hổng này: https://optimistic.etherscan.io/tx/0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451
Điểm kiểm tra: Trong quá trình kiểm tra, bạn cần chú ý xem phương pháp tính tỷ giá hối đoái có dễ bị thao túng hay không và phương pháp làm tròn có phù hợp hay không. Đồng thời, bạn có thể đề nghị nhóm dự án đúc một lượng nhỏ. cToken ngay sau khi thị trường mới được tạo ra để tránh trường hợp thị trường trống rỗng và bị thao túng.
4.2 Lỗ hổng Reentrancy do token ERC677/ERC777 gây ra
ERC677/ERC777 là phần mở rộng của hợp đồng ERC20 và tương thích với tiêu chuẩn giao thức của token ERC20. Các mã thông báo này cho phép trong quá trình chuyển, nếu địa chỉ nhận là hợp đồng, chức năng gọi lại của địa chỉ nhận (chẳng hạn như transferAndCall hoặc tokenReceured) sẽ được kích hoạt.
Trong phiên bản cũ của mã Complex Finance V2, khi người dùng vay tiền trên thị trường cToken, các token đã vay sẽ được chuyển ra ngoài trước và sau đó dữ liệu khoản vay sẽ được ghi lại.
Nếu mã thông báo được người dùng cho mượn là mã thông báo ERC677/ERC777 có chức năng gọi lại, thì một hợp đồng độc hại nhận mã thông báo có thể được tạo để nhập lại chức năng mượn thông qua chức năng gọi lại để vay lại, bởi vì việc vay của người dùng trong thời gian lần vay cuối cùng là Dữ liệu vẫn chưa được tính, vì vậy mã thông báo có thể được cho vay lại vào thời điểm này bằng cách vượt qua thành công quá trình kiểm tra sức khỏe của tài khoản.
Bạn có thể tham khảo giao dịch của dự án Complex fork Hundred Finance bị hack do lỗ hổng này: https://blockscout.com/xdai/mainnet/tx/0x534b84f657883ddc1b66a314e8b392feb35024afdec61dfe8e7c510cfac1a098
Điểm kiểm tra: Logic vay đã được sửa trong phiên bản mới nhất của mã Hợp chất V2. Thay vào đó, dữ liệu vay được ghi lại trước và sau đó mã thông báo đã mượn sẽ được chuyển ra ngoài. Trong quá trình kiểm tra, cần chú ý xem liệu mã liên quan cho chức năng cho vay có tuân thủ đặc tả CEI (Kiểm tra-Hiệu ứng-Tương tác) hay không và cần xem xét tác động của mã thông báo với chức năng gọi lại.
4.3 Rủi ro thao túng giá do cơ chế oracle không phù hợp
4.3 Rủi ro thao túng giá do cơ chế oracle không phù hợp
Vì Composite Finance áp dụng mô hình cho vay có tài sản thế chấp quá mức nên số lượng token mà người dùng có thể cho vay sẽ phụ thuộc vào việc liệu giá trị của tài sản thế chấp có đủ hay không.
Do đó, nếu cơ chế cung cấp giá của oracle được dự án sử dụng khi tính toán giá trị tài sản thế chấp dễ bị thao túng thì sẽ dễ dàng cho vay nhiều token hơn dự kiến.
Ví dụ: trong trường hợp dự án ngã ba phức hợp Lodestar Finance bị hack, cách mà nhà tiên tri thu được giá của mã thông báo plvGLP thế chấp trước tiên là chia số lượng mã thông báo PLVGLP trong hợp đồng plvGLP (totalAssets) cho tổng nguồn cung plvGLP ( TotalSupply) tính toán tỷ giá hối đoái, sau đó nhân tỷ giá hối đoái với giá của mã thông báo GLP để tính giá của mã thông báo plvGLP.
plvGLP có chức năng quyên góp cho phép người dùng quyên góp sGLP để đúc các token PLSGLP tương ứng cho hợp đồng token plvGLP.
Do đó, kẻ tấn công trước tiên có thể sử dụng các khoản vay nhanh để tạo một số lượng lớn vị thế thế chấp plvGLP trên thị trường Lodestar Finance, sau đó sử dụng các khoản vay nhanh để đúc một lượng lớn sGLP trên GMX, sau đó sử dụng chức năng quyên góp để đúc các mã thông báo PLSGLP cho hợp đồng plvGLP để tăng giá trị tổng tài sản. Khi tổng tài sản tăng lên, tỷ giá hối đoái của plvGLP sẽ lớn hơn, khiến giá của token plvGLP tăng ngay lập tức và nhanh chóng, cho phép các token khác được cho vay trên thị trường ngoài mong đợi.
Bạn có thể tham khảo giao dịch bị hack của Lodestar Finance: https://arbiscan.io/tx/0xc523c6307b025ebd9aef155ba792d1ba18d5d83f97c7a846f267d3d9a3004e8c
Cũng cần lưu ý rằng Composite Finance hoặc các dự án phân nhánh của nó cũng sẽ sử dụng các nhà tiên tri ngoài chuỗi như ChainLink hoặc CoinBase để thu được giá tài sản thế chấp. Nếu bạn gặp phải những biến động nghiêm trọng của thị trường, có thể có chênh lệch giá giữa giá ngoài chuỗi và giá trên chuỗi, gây nguy hiểm cho an ninh tài chính của dự án.
Ví dụ: giá của mã thông báo LUNA giảm mạnh nhanh chóng vì lý do thị trường và các giao thức phân nhánh của Hợp tác tài chính Venus Protocol và Blizz Finance đều sử dụng các oracle của Chainlink làm nguồn cung cấp giá để tính giá trị tài sản thế chấp. Trong số đó, giá thấp nhất của mã thông báo LUNA (. minAnswer) được mã hóa cứng với giá trị 0,10 USD.
Khi giá của mã thông báo LUNA giảm xuống dưới 0,1 đô la (ví dụ: 0,001 đô la), bất kỳ ai cũng có thể mua một lượng lớn LUNA theo giá thị trường và sử dụng nó làm tài sản thế chấp (trị giá 0,10 đô la) để cho vay các tài sản khác từ nền tảng.
Điểm kiểm tra: Trong quá trình kiểm tra, bạn cần chú ý xem cơ chế cung cấp giá oracle được sử dụng khi tính toán giá trị của tài sản thế chấp có dễ bị bên ngoài thao túng hay không. Bên dự án nên sử dụng nhiều nguồn giá để tiến hành đánh giá toàn diện. tránh được những rủi ro do một nguồn giá duy nhất gây ra.
4.4 Rủi ro thao túng tỷ giá hối đoái do nhiều mã thông báo điểm vào
Có một chức năng gọi là scannerToken trong mã của Hợp chất, được sử dụng để cho phép người dùng vô tình chuyển mã thông báo vào hợp đồng có thể rút các mã thông báo này. Mã của phiên bản cũ như sau. Chức năng này có một kiểm tra bảo mật quan trọng: tham số mã thông báo được truyền vào không thể là mã thông báo tài sản cơ bản của hợp đồng.
Tuy nhiên, nếu có nhiều hợp đồng điểm vào cho mã thông báo tài sản cơ bản của một thị trường cToken nhất định (cùng một số dư cơ bản có thể được truy cập thông qua nhiều địa chỉ hợp đồng và các tương tác bên ngoài ảnh hưởng đến số dư của tất cả các điểm vào, thì đây là một đại lý sớm giống như model) , kẻ tấn công có thể gọi hàm scannerToken để chuyển mã thông báo nội dung cơ bản trong hợp đồng bằng cách chuyển vào một hợp đồng điểm vào khác với hợp đồng cơ bản.
Lấy TUSD làm ví dụ bên dưới. Nó có hai hợp đồng điểm vào. Hợp đồng điểm vào phụ 0x8dd5fbce sẽ chuyển tiếp bất kỳ cuộc gọi nào (chẳng hạn như chuyển khoản hoặc số dư) tới hợp đồng chính, có nghĩa là việc tương tác với bất kỳ một trong các hợp đồng sẽ ảnh hưởng đến cả hai hợp đồng. Dữ liệu số dư trong (nghĩa là hai hợp đồng khác nhau có chung dữ liệu số dư).
Tại thời điểm này, giả sử rằng địa chỉ mã thông báo cơ bản được đặt trên thị trường là địa chỉ hợp đồng chính của TUSD, thì chúng ta có thể sử dụng địa chỉ hợp đồng điểm nhập phụ 0x8dd5fbce làm tham số mã thông báo đến khi gọi hàm scannerToken và địa chỉ (mã thông báo) có thể được kiểm tra thành công! = cơ bản, sau đó hợp đồng sẽ chuyển tất cả các mã thông báo tài sản cơ bản TUSD đến địa chỉ quản trị viên.
Tỷ giá hối đoái của TUSD/cTUSD sẽ bị ảnh hưởng bởi số lượng token tài sản cơ bản TUSD trong hợp đồng cTUSD khi tất cả TUSD được chuyển đến địa chỉ của quản trị viên, tỷ giá hối đoái của TUSD/cTUSD sẽ giảm mạnh ngay lập tức. Tại thời điểm này, kẻ tấn công có thể kiếm lợi bằng cách thanh lý những người dùng khác với tỷ giá hối đoái rất thấp hoặc hoàn trả ít hơn số lượng token dự kiến sau khi vay.
Điều đáng nói là phiên bản mới nhất của mã Hợp chất V2 đã thêm xác minh quyền vào chức năng quétToken để đảm bảo rằng hợp đồng chỉ có thể được gọi bởi vai trò người quản lý và đã loại bỏ tất cả các thị trường có nhiều mã thông báo điểm vào.
Điểm kiểm tra: Trong quá trình kiểm tra, liên quan đến chức năng chuyển mã thông báo trong hợp đồng, cần xem xét tác động của kịch bản có nhiều mã thông báo điểm vào đối với dự án. mã thông báo hoặc xác minh việc chuyển mã thông báo trước và sau Liệu số lượng mã thông báo tài sản cơ bản trong hợp đồng có thay đổi hay không và kiểm tra quyền của các chức năng liên quan.
4.5 Vấn đề tương thích giữa phiên bản cũ và mới của mã hợp đồng
Nếu trong dự án phân nhánh của Composite Finance V2, mã của hợp đồng cốt lõi được phân nhánh bằng phiên bản mới của mã Composite Finance V2, nhưng một số hợp đồng khác tương tác với nó lại sử dụng phiên bản mã cũ thì khả năng tương thích có thể xảy ra.
Ví dụ: giá trị trả về của hàm getBorrowRate lấy lãi suất vay trong hợp đồng InterestRateModel được sử dụng bởi phiên bản cũ của cToken là hai giá trị loại uint, nhưng trong phiên bản mới của hàm InterestRateModel, hàm getBorrowRate chỉ trả về một uint giá trị kiểu.
Tuy nhiên, trong dự án phân nhánh Complex Finance V2 Percent Finance, nhóm dự án đã sử dụng phiên bản cũ của mã hợp đồng cToken, trong khi hợp đồng InterestRateModel sử dụng phiên bản mới. Điều này khiến hàm AccuInterest trong cToken không thành công khi gọi hàm getBorrowRate. Chức năng tích lũy lãi suất được sử dụng trong cả việc rút tiền và cho vay, điều này cuối cùng khiến cho chức năng rút tiền và cho vay không thể tiến hành bình thường và số tiền trong hợp đồng bị khóa hoàn toàn.
Điểm kiểm tra: Trong quá trình kiểm tra, bạn cần chú ý xem những thay đổi trong giao diện hợp đồng, biến trạng thái, chữ ký hàm và sự kiện trong mã cập nhật có làm gián đoạn hoạt động bình thường của hệ thống hiện có hay không, đảm bảo tính nhất quán của tất cả các phiên bản mã hợp đồng cập nhật hoặc đảm bảo mã được cập nhật tương thích với các phiên bản mã cũ hơn.
4.6 Sự cố mã hóa cứng do triển khai đa chuỗi
Trong mã của Composite Finance V2, hằng số blockPerYear biểu thị số khối ước tính được sản xuất mỗi năm. Giá trị của nó được mã hóa cứng trong hợp đồng mô hình lãi suất thành 2102400. Điều này là do thời gian sản xuất khối trung bình của Ethereum là 15 giây.
Tuy nhiên, thời gian tạo khối của các chuỗi khác nhau không nhất thiết phải giống nhau và số lượng khối gần đúng được sản xuất trong năm cũng không nhất thiết phải giống nhau. Nếu dự án Composite fork được triển khai trên các chuỗi khác, nhưng các giá trị được mã hóa cứng không được sửa đổi theo điều kiện của các chuỗi khác nhau, thì phép tính lãi suất cuối cùng có thể vượt quá mong đợi. Điều này là do giá trị của blockPerYear sẽ ảnh hưởng đến giá trị của baseRatePerBlock và multiplierPerBlock, còn baseRatePerBlock và multiplierPerBlock cuối cùng sẽ ảnh hưởng đến lãi suất vay.
Ví dụ: thời gian tạo khối của chuỗi BSC là 3 giây, khi đó số khối ước tính cho cả năm (blocksPerYear) sẽ là 10.512.000. Nếu giá trị của blockPerYear không được sửa đổi trước khi triển khai, lãi suất vay được tính toán cuối cùng sẽ cao gấp 5 lần so với dự kiến.
Điểm kiểm tra: Trong quá trình kiểm tra, cần chú ý xem các hằng số hoặc biến được mã hóa cứng trong hợp đồng dự án có gây ra kết quả không mong muốn theo đặc điểm của các chuỗi khác nhau hay không. Bên dự án nên sửa đổi chính xác giá trị của chúng. theo các điều kiện của các chuỗi khác nhau.
khác
Ngoài những mối quan tâm chính được đề cập ở trên, các dự án phân nhánh của Hợp chất V2 thường sửa đổi một số logic nghiệp vụ dựa trên thiết kế của nhóm dự án, chẳng hạn như thêm mã để tương tác với các giao thức bên ngoài của bên thứ ba. Điều này cần được đánh giá trong quá trình kiểm toán dựa trên các yêu cầu thiết kế và logic kinh doanh cụ thể của nó xem liệu nó có ảnh hưởng đến mô hình và dự án cho vay cốt lõi của chính Complex Finance V2 hay không.
viết ở cuối
Chúng tôi hy vọng rằng sổ tay kiểm tra bảo mật này dành cho Complex Finance V2 và dự án Fork của nó có thể giúp mọi người hiểu rõ hơn và đánh giá tính bảo mật của các hệ thống phức tạp như vậy trong quá trình kiểm tra. Với bản cập nhật lặp đi lặp lại của công nghệ, sổ tay hướng dẫn này cũng sẽ được cập nhật và cải tiến.
[1] https://github.com/YAcademy-Residents/defi-fork-bugs
[1] https://github.com/YAcademy-Residents/defi-fork-bugs
[2] https://medium.com/chainsecurity/trueusd-comound-vulnerability-bc5b696d29e2
[3] https://github.com/code-423n4/2023-05-venus-findings/issues/559
[4] https://learnblockchain.cn/article/2593
[5] https://github.com/comound-finance/comound-protocol
Tác giả Cửu Cửu |
Biên tập viên Liz |
Tất cả bình luận