threshold-network / solidity-contracts

38 stars 18 forks source link

Drop support for legacy KEEP stakes #141

Closed pdyraga closed 3 months ago

pdyraga commented 1 year ago

Goal

KEEP x NU merge proposal requirement was to keep support for legacy KEEP and NU stakes so that no one was left behind. Threshold TokenStaking contract has respected this requirement since the very first version deployed in Feb 2022. Unfortunately, this code has a lot of complexity and is often holding us back.

This issue aims at eliminating KEEP legacy stake support without leaving any stakers without rewards they are eligible for.

The current state

@r-czajkowski prepared a script checking how many legacy KEEP stakers are in the Threshold Staking contract.

There are 30 legacy KEEP stakes.

8 of them have total stake amount in T equal to 0 and all of them have already undelegated their stakes in KEEP token staking contract. Here are the 8 staking providers:

0x2BAF3650263348f3304c18900A674bB0BF830801 (undelegated and recovered),
0xF2f5E0a3365c385A3ADCA4F614eD0984dFff52a3 (undelegated),
0x4F4f0D0dfd93513B3f4Cb116Fe9d0A005466F725 (undelegated),
0xc5795fa1EADF77FCDa0C6D9F9B340D634C2ba546 (undelegated),
0x9767795d399E86fCc0F600dB6F302F5C0692e0cF (undelegated),
0x6dAfE16b14c95eB99c64e8d4E5435F7574B2825c (undelegated and recovered),
0xe3a2d16dA142E6B190A5d9F7e0C07cc460B58A5F (undelegated and recovered),
0x4c21541f95a00C03C75F38C71DC220bd27cbbEd9 (undelegated and recovered)

So we actually have 22 active legacy KEEP stakes in Threshold.

Here is the full list:

┌─────────┬──────────────────────────────────────────────┬──────────────────────────────────────────────┬──────────────────────────────┬──────────────────────────────┐
│ (index) │               stakingProvider                │                    owner                     │         keepInTStake         │         totaStakeInT         │
├─────────┼──────────────────────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│    0    │ '0xDcd4199e22d09248cA2583cBDD2759b2acD22381' │ '0xbd7157F5Beb24525adD6C4c0559C5261b5E16742' │ '1195797157813754000000000'  │ '1195797157813754000000000'  │
│    1    │ '0xfc97a906c715587b56c2c65a07ce731ba80339de' │ '0xbd7157F5Beb24525adD6C4c0559C5261b5E16742' │ '1191970606908749987200000'  │ '1191970606908749987200000'  │
│    2    │ '0x07C9a8f8264221906b7b8958951Ce4753D39628B' │ '0x0FA840c61bEBc545bfEAef45f890fcc84Fddd9D5' │ '2391594315627508000000000'  │ '2630378612917165417743972'  │
│    3    │ '0xd977144724Bc77FaeFAe219F958AE3947205d0b5' │ '0x53d10c2792343966911c849Bc2E80e5938E9069a' │ '12941777815814071690880000' │ '45585860955795009534738650' │
│    4    │ '0x045E511f53DeBF55c9C0B4522f14F602f7C7cA81' │ '0xf7174b1b0c501015Cae751230483f95a7d9D854e' │ '17040803061197526477320000' │ '17040803061197526477320000' │
│    5    │ '0x650A9eD18Df873cad98C88dcaC8170531cAD2399' │ '0x461aa63A98e6f8BdAa19CA3f2258670E794FFF34' │ '30696593541076206533887296' │ '30696593541076206533887296' │
│    6    │ '0x4bFa10B1538E8E765E995688D8EEc39C717B6797' │ '0x85f00Ec494D31409640630644b84ee04844a4658' │ '1516906960195796989128000'  │ '4007348453083680834611080'  │
│    7    │ '0x2eBE08379f4fD866E871A9b9E1d5C695154C6A9F' │ '0x768536f03B64E6903c452514596886305e752589' │ '5847299822861688154504000'  │ '5847299822861688154504000'  │
│    8    │ '0x3B9e5ae72d068448bB96786989c0d86FBC0551D1' │ '0x9eEf87f4C08d8934cB2a3309dF4deC5635338115' │ '2153601982090783423904000'  │ '2153601982090783423904000'  │
│    9    │ '0x06eb8d86cBc1693079D2Ff0fa9cB55A26CD07f15' │ '0x06eb8d86cBc1693079D2Ff0fa9cB55A26CD07f15' │  '132843497855845559368000'  │  '132843497855845559368000'  │
│   10    │ '0x33769235A2980730Ae7E17fc6EaF4740530cde1B' │ '0x33769235A2980730Ae7E17fc6EaF4740530cde1B' │  '112031844121254984752000'  │  '112031844121254984752000'  │
│   11    │ '0x1147ccFB4AEFc6e587a23b78724Ef20Ec6e474D4' │ '0x3FB49dA4375Ef9019f17990D04c6d5daD482D80a' │  '483102051756756616000000'  │  '483102051756756616000000'  │
│   12    │ '0xcBB734bBa70c6462a9F22C2b481346ebEf3CFAd3' │ '0x64C83375e019835433F832C07Fee3c77284654dA' │ '1195797157813754000000000'  │ '1195797157813754000000000'  │
│   13    │ '0x01474098607eD064F72832E1491b2261967166DA' │ '0x01474098607eD064F72832E1491b2261967166DA' │  '71747829468825240000000'   │  '71747829468825240000000'   │
│   14    │ '0x2BAF3650263348f3304c18900A674bB0BF830801' │ '0x773a3210aa5E94bf2d713F67FB99A8e89D0782E2' │             '0'              │             '0'              │
│   15    │ '0xA5f6822ef1A7DF72628259f9D1dc17eb2BCb2385' │ '0x78DC7f84a8DA5C96C4c54DcF5bD6E9ccd4fe2bb5' │ '1147965271501203840000000'  │ '1482565271501203840000000'  │
│   16    │ '0xA4166C3E14cbDd6D4494945A99616f1C73aD9699' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '717478294688252400000000'  │  '717478294688252400000000'  │
│   17    │ '0xaEa619D02dcF7299FB24dB2F60A08BFC8FB2dbcf' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '717478294688252400000000'  │  '717478294688252400000000'  │
│   18    │ '0xca70feA021359778daeC479b97D0cD2eFE1Ad099' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '956637726251003200000000'  │  '956637726251003200000000'  │
│   19    │ '0xF2f5E0a3365c385A3ADCA4F614eD0984dFff52a3' │ '0x537Ab7FeC05f7f6A9323EF1321Ef60927B1Bf826' │             '0'              │             '0'              │
│   20    │ '0x4F4f0D0dfd93513B3f4Cb116Fe9d0A005466F725' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   21    │ '0xc5795fa1EADF77FCDa0C6D9F9B340D634C2ba546' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   22    │ '0x9767795d399E86fCc0F600dB6F302F5C0692e0cF' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   23    │ '0x0Ace6419dbDAb7f9330568258B9dDB37A295b677' │ '0x1E183d6337a8353994Aaf327bE00829990818095' │ '2391594315627508000000000'  │ '7601794315627508000000000'  │
│   24    │ '0xe26E2d93Bbc8fde0e1E3B290Fc927Fb374E7e34e' │ '0xdD08121f4C80182c4748D12140477376324E2c93' │ '3348232041878511200000000'  │ '16869940158913096123035232' │
│   25    │ '0x6dAfE16b14c95eB99c64e8d4E5435F7574B2825c' │ '0x2e6BCE584B7d56eC9A5108Bc552e80F3cBA08A85' │             '0'              │             '0'              │
│   26    │ '0x341154298aB7ca86278DF9665fB2B8610b92214D' │ '0xDAe97c91579891d5bb84aCd5974fFF149777341B' │ '1434956589376504800000000'  │ '1434956589376504800000000'  │
│   27    │ '0x8CC46611beC3217D058D92fD234A8ed7D205e0D2' │ '0x8053aF95c389a1B0C69F37cdCf0D156b34c4D361' │  '765310181000802560000000'  │  '765310181000802560000000'  │
│   28    │ '0xe3a2d16dA142E6B190A5d9F7e0C07cc460B58A5F' │ '0x875f8fFCDDeD63B5d8Cf54be4E4b82FE6c6E249C' │             '0'              │             '0'              │
│   29    │ '0x4c21541f95a00C03C75F38C71DC220bd27cbbEd9' │ '0xC897cfeE43a8d827F76D4226994D5CE5EBBe2571' │             '0'              │             '0'              │
└─────────┴──────────────────────────────────────────────┴──────────────────────────────────────────────┴──────────────────────────────┴──────────────────────────────┘

Proposition

We will execute the script @r-czajkowski prepared one more time to snapshot the addresses of legacy KEEP stakers. We will ensure none of those stakers are tBTC v2 beta stakers.

We will modify the script calculating rewards to have a special path for the addresses from this list: take into account the amount from KeepTokenStaking.getDelegationInfo and the amount staked in T in the Threshold TokenStaking contract instead of looking at the AuthorizedIncreased / AuthorizationDecreased events.

At the same time, we will deploy an update to Threshold TokenStaking contract to drop the support for KEEP legacy stakes and set KEEP legacy stake for those addresses to 0.

We will keep this logic in the reward calculation script for 3 months. tBTC v2 authorization decrease delay is 45 days and KEEP staking undelegation period is 2 months. Given we drop functions like notifyKeepStakeDiscrepancy from Threshold Staking contract, KEEP stakers can undelegate their tokens from KEEP staking contract right away. We will give them one additional month to wrap their KEEP to T and top-up stakes before we remove the special path from the reward calculation script.

This approach allows investing the minimum dev time needed but requires very clear communication and community alignment so that all KEEP legacy stakers understand what is going to happen and what they should do.

Outstanding work

Staking with the legacy KEEP staking contract allows using the entire stakeahead for KEEP grantees. Some grantees may not be able to withdraw liquid tokens. As a result, their stake weight may be lower.

Before moving forward with this proposal we MUST confirm how many stakers from the list stake from grants and what is the remaining vesting time for them. We can bypass the problem by adding a stake weight offset in the reward calculation script until their tokens are vested.

cygnusv commented 10 months ago

We will execute the script @r-czajkowski prepared one more time to snapshot the addresses of legacy KEEP stakers.

Snapshot pulled from Threshold subgraph on November 8th, 2023 by @manumonti. This also include authorization amounts:

It would be interesting to run @r-czajkowski's script too, just in case.

We will ensure none of those stakers are tBTC v2 beta stakers.

Confirmed that no beta staker is a legacy KEEP or NU staker.

We will modify the script calculating rewards to have a special path for the addresses from this list: take into account the amount from KeepTokenStaking.getDelegationInfo and the amount staked in T in the Threshold TokenStaking contract instead of looking at the AuthorizedIncreased / AuthorizationDecreased events.

This is not a blocker for the upgrade and can be done in parallel. Opened https://github.com/threshold-network/merkle-distribution/issues/95 to track this.

At the same time, we will deploy an update to Threshold TokenStaking contract to drop the support for KEEP legacy stakes and set KEEP legacy stake for those addresses to 0.

See #153. Please review ASAP @lukasz-zimnoch @pdyraga

We will keep this logic in the reward calculation script for 3 months. tBTC v2 authorization decrease delay is 45 days and KEEP staking undelegation period is 2 months. Given we drop functions like notifyKeepStakeDiscrepancy from Threshold Staking contract, KEEP stakers can undelegate their tokens from KEEP staking contract right away. We will give them one additional month to wrap their KEEP to T and top-up stakes before we remove the special path from the reward calculation script. This approach allows investing the minimum dev time needed but requires very clear communication and community alignment so that all KEEP legacy stakers understand what is going to happen and what they should do.

cc @manumonti @dimpar @lukasz-zimnoch

Before moving forward with this proposal we MUST confirm how many stakers from the list stake from grants and what is the remaining vesting time for them. We can bypass the problem by adding a stake weight offset in the reward calculation script until their tokens are vested.

KEEP team is better positioned for this @lukasz-zimnoch @pdyraga

lukasz-zimnoch commented 10 months ago

List of legacy KEEP stakes in Threshold pulled using @r-czajkowski script on November 8th:

┌─────────┬──────────────────────────────────────────────┬──────────────────────────────────────────────┬──────────────────────────────┬──────────────────────────────┐
│ (index) │               stakingProvider                │                    owner                     │         keepInTStake         │         totaStakeInT         │
├─────────┼──────────────────────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│    0    │ '0xDcd4199e22d09248cA2583cBDD2759b2acD22381' │ '0xbd7157F5Beb24525adD6C4c0559C5261b5E16742' │ '1195797157813754000000000'  │ '1195797157813754000000000'  │
│    1    │ '0xfc97a906c715587b56c2c65a07ce731ba80339de' │ '0xbd7157F5Beb24525adD6C4c0559C5261b5E16742' │ '1191970606908749987200000'  │ '1191970606908749987200000'  │
│    2    │ '0x07C9a8f8264221906b7b8958951Ce4753D39628B' │ '0x0FA840c61bEBc545bfEAef45f890fcc84Fddd9D5' │ '2391594315627508000000000'  │ '5326848660128994849380158'  │
│    3    │ '0xd977144724Bc77FaeFAe219F958AE3947205d0b5' │ '0x53d10c2792343966911c849Bc2E80e5938E9069a' │ '12941777815814071690880000' │ '45585860955795009534738650' │
│    4    │ '0x045E511f53DeBF55c9C0B4522f14F602f7C7cA81' │ '0xf7174b1b0c501015Cae751230483f95a7d9D854e' │ '17040803061197526477320000' │ '17040803061197526477320000' │
│    5    │ '0x650A9eD18Df873cad98C88dcaC8170531cAD2399' │ '0x461aa63A98e6f8BdAa19CA3f2258670E794FFF34' │ '30696593541076206533887296' │ '30696593541076206533887296' │
│    6    │ '0x4bFa10B1538E8E765E995688D8EEc39C717B6797' │ '0x85f00Ec494D31409640630644b84ee04844a4658' │ '1516906960195796989128000'  │ '4007348453083680834611080'  │
│    7    │ '0x2eBE08379f4fD866E871A9b9E1d5C695154C6A9F' │ '0x768536f03B64E6903c452514596886305e752589' │ '5847299822861688154504000'  │ '5847299822861688154504000'  │
│    8    │ '0x3B9e5ae72d068448bB96786989c0d86FBC0551D1' │ '0x9eEf87f4C08d8934cB2a3309dF4deC5635338115' │ '2153601982090783423904000'  │ '2153601982090783423904000'  │
│    9    │ '0x06eb8d86cBc1693079D2Ff0fa9cB55A26CD07f15' │ '0x06eb8d86cBc1693079D2Ff0fa9cB55A26CD07f15' │  '132843497855845559368000'  │  '132843497855845559368000'  │
│   10    │ '0x33769235A2980730Ae7E17fc6EaF4740530cde1B' │ '0x33769235A2980730Ae7E17fc6EaF4740530cde1B' │  '112031844121254984752000'  │  '112031844121254984752000'  │
│   11    │ '0x1147ccFB4AEFc6e587a23b78724Ef20Ec6e474D4' │ '0x3FB49dA4375Ef9019f17990D04c6d5daD482D80a' │  '483102051756756616000000'  │  '483102051756756616000000'  │
│   12    │ '0xcBB734bBa70c6462a9F22C2b481346ebEf3CFAd3' │ '0x64C83375e019835433F832C07Fee3c77284654dA' │ '1195797157813754000000000'  │ '1195797157813754000000000'  │
│   13    │ '0x01474098607eD064F72832E1491b2261967166DA' │ '0x01474098607eD064F72832E1491b2261967166DA' │  '71747829468825240000000'   │  '71747829468825240000000'   │
│   14    │ '0x2BAF3650263348f3304c18900A674bB0BF830801' │ '0x773a3210aa5E94bf2d713F67FB99A8e89D0782E2' │             '0'              │             '0'              │
│   15    │ '0xA5f6822ef1A7DF72628259f9D1dc17eb2BCb2385' │ '0x78DC7f84a8DA5C96C4c54DcF5bD6E9ccd4fe2bb5' │ '1147965271501203840000000'  │ '1482565271501203840000000'  │
│   16    │ '0xA4166C3E14cbDd6D4494945A99616f1C73aD9699' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '717478294688252400000000'  │  '717478294688252400000000'  │
│   17    │ '0xaEa619D02dcF7299FB24dB2F60A08BFC8FB2dbcf' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '717478294688252400000000'  │  '717478294688252400000000'  │
│   18    │ '0xca70feA021359778daeC479b97D0cD2eFE1Ad099' │ '0xbCdffff120C4e2f1199317A9448e99Eb02771496' │  '956637726251003200000000'  │  '956637726251003200000000'  │
│   19    │ '0xF2f5E0a3365c385A3ADCA4F614eD0984dFff52a3' │ '0x537Ab7FeC05f7f6A9323EF1321Ef60927B1Bf826' │             '0'              │             '0'              │
│   20    │ '0x4F4f0D0dfd93513B3f4Cb116Fe9d0A005466F725' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   21    │ '0xc5795fa1EADF77FCDa0C6D9F9B340D634C2ba546' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   22    │ '0x9767795d399E86fCc0F600dB6F302F5C0692e0cF' │ '0x8b055ac1c4dd287E2a46D4a52d61FE76FB551bD0' │             '0'              │             '0'              │
│   23    │ '0x0Ace6419dbDAb7f9330568258B9dDB37A295b677' │ '0x1E183d6337a8353994Aaf327bE00829990818095' │ '2391594315627508000000000'  │ '7601794315627508000000000'  │
│   24    │ '0xe26E2d93Bbc8fde0e1E3B290Fc927Fb374E7e34e' │ '0xdD08121f4C80182c4748D12140477376324E2c93' │ '3348232041878511200000000'  │ '16869940158913096123035232' │
│   25    │ '0x6dAfE16b14c95eB99c64e8d4E5435F7574B2825c' │ '0x2e6BCE584B7d56eC9A5108Bc552e80F3cBA08A85' │             '0'              │             '0'              │
│   26    │ '0x341154298aB7ca86278DF9665fB2B8610b92214D' │ '0xDAe97c91579891d5bb84aCd5974fFF149777341B' │ '1434956589376504800000000'  │ '1434956589376504800000000'  │
│   27    │ '0x8CC46611beC3217D058D92fD234A8ed7D205e0D2' │ '0x8053aF95c389a1B0C69F37cdCf0D156b34c4D361' │  '765310181000802560000000'  │  '765310181000802560000000'  │
│   28    │ '0xe3a2d16dA142E6B190A5d9F7e0C07cc460B58A5F' │ '0x875f8fFCDDeD63B5d8Cf54be4E4b82FE6c6E249C' │             '0'              │             '0'              │
│   29    │ '0x4c21541f95a00C03C75F38C71DC220bd27cbbEd9' │ '0xC897cfeE43a8d827F76D4226994D5CE5EBBe2571' │             '0'              │             '0'              │
└─────────┴──────────────────────────────────────────────┴──────────────────────────────────────────────┴──────────────────────────────┴──────────────────────────────┘

According to KeepStake contract, the following legacy KEEP stakes come from grants:

stakingProvider                                owner

0x07C9a8f8264221906b7b8958951Ce4753D39628B     0x0FA840c61bEBc545bfEAef45f890fcc84Fddd9D5
0xd977144724Bc77FaeFAe219F958AE3947205d0b5     0x53d10c2792343966911c849Bc2E80e5938E9069a
0x045E511f53DeBF55c9C0B4522f14F602f7C7cA81     0xf7174b1b0c501015Cae751230483f95a7d9D854e
0x650A9eD18Df873cad98C88dcaC8170531cAD2399     0x461aa63A98e6f8BdAa19CA3f2258670E794FFF34
0x2eBE08379f4fD866E871A9b9E1d5C695154C6A9F     0x768536f03B64E6903c452514596886305e752589
0x3B9e5ae72d068448bB96786989c0d86FBC0551D1     0x9eEf87f4C08d8934cB2a3309dF4deC5635338115
0x1147ccFB4AEFc6e587a23b78724Ef20Ec6e474D4     0x3FB49dA4375Ef9019f17990D04c6d5daD482D80a
0xcBB734bBa70c6462a9F22C2b481346ebEf3CFAd3     0x64C83375e019835433F832C07Fee3c77284654dA
0xA5f6822ef1A7DF72628259f9D1dc17eb2BCb2385     0x78DC7f84a8DA5C96C4c54DcF5bD6E9ccd4fe2bb5
0x0Ace6419dbDAb7f9330568258B9dDB37A295b677     0x1E183d6337a8353994Aaf327bE00829990818095

According to AllTheKeeps, only two grants are still vesting (both will complete January 18 2024) and belong to grantees:

Those grants are not on the above list so they are not used to stake KEEP in Threshold. That said, we can assume all legacy KEEP stakes in Threshold come from already vested grants.

cygnusv commented 10 months ago

Updated list (November 21st): https://gist.github.com/manumonti/3d5c82bffd43476838d6093deaa73de7

No changes, but posting here for reference

manumonti commented 3 months ago

This issue was closed with https://github.com/threshold-network/merkle-distribution/pull/138