LIP-118 · Arbitrum One · shared reward caller

Your orchestrator keys stay cold.
Your rewards get called. Every round.

Point your reward caller to

0x2F5901C6D8EB0181FA4f2b75EAAd0344a916fdDE

One setRewardCaller transaction from your orchestrator wallet — via the go-livepeer CLI or any signer — then the key goes back to cold storage. Full instructions ↓

livepeer.bot runs LivepeerRewardCaller — one immutable contract that makes the daily reward() call for every Livepeer orchestrator who points setRewardCaller at it. Subscribe once, put the key back in cold storage, done.

93 tests green, including a mainnet-fork suite run against the live LIP-118 deployment on Arbitrum One · two independent audits, all findings addressed · source & tests on GitHub

01 · The problem

The last hot key

Livepeer pays orchestrators through a reward() call that must land once per round — roughly every 21 hours, forever. Before LIP-118 that call had to come from the orchestrator key itself, so the key that controls your stake sat hot on a server around the clock for one routine transaction a day.

LIP-118 fixes this: setRewardCaller(addr) delegates exactly the reward call — nothing else — to an address you choose. livepeer.bot is that address, shared by everyone: one contract, one keeper, every subscriber's reward called each round, no coordination required.

02 · How it works

Three steps, one of them yours

1

Subscribe once

From your orchestrator key, one transaction on the BondingManager. Then the key goes back to cold storage — it is not needed again.

setRewardCaller(<contract>)
2

Anyone sweeps, every round

A keeper bot (we run one), a cron job, or a stranger calls the contract. It initializes the round if needed, walks the active pool, and attempts reward for every subscriber not yet rewarded.

rewardAll(15, 0)
3

Protocol mints, exactly as if you called

The BondingManager computes your reward, commission, and delegator shares itself — amounts are fixed at round initialization. Repeats every ~21 h.

RewardCallSucceeded ✓

your cold key → setRewardCaller (once) → livepeer.bot contract → rewardForTranscoderWithHint (every round) → BondingManager mints your LPT

Repeated or concurrent calls are harmless: the protocol's own lastRewardRound makes every sweep idempotent, already-rewarded orchestrators are skipped, and one failing orchestrator is isolated in try/catch — it never blocks the rest.

03 · Trust model

Built to be boring

This is the section that should decide it. Everything below is verifiable in ~400 lines of Solidity.

Immutable, unowned

No owner. No admin. No pause switch. No upgrade hook. The code you audit today is the code that runs forever.

Zero storage, zero funds

The contract keeps no mutable state and never holds LPT or ETH. There is nothing to drain, freeze, or misconfigure.

Delegation grants one power

LIP-118 lets this contract call reward for you — nothing else. Your commission, your delegators' shares, and the amounts are computed by the protocol and fixed at round start. The caller cannot move a single wei.

You keep control

Your own reward() self-call keeps working — delegation adds a caller, it never locks you out. Opt out any time with setRewardCaller(address(0)).

Bounded worst case

The worst possible failure is a missed reward call — never loss of stake or funds. And your self-call remains as the backstop for exactly that case.

No forced upgrades

If a v2 is ever wanted, it will be a new address that you deliberately re-point to. There is no mechanism by which anyone can migrate you.

Verify it yourself: 93 tests green, including a mainnet-fork suite against the live LIP-118 target on Arbitrum One (BondingManager target 0xbe19…0Bd2, protocol commit ccc82f43) · two independent automated audits, every finding fixed or answered on record (reports & responses) · read the source & tests · verified source on Arbiscan and Blockscout

04 · Join

One transaction from your orchestrator key

Call setRewardCaller on the Livepeer BondingManager (0x35Bcf3c30594191d53231E4FF333E8A770453e40 on Arbitrum One), pointing it at this contract. With Foundry's cast and a Ledger:

cast send 0x35Bcf3c30594191d53231E4FF333E8A770453e40 \
  "setRewardCaller(address)" 0x2F5901C6D8EB0181FA4f2b75EAAd0344a916fdDE \
  --rpc-url https://arb1.arbitrum.io/rpc --ledger

Not a cast user? Any signer works — open the BondingManager's write-contract page on the explorer (or use a Safe) and call setRewardCaller with the contract address. Then put your key back in the freezer.

Change your mind later? Opt out the same way, any time:

cast send 0x35Bcf3c30594191d53231E4FF333E8A770453e40 \
  "setRewardCaller(address)" 0x0000000000000000000000000000000000000000 \
  --rpc-url https://arb1.arbitrum.io/rpc --ledger

05 · Keep it running

Anyone can trigger it. Anyone can fund it.

The sweep is permissionless and idempotent — there is no keeper monopoly and no way to trigger it "wrong". If our bot ever disappears, one command keeps every subscriber paid:

# once per round (~21 h), from any funded wallet
cast send 0x2F5901C6D8EB0181FA4f2b75EAAd0344a916fdDE "rewardAll(uint256,uint256)" 15 0 \
  --gas-limit 25000000 --rpc-url https://arb1.arbitrum.io/rpc

Use the hardcoded 25M gas limit — plain eth_estimateGas does not account for the contract's ≥2.5M per-attempt safety floor. If the sweep is truncated (complete == false), call again; repeat calls are harmless. The full keeper recipe — including the mid-round eviction rescue — lives in the keeper docs.

Redundancy & funding

Keeper script repo /keeper — run your own copy anywhere a cron job runs
Decentralized backstop under evaluation — Chainlink Automation was sunset industry-wide in July 2026 before launch; successors (Chainlink CRE, Reactive Network) are being assessed in the automation guide. Meanwhile the truly decentralized layer is the one no company can sunset: the permissionless command above, runnable by anyone.
Keeper gas wallet 0xd6DEa4B2fb4Bb20019cab813fe06F992EC1Fd794 — ETH donations on Arbitrum One extend the bot's runway; it holds gas money only, never touches rewards. Please don't send more than gas dust — it's a hot operational wallet by design

What it costs (full transparency)

ScaleTxs per roundApprox. cost
Launch (~5 subscribers)1 tx, ~4–7M gas~$0.15–0.30 / day
Entire pool (100 orchestrators)3–7 txs~$1–4 / day

At Arbitrum's typical ~0.02 gwei gas price. There is no fee and no profit motive — this is infrastructure run as a public good, cheap enough for one person to fund and simple enough for anyone to replace.