← Dashboard
Ethereum Mainnet Chain ID: 1
PMA Case #—
xToken (xSNXa + xBNTa)
Flash Loan 기반 SNX 가격 조작으로 xSNXa 비정상 민팅 + xBNTa 검증 우회 — 단일 트랜잭션 이중 익스플로잇
Price Manipulation
Validation Bypass
Flash Loan
Single Tx
Dual Exploit
1. 프로토콜 의존성 구조도
전체 공격 흐름을 확인하세요.
Single atomic transaction — Block #12,419,918
Attacker CA 0xc5ac...2C11
Attacker EOA 0x07E0...dc3e
dYdX
Aave V1/V2
SushiSwap
Uniswap V2
Kyber Network
xSNXa Contract
Balancer Pool
xBNTa Contract
Bancor Pool
61,833 ETH 1
10k ETH → 564k SNX 5,536 ETH → 700k SNX 2
1,264,382 SNX → 818 ETH ⚠ SNX −98% 3
0.125 ETH → 1.28B xSNXa Kyber→Uni V2 4
Burn 415 ETH + Bal 2,046 ETH 5
Repay 61,833 ETH 6
3.9B xBNTa (×4) ⚠ BYPASS → 781,673 BNT 7
407,752 SNX + 781,673 BNT 8
ETH Token Dump/Exploit Mint Repay
2. 종합 대시보드
2-1. Transaction Info
Date / Time (UTC) 2021-05-12 13:43:46
Attack Type Flash Loan + Price Manipulation + Validation Bypass
Flash Loan 61,833.227 ETH (~$257M) from dYdX
Attacker Profit ~2,460 ETH + 407,752 SNX + 781,673 BNT (~$23.8M)
2-2. Attack Execution Flow
Phase A — SNX 가격 조작 + xSNXa 익스플로잇
Step 1: Flash Loan 조달
dYdX SoloMargin에서 61,833.227 ETH 플래시론 차입 (LogWithdraw #3). Flashbots MEV 프라이빗 트랜잭션.
61,833.227 ETH
Step 2: SNX 대량 확보
Aave V1에 5,000 ETH 예치 → 197,388.653 SNX 대출 (Borrow #12). Aave V2에 5,000 WETH 예치 → 366,730.659 SNX 대출 (Borrow #31). SushiSwap에서 5,535.939 ETH → 700,362.295 SNX (Swap #36). 총 1,264,481.607 SNX 확보.
10,000 ETH 예치 + 5,536 ETH 스왑 → 1,264,482 SNX
Step 3: SNX 가격 폭락 유도 ⚠
Uniswap V2 SNX/WETH 풀에 1,264,381.607 SNX 대량 매도 → 818.091 ETH 회수 (Swap #40). 풀 reserve: 1,452,829 SNX / 122 ETH. SNX/ETH 스팟 가격이 정상 대비 98% 폭락. 잔여 8.171 SNX는 풀에 추가 전송하여 가격 고정 (Sync #43).
1,264,381.607 SNX → 818.091 ETH (실효: 0.000647 ETH/SNX)
Step 4: xSNXa 비정상 민팅 ⚠
xSNXa mintWithEth(0.125 ETH) 호출. 컨트랙트가 Kyber를 통해 SNX 구매 → Kyber가 Uniswap V2(폭락 가격)로 라우팅: 0.12475 ETH → 1,474.547 SNX (ExecuteTrade #54, e2tRate=11,832 SNX/ETH). 그러나 NAV는 Synthetix 오라클($18.41) 기준으로 계산 → 1,282,360,456 xSNXa 발행 (Mint #56).
0.125 ETH → 1,282,360,456 xSNXa (mintAmount from Mint #56)
Step 5: xSNXa Burn + Balancer 매도
105,369,990 xSNXa burn → 414.812 ETH 직접 추출 (Burn #59, valueToSend). 잔여 ~1.18B xSNXa를 Balancer Pool(xSNXa/WETH/SNX)에서 16회 반복 LOG_SWAP: xSNXa→WETH 8회 합산 2,045.919 ETH (1,137+507+226+100+45+20+9+2), xSNXa→SNX 8회 합산 407,660 SNX (180,322+101,583+57,226+32,238+18,161+10,231+5,764+2,135).
Burn 414.812 ETH + Balancer 2,045.919 ETH + 407,660 SNX
Step 6: 역스왑 + 상환
Uniswap V2에서 830.321 ETH → 1,264,381.607 SNX 역매수 (Swap #64). SushiSwap에서 700,262.295 SNX → 5,514.688 ETH 역매도 (Swap #68). Aave V1 Repay: 197,388.653 SNX + 0.020 SNX 수수료 (Repay #73). Aave V1 Redeem: 5,000 ETH 회수 (RedeemUnderlying #78). Aave V2 Repay: 366,730.659 SNX (Repay #84). Aave V2 Withdraw: 5,000 WETH (Withdraw #90). dYdX 61,833.227 ETH 상환 (LogDeposit #176).
SushiSwap 순비용 21.25 ETH + Uni V2 순비용 12.23 ETH = 총 ~33 ETH
Phase B — xBNTa 검증 우회
Step 7: xBNTa 무한 민팅 ⚠
Bancor ETH→BNT→SPD 경로로 소량 SPD 취득 후 xBNTa 민팅 4회: 40,123,417 + 175,590,612 + 735,589,403 + 2,957,627,316 = 3,908,930,748 xBNTa (Transfer #192, #207, #222, #237). xBNTa 컨트랙트가 입력 토큰이 BNT인지 검증하지 않아 SPD(또는 임의 토큰)으로 민팅 가능.
0.12 ETH → 3,908,930,748 xBNTa (4회)
Step 8: xBNTa → BNT 매도
Bancor xBNTa/BNT 풀에서 1,954,465,374 xBNTa → 781,673.470 BNT 교환 (Conversion #242). 잔여 1,954,465,374 xBNTa는 EOA로 전송 (Transfer #247).
1,954,465,374 xBNTa → 781,673.470 BNT ($6.16M)
Final: 자산 전송 + 순이익 ✓
407,752.022 SNX → EOA (Transfer #177). 781,673.470 BNT → EOA (Transfer #241). 잔여 ETH 차익 ~2,460 ETH. 이후 1inch를 통해 SNX/BNT → ETH 스왑하여 최종 ~5,600 ETH 확보.
~2,460 ETH ($10.2M) + 407,752 SNX ($7.5M) + 781,673 BNT ($6.2M) ≈ $23.8M
2-3. Involved Entities & PnL
ATTACKER (EOA) Attacker EOA
+407,752 SNX + 781,673 BNT + ~2,460 ETH (~$23.8M)
VICTIM xSNXa Contract
−414.812 ETH (~$1.7M, NAV 7-8%)
VICTIM Balancer Pool (xSNXa/WETH/SNX)
−2,046 ETH − 407,660 SNX (~$16M)
VICTIM Bancor xBNTa/BNT Pool
−781,673 BNT (~$6.2M)
FLASH LOAN dYdX SoloMargin
61,833.227 ETH (순손실 0)
INTERMEDIARY Aave V1 + V2
564,119 SNX 대출/상환 (순손실 0, 수수료 0.02 SNX)
2-4. Oracle / Price Manipulation Detail
📊 정상 가격 (tokenPriceCache)
WETH $4,158.19
SNX $18.41
SNX/ETH 0.004427
BNT $7.88
⚠ Uni V2 조작 후 가격
Post-dump reserve 1,452,829 SNX / 122 ETH
SNX/ETH (조작) 0.0000841
SNX USD (조작) ~$0.35
가격 하락률 −98.1%
💰 Dump/Reverse 비용
SushiSwap 매수 5,535.939 ETH
SushiSwap 역매도 5,514.688 ETH
Uni V2 덤프 회수 818.091 ETH
Uni V2 역매수 830.321 ETH
순 슬리피지 ~33.48 ETH
🎯 Exploit 수익원
xSNXa Burn 414.812 ETH
Balancer→ETH (×8) 2,045.919 ETH
Balancer→SNX (×8) 407,660 SNX
xBNTa→BNT 781,673 BNT
2-5. Key Events
# Event From To Amount Deviation
1 LogWithdraw (Flashloan borrow #3) dYdX SoloMargin Attacker CA 61,833.227 ETH —
2 Deposit + Borrow (V1, #9/#12) Attacker CA Aave V1 5,000 ETH → 197,388.653 SNX —
3 Deposit + Borrow (V2, #24/#31) Attacker CA Aave V2 5,000 WETH → 366,730.659 SNX —
4 Swap (#36) Attacker CA SushiSwap 5,535.939 ETH → 700,362.295 SNX $32.9/SNX 126.5 SNX/ETH
5 Swap Dump ⚠ (#40) Attacker CA Uniswap V2 1,264,381.607 SNX → 818.091 ETH $2.69/SNX −85.4% from $18.41
6 ExecuteTrade (#54, Kyber→Uni V2) xSNXa Contract Kyber→Uni V2 0.12475 ETH → 1,474.547 SNX $0.35/SNX −98.1%, 11,832 SNX/ETH
7 Mint xSNXa ⚠ (#56) Attacker CA xSNXa 0.125 ETH → 1,282,360,456 xSNXa 조작가 민팅 NAV=Synthetix 오라클
8 Burn xSNXa (#59) Attacker CA xSNXa 105,369,990 xSNXa → 414.812 ETH —
9 LOG_SWAP (×16, Balancer #93~#168) Attacker CA Balancer Pool ~1.18B xSNXa → 2,046 ETH + 407,660 SNX —
10 Swap reverse (#64) Attacker CA Uniswap V2 830.321 ETH → 1,264,381.607 SNX $2.73/SNX 1,523 SNX/ETH (복원 중)
11 Swap reverse (#68) Attacker CA SushiSwap 700,262.295 SNX → 5,514.688 ETH $32.7/SNX 126.9 SNX/ETH, 정상 복원
12 Repay V1 (#73) + RedeemUnderlying (#78) Attacker CA Aave V1 197,388.653 SNX + 5,000 ETH 회수 —
13 Repay V2 (#84) + Withdraw (#90) Attacker CA Aave V2 366,730.659 SNX + 5,000 WETH 회수 —
14 LogDeposit (Flashloan repayment #176) Attacker CA dYdX 61,833.227 ETH —
15 Transfer SNX (#177) Attacker CA Attacker EOA 407,752.022 SNX —
16 Mint xBNTa ⚠ (×4, #192~#237) Attacker CA xBNTa 0.12 ETH → 3,908,930,748 xBNTa 검증 우회 SPD 경로
17 Conversion (#242, xBNTa→BNT) Attacker CA Bancor Pool 1,954,465,374 xBNTa → 781,673.470 BNT —
Total Profit ~2,460 ETH + 407,752 SNX + 781,673 BNT ~$23.8M
2-6. 유사 공격 비교
Date Protocol Attack Vector Loss Flash Loan
2020-02-15 bZx Hack I Oracle manipulation (Kyber/Uniswap) ~$350K dYdX
2020-02-18 bZx Hack II sUSD price pump (Kyber) ~$600K bZx iETH
2021-05-08 Rari Capital Cross-protocol reentrancy ~$11M —
2021-05-12 ★ xToken (xSNXa/xBNTa) SNX price dump + xBNTa validation bypass ~$24.5M dYdX 61,833 ETH
2021-05-19 Venus Protocol XVS price manipulation ~$200M —
2021-05-20 PancakeBunny BUNNY price manipulation ~$45M PancakeSwap
2-7. Root Causes & Lessons
🔴 취약점
xSNXa NAV를 Synthetix 오라클(TWAP, $18.41)로 계산하지만, 실제 SNX 매입은 Kyber→Uniswap V2 스팟 가격에 의존. 두 가격 소스 간 이원화를 플래시론으로 극단적으로 확대 가능.
xBNTa 민팅 시 입력 토큰 검증 부재 — BNT가 아닌 SPD 토큰(Bancor 경유)으로 무제한 xBNTa 발행.
Uniswap V2 SNX/WETH 풀의 유동성(~940 ETH)이 61,833 ETH 플래시론 대비 현저히 작아 가격 조작 비용이 극히 낮음.
xSNXa Burn 및 민팅 시 슬리피지 보호, 수량 제한(circuit breaker) 완전 부재.
🟢 교훈
NAV 계산과 실제 토큰 매입 모두 동일한 TWAP/Chainlink 오라클 사용 필수.
민팅 함수의 입력 토큰 검증은 require(token == BNT) 한 줄로 방어 가능 — 기본 보안 체크 누락.
단일 블록 내 민팅 수량 제한 + oracle deviation guard(가격 편차 체크) 도입 필수.
PeckShield 감사 이후 추가된 코드에 대한 재감사 미실시 — 배포 전 필수 재검토.
2-8. 공격 당시 토큰 가격 (tokenPriceCache)
SNX (Uni V2 조작)
~$0.35
−98.1%
xSNXa (pre-exploit)
$0.0163
💡 가격 조작 핵심: Uniswap V2 SNX/WETH 풀(reserve: ~188k SNX / ~940 ETH)에 1,264,382 SNX를 투입하여 풀 reserve를 1,452,829 SNX / 122 ETH로 변동 — SNX 스팟 가격 98% 폭락. xSNXa는 mintWithEth() 시 Kyber가 이 풀을 라우팅하여 0.125 ETH에 1,475 SNX를 구매하지만, NAV는 Synthetix 오라클($18.41)로 계산하여 12.8억 xSNXa 발행. 이 가격 이원화가 핵심 취약점.
3. 인터랙티브 Fund Flow
단계를 선택하여 자금 흐름을 추적하세요.
dYdX
Attacker CA
Aave V1/V2
SushiSwap
Uniswap V2
xSNXa
Balancer
xBNTa
Bancor
EOA (0x07E0)
61,833 ETH
10k ETH→564k SNX 5.5k→700k SNX
1.26M SNX→818 ETH
0.125→1.28B xSNXa
2,046 ETH+407k SNX
Repay 61,833
3.9B xBNTa →781k BNT
407k SNX+781k BNT
4. ETH Balance Waterfall
Flash loan 유입
Exploit 유입
유출
Net profit