Phân tích sự cố của Velocore

Bài viết này được dịch máy
Xem bản gốc

Vào ngày 2 tháng 6 năm 2024, Velocore đã bị tấn công vào nhóm CPMM của họ, gây ra thiệt hại tài chính khoảng 6,8 triệu đô la. Nguyên nhân gốc rễ của việc khai thác là lỗi logic trong việc tính phí giao dịch trong ConstantProductPool , kết hợp với tràn số nguyên.

Tổng quan

Phân tích khai thác

Trong tài liệu kỹ thuật, Velocore khuyến nghị người dùng tương tác trực tiếp với hợp đồng Vault để thực hiện hành động. Chức năng quan trọng nhất, theo quan điểm của người dùng, là Vault.execute() . Chức năng này cho phép người dùng hoán đổi, Stake, chuyển đổi hoặc bỏ phiếu mà không cần biết địa chỉ của nhóm nội bộ, bộ định tuyến, ETC Hơn nữa, nó hỗ trợ các hoạt động xử lý hàng loạt, cho phép người dùng thực hiện nhiều hành động trong một giao dịch duy nhất.

Cảm ơn bạn đã đọc Verichains! Đăng ký miễn phí để nhận bài đăng mới và ủng hộ công việc của tôi.

Luồng thực thi điển hình cho hoạt động Hoán đổi token như sau:

  1. Người dùng gọi SwapFacet.execute() với một mảng tokenRef và danh sách các hoạt động ( ops ).

  2. Sau đó, SwapFacet sẽ gọi hàm _execute() nội bộ để xử lý các thao tác của người dùng.

    1. _execute() lặp qua ops và xử lý từng hoạt động dựa trên loại của nó.

    2. Nếu hoạt động hiện tại là yêu cầu hoán đổi, _execute() sẽ gọi velocore__execute() của nhóm tương ứng để mô phỏng hoán đổi và trả về delta cân bằng. Sau đó, nó sẽ gọi _verifyAndApplyDelta() để xác minh và áp dụng kết quả.

  3. Sau khi quay lại hàm execute() bên ngoài, nó sẽ kiểm tra số dư của người dùng và xử lý việc chuyển tiền vào hoặc rút tiền từ ví của người dùng.

Có hai loại pool trong Velocore: pool dễ bay hơi (CPMM) và pool ổn định (pool Wombat). Pool bị tấn công là pool dễ bay hơi, vì vậy chúng tôi xem xét việc triển khai của nó trong ConstantProductPool.sol .

Hàm velocore__execute() trong ConstantProductPool chịu trách nhiệm tính toán kết quả hoán đổi và được gọi bởi hợp đồng SwapFacet bất cứ khi nào người dùng khởi tạo hoán đổi trên Velocore. Tuy nhiên, hàm này có một số lỗi:

  1. Missing Caller Validation : velocore__execute() chỉ nên được gọi từ các hợp đồng Vault (chẳng hạn như SwapFacet trong trường hợp này), nhưng xác thực này bị thiếu. Điều này cho phép bất kỳ ai gọi hàm, tạo ra một vectơ tấn công tiềm ẩn.

  2. Không có giới hạn trên cho feeMultiplier : Không có kiểm tra giới hạn trên cho feeMultiplier . Logic cho thấy feeMultiplier tăng lên mỗi lần velocore__execute() được gọi và chỉ đặt lại thành 1e9 khi dấu thời gian Block thay đổi ( Block mã thứ ba). Vì feeMultiplier được sử dụng để tính phí giao dịch ( effectiveFee1e9 trong Block mã đầu tiên), khi feeMultiplier vượt quá 3.33e11, effectiveFee1e9 sẽ ít nhất là 3.33e11 * 3e6 / 1e9 = 1e9 , nghĩa là phí vượt quá 100% . Điều này ảnh hưởng đáng kể đến unaccountedFeeAsGrowth1e18 , dẫn đến những thay đổi trong requestedGrowth1e18 và cuối cùng ảnh hưởng đến số dư của nhóm.

  3. Số học không được kiểm tra : Phép tính unaccountedFeeAsGrowth1e18 được đặt bên trong một Block không được kiểm tra ( Block mã thứ hai). Kết hợp với lỗi thứ hai, biểu thức 1e18 - ((1e18 - k) * effectiveFee1e9) / 1e9 có thể tràn, dẫn đến các hành vi không mong muốn.

Với tất cả thông tin đã cho, chúng ta có thể hiểu được chiến lược của tin tặc:

  1. Thao túng feeMultiplier : Tin tặc đã trực tiếp gọi velocore__execute() nhiều lần để tăng feeMultiplier một cách giả tạo, khiến effectiveFee1e9 vượt quá 100%. Điều này là cần thiết để thực hiện cuộc tấn công tràn số nguyên trong các bước sau. Trong cuộc tấn công thực tế, velocore__execute() đã được gọi ba lần với cùng các đối số. Thông qua thử nghiệm, chúng tôi đã đạt được hiệu ứng tương tự bằng cách chỉ gọi velocore__execute() một lần với các tham số hơi khác nhau. Điều quan trọng cần lưu ý là điều này không ảnh hưởng ngay đến số dư nhóm vì velocore__execute() không thực hiện chuyển khoản; nó chỉ cập nhật feeMultiplier .

  2. Rút hết thanh khoản USDC : Bằng cách tận dụng tính năng Khoản vay nhanh , tin tặc đã cố gắng sử dụng Token của người cung cấp thank khoản (LP Tokens) để rút gần như toàn bộ USDC khỏi nhóm, tạo ra tình trạng khan hiếm USDC và tác động đáng kể đến giá hoán đổi. Trong cuộc tấn công thực tế, tin tặc đã thực hiện ba hoạt động để rút 98% USDC của nhóm mỗi lần. Trong quá trình thử nghiệm, chúng tôi thấy rằng chúng tôi có thể đạt được kết quả tương tự trong một hoạt động duy nhất, mà không có sự khác biệt về kết quả.

  3. Khai thác Integer Underflow : Cuối cùng, hacker thực hiện một lần rút một token đơn lẻ khác, chọn một lượng USDC chính xác kích hoạt một integer underflow, khiến rpow() trả về một giá trị lớn bất thường. Điều này khiến nhóm tính toán sai, trao Token của người cung cấp thank khoản (LP Tokens) cho hacker thay vì thực hiện lệnh rút tiền hợp lệ. Điều này cho phép hacker có đủ Token của người cung cấp thank khoản (LP Tokens) để trả lại số tiền họ đã vay ở các bước trước đó.

Phần kết luận

Mặc dù Velocore đã vượt qua nhiều cuộc kiểm toán, nhưng nó vẫn chứa một số vấn đề có thể bị khai thác kết hợp để tạo ra một cuộc tấn công quy mô lớn. Nguyên nhân gốc rễ của các lỗ hổng này dường như bắt nguồn từ thiết kế hệ thống không phù hợp. Hợp đồng SwapFacet dựa vào logic của ConstantProductPool để cập nhật số dư của nhóm và thực hiện chuyển Token . Tuy nhiên, ConstantProductPool tính toán delta bằng các biến nội bộ của riêng nó (độc lập với SwapFacet ) và chỉ trả về kết quả. Thiết kế này tạo ra sự ngắt kết nối giữa các hợp đồng, dẫn đến hiểu lầm và cuối cùng là khai thác. Để giảm thiểu rủi ro trong tương lai, chúng tôi khuyên Velocore nên cấu trúc lại cơ sở mã của mình để thiết lập logic rõ ràng và mạnh mẽ giữa các thành phần nội bộ.

Nguồn
Tuyên bố từ chối trách nhiệm: Nội dung trên chỉ là ý kiến của tác giả, không đại diện cho bất kỳ lập trường nào của Followin, không nhằm mục đích và sẽ không được hiểu hay hiểu là lời khuyên đầu tư từ Followin.
Thích
Thêm vào Yêu thích
Bình luận