Skip to main content

CIP-31: CBFS Rent Schedule

Abstract

This CIP pins concrete CBY values for every parameter that CIP-9 (Runner Storage / CBFS) currently labels TBD, adds a new RELAY_CHALLENGE_BOND field, makes the existing 10 / 1 / 89 burn / 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. This CIP does not introduce any new mechanism in CIP-9.

Motivation

  1. Let Relay operators run capacity-planning math before mainnet.
  2. Let storage-rate volatility (CBY-denominated rent vs USD/GB/yr reality) be observable, monitored, and Tier-0-adjustable on a documented cadence.
  3. Provide the challenger economic incentive that makes Proof-of-Retrievability honest in steady state.
  4. Bound the worst-case Relay-side loss in slashing events.

Specification

1. Storage Fee Rate

Volumes are billed on 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 **6.95perdecimalTBpermonth,whichis6.95 per decimal TB per month**, which is 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

0.01025/GiBservedattheadministeredratewithin50.01025 / GiB served at the administered rate — within 5% of Backblaze B2's over-allowance egress price (0.01 per decimal GB = $0.010737 / GiB). An exact match would be ≈ 69,900 nano-CBY; the ~4.6% residual is well inside administered-rate uncertainty, so the round constant stands. A Runner reading a 100 MiB object pays 66,700 nano-CBY × 100 = 0.00667 CBY per read. Goes entirely to the serving Relay (no burn, no challenge-pool share). Mutability: Tier-0, key cip31.cbfs.transfer_fee_per_mib.

3. Minimum Storage Balance

i.e. one epoch of fees at the current rate for the volume’s current size. Falls below this triggers 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
Mutability: Tier-0 governance under cip31.cbfs.fee_split; the invariant MUST hold after any proposal. Disposition of the 10% share. Storage and transfer fees are collected in CBY (§1, §2). 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_i is the number of unique shards Relay i currently holds and serves with valid PoR responses in the prior epoch.
  • shard_age_in_epochs_i is min(epochs_since_assignment, MAX_SHARD_AGE_FOR_WEIGHTING) where MAX_SHARD_AGE_FOR_WEIGHTING = 90 epochs (~3 months at 1-day epochs). The cap prevents permanent first-mover advantage.
Rationale. Pure shard-count weighting rewards Relays that load shards fast but never repair; pure age weighting rewards squatters. The product rewards Relays that take on real storage AND keep it healthy over time. The 90-epoch cap is a Tier-0 parameter. Mutability: Tier-2 governance (changes the revenue distribution mechanism). Key: cip31.cbfs.relay_weight_formula. Tier-0 may not change the formula structure, only MAX_SHARD_AGE_FOR_WEIGHTING.

6. Minimum Relay Stake

Required to register a Relay Node via the Relay Registry (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 penalties were scaled by the same 6.6x, preserving every internal ratio — miss, fraud and eviction remain 1%, 10% and 40% of 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 break-even miss fraction therefore moves from 1/6 to 7/40, slightly against the challenger. Mutability: Tier-0, key cip31.cbfs.min_relay_stake.

7. Relay Challenge Bond (new field)

The CBY a challenger MUST post when calling por_challenge(shard_id, byte_offset, byte_length). This is new — CIP-9 §5.6 currently describes PoR challenges but specifies no challenger bond. Without a bond, a malicious actor can submit unlimited challenges to grief Relay Nodes (each forces a POR_RESPONSE_WINDOW Relay-side computation). Lifecycle:
  • Bond is escrowed at 0x0B for the duration of the challenge window.
  • If the Relay responds correctly within POR_RESPONSE_WINDOW blocks: bond is refunded to the challenger minus a POR_CHALLENGE_FEE = 7 CBY (kept by 0x0B as the per-challenge cost; deters frivolous challenges).
  • If the Relay fails or responds incorrectly: bond is refunded in full and the challenger additionally receives a CHALLENGER_BOUNTY = 33 CBY from the PoR challenge pool (§4 above).
    • Pool-bounded (no underflow). The paid bounty is min(CHALLENGER_BOUNTY, available_pool, epoch_cap_remaining), where available_pool = pool_balance − reserve and epoch_cap_remaining = POR_BOUNTY_EPOCH_CAP − paid_this_epoch. If the challenge pool cannot cover the full bounty, the challenger receives only what the pool holds (the pool never goes negative and no bounty is minted beyond it). POR_BOUNTY_EPOCH_CAP (Tier-0, cip31.cbfs.por_bounty_epoch_cap, default unbounded) additionally bounds total bounties per rent epoch, preventing a pool drain from starving the challenge timer’s own pre-charge (§9). The challenger’s bond refund is unconditional and independent of pool balance.
  • The Relay is slashed per §8 below.
Mutability: Tier-0, key cip31.cbfs.relay_challenge_bond. POR_CHALLENGE_FEE and CHALLENGER_BOUNTY are sub-keys, both Tier-0.

8. Slashing Schedule

The three CIP-9 §14 TBD penalty rows are pinned as:
Rationale: A single miss is operational noise (Relays restart, NICs flap). A fraud response is provably dishonest. Eviction is the terminal state. 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. Dispute Window

The on-chain dispute window for a Relay’s challenge response is 75 blocks (DISPUTE_WINDOW_BLOCKS per WP §13), aligned with CIP-2’s runner-result dispute window. After 75 blocks the response settles; no later reversal except via cryptographic EvidenceInvalidityAppeal (see CIP-32 once authored).

10. Parameter Storage at 0x09 Governance

All values above are stored at the Governance system actor (0x09) in the CIP-12 centralized governance-parameter store, under logical parameter paths cip31.cbfs.<name> (full on-chain key system:gov:param:cip31.cbfs.<name>). The Storage Manager system actor (0x0A per CIP-9 §11.1) reads these keys at the start of each rent-epoch to settle fees. 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 (6.95perdecimalTB/month=6.95 per decimal TB / month = 7.64 / TiB / month ≈ 0.0896/GiB/yr)isthereferenceflooritiswhataRelayoperatorwouldpaytosimplyresellhostedstorageandS3Standard( 0.0896 / GiB / yr) is the reference floor — it is what a Relay operator would pay to simply resell hosted storage — and S3 Standard (~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 3570/TiB/yrselfhostedoncommodityhardware, 35–70 / TiB / yr self-hosted on commodity hardware, ~154 / TiB / yr reselling B2. The chosen rate (~167/TiB/yr,1.82×B2)coversaselfhostedRelay35×over,leavesmarginevenforaRelaybackingontoB2,pricesthePoR/stake/slashingriskpremiumthatcentralizedprovidersdonotbear,andstillundercutsS3readimmediatelystoragewithverifiableretrievability,withoutSLAgradereplication.ThetransferratematchesB2soverallowanceegressprice(167 / TiB / yr, ≈ 1.82× B2) covers a self-hosted Relay 3–5× over, leaves margin even for a Relay backing onto B2, prices the PoR / stake / slashing risk premium that centralized providers do not bear, and still undercuts S3 — read-immediately storage with verifiable retrievability, without SLA-grade replication. The transfer rate matches B2's over-allowance egress price (0.01 per decimal GB). Why RELAY_CHALLENGE_BOND = 66 CBY. Sized to 1/5 of POR_MISS_PENALTY, so a challenger who provokes a miss is net economically positive (+33 bounty − 7 challenge fee = +26 CBY per valid challenge) while a frivolous challenger loses the 7 CBY fee deterministically.

Security Considerations

  1. Challenge griefing. Without RELAY_CHALLENGE_BOND a single attacker could submit thousands of cheap challenges per block. The bond + per-challenge fee (7 CBY) make this economically irrational below roughly one genuine miss per six attempts: a challenger nets +33 CBY (bounty) on a real miss and loses 7 CBY (fee) on a correct response, so expected value is 40p − 7 at miss-fraction p, breaking even at p = 7/40 ≈ 0.175.
  2. 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.
  3. Pro-rata gaming. The weight formula shard_count × shard_age is 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.
  4. 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

This CIP introduces no semantic change to CIP-9. Every parameter named here is 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_RATE 10% becomes STORAGE_FEE_PLATFORM_BPS = 1000; POR_CHALLENGE_FEE_SHARE becomes STORAGE_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.