Skip to main content

CovenantBonds & CovenantBondVault

CovenantBonds

Every position is an ERC-721 token, so the storage is keyed by token id rather than by address. That is what lets one wallet hold several distinct positions, each with its own principal, rate and bonus clock.

FieldMeaning
principalThe basis rewards are computed on. Not a withdrawable balance.
pendingAccrued and not yet claimed
rateBpsStored daily rate — base plus compound steps, 1000 (10%) to 2000 (20%). The commit boost is not stored here; it is applied live.
origin0 = Sell, 1 = Commit. Permanent — it survives everything.
ownedSinceWhen the position last changed hands
boostDeadSticky: once the boost is forfeited it never returns for that bond

Entrypoints

  • openBond(amount) — voluntary, 20%..100% of the caller's balance, 15%/day effective at birth (the 10% base plus the +5 boost). Mints a new position.
  • openBondFrom(owner, amount) — the sell-side retention, entry rate 10%/day, callable only by the wired retention source
  • compound(tokenId) — rolls pending into principal; adds +0.25 point at most once per 6h. The effective rate never exceeds 20%/day.
  • claim(tokenId) — pays out to the owner; the rate is untouched
  • merge(tokenIds) — consolidates your positions into the first one; every bond merged must share the same origin and the same boost state
  • tokensOf(address) — lists a holder's positions, so the app needs no indexer

Views worth knowing

  • rateOf(tokenId) — the stored rate: base plus compound steps
  • effectiveRateOf(tokenId) — the stored rate plus the live boost, capped at 20%/day — the number a holder actually earns
  • exemptAllowanceOf(address) — retention-free selling volume left: 5 x commitPrincipalOf minus exemptUsedOf, floored at zero. The figure that prices a sale: the hook waives the retention only while it covers the whole amount
  • commitPrincipalOf(address) — sum of the wallet's commit-origin principals, the base of the allowance. Grows on openBond and on every compound of a commit bond
  • exemptUsedOf(address) — exempt volume consumed, lifetime. The hook adds to it through consumeExemption(seller, amount), which only the wired retention source may call
  • debitedThisTx(address) — how much CVN the wallet has sent out so far in the current transaction. Zero at the start of every transaction, and spent by consumeExemption, so it proves a seller is really selling on a route the hook cannot otherwise vouch for
  • hasCommitBond(address) — true while the wallet owns at least one commit-origin bond (display-level; the allowance is what decides)
  • commitBondCountOf(address) — how many commit-origin bonds the wallet holds
  • lastStripAt(address) — the instant the wallet last moved tokens out

EXEMPT_CAP_MULTIPLE is the constant behind the allowance: 5.

The token contract reports every outbound transfer to CovenantBonds — the wallet and the amount (onTokenDebit, wired once via initBonds), which is what strips the boost and what feeds the same-transaction tally; zero-amount transfers and self-transfers are ignored, so nobody can strip a stranger with a 0-amount transferFrom. tokenURI is fully on-chain and lists each position's principal, origin, whether its boost is active, and the effective daily rate.

CovenantBondVault

Cold storage. It can do exactly one thing: send a fixed tranche to the distributor.

setDistributor(address) → correctable
freezeDistributor() → irreversible
releaseTranche() → possible ONLY after the freeze

The guarantee

releaseTranche reverts while the destination is still changeable. Setting a destination and moving value are therefore mutually exclusive states, and anyone can check which one holds:

  • the address is still editable → the vault cannot move a single token; or
  • tokens can move → the address is already permanent.

That closes the window a plain "setter now, renounce later" pattern would leave open, during which an operator could point the vault at their own wallet. The destination must also be a contract, so a mistyped wallet address cannot become it.

The operator controls when. Never where.