Euler Finance Flash Loan Attack : Deep dive into Smart contract

Euler Finance Flash Loan Attack에 사용된 스마트 컨트랙트의 흐름을 Phalcon.xyz와 Etherscan을 사용해 분석한 글이다.

※ 본 게시글의 암호화폐 주소 추적은 BIG의 암호화폐 추적 솔루션인 "QLUE"를 사용했습니다.


이전 글 보기

Euler Finance Flash Loan Attack
2023년 3월 13일, Euler Finance는 스마트 컨트랙트의 취약점으로 인해 Flash Loan Attack을 당하게 되어 약 2억 달러에 해당하는 자금을 탈취당했다. 하지만 공격자는 피해 금액의 약 90%를 돌려주게 되었는데... 본 사건의 전반적인 내용과 공격 과정을 자세하게 살펴본다.

Phalcon.xyz의 Fund Flow

[그림 1] Phalcon에서 Fund Flow

Invacation Flow

[그림 2] 계약 0xeBC29199C817Dc47BA12E3F86102564D640CBf99 : DAI 거래
  1. 공격자는 0xeBC29199C817Dc47BA12E3F86102564D640CBf99(공격에 사용된 계약1)을 사용하여 Aave로부터 30,000,000 DAI를 Flash Loan을 통해 대출했다. 두 개의 계약 0x583c21631c48d442b5c0e605d624f54a0b366c72(Violator), 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator) 생성했다.
  2. 0x583c21631c48d442b5c0e605d624f54a0b366c72(Violator)에 30,000,000 DAI를 송금했다.
[그림 3] 두 개의 하위 계약 생성
  1. 공격자는 20,000,000 DAI를 0x27182842e098f60e3d576794a5bffb0777e025d3(Euler)에 예치했다.
  2. 19,568,124 eDAI를 획득했다.
[그림 4] 담보 획득
  1. mint()함수(자체 차용)를 호출하여 레버리지를 늘려 약 10배에 가까운 195,681,243 eDAI를 대출했다.
  2. 대출금에 대한 200,000,000 dDAI를 부채로 받았다.
[그림 5] 예치금의 10배 대출 실행
  1. 공격자는 남은 10,000,000DAI를 0x27182842e098f60e3d576794a5bffb0777e025d3(Euler)에 담보로 맡겼다.
  2. repay()함수를 호출하여 10,000,000 dDAI를 상환했다. (부채를 줄이고 담보 가치를 높여 다시 빌리기 위함)
[그림 6] 부채 일부 상환
  1. mint()함수(자체 차용)를 다시 호출하여 195,681,243 eDAI를 대출했다.
  2. 대출금에 대한 200,000,000 dDAI를 부채로 받았다. → 현 계정 : 총 410,930,612 eDAI, 390,000,000 dDAI
[그림 7] 한번 더 대출 실행
  1. donateToReserves() 호출하여 100,000,000 eDAI를 예정된 주소로 기부했다. → 현 계정 : 310,930,612 eDAI, 390,000,000 dDAI (현 계정은 오류가 있는 상태가 되지만 donateToReserves() 함수는 계정의 상태 요소를 확인하지 않음)
[그림 8] 100,000,000 eDAI 기부

공격자는 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator)계약을 통해 0x583c21631c48d442b5c0e605d624f54a0b366c72(Violator)을 청산했다.

  1. Euler 청산 프로토콜에 의해 부채가 할인되어 254,234,371 dDAI가 되었다.
  2. 부채 254,234,371 dDAI가 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator)로 이전되었다.
  3. 부채에 따른 수수료 약 5,084,687 dDAI가 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator)로 이전되었다. → 총 259,319,058dDAI의 부채 이전
  4. 0x583c21631c48d442b5c0e605d624f54a0b366c72(Violator)에 남아있던 310,930,612eDAI가 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator)로 이전되었다.

스스로 청산할 경우 부채에 대한 할인이 이루어짐(청산인이 청산을 시작하면 할인은 채무자의 요인에 따라 계산이 된다. Liauidator는 eDAI>dDAI인 상황이 되기 때문에 청산되지 않는다.)

[그림 9] violator 청산

공격자는 withdraw()함수를 사용하여 청산에서 얻은 자금을 인출하고 부채를 정리한 후 잔액을 출금했다.

  1. 0x27182842e098f60e3d576794a5bffb0777e025d3(Euler)에서 38,904,507DAI를 받았다.
  2. 38,064,411 eDAI를 교환했다.
  3. 0xeBC29199C817Dc47BA12E3F86102564D640CBf99(공격에 사용된 계약1)는 38,904,507DAI를 받았다.
  4. Aave로 약 0.037 aDAI가 전송되었다. (aToken : Aave에 자산을 공급 및 인출할 때 발행되고 소각되는 토큰)
  5. 38,904,507DAI 중 30,027,000 DAI로 처음 빌린 Flash loan 대출금을 갚는다.
[그림 10] DAI로 전환하여 대출 청산하고 차액 송금
  1. 차액 8,877,507DAI를 [주소 0xb66cd966670d962c227b3eaba30a872dbfb995db]로 송금했다.

요약

  • Receiver

    • Balancer/Aave v2로부터 flash loan 대출 → 30M DAI
    • 2개의 계약 생성 (violator, Liquidator)
  • Violator

    • deposit() 함수를 사용하여 자금의 2/3을 Euler에 입금하고 19.5M eDAI 받음
    • min() 함수를 사용하여 예치금의 10배 차용 → Euler로부터 195.6M eDAI, 200M dDAI 받음
    • repay() 함수를 사용하여 남은 1/3으로 부채 일부 상환 → 10M DAI 보내고, 10M dDAI 소각
    • min() 함수를 사용하여 Euler로부터 추가로 195.6M eDAI, 200M dDAI 받음
    • donateToReserves() 함수를 사용하여 기부 → 100M eDAI를 Euler에 전송
  • Liquidator

    • liquidate()을 사용하여 Violator 계정 청산
    • invoke()을 사용하여 Euler에서 토큰(38.9M DAI) 인출
    • Flash Loan 상환, 차액 [주소 0xb66cd966670d962c227b3eaba30a872dbfb995db]로 송금
You've successfully subscribed to PLAINBIT
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.