Skip to Content
Freeze-and-Burn Finality

Freeze-and-Burn Finality

ClaimRush v1.0.0 reaches permanent runtime finality through one timelocked ceremony. The launch window is governed and patchable. The end state is public, delayed, and irreversible.

Finality is a two-part ceremony for the proxy-backed runtime quartet:

  • freezeConfig() locks the documented core wiring setters on the five freeze-gated contracts (ClaimToken freezes at wire time; the remaining four freeze in the ceremony)
  • burning the four runtime ProxyAdmin owners removes quartet upgrade authority forever

The quartet is:

  • MineCore
  • Furnace
  • MarketRouter
  • ShareholderRoyalties

The direct permanent roots remain:

  • ClaimToken
  • VeClaimNFT

What the ceremony does

ClaimToken freezes at wire time: ClaimToken.freezeConfig() and ClaimToken.renounceOwnership() execute at the end of Wire.s.sol, immediately after wiring. ClaimToken has no post-freeze owner knobs (no pause, no metadata, no guardian), so ownership is dead weight after freeze. By the time the ceremony runs, it is already frozen and ownerless.

The canonical finality batch is therefore 8 operations:

  1. MineCore.freezeConfig()
  2. Furnace.freezeConfig()
  3. VeClaimNFT.freezeConfig()
  4. ShareholderRoyalties.freezeConfig()
  5. MineCore ProxyAdmin.renounceOwnership()
  6. Furnace ProxyAdmin.renounceOwnership()
  7. MarketRouter ProxyAdmin.renounceOwnership()
  8. ShareholderRoyalties ProxyAdmin.renounceOwnership()

This ordering is mandatory.

  • Every freeze call runs before any proxy-admin burn
  • If any freeze precondition fails, the whole batch reverts
  • No runtime proxy admin is ever burned unless all four ceremony freezes succeed first
  • The script asserts that ClaimToken is already frozen before scheduling

What finality means

After the batch executes successfully:

  • All five freeze-gated contracts (ClaimToken, MineCore, Furnace, VeClaimNFT, ShareholderRoyalties) report configFrozen() == true (ClaimToken was already frozen at wire time)
  • the runtime quartet can no longer be upgraded
  • the quartet proxy addresses remain the canonical live addresses
  • ClaimToken and VeClaimNFT remain direct permanent roots

Finality means both layers are locked:

  • wiring is locked by the five freezeConfig() calls (ClaimToken freezes at wire time; the remaining four freeze in the ceremony)
  • runtime logic is locked by burning the four runtime ProxyAdmins
  • the public governance window is over for the runtime itself

What stays mutable afterward

Finality is not full protocol owner renounce.

The timelock still owns the protocol owner() paths after the burn, so documented post-freeze operational knobs remain available, including:

  • MineCore.guardian
  • MineCore.entryTokenRegistry
  • MineCore.delegationHub
  • Furnace.guardian
  • Furnace.entryTokenRegistry
  • Furnace.delegationHub
  • Furnace delayed emergency LP-vault recovery
  • MarketRouter policy knobs such as settlement keepers and bonus-target escrow params
  • VeClaimNFT metadata URIs (setBaseURI, setContractURI)
  • ShareholderRoyalties compounding keepers/floors

Those actions no longer happen instantly. They remain timelocked governance actions.

Governance path

The production chain of authority is:

  • Safe -> TimelockController -> ProxyAdmin -> runtime proxy
  • Safe -> TimelockController -> protocol owner()

Defaults:

  • PROPOSER_ROLE = Safe
  • CANCELLER_ROLE = Safe
  • EXECUTOR_ROLE = Safe

The guardian remains separate and immediate for pause/unpause response.

Why the delay matters

The freeze-and-burn batch is intentionally timelocked before execution.

That delay is not just an operational buffer:

  • it creates a public onchain countdown to finality
  • the exact batch calldata is visible before execution
  • the Safe can cancel if anything looks wrong
  • users and integrators can see that permanent runtime immutability is approaching
  • operators get one final review window before the protocol crosses into permanent runtime finality

On mainnet, that countdown is part of the protocol’s credibility story.

Operational sequence

  1. Finish deployment, wiring, and genesis
  2. Transfer ownership to the timelock
  3. Bootstrap the timelock roles and renounce deployer admin
  4. Run audit/fix cycle while quartet upgrades are still available
  5. When ready for permanent finality, schedule the freeze-and-burn batch
  6. Wait the timelock delay
  7. Execute the batch
  8. Verify frozen state and burned proxy admins onchain

Required scripts

  • FinalizeOwnership.s.sol
  • FinalizeTimelockBootstrap.s.sol
  • TimelockAcceptOwnership.s.sol
  • TimelockRuntimeUpgrade.s.sol
  • FreezeAndBurn.s.sol

Emergency model before finality

Before the burn, critical runtime bugs are handled in the standard order:

  1. guardian pauses the affected surface immediately
  2. governance schedules the runtime upgrade through the timelock
  3. wait the delay
  4. execute and verify
  5. unpause only after the fix is confirmed live

Post-finality model

After the burn:

  • runtime upgrades are impossible
  • surviving owner knobs still require the timelock delay
  • “post-freeze operational change” means schedule -> wait -> execute, not “call the setter directly”
  • the timelock remains load-bearing governance, not a ceremonial leftover

Verification checklist

After execution, confirm:

  • all five configFrozen() values are true
  • each runtime ProxyAdmin.owner() is address(0)
  • python3 scripts/verify_deployment.py --network <network> --rpc-url "$RPC_URL" --require-frozen passes
  • the deployment manifest still shows the same quartet proxy addresses
  • the manifest proxyAdminOwner values are updated to 0x0000000000000000000000000000000000000000