Summary
The protocol was paused for a short period of time (less than a round) last week in order to fix a security vulnerability in the BondingManager contract. Members of the core development team discovered the vulnerability at the beginning of the week, analyzed the vulnerability to understand its impact, implemented a fix, validated the fix and completed deployment of the fix around 5:00am EST Wednesday 1/13/21.
The vulnerability, if exploited, would have allowed a delegator to increase its stake and fees by delegating to a transcoder under certain conditions resulting in the delegator earning more rewards and fees than it should have been entitled to. This vulnerability has been fixed and users do not need to worry about the vulnerability impacting them. At the moment, based on analysis of contract state before and after the deployment of the fix, no cases of compromised user value have been discovered by the core development team. The technical details of the vulnerability are shared below for informational purposes.
Technical Details
Impact
What kind of vulnerability is it? Who is impacted?
Description
This vulnerability can allow a delegators to increase their stake or fees by delegating to a transcoder that has previously generated rewards or fees, but that has not generated rewards or fees in the current round. The two types of delegation actions that can exploit this vulnerability when the proper conditions are met are:
- A delegator switching delegation from one transcoder to another
- An unbonded delegator delegating to a transcoder
The root cause of this vulnerability is that whenever earnings are calculated the cumulativeRewardFactor
and cumulativeFeeFactor
for the delegator’s transcoder from the delegator’s lastClaimRound
are used, but these values can be 0 if the delegator’s transcoder did not generate rewards or fees in lastClaimRound
. In this scenario, the cumulativeRewardFactor
should be non-zero if the transcoder previously generated rewards and the cumulativeFeeFactor
should be non-zero if the transcoder previously generated fees.
The calculation of the amount of rewards and fees to allocate to delegators in a range of rounds depends on the relationship between the factors at the start round of the range and the end round of the range. If either factor for the start round of the range is 0 when it should instead be a non-zero value, delegators would be allocated more rewards or fees that they should be entitled to. Furthermore, the extra rewards or fees allocated to delegators could cause the total stake and fees of delegators tracked by the BondingManager to exceed the total LPT and ETH held by the system.
When a delegator switches its delegation or when an unbonded delegator delegates to a transcoder, the current round factors for the transcoder could be 0 if the transcoder does not generate rewards or fees in the current round. The following example illustrates the problem focusing on rewards (would work similarly for fees):
- Delegator is delegated to transcoder 1 OR the delegator is unbonded
- Transcoder 2 calls reward in round
N - 1
setting itscumulativeRewardFactor
for the round toX
- Round
N
is initialized - Transcoder 2 does not call reward in round
N
- Delegator delegates to transcoder 2 setting the delegator’s
lastClaimRound
toN
- Round
N + 1
is initialized - The earnings calculation for the delegator starts at round
N
and ends at roundN + 1
- The
cumulativeRewardFactor
for roundN
is 0 because transcoder 2 did not generate rewards for that round. - The
cumulativeRewardFactor
for roundN + 1
isX
because the BondingManager looks up thecumulativeRewardFactor
from thelastRewardRound = N - 1
for transcoder 2 - The ratio between the
cumulativeRewardFactor
for roundN
and roundN + 1
incorrectly indicates that there are new rewards to allocate to the delegator.
- The
Triggering/Reproducing
Exploit Scenarios
This vulnerability could be inadvertently or maliciously triggered.
When this vulnerability is triggered, the delegator could unbond/withdraw more LPT and ETH than it should have been entitled too. The delegator would only be able to unbond/withdraw this extra LPT and ETH if it does not exceed the total LPT or ETH held by the system. If the extra LPT and ETH exceeds the total LPT or ETH held by the system, the unbond/withdraw actions would trigger transaction reverts instead.
Patches
Has the problem been patched? What versions should users upgrade to?
The vulnerability has been patched in the following set of commits:
Deployment
These were the steps taken for deployment with links to the relevant transactions:
- Deploy a new BondingManger implementation contract
- Stage an update with the Governor that registers the new BondingManager implementation with the Controller
- A delay of 0 was used because it was determined that a fix needed to be deployed as soon as possible to safeguard user value.
- Multisig submission of the tx
- Multisig approval and execution of the tx
- Execute the staged update to complete the registration of the new BondingManager implementation with the Controller
The list of deployed contract addresses has been updated with the latest version of the BondingManager implementation contract.
For more information
If you have any questions or comments about this advisory:
- Email us at security@livepeer.og