Skip to Content
ClaimAllHelper

ClaimAllHelper (bundle + delegated Collect)

ClaimAllHelper is a stateless orchestration helper that bundles common Collect actions (Barons ETH + King ETH fallback) into a single transaction and provides delegation-gated wrappers for bots. It does not change economics or custody funds. In the CLAIM stream, this is the convenience layer for harvesting all earned ETH in one call.

It exists to:

  • bundle common Collect actions into a single transaction
  • provide delegation-gated wrappers for bots (via DelegationHub)

It does not:

  • change economics
  • custody funds
  • introduce new reward logic

Source of truth: src/ClaimAllHelper.sol.

Wiring

ClaimAllHelper is deployed as its own contract.

It is constructed with immutable pointers to:

  • ShareholderRoyalties (Barons ETH)
  • MineCore (King ETH fallback bucket)

Deployment hardening + runtime safety:

  • both constructor addresses must be nonzero contract addresses
  • every public path first verifies the canonical back-links it depends on:
    • MineCore.claimAllHelper() == address(this)
    • MineCore.royalties() == royalties
    • ShareholderRoyalties.claimAllHelper() == address(this)
    • ShareholderRoyalties.mineCore() == mineCore
  • if you need to change helper wiring, redeploy the helper and update both core contracts via the timelocked owner

Addresses come from deployments/<network>.json.

Why a helper exists

Two protocol contracts expose helper-only entrypoints:

  • ShareholderRoyalties.claimShareholderFor(user, ...) is onlyClaimAllHelper
  • MineCore.withdrawKingBalanceFor(user) is onlyClaimAllHelper

These entrypoints let an EOA (or bot) call ClaimAllHelper, while the helper calls into those contracts in a way that preserves protocol invariants.

Public surface

Bundle for the caller

claimAll(mode, targetTokenId, durationSeconds, createAutoMax, minVeOut)

What it does:

  1. Claims Barons ETH for the caller via ShareholderRoyalties.claimShareholderFor(msg.sender, ...)
  2. Withdraws the caller’s King ETH fallback bucket via MineCore.withdrawKingBalanceFor(msg.sender)

Mode values match ShareholderRoyalties:

  • mode = 0 ETH (Collect ETH)
  • mode = 1 LOCK_FURNACE (Collect & Lock)

Important behavior:

  • The helper is nonpayable.
  • If Barons claim reverts (example: locking paused in mode=1), the whole bundle reverts and the King bucket is not withdrawn.
  • The King ETH withdraw leg is wrapped in try/catch — if it reverts, the helper emits Events.KingWithdrawalFailed(user, reason) and the bundle still succeeds with just the Barons payout. Zero King balance is a no-op (returns early without reverting), not a failure. The two legs are not symmetric: Barons failure is fatal, King failure is best-effort.

Delegation-gated wrappers

These methods are for bots acting on behalf of user.

MethodWhat it doesRequired permission
claimShareholderForUser(user, ...)Barons Collect for userP_CLAIM_SHAREHOLDER_FOR
withdrawKingBalanceForUser(user)Withdraw King ETH bucket for userP_WITHDRAW_KING_BUCKET_FOR
claimAllFor(user, ...)Bundle: Barons Collect + King bucket withdrawP_CLAIM_ALL_FOR

Authorization model:

  • ClaimAllHelper has no standalone hub pointer. Delegated wrappers resolve authority from the live MineCore / ShareholderRoyalties / shared Furnace bundle.
  • For every delegated helper path, the helper first requires:
    • MineCore.claimAllHelper() == address(this)
    • MineCore.royalties() == royalties
    • ShareholderRoyalties.claimAllHelper() == address(this)
    • ShareholderRoyalties.mineCore() == mineCore
    • MineCore.furnace() == ShareholderRoyalties.furnace()
    • Furnace.mineCore() == mineCore
    • Furnace.shareholderRoyalties() == royalties
    • Furnace.delegationHub() == MineCore.delegationHub()
  • withdrawKingBalanceForUser(...) fails closed on any MineCore/Furnace hub drift; it does not trust a raw MineCore.delegationHub() read in isolation.
  • claimShareholderForUser(...) and claimAllFor(...) use that same canonical-hub preflight, so split-brain MineCore.furnace() vs ShareholderRoyalties.furnace() wiring is rejected before authorization.

On success, delegated wrappers emit:

  • Events.DelegationSessionUsed(user, delegate, actionTypeId, permsUsed, refId=0, timestamp)

actionTypeId values (v1.0.0):

  • 10 = CLAIM_SHAREHOLDER_FOR
  • 11 = WITHDRAW_KING_BUCKET_FOR
  • 12 = CLAIM_ALL_FOR

Integrator notes

Computing minVeOut (mode = LOCK_FURNACE)

ClaimAllHelper does not compute slippage bounds for you.

For Collect & Lock:

  1. Quote via FurnaceQuoter (resolve address from furnace.furnaceQuoter()):
    • furnaceQuoter.quoteEnterWithEth(user, ethIn, targetTokenId, durationSeconds, quoteCreateAutoMax)
  2. Convert quote to min-out:
    • minVeOut = floor(veOut * (10_000 - slippageBps) / 10_000)
    • veOut here covers only the newly locked amount at the lock’s remaining duration; entry into an existing lock does not change its duration.
    • If veOut > 0 but floor-rounding would produce minVeOut == 0, clamp to 1 before calling a Furnace entry path.

Use the same approach whether you call:

  • ShareholderRoyalties.claimShareholder(...) directly, or
  • ClaimAllHelper bundle methods.

Locking pause behavior

If Furnace.lockingPaused == true:

  • any path that uses mode LOCK_FURNACE will revert
  • mode ETH (Collect ETH) still works

UX recommendations

  • Keep the UI verb Collect for ETH payouts.
  • Only expose ClaimAllHelper if you actually need bundling or delegated wrappers.
    • Many apps can call claimShareholder and withdrawKingBalance separately.

See also