Skip to content

Conversation

SidestreamSweatyPumpkin

What does this pull request do? Explain your changes. (required)

This PR adds a new feature to the livepeer protocol which will allow transcoders to set a multiple addresses they trust to claim the rewards on every round without requiring the main wallet to stay unlocked.

Specific updates (required)

  • contracts/bonding/BondingManager.sol contract is modified to include
    • New rewardCallerToTranscoderProposed public mapping to keep self-proposed rewardCallers
    • New rewardCallerToTranscoderConfirmed public mapping to keep RewardCallers confirmed by the relevant transcoders
    • New proposeTranscoderForRewardCaller function to propose RewardCaller for transcoders
      • Can be undone by proposing address(0)
    • New confirmRewardCaller function to confirm previously proposed RewardCaller
      • Also resets the proposed address to zero
    • New removeRewardCaller, function to remove confirmed RewardCallers by the transcoders
    • Existing rewardWithHint is modified to also be callable by the confirmed RewardCallers
  • test/unit/BondingManager.js test is modified to include new "reward delegation" section
  • yarn test:coverage:check command is added to the CI to insure 100% test coverage

How did you test each of these updates (required)

A new "reward delegation" section contains tests that ensure:

  • A transcoder is able to to call the reward even if RewardCaller is set for them, or removed
  • If a RewardCaller is set, the account is able to call reward
  • If the RewardCaller is not set or removed, it is not able to call reward
  • A transcoder is not able to re-confirm RewardCaller after adding them, adding and removing them
  • It is impossible to confirm RewardCaller without a proposal submitted by the RewardCaller itself
  • It is impossible to remove the RewardCaller for another transcoder
  • Checkpoint logs reward recipient, not the RewardCaller

Does this pull request close any open issues?

No

Checklist:

  • README and other documentation updated
    • No relevant documentation found, the changes are backwards compatible
  • All tests using yarn test pass

@SidestreamSweatyPumpkin
Copy link
Author

SidestreamSweatyPumpkin commented Sep 12, 2025

Additional notes on the implementation and known problems

Low-01:

If the TranscoderA sets TranscoderB as their RewardCaller, the RewardCaller wouldn't be able to claim rewards on behalf of TranscoderA (which the TranscoderA can still directly claim the rewards themselves). This edge case (of using another active transcoder as a RewardCaller) is rather unexpected, but might not be obvious for the users. The security implications for this edge case is the DoS, but only limited to the case where TranscoderB owns private key of the TranscoderA and wise-versa.

Note-01:

In this implementation it is NOT possible for multiple different transcoders to set the same address as their RewardCaller. Moreover, if a RewardCaller after being confirmed by TranscoderA is wanted to be used by the TranscoderB, TranscoderA first need to remove the RewardCaller. This restriction is added to prevent confusion associated with the expectation that the same RewardCaller can be used for multiple transcoders.

Note-02:

In this implementation is it possible to set multiple RewardCallers per single transcoder. We found no security issues associated with that. The front-running DoS / address squatting attack is mitigated by requiring proposeTranscoderForRewardCaller to be called by the potential RewardCaller, ensuring the ownership of the private key by the transcoder.

Note-03:

It is not part of the current implementation, but it's possible to add a functionality to self-revoke RewardCaller. Currently, only the transcoder which set the RewardCaller can remove it by calling removeRewardCaller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant