MoonVault
Welcome back, AsianOnPulse.

EXECUTION ARCHITECTURE

How an exit actually executes

A take-profit protocol lives or dies on one question: can a manipulated price, a hostile caller, or a dead component take the gain? Below is the full answer. Every mechanism described is enforced in verified contract code — not in policy.

1 · The oracle: guarded, or it doesn't count

Targets trigger against a GuardedOracle with two hard gates. Staleness: a price older than the freshness window is not a price — reads revert rather than serve it. Deviation: a single update may not move the feed more than 20% — a manipulated print on a thin pair cannot teleport the oracle to a fake level in one step; an attacker would need to sustain the manipulation across multiple updates, paying real market cost the whole way.

2 · The keeper: permissionless, and safe to be

Anyone may call seal() on a vault whose target the oracle confirms — the caller earns a 0.1% tip, so execution never depends on our server being alive. This is safe for one reason: the engine derives its own slippage floor from the oracle price (3% maximum deviation from oracle mid), and a caller's parameters can only make execution stricter, never looser. A hostile keeper cannot sandwich the sale below that floor; the transaction reverts instead. Refusing to sell is the designed failure mode — a bad fill is permanent, a delay is not.

3 · Slippage: who bears it

Execution costs (DEX fees, price impact within the 3% band) come out of gross proceeds before the 80/20 split — the owner and the protocol share costs in the same ratio as gains. The protocol never tops up a fill and never socialises one vault's slippage onto others. If the book cannot absorb the position within the band, the sale reverts and the vault stays open.

4 · Circuit breakers and the dead-protocol case

  • Stale oracle → trading halts. No component ever prices against a feed nobody is maintaining.
  • Oracle dead 30 days → unconditional rescue. The holder withdraws the full position, penalty-free, via rescueWithdraw() — the Rescue withdraw button on /vaults appears on a vault once the engine says it would succeed. The hatch reads a non-reverting timestamp — it can never be blocked by the failure it exists to escape.
  • No pause on exits. There is no code path — for the team or anyone — that can freeze a withdrawal or termination.
  • No admin withdrawal. Every function that moves a vault's asset pays the vault's owner. The team cannot pull deposits: not "won't" — can't.

5 · MEV posture

The oracle-anchored floor is the primary defence: value extractable by ordering games is capped at the 3% band, and the keeper tip makes honest execution the profitable strategy. For mainnet, large-vault exits will additionally route through batch/intent venues (CoW-style) and per-venue impact caps limit any single fill to 1% of pool reserves — both already specified in the v2 engine's venue router.

6 · Per-chain honesty

A vault size that exits cleanly on Base may be untradeable on a thinner chain at the same notional. Before mainnet on each chain we publish a venue matrix — routing venue, reference depth, maximum vault size — with the size cap enforced in the contract, not the UI. Venues must be verified-source, six months live, with no freeze switch; unverified routers never enter the whitelist, whatever their front end advertises.

Current deployment is PulseChain mainnet, all contracts verified, running as a private pilot. No external audit has been completed yet — treat every deposit as risk capital until one is published here. Risk disclaimer · Transparency