DeFi 보안 리뷰와 익스플로잇 분류
도입
DeFi 보안은 취약점 이름을 외우는 일이 아니다. reentrancy, oracle manipulation, governance capture, liquidation cascade, admin key failure는 서로 다른 precondition과 monitoring signal을 가진다. 같은 손실액이라도 원인이 다르면 다음 release gate가 달라진다.
이 강의는 audit checklist를 넘어 runtime security로 간다. launch 전에 invariant를 검증하고, launch 이후에는 oracle deviation, reserve drift, role change, cap usage, liquidation queue를 계속 본다. 보안 리뷰는 배포 전 문서가 아니라 운영 시스템이다.
학습 목표
- DeFi exploit을 code bug, oracle manipulation, economic attack, governance failure, ops failure로 분류한다.
- invariant fuzzing, oracle guard, access control, pause rule을 review checklist로 만든다.
- security review가 audit PDF가 아니라 release 이후 monitoring까지 이어져야 함을 이해한다.
개념 설명
Reentrancy
완화 장치를 정의한다.
Oracle manipulation
완화 장치를 정의한다.
Governance capture
완화 장치를 정의한다.
Ops key failure
완화 장치를 정의한다.
| Review 영역 | 질문 | 산출물 |
|---|---|---|
| Invariant | 어떤 관계가 항상 유지되어야 하는가 | fuzz/invariant tests |
| Oracle | 가격 입력이 조작 또는 지연될 수 있는가 | adapter guard |
| Access | 누가 parameter를 바꿀 수 있는가 | role map |
| Pause | 무엇을 끄고 무엇은 열어둘 것인가 | pause matrix |
| Monitoring | 사고 전 어떤 신호가 보이는가 | alert rule |
코드로 확인하기
export function alertSeverity({ oracleDeviationBps, reserveDriftBps, roleChanged }: { oracleDeviationBps: number; reserveDriftBps: number; roleChanged: boolean;}) { if (roleChanged || reserveDriftBps > 100) return "critical"; if (oracleDeviationBps > 150) return "high"; return "watch";}security_review: invariant: - total_assets_gte_total_debt_after_interest - lp_invariant_non_decreasing_after_fee runtime_alerts: - oracle_deviation_bps - reserve_drift_bps - privileged_role_change - liquidation_queue_size코드는 보안 리뷰가 production alert와 연결되어야 함을 보여준다. YAML의 invariant 이름은 실제 test file과 monitoring rule 이름으로 이어져야 한다.
강의 포인트
| 관점 | 확인할 질문 | 증거로 남길 것 |
|---|---|---|
| Precondition | 공격자가 무엇을 준비해야 하는가 | liquidity, role, oracle 상태 |
| Trigger | 어떤 event가 시작점인가 | tx, price, proposal |
| Detection | runtime에서 무엇을 볼 것인가 | alert metrics |
| Prevention | 다음 release에서 무엇을 막을 것인가 | test and gate |
실무 예시
컨트랙트[OPS] AMM pool에 oracle adapter를 붙였다. audit는 adapter가 compile되는지 확인할 수 있지만, 운영은 price deviation이 갑자기 커질 때 borrow와 liquidation을 어떻게 제한할지 정해야 한다. oracle incident는 code bug가 아니라 market condition과 함께 발생한다.
보안 리뷰 결과는 Jira ticket으로 끝나면 안 된다. invariant test, dashboard alert, admin timelock, emergency communication plan으로 내려와야 한다. 그래야 사고가 났을 때 누가 무엇을 해야 하는지 바로 보인다.
흔한 오해와 실패 시나리오
| 오해 | 실패 시나리오 | 교정 방식 |
|---|---|---|
| audit PDF가 보안이다 | runtime drift를 못 본다 | monitoring rule을 같이 만든다 |
| exploit class는 분류표다 | 대응 action과 연결되지 않는다 | precondition과 trigger를 남긴다 |
| pause는 emergency button이다 | 사용자 보호 행동까지 막을 수 있다 | action별 pause matrix를 둔다 |
| oracle guard는 backend 문제다 | contract와 backend 둘 다 필요하다 | adapter와 offchain alert를 같이 둔다 |
실습 과제
- Exploit class 매트릭스 만들기: reentrancy, oracle manipulation, governance capture, liquidation cascade, admin key failure를 precondition과 대응으로 나눈다.
- Runtime alert 규칙 작성하기: oracle deviation, reserve drift, role change, TVL drop을 감지하는 alert rule을 작성한다.
완료 기준
- 최소 5개 exploit class를 precondition, trigger, monitor, prevention으로 나눴다.
- DeFi 기능 하나에 대해 invariant test와 runtime alert를 함께 작성했다.
근거 자료
- 09 Risk and Security
- OWASP Smart Contract Top 10