Open TakaYuPP opened 2 months ago
@TakaYuPP We will have a few more reviewers, please add a bit PR description about this contract so they can catchup faster. Please also add some example about 2 main functions lock and unlock
@philippwerner @cyber-pc please review this when you are available
@TakaYuPP I'm doing my review now. Can you please merge the current qubic:develop branch into this? For the next PR, please create a separate branch (don't commit to develop).
@TakaYuPP I'm doing my review now. Can you please merge the current qubic:develop branch into this? For the next PR, please create a separate branch (don't commit to develop).
Thank you for reviewing my PR. I merged the current qubic:develop branch into this.
Here is my fix: qearn_bugfix.patch
You can apply it to your repo with git apply
.
Sorry, I did some changes in a prior commit, causing the patch not to apply. This should work: qearn_bugfix.patch
I have massively extended the gtests in Branch to check and understand the code, see the branch feature/2024-10-14-qearn-test
. The contract now seems to be working the way I understand the concept of QEARN. So, the only must-have change required before merging is to adjust the initial epoch.
To be honest, the code is still very hard to read: naming of variables and functions could be improved, names do not follow a common scheme (Infor vs Info, with vs without underscore, use of capital letters, use of abreviations), there is some unneccessary code duplication, code formatting is bad at many places.
I strongly recommend to improve your coding style, @TakaYuPP , at least in future projects. Some hints:
I have massively extended the gtests in Branch to check and understand the code, see the branch
feature/2024-10-14-qearn-test
. The contract now seems to be working the way I understand the concept of QEARN. So, the only must-have change required before merging is to adjust the initial epoch.To be honest, the code is still very hard to read: naming of variables and functions could be improved, names do not follow a common scheme (Infor vs Info, with vs without underscore, use of capital letters, use of abreviations), there is some unneccessary code duplication, code formatting is bad at many places.
I strongly recommend to improve your coding style, @TakaYuPP , at least in future projects. Some hints:
- Be consistent. If you do something a certain way, do all similar things in the same way.
- Choose descriptive and unambiguous names.
- Avoid code duplication by storing values in variables and by moving repleated code into functions.
Thank you a lot for your review. I will refer your advice for future projects. Thank you so much again!
This is the PR for smart contract of Qearn project. Qearn is staking project.
The summary of the idea for Qearn.
The basic idea is to allocate some percentage of current emissions for a staking pool, eg. 100B per week. The goal is to reduce the circulating supply while at the same time providing risk free yield to those that are willing to lock their QU. each week 100B QU will become available for a 52 week locking bonus. Everybody that locks their QU for 52 weeks and does not unlock will share proportionally in the 100B QU bonus, adjusted by the unlocking penalty that will be used to burn, reward those that do not unlock and partly back to the unlocker.
For example, if 800B are locked in a week and all 800B stays locked for full 52 weeks, they will share the 100B for a 12.5% yield. Immediately after the locking is done everybody will know that at least 12.5% will be earned.
Let us continue with the above example and say that over the 52 weeks 300B get unlocked, which would boost the yield from 12.5% to 20%! if the average unlock time was 25 weeks for the 300B, then 25% of what 300B/800B would have earned would be burned over the 52 weeks. 9.375B burned. so the remaining 500B would split 91.625B for a yield of 18.325%.
To prevent spam attack we will probably need a minimum locking of 10M QU
The algorithm for smart contract https://docs.google.com/document/d/1HnhBYs9m6UmgbhHmlKW4kPld-T3cF3vBc0nTtVGnp-A/edit?usp=sharing I wrote the above document to make it easier for reviewers to understand.
The example for main functions(Lock, Unlock).
Let's assume the anyone locks the 1B qu at epoch 200. The _InitialRoundInfo, _CurrentRoundInfo will save the info(total locked amount and total bonus amount at any epoch) for the Round. For example, state._InitialRoundInfo.get(200)._Total_Locked_Amount should be the total amount locked by users at epoch 200. In above example, this amount should be increased as 1B. state._InitialRoundInfo.get(200)._Epoch_Bonus_Amount should be the bonus amount of epoch 200. e.g. (100B) The frontend can ask this entity via GetLockInforPerEpoch function.
I saved the info(user Id, locked epoch, locked amount) for user on array Locker. In above example, state.Locker.get(100)._Locked_Amount should be 1B. state.Locker.get(100)._Locked_Epoch = 200. state.Locker.get(100).ID = user_id. the 100 means the identity of user in the array Locker. I have wrote the above doc to make it easier for reviewers to understand about the algorithm for smart contract. please check the doc.
Users can unlock the partially. Let's continue with the above example and user unlocks the 100M qu at epoch 230. at this time, the full locked weeks should be 29. (230 - 200 - 1 = 29) state._InitialRoundInfo.get(200)._Total_Locked_Amount and state.Locker.get(100)._Locked_Amount should be decreased as 100M. user will get the 100M + bonus amount(30% calculated by below table). also the bonus amount and burn amount will be calculated by the reward table as following. state._InitialRoundInfo.get(200)._Epoch_Bonus_Amount should be decreased as bonus amount 30% + burn amount 35%.