Skip to main content

FeeRegistry & Treasury

FeeRegistry

contracts/src/core/FeeRegistry.sol — the single governance surface. Every other contract reads its configuration from here; nothing else has an owner with meaningful power.

Views (read by the token / hook / factory / treasury / bonds)

FunctionMeaning
reserveAsset()USDG — the quote asset, reserve denomination, and currency0 of every pool
poolManager()The Uniswap V4 PoolManager
protocolTreasury()Recipient of the 0.30% base fee + the 10% index-fee cut + launch fees
protocolToken()$IPAD — unset (0x0) until the token launches
launchFeeWei()Optional native fee per launch
isAssetAllowed(address)Stock allow-list membership
priceFeedOf(address)Chainlink USD feed for a basket stock (NAV + bond valuation)
maxBondDiscountBps()Protocol cap on any index's bond discount (10%)
minBondPoolLiquidity()Min pool liquidity before the bond TWAP is trusted (0 = off)
sequencerFeed()Optional L2 sequencer-uptime feed for guarded oracle reads
isPaused()Guardian pause state

Governance setters (owner, Ownable2Step)

setAsset / setAssets (allow-list), setPriceFeed (feeds are replace-only — can't be cleared to 0x0), setPoolManager, setProtocolTreasury, setProtocolToken, setLaunchFeeWei, setMaxBondDiscountBps, setSequencerFeed, setMinBondPoolLiquidity, setGuardian.

Pause semantics

setPaused(bool) — callable by owner or guardian. Pausing blocks new launches only. It can never block a swap, an IndexTreasury.redeem(), or a bond claim() — exit paths are unpausable by construction.

Legacy fields

The registry still carries a few fields from the removed keeper/dividend era (keeper, challengeWindow, maxEthPerRound, swapEngine, distributionEnabled, ethUsdFeed). They are vestigial in the current inline-split model and are not read by the live fee path. They're slated for removal before mainnet.

Treasury (interim protocol fee sink)

contracts/src/core/Treasury.sol — a plain Ownable2Step vault that receives the protocol's cut: the 0.30% base fee + 10% of every index fee (in USDG, sent by the hook) and native launch fees. It exposes withdraw(token, to, amount), withdrawNative(to, amount), and migrate(successor, tokens[]).

The $IPAD migration path

The protocol token ($IPAD) is not deployed yet — it will be distributed to participants later. The redeemable versions (ProtocolToken.sol, ProtocolTreasury.sol) are kept in-repo, tested, and un-deployed. Because the fee recipient is a mutable registry address, migration needs no core redeploy:

1. Deploy ProtocolToken ($IPAD) + ProtocolTreasury (redeemable)
2. registry.setProtocolTreasury(newTreasury)
3. registry.setProtocolToken(ipad)
4. oldTreasury.migrate(newTreasury, [usdg, ...indexTokens])

From then on, the protocol cut accrues to the $IPAD-redeemable treasury with no interruption to any live index token.