Quote:
_"In practical terms, it can be defined that after any write function called on the BONDING_MANAGER (including the checkpointBondingState below), the checkpointed state of all involved accounts should follow that mutation consistently. The “involved accounts” include:
…
If any of the above is a transcoder, all their delegators with at least 1 checkpoint."_
The BondingCheckpoint for an address that interacts with the BondingManager takes several inputs which are stored in the Delegate struct and one input from the Transcoder struct - t.lastRewardRound.
The checkpointing logic generally checkpoints the addresses where a state change occurs. For example, increaseTotalStake will checkpoint the state of the transcoder which had their stake increased. However, a delegator’s bonding state can change when their transcoder’s state - specifically the lastRewardRound changes.
When the lastRewardRound for a transcoder is updated in the rewardWithHint or updateTranscoderWithFees functions, it does not update the lastRewardRound for all the delegators to this transcoder. If the functions were implemented correctly they would contain a code block which iterates through all the delegators of the transcoder and updates their bonding checkpoint. Instead, the rewardWithHint function only checkpoints the transcoder (who is also msg.sender):
function rewardWithHint(address _newPosPrev, address _newPosNext)
public
whenSystemNotPaused
currentRoundInitialized
autoCheckpoint(msg.sender)
{
After t.lastRewardRound is updated, the function ends without additional checkpointing other than the autoCheckpoint(msg.sender) modifier:
t.lastRewardRound = currentRound;
emit Reward(msg.sender, transcoderRewards);
} //----FUNCTION END-----
This means that the lastRewardRound will be incorrect for the delegator leading to incorrect rewards and the delegator’s bonding state can change without the bonding checkpoint being updated.
Manual Review
There could be a mapping from transcoder to an array of delegates which gets updated every time a delegate is added or removed. When lastRewardRound is updated, it could iterate through the deleagtors and update the checkpoint for t.lastRewardRound.
Other
The text was updated successfully, but these errors were encountered:
All reactions