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
