Skip to content

Introducing v3: Every change to the Bondi core, and why

16 min readAli Sarp Mestçioğlu

Bondi v3 is built on the v2 contracts and closes the gap between a token that pays coupons and a bond: calls, amortizations, a supply that grows, fees taken onchain, proceeds that never pass through Bondi's hands, and a coupon that trades. This post walks every change to the core and the reason for it.

Introducing v3: Every change to the Bondi core, and why — three aligned mint grid layers meeting in one deep pine core.

Where v2 left off

Bondi v2 put the bond onchain as a fungible, verifiable token. A Bond Token (BT) is a token backed one to one by publicly traded corporate bonds under regulated custody, each token representing $100 of face value; a basket BT holds several bonds inside one token. v2 carried a bond's simplest life onchain: one funding, one issuance, coupons by snapshot, principal at maturity. It ran real bonds from issuance to maturity without incident.

Bondi v3 is the next step on that same core. It is built on the v2 contracts, not beside them, and it closes the gap between "a token that pays coupons" and "a bond": calls, amortizations, a supply that can grow, fees taken onchain, proceeds that never pass through Bondi's hands, a coupon that trades, and a backend that operates all of it. This post walks every change and the reason for it. 🐢

The design rule has not moved. The BT is a faithful bond, because bonds issued natively onchain one day will be exactly that, and the primitive for that future has to replicate a bond in full today. Two vaults sit on top of the primitive and are part of v3. The Reinvestment Vault takes BTs and issues a compounding vault share, vBT, which is what lending markets take as collateral. The Redemption Vault gathers exits of any size into one real bond sale.

Everything else about them, the batch, the reinvestment guards, the share oracle, is in their own posts: the Redemption Vault and the Reinvestment Vault.


Bondi never touches your money

The largest change in v3 is the one a holder never sees.

In v2, proceeds reached holders through Bondi. Coupon money came from the custody partner, passed through Bondi's own Safe, and the Safe deposited it into the distribution contract before a snapshot was taken. Each payment needed the partner and Bondi to act in a specific sequence, a process that worked but was not built to scale. Fees were computed off-chain, taken off-chain, and baked into the mint price of the token; the contracts had no notion of them.

In v3 the regulated partner that holds the bonds sends coupon, call and principal proceeds straight into the distribution contract, and Bondi's role shrinks to one verb: register. The treasury Safe registers the event on the contract, which deducts the commission fixed at deployment and books the net amount as a liability to holders. Bondi never holds the funds, and the contracts do not give it a way to.

Registration is guarded. The contract carries three pairs of counters, registered and paid, for coupons, for calls and for principal. Paid can never exceed registered. A new registration is refused unless the stablecoins the contract already holds, net of every existing liability, cover it. The solvency check runs before the liability exists, so nothing is ever promised against money that is not there.

Fees moved onchain with the same stroke. The service fee, the minting commission, the coupon commission and the principal commission are immutable values written into the funding contract at deployment. The first two are taken when the funding is extracted, the last two at every registration, for the life of the bond, and there is no function anywhere to change them. Fees can also be split across several receivers, so a bond launched with a partner shares revenue by contract rather than by invoice.


Issuance: funding, extraction, emission, and rounds

v2 already moved through the same three phases, funding, extraction and emission. What changed is what each phase knows.

  • Funding now has a target and a maximum, for two reasons that come from the bond market itself. A funding succeeds when it reaches its target, and extraction is only possible once it has. The target exists because the bond behind the token trades in institutional lots: nearly every USD bond issued in the international market carries a $200,000 minimum, while many US-registered bonds trade in $1,000 or $2,000 pieces and allow a far lower target. Below the lot, no bond can be bought. The maximum exists because a bond has a finite amount outstanding and a finite depth at a fair price; a funding that pulled in far more than the market could fill at that price would either strand the excess or buy badly. Between the two, a funding can run oversubscribed until Bondi extracts. In v2 the target was also the cap. v2 also assumed a six-decimal stablecoin; v3 reads the decimals of whatever stablecoin the bond is launched with.

  • Extraction takes the raised stablecoins, deducts the service fee and minting commission onchain, splits them across the fee receivers, and forwards the remainder to the custody partner that buys the bonds. In v2 the fees had already been taken before this step and the whole balance went out.

  • Emission mints the Bond Token supply from two pricing inputs, the bond's clean price and its accrued interest, whose sum is the dirty price the partner actually paid. In v2 a single mint price was entered by hand. Supply now follows from post-fee capital and the real purchase price, so every token is backed by exactly the bonds it claims.

  • Delivery is new. When an investor funds, they hold a non-transferable funding receipt for their deposit. In v2 each investor had to come back after emission and convert that receipt into Bond Tokens by hand, and this was the single most requested change. In v3 Bondi's relayer converts every receipt of every investor with completed identity verification (KYC) and delivers the Bond Tokens to their wallet. Self-claim remains open to anyone who prefers it.

  • Rounds. The same Bond Token can now be minted many times. In v2 a Bond Token could be minted once, so its supply could never be increased after the first issuance. In v3 each funding round has its own funding contract and its own receipt, and all rounds share one Bond Token and one distribution contract, so supply grows with demand. A later round is priced at the bond's dirty price on that day, so a later investor pays what the bond is worth and receives exactly the tokens that price implies. A round is closed only when every receipt has been converted and any rounding dust has been burned; until then, the next round cannot open and no coupon or call can be registered. The reason is snapshot integrity: whenever a coupon or a call reads balances, total supply equals what holders actually hold.

  • Maturity can be extended once principal has been registered, for the case where a bond's terms move.

Bondi v3: one funding round, repeatable, and the payout path from the regulated token issuer through the distribution contract to holders


Every payout, delivered

The relayer is Bondi's payout service, and in v3 it covers the whole life of the token: Bond Token delivery after a funding, coupons, calls, and after maturity plus a set delay, principal for holders who have not acted, burning their tokens and paying them. Self-claim onchain is open to every holder on every path, from day one to maturity.


Issuer calls, done properly

A call is the event v2 had no answer for. In v3 it is a full path with a freeze around it.

  1. The custody partner funds the distribution contract with the call proceeds. The treasury registers the call with the gross amount and the called fraction. Commission is deducted, the net liability is reserved, the price per token is fixed, the amount of BT to retire is computed from supply at that block, and the Bond Token freezes.
  2. The backend reads every holder's balance at the registration block.
  3. The relayer executes the call for each holder against that balance. The called fraction is burned and the holder is paid at the fixed price. If a balance does not match, nothing changes and the row is flagged.
  4. When the retired total reaches the target, the token unfreezes in the same transaction.

The freeze is the point. Because nothing moves between registration and completion, there is no moving snapshot to reconcile and no way to position around the event: every holder is paid exactly on the balance they held. And the freeze is short. The relayer processes the whole holder list in a burst, so a token with thousands of holders is untransferable for a matter of seconds. An amortization, or one constituent of a basket maturing early, settles through the same call path at par. 💸


The Coupon Token and the Principal Token

Whenever a coupon reached a holder who had not completed KYC, v2 had one answer: wait. The coupon sat unclaimed in the distribution contract, and inside the Reinvestment Vault an entitlement entry recorded stablecoins the vault could not hand over. Ledger entries, frozen until paperwork.

Those ledgers are gone. In their place are transferable tokens: the Coupon Token, a bearer coupon in digital form, and its twin for principal, the Principal Token. One token is one dollar of claim, in the stablecoin's own decimals. It is minted only by the distribution contract or the vault, only against stablecoins already sitting in that contract for that holder, and the stablecoins stay exactly where they are. The token's supply is always backed one to one, and nothing else can mint it.

When a coupon is processed, the fork is explicit. A wallet with KYC is paid stablecoins. A registered vault is paid stablecoins and receives its accounting callback, so vault holders are credited per share rather than handed a token. Everyone else receives Coupon Tokens for their exact entitlement, and the entitlement is marked settled before the mint, so the same coupon can never be collected twice. The stablecoin left over when a holder without KYC exits the Reinvestment Vault is minted the same way. And principal has its own token: when an amortization, a call or a maturity returns principal to a holder without KYC, a Principal Token is minted for exactly that amount, one token, one dollar, cashed in exactly the same way. Interest and return of capital are different things for a holder's accounting, so they carry different names; economically the two tokens are identical.

Holding the token needs no KYC, and neither does transferring it. Cashing it in does: any holder of the token who has completed KYC, not only the original snapshot address, can burn any amount and receive the same amount of stablecoin from the contract that owes it. A wallet blacklisted at a regulator's request receives its Coupon and Principal Tokens like anyone else, but cannot move them or cash them in until the matter is resolved, and the same blacklist applies to every Bond Token. The token is independent of the Bond Token's freezes: during a call the bond is frozen and the coupon still moves. It is not collateral anywhere and is not meant to be.

The snapshot and the proof stay exactly as they were. The Merkle tree still fixes who is owed what at the coupon block; what changed is that the delayed claim became a bearer instrument instead of a ledger entry. The paper bond had this right: whoever held the coupon got paid. 🎟️


Compliance with a narrower hand

v2's Bond Token let the admin Safe move any balance between any two wallets, a power far broader than any compliance case needs, and admin actions bypassed the pause and the blacklist. Both are gone. What replaced them:

  • A compliance burn that works only on a wallet already blacklisted, only when compliance authorities order it, and never on a registered vault. It relocates the tokens to the admin Safe rather than destroying them, so total supply stays intact for accounting, and it emits its own event.

  • Blacklisting as one action. The KYC register tracks every Bond Token attached to it. When a regulator's request revokes a wallet's KYC, the wallet is blacklisted on all of them, and on the Coupon and Principal Tokens, in one transaction.

  • Two brakes instead of one. v2 had a single admin pause. v3 keeps the emergency pause, which halts transfers while compliance actions continue, and adds the call freeze, which is automatic and stricter: from registration to completion, transfers, mints and every other burn revert, and only the call's own burns pass.

  • A participant whose KYC is revoked between funding and delivery is handled by one defined path when the round closes: the receipt is burned, the tokens go to the admin Safe so supply stays intact, and any refund is handled under compliance policy off-chain.


Vaults are part of the primitive

The two vaults introduced above, the Reinvestment Vault that issues the vBT collateral and the Redemption Vault that turns exits into a real bond sale, are not bolted on. The core is built to know them. A vault is registered on the core stack; from then on the distribution contract pays it like any holder and calls back into it in the same transaction, so proceeds are credited per share the moment they land: a coupon becomes more BTs in the Reinvestment Vault, and a call settles a pending request in the Redemption Vault. Before each settlement event the admin certifies that the vault side is clean, a one-shot attestation the next registration consumes. Everything else about them, the batch, the reinvestment guards, the share oracle, is in their own posts, coming this week; until then, the docs: Reinvestment Vault and Redemption Vault.


The pools stopped being special

A liquidity pool is a holder of Bond Tokens that cannot complete KYC. In v2 that meant liquidity positions had to be withdrawn from the pool before every coupon snapshot and redeployed after, so that no coupon would be stranded on the pool address. In v3 nobody withdraws. At the snapshot block the backend reconstructs every position in the pool, principal at the snapshot tick plus fees already booked plus fees earned since the last poke, attributes each to its owner, and gives each owner one leaf that combines their direct holdings and their pool positions. Anything the reconstruction cannot attribute must be zero or the run fails, never silently rounded. Liquidity providers are paid what their share of the pool earned, and liquidity never leaves the pool.


The backend grew with it

One backend deployment now serves both generations. Each bond is tagged with the contract generation it runs on, and the orchestrator, relayer and watcher pick the matching interfaces and events per bond, so the live v2 bonds and the v3 bonds run side by side in one service without a migration.

The relayer runs every payout path described above: Bond Token delivery after a funding, incentive claims, coupons, the call wave with its snapshot and balance checks, principal after the cutoff, and Redemption Vault payouts to each owner once the Safe fulfills a batch. One thing did not change and will not: no coupon is finalized without a person verifying the snapshot first. 🔍


The primitive, complete

Put it together and a Bond Token now does what a bond does. It pays its coupons on the calendar and pays them to whoever holds the coupon. It gets called in part or in full, amortizes, and returns principal at maturity, each at the contractual price, each to every holder exactly. Its supply grows when demand does, at the bond's real price on the day. And through all of it, the money moves from the custody partner to the contract to the holder, with no one in between.

That is what a bond issued natively onchain will look like, and it is why v3 is built this way. Until issuers come onchain, the bonds behind a BT are bought in the traditional market and held under custody, and v3 carries their full life onchain for them. When issuers do come, the primitive is already here. 🐢

All posts