How trading works
A bond changes hands by moving its NFT, and the protocol contracts run no venue. Any NFT marketplace can trade the token too, see Your bond as an NFT. Coffer runs one marketplace contract, separate from the protocol, where a holder sells a bond through a listing and a buyer bids for one through an offer. The marketplace holds nobody’s funds and nobody’s bonds. Both stay in their owner’s wallet until a fill settles through approvals, and the contract’s own balance carries only the fees it has earned. In the app the marketplace lives in the marketplace section of a bond’s page and in the Ask and Offer columns of Browse.
A listing and an offer
Section titled “A listing and an offer”A listing is the holder’s side. The holder names an ask in ETH, a buyer fills it and pays the ask plus the marketplace fee, and the bond moves to the buyer. An offer is the buyer’s side. A would-be buyer names an amount in WETH, the holder accepts it, and the WETH moves to the holder while the bond moves the other way. Either side can stand alone, a bond can carry a listing and several offers at once, and the first fill on either side settles the trade.
Signed messages
Section titled “Signed messages”Both are signed messages. Signing is free and happens off chain. The wallet signs a typed message with seven fields, the maker’s own address, the bond, the price or the amount, the bond’s maturity value, an expiration, and two counters called nonces. The signed message is stored off chain and shown in the app. Nothing touches the chain until the other side fills, and the fill is one transaction by the taker, in which the contract verifies the signature at that moment and settles. Signing costs nothing, and cancelling costs only the gas of a cancel transaction.
What moves at a fill
Section titled “What moves at a fill”When a buyer fills a listing, the NFT goes to the buyer, the ask goes to the seller in ETH, the fee stays in the marketplace, and any excess ETH is refunded. A seller whose wallet cannot take ETH within the gas allowed is paid in WETH instead, so the trade never fails on the seller’s side. When a holder accepts an offer, the WETH amount goes from the buyer to the seller, the WETH fee goes from the buyer to the marketplace, and the NFT goes from the seller to the buyer. Before anything moves the contract checks that the two parties differ, that the nonces are current, and that the seller still holds the bond and has approved the marketplace. It checks that the message has not expired, that the signature is the maker’s, that the bond is outstanding, and that the signed maturity value equals the bond’s live one.
Approvals, once each
Section titled “Approvals, once each”A holder gives the marketplace one approval to move their bonds, the card Approve Marketplace with the line “The Marketplace needs permission to manage your bonds before you can list them.” It covers every bond the wallet holds and is given once. A buyer approves WETH for the marketplace once and without limit, through Approve WETH, so no offer ever asks for it again. WETH itself comes from the wallet menu. Wrap ETH there turns ETH from your wallet into WETH, and Unwrap WETH turns it back.
One live signed message per maker and bond
Section titled “One live signed message per maker and bond”Every message is signed at the bond’s current nonce for that maker. A fill or a cancel advances the nonce by one, which kills every earlier signature on that bond, and a second, global nonce cancels everything a maker has signed in one transaction. Revoking is on chain only. Signing a new message off chain revokes nothing, so an earlier signature stays fillable until a fill or a cancel moves the nonce.
The app shows one message per maker and bond. A new message at the same nonce replaces it when it improves on its terms, a higher offer or a lower ask, in one signature and with no transaction. A message at equal or worse terms is refused, and the app offers the cancel first.
The improving replacement is allowed for a simple reason. A better price can be accepted earlier, and the earlier signature that stays on chain is a deal its maker signed. A taker who fills it takes the worse of the two terms on purpose.
Expirations
Section titled “Expirations”A listing expires at the bond’s maturity. An offer runs for the number of days its maker chose, from 1 to 90, 30 by default. The line under a price says when, “Expires at maturity, …”, “Expires … · …” with the time left, or “Expired …” once it has passed. Until then a signed message stays fillable.
The maturity value binds
Section titled “The maturity value binds”The bond’s maturity value is signed into every listing and offer and checked again at the fill. If the bond’s remaining value changed after signing, through a redemption or a claim in a default, the fill fails and the message is hidden until its maker signs again. The value binds the size of a claim, not its quality. Two bonds with the same maturity value can settle very differently, because what a claim can draw on is the coffer’s balance and its validator’s stake, and a defaulted coffer pays first come first served from whatever it holds. The checks on Before you buy apply to a purchase here as much as to a fresh bond. The app asks you to confirm them, in a review on the buy card and once at the WETH approval an offer needs.
The fee
Section titled “The fee”The marketplace charges a fixed 9 percent of the buyer’s profit, the maturity value minus the price or the amount, when that difference is positive. It is charged on completed trades only, never on signing or cancelling, and a trade at or above the maturity value pays no fee. The buyer of a listing pays it in ETH on top of the ask, and the maker of an offer pays it in WETH on top of the amount. Every card shows it in two rows, “Marketplace fee” over “You pay” or “You pay if accepted”. The rate is a constant in the contract with no setter, see Fees.
Shown and hidden
Section titled “Shown and hidden”Every listing and offer is checked before it is stored, against the conditions the contract will check at the fill. The checks go on while it stands, and a message that fails one is hidden. The reasons are six, its expiration passed, the bond is no longer outstanding, the maturity value changed, the WETH no longer covers the offer, a contract wallet withdrew its signature, or the seller no longer holds the bond. A maker whose offer is hidden reads why on the bond’s page, “Your offer is not shown” with the reason and “Cancel it on-chain to revise it.”, see Why an offer is not shown. A bond’s page shows the top 50 offers by amount and the count of all of them. One WETH balance can stand behind several offers and the first fill takes it, and a closed listing or offer is deleted 30 days after it closes.
What the app shows
Section titled “What the app shows”Browse carries an Ask column and an Offer column for every bond, and for a connected wallet with an offer of its own the status pill reads Bidding, or Outbid when a higher offer stands. A holder’s NFT card wears an Offer received pill while an offer stands on the bond. On a bond’s page the holder sees Approve Marketplace, then List Bond, then Cancel Listing once listed (List a bond walks through them), and an Offers table with the count and an Accept button per row. A visitor sees Buy Bond when the bond is listed, above Make Offer (Make an offer walks through it), or Cancel Offer once they have one. A holder who bid on a bond before holding it keeps that offer, “You made it before you held the bond. Nobody can fill it while you hold the bond, the next holder can.” A matured bond is not traded here, “It is no longer traded here.”, but a message signed while it was active stays fillable until its maker cancels it. Buying a listing and accepting an offer are on Buy or accept.
Contract wallets and phones
Section titled “Contract wallets and phones”A Safe or another contract wallet signs listings and offers through ERC-1271. The contract checks such a signature at the fill, and the wallet’s own code is asked before the message is shown, so a message whose wallet withdraws its signature is hidden. On a phone the app connects through WalletConnect or through a wallet’s own browser. Both are on Contract wallets.
Trading adds risks of its own, a stale signature, a pre-signed nonce, a bond whose value changes, a maker’s code inside a fill, and a defaulted coffer behind an ordinary looking maturity value. Risks states each with its mechanism.