Open the app

Open a market with arbitrage recapture

Read what a market on the recapture root gains and gives up, the five frozen fields that switch the lane on, and the one quote it serves.

Introduction

A market on the arbitrage-recapture root opens through HookrMarketCoordinatorV5 exactly the way any other Hookr market does. Two things differ: the market's kernelId names the recapture root rather than the default one, and five fields in StackLimits that are zero on every other Hookr market are filled in.

This guide is the decision before the transaction. It covers what the market gains, what it gives up, the five fields that switch the lane on, and the one quote currency it works on. Read Arbitrage recapture first for what a correction actually does; this page assumes it.

The Hookr app does not offer this root in its launch flow yet, so a market on it is opened by calling the coordinator directly.

What the Market Gains

A correction's realized profit splits five ways, and 40% of it goes to the address the market freezes as correctionCreator. That is on top of everything the five native rules already pay a creator, and it comes out of value that would otherwise leave the pool with an arbitrageur.

The pool's in-range liquidity providers take 20% of a correction triggered through Hookr's own router, and 40% of one triggered through any other route, because a swap with no authenticated trader has no one to rebate. A market that expects most of its flow from aggregators is a market whose LPs take the larger share.

None of the five native rules changes. The module set behind a recapture root is the same module set, so surge, guard window, auto burn, LP reward, pot and royalty all behave exactly as Native mechanics describes them.

What the Market Gives Up

Every quote except native ETH. The registry admits a correction executor only on a native-quoted pool. A USDG, HOOKR or tokenized-stock pair cannot carry the lane, so if the market needs one of those quotes this root is not available to it at all.

A partner contract inside every swap. The pool calls a contract Hookr did not write, in both swap phases, and that contract's source is not verified on the explorer. The call is fail-open: a revert on the executor's side becomes an event and the swap settles.

Fail-open does not mean the lane can never break a trade. Two things on this root can: the beforeSwap refusal below, and gas, because the correction library on this root checks nothing before calling the executor and a swap sent with a limit too small for it runs out of gas and reverts.

Some swaps, by design. The root refuses a swap that arrives from inside a registered v3 pool's callback. That is the behaviour it exists for, and it means an aggregated route can revert against this pool without the router having done anything wrong.

Routing that the default root already has. Allowlists are granted per hook address, and nothing the default root carries reaches this one. Hooklist and routing has the current state.

Swaps that must carry the correction's gas. On this root the correction is priced into the call rather than gated by a floor, so a swap sent with a limit too small for it reverts instead of settling uncorrected. An interface routing to these pools sizes from the ordinary estimate with headroom, and carries a measured floor on top for the case where the lane found nothing to do at estimate time. Routing a correcting pool has the reasoning and the app's current number.

The Five Fields

The correction members of StackLimits, as the registry holds them:

address correctionExecutor;
address correctionCreator;
uint16  correctionMaxVolumeBps;
uint96  correctionMinProfitQuote;
bytes32 correctionFeePolicyId;
FieldWhat a market on this root setsWhat the registry requires
correctionExecutor0x28AF7A3645080e926a3101461e0Ec0594D42D806non-zero, with code, and the executor the root's sealed profile admits
correctionCreatorthe address the creator share pays tonon-zero
correctionMaxVolumeBps5000above zero and at most MAX_CORRECTION_VOLUME_BPS, which is 5000
correctionMinProfitQuote1above zero
correctionFeePolicyId0xd2653e091cb7002585fd8b1192b58f11b9c951061dc797123e37d5e2ccb45cefequal to HookrWthFeePolicyV2.FEE_POLICY_ID

correctionCreator is the one real choice in the table. It is the address the fee policy pays CREATOR_BPS to, and it is separate from lpFeeRecipient, from royaltyTo and from the launching wallet, so a market can send correction proceeds somewhere other than its LP fees.

The volume and profit fields are not choices and not caps. They are set to the registry's permissive maximum and to the smallest value it accepts because the registry demands the fields and nothing downstream enforces them. Arbitrage recapture says why.

What Admission Checks

The registry validates the five together, and refuses several shapes that look reasonable.

ConditionResult
A zero executor with any other correction field non-zeroInvalidStackLimits()
A non-zero executor with a zero creator, a zero volume field, a volume field above MAX_CORRECTION_VOLUME_BPS, or a zero profit fieldInvalidStackLimits()
A non-zero executor on a pool whose quote is not address(0)InvalidStackLimits()
A correctionFeePolicyId that is not the policy idInvalidStackLimits()
An executor address with no codeInvalidIntegrationWiring()
An executor whose routeAdmissionOpen() returns false or revertsInvalidIntegrationWiring()
An executor whose feePolicyId() does not match the frozen oneIntegrationMetadataMismatch(executor)

The quote check is stricter than "quote is native": the registry requires currency0 to be the quote and currency1 to be the subject, because the partner executor reads the pair that way round. A native-quote pool satisfies it automatically, since address(0) sorts first.

The last two rows are live reads of the executor at creation time. A market cannot be opened against an executor that is closed for admission.

Getting It Wrong Is Permanent

Leaving the five fields at zero on a recapture root opens a plain V2 pool wearing that root's name. The correction path returns on its first line when the frozen correctionExecutor is the zero address, so the partner is never reached and no correction can ever run on that pool. It will trade correctly and pay the five native rules correctly, and the lane the root exists for will be dead in it.

There is no repair. The correction fields are part of the stack hash, the stack is frozen at creation, and the pool's root is named in its PoolKey. Both are set at launch or never. Immutability and ownership lists everything else in that category.

Check the Pair First

Two conditions decide whether the lane does anything at all, and neither is enforced at launch.

The quote must be native ETH. Anything else is refused at admission, so this one announces itself.

The pair needs a reference venue. The partner executor only corrects against venues it has registered for that pair, read through getTokenPools(address,address) and registeredPools(bytes32). A pair with none is admitted, opens normally and never corrects.

A token that does not exist yet cannot have a reference venue, so a new-token launch on this root starts with the lane switched on and nothing for it to do. That is a reason to choose the root rather than a reason not to: the root cannot be added later, so a market that expects to be listed elsewhere opens here or gives up the lane permanently.

Next Steps

Read Open a new-token market for the rest of the launch sequence, all of which applies unchanged.