L2 Rollup 리스크 읽기
도입
L2를 지원할지 결정할 때 수수료와 TVL만 보면 위험하다. 결제 서비스는 "싸고 빠른 네트워크"가 아니라 "사용자가 돈을 넣고 빼고, merchant가 정산받고, 장애 때 설명할 수 있는 네트워크"를 필요로 한다. 그래서 rollup을 읽을 때는 proof system, data availability, exit window, sequencer/proposer failure, upgrade key, stablecoin asset model을 함께 봐야 한다.
이 강의의 목표는 L2BEAT 표를 그대로 따라 읽는 것이 아니다. 공개 risk data를 checkout release decision으로 바꾸는 훈련이다. 특정 L2가 Stage 1인지, fraud proof가 있는지, DA가 어디에 있는지보다 중요한 질문은 "이 조건에서 우리 결제 제품을 어디까지 열 수 있는가"다.
학습 목표
- L2 risk를 state validation, DA, exit window, sequencer failure, proposer failure, upgradeability, asset support로 분해한다.
- L2BEAT의 risk/stage 정보를 제품 지원 등급과 출시 차단 조건으로 바꾼다.
- sequencer outage, withdrawal delay, bridge upgrade가 사용자 결제 상태에 미치는 영향을 설명한다.
- L2별 monitoring, status page, refund/withdrawal UX를 설계한다.
개념 설명
핵심 가정 오류
finality와 attestation 조건이 명확한가
운영 상태 누락
route별 trust assumption이 분리되는가
학습 산출물 미흡
L2 risk intake sheet 작성
1. L2 risk는 "싸다/빠르다"보다 먼저 읽는다
| 축 | 제품팀이 물어야 할 질문 | 결제 서비스 영향 |
|---|---|---|
| State validation | fraud proof인가 validity proof인가, 실제로 permissionless인가 | invalid state가 통과할 위험과 withdrawal 확정 시간 |
| Data availability | transaction data가 Ethereum에 게시되는가, 외부 DA인가 | 사용자가 state를 독립적으로 재구성할 수 있는지 |
| Exit window | upgrade 전에 사용자가 빠져나갈 시간이 있는가 | 위험 upgrade 전에 treasury와 사용자 자금 회수 가능성 |
| Sequencer failure | sequencer가 멈추면 L1 경유 self-sequence가 가능한가 | checkout, refund, transfer 지연 |
| Proposer failure | state root 제출자가 멈추면 withdrawal이 가능한가 | merchant settlement와 treasury withdrawal 지연 |
| Upgradeability | bridge/rollup contract를 누가 얼마나 빨리 바꿀 수 있는가 | emergency key와 governance risk |
| Asset support | native USDC인지 bridged asset인지 | 회계, refund, redemption, user display |
L2BEAT의 Risk Analysis는 이런 축을 비교할 수 있게 해준다. 다만 숫자와 stage는 시간이 지나며 바뀌므로, product release 문서에는 반드시 접근일과 검토한 항목을 남겨야 한다.
2. Rollup, validium, optimium을 자금 회수 관점으로 본다
L2 분류는 기술 이름이 아니라 사용자가 자금을 회수할 수 있는 조건을 설명해야 한다.
| 분류 | 핵심 데이터 위치 | 장점 | 제품 리스크 |
|---|---|---|---|
| Rollup | L2 data가 Ethereum에 게시됨 | Ethereum 기반 검증/재구성 가능성이 높다 | proof, sequencer, proposer, upgrade 위험은 여전히 남는다 |
| Validium | transaction data가 off-chain DA 또는 committee에 의존 | 비용과 처리량에 유리할 수 있다 | DA committee 또는 외부 DA가 실패하면 withdrawal/검증 위험 증가 |
| Optimium | optimistic proof + off-chain DA 조합 | 빠르고 저렴할 수 있다 | fraud proof와 DA assumption을 모두 검토해야 한다 |
Ethereum.org의 data availability 설명은 data가 없으면 독립 검증이 불가능하다는 점을 강조한다. L2 지원 정책에서는 "DA가 어디냐"를 단순 기술 선택이 아니라 자금 회수와 dispute 가능성의 조건으로 다뤄야 한다.
3. Stage는 maturity signal이지 보안 보증서가 아니다
L2BEAT Stages Framework는 Stage 0, Stage 1, Stage 2로 rollup의 탈중앙화와 trust minimization 성숙도를 표시한다. 중요한 점은 Stage가 전체 보안 수준을 보장하지 않는다는 것이다. Stage가 높아도 proof system bug, contract bug, bridge implementation bug는 별도로 검토해야 한다.
| Stage 해석 | 결제 서비스에서의 사용법 |
|---|---|
| Stage 0 | 제한적 지원 또는 watchlist로 두고 고액 결제와 treasury 이동을 막는다 |
| Stage 1 | 제한적 또는 full support 후보로 두되 exit window, security council, proof maturity를 별도 확인한다 |
| Stage 2 | 더 강한 trust-minimized 후보지만 bug risk와 operational support는 별도 검증한다 |
| Not reviewed / non-rollup | default unsupported로 두고 예외 승인을 요구한다 |
지원 등급은 stage 하나로 결정하지 않는다. native stablecoin support, bridge policy, oracle/indexer 품질, RPC SLA, custody/on-ramp 지원까지 합쳐서 판단해야 한다.
4. Optimistic과 ZK의 차이는 withdrawal UX로 드러난다
| 항목 | Optimistic rollup | ZK rollup |
|---|---|---|
| 검증 방식 | fraud proof와 challenge window | validity proof |
| withdrawal UX | challenge period 때문에 finality가 늦을 수 있다 | proof generation/verification 지연에 영향을 받는다 |
| failure 관찰 | fraud proof actor, challenge window, proposer 상태 | prover, verifier, circuit, proof submission 상태 |
| 결제 정책 | 빠른 bridge나 liquidity route를 쓰면 별도 trust가 추가된다 | proof 지연 때 pending 상태와 fallback 필요 |
사용자에게 "L2라서 몇 초 안에 끝난다"고 약속하면 안 된다. L2 내부 transfer는 빠를 수 있지만, L1 withdrawal이나 cross-chain settlement는 별도 finality를 갖는다.
5. Sequencer outage는 단순 장애가 아니라 결제 상태 문제다
sequencer가 멈추면 새 checkout, refund, transfer, withdrawal이 각각 다르게 영향을 받는다. checkout은 route를 닫는 것이 맞을 수 있고, refund는 pending queue로 남겨야 할 수 있으며, treasury withdrawal은 L1 escape path를 확인해야 한다.
코드로 확인하기
위 신뢰 모델을 코드와 운영 규칙으로 확인한다. 메시지 상태, 최종성, 재시도, 관측 지점이 어디서 분리되는지 보는 것이 목적이다.
백엔드L2 지원 등급 정책 — TypeScript
L2BEAT/공식 문서에서 읽은 risk 등급을 그대로 결제 정책으로 변환한다. enable할 결제 기능을 등급으로 제한하면 코드 한 곳에서 governance가 가능하다.
type L2SupportTier = "full" | "limited" | "deposit-only" | "watchlist" | "unsupported";type L2Profile = { chainId: number; name: string; stage: "Stage 0" | "Stage 1" | "Stage 2"; hasFraudOrValidityProof: boolean; sequencerType: "centralized" | "decentralized" | "based"; withdrawalDelayDays: number; // optimistic 의 경우 7 l1EscapeHatchAvailable: boolean; l2beatRiskUrl: string; lastReviewedAt: string; tier: L2SupportTier;};export const L2_REGISTRY: L2Profile[] = [ { chainId: 8453, name: "Base", stage: "Stage 1", hasFraudOrValidityProof: true, sequencerType: "centralized", withdrawalDelayDays: 7, l1EscapeHatchAvailable: true, l2beatRiskUrl: "https://l2beat.com/scaling/projects/base", lastReviewedAt: "2026-05-14", tier: "full" }, { chainId: 42161, name: "Arbitrum One", stage: "Stage 1", hasFraudOrValidityProof: true, sequencerType: "centralized", withdrawalDelayDays: 7, l1EscapeHatchAvailable: true, l2beatRiskUrl: "https://l2beat.com/scaling/projects/arbitrum", lastReviewedAt: "2026-05-14", tier: "full" }];const TIER_FEATURES: Record<L2SupportTier, Array<"checkout" | "refund" | "withdrawal" | "merchant-settle">> = { full: ["checkout", "refund", "withdrawal", "merchant-settle"], limited: ["checkout", "refund"], "deposit-only": ["checkout"], watchlist: [], unsupported: []};export function isFeatureAllowed(chainId: number, feature: "checkout" | "refund" | "withdrawal" | "merchant-settle") { const p = L2_REGISTRY.find((r) => r.chainId === chainId); return p ? TIER_FEATURES[p.tier].includes(feature) : false;}인덱서Sequencer outage 감지 — block height 정체 알람
L2 RPC에서 blockNumber 가 N분 동안 멈추면 outage 신호. fallback RPC에서도 동일하면 route disable.
import { createPublicClient, http } from "viem";const STALL_SECONDS = 120;export async function detectSequencerStall(args: { chainId: number; rpcUrls: string[] }) { const samples = await Promise.all( args.rpcUrls.map(async (url) => { const c = createPublicClient({ transport: http(url) }); const block = await c.getBlock({ blockTag: "latest" }); return { url, blockNumber: block.number, timestamp: Number(block.timestamp) }; }) ); const now = Math.floor(Date.now() / 1000); const stalled = samples.every((s) => now - s.timestamp > STALL_SECONDS); if (stalled) { await disableRoutesForChain(args.chainId, "sequencer-stall"); await alerts.fire({ severity: "critical", reason: `chain ${args.chainId} sequencer appears stalled`, samples }); }}클라이언트Withdrawal 지연 UX 메시지 — 7일 optimistic case
사용자가 L2에서 L1으로 자금을 인출할 때 7일 챌린지 기간을 명시. status 추적 단계가 미정의면 안된다.
type WithdrawalStatus = "L2Submitted" | "WaitingChallenge" | "ReadyToFinalize" | "Finalized";export function renderWithdrawalCopy(s: WithdrawalStatus, submittedAt: Date, challengeDays = 7) { const elapsed = (Date.now() - submittedAt.getTime()) / 86_400_000; const remaining = Math.max(0, challengeDays - elapsed); switch (s) { case "L2Submitted": return `L2에서 인출 요청을 받았습니다. L1 확정까지 약 ${challengeDays}일 (챌린지 기간) 이 필요합니다.`; case "WaitingChallenge": return `챌린지 기간 진행 중 — 약 ${remaining.toFixed(1)}일 남았습니다.`; case "ReadyToFinalize": return `챌린지 기간이 끝났습니다. L1에서 인출을 확정해 주세요.`; case "Finalized": return `인출이 L1에서 확정되었습니다.`; }}강의 포인트
| 관점 | 수업 중 확인할 질문 | 산출물 |
|---|---|---|
| Risk intake | L2BEAT와 공식 문서에서 어떤 항목을 읽었는가 | L2 risk intake sheet |
| 지원 등급 | 이 L2에서 어떤 결제 기능을 열 수 있는가 | Full/Limited/Deposit-only/Watchlist/Unsupported 표 |
| UX | outage와 withdrawal delay를 사용자에게 어떻게 표시하는가 | status copy와 support macro |
| 운영 | 어떤 alert가 route disable로 이어지는가 | monitoring rule과 runbook |
| 재검토 | stage, proof, DA, native asset 정보가 바뀌면 누가 갱신하는가 | review cadence와 source register |
실무 예시
운영[BACKEND] 결제 서비스 L2 지원 등급
| 등급 | 허용 기능 | 요구 조건 | 사용자 고지 |
|---|---|---|---|
| Full support | checkout, refund, merchant settlement, treasury rebalancing | native stablecoin, 검증된 bridge path, 운영 SLA, withdrawal plan | 일반 지원 네트워크로 표시 |
| Limited support | checkout과 refund만 허용 | 일부 risk가 남지만 route disable과 support 대응 가능 | 지연 가능성 표시 |
| Deposit-only | 입금 확인만 허용하고 payout은 다른 네트워크 사용 | withdrawal 또는 settlement path가 약함 | 수령 전용 네트워크로 표시 |
| Watchlist | 내부 테스트와 소액 파일럿 | proof/DA/asset support가 성숙하지 않음 | public checkout에 노출하지 않음 |
| Unsupported | 모든 사용자 기능 차단 | exit, DA, bridge, asset support가 불충분 | 선택지로 표시하지 않음 |
L2 risk intake sheet 예시
| 항목 | L2 A | L2 B | 출시 판단에 미치는 영향 |
|---|---|---|---|
| Proof system | fraud proof 또는 validity proof | fraud proof 또는 validity proof | withdrawal 확정 시간과 invalid state 대응 |
| DA | Ethereum onchain 또는 외부 DA | Ethereum onchain 또는 외부 DA | 독립 검증과 자금 회수 가능성 |
| Exit window | regular/emergency window | regular/emergency window | 긴급 upgrade 전 사용자 탈출 가능성 |
| Sequencer failure | self-sequence 가능 여부 | no mechanism 또는 delay | route disable 기준 |
| Proposer failure | self propose, replace proposer, cannot withdraw | self propose, replace proposer, cannot withdraw | treasury withdrawal risk |
| Asset support | native USDC 또는 bridged USDC | native USDC 또는 bridged USDC | token display와 refund 정책 |
학습자는 실제 값은 L2BEAT와 각 L2 공식 문서에서 확인해 채운다. 이 강의 자료에는 고정 숫자를 박아두지 않는다. L2 risk 데이터는 운영 중 변하므로 release 시점에 다시 확인하는 절차가 더 중요하다.
Sequencer outage 사용자 문구
| 내부 상태 | 사용자 표시 | 운영 행동 |
|---|---|---|
| New checkout blocked | 이 네트워크 결제는 일시적으로 중단되었습니다 | route disable, status page update |
| Submitted but not confirmed | 네트워크 확인이 지연되고 있습니다 | tx monitoring, retry policy 확인 |
| Refund queued | 환불 요청을 접수했으며 네트워크 복구 후 처리됩니다 | refund queue owner 지정 |
| Withdrawal delayed | 출금 경로 확인이 지연되고 있습니다 | L1 escape path와 bridge status 확인 |
흔한 오해와 실패 시나리오
| 오해 | 실제 기준 |
|---|---|
| TVL이 크면 안전하다 | TVL은 risk axis를 대체하지 않는다 |
| Stage가 높으면 모든 문제가 해결된다 | Stage는 탈중앙화 성숙도 signal이고 bug/ops risk는 별도다 |
| native USDC가 있으면 L2 risk가 없다 | 자산 risk는 줄어도 sequencer, proof, bridge, upgrade risk는 남는다 |
| withdrawal delay는 treasury만의 문제다 | refund, merchant settlement, customer support에 직접 영향을 준다 |
| L2 장애는 chain team이 해결할 일이다 | 제품은 route disable, pending UX, refund queue, status page를 책임져야 한다 |
실습 과제
- 운영L2 risk intake sheet 작성: 선택한 L2 2개에 대해 state validation, DA, exit window, sequencer failure, proposer failure, upgradeability, native stablecoin support를 표로 정리한다.
- 백엔드[OPS] 결제 서비스 지원 등급 정하기: 각 L2를 Full support, Limited support, Deposit-only, Watchlist, Unsupported 중 하나로 분류하고 출시 차단 조건과 사용자 안내 문구를 작성한다.
- 클라이언트[OPS] Sequencer outage UX 설계: sequencer outage 또는 withdrawal 지연 상황에서 checkout, refund, treasury withdrawal, status page가 어떤 상태를 보여야 하는지 설계한다.
완료 기준
- L2BEAT risk axis를 결제 제품 질문으로 바꿨다.
- 선택한 L2 2개에 대해 지원 등급과 출시 차단 조건을 작성했다.
- sequencer outage와 withdrawal delay의 사용자 문구와 운영 행동을 분리했다.
- stage, DA, proof, native asset 정보의 재검토 주기와 source register를 정했다.
근거 자료
- L2 Rollup 리스크: 03-크로스체인-L2/02-L2-Rollup-리스크.md
- L2BEAT와 L2 리스크: 90-출처/원문-노트/L2BEAT와-L2-리스크.md
- L2BEAT Scaling Risk Overview: https://l2beat.com/scaling/risk
- L2BEAT Scaling Summary: https://l2beat.com/scaling/summary
- L2BEAT Stages Framework: https://l2beat.com/stages
- Ethereum.org Data Availability: https://ethereum.org/developers/docs/data-availability/