지난 한 주(2026/08/03 - 2026/08/09) 동안 총 약 $1.6M의 손실을 초래한 주목할 만한 보안 사고 2건이 다음과 같이 소개됩니다.
| 날짜 | 사고 | 유형 | 추정 손실 |
|---|---|---|---|
| 2026/08/03 | LpdFi | 가격 조작 | ~$697K |
| 2026/08/03 | Moke Token | 가격 조작 및 회계 오류 | ~$906K |
- LpdFi는 포지션 평가와 이자 상환 모두에 조작 가능한 AMM 준비금을 사용하는 시스템적 위험을 잘 보여주기 때문에 선정되었습니다. 공격자는 먼저 현물 가격 조작을 통해 기록된 원금을 부풀린 후, 직접 기부와
sync()를 통해 풀 준비금을 변경하여 과도하게 부풀려진 이자 청구를 실행 가능하게 만들었습니다. 이는 입금 평가, 이자 계산, 상환을 독립적인 작업으로 처리하는 것이 아니라, 전체 포지션 라이프사이클에 걸쳐 지급 능력을 검증하는 것이 얼마나 중요한지를 강조합니다. - Moke Token은 별개의 회계 메커니즘에 걸친 취약점들이 단일한 수익성 있는 공격으로 결합될 수 있음을 보여주기 때문에 선정되었습니다. 공격자는 현물 가격을 조작하여 청구 가능한
MOKE수량을 부풀리고, 동일한 LP 토큰을 여러 주소에 동기화하여 LP 보상 기록을 중복 생성한 후, 배당 시스템을 통해 결과 토큰을 추출 가능한BNB로 전환했습니다. 이는 조작에 강한 가격 소스를 사용하고 보상 회계를 실제 토큰 소유권과 동기화된 상태로 유지하는 것이 얼마나 중요한지를 강조합니다.
Web3 최고의 보안 감사 기관
출시 전 설계, 코드, 비즈니스 로직을 검증하세요
주간 하이라이트: LpdFi 프로토콜
이 사고는 조작 가능한 동일한 AMM 상태가 부채 생성과 자산 상환 모두를 관장했기 때문에 강조됩니다. 이는 프로토콜이 입금 평가, 이자 발생, 상환을 독립적인 단계로 처리하지 않고 전체 포지션 라이프사이클에 걸쳐 지급 능력을 검증해야 하는 이유를 보여줍니다.
2026년 8월 3일, BNB 체인의 LpdFi 프로토콜이 LPD/USDC PancakeSwap 페어에서 약 $697K를 탈취당하는 익스플로잇 피해를 입었습니다. LpdFi는 포지션의 기록된 가치와 이후 이자 지급 모두를 동일한 실시간 PancakeSwap 페어에서 도출했기 때문에, 해당 페어를 조작하면 두 가지 모두 왜곡되었습니다. 공격자는 실제 가치보다 훨씬 높게 평가된 포지션을 열고, 이자가 발생할 때까지 기다린 후, 부풀려진 이자 청구를 지급할 수 있도록 페어의 준비금을 이동시켜 프로토콜이 보유한 거의 모든 유동성을 고갈시켰습니다.
배경
LpdFi는 LPD 토큰을 중심으로 구축된 수익 프로토콜입니다. 사용자는 LPD를 예치하여 포지션을 생성합니다. 예치 시점에 프로토콜은 현재 LPD/USDC PancakeSwap 현물 가격을 사용하여 예치금을 평가하고, 그 결과를 주문의 USD 기준 원금인 uAmount로 저장합니다. 주문은 발행(issue) 단위로 이자를 발생시키며, 각 발행은 하루의 회계 기간이고 프로토콜은 각 주문의 총 이자를 기록된 원금에 따라 상한을 설정합니다.
사용자가 이자를 청구하면, 프로토콜은 LpdFi가 보유한 LP 토큰을 사용하여 LPD/USDC 페어에서 유동성을 제거함으로써 회계상의 이자를 USDC로 전환합니다. 상환된 USDC는 청구자와 수수료 주소 간에 분배됩니다. 따라서 포지션 라이프사이클의 양 끝, 즉 예치 시 평가와 상환 시 지급 모두 동일한 실시간 PancakeSwap 페어를 참조합니다.
취약점 분석
버그가 있는 컨트랙트는 0xce6a...f295e와 0x3876...273604입니다.
근본 원인은 LpdFi가 실시간 LPD/USDC 현물 가격과 준비금을 주문 회계 및 이자 상환 모두의 진실의 원천으로 사용했다는 점입니다. 두 값 모두 신뢰하기 안전하지 않습니다: 둘 다 단일 트랜잭션 내에서 충분한 임시 유동성을 가진 호출자가 이동시킬 수 있는 페어 준비금에서 도출됩니다.
예치 시, buy()는 token.price()로부터 토큰 수량을 계산합니다:

LPD.price()는 getReserves()를 통해 LPD/USDC 준비금을 직접 읽으므로, 기록된 원금은 현물 가격에 따라 변동됩니다:

상환 시, claimInterest()는 removeLp()를 호출하여 발생한 이자를 지급합니다:

removeLp()는 실시간 준비금 r1(또는 r0)으로부터 소각할 LP 토큰 수량을 계산합니다:

그 결과 두 가지 불변 조건이 깨집니다. 첫째, 기록된 원금이 현물 가격에서 도출되기 때문에, 예치금의 실제 가치보다 훨씬 큰 원금이 기록될 수 있으며 이는 이자 상한을 높입니다. 둘째, removeLp()가 실시간 준비금으로부터 LP 소각량을 산정하기 때문에, 특정 USDC 지급을 충족하기 위해 프로토콜이 소각해야 하는 LP 토큰의 수량이 청구 시점에 고정되지 않은 준비금 값에 의존합니다.
공격 분석
다음 분석은 트랜잭션 0xbb5b85...41c3588과 0x70bbe0...b3315d6을 기반으로 합니다.
-
1단계: 블록
113613923에서 공격자는 플래시 론 자금을 사용하여 LPD/USDC 페어에서 대규모USDC→LPD스왑을 수행했습니다. 이로 인해 풀의LPD준비금이 감소하고LPD.price()가 반환하는 현물 가격이 상승했습니다. -
2단계: 가격이 부풀려진 동안, 공격자는
buy()를 호출하여 과도하게 큰 주문을 열었습니다. 조작된 현물 가격으로 평가된 예치금은 USD 원금140,324,732로 기록되었습니다.

-
3단계: 다음 블록인
113613924에서 공격자는 프로토콜의 발행 경계를 넘었습니다. 단 한 블록만 경과했지만, 프로토콜은 각 발행 변경을 하루의 회계 기간으로 처리하므로, 부풀려진 원금에 대한 한 기간의 이자가 청구 가능해졌습니다. -
4단계: 청구 트랜잭션에서 공격자는
PoolManager를 통해730,607.755349USDC를 차입하고,3,440.992868USDC를 LPD/USDC 페어에 직접 전송한 후sync()를 호출했습니다. 원래 준비금 상태에서는 부풀려진 이자가LpdFi가 보유한 것보다 더 많은 LP 토큰을 요구하여 상환이 되돌아갔을 것입니다. 페어의 기록된USDC준비금을718,619.888284에서722,060.881152로 높임으로써, 공격자는removeLp()가 소각해야 하는 LP 수량을 줄여 프로토콜의 실제 LP 잔액 범위 내로 맞췄습니다.

- 5단계: 공격자는
claimInterest(0)을 호출했습니다. 부풀려진 원금은 한 발행에 대해701,623.66USDC의 청구 가능한 이자를 산출했습니다. 준비금 조작 후,removeLp()는LpdFi가 보유한 전체 LP 잔액과 거의 정확히 일치하는1,678,049.359669LP 토큰만 소각하면 되었습니다. 프로토콜은 총 LP 공급량의 약 97%를 소각하고693,529.790711USDC를 공격자에게 전송했으며, 공격자는 플래시 론을 상환하고 수익을 인출했습니다.
결론
이 사고는 조작 가능한 AMM 현물 준비금을 주문 회계와 상환 모두의 진실의 원천으로 사용한 것에서 비롯되었습니다. 평가와 상환이 동일한 실시간 풀을 읽는 독립적인 작업으로 처리되었기 때문에, 조작된 가격에서 기록된 원금이 풀의 실제 뒷받침과 결코 대조되지 않았습니다.
프로토콜은 실시간 AMM 준비금을 주문 원금이나 출금 회계의 진실의 원천으로 사용해서는 안 됩니다. 더 안전한 설계는 현물 평가 대신 최신성 및 편차 검사가 포함된 시간 가중 평균 가격과 같은 조작에 강한 가격 소스를 통해 각 예치금을 평가하고, 상환 전에 지급 능력 검사를 실행하여 청구가 포지션이 실제로 기여한 것보다 더 많은 뒷받침을 소각하지 않도록 합니다.
이번 주 추가 사고
Moke Token
2026년 8월 3일, BNB 체인의 Moke Token이 현물 가격 의존성과 중복된 LP 회계의 결합으로 약 $906K의 익스플로잇 피해를 입었습니다. 공격자는 현물 가격을 조작하여 청구 가능한 MOKE 수량을 부풀린 후, 이를 LP 배당 컨트랙트로 전송하고 배당 프로세스를 실행하여 MOKE를 BNB로 매도한 다음, 중복된 LP 기록을 통해 해당 BNB를 수집했습니다.
배경
Moke Token은 사용자 참여, 지연된 MOKE 출시, LP 보상, 추천 인센티브를 중심으로 구축된 BNB 체인 생태계입니다. 사용자는 USDT와 AC로 참여합니다. MOKE를 즉시 받는 대신, 각 참여는 MokeRelease가 관리하는 미래의 MOKE 출시를 부여하며 시간이 지남에 따라 청구 가능해집니다.
사용자가 청구하면, 컨트랙트는 정산된 MOKE/USDT 가격을 사용하여 출시된 USDT 가치를 MOKE로 전환한 후, 준비금 풀에서 해당 MOKE를 사용자에게 전송합니다. 이렇게 출시된 토큰은 기본적으로 제한되어 있으며 유동성 추가에 사용되는 컨트랙트와 같은 승인된 핸들러 주소로만 전송될 수 있습니다. LP 토큰을 보유한 사용자는 LP 지분에 따라 프로토콜의 세금 및 배당 풀에서 BNB 분배를 받습니다.
취약점 분석
버그가 있는 컨트랙트는 0x684d...b302a7와 0x5ae5...eba377입니다.
첫 번째 근본 원인은 현물 가격 의존성입니다. getMokeUsdtPrice()는 조작에 강한 가격 소스 없이 WBNB/USDT와 WBNB/MOKE 페어로부터 MOKE/USDT 가격을 도출합니다:

두 번째 근본 원인은 중복된 LP 회계입니다. _syncUserLP()는 lpToken.balanceOf(user)를 읽어 userLPRecord[user]에 기록함으로써 사용자의 LP 잔액을 기록합니다. 업데이트가 수동으로 트리거되고 현재 잔액만을 기준으로 하기 때문에, 동일한 LP 토큰이 여러 주소로 이동되어 각 주소에서 동기화될 수 있으며, 이는 기록된 총 LP 잔액과 그로 인해 얻는 배당 보상을 부풀립니다:

공격 분석
다음 분석은 트랜잭션 0xc0f1df...e26154와 0x077604...756a8f를 기반으로 합니다.
- 1단계: 익스플로잇 약 10일 전, 공격자는
MokeVault의participate함수를 통해USDT를 예치하여 출시 쿼터를 준비했으며, 하루 5.5% 속도로 해제되는45,000 USDT상당의MOKE출시 쿼터를 획득했습니다.

- 2단계: 공격자는
MOKE/WBNBLP 토큰을 발행하고MokeLPDividend에서syncUserLP를 호출하여 LP 잔액을 기록한 후, 동일한 LP 토큰을 다른 주소로 전송하고 동기화를 반복하여 하나의 토큰 세트에 대한 중복 LP 기록을 생성했습니다.

- 3단계: 공격자는 플래시 론을 이용해 대량의
BNB를 차입하고WBNB/USDT페어에서USDT로 스왑하여USDT현물 가격을 끌어올렸습니다. 그런 다음 공격자는MokeRelease에서MOKE가격을 업데이트했고, 정산된MOKE가격이 급격히 하락했습니다.

- 4단계: 조작된
MOKE가격이 적용된 상태에서, 공격자는MokeRelease에서claim을 호출하고24,766 USDT상당의 쿼터를MOKE토큰으로 상환하여 쿼터의 실제 가치보다 훨씬 많은MOKE를 수령했습니다.

- 5단계: 공격자는 출시된
MOKE를 화이트리스트에 등록된MokeLPDividend컨트랙트로 전송하고distributeDividend를 호출하여MOKE를BNB로 매도했습니다. 그런 다음 중복 LP 잔액이 기록된 주소들을 사용하여claimDividend를 호출하고 분배된BNB를 수집하여 총1,546 BNB를 획득했습니다.

결론
Moke Token은 두 가지 독립적인 결함을 결합했습니다: 플래시 론으로 이동시킬 수 있는 현물 가격과, 동일한 LP 토큰을 두 번 이상 계산하는 배당 회계. 두 가지 모두 단독으로는 함께 결합된 것만큼 큰 피해를 주지 않았을 것입니다.
프로토콜은 보안에 민감한 계산에 즉각적인 현물 가격을 피하고 대신 조작에 강한 소스를 사용해야 합니다. 토큰 잔액을 기준으로 하는 모든 회계는 잔액 변경과 함께 업데이트되어야 하므로, 동일한 토큰이 여러 주소에 걸쳐 계산될 수 없습니다.



