EGP-23: Convert timestamps to blocknumbers in Deployed Vesting Vault
EGP#: 23
Title: Convert timestamps to blocknumbers in Deployed Vesting Vault
Author(s): Type: Protocol Proposal
Status: Proposed
Date Proposed:
References
Sentence Summary
This EGP is being proposed to fix an identified bug within the deployed Vesting Vault Contract regarding the token grant configurations for core contributors, advisors, and investors. The underlying smart contract is working as expected.
Paragraph Summary
It was identified that the grants in the Vesting vault contract were misconfigured during deployment last March 31, 2022. The time in which the grants will start vesting was set up using Unix time stamps in seconds instead of block numbers. The contract expects block numbers as the threshold when funds will start dispersing. The difference between block numbers and time stamps is on an order of magnitude. This has caused all grants to not start until the year ~2630.
The purpose of this proposal is to rectify this issue by upgrading the smart contract to check for block numbers instead of timestamps.
Motivation
The purpose of this EGP is to implement a solution to resolve the identified bug in the Vesting vault smart contract and ensure that the previously allocated token grants are disbursed as originally intended.
Important note: Neither Element Finance, Inc. nor Element Finance Team members will vote on this proposal. Furthermore, Element engineers will provide purely technical comments only; they will not provide any statements on the wisdom or appropriateness of the proposal.
Specification
The VestingVault has an error that prevents an internal method, _getWithdrawableAmount(), from properly calculating how much of a grant is withdrawable. Essentially, the method verifies several things to calculate how much of a grant is withdrawable:
- the grant is past its creation date.
- the grant is past its cliff date.
- the grant is past its maturation date.
If 1 or 2 are not true, then none of the grant is withdrawable. If 3 is true, then the full amount is withdrawable. If none are true, an amount is withdrawable according to a linear vesting schedule.
The error is in the checks for 1,2,3 in that the method is expecting to compare block number values. However, the grants were created with timestamp values in seconds.
For example, grants were initially created with a cliff at timestamp 1680307199, (January 18th, 2023). As of 1/17/2023, block numbers are about 16436456. If we perform a check to see if the grant has reached its cliff yet we get the following comparison:
// determine if a grant has past itโs cliff block.number < grant.cliff // 16,436,456 < 1,680,307,199
Using this formula, at the current 12/block rate, the affected grants would not reach their respective cliffs for more than 600 years.
There are two ways to solve this issue:
- Update the grant values to use block numbers instead of timestamps
- Update the proxy implementation of the vesting vault
The former is less intrusive, requires no code change, and is therefore more secure.
Proposed Code
As a part of this proposal, a smart contract will be used to perform the necessary modifications to existing grants. This contract can be viewed here: https://github.com/sentilesdal/council/contracts/vaults/UnfrozenVestingVault.sol
Only the method that will be called is updateTimeStampsToBlocks().
The scripts in the above-mentioned repository will be used to deploy the upgraded smart contract, and create and execute the proposal.
The basic idea of the proposal is that, from the Timelock contract, the following three actions will be performed on the VestingVault:
- Upgrade the proxy implementation of the VestingVault.
- Update
cliff,expiration,createdvalues from timestamps to blocks on all grants. - Reset the proxy implementation of the VestingVault.
You can see the proposed values below for the creation of the proposal, assuming that the proposer uses only the locking vault to satisfy the minimum voting power threshold to create the proposal.
proposalId 4 votingVaults [ โ0x02Bd4A3b1b95b01F2Aa61655415A5d3EAAcaafdDโ ] extraVaultData [ โ0x00โ ] targets [ โ0x81758f3361A769016eae4844072FA6d7f828a651โ ] callDatas [ โ0x88b49b839f5625fb4d46602b47319aa61d1f024847d4e2044dde509ce44bf9eda62348cfโ ] proposalHash โ0x5b51929a3bacb941550cff14749ddeaf6fd7c059119ed0bda1c3becf1007ceb7โ, targetsTimeLock [ โ0x6De73946eab234F1EE61256F10067D713aF0e37Aโ, โ0x6De73946eab234F1EE61256F10067D713aF0e37Aโ, โ0x6De73946eab234F1EE61256F10067D713aF0e37Aโ ] calldatasTimeLock [ โ0x74474d280000000000000000000000007e6c3b228249f24bd3eccd88c97e0bdcfc20fb07โ, โ0xd80b15de0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000102acd6000000000000000000000000000000000000000000000000000000000102acd600000000000000000000000000000000000000000000000000000000015284fa000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000084ad922d23a7613e0d25f36cb65cd5f92a1551100000000000000000000000006aee0fa845ce45fb0ea2d753dedd591c8fe9ebae00000000000000000000000066cc30605d94c8d65c239b6a77002028096522ab00000000000000000000000022af075a70b9418d54e5c121419775fcd3842454000000000000000000000000b16c68f45bbd172341f20686203e829d4b80cd910000000000000000000000004103672489e420076b012dda2ba2b0c414d985ca000000000000000000000000561c1693fd7c874763f99d0f456c0d2353c85e26000000000000000000000000b0ad0eea2061d1b699e6c0d353fdee59f40262bb0000000000000000000000007c9c99a9c0bb31c054de1bd9af546db10e35785b0000000000000000000000003a543655e484d9ad9ada138170254f5880b695ce000000000000000000000000fb18b8f2bbe88c4c29ca5a12ee404db4d640fe4e00000000000000000000000020a690167060542efff10a947958286c31c7ff410000000000000000000000002592998309c9a89d9eaaf7cf7cfa94db8ba8770300000000000000000000000092634743b32a997571efdb6e536c65996a80fedf0000000000000000000000002dc2c7337da8adb2721cdde2eb91d922d4587489000000000000000000000000e68e82c3c49df3d9c8b04b0bb8e5f1cdc28dae520000000000000000000000009814ca52e5235e9ea7709475893645bed9a9cf43000000000000000000000000b603613b9e3f76ab26ce2a259f1db8ea5e9dc59500000000000000000000000046aa35190959c7a639ada37a99068b6740a0a5ed000000000000000000000000fb0e31b422e606ca996e4415243ebf15c2e5535e00000000000000000000000090e5aa59a9df2add394df81521dbbed5f3c4a1a3000000000000000000000000c6ff0793171062024e1ff7817fb88bb94e1819b70000000000000000000000003c66617410485a05793b4d73b3ddc9702c814ff0000000000000000000000000a79c60f776a25021c22c389b36f3a31b6b5b640600000000000000000000000008627fcb1edd7006b9f71fbd5b0ec91b4d8dd50a0000000000000000000000008883a2622a04b957fd49baa977024c08742cb50c00000000000000000000000075e71d75ad7c07d3a54f00036fc5d84788022ca900000000000000000000000047ac89694a89be0af1a2d6b34ce127a1247152230000000000000000000000000f0f1c7cb8435fbdb814621017d7676d3d744cf6000000000000000000000000ba62112c08c0c41250fe2d536f7575020f27d8fe0000000000000000000000007ccce39f0ce2ac030ab4571852a225065d90eb1d000000000000000000000000d3ff56d0f96c94b70bbdf4c3f9855f28a2b0e407000000000000000000000000548d993bdda290c1933c472ec1901f5d2f4b9e040000000000000000000000002286bb67635eb57e4c5176a2957103bdb067aba8000000000000000000000000f4ec9254200d67d2c9ddb73a90e2f5e05676c51700000000000000000000000031422aef08dc2d9b8f09ce203990574f2064a3f3000000000000000000000000d1cd9f81b0c7cde872215d27dab34e5d1ed1fec5000000000000000000000000475d753441ee9b4143917c21e2b74416162ae05300000000000000000000000089440fba621a627420450b06a6a68281c62255ae0000000000000000000000009adbbb05cd4f1cd5288564bd192e73499bc246cd000000000000000000000000a399882c11d3cfa62dbc4d66eaf41a943b29cd3b00000000000000000000000082261c297f24a8c89d6c9877297f4e2706c18a550000000000000000000000001d4296c4f14cc5edceb206f7634ae05c3bfc3cb7000000000000000000000000e07c444a769b735cc84875f1ee67e8ba54393014000000000000000000000000f7d74a3e2295a860cdd88b901940b367737e8a8f00000000000000000000000058e2facfd11c74932d838418785aa4ba36dc33bc000000000000000000000000114b8d7ab033e650003fa3fc72c5ba2d0fd183450000000000000000000000000fc7148e78dd0cf135b9127d48dc91c0e898f4a9000000000000000000000000f5fb27b912d987b5b6e02a1b1be0c1f0740e2c6f0000000000000000000000003f433647318b3f704bc4a4125c9c59d69fa12bfc000000000000000000000000db0c22361afa298a01bc83b6535c6fe70fba339800000000000000000000000009aa3c7cbf9c0c3ea9b1beb6ebe97d36dca8c6c10000000000000000000000000f89d54b02ca570de82f770d33c7b7cf7b3c339400000000000000000000000042f9134e9d3bf7eee1f8a5ac2a4328b059e7468c000000000000000000000000c5614f397051e6db3bfabf9813c6c9b57f23278300000000000000000000000055411a197155108641df947b745916787439368e0000000000000000000000004a7c6899cdcb379e284fbfd045462e751da4c7ce0000000000000000000000000f7573549f837fbfb06e71b372ea3d457844e48100000000000000000000000024b8b6e21e0ee7cae674a64983d3d03997007faa0000000000000000000000003a38865b3c9d87d96bfd4ba75e88326b8ff5b522000000000000000000000000e016ec54349e1fdc09c86878f25760ed317a79110000000000000000000000004d4f85480b6d75799dc5daa7b9029b9684c1c5fc000000000000000000000000d352d9ecab5114d617cab778f4b28cfcec3988ea000000000000000000000000da46892a65820d354d670e3666528595ba03025d000000000000000000000000fe78fa483daba058c02db8506636bf247773d605000000000000000000000000554c5af96e9e3c05aec01ce18221d0dd25975ab4000000000000000000000000f5dc9a96cd6695a5760d63dc6b4c91a8a8abc1fc000000000000000000000000dbbb1bd4cbda95dd2f1477be139c3d6cb9d2b3490000000000000000000000005a9b2c31877997da49e99e6143cddaa33e4c6820000000000000000000000000ad3bbda40d6bf9ce9488a08ea478081110a6ac43000000000000000000000000e094a22330b1eb7d69bb6342a63c59c07c1a5b4c000000000000000000000000bba4c8eb57df16c4cfabe4e9a3ab697a3e0c65d8000000000000000000000000cf0fb739fb119b4e41e872a2a1223832900f0361000000000000000000000000a5d50703dab1438a241bdd8ced7bfe7df578f9d50000000000000000000000005f43cd8b5eead549de4444a644b4cb425a4ea5b20000000000000000000000000907742ce0a894b6a5d70e9df2c8d2fadcaf4039000000000000000000000000828b1443f0bf41ca4bf9e211c984bfcd99508445โ, โ0x74474d28000000000000000000000000716d4e863536ac862ad34bc4ecacba07d8831beaโ ] callHashTimelock โ0x5e0acb09d9e0c73d86ff0e45c7d72287d5433cfd815ffae42c0a80ef368e26a0โ lastCall 16549454 ballot 0
Test Cases
The code will be dry-run using Ethereum mainnet forks. Values will be inspected to make sure that they make sense and yield the intended results.
The following should be true BEFORE the proposal is executed:
- All the targeted grants have the same start, cliff and expiration times.
- All targeted grants have a start and cliff timestamp of
1680307199s, 31 Mar 2023 23:59:59 GMT. - All targeted grants have an expiration timestamp of
1743465599s, 31 Mar 2025 23:59:59 GMT.
The following should be true AFTER the proposal is executed:
- All the targeted grants have the same start, cliff, and expiration times.
- All targeted grants have a start and cliff block number of
16952534+/- 1 block. - This is approximately Fri, 31 Mar 2023 23:59:59 GMT at 12.07s/block.
- All targeted grants have an expiration block number of
22185210+/- 1 block. - This is approximately Mon, 31 Mar 2025 23:59:59 GMT at 12.07s/block.
- NO other values should change.
Security Considerations
- There are several security considerations with this proposal. Most importantly, this proposal will make changes to existing token grants and is therefore very sensitive. Extra care should be taken to make sure that updated values in the created proposal align with intentions.
- The other security concern is with the contract used to perform the modifications to the grant. This contract should go under audit and review to ensure that it only performs the desired changes to the contract and has no unintended consequences.
Technical Review Plan or Audit Information (If already available)
The code for this proposal is publicly available for the community to review at https://github.com/sentilesdal/council. Engineers at Element Finance have conducted internal reviews of both the smart contract updates and the code used to generate the proposal. After the proposal is made public, there should be ample time to allow the community to audit the code.
Next Steps (Voting Outcome Summary)
- This proposal is currently a
Draft. - We welcome all questions and comments over the next week, but please be advised that Element Team Members will not be able to provide comments beyond formatting and technical commentary.
- Once the feedback has been addressed, this will move to be officially Proposed.
- Once Proposed, there will be a 1 week review period before it moves to the next stage, Off-Chain Poll (Snapshot).
- On Snapshot, the governance community will vote for:
- Yes: You agree that the vesting vault bug fix should be implemented.
- No: You disagree that the vesting vault bug fix should be implemented.
- Abstain: formally decline to vote either YES or NO.
- If this proposal passes the Off-Chain Poll, it will proceed to the On-chain Vote, where the vote options will remain the same as on Snapshot.
- If this proposal passes, the proposal will officially be Accepted and the code will proceed to the Execution stage where the vesting vault bug fix will be implemented.
| Voter | Cast Power | Vote & Rationale |
|---|---|---|
StableNode | 372,809 | Yes |
0x54Be...2A7Ab6 | 292,932 | Yes |
0x9F85...285a68 | 247,344 | Yes |
0xcAb6...Dda130 | 230,089 | Yes |
elbagococina.eth | 219,401 | Yes |
VOTE POWER
Proposal Status
- Tue February 21 2023, 03:00 pmVoting Period Starts
- Sun February 26 2023, 03:00 pmEnd Voting Period
Current Results
1-Yes
1.652M
2-Abstain
204.633
