Collect Barons rewards: Collect ETH (default) or Collect & Lock (optional)
Where this fits: Furnace loop in the CLAIM stream · Contract: ShareholderRoyalties
Goal:
- Show a user their accrued Barons ETH (royalties)
- Default (frontend): Collect ETH (mode 0); Collect & Lock remains optional when locking is enabled
- Optional: Collect & Lock (mode 1, compounding via Furnace when locking is enabled)
UI recommendation:
- Primary CTA: Collect ETH (mode 0). Show Collect & Lock as secondary when
Furnace.lockingPaused == false - Secondary CTA: Collect & Lock (mode 1)
- If you store preferences, “remember my choice” is fine, but hard-disable mode 1 when locking is paused
- UI copy should say Collect (not “Claim”)
Show accrued ETH without a tx (recommended)
checkpointUser(user) is state-changing and should not be required for read-only display.
Read (view calls):
ShareholderRoyalties.getShareholderState(user) -> (claimableEthLive, userVe, userEthPerVePaid)
Use locally:
accrued = claimableEthLive
Notes:
- The first returned field is the authoritative live claim preview.
- Do not recompute
claimable + userVe * (ethPerVe - paid) / ACCoffchain — that shortcut is wrong for decaying locks because it ignores historical flush timestamps. - This still excludes ETH that is sitting in
pendingShareholderETHand has not yet been flushed. - In normal gameplay,
pendingShareholderETHshould be near zero (takeover allocations index immediately when the ve checkpoint is current). It may briefly hold carry while the ve checkpoint catches up, or rounding dust. - Example implementation (official app):
frontend/src/lib/shareholderPendingEth.ts(if present).
Tip: checkpointUser(user) is called internally by the claim transaction. You never need to send a separate checkpoint tx before collecting — just call claimShareholder directly.
Activation gate: MIN_VE_FLUSH
Canonical takeover allocations are auto-attempted immediately whenever a processed shareholder denominator
exists, even below MIN_VE_FLUSH, but they index only once the ve checkpoint is current in that
block, so later entrants still cannot dilute older takeover ETH once the checkpoint catches up.
MIN_VE_FLUSH still matters for leftover pendingShareholderETH that could not be indexed
immediately, for example:
- zero-shareholder carry
- floor-rounded dust that leaves
delta == 0
Practical UI copy:
- “Takeover royalties accrue immediately to current Barons whenever the ve checkpoint is current.”
- “The pending bucket can also hold brief carry while the ve checkpoint catches up, in addition to zero-shareholder carry or rounding dust.”
Flow
Slippage pattern for mode 1 (Collect & Lock)
- Use the same
minVeOutpolicy as direct Furnace entries:- quote with
FurnaceQuoter.quoteEnterWithEth(user, ethIn, targetTokenId, durationSeconds, createAutoMax)(resolve address viaFurnace.furnaceQuoter()) - compute
minVeOutfrom your slippage policy (or UI setting) - if
veOutQuote > 0but floor-rounding would produceminVeOut == 0, clamp to1
- quote with
- Reminder (swap safety model):
- on swap paths, the router uses
amountOutMin = 0 - slippage enforcement is atomic via the downstream
minVeOutcheck
- on swap paths, the router uses
What success looks like
- Accrued ETH matches the official app display (
getShareholderState(user).claimableEthLive). - Primary CTA is Collect ETH; show Collect & Lock as secondary when locking is enabled.
- Collect ETH stays available as a liquid payout (and as the pause fallback).
See also
- Contract semantics + activation gate: ShareholderRoyalties (Barons)
- Slippage/minVeOut: Integrate Furnace quotes + enter
- Bundling (optional): ClaimAllHelper