익스플로잇 사례를 지표와 의존성으로 읽기
도입
DeFi 사고를 읽을 때 손실액만 보면 배울 수 있는 것이 적다. 1억 달러 손실이라는 headline은 중요하지만, 학습자가 가져가야 할 것은 어떤 전제 조건이 쌓였고, 어떤 trigger가 실행됐고, 어떤 의존성 때문에 손실이 퍼졌는지다.
사고 분석은 보안 강의와 시장 구조 강의가 만나는 지점이다. reentrancy나 oracle manipulation은 contract bug처럼 보일 수 있지만 실제 손실은 liquidity depth, liquidation bot, governance delay, bridge pause, 사용자 UI copy와 함께 결정된다. 이 강의에서는 exploit report를 운영 가능한 runbook으로 바꾸는 방법을 연습한다.
학습 목표
- exploit headline을 손실액 중심이 아니라 precondition, trigger, blast radius로 해석한다.
- oracle manipulation, reentrancy, governance capture, bridge failure, liquidation cascade를 구분한다.
- incident review를 학습 산출물, 운영 runbook, dashboard alert로 바꾼다.
개념 설명
Oracle manipulation
완화 장치를 정의한다.
Reentrancy path
완화 장치를 정의한다.
Liquidation cascade
완화 장치를 정의한다.
Governance capture
완화 장치를 정의한다.
| 사고 읽기 단계 | 질문 | 산출물 |
|---|---|---|
| Precondition | 공격 전 어떤 조건이 필요했는가 | thin liquidity, bad parameter, privileged role |
| Trigger | 어떤 transaction이나 price move가 시작점인가 | tx hash, oracle update, governance action |
| Exploit path | 어떤 accounting assumption이 깨졌는가 | call graph, state diff |
| Blast radius | 어떤 user, market, chain에 퍼졌는가 | affected accounts, exposure group |
| Containment | 무엇을 멈추고 무엇을 열어둬야 하는가 | pause scope, withdrawal rule |
| Follow-up | 재발 방지를 어디에 넣을 것인가 | invariant, dashboard alert, release gate |
사고 분석은 "누가 잘못했는가"보다 "어떤 가정이 코드와 운영에서 검증되지 않았는가"를 찾는 과정이다. oracle manipulation이면 price source만 보지 않는다. 그 가격이 lending collateral, liquidation incentive, vault share price, 사용자 표시 문구에 어떻게 쓰였는지 본다. reentrancy면 modifier 하나만 보지 않는다. 외부 call 전후로 accounting state가 어떤 순서로 업데이트되는지 본다.
코드로 확인하기
type IncidentSignal = { oracleDeviationBps: number; poolDepthUsd: number; healthFactorP10: number; privilegedAction: boolean;};export function classifyIncidentRisk(signal: IncidentSignal) { const alerts: string[] = []; if (signal.oracleDeviationBps > 150 && signal.poolDepthUsd < 5_000_000) { alerts.push("oracle-manipulation-watch"); } if (signal.healthFactorP10 < 1.05) { alerts.push("liquidation-cascade-watch"); } if (signal.privilegedAction) { alerts.push("governance-or-admin-action-review"); } return { severity: alerts.length >= 2 ? "critical" : alerts.length === 1 ? "high" : "watch", alerts };}incident_runbook: trigger: - oracle_deviation_bps_above: 150 - health_factor_p10_below: 1.05 immediate_actions: - freeze_new_borrow_if_oracle_status_is_stale - keep_repay_and_withdraw_paths_open_when_safe - snapshot_affected_positions evidence: - tx_hashes - oracle_round_ids - parameter_diff - affected_exposure_groups follow_up: - add_invariant_test - add_dashboard_alert - update_user_notice_copy이 코드는 사고를 자동 판정한다기보다 신호를 분류하는 기본 틀이다. 실제 운영에서는 false positive가 많아도 괜찮은 경고와, 즉시 거래를 막아야 하는 경고를 나눈다. runbook도 모든 기능을 멈추는 방향이 아니라 new borrow, repay, withdraw, claim처럼 action별로 분리해야 한다.
강의 포인트
| 관점 | 확인할 질문 | 증거로 남길 것 |
|---|---|---|
| Precondition | 공격 전에 어떤 약한 조건이 있었는가 | liquidity, parameter, role 상태 |
| Trigger | 사고를 시작한 onchain event는 무엇인가 | tx hash와 block number |
| Blast radius | 손실과 경고가 어디까지 퍼지는가 | affected positions, protocol edges |
| Remediation | 같은 사고를 다음 release에서 어떻게 막는가 | invariant, alert, governance gate |
실무 예시
운영[INDEXER] lending protocol에서 특정 collateral의 oracle price가 얇은 DEX pool에 의해 흔들렸다고 가정하자. 단순 사고 기록은 "oracle manipulation 발생"으로 끝난다. 좋은 교육용 사고 기록은 다르다. 공격 전 pool depth가 낮았는지, protocol이 그 pool을 가격 소스로 받아들였는지, liquidation threshold가 얼마나 공격자에게 유리했는지, keeper capacity가 충분했는지, 사용자에게 어떤 경고가 보였는지를 함께 남긴다.
이런 방식으로 기록하면 사고 사례는 공포 목록이 아니라 설계 체크리스트가 된다. 다음 AMM 강의에서는 pool depth와 slippage를 보고, lending 강의에서는 health factor cluster를 보고, governance 강의에서는 parameter change delay를 본다. 사고 하나가 여러 강의의 검증 질문으로 분해된다.
흔한 오해와 실패 시나리오
| 오해 | 실패 시나리오 | 교정 방식 |
|---|---|---|
| exploit은 contract bug다 | market depth와 oracle policy가 손실 규모를 키운다 | code path와 market condition을 함께 본다 |
| pause는 항상 안전하다 | repay나 withdraw까지 막아 사용자의 손실 회피를 방해한다 | action별 pause scope를 둔다 |
| 사후 보고서는 법무 문서다 | 개발과 운영으로 돌아갈 remediation이 없다 | invariant, dashboard, runbook으로 변환한다 |
| 큰 사고만 배울 가치가 있다 | 작은 deviation이 같은 전제 오류를 드러낼 수 있다 | near miss를 학습 데이터로 남긴다 |
실습 과제
- 사고 타임라인 재구성하기: 알려진 DeFi 사고 하나를 골라 precondition, trigger, exploit path, containment, user impact 순서로 재구성한다.
- 사후 대응 체크리스트 작성하기: oracle, governance, liquidity, pause, disclosure, user compensation 관점에서 대응 체크리스트를 만든다.
완료 기준
- 하나의 DeFi 사고를 precondition, trigger, affected accounts, containment, follow-up으로 나눠 타임라인을 만들었다.
- 사고 유형별로 사전 탐지 신호와 사후 차단 액션을 최소 5개 이상 작성했다.
근거 자료
- 09 Risk and Security
- 11 Protocol Development
- Aave Liquidations Guide