Euler Finance Flash Loan Attack
※ 해당 글은 박현재 연구원과 함께 작성한 글입니다.
※ 본 게시글의 암호화폐 주소 추적은 BIG의 암호화폐 추적 솔루션인 "QLUE"를 사용했습니다.
1. 필요한 배경 지식
- Flash Loan : 승인, 실행 및 모두 한 번의 거래로 상환되는 무담보 대출
- Euler Finance : 사용자가 다양한 암호화 자산을 대출하고 빌릴 수 있도록 설계된 이더리움 DeFi 렌딩(담보대출) 프로토콜
- eToken(담보 토큰), dToken(부채 토큰) : dToken 양이 eToken 양을 초과하면 청산이 시작
2. 사건 개요
2023년 03월 13일
- Euler Finance에 대한 flash loan 공격으로 DAI, USDC, wBTC, staked Ether(stETH)의 거래에서 약 2억 달러의 손실 발생
- wstETH(Wrapped stETH) : stETH를 wrapper에 예치하고 받은 토큰. Uniswap 및 MakerDAO를 포함한 DeFi 프로토콜과 쉽게 통합 가능
- stETH(Staked Ether) : 이더리움(ETH)을 리도(Lido)서비스에 맡기고 지급 받는 토큰. 이더리움 2.0 스테이킹의 단점을 개선하기 위해 출시
- wETH(Wrapped ETH) : DeFi 플랫폼에서 ETH를 자유롭게 다른 토큰들과 교환할 수 있도록 ERC-20 토큰화 시킨 이더리움(ETH)
- wBTC(Wrapped BTC) : 비트코인을 이더리움 환경에서 쓰기 위해 비트코인을 담보로 하는 스테이블 토큰의 일종.
2-1) 공격 관련
- 2023년 03월 13일 08:50:59 (UTC) DeFi 대출 프로토콜인 Euler Finance을 겨냥한 Flash Loan Attack 시작
- Euler Finance의 스마트 컨트랙트 중 donateToReserves() 함수의 취약점을 이용
- DAI($8.8 M), USDC($34.1 M), wBTC($18.9 M), stETH($137.1 M)의 거래에서 약 2억 달러 이상의 손실 발생
- 공격자는 탈취한 자금을 ETH와 DAI로 변환
- 자금은 Tornado Cash, Lazarus Group, 피해자 등의 주소로 나뉘어 전송
2-2) 원인
※ donateToReserves() 함수의 취약점
EToken.sol 파일의 donateToReserves() 함수에서 사용자의 부채가 담보보다 적은(eToken > dToken) 것을 확인하는 ‘checkLiquidity()’ 함수가 빠진 것을 볼 수 있다.
따라서 기부를 수행하는 계정에 대한 포지션 확인을 하지 않기 때문에, 사용자는 레버리지 예금의 일부를 자발적으로 포기해서 자신의 포지션을 불균형하게 만든 뒤, Euler 청산 프로토콜을 통해 자신의 포지션을 청산함으로써 이익을 획득할 수 있다.
Euler 프로토콜에서 스스로 청산하면 비율 기반 청산 인센티브에 대한 규정으로 인해 부채를 할인
정상적인 함수의 경우 [그림 3]과 같이 함수가 동작하고 나서 checkLiquidity()를 호출해서 사용자의 포지션을 체크한다.
checkLiquidity() 함수는 RiskManager를 호출하고 callInternalModule() 함수에서 사용자의 eToken이 dToken 보다 많다는 것을 확인하고 보장한다.
2-3) 입장
- 2023년 03월 13일 공격 사실을 인지하고 트위터 공식 계정에서 언급
2-4) Euler 재단 측 대응
- 예금 및 취약한 기부 기능을 차단하는 eToken 모듈을 비활성화
- TRM Labs, Chainalysis 및 ETH 보안 커뮤니티와 협력 조사 및 자금 복구 작업을 위해 노력
- 미국 및 영국 법 집행 기관에 정보 공유
- 공격자를 식별하는 데 도움되는 정보 제공 시, 100만 달러의 보상금 발표
2-5) 공격자와 합의
- 공격자에게 탈취 자금을 환원한다면, 10%를 가져도 된다는 제안을 온 체인 메시지로 전송
- 공격자가 3월 18일 탈취금의 일부를 반환, 3월 20일부터 본격적인 합의 시작
- 회수 가능한 자금을 모두 회수
- 공격자에게 걸었던 100만 달러 현상금을 취소
3. Flash Loan Attack 과정 분석
-
탈취 자금 입금 주소
- 0xb66cd966670d962c227b3eaba30a872dbfb995db
- 0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4
-
공격에 사용된 스마트 컨트랙트 주소
- 0xeBC29199C817Dc47BA12E3F86102564D640CBf99
- 0x036cec1a199234fc02f72d29e596a09440825f1c
본 게시글에서는 공격 과정에 대해 간략하게 작성했다. 스마트 컨트랙트 흐름에 대한 자세한 분석은 'Euler Finance Flash Loan 스마트 컨트랙트 상세 분석'에 작성했다.
‘첫 번째 스마트 컨트랙트(0xebc29199c817dc47ba12e3f86102564d640cbf99)’에서 한 번의 DAI 거래가 이루어졌고, ‘두 번째 스마트 컨트랙트(0x036cec1a199234fc02f72d29e596a09440825f1c)’에서 USDC, wBTC, stETH, wETH 거래와 두 번의 wstETH 거래가 이루어졌다. 공격자는 총 7회의 Flash Loan Attack으로 자금을 탈취했다.
2023년 3월 13일 오전 8시 50분 59초, 첫 번째 Flash Loan Attack (DAI)
- 1 : Aave의 Flash Loan으로 30,000,000 DAI를 대출한 후 공격을 위해 2개의 스마트 컨트랙트 0x583c21631c48d442b5c0e605d624f54a0b366c72(Violator), 0xa0b3ee897f233f385e5d61086c32685257d4f12b(Liquidator)를 이용
- 2,3,4 : Euler 프로토콜 계약에 2천만 DAI를 갚기로 하고, 1,956만 eDAI를 발급
- 5 : Euler 프로토콜은 예치금의 최대 10배까지 빌릴 수 있음, 1억 9,560만 eDAI를 발급
- 6 : 빌린 금액(eDAI)에 상응하는 2억 dDAI를 발급
- 7,8 : 1천만 DAI를 상환해서, 1천만 dDAI를 소멸
- 9,10 : 다시 예치금의 최대 10배인 1억 9,560만 eDAI와 2억 dDAI를 발급
- 11 : donateToReserves() 함수를 호출해서 부채 상환에 필요한 금액의 10배인 1억 eDAI를 기부
- 12,13 : Euler Protocol 내부 알고리즘에 의해 부채가 할인된 값, 청산 금액(dDAI)
- 14 : 13의 청산 수수료 2%에 해당하는 값
- 15 : 현재 남아있는 eDAI의 합
- 16 : 청산을 통해 사용자가 얻을 수익금 (DAI)
- 17 : DAI를 돌려받기 위해 지출한 담보 (eDAI)
- 18 : 청산 프로세스가 완료된 후 사용자의 수익금 전달 (38,904,507.35 DAI)
- 19 : Flash Loan 대출금의 이자 전송
- 20 : Flash Loan 대출금 및 수수료 상환 (30,027,000 DAI)
- 21 : Flash Loan 공격을 통해 획득한 차익 전송 (8,877,507.3484 DAI)
공격자가 사용한 Flash Loan Attack 과정은 모두 비슷한 프로세스로 진행되기 때문에, 첫 번째 Flash Loan Attack 과정을 이해했다면 다음 Flash Loan Attack 과정은 금방 이해할 수 있을 것이다.
2023년 3월 13일 오전 8시 56분 35초, 두 번째 Flash Loan Attack (wETH)
- Aave Flash Loan으로 20.895 wETH를 대출
- 스마트 컨트랙트 0x0b812c74729b6abc723f22986c61d95344ff7aba(Violator), 0xd3b7cea28feb5e537fca4e657e3f60129456eaf3(Liquidator)로 공격 수행
- Euler Protocol 결과로 28,994.303892 wETH 획득
- 원금과 수수료를 합친 금액인 20,913.805501 wETH는 Aave에 상환
- 차액인 8,080.5 wETH는 Wrapped Ether(0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)를 통해 8,080.5 ETH로 변환 후 [주소 0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4]로 전송
2023년 3월 13일 오전 9시 3분 23초, 세 번째 Flash Loan Attack (wBTC)
- Aave Flash Loan으로 3,000 wBTC를 대출
- 스마트 컨트랙트 0xb324581ee258aa67bc144ad27f79f8dcac569af0(Violator), 0x9ff58f4ffb29fa2266ab25e75e2a8b3503311656(Liquidator)로 공격 수행
- Euler Protocol 결과로 3,849.153972 wBTC 획득
- 원금과 수수료를 합친 금액인 3,002.7 wBTC는 Aave에 상환
- 차액인 846.43597139 wBTC는 11,559.126336wETH로 변환
- 변환된 wETH는 Wrapped Ether를 통해 11,559.2 ETH로 변환
2023년 3월 13일 오전 9시 4분 23초, 네 번째 및 다섯 번째 Flash Loan Attack (wstETH)
- 식별되지 않은 주소인 0xba12222222228d8ba445958a75a0704d566bf2c8로부터 Flash Loan으로 99,000 wstETH를 대출
- 스마트 컨트랙트 0x84273bba41cd0ec99f59b5b4c85783cf514e4e1a(Violator), 0x22c5cf8fc9891f8ef5a5e8630b95115018a09736(Liquidator)로 공격 수행
- Euler Protocol 결과로 145,200 wstETH 획득
- 대출금인 99,000 wstETH를 상환
- Flash Loan으로 99,000 wstETH를 다시 대출
- 스마트 컨트랙트 0x1e4446016f3fddfe2ecc046cf91a8010a30e9a9b(Violator), 0xcec2981d8047c401f2a4e972a7e5ada3f5ecf838(Liquidator)로 공격 수행
- Euler Protocol 결과로 119,071.4982 wstETH 획득
- 대출금인 99,000 wstETH를 상환
- 획득한 차액인 66,271.498176 wsETH를 스마트 컨트랙트 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0를 통해 73,821.459346 stETH로 변환
- 73,821.459346 stETH를 스마트 컨트랙트0xdc24316b9ae028f1497c275eb9192a3ea0f67022를 통해 73,347.7 ETH로 변환
2023년 3월 13일 오전 9시 4분 59초, 여섯 번째 Flash Loan Attack (USDC)
- Aave Flash Loan으로 210,000,000 USDC를 대출
- 스마트 컨트랙트 0x7db7099b00d1d24ef2814cfcde723eacd958b05b(Violator), 0xd444a7ac5d1c5eb8ebc9dab83834a412e9b7be76(Liquidator)로 공격 수행
- Euler Protocol 결과로 244,413,863.42 USDC 획득
- 원금과 수수료를 합친 210,189,000 USDC를 Aave에 상환
- 획득한 차액인 34,224,863.42 USDC를 Uniswap (0x6c6bc977e13df9b0de53b251522280bb72383700)을 통해 34,186,225.92 DAI로 변환
2023년 3월 13일 오전 9시 8분 59초, 일곱 번째 Flash Loan Attack (stETH)
- Aave Flash Loan으로 20,895 stETH를 대출
- 스마트 컨트랙트 0xdc24316b9ae028f1497c275eb9192a3ea0f67022(Violator), 0x12df82a443c77eae9d5bb0f5c8d0ec706ecb338c(Liquidator)로 공격 수행
- Euler Protocol 결과로 24,792.504358 stETH 획득
- 원금과 수수료를 합친 20,913.805501 stETH는 Aave에 상환
- 획득한 차액인 3,878.698858 stETH는 스마트 컨트랙트 (0xdc24316b9ae028f1497c275eb9192a3ea0f67022)를 통해 3,846 ETH로 변환
공격자 주소 | 공격을 통해 얻은 금액 | 합계 | ||
---|---|---|---|---|
0xb66cd966670d962c227b3eaba30a872dbfb995db | 43,063,733.2684 | DAI | 43,063,733.26 | DAI |
88,752.9 | ETH | 96,833.4 | ETH | |
0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4 | 8,080.5 | ETH |
7회의 Flash Loan Attack으로 [주소 0xb66cd966670d962c227b3eaba30a872dbfb995db]로 총 43,063,733.2684 DAI 및 88,752.7 ETH가 전송됐고, [주소 0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4]로 8,080.5 ETH가 전송됐다.
Flash Loan Attack No. | 획득한 차익 | 최종 변환 결과 | ||
---|---|---|---|---|
1 | 8,877,507.3484 | DAI | 8,877,507.3484 | DAI |
2 | 20,913.805501 | DAI | 8,080.5 | ETH |
3 | 846.43597139 | WBTC | 11,559.2 | ETH |
4 | 46,200 | wstETH | 73,347.7 | ETH |
5 | 20,071.4982 | wstETH | ||
6 | 34,224,863.42 | USDC | 34,186,225.92 | DAI |
7 | 3,878.698858 | stETH | 3,846 | ETH |
결과적으로 공격자는 약 2억 달러에 해당하는 43,063,733.2684 DAI 및 96,833.4 ETH를 탈취하는 데 성공했다.
4. Flash Loan Attack 이후
4-1) Euler Finance와 Hacker의 On-Chain Message 대화 내역
On-Chain Message
- 2023년 3월 13일 10:47:47 PM (UTC)
Euler : 우리를 공격한 것을 알고 있음을 언급, 공격자와 협상 시작
"We understand that you are responsible for this morning's attack on the Euler platform. We are writing to see whether you would be open to speaking with us about any potential next steps."
- 2023년 3월 14일 09:22:47 PM (UTC)
Euler : 탈취한 자금에 대한 90% 반환 요구, 미 이행 시 1 M $ 현상금 발표
"Following up on our message from yesterday. If 90% of the funds are not returned within 24 hours, tomorrow we will launch a $1M reward for information that leads to your arrest and the return of all funds."
- 2023년 3월 14일 10:25:23 PM (UTC)
Hacker : 90%의 자금을 반환할 것이며 법적 조취를 취하지 말 것을 요구
"As I said earlier EULER EXPLOITER will return 90% funds and no legal actions should be taken, not with in 24hours it takes some time YOU HAVE DEAL THIS IN A SMOOTH WAY"
- 2023년 3월 15일 11:20:47 AM (UTC)
Euler : 자금을 반환할 주소 (EulerDAO : 0xcAD001c30E96765aC90307669d578219D4fb1DCe) 제공
"The simplest way to move forward today is to return 90% of both the DAI and ETH under your control to the EulerDAO treasury address: 0xcAD001c30E96765aC90307669d578219D4fb1DCe. Then investigations can be halted, and the focus here can turn to distribution of that back to protocol users, without needing to go the legal route."
- 2023년 3월 16일 08:20:35 AM (UTC)
Hacker : 자금의 90%를 반환하겠다는 의사를 표현
"I agree with you bro euler team on their first on chain message chain they are not sending text in convincing way and possible steps if he returns 90% ."
- 2023년 3월 18일 12:00:11 PM (UTC)
Euler : 공격자가 탈취한 자산의 일부를 반환했음에 감사를 표현, 반환을 계속해서 진행할 경우 조사 중단을 약속
"Thank you for returning a portion of the assets. The original offer still stands if you would like to continue by returning the funds. The reward for information will be removed immediately and all our investigations will be dropped."
- 2023년 3월 20일 04:51:59 PM (UTC)
Hacker : 합의를 할 것이라는 의사를 표현
"We want to make this easy on all those affected. No intention of keeping what is not ours. Setting up secure communication. Let us come to an agreement."
- 2023년 3월 20일 07:14:23 PM (UTC)
Euler : 비공개로 이야기 하기를 제안
"Message received. Let's talk in private on blockscan via the Euler Deployer address and one of your EOAs, via signed messages over email at contact@euler.foundation, or any other channel of your choice. Reply with your preference."
- 2023년 3월 21일 06:18:23 PM (UTC)
Hacker : 탈취한 자금을 반환할 의사가 있음을 표현
"We still want to do the right thing returning funds to the Euler team. Will communicate shortly."
... 중략
- 2023년 3월 28일 01:56:11 AM (UTC)
Hacker : 남은 금액은 가능한 한 빨리 돌려줄 것이라고 언급
"The rest of the money will be returned ASAP. I only look after my safety, and that is the reason for the delay. I'm sorry for any misunderstanding. Please read my next message."
- 2023년 3월 28일 01:57:47 AM (UTC)
Hacker : "나는 제이콥이다. 내가 다른 사람들의 인생을 망쳤다. 미안하다. 용서해달라."
"Jacob here. I don't think what I say will help me in any way but I still want to say it. I fucked up. I didn't want to, but I messed with others' money, others' jobs, others' lives. I really fucked up. I'm sorry. I didn't mean all that. I really didn't fucking mean all that. Forgive me."
4-2) Euler와 협상 중 공격자의 추가 행위
2023년 4월 3일 오전 10시 54분 59초
- 합의 과정에서 공격자에게 알려준 주소인 Euler: Multisig2 (0xcad001c30e96765ac90307669d578219d4fb1dce)로 8,080 ETH 전송
탈취한 DAI 환원 과정
- [주소 0xb66cd966670d962c227b3eaba30a872dbfb995db]에서 공격을 통해 획득한 43,063,733.2684 DAI와 다른 주소에서 받은 1.1 DAI가 합쳐져 총 43,063,734.35 DAI를 나누어 4개의 주소로 전송
- 43,063,734.35 DAI 중 5 DAI를 제외한 43,063,729.3501 DAI를 Euler 측에 환원
탈취한 ETH 환원 과정
- Tornado Cash(0xc66dfa84bc1b93df194bd964a41282da65d73c9a)에 전송한 3601 ETH 중 2500 ETH를 Euler 측에 환원
- Lazarus Group으로 식별된 주소(0x098b716b8aaf21512996dc57eb0615e2383e2f96)에 100 ETH 전송
- 트위터에서 본인이 이번 사건의 피해자라고 주장했던 사람의 주소(0x2af24e5575045a582d9c53febd48724473e67407)에 100 ETH 전송
- 96,833.4 ETH 중 95,556.56059211764 ETH를 Euler 측에 환원
탈취한 자금을 환원하는 과정에서 자금을 전송받은 주소와 받은 금액을 아래 표와 같이 정리했다.
전송받은 주소 | 보낸 금액 | |
---|---|---|
0xc66dfa84bc1b93df194bd964a41282da65d73c9a | 3,601 | ETH |
0x098b716b8aaf21512996dc57eb0615e2383e2f96 (Lazarus) | 100 | ETH |
0x2af24e5575045a582d9c53febd48724473e67407 (Avalos) | 100 | ETH |
0xee009faf00cf54c1b4387829af7a8dc5f0c8c8c5 | 54,000 | ETH |
0xc4e04ac48639ff077ebb36e7cfe0c4993b7b208e | 10,787,465.25 | DAI |
7,738.3 | ETH | |
0x46e0be2df97dac791fc8e30cf2b2e4f58c50cf55 | 10,787,465.25 | DAI |
7,738.3 | ETH | |
0xa1b44d4b5b4c361f51e029b81bf2db9cf4d8e676 | 10,787,465.25 | DAI |
7,738.3 | ETH | |
0x8765a35394c98e81b9d56d44248e1199d8e38a4c | 10,787,465.25 | DAI |
7,738.3 | ETH |
공격자가 탈취한 자금은 2023년 3월 18일부터 4월 3일까지 위 표의 주소를 거쳐 Euler: Multisig2 (0xcad001c30e96765ac90307669d578219d4fb1dce)로 합쳐졌다. Euler: Multisig2 주소로 모인 자금을 아래 표와 같이 정리했다.
전송한 주소 | 보낸 금액 | 합계 | ||
---|---|---|---|---|
0xa1b44d4b5b4c361f51e029b81bf2db9cf4d8e676 | 344,925.5 | DAI | 43,063,729.3501 | DAI |
0x0d1b0c32b52583fd155ea6a2df10214270da9843 | 20,000,000 | DAI | ||
0xc4e04ac48639ff077ebb36e7cfe0c4993b7b208e | 10,787,465.2501 | DAI | ||
0.0569100165 | ETH | |||
0xee009faf00cf54c1b4387829af7a8dc5f0c8c8c5 | 11,931,338 | DAI | ||
84,963.6 | ETH | |||
0xd90e2f925da726b50c4ed8d0fb90ad053324f31b (Tornado Cash) | 2,500 | ETH | 95,556.56059211764 | ETH |
0x2af24e5575045a582d9c53febd48724473e67407 (Avalos) | 12 | ETH | ||
0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4 | 8,080 | ETH | ||
0x8765a35394c98e81b9d56d44248e1199d8e38a4c | 0.05355134923 | ETH | ||
0.6 | DAI | |||
0x46e0be2df97dac791fc8e30cf2b2e4f58c50cf55 | 0.85013075191 | ETH |
이번 공격으로 피해를 입은 피해자 중 한 명인 Solidity 개발자 Santiago Sanchez Avalos는 공격자에게 직접 on-chain message를 보내 자신의 삶이 완전히 망가졌다고 얘기하며, Euler 측의 협상 제안을 받아들일 것을 요구했다.
공격자가 메시지를 본 뒤, Avalos에게 100 ETH를 전송했지만 Avalos는 받은 100 ETH 중 일부를 다른 주소로 보내는데, 이는 Avalos가 Euler에 맡긴 자금이 78 wstETH이기 때문에 차익에 해당하는 금액이 도난 자금이 되기 때문이다.
Avalos의 메시지가 공격자의 마음을 바꿨는지는 모르지만, 공격자는 이 메시지를 받고나서 탈취한 자금을 돌려주기 시작했다.
5. 결론
- 공격자는 2개의 스마트 컨트랙트를 사용해서 7회의 Flash Loan Attack을 수행했다.
- 공격자는 Euler Finance의 스마트 컨트랙트(EToken.sol) 함수인 donateToReserves()의 취약점을 이용해 43,063,733.2684DAI, 96,833.4ETH를 탈취했다.
- 공격자는 탈취한 ETH 중 100 ETH를 북한의 Lazarus Group으로 식별되는 주소에 전송했다.
- 공격자는 탈취한 ETH 중 3601 ETH를 Tornado Cash 서비스에 사용했다.
- 공격자는 탈취한 ETH 중 100 ETH를 스스로 피해자라고 주장하는 사람의 주소에 전송했다.
- 공격자는 Euler 측의 제안(탈취한 금액의 10%을 제외한 나머지를 환원할 것)을 받아들이고, 43,063,729.3501 DAI 및 95,556.56059211764 ETH를 Euler 측에 환원했다.
- Euler 측은 대부분의 자금을 돌려받은 후 약속대로 공격자에 대한 수사를 취하했지만, 불법 조직인 Lazarus Group으로 자금을 전송한 것 때문에 공격자가 수사를 피할 수는 없을 것이라고 한다.