- No upgradability. Every deployed contract is immutable. Wiring is a one-shot
set → freezeand there is no admin path to redirect a vault’scoreafter the freeze. - NFT custody is narrow. The LP’s Uniswap v3 position NFT is held by a dedicated vault for the swap’s life, accepts deposits only from the canonical position manager, and returns to the LP at settle.
- EIP-170 is satisfied. The deployed
InflexionCoreis 23,934 B, under the 24,576-byte contract-code-size limit. An earlier version briefly exceeded it; the resolution is described in full below.
Immutability and custody are part of why Claim A (no bad debt, FULL) holds with no trusted operator: settlement runs on-chain against the counterparty’s own collateral, with no upgrade key that could rewrite the settle path after the fact.
No upgradability — the one-shot wiring pattern
There is no proxy, no upgrade beacon, no admin-redirectable logic address. The contracts deploy once and stay byte-for-byte fixed. The only privileged action is the initial wiring of vaults to the core state machine, and that action self-destructs after a single use. The pattern is aset... setter paired with a freeze... latch:
- The deployer calls
setCoreon each vault to point it atInflexionCore, then callsfreezeCoreto permanently lock that pointer. - The same shape applies to the core’s own dependency wiring (
setCvamm/freezeCvamm).
core address — a re-wire attempt reverts. This closes the obvious “swap the logic out from under live swaps” attack: once a market is open, the code that will settle it is fixed.
NFT custody — narrow by construction
During a swap the LP’s Uniswap v3 position NFT is held by theILVault ERC-721 custody contract. Custody is intentionally narrow so the NFT can be neither hijacked on the way in nor mis-credited on the way out.
1
Take custody — canonical source only
ILVault.onERC721Received accepts an NFT only from the canonical NonfungiblePositionManager configured at deploy. A token arriving from any other ERC-721 contract is rejected, so a forged “position” NFT cannot be deposited to spoof a swap.2
Fees during the swap — recipient is forced
While the position is custodied,
claimFees routes accrued Uniswap fees to a forced recipient: the registered LP. The caller cannot redirect fee proceeds; custody never becomes a fee-siphon vector.3
Liquidity is snapshotted, not re-read
The position’s liquidity
L is stored once at creation and settlement uses that stored value — settle never re-reads positions(tokenId).liquidity. This is invariant I6: an external increaseLiquidity on the custodied NFT cannot inflate the computed IL above MaxIL. See price pinning for the companion geometry checks.4
Return at settle
returnNFT hands the position back to the LP at settlement. Custody is for the swap’s duration only.EIP-170 — the resolved size-pass
EIP-170 caps deployed contract bytecode at 24,576 bytes (0x6000).forge build and forge test run on revm, which does not enforce the limit — so a too-large contract compiles and passes its entire test suite while still being undeployable on a real chain. That gap is exactly the trap Inflexion hit and resolved.
The history
The numbers
The fix bought roughly 855 B of headroom (24,789 → 23,934) — the contract now sits comfortably below the ceiling, with the public libraries carrying the extracted math as
delegatecall code.
A side effect of the library extraction worth knowing for SDK / parity and audit purposes:
CvammPricing, QuoteVerification, SwapMath, and TickMath are delegatecall-only libraries — they execute in the caller’s storage context and cannot be unit-tested as standalone deployed contracts via live calls. This is reflected in the test suite (a CvammPricing live-parity test was corrected to acknowledge libraries are delegatecall-only). It does not weaken any invariant: the extracted code is the same code, just relocated.Why this matters for trust
The EIP-170 episode illustrates the project’s posture: a limit was hit, the build tooling (revm) did not surface it, it was caught before mainnet, fixed deterministically in code, and the one stale documentation note is flagged rather than hidden. No on-chain behaviour changed — the events, the invariants, and the settle path are identical; only the bytecode layout and optimizer setting moved.Live, immutable deployment
These are the immutable contracts running on Arbitrum Sepolia (chainId 421614), redeployed fresh on 2026-06-05. Once wired and frozen, none of these addresses can be redirected. Network: Arbitrum Sepolia · chainId421614 · deploy block 274081134 (subgraph startBlock) · deployed 2026-06-05
Core protocol
Stylus & libraries
Oracles
Uniswap
Chainlink feeds
Demo tokens / pool / LP
Lifecycle swaps
Live create→settle lifecycle (2026-06-05, short 300s fee-500 market
0xb8bbd684f213d5833886ade7b531a6949d85522249881a2b5d46a5cc76e439c2):
- Path A (cvAMM convexity) — swapId 1, LP tokenId 3220 · V0 $270,531.28 · MaxIL $1,669.24 · premium $9.70 (0.58% of MaxIL) · settled payout $148.64 from ConvexityVault.
- Path B (MM routing) — swapId 2, LP tokenId 3221 · MM beat cvAMM ($8.93 vs $13.80) · MaxIL $3,215.65 · MM collateral locked $3,215.65 · settled payout $245.66 from MM collateral.
Related
Invariants I1–I10
The ten Foundry-fuzzed invariants, including I6 (liquidity immutability) which underpins NFT custody safety.
Price pinning
On-chain Chainlink-derived entry/settlement prices and the LP-lies-about-geometry defenses that complement custody.
CEI & reentrancy
The four-phase create path and status-flip-first settle that keep custody and state transitions atomic.
Status & caveats
The running ledger of known limits — including the stale EIP-170 note — each with its why and mitigation.