Back to Blog

MetaPool의 동일한 취약점을 두 가지 방법으로 악용하는 방법 (Nerve Bridge / Saddle Finance): 보이는 것이 전부가 아니다

Code Auditing
May 6, 2022
7 min read

2022년 4월 30일, 공격자가 Nerve Bridge 사건과 동일한 취약점을 악용하여 Saddle Finance를 공격했습니다. 총 4,900 이더가 공격 대상이 되었습니다. 다행히도 그 중 1,360 이더는 저희가 성공적으로 구해냈습니다. 이 사건에 대한 자세한 설명은 공식 사후 분석에서 확인할 수 있습니다.

동일한 취약점이 악용되었음에도 불구하고, 공격 방식은 이전 사건과 다릅니다. 새로운 공격 방식이 예상만큼 간단하지 않기 때문에, 심층 조사를 수행하는 데 더 많은 노력을 기울일 필요가 있다고 생각합니다. 이 보고서에서는 먼저 취약점을 간략히 설명한 후, Nerve Bridge 사건의 원래 공격 방식을 검토합니다. 그런 다음 새로운 공격 방식을 이해하기 위해 공격 과정을 분석함으로써 Saddle Finance 사건에 집중합니다.

0x1. 배포된 컨트랙트 정보

관련 컨트랙트 주소는 다음과 같습니다:

  • 피해 MetaSwap 컨트랙트: 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
  • 취약한 MetaSwapUtils 컨트랙트: 0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17

주목할 점은, 검증된 MetaSwap 컨트랙트와 연관된 MetaSwapUtils 컨트랙트의 표시된 코드Settings에 명시된 주소의 실제 배포된 MetaSwapUtils 컨트랙트와 동일하지 않다는 것입니다. 아래와 같습니다:

따라서 이 두 MetaSwapUtils 컨트랙트를 혼동하지 마세요 :)

0x2. 취약점 분석

취약한 컨트랙트는 MetaPool에 속하며, 이는 이전 블로그에서 자세히 논의되었습니다. 간단히 말해, MetaPool은 원래 Curve가 단일 코인을 다른 (기본) 풀의 모든 코인과 함께 유동성을 희석시키지 않고 풀링할 수 있도록 설계되었습니다. 이는 본질적으로 안정 코인과 여러 다른 안정 코인으로 구성된 기본 풀의 LP 토큰으로 이루어진 풀입니다. MetaPool 설계에 대한 우려 사항이 있는데, 즉 MetaPool은 기본적으로 안정 코인의 가격을 유지하는 안정 코인 풀인 반면, 기본 안정 코인 풀의 LP 토큰은 안정 코인이 아니라는 점입니다.

실제로, 기본 안정 코인 풀의 LP 토큰 가격은 기본 풀의 getVirtualPrice 함수를 호출하여 얻을 수 있으며, 그 가격은 기본 풀이 부과하는 수수료의 누적과 함께 꾸준히 증가합니다. 이를 처리하기 위해 MetaPool은 아래에 표시된 것처럼 가격을 계산하기 전에 LP 토큰의 보유량을 스케일 업합니다.

따라서, 사용자가 LP 토큰을 안정 코인으로 스왑하는 경우, LP 토큰의 양은 가격을 계산하기 전에 스케일 업됩니다. 반대로, 사용자가 안정 코인을 LP 토큰으로 스왑하는 경우, 계산된 LP 토큰의 양은 전송 및 장부 기록 전에 스케일 다운됩니다.

위의 swapUnderlying 함수 코드 스니펫은 MetaPool의 안정 코인과 기본 풀의 안정 코인 간의 스왑에 사용됩니다. 두 개의 빨간 사각형에 표시된 것처럼, 이 함수는 들어오는 LP 토큰의 양을 스케일 업하고 교환되는 LP 토큰의 양을 스케일 다운합니다.

그러나 swap 함수의 구현은 swapUnderlying 함수의 구현과 일치하지 않습니다. 구체적으로, 취약점의 근본 원인은 LP 토큰의 양을 적절히 스케일 다운 및 업하지 않는 swap 함수(즉, _calculateSwap 함수)의 결함 있는 계산 구현 때문입니다. 아래에 표시된 것처럼, 왼쪽은 MetaPool의 취약한 코드를 보여주고, 오른쪽은 수정된 버전을 보여줍니다.

Nerve Bridge 사건의 공격자는 swap 함수와 swapUnderlying 함수 간의 불일치를 악용했습니다. (참고로 Nerve Bridge는 Saddle Finance의 포크 프로젝트입니다.) 그 후, Saddle Finance는 취약점을 수정하고 즉시 MetaSwapUtils 라이브러리의 새 버전(즉, V2)을 재배포했습니다.

안타깝게도, 알 수 없는 이유로 이더리움의 sUSD V2 MetaPool은 여전히 오래되고 취약한 MetaSwapUtils 라이브러리와 함께 배포되었습니다. 그 결과, 이 취약점은 4월 30일 다시 한번 공격자에 의해 성공적으로 악용되었습니다. 흥미롭게도, Nerve Bridge 사건에서 사용된 공격 방식과 달리, 다른 방식이 취약한 MetaPool을 공격하는 데 사용되었습니다.

0x3. Nerve Bridge 사건의 원래 공격 방식

원래 공격 방식을 검토하기 위해 아래 그림(이전 블로그 참조)을 재사용합니다.

취약한 swap 함수가 교환되는 LP 토큰(Nerve 3-LP)의 양을 스케일 다운하지 않기 때문에, 3단계에서 교환된 양(36,959)은 정상보다 더 큽니다. 그런 다음 공격자는 swapUnderlying 함수(취약점 없음)를 호출하여 36,959 Nerve 3-LP(4단계와 5단계)를 51,494 fUSDT로 판매하여 1,143 fUSDT의 이익을 얻습니다.

합리적으로, 이익은 다음과 같이 설명할 수 있습니다: 공격자는 3단계에서 더 많은 Nerve 3-LP를 수확하고, 그런 다음 swap 함수와 swapUnderlying 함수 간의 불일치를 활용하여 "정상" 가격으로 판매합니다.

0x4. Saddle Finance 사건의 새로운 공격 방식

최근 Saddle Finance 사건의 공격자는 swapUnderlying 함수를 사용하지 않고 동일한 취약한 swap 함수를 공격하는 다른 방식을 사용했습니다. 여기서는 하나의 공격 트랜잭션을 구체적인 예로 들어 과정을 설명합니다.

직관적으로, 3단계와 4단계의 모든 함의가 상쇄되기 때문에 어떠한 이익도 존재하지 않아야 할 것처럼 보입니다. 구체적으로, 3단계에서 공격자는 교환되는 LP 토큰(즉, saddleUSD)을 스케일 다운하지 않아 더 많은 saddleUSD를 스왑 아웃할 수 있습니다. 그러나 4단계에서 취약한 swap 함수가 가격 계산 전에 들어오는 saddleUSD의 양을 스케일 업하지 않기 때문에, 공격자는 필연적으로 더 적은 sUSD를 스왑 아웃하게 됩니다.

그러나 위 그림에서 볼 수 있듯이, 공격자는 3단계와 4단계의 스왑 쌍을 통해 2,059,771 sUSD의 이익을 얻었습니다. 이익의 이유를 파악하기 위해 가격 결정 메커니즘을 깊이 파고들어 공격 과정을 이해하는 심층 조사를 수행해야 합니다.

0x4.1 가격 결정 메커니즘

Saddle Finance의 MetaPool은 Curve의 가격 결정 공식을 상속받습니다:

함수의 그래프(n이 2일 때)는 아래 그림에서 파란색 곡선으로 표시됩니다. (공식의 설계는 Curve StableSwap 백서에서 찾을 수 있습니다.)

여기서 질문이 생깁니다: MetaPool은 이 공식을 사용하여 각 스왑의 가격을 어떻게 계산합니까?

n이 2이고 사용자가 dx0 token0을 사용하여 dx1 token1으로 스왑한다고 가정합니다. dx1의 계산 과정을 시뮬레이션할 수 있습니다. 각 스왑에서 A는 상수로 처리될 수 있으며, D는 가격 곡선에 영향을 줄 수 있는 유일한 변수입니다. 실제로, D는 풀이 부과하는 수수료의 누적과 함께 증가합니다. 구체적으로, 계산 과정은 다음 세 단계로 요약할 수 있습니다:

  • 단계 I: 현재 풀의 보유량(x0 및 x1)을 공식에 대입하여 현재 가격 곡선을 결정하는 현재 D를 계산합니다.
  • 단계 II: x0을 dx0만큼 증가시키고, 현재 Dx0을 공식에 대입하여 새로운 x1을 계산합니다.
  • 단계 III: 그런 다음, dx1은 새로운 x1과 이전 x1의 차이입니다.

token0이 기본 풀의 LP 토큰인 경우, 단계 II는 다음과 같이 됩니다:

여기서 baseVirtualPrice/1e18은 공격 중에 약 1.0033입니다. 반대로, 토큰이 기본 풀의 LP 토큰인 경우, 단계 III은 다음과 같이 됩니다:

D가 가격 곡선에 어떤 영향을 미치는지 이해하기 위해 예시를 사용하여 설명합니다. 사용자가 먼저 dx0 token0을 dx1 token1으로 스왑하고, 그런 다음 dx1 token1을 dx0' token0으로 스왑한다고 가정합니다.

위 그림에서 볼 수 있듯이, ②단계에서 첫 번째 스왑에 대한 수수료를 부과하므로 D가 증가하여 가격 곡선이 위쪽으로 이동합니다(검은색 곡선에서 파란색 곡선으로). 또한, 그림은 dx0'이 dx0'보다 작은 이유를 명확하게 설명합니다.

0x4.2 공격 분석

이익의 이유를 분석하기 위해, 취약한 버전과 수정된 버전의 MetaSwapUtils 라이브러리를 로컬에 배포하고 해당 시점의 피해 풀 상태를 사용하여 공격을 시뮬레이션했습니다. 또한, 이 시뮬레이션 중에 공격 과정을 이해하는 데 도움이 되는 몇 가지 값을 기록했습니다. 즉, A는 10,000, x_sUSD는 8,130,463, x_saddleUSD는 9,688,608, 그리고 D는 해당 시점에 17,818,392였습니다.

위 그림은 이익이 발생하는 스왑 쌍의 과정을 설명합니다:

  • 스왑-I: 14,800,272 sUSD를 9,657,586 saddleUSD로 스왑
  • 스왑-II: 9,657,586 saddleUSD를 16,860,043 sUSD로 스왑

구체적으로, 스왑-I은 다음 두 단계로 나눌 수 있습니다:

  • ①: 14,800,272 sUSD를 9,625,654 saddleUSD로 스왑. 이제 D는 17,931,435로 증가합니다(부과된 수수료로 인해).
  • ②: 취약한 MetaPool이 교환된 saddleUSD의 양을 스케일 다운하지 않기 때문에, 풀은 31,932 saddleUSD를 손실합니다. 이 손실로 인해 D15,736,195로 감소하여 가격 곡선이 아래쪽으로 이동합니다(검은색 곡선에서 회색 곡선으로).

마찬가지로, 스왑-II도 두 단계로 나눌 수 있습니다:

  • ③: 가격 곡선이 아래쪽으로 이동했기 때문에, 동일한 9,625,654 saddleUSD로 비용인 14,800,272 sUSD보다 훨씬 더 많은 16,891,906 sUSD를 스왑 아웃할 수 있습니다.
  • ④: 취약한 MetaPool이 가격 계산 전에 들어오는 saddleUSD의 양을 스케일 업하지 않기 때문에, MetaPool에 31,863 sUSD가 남아 가격 곡선을 위쪽으로 이동시킵니다(회색 곡선에서 파란색 곡선으로). 그럼에도 불구하고, 스왑 쌍은 여전히 2,059,771 sUSD의 이익을 냅니다.

분명히, 위의 분석은 공격자가 새로운 공격 방식을 사용하여 이익을 수확할 수 있었던 이유를 명확하게 설명합니다. 또한, 스왑-II에서 MetaPool에 sUSD가 남아 있기 때문에 원래 공격 방식이 새로운 것보다 더 효율적인 것으로 보입니다. 물론, 공격자는 풀을 고갈시키기 위해 여러 번 공격을 시작할 수 있으며, 이는 실제로도 관찰되었습니다.

0x5. 요약

조사 결과, 두 사건에서 이익의 근본 원인은 동일함을 알 수 있습니다. 구체적으로, 첫 번째 스왑(LP 토큰을 위한 스왑)이 취약한 MetaPool의 D를 감소시키고, 이는 가격 곡선을 아래쪽으로 이동시킵니다. 그 이동이 이후의 가격 결정에 크게 영향을 미치며, 이후 이익의 주요 원인이 됩니다.

BlockSec 소개

BlockSec은 2021년 전 세계적으로 저명한 보안 전문가 그룹에 의해 설립된 선구적인 블록체인 보안 회사입니다. 이 회사는 대중 채택을 촉진하기 위해 신흥 Web3 세계의 보안과 사용성을 향상시키는 데 전념하고 있습니다. 이를 위해 BlockSec은 스마트 컨트랙트 및 EVM 체인 보안 감사 서비스, 보안 개발 및 위협 사전 차단을 위한 Phalcon 플랫폼, 자금 추적 및 조사를 위한 MetaSleuth 플랫폼, 그리고 크립토 세계에서 web3 빌더들이 효율적으로 서핑할 수 있도록 돕는 MetaDock 확장 프로그램을 제공합니다.

현재까지 이 회사는 MetaMask, Uniswap Foundation, Compound, Forta, PancakeSwap 등 300개 이상의 저명한 고객을 대상으로 서비스를 제공했으며, Matrix Partners, Vitalbridge Capital, Fenbushi Capital을 포함한 저명한 투자자들로부터 두 차례의 자금 조달 라운드에서 수천만 달러를 받았습니다.

공식 웹사이트: https://blocksec.com/

공식 트위터 계정: https://twitter.com/BlockSecTeam

Sign up for the latest updates
~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리
Security Insights

~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리

이 주간 블록체인 보안 리포트는 2026년 6월 22~28일 발생한 주요 사건 2건을 다루며, 이더리움과 카르다노에서 약 410만 달러의 피해가 확인됐습니다. Taiko 브릿지 공격은 노출된 SGX 서명 키와 디버그 엔클레이브를 거부하지 못한 증명 정책 결함을 이용해 악성 증명자를 등록하고 L2 상태 증명을 위조했습니다. SecondFi 지갑은 Ed25519 논스 도출 시 비밀 입력이 제거되는 결함으로 공개 트랜잭션 데이터만으로 개인 키 복구가 가능했습니다.

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리
Security Insights

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리

이 주간 블록체인 보안 보고서는 2026년 6월 15일~21일을 다루며, 이더리움과 BNB 체인에서 3건의 주요 사고가 발생해 약 $18.3M의 손실이 발생했습니다. jaredFromSubway 사건은 MEV 봇이 차익거래를 위해 신뢰할 수 없는 제3자 컨트랙트에 자산을 승인한 역방향 승인 공격으로, 가짜 래퍼 토큰과 스왑 풀을 이용해 약 $15M 손실이 발생했습니다. Aztec은 이스케이프 해치 ZK 회로의 제약 누락으로 공격자가 가짜 머클 트리로 온체인 검증을 통과했습니다.

Web3 컴패니언: 오픈소스 보안 에이전틱 지갑

Web3 컴패니언: 오픈소스 보안 에이전틱 지갑

BlockSec가 Web3 Companion을 오픈소스로 공개했습니다. 이 보안 중심의 에이전트 지갑은 자체 AI 에이전트를 신뢰하지 않는 방식으로 설계되었으며, 키 격리, 강력한 정책, Passkey를 활용해 온체인 자산을 보호합니다.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit