livepeer / livepeer/LIPs

Transcoder withdrawal address

Open
#4 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
8
Forks
20
PR merge metrics
No merged PRs in 30d

Description

At the moment, transcoders use a single address for the following purposes:

  • As the on-chain identifier for the transcoder
  • The associated private key signs transactions to invoke contract functions such as BondingManager.reward(), JobsManager.claimWork() and JobsManger.verify() that validate that the sender address is the transcoder's identifier address
  • As the withdrawal address for any LPT earned as rewards and ETH earned as fees

Transcoders can instead use one address as their identifier address (so that contract functions can validate that the transcoder is the sender) and use one address as their withdrawal address.

There are a number of benefits that come with allowing a transcoder to specify a withdrawal address that is distinct from its identifier address

  • The associated private key for the identifier address can be "hot" and the associated private key for the withdrawal address can be "cold". The hot key can hold just enough ETH to submit transactions associated with being an active transcoder and be actively used to sign transactions by an automatic process. The cold key can hold larger amounts of ETH/LPT and can be secured by a hardware wallet since it does not need to be actively used. Note: it will nonetheless be crucial for a transcoder node operator to properly secure the hot key since a compromised hot key can allow an attacker to cause the transcoder node operator to be slashed. However, with this hot key and cold key setup, any of the transcoder node operator's withdrawn ETH/LPT or reserve funds will be safe in the event of a compromised hot key
  • The withdrawal address can be associated with a contract that specifies rules for the use of withdrawn ETH/LPT
    • The contract could be a 2-of-3 multisig wallet - 3 parties could agree to be joint owners of a
      transcoder node and designate one party to be the transcoder node operator with any earnings
      generated being transferred into this multisig wallet. Multisig wallet funds could then be spent if 2 of 3
      parties agree.
    • The contract could be an Aragon DAO - a group of community members
      could agree to be members of the DAO which owns the transcoder node and designate one party to be the transcoder node operator with any earnings being transferred into the DAO. An initial
      implementation of the DAO might use a simple voting application to allow community members to
      authorize the use of DAO funds. The DAO could be upgraded to use alternative applications such as
      liquid democracy to govern the use of DAO funds
    • The contract could define payout logic for a staking service such as 1Protocol

From an implementation point of view this would require an additional withdrawalAddress in the transcoder struct in the BondingManager contract. This value of withdrawalAddress could be specified when invoking the BondingManager.transcoder() function. (One note here is that the BondingManager.transcoder() would become even more overloaded in this case because it is used not only to register as a transcoder, but also for changing rates and now setting a withdrawal address. It might be worth splitting up the function into two separate functions, one for registering with a withdrawal address and one for setting rates).

BondingManager.withdrawStake() would check if the sender has a withdrawalAddress as a transcoder - if so, the function will ask the Minter to transfer LPT rewards to withdrawalAddress, if not the function will ask the Minter to transfer LPT rewards to the sender address. BondingManager.withdrawFees() would work similarly.

BondingManager is delegate proxied meaning any changes during an upgrade will have to be storage layout compatible. At the moment, the addition of withdrawalAddress to the transcoder struct should be acceptable because the transcoder struct is only used in a mapping and not in any arrays and we would be adding an additional storage variable and not deleting or replacing any existing ones (we would need to make sure it comes after all existing variables in the transcoder struct!).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the BondingManager transcoder(), withdrawStake(), and withdrawFees() entry points, then inspect the transcoder struct and its Minter transfer path. Done means defining the separate withdrawal address behavior while preserving delegate-proxy storage layout compatibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
blockchain
Domain
blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.