threat model
This page enumerates every attack class we've thought about, what an attacker would do, and the defense(s) that close it. If you can think of a class that isn't on this list, that's the interesting case — please report it.
T-1 · single-block flash-loan pump-and-dump
The original Uniperp attack. Flash-loan ETH → big direct buy → chain openLong calls at manipulated spot → self-liquidate via TWAP mismatch in the same tx.
Blocked by: D7 caps single-block curve advance at 5 ETH, so a 50-ETH pump reverts outright. D1 rejects opens against the manipulated spot if any pump does get through. D4 prevents same-block self-liquidation.
T-2 · multi-block sustained pump
Spread the attack: pre-buy under the D7 cap across many blocks, let TWAP catch up between each, then leveraged-open + dump. The single-block defenses don't catch this directly.
Blocked by: the combined cost. D7 forces the attacker's capital to sit at risk for tens of minutes. D1 + D6 cap each block's contribution. Round-trip slippage and band L-reduction on the eventual dump eat the band-capital edge. Verified empirically: a 30-ETH-scale attack nets ≤ 0.1 ETH P&L — unprofitable once gas is counted.
T-3 · abandoned-position bad-debt farming
Open leveraged positions, extract value via direct sells, never close. Bands hold phantom borrowedETH that nobody repays.
Blocked by: D10 — funding rate inflates effective debt by 50% APR. A lev-5 position with no price movement crosses the 105% health threshold in ~1 year and gets liquidated. Indefinite hold is no longer an exit path. D8 caps absolute exposure at 200 ETH; D9 auto-pauses opens past 5 ETH of bad debt.
T-4 · liquidation sandwich (MEV)
Frontrun a swap that will trigger a liquidation: dump TOKEN to push spot down, let liq sell at the manipulated spot, backrun to buy back cheap. Sandwich profit comes from user surplus.
Blocked by: M-01 — when spot has drifted from TWAP by more than 1500 ticks at scan time, the scan defers. A bot can't force a liquidation at a manipulated price.
T-5 · direct pool manipulation
Bypass the hook and call PoolManager directly: addLiquidity to inject unauthorized LP, removeLiquidity to steal, donate to skew fee accumulators.
Blocked by: beforeAddLiquidity / beforeRemoveLiquidity revert unless sender == hook. beforeDonate is registered and reverts unconditionally (D5).
T-6 · hostile staking contract
Owner sets a malicious staking that consumes all gas in notifyReward, trying to brick liquidations via the 1/64 rule starving the catch handler.
Blocked by: M-02 — staking.notifyReward is called with gas: 100_000. Catch handler always has enough gas.
T-7 · reentrancy
Malicious user contract or hostile staking tries to reenter openLong / close / claim mid-flow.
Blocked by: single nonReentrant lock across all user functions; PoolManager's own unlock guard prevents nested unlock() calls.
T-8 · cooldown asymmetry exploit
The original Uniperp had a close cooldown but no liquidation cooldown, creating an asymmetric in-tx exit via TWAP-triggered self-liquidation.
Blocked by: D4 — liquidation cooldown matches the close cooldown. Symmetric.
known limitations (not closed)
The defenses don't cover everything. Honest disclosure:
- per-address rate limiting is absent. D7 is global — Sybils share the budget. Real Sybil resistance would need proof-of-personhood or capital lockup.
- the TWAP is in-pool only. A sufficiently capitalized attacker who can sustain a price for 5+ minutes can move TWAP. Combined with D7 it's expensive but not impossible.
- slippage default is loose.
minHoldingOut = 0is allowed on openLong, leaving users sandwich-vulnerable unless their frontend sets a sensible default. - owner key is a single point of failure.
setStakingis one-shot. A compromised deploy is unrecoverable. Production deploys should use a multisig and a well-rehearsed runbook.