Architecture
Coffer is three parts with three different jobs. The contracts on Ethereum are the protocol. The whitepaper calls it “a non-custodial dApp whose contracts rely on the Ethereum protocol alone, with no oracles and no governance”, and nothing in them can be upgraded. The server behind the app mirrors the chain for the app and stores the signed listings and offers, and it writes nothing on chain. The app is a website that reads the server, reads a few values from the chain itself, and sends transactions from the user’s own wallet. This page says what each part holds and what a reader can check without trusting any of them.
The contracts
Section titled “The contracts”Five contracts make up the protocol. The factory creates a Coffer for a validator at an address known before the creation, and the account that calls it becomes the Coffer’s owner, the validator. Each Coffer is a light copy of one shared implementation and holds one validator’s terms, balance and bonds. The bond NFT is one contract for every bond of every Coffer, and it registers the Coffers the factory created. The redemption escrow holds the maturity value of the bonds a validator settled, until the holder claims it. The fee curve sets the protocol fee by the time since its own deployment and pools the fees for the recipient. The factory deploys the last three and the implementation itself, once, when it is deployed. The marketplace is a sixth contract and a separate system, “not part of the Coffer protocol contracts” in the whitepaper’s words, which needs the bond NFT and WETH and reads a bond’s value from its Coffer. See How a bond works, How trading works, and the addresses on Networks and addresses.
A Coffer drives three contracts that the Ethereum protocol itself provides, the deposit contract, the withdrawal request contract and the consolidation request contract. Through them it tops up a validator, requests withdrawals and exits, and converts credentials, and Coffer runs only on chains where the last two exist. What ties a Coffer to a validator is the validator’s withdrawal credentials on the consensus layer. The contracts verify neither that link nor the validator’s balance behind the issue size, the holder checks both before buying, see Before you buy.
The contracts do not read the consensus layer. In the whitepaper’s words, “some parameters relevant to evaluating a bond are computed and presented off-chain rather than read on-chain”. The app presents them and the arithmetic that relates them, so a holder judges a bond from its components and not from one summary number. That is the first reason the server behind the app exists.
After deployment, little can change. The code of every contract is fixed. The protocol’s administrator, the owner of the fee curve, can change one thing, the address that receives the protocol fees, while the fee amounts and their schedule are code. Anyone can send the pooled fees to that address, and the call never pays the caller. A validator owns their Coffer and changes its terms, while bonds are outstanding, only in the holders’ favour, see Terms and what can change. The marketplace’s owner chooses the recipient of the marketplace fees and sweeps them, and the rate is a constant. There is no pause switch anywhere. A default is a state of the code, declared by anyone the moment a matured bond cannot be paid, see Default. The contracts’ source is published on GitHub under a licence the Terms describe, see What is Coffer.
The server behind the app
Section titled “The server behind the app”The server behind the app keeps a copy of the public data the app shows. It follows every event of the contracts as it happens, a Coffer created, a bond bought, redeemed or transferred, a sale, a cancel, a claim, a default. It reads the consensus layer every 12 seconds, one slot, for the validators’ balances and statuses, the deposit queue and the withdrawal queue. And it reads the execution layer for what the events do not carry, such as each Coffer’s balance.
From those reads it computes what the chain does not state, the coffer and bond statuses, the coverage band, the timeline of a bond’s history, the pending deposits and the scheduled withdrawals, and the network figures. Where a figure cannot be known yet it serves nothing rather than a guess. The coverage band is missing until a Coffer’s balance has been read, and it can only read too low and never too high, because a credit the server has not seen leaves the backing below the truth.
One kind of data exists nowhere else. A signed listing or offer is not the record of something that happened on chain. It exists because a maker signed and posted it, so the server holds it as a claim and checks it against the chain, once when it arrives and again every time it is shown. It hides a message that fails a check while the signature stays valid on chain, and it deletes a closed message 30 days after it closed, see Why an offer is not shown. Everything else the server holds is a mirror, and if it were lost it could be rebuilt from the chain, the signed messages and the history of the network figures excepted.
The server never sends a transaction, holds no key and holds no funds. It can show or hide, and nothing more. Its reads enforce the conditions the contract enforces, as far as it can see them, so that a message it serves is one the contract would fill, and it refuses to store a message it could not verify.
The app
Section titled “The app”The app has three data paths. Every list and every detail view comes from the server behind the app. A few values come from the chain directly. They are the marketplace nonces, the WETH balance and allowance, the approval of the marketplace on the bond NFT, the holder’s escrow balance, a bond’s live remaining value, a Coffer’s outstanding bond count. The network’s request fee is read at the click, because the queue prices it. Everything else comes from the user’s wallet, the address, every signature and every transaction. The app builds a transaction, pins it to the one chain it runs on, and hands it to the wallet, which signs it and sends it through its own connection. A wallet on another chain sends nothing. The app holds no key and never sends a transaction itself.
One rule shapes every action. A transaction is done when the server or the chain shows its effect, not when the receipt arrives, and the button reads Syncing… in between, usually for a few seconds. A listing or an offer is not a transaction. The maker signs a message and the app posts it to the server, which verifies it and serves it.
The app is one of three websites. The site at coffer.bond carries no wallet code, the app at hoodi.app.coffer.bond does, and these docs are the third. Networks and addresses lists them with the contract addresses.
What you can check on the chain, and what you take from the server
Section titled “What you can check on the chain, and what you take from the server”On the chain, with a block explorer or a node of your own, and without the app or the server:
- A Coffer’s terms, its balance, its outstanding bonds and whether it is in default, and every transaction and event that touched it.
- A bond’s holder, its maturity value and its remaining value, on the bond NFT and its Coffer.
- The marketplace’s nonces for a wallet and a bond, whether a holder approved the marketplace, and a bidder’s WETH balance and allowance.
- On the consensus layer, the validator’s balance, its status and its withdrawal credentials, the link between the validator and its Coffer that the contracts do not verify.
From the server behind the app, mirrored from public data or derived from it:
- The coffer and bond statuses, and the coverage band with its buffered, covered and uncovered words, all on Statuses across the layers.
- The pending deposits, the scheduled withdrawals and the network’s figures.
- A bond’s history as one timeline, from the chain’s events and the server’s own records.
- The listings and offers, which are shown and which are hidden and why.
The server can be wrong in known ways and known directions. It can lag the chain by a few seconds, and it can stop. It can serve a message the contract then rejects, which costs the taker gas and nothing else, and it can hide a message that stays valid on chain until its maker cancels it. Its coverage band can read too low and never too high. And it trusts the nodes it reads. None of this moves funds, changes a bond or signs for anyone. What moves funds is a transaction from a wallet, and the checks before one are on Before you buy and Risks.
Who runs what
Section titled “Who runs what”Ethereum runs the contracts, and after deployment nobody can change them, beyond the fee recipients and each validator’s own terms. The wallet is run by its maker and sends transactions through its own connection to the network. The Terms say who runs the server and the app and what is published, and the Privacy Notice names the providers that handle data along the way.