Architecture
| Contract | Responsibility |
|---|---|
CovenantCoin | ERC-20, fixed supply, no mint function; reports outbound transfers to the bonds contract |
CovenantCore | The Uniswap v4 hook: tax, launch tax, the 10% retention and its exemption, the launch band |
CovenantNotes | Bond positions: accrual, compounding, claims |
CovenantSwap | UX entrypoints wrapping PoolManager.unlock |
CovenantBondMarket | Fixed-price marketplace for bonds: takes custody while listed, constant fees |
CovenantMath | Pure helpers |
All contracts are immutable: no proxy, no upgrade path, nothing about them can be
rewritten after deployment. There is no assembly, no delegatecall, no selfdestruct,
and all arithmetic is checked.
Immutable is not the same as ungoverned, and it would be dishonest to leave it there. These powers are held by the deploying key and survive forever, because they cannot be removed any more than the rest of the code can:
| Power | What it can do | What it cannot do |
|---|---|---|
| Emergency stop | Halt claiming, compounding, merging, transfers, and with them the whole marketplace. The protocol clock stops too, so nothing accrues while it is on and nothing is lost when it lifts. | Take anything. Principal and rewards stay where they are, and swapping the token is deliberately left running so holders are never trapped. |
| Transfer lock | Close bond transfers again after opening them, which also closes the marketplace, since every listing moves the token. | Take a bond or its rewards. Claiming and compounding keep working, and a listed bond can still be cancelled back to its seller. |
| Retention dial | Lower the sell-side retention below its engraved 10% cap, down to zero, which mints no sell bonds at all, and restore it afterwards. | Raise it past the cap: RETENTION_CAP_BPS is a constant, so exiting can never cost more than launch day advertised. It leaves the 3% tax, the exemption quota and already-minted positions untouched. |
| Rate grant | Add daily rate to every bond at once, positions already open included, and clear it again. It is not capped, and it sits on top of the 20%/day ceiling rather than inside it, so what a bond pays is not bounded by that ceiling. | Lower a bond below the rate it earned: the grant only ever adds. It touches no principal, no balance and no ownership, and settles nothing: each position picks up a change on its next touch, for at most one window of elapsed time. |
| Rate floor | Lift every bond to one daily rate at once, whatever its ladder, and clear it again. Uncapped and immediate: a floor at 30%/day means every position reads 30%/day from that block, with nothing to claim or compound first. | Take a bond below its own rate, or below the floor. It writes no position, so clearing it puts every ladder back exactly where its holder left it. |
| Metadata source | Point the NFT artwork at a renderer, then freeze that choice permanently. | Touch balances, rates or ownership. A renderer that misbehaves degrades to "no image". |
Three of them deserve to be weighed honestly. The transfer lock is reversible in both directions: it is a switch, not a one-way unlock, so "transfers are open" is a state and not a promise. While the emergency stop is on you cannot withdraw rewards you have already earned, and a key lost in that state would freeze them for good. The rate grant is the one that touches the numbers: with it, the yield a bond pays is not a property of the code alone, and the same key that raises it can clear it back to zero.
What the code still guarantees is the floor and the direction: a grant only ever adds, no setting can take a position below the rate it earned, and no setting can make exiting cost more than the 10% the cap allows. These are trusted roles, not trustless guarantees, and you should treat them as such.
How the pieces talk
trader ──→ CovenantSwap ──→ PoolManager ──→ CovenantCore
│
10% retained on a non-exempt sell ───┘
↓
CovenantNotes ──(rewards)──→ bond holders
The hook is the only contract that touches Uniswap. The bond contract holds plain ERC-20 balances and never interacts with the pool, which keeps the reward accounting completely independent of anything happening on the exchange.