The Livepeer protocol defines the rules of participation for a cryptotoken powered decentralized video transcoding marketplace. The protocol relies on a system of smart contracts deployed on the Ethereum blockchain.
This document is a technical specification of the protocol. For a more general overview of the protocol see:
- The whitepaper for the original proposal
- The Streamflow proposal paper for the Streamflow scalability upgrade proposal
This specification applies to the Streamflow version of the protocol.
This specification will describe protocol actions in terms of smart contract function calls that trigger state transitions within the system.
Users that bond tokens have bonded stake that can be delegated to another user. The total amount of bonded tokens delegated to a user is the user's delegated stake.
The users that participate in the Livepeer protocol are:
- Delegators: Users that bond tokens and delegate their bonded stake to other users, usually registered transcoders in exchange for shared rewards and fees.
- Transcoders: Delegators with bonded stake delegated to themselves that also perform transcoding work for the network. The transcoders with the most delegated stake are elected as active transcoders that process transcode jobs for the network. Note that as of the Streamflow version of the protocol, outside of the contracts and this specification, most documentation will use the term "orchestrator" to refer to the protocol participant that performs transcoding work and will use the term "transcoder" to refer to machines connected to orchestrators that transcode video, but do not directly participate in the protocol. Pre-Streamflow, the transcoder role performed all of these functions. We continue to use the term "transcoder" to refer to the protocol participant that performs transcoding work in the contracts and specification since the distinction between an orchestrator and transcoder is an extra-protocol concern.
- Broadcasters: Submit transcode jobs for video streams.
The Livepeer protocol is round based and each round is represented by some number of Ethereum blocks. During each round, delegators help elect the top transcoders that share the most rewards and fees and the transcoders that they believe will create the most economic value in the network by efficiently transcoding video streams. They delegate their bonded stake to registered transcoders and at the beginning of each round, the top transcoders with the largest amount of delegated stake amongst all registered transcoders are locked in as the members of the active transcoder set for that round.
Active transcoders will:
- Earn inflationary rewards during a round in proportion to their delegated stake. The transcoder keeps a portion of the rewards and shares the rest with its delegators based on the reward cut rate previously advertised
- Earn fees by transcoding video sent by broadcasters. The transcoder keeps a portion of fees earned and shares the rest with is delegators based on the fee share rate previously advertised
- Advertise a URI in an on-chain registry that broadcasters can use to connect with the transcoders off-chain
Broadcasters that seek to distribute video to a large audience in a variety of bitrates and formats it will connect with active transcoders off-chain and send video segments to selected transcoders that will transcode input segments into output segments corresponding to the video profiles requested by the broadcaster.
The broadcaster's workflow consists of the following processes:
- A transcoder selection algorithm based on a combination of factors such as stake, price and historic performance in order to pick transcoders to send segments to
- An off-chain payment protocol to send micropayments to transcoders that can be aggregated into larger macropayments that can be settled on-chain
- An off-chain payment accounting protocol to determine the value of payments to send to transcoders
- A local verification algorithm on results received from a transcoders in order to check that video was correctly transcoded
The only process listed that is currently in the scope of this specification is the off-chain payment protocol. The Streamflow version of the protocol uses a probabilistic micropayment (PM) protocol and design details can be found in the PM specification.
The Livepeer smart contract system is written in Solidity and will be deployed on the Ethereum blockchain. The system consists of the following contracts:
Controller
: Maintains a registry that maps contract identifiers to contract addresses.LivepeerToken
: Manages state and logic for the ERC-20 Livepeer token that is used for bonding. The contract owner can mint new tokens.ManagerProxy
: A proxy contract that maintains state and relies on a target contract to implement state changing logic. It forwards function calls usingdelegatecall
to invoke function logic in a target contract with its own storage context.ServiceRegistry
: Manages transcoder service metadata that is required for the off-chain transcoding workflow.RoundsManager
: Manages state and logic associated with round progression.BondingManager
: Manages state and logic associated with bonding, unbonding, transcoder registration, and claiming rewards and fees.TicketBroker
: Manages state and logic associated with the PM protocol (i.e. tracking funds available for tickets, ticket redemption).Minter
: Manages state and logic associated with the issuance of new tokens. The contract also serves as the escrow for all bonded tokens and all deposited Ether (used to pay for tickets in the PM protocol).
Contracts registered with Controller
are managers. Managers use the registry maintained by Controller
to look up the addresses of other managers in the system.
BondingManager
, TicketBroker
, and RoundsManager
are deployed as upgradeable manager proxies. An instance of ManagerProxy
is deployed for each of these managers and the actual
contracts are deployed as target contracts for the manager proxies. As a result, these managers can be upgraded by deploying new versions of the target contracts while maintaining
state (with some storage layout related restrictions).
After protocol genesis, Minter
becomes the owner of LivepeerToken
and is able to issue new tokens based on the logic in its implementation.
For any contract with the name Contract
we refer to the deployed instance of the contract as contract
.
Function calls on a specific contract are written as contract.foo()
. Parameters are excluded when describing function calls and instead detailed in plain English.
The staking token of the protocol is the Livepeer token which will be referred to as LPT.
The payment token of the protocol is currently regular Ether, which will be referred to as ETH, but the protocol could be modified to support other tokens such as stablecoins in the future.
In a round, the set of transcoders that are pending activation in the next round is called the transcoder pool. The pool has a max size of numActiveTranscoders
and is implemented as a sorted doubly linked list. Each element in the pool contains a transcoder's ETH address and the transcoder's delegated stake. At the beginning of a round, the members of the pool are locked in as the active transcoder set for that round.
Delegator information is stored in a delegator structure. All users that have bonded stake have a delegator structure associated with their address. As a result, users that are transcoders also have delegator structures stored that contain their bonded stake information.
Field | Description |
---|---|
bondedAmount | The amount of bonded stake. |
fees | The amount of fees collected. |
delegateAddress | The Ethereum address of the delegate. |
delegatedAmount | The amount of delegated stake. |
startRound | The round the delegator becomes bonded and delegated to its delegate. |
lastClaimRound | The last round that the delegator claimed reward and fee pool shares. |
nextUnbondingLockId | The ID of the next unbonding lock the delegator creates. |
unbondingLocks | The collection of unbonding locks created by the delegator. |
A delegator can have zero or many unbonding locks. See Unbonding Lock for more information.
A delegator can be in one of the following states Pending
, Bonded
, or Unbonded
.
- A delegator is in the
Pending
state ifstartRound > currentRound
. A delegator enters thePending
state when it bonds from theUnbonded
state. - A delegator is in the
Bonded
state ifstartRound > 0 && startRound <= currentRound
. A delegator enters theBonded
state at the start ofstartRound
which is set after it bonds. - A delegator is in the
Unbonded
state ifbondedAmount == 0
. A delegator starts off in theUnbonded
state by default and also enters theUnbonded
state if it fully unbonds.
When a delegator unbonds, information about the amount of LPT being unbonded and the round at which the locked LPT can be withdrawn is stored in an unbonding lock structure.
Field | Description |
---|---|
amount | The amount of LPT being unbonded |
withdrawRound | The round at which the unbonding period is over and the locked LPT can be withdrawn. |
Transcoder information is stored in a transcoder structure.
Field | Description |
---|---|
lastRewardRound | The last round that the transcoder called received rewards as an active transcoder. |
rewardCut | The percentage of inflationary rewards that a transcoder keeps. |
feeShare | The percentage of transcode job fees that a transcoder shares with its delegators. |
earningsPoolPerRound | The reward and fee pools for each round. |
lastActiveStakeUpdateRound | The last round that the transcoder's stake was updated as an active transcoder. |
activationRound | The round in which the transcoder will become active. |
deactivationRound | The round in which the transcoder will become inactive. |
A delegator is considered a registered transcoder if it has non-zero bonded stake delegated to itself.
A registered transcoder is considered active if transcoder.activationRound <= currentRound < transcoder.deacivationRound
.
Earnings information from a round is stored in an earnings pool structure.
Field | Description |
---|---|
rewardPool | Delegator rewards. If hasTranscoderRewardFeePool = true , will contain transcoder rewards as well. |
feePool | Delegator fees. If hasTranscoderRewardFeePool = true , will contain transcoder fees as well. |
totalStake | Transcoder's total stake during the round. |
claimableStake | Stake that can be used to claim portions of the delegator reward and fee pools. |
transcoderRewardCut | Transcoder's reward cut for the round. |
transcoderFeeShare | Transcoder's fee share for the round. |
transcoderRewardPool | Transcoder rewards. If hasTranscoderRewardFeePool = true , this will be 0. |
transcoderFeePool | Transcoder fees. If hasTranscoderRewardFeePool = true , this will be 0. |
hasTranscoderRewardFeePool | Flag to indiciate if delegator and transcoder reward/fee pools are separate. |
Note that the hasTranscoderRewardFeePool
flag was introduced in a previous upgrade. Any earnings pools created prior to the upgrade would not have separate delegator and transcoder reward/fee pools. The hasTranscoderRewardFeePool
flag is false for these pools (since there was no way to update the flag before the upgrade and since the default value for the storage position for the flag will be false). So, contract code can calculate the amount claimed from reward/fee pools differently depending on if hasTranscoderRewardFeePool
is true or false. See the comments in the EarningsPool
library for more details.
Transcoder service metadata required for the off-chain transcoding workflow is stored in a record structure.
Field | Description |
---|---|
serviceURI | The URI endpoint that can be used to send off-chain requests to the transcoder. |
This section describes the state transitions associated with common protocol actions.
For actions specific to the PM protocol refer to the PM specification.
At the start of each round, the round must be initialized before any other protocol actions can be executed. Round initialization entails locking in the latest active transcoder set for the round and setting the maximum number of tokens that can be issued (based on the current inflation rate). A round can only be initialized once and anybody can invoke the function to initialize a round.
B
is the current block number such thatB % roundLength == 0
RoundsManager
BondingManager
Minter
- At some block number
M
in the setB, B+1, B+2...B + roundLength - 1
, a user callsroundsManager.initializeRound()
. currentRound = M / roundLength
.- If the last initialized round is not less than
currentRound
, abort. - Set the last initialized round to
currentRound
. - Set the total active stake for
currentRound
. - Set the maximum number of LPT that can be issued in the round based on the current LPT supply and the current
inflationRate
.
Round progression is dependent on some actor calling roundsManager.initializeRound()
at the start of a new round. Since, protocol actions cannot be executed until
the current round is initialized, actors have an incentive to pay the transaction fees for calling roundsManager.initializeRound()
if they stand to economically benefit from
any protocol action that could take place during an initialized round. One example is a transcoder that has accumulated enough delegated stake to become an active transcoder in a round. The
transcoder will be able to claim inflationary rewards and fees from processing transcode jobs if it joins the active transcoder set for a round, so it has an incentive to initialize a round so that
it can be included in the active transcoder set for that round.
Delegators bond LPT and delegate their bonded stake either to themselves or to someone else. Although delegators do not have to delegate to registered transcoders, they are incentivized to do so by the potential returns in the inflationary rewards and fees shared by the transcoder. Delegators cannot bond more tokens than they own.
- User
T
- User
D
LivepeerToken
BondingManager
D
approvesbondingManager
to transfer an amount of LPT fromD
by callinglivepeerToken.approve()
.D
callsbondingManager.bond()
to bondX
LPT toT
.- Increase T's total stake by X
D
's LPT balance decreases byX
.D
is delegated toT
.- Set
startRound = currentRound + 1
. D
enters thePending
state.- Once
currentRound = startRound
,D
enters theBonded
state.
Delegators that delegated their bonded stake to a transcoder can delegate their bonded stake to someone else. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- Users
T1
,T2
- User
D
delegated toT1
- User
D
in theBonded
state
BondingManager
D
callsbondingManager.bond()
to bond 0 LPT toT2
.D
's bonded stakeX
becomes delegated toT2
.- Decrease T1's total stake by X
- Increase T2's total stake by X
Delegators that delegated their bonded stake to someone can atomically delegate their bonded stake to someone else and also increase their bonded stake. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- Users
T1
andT2
- User
D
is delegated toT1
- User
D
in theBonded
state
LivepeerToken
BondingManager
D
approvesbondingManager
to transferX2
LPT fromD
by callinglivepeerToken.approve()
.D
callsbondingManager.bond()
to bondX2
LPT toT2
.D
's bonded stake increases toX1 + X2
.- Decrease T1's total stake by X1
- Increase T2's total stake by X1 + X2
D
's LPT balance decreases byX2
.
When delegators delegate their bonded stake to a delegate, they increase the delegate's total stake.
- User
T
- User
D
BondingManager
- Increase
T
's delegated amount byX
- If
T
is not a registered transcoder, return - If
T
is not in the transcoder pool, try to add it to the transcoder pool and return - Update
T
's position in the transcoder pool - Add
X
to the next round's total active stake - Increase
totalStake
andclaimableStake
forT
's earnings pool for the next round byX
- Set
T
'slastActiveStakeUpdateRound = nextRound
When delegators unbond or change their delegation, they increase their current delegate's total stake.
- User
T
- User
D
BondingManager
- Decrease
T
's delegated amount byX
- If
T
is not in the transcoder pool, return - Update
T
's position in the transcoder pool - Subtract
X
from the next round's total active stake - Decrease
totalStake
andclaimableStake
forT
's earnings pool for the next round byX
- Set
T
'slastActiveStakeUpdateRound = nextRound
A registered transcoder can join the transcoder pool if it has sufficient total stake.
- Registered transcoder
T
with total stakeX
BondingManager
- If the transcoder pool is full:
- Let
lastTranscoder
be the transcoder in the pool with the smallest stake. LetlastStake
be the stake oflastTranscoder
- If
X <= lastStake
, return - Deactivate lastTranscoder
- Let
- Add
T
to the transcoder pool - Add
X
to the next round's total active stake - Set
totalStake
andclaimableStake
forT
's earnings pool for the next round toX
- Set
T
'slastActiveStakeUpdateRound = nextRound
- Set
T
'sactivationRound = nextRound
- Set
T
'sdeactivationRound = MAX_FUTURE_ROUND
MAX_FUTURE_ROUND
is a very large integer (i.e. 2^256 - 1
) representing a round very far in the future.
A transcoder will be pending deactivation if:
- It fully unbonds
- Is evicted from the transcoder pool because another transcoder joined with more total stake
- Active transcoder
T
with total stakeX
- Remove
T
from the transcoder pool - Subtract
X
from the next round's total active stake - Set
T
'sdeactivationRound = nextRound
Delegators can unbond some or all of their bonded stake. When a delegator unbonds the LPT becomes locked in an unbonding lock. Locked LPT can be withdrawn after an unbonding period or rebonded at anytime. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- User
D
is delegated toT
- User
D
in theBonded
state
BondingManager
D
callsbondingManager.unbond()
to unbondX
fromT
.- If
D
is not in theBonded
state, abort. - If
X
is greater thanD
's current bonded stake, abort. - Create an unbonding lock for
D
with the IDnextUnbondingLockId
. Setamount
toX
andwithdrawRound
tocurrentRound + unbondingPeriod
. - Increment
nextUnbondingLockId
. D
's bonded stake decreases byX
.- If
D
's bonded stake is zero, remove its delegate and start round. - If
D
is in the transcoder pool, deactivate D - Decrease T's total stake by X
Delegators can unbond some or all of their bonded stake and then rebond the LPT. The delegator does not have to wait for the unbonding period for locked LPT to complete before rebonding. If the delegator is in the Bonded
state, locked LPT can only be rebonded to the delegator's current delegate. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- User
D
is delegated toT
- User
D
in theBonded
state - User
D
previously executed theUnbonding
algorithm. Let the fields for the relevant unbonding lock for rebonding beunbondingLockId
,amount
andwithdrawRound
BondingManager
D
callsbondingManager.rebond()
withunbondingLockId
.- If
D
is in theUnbonded
state, abort. - If
unbondingLockId
is not a valid unbonding lock ID, abort. D
's bonded stake increases byamount
.- Increase T's total stake by amount
- Delete the unbonding lock for
unbondingLockId
.
Delegators can unbond some or all of their bonded stake and then rebond the LPT. Delegators can be in the Unbonded
state and rebond locked LPT to a delegate of their choice. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- User
D
is in theUnbonded
state - User
D
previously executed theUnbonding
algorithm. Let the fields for the relevent unbonding lock for rebonding beunbondingLockId
,amount
andwithdrawRound
BondingManager
D
callsbondingManager.rebondFromUnbonded()
with the new delegateT
andunbondingLockId
.- If
D
is not in theUnbonded
state, abort. - If
unbondingLockId
is not a valid unbonding lock ID, abort. D
's start round is set tocurrentRound + 1
.D
's delegate is set toT
.D
's bonded stake increases byamount
.- Increase T's total stake by amount
- Delete the unbonding lock for
unbondingLockId
.
Delegators with bonded stake can unbond to start the process of withdrawing their bonded LPT. Delegators cannot withdraw locked LPT until the unbonding period for the locked LPT is complete. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
- User
D
previously executed theUnbonding
algorithm. Let the fields for the relevent unbonding lock for rebonding beunbondingLockId
,amount
andwithdrawRound
- The protocol progressed through
unbondingPeriod
number of rounds such that the current round iswithdrawRound
.
LivepeerToken
BondingManager
D
callsbondingManager.withdrawStake()
withunbondingLockId
.- If
unbondingLockId
is not a valid unbonding lock ID, abort. - If
withdrawRound > currentRound
, abort. D
's LPT balance increases byamount
.- Delete the unbonding lock for
unbondingLockId
.
Delegators can withdraw any collected fees at any time. Reward and fee shares from past rounds will automatically be claimed first - see Automatically Claiming Rewards and Fees for more details.
BondingManager
- User
D
D
callsbondingManager.withdrawFees()
to withdrawX
ETH.D
's collected fees decreases byX
.D
's ETH balance increases byX
.
A user can register as a transcoder by delegating > 0 LPT to itself.
- User
T
that is not registered
BondingManager
T
callsbondingManager.bond()
with delegateT
andX > 0
A transcoder can update its service URI in the ServiceRegistry
to be used in the off-chain transcoding workflow.
- User
T
ServiceRegistry
T
callsserviceRegistry.setServiceURI()
with a providedserviceURI
.T
's service URI inServiceRegistry
is set toserviceURI
.
A transcoder can change its commission rates (i.e. reward cut and fee share) during a round. A transcoder cannot change its rates during the lock period of a round. A transcoder can also try to join the transcoder pool if it has sufficient stake in the same transaction that it updateds its commission rates.
- Transcoder
T
BondingManager
T
callsbondingManager.transcoder()
with percentage values forrewardCut
andfeeShare
.- If
rewardCut
is not a valid percentage, abort. - If
feeShare
is not a valid percenage, abort. - If
T
is not a registered transcoder, abort. - If the protocol is in the lock period of the round, abort.
- If
T
is active in the current round andlastRewardRound != currentRound
, abort. - Set the rates for
T
as a transcoder. - If
T
is not in the transcoder pool, try to add T to the transcoder pool
Note: Step 6 ensures that if T
is active in the current round that it is unable to change its rewardCut
and feeShare
before locking the current values as the transcoderRewardCut
and transcoderFeeShare
values in T
's earnings pool for the round (these values recorded in the earnings pool are used to calculate distribution of rewards/fees between a transcoder and its delegators for the round). A non-active transcoder would be able to freely set its rewardCut
and feeShare
which should be ok because 1) a non-active transcoder will not be eligible for inflationary rewards so it will not have rewards to share and 2) broadcasters will only be working with active transcoders so a non-active transcoder will not have fees to share.
LPT rewards are distributed every round to the members of the active transcoder set for the round. The total rewards available for a round is based on newly issued LPT from inflation. The amount of issued LPT during a round cannot exceed the maximum amount of LPT to be issued for a round which is set at the start of a round. An active transcoder's share of the rewards is based on the transcoder's proportional delegated stake within the active transcoder set.
- Total delegated stake of the active transcoder set is
X
- Active transcoder
T
hasY
delegated stake - Maximum amount of LPT to be issued in round
N
isA
.
BondingManager
Minter
LivepeerToken
T
callsbondingManager.reward()
in roundN
.- Set
T
'slastRewardRound = currentRound
- Set the commission rates on
T
's earnings pool forcurrentRound
using its currentrewardCut
andfeeShare
(A * Y) / X
new LPT is issued.- Total supply of LPT increased by
(A * Y) / X
. - Increase amount of LPT already issued in round
N
by(A * Y) / X
. T
places(A * Y) / X
LPT in its reward pool for roundN
.
A delegator is not credited with its reward shares until it explicitly claims them. Thus, the total reward shares to be claimed added to a delegator's bonded stake is the
delegator's pendingStake
. If a delegator has claimed all of its reward shares, its bonded stake will be equal to its pendingStake
.
Delegators that delegate their bonded stake to an active transcoder are entitled to a portion of the rewards and fees that the transcoder earns during a round. The reward and fee portions shared
by the transcoder to its delegators are based on the rewardCut
and feeShare
rates set by a transcoder. When a transcoder earns rewards during a round, it places the LPT in a reward pool associated
with the round. When a transcoder earns fees for a transcode job, it places the ETH in a fee pool associated with the round during which the transcode job was created.
The delegator reward share for a round is split amongst delegators that were delegated to the transcoder during the round based on a delegator's proportional bonded stake relative to the transcoder's delegated
stake. The transcoder is entitled to rewardCut
percent of the reward pool. The delegator fee share for a round is split amongst delegators that were delegated to the transcoder during the round a transcode job was created based
on a delegator's proportional bonded stake relative to the transcoder's delegated stake. The transcoder is entitled to 100 - feeShare
percent of the fee pool.
- Transcoder
T
withX
delegated stake - Delegator
D
withY
bonded stake delegated toT
BondingManager
T
earnsR
rewards andF
fees for a transcode job created in roundN
.T
allocatesdelegatorsRewards = (R * (100 - rewardCut)) / 100
rewards for its delegators anddelegatorsFees = (F * feeShare) / 100
for its delegators.D
claims reward and fees for roundN
either automatically or manually.D
credits(delegatorsRewards * X) / Y
rewards into its bonded stake.D
credits(delegatorsFees * X) / Y
fees into its collected fees.- If
D == T
,D
also creditsR - delegatorsRewards
rewards into its bonded stake andF - delegatorsFees
into its collected fees.
See Automatically Claiming Rewards and Fees and Manually Claiming Rewards and Fees for details on different approaches to claiming rewards and fees for particular rounds.
When a delegator calls a bonding related function (ex. delegates to a new transcoder), it first automatically claims its LPT share from the reward and fee pools for each round that it was delegated to its current transcoder.
- Delegator
D
- Transcoder
T
BondingManager
D
calls a bonding related function such asbondingManager.bond()
orbondingManager.unbond()
.- Before the logic of the bonding related function is executed,
D
claims rewards and fees for each round it was delegated to its current delegate through the current round. - After claiming rewards and fees through the current round,
D
sets its last claim round as the current round. - Execute the logic of the bonding related function.
If a delegator does not invoke a bonding related functions for a large number of rounds, it is possible that the number of rounds that it would need to automatically claim rewards and fees for becomes too large such
that the bonding related function cannot be executed within the Ethereum block gas limit. A restriction is imposed such that a delegator cannot claim through more rounds than
maxEarningsClaimsRounds
. In this situation, a delegator can manually claim rewards and fees through a chosen end round.
Delegators can automatically claim rewards and fees when calling bonding related functions, but they need to be able to manually claim rewards and fees as well. A delegator can claim rewards and fees from its last claim round through a chosen end round which does not necessarily have to be the current round.
- Delegator
D
- Transcoder
T
BondingManager
D
callsbondingManager.claimEarnings()
with the end round through which to claim rewards and fees.D
claims rewards and fees for each it was delegated to its current delegate through the end round.D
sets its last claim round as the chosen end round.
A client interacting with the protocol can check how many rounds a delegator would have to claim rewards and fees for before calling a bonding related function. If the number of rounds is too large,
the client can divide the number of rounds into portions and make multiple calls to bondingManager.claimEarnings()
with the end rounds corresponding to each portion. After claiming all the rewards
and fees, the client can then call the bonding related function without the risk of a function call not being executable within the Ethereum block gas limit. A restriction is imposed such that
a delegator cannot claim through more rounds than maxEarningsClaimsRounds
.
The only user that is able to upgrade a manager is the owner of Controller
. Upgrading a manager proxy entails deploying a new version of the target contract that the manager proxy
depends on. The new version of the target contract can contain arbitrary changes in the business logic of the old version of the target contract. The new version of the target contract should
not change the storage layout of the old version of the target contract, meaning the definition order of existing storage variables should not change and existing storage variables should not be
removed or replaced. However, the names of existing storage variables can be changed and new storage variables can be added in the new version of the target contract.
proxyName
is the name of the manager proxy being upgradedproxyId
is the contract ID of the manager proxy, defined askeccak256(proxyName)
targetName
is the name of the target contract, conventionally defined asproxyName + "Target"
targetId
is the contract ID of the target contract, defined askeccak256(targetName)
newTargetAddr
is the address of the new version of the target contract
Controller
controller
's owner callscontroller.setContract(targetId, newTargetAddr)
controller
sets the contract address mapped totargetId
asnewTargetAddr
- The manager proxy with ID
proxyId
usesdelegatecall
to forward function calls to the target contract with IDtargetId
and addressnewTargetAddr
.
The only user that is able to update a manager's parameter values is the owner of Controller
.
paramName
is the name of the parameter being updatednewValue
is the new value for the parameterparamName
- The manager
controller
's owner calls the parameter setter function defined inmanager
forparamName
. For example, ifparamName == "unbondingPeriod"
, the function call ismanager.setUnbondingPeriod(newValue)
.manager
sets the value forparamName
asnewValue
manager
fires an event notifying clients of the parameter update.
inflation
automatically adjusts based upon the current bonding rate, the total amount of active bonded stake (i.e. the total stake of the active transcoder set) in the network relative to the total supply of LPT, and targetBondingRate
.
If the current bonding rate is below targetBondingRate
, inflation
should increase. The desired effect of an increase in inflation
is for more users to participate in the
bonding and delegation process in order to increase the economic security of the network. Users that bond will be able to capture a larger share of the network relative to users that do
not bond by claiming a share of the inflationary rewards every round. Users that do not bond will see their LPT holdings become diluted in value due to the increase in the supply of LPT.
If the current bonding rate is above targetBondingRate
inflation
should decrease. The desired effect of a decrease in inflation
is for less users to participate in the
bonding and delegation process in order to increase the amount of liquid LPT available in the network. Since the inflationary rewards are smaller, users might prefer to hold on to
liquid unbonded LPT which can be freely transacted and traded rather than bonding which locks up the LPT for a period of time. If the current bonding rate is equal to targetBondingRate
,
inflation
is unchanged.
- Transcoder
T
- Delegator
D
BondingManager
RoundsManager
Minter
- The current bonding rate increases via a call to a bonding related function in
BondingManager
. - A new round begins and someone calls
roundsManager.initializeRound()
to initialize the round. - If the current bonding rate is less than
targetBondingRate
, increaseinflation
byinflationChange
. - If the current bonding rate is greater than
targetBondingRate
, decreaseinflation
byinflationChange
. - If the current bonding rate is equal to
targetBondingRate
, keepinflation
the same.
The protocol uses a number of parameters the values of which are used in protocol actions. In initial development phases after genesis, the values of these parameters can
be changed by the Controller
's owner which will be a multisig contract. In later development phases, the values of these parameters will only be changed by governance.
Each of the parameters are defined in the manager that they are the most relevant for.
Parameter | Description | Example Value |
---|---|---|
roundLength |
Number of blocks in a round. | 5760 |
roundLockAmount |
Percentage of blocks in a round that are a part of the lock period during which transcoders cannot change their rates upwards, or enter/leave the transcoder pool. | 10 |
Parameter | Description | Example Value |
---|---|---|
unbondingPeriod |
Number of rounds that a delegator must wait after calling unbond before it can withdraw its unbonded LPT. |
7 |
numActivetranscoders |
Maximum number of active transcoders during a round. | 10 |
maxEarningsClaimsRounds |
Maximum number of past rounds that a delegator can claim reward and fee shares through in a single transaction | 20 |
Parameter | Description | Example Value |
---|---|---|
inflation |
Percentage of total LPT supply that is issued as new LPT during a round. | 7 |
inflationChange |
Percentage change in inflation that occurs when the current bonding rate does not equal targetBondingRate . |
.02 |
targetBondingRate |
Percentage of total LPT supply that should be bonded to provid economic security for the system. | 50 |
For TicketBroker
parameters refer to the PM specfication.