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

fix(StakeManager): use mul by PRECISION and div back later to avoid precision loss in int divisions #67

Closed
wants to merge 4 commits into from

Conversation

3esmit
Copy link
Collaborator

@3esmit 3esmit commented Feb 24, 2024

Description

Alternative to #66;
This PR fixes #64 and fixes #24, uses a more simple solution than #66.

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 fx(StakeManager): use mul by PRECISION and div back later to avoid precision loss in int divisions fix(StakeManager): use mul by PRECISION and div back later to avoid precision loss in int divisions Feb 24, 2024
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.

This is great work @3esmit !

I've left some comments inline. Generally the changes look good to me

@@ -324,8 +326,8 @@ contract StakeManager is Ownable {
//mint multiplier points to that epoch
_mintMP(account, iEpoch.startTime + EPOCH_SIZE, iEpoch);
uint256 userSupply = account.balance + account.currentMP;
uint256 userShare = userSupply / iEpoch.totalSupply; //TODO: fix precision loss;
uint256 userEpochReward = userShare * iEpoch.epochReward;
uint256 userShare = (userSupply * PRECISION) / iEpoch.totalSupply; //TODO: fix precision loss;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe we can now remove the TODO: comments no?

userVault.stake(stakeAmount, 0);

assertEq(stakeManager.totalSupplyMP(), stakeAmount);
for (uint256 i = 0; i < 53; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just cosmetics, but 53 here is somewhat of an arbitrary number. Would be better to give some semantic meaning using a variable or constant or something like that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

53 is to complete a year. 53 weeks gives roughly 1 year.

console.log("# START EPOCH", stakeManager.currentEpoch());
console.log("# PND_REWARDS", stakeManager.pendingReward());

for (uint256 i = 0; i < 3; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
for (uint256 i = 0; i < 3; i++) {
for (uint256 i = 0; i < userVaults.length; i++) {

Copy link
Collaborator

Choose a reason for hiding this comment

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

I just realized i isn't used anywhere, so I'm not sure this actually implied userVaults.length, since you're also using userVaults.length in the inner loop.

Is there any particular reason this is supposed to loop 3 times? If yes, can we add this via some constant or variable, so this isn't getting as confusing in the future?

assertEq(lastMint, lastMintBefore + stakeManager.EPOCH_SIZE(), "must increaase lastMint");
assertEq(epoch, epochBefore + 1, "must increase epoch");
assertGt(currentMP, currentMPBefore, "must increase MPs");
assertGt(rewards, rewardsBefore, "must increase rewards");
Copy link
Collaborator

Choose a reason for hiding this comment

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

These are great.

I wonder if we can make these assertions stronger.
Do you think it's feasible to also assert by how much MPs and rewards increase?

Or maybe a rough ballpark, so that one can say "it must increase by at least this amount" ?

@3esmit 3esmit closed this Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix division precision loss Fix Floating-Point Number Calculations in Contract
2 participants