Before you trust it
FAQ
Grouped by what you are actually worried about. If an answer here disagrees with something a person told you, believe the contract.
Trust and safety
›Can you take my tokens?
No. There is no admin withdraw in the contract, and no upgrade path to add one. The owner can set the creation fee, under a cap written into the code, the treasury address, and the card renderer. That is the entire surface. See Security and limits.
›What if your owner key gets stolen?
An attacker could set the fee to the cap, point the treasury at themselves, and break the artwork. They could not touch a single escrowed token, cancel a stream, or pause anything. Your streams would keep paying out on schedule.
›Is it audited?
No. It has unit tests, fuzz invariants, and fork tests against real tokens on Robinhood Chain. That is evidence, not a substitute for an audit. It holds real funds, so treat it accordingly and read the code before committing size.
›What happens if this site goes down?
Nothing to your stream. The schedule and the funds are in the contract. Both dashboards here are rebuilt from plain
eth_call, so anyone can read, withdraw, cancel or transfer with a block explorer and no frontend at all.›Can a stream expire, or can I lose it by not claiming?
No. There is no deadline anywhere in the contract. Withdraw every day for four years or once at the end, it makes no difference to what you receive. Nothing expires, and no withdrawal is needed to keep a stream alive.
Cancelling
›If I cancel, do I get everything back?
No, and that is deliberate. The vested part stays owed to the recipient and they can still withdraw it afterwards. Only the unvested remainder returns to you. Cancelling is a stop, not a clawback. See Cancel and renounce.
›Can I cancel after I promised not to?
Only if you kept the right. Create the stream irrevocable, or call
renounceCancel later, and cancelling reverts forever. There is no undo and no admin override. That is the entire point of it.›Can the recipient cancel?
No. Only the sender, the address that funded the stream, can cancel. A recipient who wants out sells the NFT instead.
›I cancelled a stream. Why does it still show tokens?
Because the vested part is still owed to the holder until they withdraw it. Cancelling stops accrual and refunds the unvested part, it does not empty the stream.
›Why did my second cancel revert with NotCancelable instead of AlreadyCanceled?
Because
cancel clears the cancelable flag on its way out, and that check runs first. AlreadyCanceled exists in the ABI but no call path currently reaches it. Worth knowing if you decode revert selectors.The NFT
›Why is a stream an NFT?
So the claim is transferable with no custom code.
ownerOf(id) is the only address that can withdraw, so an ordinary ERC-721 transfer is a transfer of the future income. It also means your vesting shows up in any wallet and composes as collateral anywhere. See Tradable streams.›If I sell the NFT, do I keep anything?
No. The buyer becomes the recipient the moment the transfer lands, and collects everything from then on, including tokens that vested before the sale and were never withdrawn. Withdraw first if you want the vested part.
›Is buying a stream safe?
Only if
cancelable == false. Otherwise the sender can cancel and take the unvested part back, including in the block right after your purchase. Also check withdrawn: a seller can legitimately empty the vested part right before selling.›Where does the card image come from?
A renderer contract builds it on-chain, at read time, from the contract's own state. No server, no IPFS pin to lapse. The owner can swap the renderer, which changes how a stream looks and never what it pays.
›Does approving someone let them steal my stream?
It lets them withdraw its tokens to any address they choose, and transfer the NFT. That is standard ERC-721 behaviour, and
setApprovalForAll grants it over every stream you hold, now and later. Approve carefully.Schedules
›What exactly does a cliff do?
It gates the withdrawal, it does not pause the accrual. Value builds behind it the whole time, so on a 4 year stream with a 1 year cliff, the day the cliff lands, 25% unlocks at once. It does not restart the clock.
›Can start be in the past?
Yes. The stream is then already partly vested at creation, and if
start is far enough back, immediately withdrawable. Useful for backdating an agreement to the day it was actually made.›How do I create a stream with no cliff?
Pass
cliff == start. There is no separate flag, because a gate that opens at the start gates nothing. In the app, set the cliff to 0 days.›Can I change a schedule, or add tokens to a stream?
No. A stream is immutable once created. To change terms, cancel if you can and create a new one. To add tokens, create a second stream. This is why verifying before
renounceCancel matters.›Does withdrawing early slow the stream down?
No. A withdrawal only increments
withdrawn. It never touches the schedule, the end date, or the rate. Withdrawing is purely about when you want the tokens in hand.Money
›What does it cost?
A flat fee in ETH at creation, plus gas. Withdrawing, cancelling and transferring are free beyond gas, and the protocol never takes a cut of the streamed tokens. Read the current fee from
creationFee() rather than hardcoding it. See Fees.›Can you raise the fee on my existing stream?
No. The fee is read once at creation and never stored on the stream. Nothing in the withdrawal path consults it, so a fee change cannot reach a stream that already exists. And the fee can never exceed 0.01 ETH, which is a compile-time constant, not a setting.
›What if I overpay the fee?
The excess is refunded in the same transaction. Underpaying reverts with
InsufficientFee, so you never create a stream at the wrong price.Tokens and addresses
›Which tokens work?
Any ERC-20 on Robinhood Chain. The dropdown is a shortcut for tokens that actually trade there, not a permission list. Paste any address to stream it.
›What about a token that taxes transfers?
Handled. The deposit is measured by the balance actually received, so the stream is created for the net amount and only ever promises what the contract really holds.
›What about rebasing tokens?
Not recommended.
deposited is fixed at creation, so if balances change underneath the contract, the accounting will not follow. Streaming a rebasing token is a good way to be unpleasantly surprised.›Does it work with a multisig or a treasury?
Yes, as long as the contract implements
onERC721Received. If it does not, creation reverts on purpose: such an address could never withdraw or transfer, and the tokens would be stranded forever. The form checks this before you sign.›Can I stream to myself?
Yes, and it is the whole team vesting pattern. Stream your own allocation to yourself, renounce the right to cancel, and you have proven on-chain that you cannot pull it early.
Using it
›Why did withdrawMax revert?
Almost always because nothing is withdrawable yet, and withdrawing zero is rejected with
ZeroAmount. That happens during a cliff, or straight after another withdrawal. Check withdrawableOf(id) first.›Do I need this website to use QUIVER?
No, and that is deliberate. Every action is a direct contract call. See Integration for working
cast, viem and Solidity examples.›Can I withdraw to a different address than the one holding the NFT?
Yes. The holder picks the destination on every withdrawal. The tokens do not have to land on the address holding the stream.
›How do I find my streams?
streamsOfHolder(you) for what you collect, and streamsBySender(you) for what you funded. Both are plain views. The streams page is built from exactly those two calls.›The numbers on this site tick every second. Is that real?
The mathsis real, the ticking is a local mirror of the contract's formula so a counter can animate between reads. The chain is the source of truth at the moment of withdrawal, and the displayed value can be a few seconds off, because the contract reads
block.timestamp rather than your clock.Still stuck?
The contract reference lists every function, who can call it, and exactly when it reverts, including every custom error and what triggers it. If you are decoding a failure, start there.