Euler Finance Flash Loan Attack : Deep dive into Smart contract

※ 본 게시글의 암호화폐 주소 추적은 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]로 송금