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

Updating MintRatio can lead to out of sync reward values #937

Closed
c4-bot-3 opened this issue Dec 28, 2023 · 9 comments
Closed

Updating MintRatio can lead to out of sync reward values #937

c4-bot-3 opened this issue Dec 28, 2023 · 9 comments
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-c primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@c4-bot-3
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/loan/SurplusGuildMinter.sol#L293-L315
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/loan/SurplusGuildMinter.sol#L250-L251

Vulnerability details

Impact

When the governor updates the mintRatio, all the users who stake are not required to call updateMintRatio This can result in lost rewards for users.

Proof of Concept

The following code can be added to the SurplusGuildMinterUnitTest.sol

struct UserStake {
    uint48 stakeTime;
    uint48 lastGaugeLoss;
    uint160 profitIndex;
    uint128 credit;
    uint128 guild;
}
function test_unstakeUpdateMintRatio() public {
    credit.mint(alice, 100e18);
    credit.mint(bob, 100e18);

    assertEq(sgm.mintRatio(), MINT_RATIO); // 1:2

    vm.startPrank(alice);
    credit.approve(address(sgm), 100e18);
    sgm.stake(term, 100e18);
    vm.stopPrank();

    UserStake memory userStakeBefore = sgm.getUserStake(alice, term);
    asserEq(userStakeBefore.credit, 100e18);
    asserEq(userStakeBefore.guild, 200e18);

    vm.prank(governor);
    sgm.setMintRatio(MINT_RATIO * 2); // 1:4

    // still the same after update
    asserEq(userStakeBefore.credit, 100e18);
    asserEq(userStakeBefore.guild, 200e18);

    // update Ratio for user
    sgm.updateMintRatio(alice, term); // double alice's stake

    // guild amount in user Stake would have been changed.
    UserStake memory userStakeAfter = sgm.getUserStake(alice, term);
    asserEq(userStakeBefore.credit, 100e18);
    asserEq(userStakeBefore.guild, 400e18);

    // when the stake would have rewards
    // without updating mint ratio for user:
    // uint256 creditReward = (uint256(200e18) * 0.2e18) / 1e18;
    // uint256 guildReward = (40e18 * 5e18) / 1e18;
			// creditReward would be: 40e18
    // guildReward would be: 200e18

    // when updateMintRatio would be required when mintUpdate change
    // this would result in higher rewards for user:
    // uint256 creditReward = (uint256(400e18) * 0.2e18) / 1e18;
    // uint256 guildReward = (80e18 * 5e18) / 1e18;
			// creditReward would be: 80e18
    // guildReward would be: 400e18
}

Tools Used

Foundry

Recommended Mitigation Steps

Add a modifier to the getRewards can help fix this issue. This way when the user is calling getRewards and the mintRatio has changed, the user will get updated rewards based on the mintRatio

modifier syncMintRatio(address user, address term) {
    updateMintRatio(user, term)
    _;
}

function getRewards(
  address user,
  address term
) public
+ syncMintRatio(user, term)
returns (
  uint256 lastGaugeLoss, // GuildToken.lastGaugeLoss(term)
  UserStake memory userStake, // stake state after execution of getRewards()
  bool slashed // true if the user has been slashed
) {
	// get rewards logic
}

Assessed type

Timing

@c4-bot-3 c4-bot-3 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Dec 28, 2023
c4-bot-3 added a commit that referenced this issue Dec 28, 2023
@c4-pre-sort
Copy link

0xSorryNotSorry marked the issue as sufficient quality report

@c4-pre-sort c4-pre-sort added the sufficient quality report This report is of sufficient quality label Jan 2, 2024
@c4-pre-sort
Copy link

0xSorryNotSorry marked the issue as primary issue

@eswak
Copy link

eswak commented Jan 18, 2024

Somewhat similar to #1026 so I'm going to comment something along the same lines :

Acknowledging this, disagree with severity (imo it's informational).

This is the expected behavior, users are supposed to check each other and if the mintRatio go down, updateMintRatio of others so that they are not earning more rewards unduly. And if mintRatio is going up, users are expected to update their position to benefit from the new ratio. Ultimately the governance is a game of who has relatively more tokens, so the users act as keepers to each other to make sure no undue rewards are earned, and individually they are expected to do the actions needed to maximize their rewards.

@c4-sponsor
Copy link

eswak (sponsor) acknowledged

@c4-sponsor c4-sponsor added the sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons label Jan 18, 2024
@c4-sponsor
Copy link

eswak marked the issue as disagree with severity

@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jan 18, 2024
@c4-judge
Copy link
Contributor

Trumpero changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Jan 29, 2024
@c4-judge
Copy link
Contributor

Trumpero marked the issue as grade-a

@Trumpero
Copy link

considering this issue as informational based on the sponsor's comment

@c4-judge
Copy link
Contributor

Trumpero marked the issue as grade-c

@c4-judge c4-judge added grade-c unsatisfactory does not satisfy C4 submission criteria; not eligible for awards and removed grade-a labels Jan 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) downgraded by judge Judge downgraded the risk level of this issue grade-c primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

6 participants