Phân tích lỗ hổng cân bằng

lý lịch

Vào ngày 22 tháng 8, Balancer chính thức thông báo rằng họ đã nhận được báo cáo về lỗ hổng nghiêm trọng ảnh hưởng đến nhiều nhóm V2 Boost. Chỉ 1,4% TVL bị ảnh hưởng. Nhiều nhóm đã bị đình chỉ và người dùng được thông báo rút LP thanh khoản càng sớm càng tốt. [1] [2]

Vào ngày 27/8, hệ thống SlowMist MistEye đã phát hiện một giao dịch tấn công bị nghi ngờ khai thác lỗ hổng Balancer. [3]

Vì nhóm không thể bị tạm dừng và một số tiền vẫn bị ảnh hưởng bởi cuộc tấn công nên các quan chức của Balancer một lần nữa nhắc nhở người dùng lấy LP trong nhóm bị ảnh hưởng. [4] Sau đó, Balancer chính thức công bố thông tin chi tiết về lỗ hổng được tiết lộ vào tháng 8 trên Medium. [5] , nhóm bảo mật SlowMist đã xem xét nó, chi tiết như sau:

Giới thiệu

Các quan chức của Balancer chỉ đơn giản chỉ ra trong tiết lộ của họ rằng vấn đề lần này là việc làm tròn nhóm tuyến tính đi xuống và nguồn cung ảo của nhóm có thể kết hợp đã khiến bptSupply bằng 0. Đầu tiên chúng ta cùng tìm hiểu ngắn gọn nội dung của giao thức Balancer liên quan đến lỗ hổng này.

Balancer V2 Vault

Cân bằng V2 [6] Giao thức này là giao thức tạo lập thị trường tự động phi tập trung (AMM) dựa trên Ethereum, đại diện cho một khối xây dựng linh hoạt cho tính thanh khoản có thể lập trình. Thành phần cốt lõi của nó là hợp đồng Vault, hợp đồng này duy trì hồ sơ của tất cả các nhóm và quản lý việc hạch toán và chuyển mã thông báo, thậm chí bao gồm cả việc đóng gói và giải nén ETH gốc. Nói cách khác, Vault được triển khai để tách biệt việc quản lý và kế toán mã thông báo khỏi logic nhóm.

Có bốn giao diện trong Vault, đó là joinPool, exitPool, swap và batchSwap (tham gia, thoát và hoán đổi là các lệnh gọi riêng biệt và không có sự kết hợp nào trong một lệnh gọi). Một trong những tính năng nổi bật là batchSwap, có thể thực hiện nhiều trao đổi nguyên tử giữa nhiều nhóm và kết nối đầu ra của một sàn giao dịch với đầu vào của một nhóm khác (GiveIn và GiveOut). Hệ thống cũng giới thiệu các giao dịch hoán đổi sét [7] , tương tự như khoản vay nhanh nội bộ.

Bể tuyến tính Bể bơi tuyến tính

Để cải thiện hiệu quả sử dụng vốn của LP cũng như vấn đề chi phí cong vênh và không cong vênh cao, Balancer đã ra mắt nhóm tuyến tính như một giải pháp trong V2, do đó giới thiệu mã thông báo BPT (ERC20 Balancer Pool Token).

hồ bơi tuyến tính [8] Bao gồm mã thông báo chính (tài sản cơ bản), mã thông báo được bao bọc (mã thông báo được bao bọc) và mã thông báo BPT, tài sản và các đối tác được bao bọc của chúng có lợi nhuận được trao đổi thông qua tỷ giá hối đoái đã biết. Tỷ lệ mã thông báo được bao bọc càng cao thì lợi suất và hiệu quả sử dụng vốn của nhóm càng cao. Trong quá trình warp, hệ số tỷ lệ thường được sử dụng để đảm bảo rằng các mã thông báo khác nhau được tính toán với độ chính xác như nhau.

Nhóm có thể kết hợpCó thể kết hợp

Tất cả các nhóm Balancer đều là các nhóm tổng hợp có chứa các mã thông báo khác và bản thân nhóm này cũng có các mã thông báo riêng. Trong số đó, tiền tệ BPT đề cập đến mã thông báo nhóm cân bằng ERC20, là nền tảng của tất cả các nhóm. Người dùng có thể tự do kết hợp mã thông báo BPT trong các nhóm khác để đổi quà. Việc quy đổi luôn bao gồm một nhóm và hai mã thông báo: GiveIn và GiveOut. In có nghĩa là gửi mã thông báo thành phần và nhận BPT, trong khi Out có nghĩa là gửi BPT và nhận mã thông báo thành phần. Nếu bản thân BPT là một token thành phần thì nó có thể được trao đổi như các token khác. Việc triển khai như vậy tạo thành một đường dẫn Hoán đổi hàng loạt đơn giản giữa các tài sản cơ bản và mã thông báo trong nhóm bên ngoài. Người dùng có thể sử dụng BPT để trao đổi lấy các tài sản cơ bản của nhóm tuyến tính. Đây cũng là Balancer Boosted Pool. [9] Sự thành lập.

Thông qua sự kết hợp trên, nhóm kết hợp của Balancer được hình thành. Nhóm ổn định tổng hợp bb-a-USD bao gồm ba nhóm tuyến tính, đồng thời gửi thanh khoản nhàn rỗi đến giao thức bên ngoài (Aave). Ví dụ: bb-a-DAI là một nhóm tuyến tính chứa DAI và waDAI (aDAI được bao bọc). Khi người dùng cần hoán đổi hàng loạt (chẳng hạn như đổi USDT thành DAI), ví dụ về đường dẫn trao đổi như sau:

  1. Trong nhóm tuyến tính USDT, đổi USDT lấy bb-a-USDT (nhập nhóm tuyến tính USDT);

  2. Trong bb-a-USD, bb-a-USDT được đổi lấy bb-a-DAI (trao đổi giữa BPT tuyến tính);

  3. Trong nhóm tuyến tính DAI, bb-a-DAI được đổi thành DAI (thoát khỏi nhóm tuyến tính DAI).

Sau khi hiểu sơ qua những kiến thức tiên quyết trên, chúng ta vào link phân tích lỗ hổng.

phân tích

Vào ngày 27 tháng 8, nhóm bảo mật SlowMist đã nhận được thông tin nhận dạng từ hệ thống MistEye rằng một lỗ hổng Balancer bị nghi ngờ đã bị khai thác ngoài tự nhiên. buôn bán [3] như sau:

Kẻ tấn công lần đầu tiên vay 300.000 USDC từ AAVE thông qua khoản vay nhanh. Sau đó, hoạt động hoán đổi hàng loạt của Vault được gọi để thực hiện tính toán trao đổi mã thông báo BPT thông qua nhóm ổn định có thể kết hợp bb-a-USD. Cuối cùng, 94.508 USDC được đổi lấy 59.964 bb-a-USDC, 68.201 bb-a-DAI và 74.280 bb-a-USDT. Cuối cùng, mã thông báo BPT thu được sẽ thoát khỏi nhóm thông qua exitPool của hợp đồng Vault để đổi lấy tài sản cơ bản, hoàn trả khoản vay nhanh và rời khỏi thị trường với lợi nhuận khoảng 108.843,7 USD.

Có thể thấy, mấu chốt của cuộc tấn công này nằm ở batchSwap, và chính xác thì điều gì đã xảy ra trong batchSwap? Chúng ta hãy xem xét kỹ hơn.

Trong toàn bộ quá trình batchSwap, kẻ tấn công trước tiên đã đổi USDC trong nhóm bb-a-USDC, sau đó trao đổi mã thông báo BPT, đổi bb-a-USDC lấy bb-a-DAI, bb-a-USDT và USDC. Cuối cùng, token chính cơ bản USDC được đổi lấy bb-a-USDT. Nói cách khác, bb-a-USDC, với tư cách là mã thông báo BPT chính, đóng vai trò là mã thông báo thành phần của GiveOut và GiveIn.

Ở bước đầu tiên, kẻ tấn công trao đổi mã thông báo BPT lấy mã thông báo chính USDC trong nhóm tuyến tính bb-a-USDC với hệ số tỷ lệ cố định và số tiền tăng lên sẽ được ghi vào bptBalance trong nhóm. Nhưng sau lần trao đổi onSwap thứ hai, chúng tôi nhận thấy rằng giá trị moneyOut của USDC được trao đổi là 0 trong cùng một quá trình trao đổi. Tại sao lại thế này?

Tìm hiểu sâu hơn về hàm onSwap, chúng tôi thấy rằng trong quá trình này, độ chính xác sẽ được xử lý về mức danh nghĩa và hệ số tỷ lệ của mã thông báo tương ứng sẽ được tính toán. Khi hàm _downscaleDown được gọi tiếp theo, moneyOut sẽ được làm tròn xuống. Nếu số lượngOut và chia tỷ lệFactors [indexOut] Sự khác biệt giữa các giá trị là lớn và giá trị được tính toán của _downscaleDown bằng 0.

Điều đó có nghĩa là, khi chúng tôi sử dụng mã thông báo BPT để đổi mã thông báo chính, nếu moneyOut quá nhỏ, giá trị trả về sẽ được làm tròn xuống 0 và giá trị này nhỏ hơn 1e12 được tính bằngscaleFactors. Tuy nhiên, số lượng bb-a-USDC đến từ moneyIn vẫn sẽ được thêm vào số tiền ảo bptBalance và hoạt động này sẽ làm tăng số dư trong nhóm bb-a-USDC, có thể được coi là sự bổ sung đơn phương của bb -a-USDC thanh khoản.

Sau đó, bằng cách sử dụng các đặc điểm của nhóm ổn định có thể kết hợp, thông qua chuyển đổi lẫn nhau giữa các mã thông báo BPT, trước tiên hãy trao đổi bb-a-USDC lấy các mã thông báo BPT khác. Để thực hiện quy trình trao đổi này, bạn có thể kết hợp đường dẫn gọi sau của nhóm ổn định: bb-a-DAI onSwap -> _swapGivenIn -> _onSwapGivenIn. Đầu tiên, thay thế bb-a-USDC bằng bb-a-DAI và bb- a-USDT theo trình tự. Không giống như các nhóm tuyến tính trực tuyến, các nhóm ổn định có thể kết hợp yêu cầu cập nhật bộ nhớ đệm của tỷ giá hối đoái trước khi thực hiện các hoạt động onSwap. Từ mã, chúng ta có thể thấy rằng trong nhóm kết hợp, onSwap trước tiên sẽ xác định xem tỷ giá hối đoái của mã thông báo được lưu trong bộ nhớ đệm có cần được cập nhật hay không.

Sau lần trao đổi trước, số lượng bb-a-USDC đã thay đổi và tổng số tiền thực sau khi danh nghĩa hóa thông qua _toNominal là tổng số dư 994.010.000.000 và nguồn cung cấp mã thông báo BPT ảo là 20.000.000.000. Có thể tính toán rằng tỷ giá hối đoái được cập nhật gần gấp 45 lần tỷ giá hối đoái ban đầu của nhóm tuyến tính trước đó là 1.100.443.876.587.504.549, tức là 49.700.500.000.000.000.000.

Sau đó, bb-a-USDC được đổi lấy USDC trong nhóm tuyến tính. Tuy nhiên, lần trao đổi này giống với lần trao đổi thứ hai, điều này một lần nữa khiến cho moneyOut được làm tròn xuống 0 và đường dẫn trao đổi vẫn giống như trước.

Lần trao đổi tiếp theo là đảo ngược USDC thành bb-a-USDC và đường dẫn trao đổi là onSwap -> onSwapGivenIn -> _swapGivenMainIn. Trong quá trình này, chúng tôi nhận thấy rằng khi tính toán số tiền Ra cần đổi, việc tính toán nguồn cung ảo dựa trên sự chênh lệch giữa tổng nguồn cung của mã thông báo BPT đã đổi và số tiền còn lại trong nhóm là 0.

Điều này là do bptSupply bằng 0 và hàm _toNominal được gọi trực tiếp khi tính toán BPT Out và lệnh gọi của đường dẫn này làm cho tỷ lệ trao đổi của USDC với bb-a-USDC gần bằng 1:1.

Tóm tắt

batchSwap kết nối đầu ra của trao đổi của một nhóm với đầu vào của một nhóm khác (tokenIn và tokenOut) thông qua nhiều giao dịch hoán đổi nguyên tử giữa nhiều nhóm và trao đổi USDC lấy mã thông báo BPT. Trong đợt Hoán đổi hàng loạt này, không có hoạt động chuyển mã thông báo thực tế nào xảy ra nhưng số tiền trao đổi cuối cùng được xác nhận bằng cách ghi lại số tiền được chuyển vào và ra. Và vì nhóm tuyến tính được trao đổi thông qua mã thông báo tài sản cơ bản nên phương thức trao đổi là tính Tỷ giá thông qua nguồn cung ảo và thuật toán cố định. Do đó, có hai lỗ hổng bảo mật trong batchSwap:

Đầu tiên là vấn đề làm tròn hướng xuống của nhóm tuyến tính. Kẻ tấn công đơn phương thêm mã thông báo chính vào nhóm thông qua làm tròn để tăng tỷ lệ mã thông báo được lưu trong bộ nhớ đệm, từ đó thao túng tỷ giá trao đổi mã thông báo trong nhóm tổng hợp tương ứng;

Thứ hai, do đặc điểm nguồn cung ảo của nhóm có thể kết hợp, nguồn cung ảo được tính bằng cách trừ số dư trong nhóm khỏi mã thông báo BPT. Nếu GiveIn là mã thông báo BPT tại thời điểm quy đổi, phần này sẽ được khấu trừ vào phần tiếp theo cung cấp. , kẻ tấn công chỉ cần trao đổi BPT dưới dạng GiveIn và thao tác nguồn cung của nó về 0 trước, sau đó thực hiện hoán đổi ngược, tức là BPT sau đó được sử dụng làm GiveOut. Lúc này, vì nguồn cung bằng 0 nên thuật toán sẽ gần bằng 1: Tỷ lệ 1 thấp hơn tỷ lệ quy đổi của nhóm tuyến tính để quy đổi thực tế, điều này khiến số lượng mã thông báo BPT của GiveOut bị thao túng gián tiếp.

Chúng ta có thể thấy rằng lỗ hổng thứ nhất làm tăng tỷ giá hối đoái, trong khi lỗ hổng thứ hai làm giảm tỷ giá hối đoái theo hướng ngược lại, kẻ tấn công đã lợi dụng buff kép để kiếm lợi nhuận và bỏ đi.

Liên kết tham khảo:

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Chia sẻ
Bình luận
0/400
Không có bình luận
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)