Pulled orbmis/headroom and recomputed it rather than take the config, and it checks out. Your cap invariant isn’t reserved+confirmed ≤ cap on a single cursor like the StatefulBound reference; it’s cumulativeTurnover ≤ maxCumulativeTurnover (CURSOR_HEADROOM, HeadroomPoC.sol L298/534), read via cursorSummary(envelopeId) on the EnvelopeRegistry 0x091f…07d1. Ran it against envelope 0x48e972a2…bcb041 on Base Sepolia (84532):
portfolioValue 10000
cumulativeTurnover 0
maxCumulativeTurnover 8000
remainingTurnover 8000
vaultAllocations [2500,2500,2500,2500,0,0] = 10000 bps
riskAllocations [5000,5000,0] = 10000 bps
cursorRoot 0x2f19c6e6… (= slot-5 of getEnvelope) active true
VERIFIED-GOOD at Base-Sepolia block 43697267, stateRoot 0xbb4fbc638e657de5e9fbdefcc290054e251087cf9948b471c15677b09e3a89ff:
-
cumulativeTurnover 0 ≤ maxCumulativeTurnover 8000— the headroom bound holds, -
I re-derived
remaining = 8000 − 0 = 8000, matching the contract’s ownremainingTurnover(not read on faith), -
allocations sum to 10000 bps on both the vault and risk-bucket axes — fully allocated, in bounds.
Two things worth flagging for the thread:
-
This is a second, independently-recomputable instance of the same ERC-8312 guarantee — a turnover-cursor headroom model, distinct from the reserved+confirmed aggregate of the zero-human-loop
StatefulBound, both reducing to “aggregate ≤ cap, provable from public state.” Two different implementations converging on one checkable invariant is a good sign for the spec. -
Our recompute-kit
8312/cap-conservationrecipe is tuned to theStatefulBoundstorage layout, so it doesn’t drop onto your accessor shape — I recomputed viacursorSummaryhere. I’ll generalize the recipe to take an accessor form so it covers the headroom model too; happy to fold your case in as a second conformance vector if you’re up for it.
Clean on my side, the bound holds live, re-runnable by anyone from that one cursorSummary call.