> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cowboy.inc/llms.txt
> Use this file to discover all available pages before exploring further.

# Cip 31 cbfs rent schedule

# CIP-31: CBFS Rent Schedule

| Field           | Value                                                                           |
| --------------- | ------------------------------------------------------------------------------- |
| **CIP**         | 31                                                                              |
| **Title**       | CBFS Rent Schedule, Relay Challenge Bond, and Slashing Curve                    |
| **Status**      | Draft                                                                           |
| **Type**        | Standards Track (Economic / Parameter)                                          |
| **Created**     | 2026-05-14                                                                      |
| **Author(s)**   | Cowboy Foundation                                                               |
| **Depends-on**  | CIP-9 (RAS / CBFS), CIP-3 (fee model), CIP-12 (governance)                      |
| **Required-by** | CIP-9 §10.4 / §14 (replaces TBD parameter values); WP §17.6 (forward reference) |

## 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

```
STORAGE_FEE_PER_MIB_PER_EPOCH = 2905  // nano-CBY per MiB per rent epoch (1 day per CIP-4)
```

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.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

```
TRANSFER_FEE_PER_MIB = 66_700  // nano-CBY per MiB served on read
```

≈ $0.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

```
MIN_STORAGE_BALANCE = STORAGE_FEE_PER_MIB_PER_EPOCH × ceil(volume_size_bytes / 2^20) × 1
```

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:

| Share   | Destination                                                | Rationale                                                                                  |
| ------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **10%** | **Platform Fee Account** (credited to system actor `0x18`) | Marketplace platform share; disposition below                                              |
| **1%**  | **PoR Challenge Pool** (accrued at `0x0B` Relay Registry)  | Funds challenger bounties (§7 below); paid out on valid `por_challenge` settlement         |
| **89%** | **Relay pro-rata distribution**                            | Active Relays, weighted by `weight_i = (shard_count_i × shard_age_in_epochs_i)` (§5 below) |

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

```
weight_i  = shard_count_i × shard_age_in_epochs_i
share_i   = weight_i / Σ_j weight_j
payout_i  = share_i × (storage_fees_collected × 0.89)
```

* `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

```
MIN_RELAY_STAKE = 33_000 CBY
```

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**)

```
RELAY_CHALLENGE_BOND = 66 CBY
```

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:

```
POR_MISS_PENALTY        = 330  CBY     // Relay failed to respond within POR_RESPONSE_WINDOW
POR_FRAUD_PENALTY       = 3300 CBY     // Relay responded with provably invalid data (> MISS by 10×)
RELAY_EVICTION_PENALTY  = 13200 CBY    // Relay forcibly removed from registry (multiple consecutive frauds, or refusal to repair under §5.5)
```

**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.

```
0x09 governance parameters (CIP-31), stored under the CIP-12 `system:gov:param:` prefix:
  cip31.cbfs.storage_fee_per_mib_per_epoch        u64 (nano-CBY)
  cip31.cbfs.transfer_fee_per_mib                 u64 (nano-CBY)
  cip31.cbfs.fee_split.platform_bps                   u16 (default 1000)
  cip31.cbfs.fee_split.challenge_pool_bps         u16 (default 100)
  cip31.cbfs.fee_split.relay_bps                  u16 (default 8900)
  cip31.cbfs.min_storage_balance_epochs           u16 (default 1)
  cip31.cbfs.min_relay_stake                      u64 (CBY)
  cip31.cbfs.relay_challenge_bond                 u64 (CBY)
  cip31.cbfs.por_challenge_fee                    u64 (CBY, default 1)
  cip31.cbfs.challenger_bounty                    u64 (CBY, default 5)
  cip31.cbfs.por_miss_penalty                     u64 (CBY)
  cip31.cbfs.por_fraud_penalty                    u64 (CBY)
  cip31.cbfs.relay_eviction_penalty               u64 (CBY)
  cip31.cbfs.max_shard_age_for_weighting          u16 (default 90)
```

### 11. Genesis-defaults Summary Table

| Parameter                        | Default         | Mutability | Key                                        |
| -------------------------------- | --------------- | ---------- | ------------------------------------------ |
| `STORAGE_FEE_PER_MIB_PER_EPOCH`  | 2,905 nano-CBY  | Tier-0     | `cip31.cbfs.storage_fee_per_mib_per_epoch` |
| `TRANSFER_FEE_PER_MIB`           | 66,700 nano-CBY | Tier-0     | `cip31.cbfs.transfer_fee_per_mib`          |
| `STORAGE_FEE_PLATFORM_BPS`       | 1000 (10%)      | Tier-0     | `cip31.cbfs.fee_split.platform_bps`        |
| `STORAGE_FEE_CHALLENGE_POOL_BPS` | 100 (1%)        | Tier-0     | `cip31.cbfs.fee_split.challenge_pool_bps`  |
| `STORAGE_FEE_RELAY_BPS`          | 8900 (89%)      | Tier-0     | `cip31.cbfs.fee_split.relay_bps`           |
| `MIN_STORAGE_BALANCE_EPOCHS`     | 1               | Tier-0     | `cip31.cbfs.min_storage_balance_epochs`    |
| `MIN_RELAY_STAKE`                | 33,000 CBY      | Tier-0     | `cip31.cbfs.min_relay_stake`               |
| `RELAY_CHALLENGE_BOND` (**new**) | 66 CBY          | Tier-0     | `cip31.cbfs.relay_challenge_bond`          |
| `POR_CHALLENGE_FEE`              | 7 CBY           | Tier-0     | `cip31.cbfs.por_challenge_fee`             |
| `CHALLENGER_BOUNTY`              | 33 CBY          | Tier-0     | `cip31.cbfs.challenger_bounty`             |
| `POR_MISS_PENALTY`               | 330 CBY         | Tier-0     | `cip31.cbfs.por_miss_penalty`              |
| `POR_FRAUD_PENALTY`              | 3,300 CBY       | Tier-0     | `cip31.cbfs.por_fraud_penalty`             |
| `RELAY_EVICTION_PENALTY`         | 13,200 CBY      | Tier-0     | `cip31.cbfs.relay_eviction_penalty`        |
| `MAX_SHARD_AGE_FOR_WEIGHTING`    | 90 epochs       | Tier-0     | `cip31.cbfs.max_shard_age_for_weighting`   |
| Relay weight formula structure   | (§5)            | Tier-2     | `cip31.cbfs.relay_weight_formula`          |

## 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.95 per decimal TB / month = $7.64 / TiB / month ≈ $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 $35–70 / TiB / yr self-hosted on commodity hardware, ~$154 / TiB / yr reselling B2. The chosen rate (\~$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.
