안녕하세요. 스마트 컨트렉트 개발자 개발이 체질의 최원혁입니다.
2023년 2월 8일 BSC 체인의 DKP 토큰이 공격을 받았습니다. PancakeSwap에 유동성이 공급되있던 DKP 토큰은 공격자의 플래시론에 의해 가격이 조작되어, 공격자는 약 $80,000의 이익을 얻었습니다.
이번 Hack Series는 QuillAudits의 분석 보고를 참고하여 공격자의 공격 패턴과 방법에대해 알아보겠습니다.
| 공격 시나리오 :
- 공격자 주소 :0xF38B677fa6E9E51338D0c32FD21afe43406E06Df
- 공격자 컨트렉트(1) : 0xf34ad6cea329f62f4516ffe00317ab09d934fba3
- 공격 자금 트랜잭션 :https://bscscan.com/tx/0x4e5b2b6e9f033e696dd90d7ef90ffe1316d5b1fdbd73999a7feace88690bf19f
(1) 공격자는 플래시론 공격 전에, 공격 자금으로 Binance-Peg(BSC-USD)토큰 937개를 공격 패턴을 실행할 컨트렉트(0xf34ad6)에 전송(transfer)합니다.
- 공격자 컨트랙트(2) : 0xb24FC2F9eE4467CF64990584faB02274AA247735
- 공격 트랜잭션 : 0x0c850f54c1b497c077109b3d2ef13c042bb70f7f697201bcf2a4d0cb95e7427
- BSC-USD/DKP Pair(PancakeSwap LP) 컨트렉트 : 0xBE654FA75bAD4Fd82D3611391fDa6628bB000CC7
(2) 공격자는 PancakeSwap의 BSC-USD/DKP Pair(PancakeSwap LP)에서 259,390개의 BSC-USD 토큰을 빌려서 공격자의 컨트렉트(0xf34ad6)에 전송합니다. 이 과정에서 BSC-USD/DKP 유동성 풀의 BSC-USD 토큰이 빠져나가면서 DKP 가격이 하락하게 됩니다. 이후 pancakecall() 함수를 통해 exchange()함수를 실행하며 가격이 낮아진 DKP를 BSC-USD 토큰 100개로 DKP 토큰 17,029개로 스왑합니다.
그런 다음 공격자는 주소 0xb24fc2에서 공격자의 컨트렉트(0xf34ad6)로 17,029 DKP를 전송했습니다. 이후, 갖고있던 BSC-USD토큰 259,390개를 BSC-USD/DKP 유동성 풀에 다시 돌려주면서 플래시론 공격 트랜잭션은 끝이 납니다.
이 과정에서 이미 공격자는 아주 저렴한 가격으로 17029개의 DKP토큰을 얻었습니다.
(3) 공격자의 컨트렉트(0xf34ad6)에 있는 17,029 DKP를 PancakeSwap의 swapExactTokensForTokensSupportingFeeOnTransferTokens함수를 실행하여 USDT(=BSC-USD)토큰으로 스왑합니다. 공격자는 DKP 토큰을 USDT로 다시 교환하여 약 $79,233 USDT의 이익을 얻었습니다.
| 취약점 분석 및 원인 :
AMM을 활용하는 DEX는 두 토큰의 균형 비율에 의해 가격이 결정됩니다. 갑자기 한쪽 토큰의 유동성이 빠지게 되면 균형 비율이 깨지면서 다른 한쪽 토큰의 가격은 하락하게 됩니다.
이번 DKP 토큰 사례는 플래시론의 트랜잭션 안에서 실행됬던 PancakeSwap exchange()함수의 취약점에서 발생했습니다. 플래시론을 통해 대출된 토큰은 유동성 풀 가격에 영향을 주면 안됬지만, exchange() 함수는 트랜잭션을 보낸 주소가 플래시론으로 부터 온 트랜잭션임을 감지하지 못하여 하락한 가격을 기준으로 토큰을 스왑해 주었습니다.
| 공격 예방 및 대책안 :
플래시론 공격은 디파이의 담보 대출과 동시에 암호화폐 구매 과정에서 발생하는 담보 평가를 일시적으로 조작함으로써 발생하였습니다. 이를 방지하기 위해 많은 디파이 프로젝트들이 오라클 시스템을 개선하고 있습니다.
(1) 스왑 요청시, EOA(Externally Owned Account) 와 CA(Contract Address) 구분하기
[Solidity] 지갑주소(EOA)와 컨트렉트 주소(CA) 구분하기 || Solidity 0.8 | isContract ||
안녕하세요. 스마트 컨트렉트 개발자 개발이 체질의 최원혁입니다. 이번 게시글에서 Solidity에서 지갑 주소(EOA : Externally Owned Account)와 컨트렉트 주소(CA : Contract Address)를 구분하여 예외처리하는
borntodevelop.tistory.com
- Contract Address (CA) : 컨트렉트 주소
- Externally Owned Account (EOA) : 개인 소유 주소
플래시론은 단 한번의 트랜잭션을 통해 최종적으로 대출받은 암호화폐를 돌려줘야하며, 만약 지갑에 대출금이 없거나 부족하다면, 담보물을 회수하거나 트랜잭션을 실패시킵니다. 때문에 플래시론은, 한번의 트랜잭션을 통해 다른 스마트컨트렉트의 함수를 요청하며 이득을 본 후, 대출금을 그대로 돌려주는데 활용됩니다. 이 과정에서 다른 스마트컨트렉트가 요청받는 주소는 개인지갑주소가 아닌 컨트렉트 주소가 될 것입니다.
그래서 exchange 또는 swap 같은 기능을 가진 함수는 EOA로만 실행 시킬 수 있도록 구현하여 플래시론을 방지합니다.
(2) Time Weighted Average Price(TWAP) 활용하기
[DeFi Series] Time Weighted Average Price(TWAP) 알고리즘 파헤치기 || Math | DeFi ||
안녕하세요. 스마트컨트렉트 개발자 개발이 체질의 최원혁입니다. 이번 게시글에서 소개해드릴 DeFi Series는 Time Weighted Average Price(TWAP) 알고리즘입니다. TWAP란 풀어서 'Time Weighted Average Price' 이며
borntodevelop.tistory.com
TWAP란 풀어서 'Time Weighted Average Price' 이며 직역하면 '시간가중평균가격'입니다. 시시각각 변하는 가격을 주기적으로 기록하여 평균을 계산하는 공식으로, 주로 디지털 거래소 또는 탈중앙화 거래소(DEX)에서 디지털 자산의 가격을 조회할 때 사용됩니다.
대부분의 온체인 DEX는 가격 오라클 변조를 방지하기 위해 가격 쿼리에 대한 조작 방지 API를 제공합니다. 현재 가장 실행 가능한 방법은 시간 가중 평균 가격 책정(TWAP)입니다. TWAP는 거래가 완료된 후, 토큰의 가격을 저장하여 시세를 결정하는 알고리즘이기 때문에 플래시론 어택에 강한 보안성을 갖고 있습니다.
지금까지 플래시론 어택에 의한 DKP토큰 가격 조작 사건에 대해 알아봤습니다.
감사합니다.
| 🔎 Reference :
Decoding DKP Token‘s $80K Exploit | QuillAudits
On February 8, 2023, the DKP token on the BNB chain was attacked. The attacker used the flash loan technique to exploit the contract.
medium.com
댓글