Skip to content

fix(deploy-uni-hook): anchor price/balance/skew gates to the pool's own price - #1031

Merged
aaronjmars merged 1 commit into
mainfrom
fix/deploy-uni-hook-price-anchor-gate
Sep 5, 2026
Merged

fix(deploy-uni-hook): anchor price/balance/skew gates to the pool's own price#1031
aaronjmars merged 1 commit into
mainfrom
fix/deploy-uni-hook-price-anchor-gate

Conversation

@aaronjmars

Copy link
Copy Markdown
Collaborator

What

Freeform balance / skew / "heavier-side" hooks generated by this skill compare the two virtual reserves. That comparison is a raw-price gate in disguise: StateLibrary gives amount0 = L*2^96/sqrtP and amount1 = L*sqrtP/2^96, so amount0/amount1 = 1/price and the liquidity L cancels exactly. The gate therefore tests the pool's raw price against an implicit 1.0, which only matches "balanced" for a same-decimals pair near parity.

Consequence: on any real pair the pool is permanently one-directional (one whole leg of trade reverts forever). A USDC(6d)/WETH(18d) pool sits ~8 orders of magnitude off; two 18-dec tokens at price 2.0 are already outside a 10% band. And "every trade rebalances toward 50/50" is false anyway (a full-range position is already 50/50 by value at any price).

The skill's own behavioral-test scaffold hides this: setUp() opens the pool at 1:1 (the one price where such a gate looks correct) and the generator may not edit setUp().

Changes

  1. Fleet audit rules -> Gates rule 6 (SKILL.md): documents the L-cancels defect and the fix - snapshot the pool's own sqrtPriceX96 at afterInitialize and gate against that, never 1.0. Requires the afterInitialize callback (flag 0x1000) on any price/balance/skew hook.
  2. Fleet audit rules -> Tests + step 4 build/test guidance: a price/balance/skew gate must be asserted off 1:1.
  3. templates/Hook.t.sol: new _freshPoolAt(uint160 sqrtPriceX96) helper (fixed scaffolding) that repoints the test pool to a second pool on the same hook at an arbitrary price, so the generator can assert both legs away from parity without touching setUp().

No frontmatter or file-count change, so catalog/skills.json is unaffected (verified against the ci-skills-json normalized diff). forge fmt --check passes on the template.

…wn price, not an implicit 1.0

A freeform balance/skew gate that compares the two virtual reserves is
really comparing raw price to 1.0: StateLibrary gives amount0/amount1 =
1/price, so the liquidity L cancels exactly. Such a gate is permanently
one-directional on any pair that is not a same-decimals pool near
parity (a USDC/WETH-shaped pool sits ~8 orders of magnitude off, two
18-dec tokens at price 2.0 are already outside a 10% band): one whole
leg of trade reverts forever.

- Codify it in the Fleet audit rules (Gates rule 6): snapshot the
  pool's own sqrtPriceX96 at afterInitialize and gate against that,
  and add the afterInitialize callback (flag 0x1000) to any price /
  balance / skew hook.
- Require the behavioral test to assert such gates OFF 1:1. The setUp
  scaffold pool is at 1:1, the single price where the bug hides, and
  the generator may not edit setUp. Add a _freshPoolAt(sqrtPriceX96)
  helper so a test can repoint the pool off parity and assert both legs.
@aaronjmars
aaronjmars merged commit ad4dd82 into main Sep 5, 2026
3 checks passed
@aaronjmars
aaronjmars deleted the fix/deploy-uni-hook-price-anchor-gate branch September 5, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant