near / nearcore-support

This repository is used to keep track of nearcore issues reported by validator community and infrastructure partners
1 stars 0 forks source link

[Node Issue]: Incorrect Validator Reward Payouts #7

Open sbond14 opened 1 month ago

sbond14 commented 1 month ago

Contact Details

staking-notifications@foundrydigital.com

What happened?

Foundry recently had a large delegation to our validator. We noticed that the delegator instantly started earning rewards, even though the stake weight of the pool had not yet increased. It seems like the new stake doesn’t become active for a few epochs, but instantly starts earning a share of the rewards (which in turn decreases rewards for all other delegators).

You can see the delegator staked in epoch 2657, and instantly earned rewards during that epoch. https://nearscope.net/delegator/4855ba0899d235ab059689db02686e6574cf1a70d10bbc77ed0d82d1d9b07b16/tab/rewards

However, our validator didn't see an increase in total rewards until epoch 2660. https://nearscope.net/validator/foundry.poolv1.near/tab/rewards

This is a massive problem as the delegators are 2 separate parties. It seems like a malicious delegator could abuse this mechanism to constantly take rewards from other innocent delegators.

What is even more confusing is that the new delegator earned rewards in epoch 2657 and 2658, but no other delegator saw decreased rewards until epochs 2659 and 2660 (and all delegators including the new one saw decreased rewards during those 2 epochs).

Version

1.40.0

Node type

RPC (Default)

Are you a validator?

Relevant log output

Not relevant

Node head info

Not relevant

Node upgrade history

Not relevant

DB reset history

Not relevant
evgenykuzyakov commented 1 month ago

While this is not precise, it's by design. This is how the staking pool was implemented.

The main reason is the stake proposal becomes active only after 2 epochs, so for the 2 epochs the rewards are given for the previous stake amount, while the pool size has increased.

The new delegated stake immediately receives staking pool shares and the portion of the rewards from the next epoch. What's also the case is the pool will receive the rewards for the 2 epochs after any delegator unstakes. So if a large delegator unstakes, the remaining pool delegations will share the rewards for the previous stake amount for the 2 epochs, but the unstaked delegator doesn't. So it's not possible to abuse the rewards this way without having to unstake.

Example:

  1. Initially pool has 10K NEAR and receives 10% APY.
  2. A large delegator comes in and stakes 90K NEAR.
  3. For the next 2 epochs, the pool will effectively receive 1% APY, because their stake is now 100K, but rewards are only for the 10K
  4. Next, the APY is back to 10% for the rewards of the total stake of 100K.
  5. The large delegator decides to unstake 90K.
  6. For the next 2 epochs, the rewards are coming for 100K stake, but distributed across 10K delegations. This makes effective 100% APY.
  7. The large delegator can withdraw and APY is back to 10% on 10K rewards.

Hope it helps

sbond14 commented 1 month ago

This seems like very poor design. If the large delegator stakes for a long time, any delegator that has to unstake before they do will never see those extra rewards on the back end. Why not just delay rewards to the new delegator for 2 epochs?