QUIVER

Use cases

Tradable streams

Every stream is minted as an ERC-721. That is not decoration on top of a vesting contract, it is the vesting contract's data model, and it is what makes a stream something you can sell.

The token is the claim

Most vesting contracts store a recipient address in a struct. Yours is a row in their database, and if you ever need to move it, you need a function they thought to write, and usually somebody's permission to call it.

QUIVER stores no recipient field. The claim is the NFT. ownerOf(id) is the only address that can withdraw, so an ERC-721 transfer, which every wallet, marketplace and contract on earth already knows how to do, is also a transfer of the future income. No custom logic, no migration function, no permission from the funder.

What that buys, for free

  • It is visible. Your vesting shows up in any wallet that renders NFTs, next to everything else you own, without us shipping an app for it.
  • It is sellable. Any ERC-721 marketplace can list it. An employee who needs cash today can sell four years of patience to somebody who has it.
  • It composes. Any protocol that accepts ERC-721 as collateral accepts a stream, because the claim can be transferred without the funder cooperating.
  • It is portable. Approvals, operators and safe transfers all work exactly as you expect, because they are the standard ones.

None of this required a feature. It fell out of the data model, which is the whole argument for the design.

The card is drawn on-chain

tokenURI(id)returns a data URI, built at read time from the contract's own state by a separate renderer contract. There is no server to keep up and no IPFS pin to lapse. When a wallet loads the card, it shows the real progress at that moment.

The renderer is swappable by the protocol owner, and that is worth being precise about: it can change how a stream looks, and it can never change what a stream pays. A renderer that reverts cannot block a transfer or a withdrawal either. Art and money are separate contracts on purpose.

Selling a stream

A stream is an ordinary ERC-721, so you sell it the way you sell any NFT: list it, or transfer it directly against payment. The contract to point a marketplace at is QUIVER itself, and the token id is the stream id.

bash · transfer a stream
RPC=https://rpc.mainnet.chain.robinhood.com
QUIVER=0x2866D49f364a70383591a958354A89F6BDf050f2

# who holds the claim right now
cast call $QUIVER "ownerOf(uint256)(address)" $ID --rpc-url $RPC

# hand it over: the buyer becomes the recipient in this block
cast send $QUIVER "safeTransferFrom(address,address,uint256)" \
  $SELLER $BUYER $ID --rpc-url $RPC --private-key $KEY

Use safeTransferFrom rather than transferFrom when the destination might be a contract. It checks the receiver can hold NFTs, and a stream sent to a contract that cannot handle ERC-721 could never be withdrawn or moved again.

Buying a stream: read these first

Everything you need to price a stream is on-chain, and you should read it yourself rather than trust a listing. Three things decide what it is worth.

cancelable
If true, the sender can cancel and take back the unvested part. You would be buying a claim the funder can shrink at will.
deposited minus withdrawn
What is actually left to collect. A seller can withdraw everything vested right before selling, which is entirely legitimate and changes the value completely.
the schedule
start, cliff and end tell you when the remainder actually arrives. A stream ending in four years is not worth what one ending next month is.

The one real trap

Buying a cancelable stream means buying something the sender can gut. They can cancel in the same block as your purchase, taking back the entire unvested remainder and leaving you with the vested crumbs. Nothing in the contract prevents this, and no amount of care on the marketplace side fixes it. If you are buying, insist on cancelable == false, and check it yourself on-chain rather than taking a screenshot for it.

The check, in one call

bash · price it honestly
# sender, start, cliff, cancelable, canceled, token, end, deposited, withdrawn
cast call $QUIVER \
  "getStream(uint256)((address,uint40,uint40,bool,bool,address,uint40,uint128,uint128))" \
  $ID --rpc-url $RPC

# what the current holder could take out before selling to you
cast call $QUIVER "withdrawableOf(uint256)(uint128)" $ID --rpc-url $RPC

If cancelableis true, treat the price as an option on the sender's goodwill, not as the value of the remaining schedule.

Approvals work, and cut both ways

approve and setApprovalForAllbehave exactly as the standard says, which means an approved operator can withdraw a stream's tokens to any address they choose, not just transfer the NFT. Approving an operator on QUIVER is approving them to take the money, not only to move the token.

Transferring a stream clears the single-token approval, as ERC-721 requires, so a buyer does not inherit the seller's stale approvals on that token.

Where the ids live

streamsOfHolder(address)lists what an address currently collects, and it reflects transfers: selling a stream removes it from the seller's list and adds it to the buyer's. streamsBySender(address) lists what an address funded, and it is append-only, so it stays a complete history. Both are covered on Integration.