Phân tích nhanh vụ hack trên KyberSwap

Theo phân tích từ công ty kiểm toán Certik, bằng cách tận dụng kẽ hở dù nhỏ nhất trên một số pool thanh khoản của KyberSwap, hacker đã khai thác thành công qua việc hoán đổi chéo để lấy đi số tiền lớn trên các pool thanh khoản này.

Vào ngày 22/11, KyberNetwork đã bị tấn công cho vay nhanh (flashloan) trên một số chuỗi, dẫn đến thiệt hại khoảng 47 triệu USD. Theo Certik, với kỹ thuật này, quan trọng là hiểu cách thức hoạt động của những nhà tạo thanh khoản tập trung.

Các nhà cung cấp thanh khoản tự động cơ bản triển khai một đường cong sản phẩm không đổi chuẩn (x*y=k),nơi tất cả giao dịch diễn ra.

Certik phát hiện rằng, thanh khoản có thể được tận dụng tốt hơn nếu các pool được tạo ra với đường cong giá được giới hạn chặt chẽ hơn. Việc có nhiều thanh khoản hỗ trợ trong một biên độ giá hẹp cũng giảm thiểu rủi ro trượt giá hiệu quả, vì quy mô giao dịch sẽ phải tăng lên theo tỷ lệ của pool thanh khoản để có cùng ảnh hưởng giá.

Phổ biến bởi Uniswap v3, mô hình nhà tạo thanh khoản tập trung cho phép nhà cung cấp thanh khoản (LPs) thêm thanh khoản vào các biên độ giá ưa thích của họ.

Certik chỉ ra, kết quả của thiết kế này là mỗi vị trí cung cấp thanh khoản (LP) phải được theo dõi riêng lẻ vì thanh khoản trong pool trở nên không thể tương đồng. Phạm vi của giá có thể chia thành các “tick” rời rạc, cho phép LP cung cấp thanh khoản giữa bất kỳ hai “tick” nào. Chỉ số của một “tick”, được ký hiệu là i, được định nghĩa là logarith của giá tương ứng.

Thanh khoản ròng của những người cung cấp thanh khoản và các tham số khác được lưu trữ trong một cấu trúc dữ liệu danh sách liên kết.

Mỗi vị trí này, thực tế tạo ra đường cong giá do người dùng tự xác định. Bằng cách tổng hợp tất cả các vị trí khác nhau vào một đường cong giá duy nhất, nó cho phép một pool duy nhất hỗ trợ đa dạng các ưu tiên của người cung cấp thanh khoản (LP).

Khi thêm hoặc loại bỏ thanh khoản vào một biên độ “tick”, pool thanh khoản phải ghi lại lượng thanh khoản ảo được thêm vào hoặc đưa ra khi vượt qua những “tick” này, và có bao nhiêu token được sử dụng để kích hoạt thanh khoản trong biên độ đó. Hoán đổi token 0 để lấy token 1 khiến giá pool hiện tại và “tick” hiện tại di chuyển xuống, trong khi hoán đổi token 1 để lấy token 0 khiến giá pool hiện tại và “tick” hiện tại di chuyển lên. Khi thực hiện hoán đổi, tổng lượng thanh khoản được thêm vào hoặc loại bỏ khi “tick” vượt qua biên độ này để di chuyển về phía trái và phải, và đây là lỗ hổng trong KyberSwap, nơi diễn ra vụ tấn công.

Tính dễ bị tổn thương

Nói một cách đơn giản, lỗ hổng này nằm trong quá trình triển khai hàm computeSwapStep() của KyberSwap Elastic. Hàm này chịu trách nhiệm tính toán số tiền đầu vào và đầu ra thực tế của giao dịch cần được trừ hoặc thêm, phí hoán đổi sẽ được thu thập và giá trị căn bậc hai kết quả là hàm sqrtP.

Hàm này gọi lúc đầu gọi là là hàm calcReachAmount(), và được cho rằng giao dịch của hacker sẽ không vượt qua biên độ “tick”, nhưng sai lầm xảy ra khi tạo ra một giá ảo lớn hơn so với targetSqrtP, được tính bằng cách gọi hàm “calcFinalPrice”. Kết quả là thanh khoản không bị loại bỏ và dẫn đến cuộc tấn công tiếp theo.

Luồng tấn công

Ví dụ này dựa trên giao dịch Ethereum có txhash là: 0x396a83df7361519416a6dc960d394e689dd0f158095cbc6a6c387640716f5475.

Giao dịch này đại diện cho sáu cuộc tấn công đều sử dụng cùng một phương pháp. Vì vậy, Certik đã lấy cuộc tấn công vào cặp USDC-ETHX làm ví dụ.

1. Đầu tiên, tin tặc đã cho vay nhanh 500 ETHx từ Uniswap và thao túng pool KS2-RT ((KyberSwap v2 Reinvestment Token), vốn chỉ có 2,8 ETHx, bằng cách hoán đổi số lượng ETHx quá mức. Tin tặc đã đổi 246,754 ETHx lấy 32389,63 USDC, làm cạn thanh khoản của pool và tăng currentTick hiện tại lên 305,000.

Sau khi hoán đổi, còn lại 249,5 ETHX và 13,2 USDC trong pool.

Có thể thấy, tin tặc ban đầu muốn đổi 500 ETHX lấy USDC, nhưng 246,754 ETHx là đủ để có được 32.389,63 USDC và tăng currentTick lên 305,000. Có nghĩa là không có thanh khoản nào khả dụng trên biên độ “tick” 305,000 để tin tặc hoán đổi vào thời điểm đó, nó được coi là vùng chân không.

2. Sau đó, tin tặc gọi hàm mint() từ hợp đồng KyberSwap: Elastic Anti-Snippingposition Manager, để tạo ra một pool thanh khoản mới với 16 USDC và 5,87e-3 ETHX. “Tick” được đặt trong biên độ hẹp từ 305,000 đến 305,408, có nghĩa là tin tặc đã tạo pool thanh khoản của riêng mình để theo dõi “tick” ở mức 305,000.

Sau đó, tin tặc đã loại bỏ một phần thanh khoản, nhưng vẫn để lại một phần thanh khoản trong biên độ “tick” từ 305,000 đến 305,408.

3. Tin tặc tiến hành lần hoán đổi thứ hai từ ETHX sang USDC. Chúng đã đổi 244.08 ETHX ở biên độ “tick” là 305,000 để nhận được 13.6 USDC và làm tăng biên độ “tick” lên 305,408.

Nhìn bề ngoài, đây có vẻ là một giao dịch hoán đổi kỳ lạ vì tin tặc là kẻ duy nhất cung cấp thanh khoản trong khoảng từ 305,000 đến 305,408, nhưng đó là tiền đề cho bước tiếp theo.

4. KyberSwap sử dụng hàm computeSwapStep() để xác định xem giao dịch có vượt một khoảng “tick” hay không. Một phần của hàm được hiển thị dưới đây:

Ở đây, tập trung vào hàm calcReachAmount(). Hàm này tính toán số lượng token cần thiết cho một giao dịch nếu currentSqrtP (giá căn bậc hai hiện tại) đạt đến targetSqrtP.

Cerik nhận định, trong giao dịch này, giá trị của usedAmount là 244080034447360000000, trong khi lượng ETHx mà tin tặc nhập vào để đổi là 244080034447359999999, ít hơn một so với giá trị của usedAmount. Hàm computeSwapStep() xác định rằng giao dịch này không đủ để làm cạn thanh khoản trong biên độ “tick” hiện tại và không cần phải đổi qua biên độ “tick” khác. Có nghĩa là nextSqrtP không được cập nhật thành targetSqrtP.

Hàm calcFinalPrice sau đó được gọi để tính toán giá trị nextSqrtP tiếp theo. Phần quan trọng ở đây là trong quá trình tính toán, phí hoán đổi được tính vào trong thanh khoản. Dẫn đến việc giá cuối cùng của nextSqrtPthực tế cao hơn dự kiến kiến ban đầu, cụ thể là cao hơn giá tại biên độ “tick” 305,408.

Quay lại hàm trao đổi ở trên, Certik cho biết giá trị của sqrtP và nextSqrtP được so sánh để xác định xem có cần phải đổi biên độ “tick” hay không. Điều kiện ở đây chỉ xác định xem sqrtP có ‘bằng’ nextSqrtP hay không, và chỉ khi nó bằng nhau, hàm thấp hơn là updateLiquidityAndCrossTick() mới được gọi để thêm hoặc bớt thanh khoản (swapData.baseL) và vượt qua biên độ “tick”.

Tại điểm này, sqrtP hiện đang lớn hơn nextSqrtP. Có nghĩa là tin tặc đã tạo ra tình huống trong đó giá hiện tại đã vượt qua giới hạn trên của khoảng “tick”, nhưng không kích hoạt hàm updateLiquidityAndCrossTick() để bớt thanh khoản, dẫn đến sự tồn tại của thanh khoản giả mạo.

5. Cuối cùng, tin tặc thực hiện một giao dịch trả ngược, đổi USDC thành ETHx, làm giảm giá một chút trên biên độ “tick” 305,408 – giới hạn trên của phạm vi thanh khoản do tin tặc cung cấp (từ 305,000 đến 305,408) xuống một chút dưới giá ở biên độ “tick” 304,982.

Khi giá vào khoảng biên độ “tick” từ 305,000 – 305,408, nơi tin tặc cung cấp thanh khoản, từ một chút cao hơn 305,408, hàm updateLiquidityAndCrossTick() đã được gọi. Thanh khoản giả mạo được thêm vào thanh khoản nằm trong biên độ “tick” 305,000 – 305,408, làm tăng thanh khoản giữa các giá trị trong biên độ “tick” so với thanh khoản thực tế. Tin tặc sau đó đổi 493,638 ETHx thành 27,517 USDC trong khoảng giá này (bao gồm khoảng 250 ETHx không được tính trong biên độ “tick” 305,000 – 305,408). Kết quả là các chi phí trước đó đã được khôi phục và đồng thời pool thanh khoản bị mất toàn bộ USDC, Certik kết luận.

6. Trả lại khoản vay nhanh và hoàn thành cuộc tấn công.

Quá trình này được lặp lại đối với nhiều cặp giao dịch trên giao thức KyberSwap ở nhiều blockchain khác nhau, dẫn đến những tổn thất sau đây.

POLY: 1.180.097 USD; ETH: 7.486.868 USD; OP: 15.504.542 USD; BASE: 318.413 USD; ARB: 16.833.861USD; AVAX: 23.526 USD.

Các vụ tấn công được Certik xác nhận đến từ ba địa chỉ Ethereum (EOAs) khác nhau, trong đó địa chỉ 0x502 chiếm phần lớn tài sản. Ban đầu, địa chỉ 0x502 đã liên hệ với dự án để thông báo, họ sẽ đàm phán sau một khoảng thời gian nghỉ ngơi. Đội ngũ KyberSwap sau đó cũng liên hệ để đề xuất một phần thưởng 10% với hạn chót là 6 giờ sáng UTC ngày 25/11.

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
1
Thêm vào Yêu thích
Bình luận