Livepeer Contracts: Github
Livepeer Contracts Arbiscan
- LivepeerToken (LPT) ownership and delegation
- Staking and selection of active orchestrators
- Distribution of inflationary rewards and fees to participants
- Time-based progression of the protocol through rounds
- Payment processing through a probabilistic micropayment system
- Core Protocol Contracts — staking, payments, round progression, and service discovery
- Token and Utility Contracts — the LPT token and bridge infrastructure
- Governance Contracts — on-chain voting, proposal execution, and treasury management
Contract Interaction Architecture
Core Protocol Contracts
The core protocol contracts manage staking, delegation, reward distribution, round progression, payment processing, and service discovery. The Controller serves as the central registry — upgrading a contract means registering a new target implementation address via the Controller, while the proxy address remains stable.Controller
The Controller is the central registry for all protocol contracts. Every other contract resolves peer contract addresses by callinggetContract(keccak256("<name>")) on the Controller. Upgrades are applied by registering a new implementation address under the same name hash — the proxy addresses never change.
Controller
Controller
Address (Arbitrum One):Verified · Deployed by Livepeer Deployer · 20 transactionsPurpose:
- Central address registry for all protocol contracts
- Enables contract upgrades while keeping proxy addresses stable
- Provides
pause()/unpause()for emergency system-wide halts - Owner is the Governor contract — all upgrades must go through governance
Controller.sol):getContract(bytes32 _id) → address— look up a registered contract by keccak256 name hashgetContractInfo(bytes32 _id) → (address, bytes20)— returns address and git commit hashsetContractInfo(bytes32 _id, address _contractAddress, bytes20 _gitCommitHash)— register or update a contract; callable by owner (Governor) onlypause()/unpause()— halt or resume all contracts that checkcontroller.paused()updateController(bytes32 _id, address _controller)— update the Controller reference in a registered contract
BondingManager
The BondingManager is the most critical economic contract in the protocol. It manages the active orchestrator pool as a sorted doubly-linked list, handles all LPT bonding and unbonding, and distributes inflationary rewards and fees each round.feeShare in the protocol is defined as: the percentage of fees paid to delegators by the transcoder (orchestrator). It is not the gateway’s cut — it is the orchestrator’s share of fees that they pass on to their delegators. Source: BondingManager.sol struct comment: // % of fees paid to delegators by transcoder.
BondingManager
BondingManager
Proxy Address (Arbitrum One):Verified · 198,341 transactions · ActiveTarget Address (Arbitrum One — V11, current):
0x4bA7E7531Ab56bC8d78dB4FDc88D21F621f34BB4 Deployed 16 Feb 2026 ·
Registered in Controller as BondingManagerTarget · Source not yet verified on
BlockscoutPurpose:- Manages the active orchestrator pool (sorted by stake using SortedDoublyLL)
- Handles
bond(),unbond(), andwithdrawStake()for all delegators - Distributes inflationary LPT rewards to orchestrators and their delegators each round
- Manages the unbonding period — delegators must wait
unbondingPeriodrounds before withdrawing - Tracks per-round earnings pools for each orchestrator
- Calls
checkpointBondingState()on BondingVotes on every state change for governance weight - Since Delta upgrade: sends
treasuryRewardCutRatefraction of each reward to Treasury
BondingManager.sol, delta branch):bond(uint256 _amount, address _to)— delegate LPT stake to an orchestratorunbond(uint256 _amount)— begin withdrawal; creates an unbonding lock, starts the unbonding periodrebond(uint256 _unbondingLockId)— cancel unbonding and re-bond stakerebondFromUnbonded(address _to, uint256 _unbondingLockId)— re-bond to a new orchestrator from unbonded statewithdrawStake(uint256 _unbondingLockId)— complete withdrawal after unbonding period expireswithdrawFees(address payable _recipient, uint256 _amount)— withdraw accumulated ETH feestranscoder(uint256 _rewardCut, uint256 _feeShare)— register as an orchestrator or update parameters;_rewardCutis % of reward kept by orchestrator;_feeShareis % of fees passed to delegatorsreward()— called by active orchestrators each round to mint inflationary LPT and distribute to earnings poolclaimEarnings(uint256 _endRound)— checkpoint and claim accumulated rewards and fees through a given roundpendingStake(address _addr, uint256 _endRound) → uint256— returns unclaimed pending stake for a delegatorpendingFees(address _addr, uint256 _endRound) → uint256— returns unclaimed pending ETH fees for a delegatorgetTranscoder(address _transcoder)— returns orchestrator state (rewardCut, feeShare, active status, etc.)getDelegator(address _delegator)— returns delegator state (bondedAmount, delegate, lastClaimRound, etc.)
TicketBroker
The TicketBroker implements Livepeer’s off-chain probabilistic micropayment (PM) system. Gateways pre-fund a deposit and reserve on-chain; they send lottery tickets to orchestrators off-chain with each transcoding job. Orchestrators redeem winning tickets on-chain to claim payment. This amortises per-segment payment costs across many tickets.TicketBroker
TicketBroker
Proxy Address (Arbitrum One):Verified · ActiveTarget Address (Arbitrum One — V2, current):
0xea1b0F6c8D158328a6e3D3F924B86A759F41465c Verified on-chain 18 Mar 2026
via Controller.getContract(keccak256("TicketBrokerTarget"))Purpose:- Holds gateway ETH deposits and reserves
- Validates and settles winning probabilistic payment tickets
- Manages the unlock period before gateways can withdraw funds
- Tracks claimed reserves per orchestrator per round to prevent over-redemption
- Emits
WinningTicketRedeemedevents used for on-chain payment monitoring
TicketBroker.sol):fundDeposit()— gateway adds to ETH deposit (payable)fundReserve()— gateway adds to ETH reserve (payable)fundDepositAndReserve(uint256 _depositAmount, uint256 _reserveAmount)— fund both in one call (payable)redeemWinningTicket(Ticket calldata _ticket, bytes calldata _sig, uint256 _recipientRand)— orchestrator redeems a winning ticket; transfers ETH to fee pool via BondingManagerunlock()— gateway initiates the withdrawal unlock periodcancelUnlock()— gateway cancels an in-progress unlockwithdraw()— gateway withdraws deposit and reserve after unlock periodgetReserve(address _reserveHolder) → Reserve— returns reserve state for an addressgetSender(address _sender) → Sender— returns sender (gateway) state: deposit, reserve, unlock period
RoundsManager
The RoundsManager defines the protocol’s time unit. A round is a fixed number of Arbitrum blocks. The current round must be initialised before orchestrators can callreward(). It stores per-round block hashes used as randomness for ticket validation.
RoundsManager
RoundsManager
Proxy Address (Arbitrum One):Verified · ActiveTarget Address (Arbitrum One):
0x92d804Ed49D92438aEA6fe552BD9163aacb7E841 Verified · “Livepeer: Target
Rounds Manager” on ArbiscanPurpose:- Tracks the current round number and round length in blocks
- Stores block hashes per round for ticket randomness (used by TicketBroker)
- Enforces the round lock period — orchestrators cannot change parameters during the lock window at end of each round
initializeRound()must be called at the start of each new round before reward calls proceed
RoundsManager.sol):initializeRound()— initialise a new round; callable by any address; updates block hash store and lip upgrade roundscurrentRound() → uint256— returns current round numbercurrentRoundInitialized() → bool— returns whether the current round has been initialisedcurrentRoundLocked() → bool— returns whether the current round is in its lock periodblockHashForRound(uint256 _round) → bytes32— returns the stored block hash for a given roundroundLength() → uint256— returns round length in blocksroundLockAmount() → uint256— returns lock period as a percentage of round length (MathUtils percPoint)
Minter
The Minter controls LPT token inflation. Each round it calculates the mintable token supply based on the configured inflation rate. Since the Delta upgrade (LIP-91), a configurable fraction of each round’s reward is minted to the Treasury rather than solely to orchestrators and delegators.Minter
Minter
Address (Arbitrum One):Verified · ActivePurpose:
- Manages LPT token inflation schedule
- Calculates mintable tokens per round based on current
inflationrate and total LPT supply - Adjusts inflation up or down each round based on actual bonding rate vs
targetBondingRate - Called by BondingManager during orchestrator
reward()calls — not called directly - Holds ETH received from TicketBroker redemptions and disburses to orchestrators
Minter.sol):createReward(uint256 _fracNum, uint256 _fracDenom) → uint256— called only by BondingManager; mints a fraction of mintable tokens for the round as a rewardtrustedTransferTokens(address _to, uint256 _amount)— transfer LPT to an address; callable by BondingManager onlytrustedBurnTokens(uint256 _amount)— burn LPT; callable by BondingManager onlytrustedWithdrawETH(address payable _to, uint256 _amount)— withdraw ETH to an address; callable by BondingManager onlydepositETH()— receive ETH from TicketBroker on ticket redemption (payable)currentMintableTokens() → uint256— returns LPT mintable in the current roundcurrentMintedTokens() → uint256— returns LPT already minted in the current roundinflation() → uint256— returns current inflation rate as a MathUtils percPoint valueinflationChange() → uint256— returns per-round inflation adjustment amounttargetBondingRate() → uint256— returns the target bonding rate that inflation adjusts towards
ServiceRegistry
The ServiceRegistry stores each orchestrator’s publicly advertised HTTPS service URI on-chain. Gateway nodes query this registry during network initialisation to discover orchestrators. Each update emits aServiceURIUpdate event that off-chain indexers track.
ServiceRegistry
ServiceRegistry
Proxy Address (Arbitrum One):Verified · ~600 transactions · Last active Jan 2026Target Address (Arbitrum One):
0x38093CDca43aeCd7bb474983519A246e93A3b0a7 Verified · “Livepeer: Target
Service Registry” on ArbiscanPurpose:- Allows orchestrators to register and update their service endpoint URIs
- Enables gateway nodes to discover orchestrators when using
-network arbitrum-one-mainnet - Not used when a gateway specifies
-orchAddrdirectly
ServiceRegistry.sol):setServiceURI(string calldata _serviceURI)— orchestrator registers or updates their HTTPS endpoint; emitsServiceURIUpdate(address indexed _addr, string _serviceURI)getServiceURI(address _addr) → string— returns the registered URI for a given orchestrator address
AIServiceRegistry
A standalone ServiceRegistry for AI subnet orchestrators. Detached from the Controller — its address is hardcoded in go-livepeer (starter.go) rather than resolved dynamically. Deployed by a different deployer than the main protocol contracts.
AIServiceRegistry
AIServiceRegistry
Address (Arbitrum One):Verified · Deployed Apr 2024 · Active · Deployed by AI subnet deployer (different from main Livepeer Deployer)Purpose:
- Stores service URI and capability metadata for AI-enabled orchestrators
- Used when a node is started with
-aiServiceRegistryflag - Same interface as ServiceRegistry (
setServiceURI,getServiceURI)
Token and Utility Contracts
LivepeerToken (LPT)
Dual-chain — Ethereum Mainnet (origin) and Arbitrum One The LivepeerToken is the native protocol token. It is an ERC-20 with AccessControl-based MINTER_ROLE and BURNER_ROLE. The canonical token contract lives on Ethereum Mainnet; a bridged representation exists on Arbitrum One.LivepeerToken
LivepeerToken
Address (Arbitrum One):Verified · 261,217 holders · ActiveAddress (Ethereum Mainnet):
0x58b6a8a3302369daec383334672404ee733ab239 Verified · 1.88M holders ·
Origin tokenPurpose:- ERC-20 token used for bonding, staking, gateway payment reserves, and governance voting weight
approve()must be called before bonding or funding deposits- On Arbitrum One: minted by Minter (inflationary rewards) and by the bridge (inflows from L1)
LivepeerToken.sol, inherits OpenZeppelin ERC20 + ERC20Permit + ERC20Burnable + AccessControl):- Standard ERC-20:
transfer(),transferFrom(),approve(),balanceOf(),totalSupply(),allowance() permit(...)— EIP-2612 gasless approvalmint(address _to, uint256 _amount)— callable only by MINTER_ROLE (Minter contract on Arbitrum, BridgeMinter on L1)burn(uint256 _amount)— callable only by BURNER_ROLE
BridgeMinter
Ethereum Mainnet Holds MINTER_ROLE on the L1 LivepeerToken. Called by the bridge when LPT is transferred from Arbitrum back to Ethereum Mainnet, minting the corresponding L1 LPT.BridgeMinter
BridgeMinter
Address (Ethereum Mainnet):
0x8dDDB96CF36AC8860f1DE5C7c4698fd499FAB405 Verified · Active ·
“Livepeer: Bridge Minter” on BlockscoutL1LPTGateway / L2LPTGateway
Paired bridge gateway contracts on Ethereum Mainnet (L1) and Arbitrum One (L2). LPT bridged L1→L2 is locked in L1Escrow; LPT bridged L2→L1 is released from escrow or minted via BridgeMinter. Based on the Dai bridge architecture.Bridge Gateways
Bridge Gateways
L2LPTGateway (Arbitrum One):Verified · ActiveL1LPTGateway (Ethereum Mainnet):Verified · Active · Holds bridged LPT
0x6142f1C8bBF02E6A6bd074E8d564c9A5420a0676 Verified · ActiveL1Escrow (Ethereum Mainnet):LivepeerTokenFaucet
Testnets Only Distributes test LPT on testnets. Does not exist on Ethereum Mainnet or Arbitrum One mainnet.Governance Contracts
The Delta upgrade (LIP-89, LIP-91 — October 2023) introduced full on-chain governance. The governance system consists of four contracts working together: BondingVotes checkpoints voting power, LivepeerGovernor manages proposal voting, Treasury holds protocol funds, and Governor executes approved upgrades.BondingVotes
BondingVotes implements the ERC-5805 votes interface, storing per-round stake checkpoints for every delegator and orchestrator. The LivepeerGovernor queries it to determine voting power at proposal creation time. Checkpoints are written automatically by BondingManager on every bond, unbond, reward, and earnings claim.BondingVotes
BondingVotes
Proxy Address (Arbitrum One):Verified · ActiveTarget Address (Arbitrum One):
0x68AF80376Bc1CA0C25a83b28e5570E8c7bdD3119 VerifiedPurpose:- Stores per-round stake checkpoints for every participant
- Implements ERC-5805 (
getPastVotes,getPastTotalSupply) used by LivepeerGovernor - Checkpoints are written by BondingManager — not called directly by users
- Supports delegator vote overrides: a delegator can override their orchestrator’s vote
BondingVotes.sol, delta branch):checkpointBondingState(address _owner, uint256 _startRound, uint256 _bondedAmount, address _delegateAddress, uint256 _delegatedAmount, uint256 _lastClaimRound, uint256 _lastRewardRound)— called by BondingManager to checkpoint stake state; not callable directlycheckpointTotalActiveStake(uint256 _totalStake, uint256 _round)— checkpoint total active stake; called by BondingManagergetPastVotes(address _account, uint256 _round) → uint256— returns voting power for an account at the start of a given roundgetPastTotalSupply(uint256 _round) → uint256— returns total voting power (active stake) at a given roundhasCheckpoint(address _account) → bool— returns whether an account has any checkpointed stake
Governor
The original upgrade execution contract. Holds the owner role on the Controller. Executes protocol upgrades (contract address updates, parameter changes) via a staged proposal queue with a configurable delay.Governor
Governor
Address (Arbitrum One):Verified · 18 transactions · Last active Aug 2025 · Deployed by Livepeer DeployerPurpose:
- Owns the Controller contract — only address that can call
setContractInfo() - Executes protocol upgrade transactions after governance approval
- Enforces a staged execution queue with a mandatory delay
Governor.sol):stage(Transaction[] calldata _transactions, uint256 _delay)— queue a batch of upgrade transactions with a delay; emitsTransactionStagedexecute(Transaction[] calldata _transactions)— execute a queued batch after its delay has elapsed; emitsTransactionExecutedowner() → address— returns the owner (currently the LivepeerGovernor proxy via timelock)
LivepeerGovernor
Implements OpenZeppelin’s upgradeable Governor framework adapted for Livepeer’s stake-weighted voting. Voting power equals bonded LPT as recorded by BondingVotes at proposal creation time. Supports GovernorCountingOverridable — delegators can override their orchestrator’s vote on any proposal.LivepeerGovernor
LivepeerGovernor
Proxy Address (Arbitrum One):Verified · ActiveTarget Address (Arbitrum One):
0xd2Ce37BCB287CaDc40647f567C2D3C4220901634 VerifiedPurpose:- On-chain voting for protocol proposals, weighted by bonded LPT stake
- Delegators can override their orchestrator’s vote (GovernorCountingOverridable)
- Passed proposals execute through the Treasury timelock, then through the Governor to the Controller
bumpGovernorVotesTokenAddress()must be called if BondingVotes address ever changes
LivepeerGovernor.sol, delta branch):initialize(uint256 _initialVotingDelay, uint256 _initialVotingPeriod, uint256 _initialProposalThreshold, uint256 _initialQuorumNumerator, TimelockControllerUpgradeable _timelock, address _controller)— one-time initialisation via proxypropose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) → uint256— submit a new governance proposal; returns proposalIdcastVote(uint256 proposalId, uint8 support) → uint256— cast a vote (0=Against, 1=For, 2=Abstain)castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) → uint256— vote with explanationqueue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) → uint256— queue a passed proposal into the timelockexecute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) → uint256— execute a queued proposal after timelock delayquorumDenominator() → uint256— returnsMathUtils.PERC_DIVISOR(the quorum denominator)bumpGovernorVotesTokenAddress()— update the internal BondingVotes reference if its address has changed
Treasury
An OpenZeppelin TimelockControllerUpgradeable that holds the protocol’s on-chain treasury. A configurable percentage of each round’s inflationary LPT rewards is directed here by the Minter. All disbursements require a passed LivepeerGovernor proposal. Automatic contributions halt when the treasury balance exceedstreasuryBalanceCeiling (configured in BondingManager).
Treasury
Treasury
Address (Arbitrum One):Verified · ActivePurpose:
- Receives a fraction of each round’s inflationary LPT rewards (rate set by
treasuryRewardCutRatein BondingManager) - Governed entirely by LivepeerGovernor — all disbursements require a passed proposal
- Implements TimelockController — all operations have a mandatory delay between queue and execution
- Contributions automatically halt when LPT balance exceeds
treasuryBalanceCeiling - Funds Special Purpose Entities (SPEs) and ecosystem grants via governance proposals
schedule(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt, uint256 delay)— schedule an operation; callable by proposer role (LivepeerGovernor)execute(address target, uint256 value, bytes calldata payload, bytes32 predecessor, bytes32 salt)— execute a ready operation; callable by executor rolecancel(bytes32 id)— cancel a pending operation; callable by canceller roleisOperation(bytes32 id) → bool— check if an operation existsisOperationReady(bytes32 id) → bool— check if an operation is past its delay and ready to executegetMinDelay() → uint256— returns the minimum delay for all operations
Full Address Reference
For the complete list of all current and historical contract addresses across Arbitrum One and Ethereum Mainnet, including all historical target/implementation versions, see the Contract Addresses reference page. All addresses in this page were verified on 18 March 2026 by querying the Controller contract directly on-chain viagetContract(keccak256("<name>")) (Arbitrum One) and Blockscout get_address_info (Ethereum Mainnet). No documentation sources were used.