Documentation

How Shipped works

A delivery bond is money a creator locks behind a dated, public promise. This page explains how a bond runs from posting to settlement, what each term means, and how to check a payout yourself.

How it works

A creator posts a bond: a milestone, a deadline, an amount in one asset, and who judges delivery. Shipped’s bonds contract holds the money in escrow, and every term is fixed the moment the bond is posted.

  1. Post. The creator locks the first amount and names a verifier, an on-chain check, or both. Two bond tokens that can’t be transferred mark the two sides: one held by the creator, and one held by the payout vault for the project’s holders or by a named address.
  2. Deliver. The creator ships and posts evidence. Anyone can add to the bond while it’s open, directly or through a fee split.
  3. Rule. The verifier accepts at any time up to the end of their window. After the deadline they can also reject, rule a partial delivery if the bond allows it, or rule the milestone void. An on-chain check proves delivery on its own once it has held for an hour.
  4. Appeal. If the bond names an appeal panel, anyone can contest a ruling within the appeal window by posting the appeal deposit. The panel upholds or overturns it.
  5. Settle. The bond pays out by the ruling: the creator’s share is released to the creator and the rest is paid to holders or the named address. Both bond tokens are burned, and a record is minted to the creator’s wallet whatever the outcome.

If nobody rules in time, anyone can settle the bond at the split the creator fixed when it was posted. That split is shown on every bond as "If nobody rules".

Phases

PhaseIn the APIWhat is happeningWho can act
OpenopenBefore the deadline.Verifier can accept; anyone can add to the bond; creator can post evidence or concede.
DueduePast the deadline, inside the verifier’s window.Verifier rules: accept, reject, partial or void.
Backup reviewbackupThe verifier’s window closed without a ruling.Backup verifier rules.
UnansweredexpiredEvery window closed without a ruling.Anyone settles at the default split.
In reviewreviewRuled, appeal window open.Anyone but the panel can appeal with the appeal deposit.
AppealedappealedThe panel is hearing the appeal.Panel upholds or overturns.
Ready to finalizefinalizableThe appeal window, or the panel’s, has closed.Anyone finalizes; the ruling pays out.
SettledsettledPaid out and final.Holders claim their payouts, and anyone else owed money withdraws it.

The terms

Everything below is chosen when the bond is posted and can’t be changed afterward.

  • Title and milestone. A one-line title of up to 96 bytes, and up to 2,048 bytes on what will be delivered and how anyone can tell. Both are stored on chain.
  • Deadline. At least 10 minutes and at most three years out.
  • Bond. The money locked behind the promise, held in escrow in one of the assets Shipped accepts: WETH (ether in token form) or USDG (Global Dollar, a dollar stablecoin issued by Paxos). It can start at zero, and anyone can add more while the bond is open.
  • Project and payout address. The token or collection whose holders are paid on a miss. Any bond can name one address to receive that payout instead of holders, and a bond with no project must.
  • Verifier and window. Who rules, and for how long after the deadline: between 1 hour and 60 days. The verifier can be the AI council, a person or team, or nobody, in which case an on-chain check decides on its own.
  • Backup verifier. Optional. Rules only once the verifier’s window has closed, within its own window.
  • Appeal panel. Optional. With a panel come an appeal window, the panel’s window and an appeal deposit. Without one, rulings settle at once.
  • Partial rulings. Whether the verifier may release part of the bond for part of the milestone.
  • If nobody rules. The creator’s share when nobody rules in time, or when the milestone is ruled void: 0% pays everything to holders or the named address, 100% releases everything to the creator, or any split between.
  • Verifier fee. Paid from the bond for a verifier’s ruling that stands, up to 10% of the bond.
  • Payout cap and exclusions. For holders’ payouts: the most any one holder can receive, and up to 32 addresses that never count as holders.
  • On-chain check. A contract that proves delivery from chain state, such as a supply count reaching a number or a launch flag switching on.

The AI council

On networks that have an AI council, it judges bonds by default. The council is three AI judges, each running on a model from a different company: OpenAI, Anthropic and xAI. A bond can name the council as its verifier, its backup verifier or its appeal panel, just as it would name a person.

  • What it judges. Whether the milestone, as written, was delivered by the deadline: in full, in part where the bond allows it, or not at all. A milestone that can’t be judged as written can be ruled void, which settles the bond at its split for when nobody rules. Each judge reads the bond’s terms, the evidence the creator posted and, when the bond has one, the result of its on-chain check. It judges only on public evidence that anyone could check. Each judge is told to report any text in the evidence that tries to tell it what to decide, and to judge as if that text weren’t there.
  • Two of three. Each judge decides on its own and votes on chain. The council rules only when two of them vote the same way, and the second matching vote records the ruling on chain in the same transaction. Before the deadline, a judge votes only to accept, and only when the evidence clearly shows delivery. As an appeal panel, the council upholds or overturns the ruling under appeal.
  • Every opinion is published. Before a judge votes, it publishes its opinion: its verdict, how confident it is, its reasons, the evidence it relied on, and the model it ran on. The API serves each one at /v1/council/opinions/:hash, and every bond the council judges shows them in its council panel.
  • Checking an opinion. Each vote records a fingerprint: the keccak256 hash of its opinion’s exact bytes. Download the opinion, hash the file exactly as it is, and compare the result with the fingerprint in the vote. If anyone changed a single byte, the two won’t match.
  • Who runs it. Shipped runs the three judges. Their seats, each labeled with the company whose model it runs on, are fixed on chain when the council is set up, and nobody, Shipped included, can add, remove or replace one. The model behind a seat can move to a newer one from the same company, and every opinion names the exact model that wrote it. A new set of seats is a new council, which only bonds posted afterward can name.

If two judges never agree in time, the bond goes on as if nobody ruled: a backup verifier rules if the bond names one, and otherwise the bond settles at the split it set for when nobody rules.

Outcomes

Every settled bond leaves a record in the creator’s wallet with one of these stamps. Only a ruling or a check that paid the creator in full counts as shipped.

StampHow it happenedCreator’s share
ShippedAccepted by the verifier, the backup verifier or the panel, or proven by the bond’s on-chain check.100%
PartialA partial ruling.As ruled
Not shippedRejected.0%
ConcededThe creator gave up on the milestone.0%
VoidThe milestone was ruled void.The default split
UnruledNobody ruled; the default split paid the creator.The default split
ExpiredNobody ruled in time, so the bond was paid to holders (or to its payout address).0%

Fees

The protocol fee is taken only from what’s released to the creator, never from a payout, at the rate in force when the bond was posted. The verifier’s fee, when a bond sets one, comes out of the bond before the split, only for a verifier’s ruling that stands, and never more than 10% of the bond.

Fee splits

Many launchpads pay a token’s creator a share of its trading fees. A fee split sends a portion of that fee, chosen by the creator, into a bond until the bond is decided or its deadline passes, whichever comes first. For each bond, the creator makes one split and chooses its share, then sets the launchpad’s fee recipient to the split’s address.

Fees build up in the split until it pays out its balance, and each payout sends the bond’s share into the bond. Anyone can trigger a payout. Shipped also triggers one for every split at regular intervals while its bond is open, and once more shortly before the deadline. Each payout made while the bond is open and before its deadline sends the chosen share of every fee paid in the bond’s asset into the bond, and the rest to the creator. For a bond held in WETH, fees paid in ETH count too, and the split wraps them first. Fees in any other token go entirely to the creator, as does everything the split pays out after the deadline or once the bond is decided.

On Ripples, only the wallet that currently receives a launch’s creator fee can redirect it, and the bond page sets up the redirect to the bond’s split for you. After that, the split is the fee recipient, and it can’t redirect the fee while the bond is open, so the fee stays with the split until the bond is decided.

Payouts

When a bond that pays holders settles, the holders’ share of the bond moves to the payout vault. Each holder’s share is calculated by fixed rules from the project’s public transfer history, published with a manifest of every share and every input behind it, and claimable after a two-day review. Claims never expire.

  1. Holdings. Balances of the project from its transfer logs: token amounts, or one per piece for a collection.
  2. Exclusions. These addresses are left out when shares are calculated: the zero and dead addresses, the Shipped contracts, the bond’s fee split, its creator, verifiers and panel, any addresses the bond itself excludes, and addresses excluded across the network, such as the Uniswap v4 pool manager, which holds the tokens of every trading pool.
  3. Weight. Balance multiplied by seconds held between the bond’s posting and its deadline, or the ruling if that came first. A last-minute buy earns almost nothing.
  4. Cap. A bond can cap the share any one holder receives. Anything above the cap is shared pro rata among the other holders, and this repeats until no holder is over the cap.
  5. Amounts. Each holder receives the funded amount times their weight over the total weight, rounded down.

Verify a payout list

Every payout list is published as a manifest that records each holder’s share and every input behind it. The vault stores a fingerprint of that file and a single value that every claim is checked against. If anyone changed the list after publishing it, the check below would fail.

In technical terms, the manifest is canonical JSON (sorted keys, no whitespace), the vault stores its keccak256 hash, and the claims form a Merkle tree under the vault’s root. Because the manifest records every input, anyone can recompute the payout list from chain data, as described below. The tool below runs the quicker check: it reads the payout pool from the vault, downloads the manifest, and checks its hash, every claim proof and the totals.

The same checks, in a few lines of viem:

import {
  concat, createPublicClient, encodeAbiParameters, getContract, http, keccak256, parseAbi, toBytes,
} from "viem";

const API = "https://api.shipped.world";
const deedId = 1n; // the bond whose payout list you are checking
const vault = getContract({
  address: "0x4c4a3A1e86897aC79A5f93B687adD2E65485a782",
  abi: parseAbi([
    "function getPool(uint256) view returns ((address asset, uint64 windowStart, uint64 windowEnd, " +
      "uint64 proposedAt, address publisher, uint64 fundedAt, uint256 funded, uint256 total, " +
      "uint256 claimed, bytes32 root, bytes32 manifestHash))",
  ]),
  client: createPublicClient({ transport: http("https://rpc.mainnet.chain.robinhood.com") }),
});

const LEAF_TYPEHASH = keccak256(toBytes("ShippedRefund(uint256 chainId," +
  "address vault,uint256 deedId,address account,uint256 amount)"));

// 1. The manifest's exact bytes hash to what the vault holds.
const url = `${API}/v1/refunds/${deedId}/manifest`;
const bytes = new Uint8Array(await (await fetch(url)).arrayBuffer());
const manifest = JSON.parse(new TextDecoder().decode(bytes));
const pool = await vault.read.getPool([deedId]);
keccak256(bytes) === pool.manifestHash;

// 2. Every claim's proof reaches the vault's root.
const types = ["bytes32", "uint256", "address", "uint256", "address", "uint256"]
  .map((type) => ({ type }));
const leaf = (account, amount) => keccak256(keccak256(encodeAbiParameters(types, [
  LEAF_TYPEHASH, BigInt(manifest.chainId), manifest.vault,
  BigInt(manifest.deedId), account, BigInt(amount),
])));
const pair = (a, b) =>
  keccak256(BigInt(a) < BigInt(b) ? concat([a, b]) : concat([b, a]));
manifest.claims.every(({ account, amount, proof }) =>
  proof.reduce(pair, leaf(account, amount)) === pool.root);

// 3. The amounts add up to the total the vault holds, which never exceeds what it was funded with.
const sum = manifest.claims.reduce((total, { amount }) => total + BigInt(amount), 0n);
sum === pool.total && pool.total <= pool.funded;

To recompute the payout list itself, replay the project’s Transfer logs from its first block through the last block before the deadline (or the ruling, if that came first), drop the excluded addresses, weight each balance by the seconds it was held, apply the cap, and compare your amounts with the manifest’s. The manifest records every input: the block range and its hash, the window, the exclusions and the cap.

Verified creators

Anyone can post a bond that names any project. A bond marks its creator as verified when the project itself names that wallet as its own. Shipped reads this on chain at the block where the bond was posted:

  • Project owner. The project’s contract returns the creator from owner().
  • Collection creator. The contract returns the creator from creator() or CREATOR().
  • Launch creator. The token was launched on Ripples, whose launch records Shipped reads, and the launch records the wallet as its creator or as its fee recipient.

A bond whose creator isn’t verified says “Not verified as the project’s owner or creator”. A project’s record, on the board and on its page, counts only the bonds its verified creators posted. Bonds others posted naming the project are listed separately, under “Posted by others”, and never count toward it. A creator’s own record counts every bond that wallet posted.

What Shipped can and can’t do

The contracts can’t be upgraded. No one, Shipped included, can withdraw a bond’s money, change a bond’s terms, or rule on a bond they weren’t named on. A bond’s money leaves the contracts only by that bond’s own rules.

The bonds contract and the payout vault share a single owner, and no other Shipped contract has an owner. On Robinhood Chain, the owner is a multisig wallet with two signers, and both must approve every action. The owner can:

  • Choose which assets new bonds can hold. Removing one doesn’t affect bonds already open in it.
  • Set the protocol fee for bonds posted afterward, up to 5%. A bond keeps the rate it was posted at.
  • Change the address the protocol fee is paid to. Every bond that settles after the change, including bonds already open, pays its fee to the new address.
  • Pause the posting of new bonds. Bonds already open run to the end as usual.
  • Change how bonds and records are drawn. This swaps the image a wallet shows, not what the record says.
  • Reject a proposed payout list during its two-day review, so a corrected one can be published. Every rejection is recorded on chain with its reason, and the proposer publishes a new list a day later. Holders can claim only from a list that passes its review without being rejected.
  • Choose who proposes payout lists for bonds that settle after the change. A payout already in the vault keeps its proposer.
  • Hand a bond’s payout to a new proposer, but only when the payout has no list under review or open for claims and its current proposer has published nothing for it in the last two weeks.
  • Hand ownership to a new owner, who has to accept it.
  • Give up ownership of the bonds contract for good, which would freeze all of its settings as they stand.

The owner can’t name itself as the proposer of payout lists, and can’t reject a list once its review has ended. It also can’t give up ownership of the payout vault, which ensures someone can always reject a proposed list while it is under review. Once a list’s review ends, its claims are final and never expire.

If you think your share in a proposed list is wrong, email security@shipped.world while the list is under review, with the bond number and your wallet address. Before a list opens for claims, you can check it yourself with the payout list verifier.

Embeds

You can show the board or a record on your own site. These pages are made to be framed: they have no header or footer, only a small link back to Shipped, and every link in them opens Shipped in a new tab.

The board embed takes the same sort and by parameters as the board page: sort is shipped, missed, lost or posted, and by is creators or projects. It shows the top ten.

<iframe src="https://app.shipped.world/embed/board?sort=shipped" title="The Shipped board" width="100%" height="760" style="border:0"></iframe>

A record card takes a creator’s or a project’s address. This one shows the creator at the top of the board:

<iframe src="https://app.shipped.world/embed/p/0x204bB6B65C2DF23b1277b83988E91cE9f30493DB" title="On the record at Shipped" width="100%" height="520" style="border:0"></iframe>

Contracts

These contracts can’t be upgraded. The API and the contracts call a bond a deed, and a holders’ payout a refund.

Robinhood Chain

ContractAddress
Bonds contract
ShippedDeeds: holds every bond’s money in escrow, records rulings and pays out.
0xD5Da523ee49CB7Fe855B0C6fa38707190A9D531F
Records
ShippedRecords: the record minted to the creator at settlement, which can’t be transferred.
0x132E00ff4989A35F704fbE480331FcFeBf8e072C
Payout vault
RefundVault: holds holders’ payouts and pays each claim that matches the published payout list.
0x4c4a3A1e86897aC79A5f93B687adD2E65485a782
Fee split factory
DeedFeeSplitFactory: makes a bond’s fee split at a predictable address.
0xB42dea9810e4B57697eD6df1eE7e21C3642f9AF7
On-chain check
StaticCallCheck: reads a value from a contract and compares it with a threshold.
0x2e7C4F0F2e6079C3B5F7Cd2440308234CBDc537D
Label renderer
DeedRenderer: draws bonds and records as labels, on chain.
0x96ea539D97665E30DBE0997C16445C940F599117
Treasury
Receives the protocol fee.
0x9C13c067129881c2F7502C95C47D59C43c24D582
Payout proposer
The wallet that publishes each payout list. Anyone can check a list, and the owner can reject it, during its two-day review.
0x0ab603c8dB97E3D9fc5A66f85485ef6144037452
AI council
AgentCouncil: three AI judges that rule only when two agree.
0x71b3F054cfc653d1BA6433b8EF6a5627fA5692db
Owner
Holds the powers listed under What Shipped can and can’t do.
0x9C13c067129881c2F7502C95C47D59C43c24D582
WETH
Ether in token form · Bond asset · 18 decimals
0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73
USDG
Global Dollar, a dollar stablecoin issued by Paxos · Bond asset · 6 decimals
0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168

Data API

Every bond, event and payout is public. Payouts to holders are under /v1/refunds. The API lives at https://api.shipped.world and answers in JSON, with amounts as decimal strings and checksummed addresses. Phases use the values in the Phases table above. For example, this asks for five bonds that are past their deadline and still waiting for a ruling:

curl "https://api.shipped.world/v1/deeds?phase=due,backup,expired&limit=5"
EndpointReturns
GET /v1/configNetwork, contracts, bond assets, the standing appeal panel and the AI council.
GET /v1/statsCounts of bonds posted, still open, awaiting a verdict, settled and shipped, plus the amount bonded now.
GET /v1/boardCreators or projects ranked by bonds shipped, or by misses, amount forfeited or amount bonded when you pass sort, with each record and its totals.
GET /v1/verdictsThe latest settled bonds, newest first.
GET /v1/deedsBonds, filtered by phase, creator, project, verifier or search.
GET /v1/deeds/:idOne bond with its terms, timeline, events, split and payout.
GET /v1/deeds/:id/councilThe AI council’s votes on a bond, with each judge’s opinion and the ruling, if the bond names the council.
GET /v1/council/opinions/:hashThe exact bytes of a judge’s opinion, whose keccak256 hash its vote records on chain.
GET /v1/creators/:addressA creator’s bonds and record.
GET /v1/projects/:addressA project’s bonds, the record of those its verified creators posted, and the same tallies for bonds posted by others.
GET /v1/verifiers/:addressWhat a verifier has due, coming up and ruled.
GET /v1/accounts/:addressMoney owed, holders’ payouts, bonds posted and judged.
GET /v1/refunds/:idA bond’s payout pool: funded, allocated, claimed, and when claims open.
GET /v1/refunds/:id/:accountOne holder’s payout: the amount, its proof, and whether it was claimed.
GET /v1/refunds/:id/manifestThe exact manifest bytes behind a payout.
GET /healthThe chain’s latest block, the latest block indexed, and the lag between them.