Attributes
- Author(s): @poktblade
- Implementer(s): Me, myself, and I and literally anyone else who wants to join the fun.
- Category: Protocol Upgrade
Summary
A new transaction within the network that allows a node to transfer a portion or their full stake to another account (or node) without the need to unstake. As well, this transaction will ensure that the transfered POKT is still staked into the network (no excess liquidity)
Community Calls
This topic was brought up two times in seperate V0 Developer Protocol Community calls. From an initial round of discussion, there isn’t necessarily anything engineering blocking about this feature. (@blockjoe , @luyzdeleon )
Motivation
Validator bidding war
The bidding war is defined as the top 1,000 validator nodes competing amongst each other to receive the block proposer reward currently set at 5%. The problem arises whenever one of these validators become “outbidded” and is no longer a validator (i.e: 1,001th validator). The outbided validator needs to decide whether they should increase their StakedAmount
to reenter the top 1,000 validators or exit the bidding war by unstaking.
Whenever considering why someone would unstake after being outbidded, there is a high chance that they are unstaking to restake as horizontally scaled servicers or because it is no longer worth it from a macroeconomic perspective (or from a reward perspective). That being said, the main purpose is not to exit the network. We should not be penalizing participants by a hefty 21 days unstaking time before they can actually transition their stake into scaled servicers. Furthermore, the network is also penalized as we lose MAX(1, n)
amount of potential servicers while the unstaking occurs since validators can be servicers too
Non Diverse/Small Validator Set
On top of this, leaving the responsibility for small to medium node runners to decide what will happen in the next 21 days is extremely harsh. The truth is only whales can afford to participate in such a bidding war, whereas most are incentivized to not validate and stay away from the high risk high reward scenarios. By offering a zero to low risk penalty, we should see more small to medium node runners participate in validation and as a result see a more diverse validator set. This is needed for a healthy decentralized protocol
Overall unhealthy staking economics
PIP-22 allows for either both horizontally scaled or vertical scaled nodes (up to a cap). We should allow for flexibility to chose for one or both and the ability to convert amongst the two. This would allow for efficient consolidation without the need to unstake and weaken the network.
PUP-19 also incentized more nodes to become validators. However, now if the DAO was to revert the block proposer to 1% (not saying it will, just an example), then it could result in a large reduction in validators and large amount of POKT being unstaked due to the bidding war. So, there is a side effect where the DAO is dissuaded to make this decision. With an transfer stake transaction, the DAO has more options on whether they should increase or decrease economic parameters.
Future PUPS and PIPS: Future proposals may result in some form of consolidation between servicers and validators (i.e GV). By offering a way to TransferStake’s, we are offering a healthy mechanism that participants of the network can use to bypass the so called “transition phase”
Initial Specification
These specifications are subject to change, it is not finalized. I am opening the floor for all to give their thoughts and shape TransferStake
into something that is viable both from engineering perspective and what reflects the DAO’s will support. (And TBH, I wrote this in like 30 mins)
The final specifications will be announced after a round of discussion, let’s get it rollin’
Dependency
- Non custodial staking activated
CLI Command
pocket accounts transfer-stake <sender_address> <receiver_operator_address> <receiver_output_address> <amount> <fee> <network_id> <service_url> <chain_ids>
TransferStake Transaction Rules
- The sender address must be a staked node (not unstaking, not jailed) otherwise the transaction will fail (INVALID_VALIDATOR_ERR/NOT_FOUND)
- If the sender address set an output address, it must be signed by the output address otherwise then transaction will fail
(INVALID_SIGNER_ERR) - If the sender of the transaction does not have an output address, it must be signed by the sender address, otherwise the transaction will fail (INVALID_SIGNER_ERR)
- If receiver node is already staked, and receiver output address is set (or empty), then the
receiver_output_address
in the TransferStake command must match (or be empty as well) otherwise the transaction will fail - The transfer stake amount must be within the bounds of
MinStake
andSenderStakedBalance
, otherwise the transaction will fail. (INSUFFICIENT_TRANSFER_ERR)
(We can also modify the transfer minimum amount so that senders can send smaller amounts lower thanMinStake
as long as the receiver is already a staked node. This modification should not use the Receiver’s Account balance due to unauthorized reasons (unless multi sig is supported)). This may include a little extra logic when it comes to engineering implementation but nothing major
Upon successful transactions, the state of the network will change as such:
- If the receiver account is unstaked, they will be staked into the network. Else If the receiver account is already staked, their staked balance will update
-
SenderStakeBalance
will decrement. If theSenderStakeBalance
drops belowMinStake
, they will be effectively be unstaking (21 day waiting period) / unstaked (if net balance is 0)
Feature Flag
This new transaction will be protected by an block height activation feature flag
Implementation, Viability, Testing, Audits, etc
Dissenting Opinions
This adds more block bloat
This is not too much of a concern. There are upcoming features i.e persistent replacement & LeanPOKT that will significantly reduce our storage requirements. Furthermore, the amount of TransferStake transaction should be on the lower end
Shuffling nodes will affect sessions and our QoS
This is nothing new to our protocol as is. If a node unstake, the dispatcher and full nodes should generate a new session. Additionally, TransferStake can minimize the amount of times a new session is generated by making TransferStake valid only at the end of a session block. With this modification, there is no need for apps, nodes, and dispatchers to generate new sessions since nodes shuffled via transferstake will only apply at the end of a session
Attack Vector(s)
Unauthorized Node transfers (Prevented momentary incentive not to do this + multisig if needed)
- Attacker transfer 15K stake to non staked random addresses with the attacker’s output address
- Random address doesn’t realize the output address is set to attackers output address, and stakes additional funds
- Atacker submits unstake and gets the net rewards
Block proposer gaming: Increasing your chances of being a block proposer by generating a keypair that is more likely to be chosen. I need to do more research, but given that there is a psuedo randominess and ticketed system for this - I think the risk is mitigated b itself
PIP-22 Gaming: Transfer stake to a node that is in session to earn more rewards. This is mitigated by only allowing transfer stake to occur at the end of session.
PIP-22 Gaming 2: If you are able to determine what the next block hash is, you can determine which nodes will be included in the next session and transfer stake to them. TBD - Needs more research on block hash determinstic behavior and if it’s gameable.
Oopsie: An application logic falls through the crack - allowing everyone and their grandma to do unauthorized stakes or duplicate stakes. - This is why we have a process for Q/A and a process!
Edits
- 8/13/2022: Added clarity on options for
TransferStake
minimum in TransferStake Transaction Rules - 8/14/2022: Added a hypthoetical attack vector and added clarity on output address
- 9/1/2022: Added more attack vectors and migitations
Copyright
Copyright and related rights waived via CC0.