Docs · Bobber on Robinhood Chain

How the line works.

Everything Bobber does is one contract, the Reservoir, reading Chainlink on Robinhood Chain. This page explains every rule it enforces, in plain words, with the live parameters read from the chain.

01 What Bobber is

A coupon for patience.

Bobber is a barrier coupon line on tokenized stocks. You cast a stock token (SPY, AAPL, NVDA, TSLA, AMZN, GOOGL, META, MSFT, GLD, GME) or USDG as bait into the Reservoir, a single smart contract on Robinhood Chain. The line then waits for four NYSE closing bells. At every bell where the price is still at or above 95% of where you cast, the line earns a small coupon in USDG.

Your bait is never swapped, lent or pledged. It sits in the Reservoir and comes back whole, at any stage, with no fee. Coupons come only from USDG already in the Reservoir, and a line opens only if its worst case is set aside first.

Bobber is not a yield promise. A stage that misses pays nothing. Your stock token keeps moving with the market the whole time, exactly as it would in your wallet.

02 A season

Four bells, four stages.

1 · Ripplefirst bell after the cast
2 · Nibblesecond bell
3 · Bitethird bell
4 · Hookedseason over

A season is four closing bells: the NYSE close, rung on chain by the observer. When you cast, the Reservoir reads the live Chainlink price of your bait: that is the cast price. The barrier is 95% of it (barrierBps, fixed for your line at the moment you cast).

At every bell the Reservoir reads the same feed again:

  • Holds: price ≥ barrier. The stage pays the coupon, 0.25% of your bait value in USDG (couponBps), or +50% more if you chummed before that bell.
  • Misses: price < barrier. The stage pays nothing and takes nothing. Your bait is untouched.

A bell counts for your line only once the line has soaked for at least 16 hours (minSoak, fixed for your line at the cast), and only if the Chainlink round it read was published after your cast. With the default 16 hours that means overnight: cast before about midnight ET and that day's 16:00 close counts; cast later and your season starts at the following close. A skipped bell is not a miss, it simply is not one of your four.

USDG bait grows against SPY. USDG is valued at face, so its barrier is set on SPY: a USDG line's stage holds while SPY stays at or above 95% of SPY's price at your cast.

Example · USDG

Bait
1,000 USDG
Per held bell
2.50 USDG
Chummed bell
3.75 USDG
Max per season
15.00 USDG

Four held, chummed bells: 4 × 3.75. Four held bells without chum: 10.00.

Example · AAPL

Bait
3 AAPL at $341.45
Bait value
1,024.36 USDG
Barrier (95%)
$324.38
Per held bell
2.56 USDG

The contract uses the full 8-decimal Chainlink price ($341.4532), so the bait value is 1,024.36, not 1,024.35.

03 Chum

Chum the water.

chum(lineId) marks the next bell of your line. If that bell holds, it pays the coupon plus 50% (chumBonusBps, fixed for your line at the cast). If it misses, it pays nothing, like any miss.

Chumming costs only gas. It covers one bell at a time: after that bell rings you can chum the following one. You cannot chum twice for the same bell, and not after the fourth stage. The Reservoir has already reserved the chummed amount for every stage, so a chum never fails for lack of USDG.

04 Reel in & Recast

After the fourth bell.

Once four stages are counted the season is over and you choose:

  • Reel in (reelIn): your bait comes back whole, and everything the line caught is paid in USDG. Works even while casting is paused.
  • Recast (recast): a new season starts at today's live price and today's terms. USDG bait compounds: the catch joins the bait instead of being sent. Stock bait pays its catch out in USDG first, then the same tokens go back in at the new price, with a new barrier.

A recast needs the Reservoir to cover the new line's worst case, just like a fresh cast, and the species must still be listed. When the Reservoir is nearly empty a recast can be refused; reel in instead: that always works.

05 Cut line

Leave any time.

cutLine(lineId) ends a line at any stage. Your bait comes back whole, whatever you caught so far is paid in USDG, and there is no fee. The stages left in the season are simply not observed.

Cut line works even while the Reservoir is paused. Nobody, not the owner and not the observer, can stop you from taking your bait back.

If a payment bounces. If a token's issuer has paused transfers or frozen your address at that moment, the Reservoir does not revert: it records the amount as owed to you (owed(token, you), event Owed) and you collect it later with claim(token). The app shows an "Owed to you" card when this happens.

06 The Reservoir

Only what is already there.

The Reservoir holds three kinds of tokens, and keeps them apart:

Bait

Every token anglers cast, tracked per token in baitLocked. It only ever leaves to the angler who cast it.

Reserved USDG

The worst case of every open line: four chummed coupons (1.5% of bait value by default), set aside at the cast in reservedUsdg.

Free USDG

Everything else: freeBalance(USDG), which also excludes payments owed to anglers (owedTotal). New lines, prizes and owner withdrawals can only use this.

The reserve rule. A line opens only if free USDG covers its worst case, which is then reserved until the line closes. So a coupon that is earned is always there to pay. If free USDG is short, the cast is refused (ReservoirCannotPay) instead of opening a line that might not be paid. Right now the Reservoir can take bait worth up to free USDG ÷ 1.5% at default terms.

Who can take what. The owner can withdraw and prize only from the free balance: never bait, never reserved coupons, never owed payments. Prizes carry a public reason on chain in the Prized event. stock(token, amount) is permissionless: anyone can add USDG to the Reservoir; stocked tokens are not bait and leave only as coupons, prizes or a free-balance withdrawal.

07 Prices & bells

Chainlink decides what.

Every price Bobber uses comes from the Chainlink feed of that token on Robinhood Chain, normalised to 8 decimals. The cast price is the live Chainlink price at the moment of your cast, not yesterday's close.

  • The observer decides only when, never what. It calls ringBell() once per NYSE close; the contract then reads every feed itself. The observer cannot pass in a price.
  • Bells are spaced at least 16 hours apart (minBellGap), so two bells cannot be rung for one close.
  • Stale or paused feeds are skipped. If a feed has not updated for more than 4 days (maxStale), or the token's issuer has paused its oracle for a corporate action such as a split (oraclePaused()), that bell records no price for it and is skipped for its lines: not a miss, not a stage. The line waits for the next bell.
  • Soaking. A bell counts for a line only if it rang at least 16 hours after the cast (minSoak, snapshotted per line as soak). Earlier bells are skipped for that line the same way.
  • Fresh rounds only. Each bell stores the price and the time Chainlink published it (bellObs). A bell counts for a line only if that round was published after the cast, so a line is never judged on the very price it was cast at.
  • Anyone can settle. settle(lineId) processes rung bells for any open line, up to 64 per call (MAX_SCAN); call it again for more. It is optional: chum, reel in, recast and cut line settle first on their own.
Chainlink feeds used by Bobber · live prices
SpeciesTokenChainlink feedPrice nowUpdated
Reading feeds…

08 Contract

One contract, read it.

Reservoirnot deployed yet

Live parameters

Reading…

ParameterValueMeaning

Functions

Anglers

cast(bait, amount)
Open a line. Needs an approve first. Paused → refused.
chum(lineId)
+50% on the next bell if it holds. Paused → refused.
reelIn(lineId)
After four stages: bait back, catch paid. Works while paused.
recast(lineId)
After four stages: a new season. Paused → refused.
cutLine(lineId)
Any stage: bait back, catch so far paid, no fee. Works while paused.
claim(token)
Collect a payment that bounced earlier and was kept as owed.

Anyone

settle(lineId)
Process rung bells for an open line.
stock(token, amount)
Add tokens to the Reservoir.
quote · preview · livePrice
Views: what a cast would look like, a line as if settled, a live price.
freeBalance · lines · bells · bellObs · owed
Views over everything the Reservoir holds, owes and has observed.

Observer

ringBell()
Snapshot every feed at a close. Spaced by minBellGap.

Owner

listSpecies(token, feed, index, stable)
Stock a species. Its feed and index are fixed forever; re-listing a delisted species must repeat them exactly. Only USDG can be valued at face.
delistSpecies(token)
Stop new casts of a species. Open lines keep fishing and keep being observed.
setParams(…, soak)
Terms for new lines, within hard bounds: barrier 50–100%, coupon ≤ 5%, chum ≤ +100%, bell gap ≥ 12 hours, stale 1 hour–7 days, soak 1 hour–3 days. Open lines keep the barrier, coupon, chum and soak they were cast with.
withdraw(token, to, amount)
Free balance only.
prize(to, token, amount, reason)
Weigh-in prizes from free balance, with a public reason.
setPaused · setOwner · setObserver
Pause blocks cast, chum and recast only.

Events

  • Cast a line opened
  • Chummed next bell chummed
  • Observed a stage held or missed
  • Skipped a bell did not count
  • Reeled reeled in or recast, with the catch
  • LineCut line cut
  • BellRung a close observed
  • Stocked tokens added
  • Withdrawn owner took free balance
  • Prized prize with reason
  • SpeciesListed
  • ParamsSet
  • Owed a payment bounced, kept for claim
  • Claimed owed payment collected
  • SpeciesDelisted
  • PausedSet
  • OwnerSet
  • ObserverSet

Errors, in plain words

ErrorWhat it means

09 Risks

Read this first.

  1. Your bait moves with the market. A tokenized stock can fall far below the barrier. Bobber returns the same number of tokens you cast, not their value at cast time.
  2. The issuer can act on the token. If an issuer burns or seizes stock tokens held by the Reservoir, so it holds less than is locked for anglers, each angler of that stock gets back a pro-rata share instead of the whole bait. If transfers are paused or your address is frozen, payments wait as owed until you claim them.
  3. Coupons exist only while the Reservoir is stocked. There is no promised rate. When free USDG runs low, new lines are refused; open lines keep their reserved coupons.
  4. Casting can be paused (by the owner key), but nothing can block cut line or reel in. If the observer stops ringing bells, your line simply waits; you can always cut it and take the bait back.
  5. Owner powers are bounded but real. The owner sets terms for new lines within hard limits, lists and delists species, and can lower the bell spacing to 12 hours. A species' feed can never be changed. Open lines keep the barrier, coupon, chum and soak they were cast with.
  6. Oracles can fail. A stale or paused Chainlink feed skips bells; a wrong feed price would be read as is.
  7. Unaudited smart contract. Bugs are possible. Only cast what you can afford to have stuck or lost.
  8. Non-US persons only. Tokenized stocks on Robinhood Chain are not offered to US persons. Check the rules where you live.
  9. Not investment advice. Bobber is software. It is not a bank, broker or adviser.

10 Glossary

Words on the dock.

Angler
Anyone with a line in the water.
Bait
The stock token or USDG you cast. Returned whole.
Bait value
Bait × cast price, in USDG. Coupons are a share of it.
Barrier
95% of the cast price. At or above it, a stage holds.
Bell
An NYSE close observed on chain.
Cast
Opening a line.
Catch
USDG a line has earned so far (accrued).
Chum
+50% on the next bell if it holds.
Coupon
0.25% of bait value, paid for each stage that holds.
Cut line
Leaving early, no fee.
Observer
The key that rings bells. Chooses when, never what.
Recast
Starting a new season with the same bait.
Reel in
Ending a full season: bait back, catch paid.
Reservoir
The contract holding bait and USDG.
Season
Four counted bells: Ripple, Nibble, Bite, Hooked.
Owed
A payment that could not be delivered, kept for you until you claim it.
Soak
How long a line must be in the water before a bell can count for it: 16 hours by default, so overnight.
Weigh-in
The leaderboard, computed from on-chain lines.