#3 Balancer V2 사건: 반올림 불일치로 인한 불변량 붕괴와 체인 간 전파
2025년 11월 3일, Balancer V2의 Composable Stable Pool과 여러 체인에 걸친 다수의 포크 프로젝트들이 조직적인 익스플로잇 공격을 받아 총 1억 2,500만 달러 이상의 손실이 발생했으며, 그 중 약 4,500만 달러가 복구된 것으로 알려졌다. 근본 원인은 업스케일링과 다운스케일링 연산 간의 반올림 불일치로 인한 불변량 계산의 정밀도 손실에서 비롯된 가격 조작이었으며, 이는 궁극적으로 BPT(Balancer Pool Token) 가격 결정 로직을 왜곡시켰다.
이 사건은 손실 규모뿐만 아니라 근본적인 버그의 미묘함으로 인해 2025년 10대 보안 사건 중 하나로 손꼽힌다. 또한, 익스플로잇이 여러 체인에 걸쳐 빠르게 전파되어 Balancer와 그 포크 프로젝트 모두에 영향을 미쳤으며, 공유 코드베이스와 조합 가능한 DeFi 인프라가 시스템적 위험을 얼마나 크게 증폭시킬 수 있는지를 여실히 보여주었다.
BlockSec은 "심층 분석: Balancer V2 익스플로잇" [1]이라는 상세한 보고서를 발행하였으며, 이를 통해 기술적 세부 내용을 자세히 분석하였다. 아래에는 이 사건에 대한 간략한 설명을 제공한다.
배경
Balancer V2의 Composable Stable Pool
이번 공격에서 영향을 받은 구성 요소는 Balancer V2 프로토콜의 Composable Stable Pool [2]이었다. 이 풀은 거의 1:1 등가(또는 알려진 환율로 거래)를 유지할 것으로 예상되는 자산들을 위해 설계되었으며, 최소한의 가격 영향으로 대규모 스왑을 허용하여 유사하거나 상관관계가 있는 자산 간의 자본 효율성을 크게 향상시킨다. 각 풀은 풀의 유동성 공급자 지분을 나타내는 자체 Balancer Pool Token(BPT)과 해당 기초 자산들을 보유하고 있다.
-
이 풀은 Stable Math(Curve의 StableSwap 모델 기반)를 채택하며, 불변량 D는 풀의 가상 총 가치를 나타낸다.
-
BPT 가격은 다음과 같이 근사할 수 있다:
위 공식에서, 실제 자금 손실 없이도 D를 장부상 더 작게 만들 수 있다면 BPT 가격이 더 낮게 보일 것이다.
batchSwap()과 onSwap()
Balancer V2는 Vault [3] 내에서 멀티-홉 스왑을 가능하게 하는 batchSwap() 함수를 제공한다. 이 함수에 전달되는 매개변수에 의해 결정되는 두 가지 스왑 유형이 있다:
GIVEN_IN("Given In"): 호출자가 입력 토큰의 정확한 양을 지정하면, 풀이 해당 출력 양을 계산한다.GIVEN_OUT("Given Out"): 호출자가 원하는 출력 양을 지정하면, 풀이 필요한 입력 양을 계산한다.
일반적으로 batchSwap()은 onSwap() 함수를 통해 실행되는 여러 토큰 간 스왑으로 구성된다. 이 과정에는 불변량 D [1]와 연관된 양 계산이 필연적으로 포함된다.
스케일링과 반올림
다양한 토큰 잔액에 걸쳐 계산을 정규화하기 위해 Balancer는 다음 두 가지 연산을 수행한다:
- 업스케일링: 계산 수행 전 잔액과 금액을 통합된 내부 정밀도로 스케일 업한다.
- 다운스케일링: 결과를 원래 정밀도로 다시 변환하며, 방향성 반올림을 적용한다(예: 풀이 부족하게 청구하지 않도록 입력 금액은 보통 올림 처리되며, 출력 금액은 종종 내림 처리된다).
업스케일링과 다운스케일링은 이론적으로 쌍을 이루는 연산으로, 각각 곱셈과 나눗셈에 해당한다. 그러나 이 두 연산의 구현에는 불일치가 존재한다. 구체적으로, 다운스케일링 연산에는 divUp과 divDown의 두 가지 변형 또는 방향이 있다. 반면, 업스케일링 연산에는 mulDown이라는 단 하나의 방향만 존재한다.
취약점 분석
근본적인 문제는 BaseGeneralPool._swapGivenOut() 함수의 업스케일링 과정에서 수행되는 내림 반올림 연산에서 비롯된다. 특히, _swapGivenOut()은 _upscale() 함수를 통해 swapRequest.amount를 잘못되게 내림 처리한다. 이렇게 반올림된 값은 이후 _onSwapGivenOut()을 통해 amountIn을 계산할 때 amountOut으로 사용된다. 이 동작은 반올림이 프로토콜에 유리한 방향으로 적용되어야 한다는 표준 관행에 어긋난다.
따라서 특정 풀(wstETH/rETH/cbETH)에서 계산된 amountIn은 실제 필요한 입력량을 과소 추정한다. 이를 통해 사용자는 하나의 기초 자산(예: wstETH)을 더 적은 양으로 다른 자산(예: cbETH)과 교환할 수 있게 되어, 유효 유동성 감소의 결과로 불변량 D가 낮아진다. 결과적으로, BPT 가격 = D / totalSupply이므로 해당 BPT(wstETH/rETH/cbETH)의 가격이 인위적으로 낮아진다.
공격 분석
공격자는 탐지 위험을 최소화하기 위해 두 단계의 공격을 실행했을 가능성이 높다:
- 첫 번째 단계에서는 단일 트랜잭션 내에서 핵심 익스플로잇이 수행되었으며, 즉각적인 수익은 발생하지 않았다.
- 두 번째 단계에서는 공격자가 별도의 트랜잭션에서 자산을 인출하여 수익을 실현했다.
첫 번째 단계는 매개변수 계산과 배치 스왑의 두 단계로 나눌 수 있다. 아래에서는 Arbitrum의 예시 공격 트랜잭션(TX)을 사용하여 이 단계들을 설명한다.
매개변수 계산 단계
이 단계에서 공격자는 오프체인 계산과 온체인 시뮬레이션을 결합하여 Composable Stable Pool의 현재 상태(스케일링 팩터, 증폭 계수, BPT 비율, 스왑 수수료 및 기타 매개변수 포함)를 기반으로 다음(배치 스왑) 단계의 각 홉 매개변수를 정밀하게 조정했다. 공격자는 프론트러닝 노출을 줄이기 위한 목적으로 이러한 계산을 보조하는 보조 컨트랙트도 배포했을 수 있다. 자세한 내용은 [1]을 참조하라.
배치 스왑 단계
이후 batchSwap() 연산은 세 단계로 나눌 수 있다:
1단계: 공격자는 BPT(wstETH/rETH/cbETH)를 기초 자산으로 스왑하여 한 토큰(cbETH)의 잔액을 반올림 경계의 가장자리(amount = 9)로 정밀하게 조정한다. 이는 다음 단계에서의 정밀도 손실을 위한 조건을 설정한다.
2단계: 공격자는 조작된 양(= 8)을 사용하여 다른 기초 자산(wstETH)과 cbETH 간에 스왑을 실행한다. 토큰 양 스케일링 시 내림 반올림으로 인해 계산된 Δx가 약간 작아지며(8.918에서 8로), 이는 Δy를 과소 추정하게 되어 불변량이 더 작아진다(Curve의 StableSwap 모델의 D). BPT 가격 = D / totalSupply이므로 BPT 가격이 인위적으로 낮아진다.
3단계: 공격자는 기초 자산을 다시 BPT로 역스왑하여 잔액을 복원하는 동시에 낮아진 BPT 가격으로부터 이익을 얻는다.
요약
이 사건은 서로 다른 체인에 걸쳐 Balancer V2의 Composable Stable Pool과 다수의 포크 배포를 표적으로 한 일련의 조직적인 익스플로잇 트랜잭션을 포함하여 상당한 손실을 초래했다. 첫 번째 익스플로잇 이후 모방 트랜잭션이 빠르게 등장하면서, 공격 패턴이 노출되면 얼마나 빠르게 전파될 수 있는지를 보여주었다.
주요 교훈:
- 반올림 및 정밀도 처리: 토큰 양에 대한 모든 스케일링 및 정밀도 연산은 프로토콜에 유리한 방향으로 반올림되어야 한다.
_upscale()(내림 전용)과 다운스케일링 연산(방향성 반올림) 간의 단 하나의 불일치만으로도 악용 가능한 가격 왜곡을 만들어내기에 충분했다. - 보안의 군비 경쟁: 공격자는 탐지를 피하기 위해 조작과 수익 추출을 별도의 트랜잭션으로 분리했다. 탐지 시스템은 개별 트랜잭션만 표시하는 것이 아니라 관련 트랜잭션들을 상호 연관시켜야 한다.
- 운영 보안: 익스플로잇 패턴이 공개되자 모방 공격자들이 수 분 내에 여러 체인에서 이를 복제했다. 코드베이스를 공유하는 프로토콜들은 조율된 모니터링과 신속한 크로스체인 일시 중지 기능이 필요하다.
참고 문헌
-
https://blocksec.com/blog/in-depth-analysis-the-balancer-v2-exploit
-
https://docs-v2.balancer.fi/concepts/pools/composable-stable.html
-
https://docs-v2.balancer.fi/reference/swaps/batch-swaps.html
BlockSec 소개
BlockSec은 풀스택 블록체인 보안 및 암호화폐 컴플라이언스 제공 업체입니다. BlockSec은 코드 감사(스마트 컨트랙트, 블록체인 및 지갑 포함), 실시간 공격 차단, 사건 분석, 불법 자금 추적, AML/CFT 의무 준수 등을 프로토콜 및 플랫폼의 전체 생애주기에 걸쳐 고객이 수행할 수 있도록 돕는 제품과 서비스를 구축합니다.
BlockSec은 권위 있는 학술 컨퍼런스에서 다수의 블록체인 보안 논문을 발표했으며, DeFi 애플리케이션의 여러 제로데이 공격을 보고하고, 다수의 해킹을 차단하여 2,000만 달러 이상을 구제했으며, 수십억 달러 상당의 암호화폐를 보호했습니다.
-
공식 웹사이트: https://blocksec.com/
-
공식 트위터 계정: https://twitter.com/BlockSecTeam
-
🔗 BlockSec 감사 서비스 : 요청 제출



