Back to Blog

#6: Hundred Finance 사건: 취약한 포크 프로토콜에서 정밀도 관련 익스플로잇 파동의 촉매제

Code Auditing
February 16, 2024
5 min read

2023년 4월 16일, Compound V2의 포크인 Hundred Finance가 공격을 받아 약 740만 달러의 손실이 발생했습니다. 이 공격에는 두 가지 주요 문제가 포함되어 있었습니다:

  • 정밀도 손실 문제 (잘못된 반올림 문제);
  • 빈 마켓(empty markets), 이를 통해 해커가 exchangeRate를 조작할 수 있었습니다.

DeFiLlama에 따르면 가장 많이 포크된 대출 프로토콜인 Compound V2는 100개 이상의 포크를 보유하고 있습니다. OpenZeppelin의 감사를 받고 실전에서 검증된 이 컨트랙트는 안전하다고 여겨졌습니다. 그러나 Hundred Finance 공격은 특히 낮은 유동성 환경에서 정밀도 손실이 DeFi 프로토콜 보안에 치명적인 영향을 미칠 수 있음을 보여주었으며, Midas와 Radiant 같은 유명 포크들에서도 유사한 취약점 악용 사례가 연이어 발생하는 계기가 되었습니다.

더 깊이 이해하고자 하신다면 전체 분석 자료를 참고하시기 바랍니다. 아래에서는 2023년 10대 보안 사고 중 하나로서 이 사건에 대한 간략한 소개를 제공합니다.

배경

Hundred Finance 개요

Hundred Finance는 Chainlink 오라클을 활용하여 여러 메인넷에서 운영되는 Compound v2의 포크입니다. 전통적인 금융 대출 방식과 달리, Compound와 Aave 같은 DeFi 대출 프로토콜은 초과 담보 대출을 허용하지 않습니다. 간단히 말해, $100 상당의 토큰 A를 예치하면 $100 미만의 자산만 빌릴 수 있습니다. 대부분의 프로토콜의 위험 통제 계수에 따르면, 이 비율은 일반적으로 50%에서 80% 사이입니다.

대출 프로토콜에서 흔한 공격 방법으로는 가격 조작과 재진입(reentrancy)이 있습니다. 흥미롭게도, Hundred Finance는 이전에 2022년 3월 재진입 공격을 경험한 바 있지만, 이번 사건은 새로운 공격 벡터를 만들어냈습니다.

hToken

Compound와 Aave를 포크한 대출 프로토콜은 각 기초 토큰(담보)에 대응하는 회계 토큰을 생성합니다. Hundred Finance의 경우:

  • USDC는 hUSDC에 대응
  • WBTC는 hWBTC에 대응

기초 토큰과 hToken 사이의 교환 비율을 exchangeRate라고 합니다.

  • 자산을 예치할 때, 사용자는 hToken의 mint()를 호출해야 합니다.
  • 자산을 인출할 때, 사용자는 hToken의 redeem()을 호출해야 합니다.

exchangeRate

다음은 exchangeRate 계산 공식입니다: image

여기서:

  • getCash(): 이 hToken 컨트랙트가 소유한 기초 토큰 잔액의 양. 이것은 조작될 수 있는 핵심 파라미터입니다. 기억해 두시기 바랍니다.
  • totalBorrows(): 마켓에서 현재 대출된 기초 토큰의 양으로, 마켓 공급자에게 이자가 누적되는 기준 금액입니다.
  • totalReserves(): 준비금은 각 hToken 컨트랙트의 회계 항목으로, 프로토콜의 거버넌스를 통해 출금하거나 이전할 수 있는 현금으로 따로 적립된 과거 이자의 일부를 나타냅니다.
  • totalSupply(): 현재 이 hToken 마켓에서 유통 중인 토큰의 수량.

참고: hToken과 기초 자산 간의 exchangeRate(예: dai 대 hDai 또는 eth 대 hEth)는 0.020에서 시작하여 복리 시장 이자율과 동일한 속도로 증가합니다.

청산(Liquidation)

부실 채권을 방지하기 위해 대출 프로토콜은 모든 사용자가 다른 사용자의 채무를 청산할 수 있도록 허용합니다. 다음 예시를 통해 설명하겠습니다:

  1. 앨리스는 $100 상당의 BTC를 예치하고 $70 상당의 ETH를 빌립니다.
  2. ETH 가격이 상승하거나 BTC 가격이 하락하면, 앨리스의 자산이 청산 임계값에 도달할 수 있습니다.
  3. 밥은 일정량의 ETH를 사용하여 앨리스의 BTC를 청산함으로써, 앨리스의 부채를 건전한 수준으로 되돌려 프로토콜 자금의 안전을 보장할 수 있습니다(프로토콜은 청산을 시작한 사용자에게 보상을 제공합니다).

청산은 이번 공격의 핵심이 아니지만, 공격에 관여되었습니다. 여기서 우리는 단지 모든 사용자가 한 종류의 토큰으로 다른 사용자의 채무를 청산할 수 있으며, 이로 인해 해당 hToken이 감소한다는 점만 알면 됩니다.

취약점

정밀도 손실 문제

해커는 redeem()을 통해 담보를 인출할 때, 차감해야 할 hToken 계산 결과가 1.99999992(2에 매우 가깝지만 2 미만)가 되도록 만듭니다. truncate()에서 정수로 변환할 때 내림(rounding down) 처리로 인해 최종 결과가 1이 됩니다.

exchangeRate

앞서 소개한 바와 같이, exchangeRate 계산에는 hToken 컨트랙트가 소유한 기초 잔액의 양을 나타내는 getCash()가 포함됩니다. 기초 토큰을 컨트랙트에 직접 전송함으로써(mint 없이 단순 전송), 해커는 exchangeRate를 조작할 수 있습니다. 그러나 이 exchangeRate 문제만으로는 프로토콜의 보안을 위협하지 않는다는 점을 주목해야 합니다. 해커는 이것만으로는 이익을 얻을 수 없습니다. 이번 공격의 맥락에서, 이는 주로 해커의 이익을 증폭시켜 풀을 빠르게 고갈시키는 데 활용되었습니다. 그렇지 않았다면, 공격은 단 한 번의 결정적인 타격에서 여러 차례의 소규모 공격으로 바뀌어 상당한 영향을 미치기 위해 수많은 반복이 필요했을 것입니다.

간단히 말하면, 정밀도 손실이 이번 공격의 핵심 문제입니다.

공격 과정

다음은 공격 트랜잭션이며, Phalcon Explorer를 사용하여 이 복잡한 트랜잭션을 분석하겠습니다.

트랜잭션: 0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451

  1. 플래시론을 통해 Aave V3에서 500 WBTC를 빌립니다.

  2. 이전에 획득한 모든 hWBTC를 Redeem하여, hWBTC의 totalSupply를 0으로 초기화합니다.

이전 단계의 목적은 플래시론을 이용해 준비 자금을 마련하고 hWBTC를 새로운 마켓으로 초기화하는 것입니다.

  1. 두 번째 공격 컨트랙트(공격 컨트랙트 2라고 함)를 Create하고 모든 WBTC(500.30063816 WBTC)를 공격 컨트랙트 2로 전송합니다.

  2. 4 WBTC를 사용하여 Mint() hWBTC를 200 hWBTC 생성합니다.

  3. 199.99999998 hWBTC를 Redeem()하여, hWBTC 총량을 0.00000002(2 wei hWBTC)로 남겨둡니다.

  4. 모든 WBTC(500.30063816 WBTC)를 hWBTC로 전송합니다. 직접 전송은 hWBTC를 증가시키지 않으며, WBTC를 풀에 기부하는 것으로 볼 수 있습니다. 이 단계의 주요 목적은 앞서 언급한 exchangeRate를 조작하는 것입니다. 이 시점에서 hWBTC의 totalSupply는 여전히 2 wei hWBTC이지만, 이제 500.30064194 WBTC가 있어 exchangeRate가 원래의 수백 배가 됩니다.

  5. hETH 마켓에서 1021 Ether를 빌립니다.

  6. 50030063815 WBTC를 Redeem()합니다. 계산상 1.9999992 hBTC가 차감되어야 하지만, 정밀도 손실로 인해 1 hBTC만 차감되어 상당한 정밀도 손실(약 50%)이 발생합니다. 이 시점에서 해커는 500 WBTC + 1021 Ether를 보유하여 1021 Ether의 수익을 성공적으로 얻었습니다.

  7. 공격자는 남은 hWBTC를 liquidate()하여, 다른 마켓에 대한 공격을 계속하기 위한 준비로 totalSupply를 0으로 초기화합니다. hWBTC 내의 거의 모든 WBTC가 인출되었기 때문에, 해커는 단 0.000002 Ether만으로 이를 처리합니다.

  8. 다른 마켓에 대한 공격을 계속하여 전체 프로토콜을 고갈시킵니다.

  9. Aave에 플래시론을 상환합니다.

보안 권고사항

대출 프로토콜을 위한 완화 방안

이 문제는 특히 Compound와 Aave의 포크에서 광범위하게 나타납니다. 선제적인 접근 방법으로는, 새로운 마켓을 출시할 때 일부 회계 토큰을 발행하여 totalSupply가 절대 0이 되지 않도록 보장하는 것이 있습니다.

정밀도 손실 문제를 위한 완화 방안

정밀도 손실로 인한 일련의 문제를 더 잘 방지하기 위해, 최솟값을 설정하는 것이 실무에서 효과적인 방법입니다. 이 전략은 매우 작은 값을 처리할 때 정밀도 손실로 인한 심각한 영향을 피하는 데 도움이 됩니다.

이 시리즈의 다른 글 읽기:

Sign up for the latest updates
~$135만 달러 손실: BarnBridge, DeFiTuna | BlockSec 주간 보고
Security Insights

~$135만 달러 손실: BarnBridge, DeFiTuna | BlockSec 주간 보고

이 주간 보고서는 2026년 7월 13일부터 19일까지 발생한 2건의 보안 사고를 다루며, 이더리움과 솔라나에서 총 약 135만 달러의 손실이 발생했습니다. 솔라나 대출 프로토콜 DeFiTuna은 포지션 가치가 0일 때 부채와 무관하게 건전한 것으로 처리되는 결함으로 약 57만 달러를 잃었습니다. BarnBridge는 더 이상 사용되지 않지만 활성 상태인 이더리움 거버넌스 시스템을 악용한 공격자가 악의적인 제안을 통과시켜 약 77만 6천 달러의 USDC를 탈취당했습니다.

~$800K 손실: Hinkal 이중 지불 사건 | BlockSec 위클리
Security Insights

~$800K 손실: Hinkal 이중 지불 사건 | BlockSec 위클리

이 주간 보안 보고서는 2026년 6월 29일~7월 5일 이더리움에서 발생한 약 80만 달러 손실의 주요 사고 1건을 다룹니다. Hinkal 실드 풀 프로토콜이 이중 지출 공격으로 탈취되었으며, 레거시 노트 형식의 결함을 악용해 단일 예치금에서 다수의 널리파이어를 도출한 것으로 추정됩니다. 회로 수준 취약점, 공격 흐름, 널리파이어 기반 프라이버시 프로토콜의 시사점을 분석합니다.

뉴스레터 - 2026년 6월
Security Insights

뉴스레터 - 2026년 6월

이 월간 보고서는 2026년 6월의 3대 보안 사고를 다루며, 총 확인 손실액은 약 2,200만 달러입니다. 정교한 허니팟 공격으로 미확인 토큰 허용량을 악용해 JaredFromSubway의 MEV 봇에서 약 1,500만 달러가 유출됐습니다. 두 레거시 Aztec 롤업 배포에서 증명 정산 경계 취약점으로 약 435만 달러가 손실됐습니다. SecondFi의 Ed25519 구현 결함으로 지갑 개인키가 노출되어 374개 지갑에서 약 240만 달러가 유출됐습니다. 세 사고 모두 표면상 온전해 보였지만 실제로는 적용되지 않은 보안 보장이라는 공통 패턴을 공유합니다.

Best Security Auditor for Web3

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

BlockSec Audit