7월 18일, 저희 DeFiRanger 시스템이 몇 가지 의심스러운 트랜잭션을 보고했습니다. 수동 분석 후, 이 트랜잭션들이 Array Finance에 대한 공격임을 확인했습니다. 이하에서는 공격 트랜잭션을 사용하여 공격 과정과 취약점의 근본 원인을 설명하겠습니다.
공격 트랜잭션
이 블로그에서 사용된 공격 트랜잭션은 다음과 같습니다: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa
공격 흐름

그림 1에서 볼 수 있듯이, 공격자는 AAVE에서 플래시 론을 빌린 후 186.62 WETH의 수익을 얻었습니다. (이 블로그에서는 WETH와 ETH를 명시적으로 구분하지 않습니다.)

자세한 공격 과정은 그림 2에 나와 있습니다.
- 먼저, 공격자는 Array Finance의
buy함수를 호출했습니다. 공격자는 45.91 WETH를 사용하여 Array Finance가 발행한 430 ARRAY 토큰을 획득했습니다. - 그런 다음 공격자는 클로즈드 소스 컨트랙트(Array Collater - 0xa800cda5)의
joinPool함수를 다섯 번 호출했습니다. 그는 676,410.58 DAI + 679,080.46 USDC + 901.82 WETH + 20 WBTC + 20 renBTC를 예치하고 Array Collater가 발행한 726.38 aBPT 토큰을 획득했습니다. - 공격자는
sell함수를 호출하여 430 ARRAY 토큰을 소각하고 77.17 aBPT 토큰을 받았습니다. - 마지막으로, 공격자는 Array Collater의
exitPool함수를 호출했습니다. 그는 이전 두 단계에서 획득한 804.55 aBPT 토큰을 소각하고 748,271.55 DAI + 751,225.08 USDC + 997.62 WETH + 22.63 WBTC + 22.74 renBTC를 획득했습니다.
그림 2에서 공격자가 5단계(그림 2: sell 함수 호출)에서 수익을 얻는 것을 확인할 수 있습니다. 이는 획득한 77.17 aBPT 토큰이 3단계(그림 2: buy 함수 호출)에서 예치한 49.9142 WETH보다 더 가치가 있기 때문입니다. 이하에서는 이 공격이 왜 가능한지 이해하기 위해 코드를 분석하겠습니다.
코드 취약점
다음 코드는 Array Finance의 sell 함수를 보여줍니다. 이 함수에서 Array Finance는 공격자가 보유한 ARRAY 토큰의 잔액을 사용하고 내부 _sell 함수를 호출하여 ARRAY 토큰을 판매함으로써 얻을 수 있는 aBPT 토큰의 수를 계산합니다.

다음은 _sell 함수의 구현입니다. 이 함수는 calculateLPtokensGivenArrayTokens를 호출하여 일정 수의 ARRAY 토큰으로 얻을 수 있는 aBPT 토큰의 수를 구합니다. 그런 다음 이 함수는 ARRAY 토큰을 소각하고 aBPT 토큰을 반환합니다.

다음은 calculateLPtokensGivenArrayTokens 함수의 구현을 보여줍니다.

amountLPToken의 계산에 영향을 미칠 수 있는 네 가지 인수가 있습니다. saleTargetAmount를 읽은 후, 공식은 다음과 같이 추론됩니다:
arraySmartPool.totalSupply() * (1 - (1 - amount / ARRAY.totalSupply()) ^ (1000000 / reseveRatio))
arraySmartPool은 Array Collater(0xa800cda5f3416a6fb64ef93d84d6298a685d190d)의 스마트 컨트랙트 주소입니다. arraySmartPool.totalSupply()의 값은 공격자가 플래시 론으로 빌린 자금을 Array Collater에 예치할 때 증가합니다(다음 표 참조).
TxnIndex: 64 arraySmartPool.totalSupply(): 110162296218708026400
TxnIndex: 107 arraySmartPool.totalSupply(): 165243444328062039600
TxnIndex: 150 arraySmartPool.totalSupply(): 247865166492093059400
TxnIndex: 193 arraySmartPool.totalSupply(): 371797749738139589100
TxnIndex: 236 arraySmartPool.totalSupply(): 557696624607209383650
TxnIndex: 280 arraySmartPool.totalSupply(): 836544936910814075475
이 로직은 arraySmartPool의 코드를 읽은 후 확인할 수 있습니다. 다음은 arraySmartPool의 joinPool 함수를 보여줍니다.

이 함수는 먼저 SmartPoolManager.joinPool 함수를 호출하여 msg.sender로부터 얻어야 하는 토큰 수(actualAmountsIn)를 계산합니다. 그런 다음 각 토큰에 대해 _pullUnderlying 함수를 호출하여 해당 토큰을 arraySmartPool에 예치합니다. 마지막으로 _mintPoolShare와 _pushPoolShare를 호출하여 aBPT 토큰을 발행하고 발행된 aBPT 토큰을 msg.sender에게 전송합니다.
arraySmartPool은 PCToken으로부터 상속받는다는 점에 유의하세요. _mintPoolShare 함수는 _mint 함수를 호출하며, 이는 다음과 같이 나타납니다.
_mint 함수는 varTotalSupply 변수를 증가시키며, 이 값은 totalSupply()에 의해 직접 반환됩니다. 따라서 이 값은 joinPool이 호출될 때마다 증가합니다.
수익 추정
| 공격 주소 | 공격 트랜잭션 | 수익 (ETH) |
|---|---|---|
| 0x1337 | 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa | 186.62073907323577 |
| 0x1b4fb735b51a25b280499710d02f50e4f772949664f9eb088e9d968b41ca2a1c | 59.338842936817095 | |
| 0x356ae8a278754551d9d2ae7dc0ea876b37c342ff2d010bee14aa253bb0b6030b | 18.827787420260467 | |
| 0x388fd59eab65b6034c96c01a21197eb2889d6507f84ff07e553749c541563962 | 5.880854505948256 | |
| 0xf4227ca3c8e8b5c8a0b10f034c6dee6556788c618e4cd289dc343b3247e85add | 0.4327422187881 | |
| 합계 | 271.1009661550497 | |
| 0x80d2 | 0xf061f8fc19c894ec37310ff59977ec97de55fd1494f1b1e66ae89188552d5c60 | 1.8414029470248867 |
| 합계 | 1.8414029470248867 | |
| 총합계 | 272.9423691020746 |
요약
요약하자면, 공격자는 Array Finance의 가격 메커니즘이 조작 가능한 aBPT 토큰의 totalSupply에 의존한다는 취약점을 악용했습니다. 이 취약점은 저희 연구 논문 DeFiRanger: DeFi 애플리케이션의 가격 조작 공격 탐지에서 논의되었습니다.
크레딧
Junjie Fei, Yufeng Hu, Ziling Lin, Siwei Wu, Lei Wu, Yajin Zhou @BlockSec
(성의 알파벳 순서)
BlockSec 소개
BlockSec은 2021년 세계적으로 著名한 보안 전문가 그룹에 의해 설립된 선구적인 블록체인 보안 회사입니다. 이 회사는 대중적 채택을 촉진하기 위해 신흥 Web3 세계의 보안성과 사용성을 향상시키는 데 전념하고 있습니다. 이를 위해 BlockSec은 스마트 컨트랙트 및 EVM 체인 보안 감사 서비스, 보안 개발 및 위협을 사전에 차단하기 위한 Phalcon 플랫폼, 자금 추적 및 조사를 위한 MetaSleuth 플랫폼, 그리고 크립토 세계에서 효율적으로 탐색하는 web3 빌더를 위한 MetaDock 확장 프로그램을 제공합니다.
현재까지 이 회사는 MetaMask, Uniswap Foundation, Compound, Forta, PancakeSwap 등 300개 이상의 저명한 고객사에 서비스를 제공했으며, Matrix Partners, Vitalbridge Capital, Fenbushi Capital을 포함한 저명한 투자자들로부터 두 차례의 자금 조달 라운드를 통해 수천만 달러를 유치했습니다.
공식 웹사이트: https://blocksec.com/
공식 트위터 계정: https://twitter.com/BlockSecTeam



