This file summarizes security-relevant behavior in the current contracts. It is not a replacement for a full audit.
Key trust assumptions in the current design:
UmiaHub.owner()is trusted to set critical registry pointers:- market manager
- default governance executor
- swap router
- TWAP oracle
- LBP strategy factory
- market creation signer
marketCreationSigneris trusted to approve market definitions via EIP-712 signatures.- Winning proposal execution can perform powerful treasury actions (including arbitrary external calls).
UmiaMarketCore enforces an internal invariant after split/merge:
totalRealVenture >= maxUserVirtualVentureSupplytotalRealMoney >= maxUserVirtualMoneySupply
where totalReal* includes user-deposited backing plus initial LP liquidity removed during market creation.
This invariant is central to settlement safety.
hasClaimed[marketId][user] prevents duplicate settlement claims.
marketExecuted[marketId] gates repeat execution of winning proposal payloads.
In Venture, liquidationActive blocks treasury mutation functions via whenNotLiquidating. Claims are handled by an external ILiquidator contract set via venture.setLiquidator().
Owner-only setters control protocol pointers and token approvals. Compromise impact: broad protocol control.
- Swaps are self-custodial; the permit variants recover an EIP-712 signer and consume a per-signer
swapNoncesentry for replay protection. - Market creation requires valid signer signature and nonce.
- Winning proposal execution uses executor resolved from hub.
- Only current market manager may call
executeProposal. - Executor must match
HUB.governanceExecutor(venture). - Plan version and action versions are strictly checked.
Privilege tiers:
onlyHub: initialization and hub-level operations.onlyExecutor: mint, burn, withdraw, arbitrary call, team member updates, allowance updates, document uploads, liquidation setup (setLiquidator).
-
Arbitrary call action (
CALL)- Governance payload can call arbitrary target/value/data through
Venture.executeCall. - Powerful by design; increases blast radius of malicious governance outcomes.
- Governance payload can call arbitrary target/value/data through
-
Registry pointer updates in hub
- Changing executor/router/oracle/manager can materially alter system behavior.
-
Market creation signer compromise
- Could approve malicious market definitions and payloads.
-
LP liquidity operations
createMarketremoves 50% liquidity from venture LP and later re-adds excess.- Arithmetic and slippage protections are security-critical.
-
Liquidation setup
- Liquidation is terminal and snapshots balances/supply.
- Ensure governance process around liquidation is strict.
UmiaMarketCoreusesReentrancyGuardon settlement claim and execution flows.GovernanceExecutorusesReentrancyGuard.VentureusesReentrancyGuardon transfer/call sensitive methods.- External call paths include:
- token transfers,
- Uniswap helper interactions,
Venture.executeCallarbitrary targets.
- Elapsed-time truncated TWAP: The accepted tick slews toward the pool tick at no more than 4,558 ticks/second (9,116 ticks over a normal two-second Base block), with the ramp and recovery path integrated exactly. Extra writes cannot ratchet the filter faster, and a restored price recovers during quiet time instead of leaking a stale clamped tick across the gap.
- Operator-only, full-range liquidity enforcement:
beforeAddLiquidityandbeforeRemoveLiquidityreject any caller other than the pool's registered operator (the venture'sSpotLiquidityVault), and any position that isn't full-range (minUsableTicktomaxUsableTick). Concentrated liquidity would create zero-liquidity tick gaps exploitable for cheap tick manipulation. - Spot-vs-TWAP sandwich guard:
SpotLiquidityVault._requireSpotWithinTwapDeviationcompares the current spot tick against the 30-minute TWAP tick (TWAP_WINDOW) and reverts withSpotPriceDeviationTooHighbeyondMAX_TICK_DEVIATION(1000 ticks, ~10.5%). It runs on deposits, withdrawals, decision-market creation, and settlement. Fail-closed: if the oracle holds fewer than 2 observations or cannot serve the full window (e.g. buffer exhausted by dust swaps), it reverts withInsufficientOracleHistoryrather than silently allowing the operation. The only skip is an empty position (currentLiquidity() == 0), which has no reserves to sandwich and must stay open so a drained vault can be re-bootstrapped. - Oracle buffer sizing:
afterInitializeseeds cardinality 1 andbootstrapFromLBPgrows it to 100 slots. At one observation per block that covers only ~200s on Base, short of the 30-minute window, so busy pools should be grown to at least 1,000 slots via the permissionlessincreaseCardinalityNext(). Combined with the fail-closed guard, buffer exhaustion blocks operations rather than bypassing them. See SPOT_ORACLE.md.
- Per-update price clamping: Each oracle update clamps the recorded price to at most 2.5x (or 0.4x) of the previous value. Bounds single-swap manipulation impact on the TWAP accumulator.
- Trading-start anchor: The TWAP is anchored at
tradingStart(with a zero cumulative baseline) by a one-shotinitializeat market creation, immutable thereafter. No price before trading start affects the average. - Swappable implementation: The oracle is resolved through the Hub registry on every call and its
initialize/update/calculateTWAPinterface carries the market's winning threshold, so a hardened implementation (e.g. an elapsed-time clamp) can replace this one viahub.setConditionalMarketOracle()without touchingUmiaMarketCore. - Trading-end freeze: Oracle timestamps are capped at
tradingEndvia_effectiveTimestamp(). After trading ends,update()stops accumulating andcalculateTWAP()returns a fixed value. This prevents settlement delay from diluting the TWAP or extending the influence of last-block manipulation. - Settlement oracle update: Oracle is updated at settlement time to include the final price observation before TWAP computation.
- No protocol-wide pause mechanism is present in current code.
- Winning proposal execution has no timelock in
UmiaMarketCore.executeWinningProposal. - Oracle correctness depends on manager-triggered updates around swaps/settlement.
- Permit/nonces are per-contract and need replay protection monitoring.
- Market accounting and solvency proofs (
split,merge,settleMarket,claimSettlement). - Governance payload decoding/dispatch correctness (
GovernanceExecutor,GovernancePayloadValidator,GovernanceActions). - Access control and pointer trust model (
UmiaHub,Venturemodifiers). - Uniswap v4 integration assumptions in LP removal/re-add flow.
- Liquidation state transitions and proportional payouts.
DECISION_MARKET_FLOW.mdGOVERNANCE_TREASURY_LAYER.mdUPGRADES.mddocs/contracts/references