Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Initial Multiplier Logic #52

Closed
wants to merge 6 commits into from
Closed

Refactor Initial Multiplier Logic #52

wants to merge 6 commits into from

Conversation

3esmit
Copy link
Collaborator

@3esmit 3esmit commented Feb 18, 2024

Description

  • Renames fields to more descritive variable names:
    • Account.multiplier -> Account.currentMP
    • multiplierSupply -> totalSupplyMP
    • stakeSupply -> totalSupplyBalance
  • New field:
    • Account.initialMP: used for saving how much of currentMP was generated for bonusMP (can be renamed to bonusMP), retrieved when checking if MAX_BOOST is reached.
  • processEpoch is now called at first of every external function that would need it, as a modifier.
  • Accounts are properly initialized at first stake (Fixes Properly initialize genesis epoch for account #49)
  • It's not possible anymore to unstake only a part of funds, or unstake all, or nothing.
  • Fix in migration of processAccount, send only the difference of generated MP to new contract.
  • Now with code reuse for math formulas
  • Mint Intial (Bonus) MPs now use the same formula as the regular multiplier points, but deltaTime is lockedTime.
  • Fixed the Lock and Mint function about locked funds. Now it mints correctly for increased time locked, and increased balance in remaining time locked. Fixes When stake unlocked, increasing stake and locking using stake() mints bonus MPs only for this increment #13
  • Changed how lock function works: Now lock time can only increase (previously it reverted), now the parameter value represents time increased, and therefore this case does not exist anymore.

Checklist

Ensure you completed all of the steps below before submitting your pull request:

  • Added natspec comments?
  • Ran forge snapshot?
  • Ran pnpm lint?
  • Ran forge test?
  • Ran pnpm verify?

@3esmit 3esmit changed the title 3esmit/issue51 Refactor Initial Multiplier Logic Feb 18, 2024
@3esmit 3esmit self-assigned this Feb 19, 2024
@3esmit 3esmit linked an issue Feb 19, 2024 that may be closed by this pull request
@3esmit 3esmit added this to the Staking V1 milestone Feb 19, 2024
@3esmit 3esmit added type: bug Something isn't working type: refactor labels Feb 19, 2024
@0x-r4bbit
Copy link
Collaborator

@3esmit this looks like this needs to be rebased on top of #47

Also, for future PRs please select a reviewer so someone gets notified about it :)

@0x-r4bbit
Copy link
Collaborator

0x-r4bbit commented Feb 20, 2024

@3esmit I've merged #53 and #59 as discussed offline so you can rebase this PR on top of it (now latest develop)

Once done I will review your changes.
You might want to squash your commits into f476860 as we don't need the fix test, fix lint etc commits individually.

Let me know if you need any help with this!

@3esmit 3esmit force-pushed the 3esmit/issue51 branch 2 times, most recently from 5731477 to e76b17c Compare February 20, 2024 14:21
Copy link
Collaborator

@0x-r4bbit 0x-r4bbit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice changes @3esmit !

As mentioned offline, i'd like to see some tests on this that show MPs are calculated properly.

@mart1n-xyz would you be able to give us some numbers for 2-3 scenarios (with lockup time, without lockup time, different amount of epochs etc) ?

We can then create tests in which we put in these numbers and see if the code behaves as expected.

contracts/StakeManager.sol Show resolved Hide resolved
contracts/StakeManager.sol Show resolved Hide resolved
*/
function unstake(uint256 _amount) external onlyVault noMigration {
function unstake() external onlyVault noMigration processEpoch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we no longer allow for unstaking less than current stake amount?

@mart1n-xyz Double checking: is this desired?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed because this function would give too much losses to user. It could be reimplemented if needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to allow partial unstaking (with proportional slashing of MPs).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we would have to define how thats calculated.

Currently it would work like that:

initial MP (bonus): reduce on 20% of balance, reduce 20% of initial MP.
current MP: reduce on 20% of balance, reduce 20% of current MP.

This might not be the most precise way to go for it, and we would have to consider if this causes other issues.

contracts/StakeManager.sol Show resolved Hide resolved
contracts/StakeManager.sol Outdated Show resolved Hide resolved
contracts/StakeManager.sol Outdated Show resolved Hide resolved
contracts/StakeManager.sol Show resolved Hide resolved
@3esmit
Copy link
Collaborator Author

3esmit commented Feb 21, 2024

Tests to be written:

  • tests for process epoch:
    • should update pending rewards
    • should update total supply
    • should update total supply multiplier points
    • should increase epoch
  • tests for process account:
    • should update user multiplier points
    • should update user epoch
    • should pay user proportional rewards
  • tests for stake
    • should update user lockup time
    • should mint bonus multiplier points
    • should update bonus multiplier points (restake)
    • should update total supply multiplier points
    • should update total supply balance
    • should update total supply
  • tests for lock
    • should update user lockup time
    • should update bonus multiplier points
    • should update total supply multiplier points
  • tests for unstake
    • should burn multiplier points
    • should update total supply multiplier points
    • should update total supply balance
    • should update total supply

@mart1n-xyz
Copy link
Collaborator

mart1n-xyz commented Feb 21, 2024

Here's the cases we were simulating.
Case 1 may be interesting as it compares a user with a lock-up and without. I would suggest trying to replicate these parameters for a start.
Case 2 deals with restaking - not yet applicable
Case 3 might be again interesting as one of the 2 users joins a year later.
Case 4&5 are just scaling this to more users and doing stochastic behaviour.

if (_time > MAX_LOCKUP_PERIOD) {
revert StakeManager__InvalidLockupPeriod();
}
Account storage account = accounts[msg.sender];
processAccount(account, currentEpoch);
if (account.lockUntil + _time < block.timestamp) {
revert StakeManager__InvalidLockTime();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So one thing I've realised, is that I keep confusing lockUntil with locktime.
The former is a threshold, the latter is a period.

If we treat _time as something that can only be added to the existing lockUntil, then maybe we can consider renaming lock() to increaseLockTime() ?

Not something that has to happen in this commit/PR, but maybe something to consider in the future.

I always thought lock() would allow me to set my lockup time (say, from 2 years, to 4 years)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that can be renamed like that to avoid confusions on development and audits.

Anyway, the UX would have to solve that for the user, no matter how its named or how the interface behaves.

@0x-r4bbit
Copy link
Collaborator

Thanks for the updates!

Let's add some tests related to the multiplier/reward calculation, then I think this is good to go.

We can then add all the other tests you've mentioned in your comment in a follow-up PR

@3esmit
Copy link
Collaborator Author

3esmit commented Feb 21, 2024

As I am writing tests I am finding other bugs, so I guess this will be a mega PR fixing many bugs.

@0x-r4bbit
Copy link
Collaborator

@3esmit I think it's fine if these are part of the refactor changes you've made.

If not, I think it'd be better if we isolate the changes made in this PR so it closes the 1-2 issues it was supposed to close.
Then, additional bugs you encounter, unrelated to the refactor changes can be tracked in additional issues and then tackled one by one.

Sometimes it can't be avoided, but we should strive for keep PRs as small as possible

@3esmit 3esmit closed this Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working type: refactor
Projects
None yet
3 participants