집중 유동성 틱 수학과 LP 회계
도입
집중 유동성은 같은 자본으로 더 깊은 호가를 만들 수 있지만, LP의 위험도 더 날카롭게 만든다. full-range AMM에서는 LP가 전체 가격 범위에 유동성을 제공한다. 집중 유동성에서는 LP가 특정 tick range를 선택하고, 가격이 그 범위 안에 있을 때만 active liquidity로 동작한다.
이 차이를 모르고 "LP 수익률"만 보면 위험을 놓친다. 가격이 range 밖으로 나가면 한쪽 자산으로 치우친 inventory를 들고 fee accrual도 멈출 수 있다. 따라서 concentrated liquidity 강의는 수학보다 회계가 먼저다. LP position을 token balance가 아니라 price range exposure로 읽어야 한다.
학습 목표
- 집중 유동성이 full-range liquidity와 다른 LP 손익 구조를 설명한다.
- tick range, active liquidity, fee accrual, out-of-range 상태를 구분한다.
- LP position을 사용자 잔액이 아니라 price range exposure로 기록한다.
개념 설명
BelowRange
전이 조건을 확인한다.
ActiveRange
전이 조건을 확인한다.
AboveRange
전이 조건을 확인한다.
Rebalanced
전이 조건을 확인한다.
| 상태 | fee accrual | inventory | 사용자 표시 |
|---|---|---|---|
| Below range | 없음 또는 제한적 | token0 중심 | range 아래, 재설정 검토 |
| Active | 발생 | 두 자산 혼합 | active liquidity |
| Above range | 없음 또는 제한적 | token1 중심 | range 위, inventory 편향 |
| Rebalanced | 새 range 기준 | 새 exposure | realized PnL 기록 |
코드로 확인하기
export function lpRangeStatus(currentTick: number, lowerTick: number, upperTick: number) { if (lowerTick >= upperTick) throw new Error("invalid tick range"); if (currentTick < lowerTick) return { state: "below", active: false, notice: "price below range" }; if (currentTick > upperTick) return { state: "above", active: false, notice: "price above range" }; return { state: "active", active: true, notice: "earning fees inside range" };}select position_id, owner, lower_tick, upper_tick, current_tick, fee_usd, inventory_value_usd, case when current_tick < lower_tick then 'below range' when current_tick > upper_tick then 'above range' else 'active' end as range_statefrom lp_positions;코드는 간단하지만 제품적으로 중요하다. LP dashboard가 APY만 보여주면 사용자는 fee를 벌고 있는지, 한쪽 자산으로 치우쳤는지, range를 재설정해야 하는지 알기 어렵다. range_state는 LP 화면의 핵심 필드다.
강의 포인트
| 관점 | 확인할 질문 | 증거로 남길 것 |
|---|---|---|
| Range | 현재 가격이 선택한 tick 안에 있는가 | lower, upper, current tick |
| Fees | 실제로 fee를 벌고 있는가 | accrued fee와 active time |
| Inventory | 어느 자산으로 치우쳤는가 | token composition |
| Rebalance | range 변경이 수익인지 손실인지 기록되는가 | realized PnL |
실무 예시
클라이언트[INDEXER] 사용자가 ETH/USDC LP position을 만들었다. 홈 화면에는 "APR 22%"가 보인다. 하지만 현재 가격이 upper tick 밖으로 나가면 이 APR은 과거 fee 또는 추정치일 수 있고, 새 swap에서는 fee를 못 벌 수 있다. 사용자에게는 range state, inventory, unclaimed fee, rebalance cost가 함께 보여야 한다.
운영자 관점에서는 JIT liquidity와 MEV도 본다. 큰 swap 직전에 liquidity가 들어왔다가 빠지는 패턴은 일반 LP의 fee share를 희석할 수 있다. 따라서 concentrated liquidity는 단순한 효율 개선이 아니라 execution microstructure와 연결된다.
흔한 오해와 실패 시나리오
| 오해 | 실패 시나리오 | 교정 방식 |
|---|---|---|
| range를 좁히면 항상 좋다 | 가격이 벗어나 fee가 멈추고 inventory가 치우친다 | active time과 rebalance cost를 본다 |
| APR은 현재 수익률이다 | 과거 fee와 incentive가 섞여 있다 | realized fee와 active liquidity를 분리한다 |
| LP token은 단순 예치증이다 | price range와 inventory exposure가 핵심이다 | position NFT metadata를 분석한다 |
| JIT liquidity는 무시해도 된다 | 큰 swap fee가 짧은 시간 liquidity에 포획된다 | block-level liquidity change를 본다 |
실습 과제
- LP range 상태 계산하기: currentTick, lowerTick, upperTick을 받아 active, below, above 상태와 사용자 경고 문구를 반환한다.
- LP 손익 분해표 만들기: fee income, inventory shift, price impact, LVR을 분리한 LP 포지션 리포트를 작성한다.
완료 기준
- tick range와 현재 가격을 비교해 active/out-of-range 상태를 계산했다.
- LP position의 fee, inventory, price range risk를 분리해 설명했다.
근거 자료
- 03 DEX and AMM
- Uniswap v3 Concepts