CIP-31: CBFS Rent Schedule
Abstract
This CIP pins concrete CBY values for every parameter that CIP-9 (Runner Storage / CBFS) currently labelsTBD, adds a new RELAY_CHALLENGE_BOND field, makes the existing 10 / 1 / 89 platform-account credit / challenge-pool / Relay revenue split explicit in normative text, and defines the pro-rata weighting formula that distributes the 89% Relay share across active Relay Nodes.
The funded cumulative read mechanism is defined in CIP-9 §10.4.1–§10.4.2; this CIP supplies its governed transfer rate and clarifies its separate principal/gas economics. It does not activate that mechanism or select production channel budgets.
Motivation
- Let Relay operators run capacity-planning math before mainnet.
- Let storage-rate volatility (CBY-denominated rent vs USD/GB/yr reality) be observable, monitored, and Tier-0-adjustable on a documented cadence.
- Provide the challenger economic incentive that makes Proof-of-Retrievability honest in steady state.
- Bound the worst-case Relay-side loss in slashing events.
Specification
1. Storage Fee Rate
ceil(volume_size_bytes / 2^20) MiB. Per 1 GiB of stored data per year: 2,905 nano-CBY × 1,024 MiB × 365 epochs ≈ 1.086 CBY / GiB / year.
Backblaze B2 lists **7.64 / TiB / month — the units are not interchangeable and conflating them understates the multiple. Against that, the rate is 1.82× B2, and roughly 40% below S3 Standard (~$24 / TiB / month).
The rate is denominated in nano-CBY. USD figures below are the administered CBY rate defined in CIP-36 §6.6 applied to this constant, not a property of the constant itself; §6.6 is that rate’s only definition and this section does not restate it. At the current rate the fee is $0.163 / GiB / year. If the rate moves, the Tier-0 review below retunes this constant to keep the fee inside the band — which is what the band exists for.
The rate is denominated per MiB, not per byte: the smallest integer per-byte rate (1 nano-CBY/byte/epoch) is ≈ 391.9 CBY / GiB / year — ≈ $58.78 at the administered rate, roughly 650× commodity object storage — so per-byte granularity cannot express a competitive rate.
Mutability: Tier-0 governance, stored at 0x09 under key cip31.cbfs.storage_fee_per_mib_per_epoch. The governance value is authoritative wherever it is set; the constant above is the genesis default only, and any implementation that bills from a compiled-in constant rather than the parameter is non-conforming. The Tier-0 review cadence is 30-day post-TGE → 90-day steady state; the target band is [$0.05, $0.50] / GiB / year. The rate is nano-CBY and the band is USD, so token-price movement drifts the fee against the band by construction; the administered rate (CIP-36 §6.6) pins the conversion between reviews, and the Tier-0 review retunes the constant when the drift leaves the band.
2. Transfer Fee Rate
66,700 nano-CBY × 100 = 0.00667 CBY of transfer principal at this rate, exclusive of channel lifecycle gas. Transfer principal goes entirely to the fixed serving Relay (no burn, no challenge-pool share).
Mutability: Tier-0, key cip31.cbfs.transfer_fee_per_mib.
2.1 Funded-channel charging and budget scope
CIP-9 §10.4.1 defines an independently activated funded cumulative read channel; this parameter supplies its current execution-time rater. It does not grant
a relay authority to debit an arbitrary reader or volume pool. One direct payer
transaction funds a fixed channel; subsequent payer-signed cumulative ACKs
authorize bounded claims against only that channel’s remaining principal.
The unit counter is sum(ceil(logical_shard_bytes / 2^20)) for complete,
independently verified logical shards, not ceil of a concatenated object’s bytes
and not a sum over transport chunks. At each checkpoint:
3. Minimum Storage Balance
STORAGE_GRACE_EPOCHS per CIP-9 §10.3.
Mutability: formula-derived; the multiplier 1 (one epoch) is Tier-0-tunable via cip31.cbfs.min_storage_balance_epochs.
4. Fee Distribution Split (10 / 1 / 89)
For each epochly storage-fee batch collected from an account:
Implementation contract:
STORAGE_FEE_PLATFORM_BPS = 1000(10%)STORAGE_FEE_CHALLENGE_POOL_BPS = 100(1%)STORAGE_FEE_RELAY_BPS = 8900(89%)- Invariant:
STORAGE_FEE_PLATFORM_BPS + STORAGE_FEE_CHALLENGE_POOL_BPS + STORAGE_FEE_RELAY_BPS == 10000
cip31.cbfs.fee_split; the invariant MUST hold after any proposal.
Disposition of the 10% storage-rent share. Storage and transfer fees are collected in CBY (§1, §2), but this split applies only to storage rent; transfer principal has no 10% share.
The share is therefore credited to the Platform Fee Account, system actor 0x18, and the parameter is cip31.cbfs.fee_split.platform_bps. This is a platform share in the marketplace sense — the owner pays, relays do the work, the platform takes a cut — and it is deliberately NOT called a treasury share: treasury elsewhere in Cowboy denotes the protocol treasury, and the two have different owners and different purposes.
It is credited rather than burned because burning is irreversible and crediting is not: a credited share can be burned later from the account, while a burned one cannot be recovered, and the credit preserves an on-chain record of accrued platform revenue that a burn destroys.
The address is fixed rather than governance-set, so no governance write can redirect the share and settlement needs no per-block state read to find it. Withdrawal authority is genesis-defined for the account under COW-2915 — 0x18 sits in the keyless reserved system range, so it needs an explicit genesis-configured owner or multisig rather than a recoverable key, and v1 defines accrual here while COW-2915’s resolution defines the exit path before mainnet genesis. Where a CBY sink is wanted, it is a buy-and-burn performed from that account, outside settlement and outside consensus.
This applies only to fees. Slashed Relay stake (§8) is denominated in CBY and its 10% share is still burned, which remains coherent: the stake is a token position, not a dollar claim.
5. Relay Pro-Rata Weight Formula
shard_count_iis the number of unique shards Relayicurrently holds and serves with valid PoR responses in the prior epoch.shard_age_in_epochs_iismin(epochs_since_assignment, MAX_SHARD_AGE_FOR_WEIGHTING)whereMAX_SHARD_AGE_FOR_WEIGHTING = 90epochs (~3 months at 1-day epochs). The cap prevents permanent first-mover advantage.
cip31.cbfs.relay_weight_formula. Tier-0 may not change the formula structure, only MAX_SHARD_AGE_FOR_WEIGHTING.
6. Minimum Relay Stake
0x0B). Sized to be meaningful relative to a professional Relay’s expected revenue: a Relay holding ~100 TiB of shards backs ~67 TiB of logical data at K + M = 4 + 2, earning ~5,450 CBY / month from the 89% pro-rata share — high enough to deter spam, low enough to admit professional operators.
At 33,000 CBY that is 6.06 months of revenue. The figure was 5,000 CBY when the storage fee was calibrated at CBY = $1; repricing the fee for the administered rate preserved relay revenue in USD but not the stake, which is a fixed CBY quantity, so it was resized with it. RELAY_CHALLENGE_BOND, CHALLENGER_BOUNTY and the three penalty parameters were scaled by the same 6.6x, preserving their nominal ratios to stake. POR_CHALLENGE_FEE is the one exception: 1 -> 7 is 7x, because 6.6 is not an integer and rounding down to 6 would have made the fee cheaper in real terms than it was. The current PoR settlement path charges only the eviction penalty on a confirmed third consecutive miss; it does not charge the single-miss or invalid-proof penalty parameters (§8).
Mutability: Tier-0, key cip31.cbfs.min_relay_stake.
7. Relay Challenge Bond
por_challenge(shard_id, byte_offset, byte_length). CIP-9 §5.6 defines the challenge lifecycle; this CIP pins its governed bond, fee, and bounty amounts. The bond and per-challenger/relay challenge limits make repeated speculative challenges costly.
Lifecycle:
- Bond is escrowed at
0x0Buntil a valid response or expiry settlement afterPOR_RESPONSE_WINDOWand the congestion grace. - A valid response within the window or grace returns the bond less
POR_CHALLENGE_FEE = 7 CBY, retained in the challenge pool. An invalid response transaction is rejected; it does not resolve the challenge or itself cause a slash or bounty. - An unanswered challenge after the window and grace emits a miss alarm and returns the bond less
POR_CHALLENGE_FEE. With slashing disabled, the per-shard consecutive-miss count does not advance. With slashing enabled, a miss advances that count; a valid response resets it. A first or second consecutive miss does not slash stake or pay a bounty. - On the third consecutive miss with slashing enabled, the Relay is disabled and
RELAY_EVICTION_PENALTYis slashed up to its available stake (§8). The challenger receives the full bond and may receiveCHALLENGER_BOUNTY = 33 CBYfrom the challenge pool. The paid bounty ismin(CHALLENGER_BOUNTY, available_pool, epoch_cap_remaining), whereavailable_pool = max(pool_balance − reserve, 0)after crediting the slash’s pool share andepoch_cap_remaining = max(POR_BOUNTY_EPOCH_CAP − paid_this_epoch, 0).POR_BOUNTY_EPOCH_CAP(Tier-0,cip31.cbfs.por_bounty_epoch_cap, default unbounded) limits total bounties per rent epoch;cip31.cbfs.por_pool_reservedefaults to zero. The bond refund is independent of pool balance. - If the challenged shard incarnation is removed or replaced, or the volume reaches terminal
GARBAGE_COLLECTINGbefore an unanswered challenge settles, settlement voids the challenge: the full bond is returned, the open slot is released, and there is no fee, miss alarm, slash, or bounty. ReversibleDELETEDstatus does not void a challenge.
cip31.cbfs.relay_challenge_bond. POR_CHALLENGE_FEE and CHALLENGER_BOUNTY are sub-keys, both Tier-0.
8. Slashing Schedule
The three governed penalty values referenced by CIP-9 §14 are:RELAY_EVICTION_PENALTY, capped by its actual stake. A rejected invalid proof leaves the challenge open for a valid response or expiry; it does not charge POR_FRAUD_PENALTY. POR_MISS_PENALTY and POR_FRAUD_PENALTY remain governed values but are not applied by this settlement path. A void under §7 does not advance the miss count.
Distribution of slashed Relay stake. Slashed Relay CBY follows the same three-way proportions as storage fees — 10% / 1% challenge pool / 89% pro-rata to the other Relays (the slashed Relay is excluded from the pro-rata distribution that epoch) — but not the same disposition of the 10%. Slashed stake is a CBY position, so its 10% is burned, which composes cleanly with CIP-3’s deflationary design and recycles deterrent capital into the network rather than wholesale burn. Storage fees are nano-CBY and their 10% is credited to the Platform Fee Account 0x18 (§4), which is deliberately not a treasury share.
Mutability: All three penalty rows are Tier-0, keys cip31.cbfs.por_miss_penalty, cip31.cbfs.por_fraud_penalty, cip31.cbfs.relay_eviction_penalty.
9. Challenge Resolution Timing
PoR response verification resolves a valid challenge when the response transaction executes. An invalid response transaction is rejected and leaves the challenge open. An unanswered challenge may be settled only afterPOR_RESPONSE_WINDOW plus the congestion grace; the settlement rules are in §7. The 75-block runner-result dispute window does not delay or reverse this PoR path, and no EvidenceInvalidityAppeal is implemented for it.
10. Parameter Storage at 0x09 Governance
Governed parameters above are stored at the Governance system actor (0x09) in the CIP-12 centralized governance-parameter store, under logical paths cip31.cbfs.<name> (full key system:gov:param:cip31.cbfs.<name>). The Storage Manager (0x0A, CIP-9 §11.1) reads rent parameters for rent-epoch settlement and the transfer rate at channel checkpoint execution. Payer channel terms and operational gas/lifetime budgets are not silently created as governance defaults by this CIP.
These are governance parameters. The challenge-pool balance, escrowed challenge bonds, and per-epoch counters are runtime state and live separately at the Relay Registry system actor (0x0B) under ras:* keys (see §4 and §7) — the 0x0B address in this CIP refers only to that escrow/pool/bond state, never to the parameters.
11. Genesis-defaults Summary Table
Rationale
Why a separate CIP rather than amending CIP-9 inline. CIP-9 owns the data plane (shards, manifests, erasure coding, PoR mechanics). CIP-31 owns the economic plane (rates, splits, bonds, slashing magnitudes). Splitting them lets governance touch the economic surface (Tier-0 / Tier-2) without re-opening the data-plane spec. This mirrors CIP-3 ↔ WP §13 (mechanism vs parameter values). Why these specific values. The storage rate is anchored to commodity object storage. Backblaze B2 (7.64 / TiB / month ≈ 0.28 / GiB / yr) is the ceiling users would otherwise pay for hot, durable storage. A Relay stores 1.5× raw bytes per logical byte (K + M = 4 + 2 erasure coding) and keeps 89% of fees, so its break-even fee is ≈ 1.7× its underlying storage cost: roughly 154 / TiB / yr reselling B2. The chosen rate (~0.01 per decimal GB).
Why RELAY_CHALLENGE_BOND = 66 CBY. The bond locks challenger capital while a response is pending. A valid response or unconfirmed miss costs the challenger 7 CBY; a void returns the full bond. A full bond refund and a pool-bounded bounty require a confirmed third consecutive miss with slashing enabled. Thus a single induced miss does not create the fixed +26 CBY profit assumed by the earlier schedule.
Security Considerations
- Challenge griefing. The 66 CBY bond locks capital for each open challenge, and a valid response or unconfirmed miss retains the 7 CBY fee. A rejected invalid proof creates no bounty. Only a confirmed third consecutive miss with slashing enabled can pay a pool-bounded bounty; per-relay open-challenge and per-challenger epoch limits also bound issuance. A void caused by chain-state changes refunds the full bond without a fee.
- Rate cliff. Storage rate as a Tier-0 parameter means a single proposal could spike rent 10× in one epoch. The 30/90-day review cadence in §1 is documentation only; the protocol-level guardrail is CIP-12’s Tier-0 timelock (3 days) plus the per-epoch grace period (
STORAGE_GRACE_EPOCHS= 1 storage epoch =STORAGE_EPOCH_BLOCKS= 86,400 blocks ≈ 24 h) that lets evicted volumes recover. - Pro-rata gaming. The weight formula
shard_count × shard_ageis hard to game: shard assignment is VRF-controlled (CIP-9 §5.3), shard age accrues only with valid PoR responses, and the 90-epoch cap prevents permanent capture. - Slashed-stake recycling. The 10/1/89 split for slashed Relay stake (§8) sends 89% to the other Relays. This composes with the deflationary signal (10% burn) and provides an economic incentive for healthy Relays to call out misbehaving peers — without creating a perverse incentive to frame innocent peers (since the bounty is in the 1% challenge pool, not in the 89% pro-rata share).
Backwards Compatibility
Existing rent, split, bond and slashing parameters remain separate from the independently activated funded-channel extension. Old kind-27 read tickets/completions and signatures MUST NOT be reinterpreted as cumulative ACKs; capabilities, domains, records and replay state remain distinct. Neither payment mode is activated by this specification update. The rent/challenge parameters originally named here are either:- a TBD row in CIP-9 §14 being filled in with a concrete value (10 of 13 rows), or
- a renaming / explicit-bps version of the schema already present (
STORAGE_FEE_BURN_RATE10% becomesSTORAGE_FEE_PLATFORM_BPS = 1000;POR_CHALLENGE_FEE_SHAREbecomesSTORAGE_FEE_CHALLENGE_POOL_BPS = 100), or - a brand-new field (
RELAY_CHALLENGE_BOND,POR_CHALLENGE_FEE,CHALLENGER_BOUNTY,MAX_SHARD_AGE_FOR_WEIGHTING) that supplements but does not replace CIP-9 mechanism.

