"가상 화폐 인쇄기" Popsicle 금융 이중 지출 공격 분석
BlockSec
2021-08-04 13:10
本文约3499字,阅读全文需要约14分钟
베이징 시간 2021년 8월 4일 오전 6시(블록 12955063), Popsicle Finance 프로젝트의 여러 스마트 풀이 공격을 받아 손실액이 2,000만 달러를 넘어섰습니다. DeFi 필드 펜 공격 중 하나입니다.

베이징 시간으로 2021년 8월 4일 오전 6시(블록 12955063), Popsicle Finance 프로젝트의 여러 스마트 풀이 공격을 받아 미화 2,000만 달러 이상의 손실을 입었습니다. 이는 지금까지 DeFi 분야에서 가장 큰 단일 손실입니다. 공격 중 하나. 분석 후공격 트랜잭션그리고 프로젝트 코드 우리는 이 공격이 프로젝트의 회계 허점을 악용하여 다중 인출(Double-Claiming Rewards)을 수행하는 공격임을 발견했습니다. 아래에서는 코드 및 공격 프로세스를 통해 공격을 분석합니다.

코드 분석

Popsicle Finance는 여러 체인을 포함하는 수율 최적화 플랫폼입니다.

사용자는 먼저 입금 기능을 호출하여 일정량의 유동성을 Smart Pool에 입금하고, 입금의 몫에 대한 증빙으로 Popsicle LP Token(이하 PLP Token)을 획득합니다. Popsicle Finance는 사용자가 제공한 유동성을 Uniswap과 같은 기본 풀에 예치하고 수입을 얻습니다.

사용자는 사용자가 보유한 PLP 토큰이 나타내는 유동성 공유에 따라 스마트 풀에서 유동성을 인출하기 위해 인출 기능을 호출할 수도 있습니다. Popsicle Finance는 Uniswap과 같은 기본 풀에서 PLP 토큰에 해당하는 유동성을 사용자에게 회수합니다.

마지막으로 사용자가 스마트 풀에 예치한 유동성은 시간이 지남에 따라 일정 수익률(Yield)을 생성하고 이는 계약의 사용자 상태에 누적됩니다. 사용자는 입금 보너스의 일부를 회수하기 위해 collectFees 함수를 호출할 수 있습니다.

이 공격의 핵심 기능은 collectFees 기능입니다. 코드를 단계별로 분석해 보겠습니다. 먼저 userInfo에 저장된 사용자 상태를 가져옵니다. 사용자 상태의 token0Rewards 및 token1Rewards는 사용자 예치로 인해 누적된 보상입니다.

다음으로 계약의 스마트 풀에 해당하는 토큰 쌍의 잔액을 계산합니다. 계약에 잔액이 충분하면 금액에 따라 보상이 사용자에게 지급되고, 그렇지 않으면 pool.burnExactLiquidity가 호출되어 기본 풀에서 유동성을 검색하여 사용자에게 반환합니다.

마지막으로 userInfo에 기록된 Rewards 상태가 업데이트됩니다. 이것을 보면 기관총 풀의 코드 구현은 상당히 논리적입니다. 그러나 함수 시작 부분에서 updateVault 한정자를 찾았습니다. 이 함수는 collectFees의 함수 본문보다 먼저 실행되며 허점은 updateVault 관련 함수에 있을 수 있습니다.

위는 updateVault 관련 기능의 구현입니다. 프로세스는 다음과 같습니다.

  • 먼저 _earnFees를 호출하여 기본 풀에서 누적 수수료를 가져옵니다.

  • 그런 다음 _tokenPerShare를 호출하여 token0PerShareStored 및 token1PerShareStored 매개변수를 업데이트합니다.이 두 매개변수는 풀의 각 공유가 나타내는 토큰0 및 토큰1의 수, 즉 스마트 풀의 각 공유가 나타내는 토큰 쌍의 수를 나타냅니다.

  • 마지막으로 fee0Earned 및 fee1Earned를 호출하여 이 사용자에 해당하는 예치금 보상(예: user.token0Rewards 및 user.token1Rewards)을 업데이트합니다.

위는 fee0Earned 및 fee1Earned 함수의 구현입니다.두 함수는 구현이 동일하며 둘 다 이러한 공식을 구현합니다(예: _fee0Earned).

user.token0Rewards += PLP.balanceOf(account) * (fee0PerShare - user.token0PerSharePaid) / 1e18

즉, 이 함수는 사용자가 소유한 PLP 토큰의 수를 기반으로 원래 user.token0Rewards를 기반으로 사용자에게 발행되어야 하는 수수료의 몫을 계산합니다.

그러나 우리는 이 함수가 점진적이라는 것을 알아차렸습니다. 즉, 사용자가 PLP 토큰을 보유하지 않더라도(PLP.balanceOf(account)가 0) 이 함수는 여전히 user.token0Rewards에 저장된 입금 보상을 반환합니다.

따라서 전체 계약에서 두 가지 중요한 논리적 결함을 발견했습니다.

  • 사용자의 입금 보상은 user.token0Rewards 및 user.token1Rewards에 기록되며 PLP Token 또는 기타 어떤 형태로든 연결되지 않습니다.

  • 예치금 회수에 사용되는 collectFees 함수는 부기의 user.token0Rewards 및 user.token1Rewards 상태에만 의존하며, 사용자가 PLP Token을 보유하지 않아도 해당 예치금을 인출할 수 있습니다.

우리는 공격 과정을 상상합니다:

  • 공격자는 기관총 풀에 일정량의 유동성을 예치하고 PLP 토큰의 일부를 얻습니다.

  • 공격자는 공격자의 입금 보상, 즉 상태 변수 user.token0Rewards의 값을 업데이트하는 collectFees(0, 0)를 호출하지만 실제로 입금 보상을 검색하지는 않습니다.

  • 공격자는 PLP 토큰을 자신이 통제하는 다른 계약으로 전송한 다음 collectFees(0, 0)를 호출하여 상태 변수 user.token0Rewards를 업데이트합니다. 즉, 공격자는 지속적으로 PLP Token을 순환시키고 collectFees(0, 0)를 호출하여 이러한 PLP Token에 해당하는 입금 보상을 복사했습니다.

  • 마지막으로 공격자는 위의 주소에서 collectFees 함수를 호출하여 실제 보상을 검색합니다. 현재 이러한 계정에는 PLP 토큰이 없지만 user.token0Rewards에서 계정이 업데이트되지 않았기 때문에 공격자는 여러 보상을 인출할 수 있었습니다.

실생활의 예를 들어 이 공격을 설명하면 은행에 돈을 입금하는 것과 같고 은행에서 예금 증명서를 주었지만 이 증명서에는 위조 방지 조치가 없으며 저에게 구속력이 없습니다. 몇 개를 복사했습니다. 증명서 사본을 다른 사람에게 보냈습니다. 각자이 증명서로 인해 은행에서이자를 인출했습니다.

공격 프로세스 분석

위의 코드 분석을 통해 Popsicle Finance의 스마트 풀 구현에 허점을 발견했습니다. 다음으로 공격 트랜잭션에 대한 심층 분석을 수행하여 공격자가 이 취약점을 악용하는 방법을 확인합니다.

공격자의 전반적인 흐름은 다음과 같습니다.

  • 공격자는 3개의 거래 계약을 생성했습니다. 그 중 하나는 공격 트랜잭션을 시작하는 데 사용되고 나머지 두 개는 PLP 토큰을 받고 Popsicle Finance Smart Pool의 collectFees 기능을 호출하여 입금 보상을 검색하는 데 사용됩니다.

  • 플래시론을 통해 AAVE에서 많은 양의 유동성을 빌려줍니다. 공격자는 Popsicle Finance 프로젝트에서 여러 스마트 풀을 선택하고, 이 스마트 풀에 해당하는 6가지 유형의 유동성을 AAVE에 빌려주었습니다.

  • Deposit-Withdraw-CollectFees 주기를 수행하십시오. 공격자는 Popsicle Finance 프로젝트 하에 다수의 스마트풀을 각각 공격하여 총 8번의 라운드를 수행하여 많은 양의 유동성을 빼갔다.

  • 플래시론을 AAVE에 반환하고 Tornado Cash를 통해 수익을 세탁하십시오.

이 공격 거래는 주로 여러 Deposit-Withdraw-CollectFees 루프로 구성되며 각 루프의 개략도는 위 그림과 같습니다. 분석에 따르면 논리는 다음과 같습니다.

  • 공격자는 먼저 플래시론에서 빌린 유동성을 기관총 풀에 예치하고 일정량의 PLP 토큰을 획득합니다.

  • 공격자는 PLP 토큰을 공격 계약 2로 전송합니다.

  • 계약 2를 공격하고 SmartGun Pool의 collectFees(0, 0) 함수를 호출하여 계약 2의 해당 user.token0Rewards 및 user.token1Rewards 상태를 설정합니다.

  • 공격 계약 2는 PLP 토큰을 공격 계약 3으로 전송합니다.

  • 공격 계약 2의 작동과 유사하게 공격 계약 3은 스마트 풀의 collectFees(0, 0) 함수를 호출하고 계약 2의 해당 user.token0Rewards 및 user.token1Rewards 상태를 설정합니다.

  • 공격 계약 2는 PLP 토큰을 다시 공격 계약으로 전송하며, 이는 머신건 풀의 인출 기능을 호출하여 PLP 토큰을 소각하고 유동성을 회수합니다.

  • 공격 계약 2와 공격 계약 3은 잘못된 tokenRewards 상태로 입금 보상을 검색하기 위해 collectFees 함수를 호출합니다.

이더리움 트랜잭션 추적 시각화 시스템(https://tx.blocksecteam.com/)에 따르면 트랜잭션 호출 다이어그램은 다음과 같으며 일부 중요한 트랜잭션은 빨간색으로 표시됩니다.

[가상 화폐 인쇄기] Popsicle Finance 이중 지출 공격 분석

이익 분석

이 공격의 총 수익: 2.56k WETH, 96.2 WBTC, 160k DAI, 5.39m USDC, 4.98m USDT, 10.5k UNI, 총 $20,000,000 이상.

이 공격 후 공격자는 먼저 Uniswap과 WETH를 통해 공격에서 얻은 다른 모든 토큰을 ETH로 교환한 다음 Tornado.Cash를 여러 번 사용하여 ETH를 세척했습니다.

핵심 보안 기술을 기반으로 BlockSec 팀은 오랫동안 개인 정보 컴퓨팅을 기반으로 DeFi 보안, 디지털 통화 자금 세탁 방지 및 디지털 자산 보관에 관심을 가져 DApp 프로젝트 당사자에게 계약 보안 및 디지털 자산 보안 서비스를 제공했습니다. 이 팀은 20개 이상의 최고 보안 학술 논문(CCS, USENIX Security, S&P)을 발표했으며, 파트너는 AMiner의 세계에서 가장 영향력 있는 보안 및 개인 정보 보호 학자로 선정되었습니다(2011-2020년 세계 6위). 연구 결과는 CCTV, 신화 통신 및 해외 언론 보도에 의해 수상되었습니다. 수십 개의 DeFi 보안 취약점 및 위협을 독립적으로 발견하고 2019 National Institutes of Health Privacy Computing Competition(SGX Track)에서 세계 1위를 차지했습니다. 기술에 기반한 이 팀은 개방성과 상생의 개념을 고수하고 커뮤니티 파트너와 협력하여 안전한 DeFi 생태계를 구축합니다.

QR코드를 스캔하여 더 흥미진진하게 주목하세요

https://www.blocksecteam.com/

contact@blocksecteam.com

BlockSec
作者文库