Back to Blog

#4 GMX 사고: 크로스 컨트랙트 재진입 공격으로 4년된 보안 가드 우회

Code Auditing
February 10, 2026
7 min read

2025년 7월 9일, 탈중앙화 영구 포지션 플랫폼 GMX가 Arbitrum 네트워크의 V1 컨트랙트를 대상으로 한 익스플로잇 [1, 2]을 겪었으며, 약 4,200만 달러의 손실이 발생했습니다. 공격자는 크로스 컨트랙트 재진입 취약점을 악용하여 GLP 가격을 조작한 뒤, 왜곡된 가격을 이용해 GMX V1의 유동성 풀에서 기초 자산을 탈취했습니다.

배경

GMX V1 [3]은 Arbitrum에 배포된 탈중앙화 영구 포지션 거래 플랫폼입니다. 사용자는 허가 없이 비수탁 방식으로 다양한 암호화폐 자산에 대해 레버리지를 사용한 영구 계약을 거래할 수 있습니다. GMX V1은 단일 다중 자산 풀 설계를 따르며, 지원되는 모든 자산의 유동성이 통합된 Vault 시스템에 집계됩니다.

GMX의 포지션 관리

GMX의 포지션 관리는 두 단계로 이루어집니다. 구체적으로, 사용자는 OrderBook 또는 PositionRouter 컨트랙트와 상호작용하여 증가/감소 주문을 생성합니다. 그런 다음 권한이 부여된 키퍼(keeper) 계정이 사용자의 주문을 실행하며, 이 과정에서 ShortTracker 컨트랙트의 글로벌 숏 데이터와 Vault 컨트랙트의 해당 상태가 업데이트됩니다. 아래 두 그림은 GMX에서 포지션을 관리하기 위한 두 가지 실행 경로(orderbook-execution 경로와 router-execution 경로)를 보여줍니다. 이번 사건에서 공격자는 두 경로를 모두 사용하여 글로벌 숏 데이터를 조작하고 수익을 실현했습니다.

Orderbook-execution 경로

Router-execution 경로

GMX Vault

GMX의 Vault 컨트랙트는 사용자의 포지션 및 자산 관리(예: 손익 확정)를 담당합니다. 악의적인 상호작용을 방지하기 위해, Vault 컨트랙트는 "레버리지 창"이 열려 있을 때(즉, Vault 컨트랙트의 변수 isLeverageEnabledTimelock.enableLeverage() 함수를 통해 true로 설정된 경우)에만 접근할 수 있습니다. 이 유효성 검사는 주문 실행이 고정된 경로(orderbook-executionrouter-execution)를 따르도록 강제합니다.

GMX Short Tracker

ShortTracker 컨트랙트는 주문 실행 중 글로벌 숏 데이터(예: 변수 globalShortAveragePrice)를 추적하고 업데이트하는 역할을 합니다. orderbook-executionrouter-execution 경로에 따라, ShortTracker 컨트랙트의 updateGlobalShortData() 함수는 최신 글로벌 숏 데이터를 동기화하기 위해 사용자 주문 실행 전에 호출됩니다. 이 단계는 사용자 포지션에 대한 올바른 손익 실현을 보장합니다.

WETH 포지션 감소

다른 주문과 달리, orderbook-execution 경로를 통해 WETH 포지션을 감소시키면 OrderBook 컨트랙트의 _transferOutETH() 함수가 호출되어 WETH 토큰을 인출하고 네이티브 ETH 토큰을 사용자에게 전송합니다. 수신자 _receiver가 컨트랙트인 경우, sendValue()가 컨트랙트의 fallback() 함수를 트리거하여 잠재적인 재진입 취약점을 유발할 수 있습니다. 이번 사건에서 공격자는 이 재진입 취약점을 반복적으로 악용하여 상당한 수익을 탈취했습니다.

GLP 토큰

GLP(GMX Liquidity Provider) 토큰은 Vault 컨트랙트 내 다양한 자산에 대한 통합 지분을 나타냅니다. 사용자는 GLP를 민팅하고 소각함으로써 자산을 제공하고 환매할 수 있습니다.

GLP 가격은 다음 방정식으로 계산할 수 있습니다:

GLPPrice=AUMGLPTotalSupply\text{GLPPrice}= \frac{\text{AUM}}{\text{GLPTotalSupply}}

AUM=i=asset[0]assets(ΔGlobalShort[i]+AUMOther[i])\text{AUM} = \sum^{assets}_{i = asset[0]}(\Delta_{\text{GlobalShort[i]}} + \text{AUM}_{\text{Other[i]}})

ΔGlobalShort[i]=globalShortSize×(AssetMarketPriceglobalShortAveragePrice)globalShortAveragePrice\Delta_{\text{GlobalShort[i]}} = \frac{ \text{globalShortSize} \times (\text{AssetMarketPrice} - \text{globalShortAveragePrice} ) }{ \text{globalShortAveragePrice} }

여기서:

  • GLPTotalSupply는 GLP 토큰의 총 공급량을 나타냅니다.
  • AUM은 다음 두 가지 구성 요소로 이루어집니다.
    • ΔGlobalShort\Delta_{\text{GlobalShort}}는 모든 숏 포지션의 미실현 손익(uPnL)을 나타냅니다.
    • AUMOther\text{AUM}_{\text{Other}}는 LP가 제공한 유동성과 모든 롱 포지션의 미실현 uPnL을 나타냅니다. 이 항목은 수익 실현 이전 사건 전반에 걸쳐 거의 변하지 않았습니다.
  • AssetMarketPrice는 기초 자산의 시장 가격(USD 기준)입니다.
  • globalShortSize는 모든 숏 포지션의 합계(USD 기준)입니다.
  • globalShortAveragePrice는 집계된 글로벌 숏 포지션의 평균 진입 가격입니다.

이번 사건에서 공격자는 globalShortAveragePrice를 왜곡하여 GLP 가격을 조작하고 수익을 탈취했습니다.

취약점 분석

근본 원인은 OrderBook 컨트랙트의 크로스 컨트랙트 재진입 취약점입니다. 배경에서 설명한 것처럼, orderbook-execution 경로를 통해 WETH 포지션을 감소시키면 _transferOutETH()를 통해 수신자에게 저수준 폴백 호출이 트리거됩니다. 이 함수에는 nonReentrant 수정자가 적용되어 있지만, 이 가드는 OrderBook 컨트랙트 내의 재진입만 방지할 뿐 Vault에 대한 크로스 컨트랙트 호출은 방지하지 못합니다.

정상적인 운영 하에서, VaultincreasePosition()PositionRouterPositionManager를 통해서만 호출될 수 있으며, 이들은 각 포지션 변경 전에 ShortTracker를 호출하여 globalShortAveragePrice를 업데이트합니다. 공격자는 악의적인 컨트랙트를 수신자로 지정한 주문을 생성했고, 폴백 호출 중에 PositionRouter/PositionManager 및 관련 ShortTracker 업데이트를 우회하여 VaultincreasePosition()을 직접 호출했습니다. 공격자는 globalShortAveragePrice를 업데이트하지 않은 채 숏 포지션을 반복적으로 열고 닫음으로써 해당 변수를 점진적으로 왜곡했습니다. 왜곡된 값은 GLP 가격을 부풀렸고, 공격자는 GLP를 민팅하고 환매하여 수익을 탈취할 수 있었습니다.

공격 분석

공격자는 글로벌 숏 데이터를 조작하고 수익을 실현하는 일련의 트랜잭션을 실행했습니다. 구체적으로, 이번 사건은 세 단계로 나눌 수 있습니다: 준비, 가격 조작, 수익 실현. 관련된 모든 트랜잭션은 아래 표에 나열되어 있습니다.

Tx 번호 단계 설명 트랜잭션 시간 (UTC)
1 준비 공격 컨트랙트 배포 0xa4ece5...8cd4c93f Jul-09-2025 12:16:32 PM
2 WETH 롱 증가 주문 생성 0x0b8cd6...e90a4712 Jul-09-2025 12:22:28 PM
3 WETH 롱 증가 주문 실행 0x28a000...7bf0beef Jul-09-2025 12:23:23 PM
4 WETH 롱 감소 주문 생성 0x20abfe...decc49af Jul-09-2025 12:24:56 PM
5 가격 조작 1 WETH 롱 감소 주문 실행 0x1f00da...6a4a7353 Jul-09-2025 12:25:37 PM
6 WBTC 숏 감소 주문 실행 0x222cda…c994464e Jul-09-2025 12:25:43 PM
7 가격 조작 2 Tx 5와 동일 0xc9a469...221293c2 Jul-09-2025 12:26:25 PM
8 Tx 6과 동일 0x1cbf25...d853943a Jul-09-2025 12:26:30 PM
9 가격 조작 3 Tx 5와 동일 0xb58415...3b4cfb0b Jul-09-2025 12:27:22 PM
10 Tx 6과 동일 0x5a37ff...cb59c3b7 Jul-09-2025 12:27:28 PM
11 가격 조작 4 Tx 5와 동일 0xff6fe6...377bf108 Jul-09-2025 12:28:13 PM
12 Tx 6과 동일 0xbd65d6...e0187be6 Jul-09-2025 12:28:18 PM
13 가격 조작 5 Tx 5와 동일 0x105273...19fcdec6 Jul-09-2025 12:29:12 PM
14 Tx 6과 동일 0x0cdbac...84339fcc Jul-09-2025 12:29:17 PM
15 수익 실현 수익 실현 0x03182d....a32626ef Jul-09-2025 12:30:11 PM
16 환불 공격자에게 메시지 전송 0x92a39e...89547380 Jul-09-2025 02:04:19 PM
17 GMX 프로토콜에 응답 0x1d806c...919feac0 Jul-11-2025 06:29:00 AM
18 공격자에게 응답 0x9c4ca9...39fa27fc Jul-11-2025 07:42:17 AM
19 환불 0x62b845...99211841 Jul-11-2025 08:04:34 AM
20 환불 0x255d0a...9321b3 Jul-11-2025 08:08:27 AM
21 환불 0xceafc3...a6313b22 Jul-11-2025 10:17:23 AM

준비 단계

  1. (Tx 1) 공격자는 주문 실행 중 자산 수신자로 사용될 공격 컨트랙트를 배포했습니다. 공격 컨트랙트에는 악의적인 fallback() 함수가 포함되어 있었습니다.

  2. (Tx 2) 공격자는 OrderBook 컨트랙트에서 공격 컨트랙트를 위한 WETH 롱 증가 주문을 생성했습니다.

  3. (Tx 3) 키퍼가 공격자의 증가 주문(2단계에서 생성)을 실행하여 공격 컨트랙트를 위한 WETH 롱 포지션을 개설했습니다. (Tx 3).

  4. (Tx 4) 공격자는 OrderBook 컨트랙트에서 공격 컨트랙트를 위한 WETH 롱 감소 주문을 생성했습니다.

조작 단계

  1. (Tx 5) 키퍼가 orderbook-execution 경로를 통해 공격 컨트랙트의 WETH 롱 감소 주문(4단계에서 생성)을 실행했습니다. 실행 경로는 _transferOutETH()를 호출하여 공격 컨트랙트의 악의적인 fallback() 함수를 트리거했습니다.

    fallback()이 "레버리지 창"이 열린 동안 호출되었기 때문에, 공격 컨트랙트는 globalShortAveragePrice를 업데이트하지 않고 Vault 컨트랙트와 직접 상호작용하여 WBTC 숏 포지션을 개설했으며(increasePosition() 호출), 이후 WBTC 숏 감소/종료 주문을 생성했습니다.

  2. (Tx 6) 키퍼가 router-execution 경로를 통해 WBTC 숏 감소 주문(5단계에서 생성)을 실행했습니다. 이 실행은 또한 PositionRouter 컨트랙트의 폴백 메커니즘을 통해 WETH 롱 감소 주문을 생성했습니다.

    WBTC 숏 포지션이 globalShortAveragePrice를 업데이트하지 않고 개설되었기 때문에, 해당 변수를 업데이트하면서 포지션을 종료하면 globalShortAveragePrice가 예기치 않게 하락했습니다.

  3. (Tx 7-14) 공격자는 5-6단계를 4회 반복했습니다. 그 결과, globalShortAveragePrice1.08e35에서 1.9e33으로 왜곡되었습니다.

수익 실현 단계

  1. (Tx 15) 키퍼가 orderbook-execution 경로를 통해 WETH 롱 감소 주문(Tx 14에서 생성)을 실행했습니다. 이 실행은 OrderBook 컨트랙트의 재진입 취약점으로 인해 공격 컨트랙트의 수익 실현 로직을 트리거했습니다.

    1. 폴백 호출에서 공격 컨트랙트는 먼저 7,538,567e18 USDC의 플래시 론을 빌렸습니다.

    2. 공격 컨트랙트는 mintAndStakeGlp()를 호출하여 6,000,000e18 USDC를 사용해 4,129,578e18 GLP를 민팅했습니다.

    3. 공격 컨트랙트는 Vault.increasePosition()을 호출하여 나머지 1,538,567e18 USDC로 WBTC 숏 포지션을 개설했습니다. WBTC의 글로벌 숏 데이터가 극도로 왜곡되어 있었기 때문에, 주문 실행 시 AUM이 크게 증폭되어 GLP 가격이 급격히 상승했습니다.

    4. 공격 컨트랙트는 unstakeAndRedeemGlp()를 호출하여 증폭된 가격으로 GLP를 환매하여 Vault 컨트랙트의 여러 자산을 획득했습니다.

    5. 공격 컨트랙트는 Vault.decreasePosition()을 호출하여 WBTC 숏 포지션을 종료했습니다.

    6. 공격 컨트랙트는 8.b-8.e 단계를 4회 반복하여 Vault 컨트랙트의 모든 자산을 고갈시켰습니다.

    7. 공격 컨트랙트는 약 4,200만 달러의 수익을 남기고 플래시 론을 상환했습니다.

환불

공격자와의 협상(Tx 16-18)을 통해, 공격자는 최종적으로 10% 바운티를 수락하고 나머지 탈취한 자산을 반환했습니다(Tx 19-21).

요약

이번 사건은 Arbitrum의 GMX V1을 대상으로 한 다단계 익스플로잇으로, 약 4,200만 달러의 손실이 발생한 것으로 추정됩니다. 공격자는 OrderBook 컨트랙트의 재진입 취약점을 악용하여 globalShortAveragePrice 변수를 왜곡하고 GLP 가격을 부풀렸습니다. 조작된 가격을 활용하여 공격자는 상당한 양의 자산을 탈취했습니다.

주요 교훈:

  • 크로스 컨트랙트 재진입: 단일 컨트랙트의 nonReentrant 수정자는 동일 시스템 내 다른 컨트랙트로의 재진입을 방지하지 못합니다. 임시 플래그(예: "레버리지 창")에 의존하는 접근 제어 메커니즘은 플래그가 재설정되기 전에 외부 호출이 발생할 경우 우회될 수 있습니다.
  • 운영 보안: 이번 공격자는 총 15개의 트랜잭션을 실행하여 세 가지 뚜렷한 단계로 프로토콜을 익스플로잇했습니다. 이번 사건은 실시간 모니터링, 신속한 경보 및 효과적인 완화 플레이북의 중요성을 강조합니다.

참고 자료

  1. https://x.com/GMX_IO/status/1942955807756165574
  2. https://x.com/GMX_IO/status/1943336664102756471
  3. GMX V1

BlockSec 소개

BlockSec은 풀스택 블록체인 보안 및 암호화폐 컴플라이언스 제공업체입니다. 저희는 고객이 코드 감사(스마트 컨트랙트, 블록체인 및 지갑 포함), 실시간 공격 차단, 사건 분석, 불법 자금 추적, AML/CFT 의무 이행을 프로토콜 및 플랫폼의 전체 생애주기에 걸쳐 수행할 수 있도록 지원하는 제품과 서비스를 구축합니다.

BlockSec은 권위 있는 학술 컨퍼런스에 다수의 블록체인 보안 논문을 발표했으며, DeFi 애플리케이션의 여러 제로데이 공격을 보고했고, 2,000만 달러 이상을 구제하는 복수의 해킹을 차단했으며, 수십억 달러 규모의 암호화폐를 보호했습니다.

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