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

Ironsidesec - Wrong way of rounding when expectedAmounts calculation on withdrawal processing #312

Closed
sherlock-admin2 opened this issue Jun 27, 2024 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin2
Copy link

sherlock-admin2 commented Jun 27, 2024

Ironsidesec

Medium

Wrong way of rounding when expectedAmounts calculation on withdrawal processing

Summary

When expectedAmounts are calculated, the denominator must be rounded up, but here already using rounded down denominator is used in a denominator which will inflate the end value.

Vulnerability Detail

  1. ratiosX96Value in L580 below is calculated with mulDiv which will round down mostly due to volatile prices, and more volatile if underlying tokens > 1.
  2. this ratiosX96Valuev is used to calculate coefficientX96 in denominator on L536 below. So using a rounded down value will inflate the `` value.
  3. This inflated coefficientX96 is used as a numerator on L545 below calculating the expectedAmounts. Which will be inflated and rounding is in favor of a user. So he might get more than he deserves and also this will definitely revert when last withdrawer tries to withdraw his Lp, it might revert.

https://github.com/sherlock-audit/2024-06-mellow/blob/26aa0445ec405a4ad637bddeeedec4efe1eba8d2/mellow-lrt/src/Vault.sol#L476-L534

2024-06-mellow/mellow-lrt/src/Vault.sol


557:     function calculateStack()
561:     {
... SNIP ...
577:         for (uint256 i = 0; i < tokens.length; i++) {
578:             uint256 priceX96 = priceOracle.priceX96(address(this), tokens[i]);
579:             s.totalValue += FullMath.mulDiv(amounts[i], priceX96, Q96); 
580:    >>>      s.ratiosX96Value += FullMath.mulDiv(s.ratiosX96[i], priceX96, Q96); 
581:             s.erc20Balances[i] = IERC20(tokens[i]).balanceOf(address(this));
582:         }
583:     }
584: 


525:     function analyzeRequest(
... SNIP ...
534:         uint256 value = FullMath.mulDiv(lpAmount, s.totalValue, s.totalSupply);
535:         value = FullMath.mulDiv(value, D9 - s.feeD9, D9);
536:   >>>   uint256 coefficientX96 = FullMath.mulDiv(value, Q96, s.ratiosX96Value);

... SNIP ...
541:         for (uint256 i = 0; i < length; i++) {
542:             uint256 ratiosX96 = s.ratiosX96[i];
543:             expectedAmounts[i] = ratiosX96 == 0
544:                 ? 0
545:    >>>          : FullMath.mulDiv(coefficientX96, ratiosX96, Q96);
546:             if (expectedAmounts[i] >= request.minAmounts[i]) continue;
547:             return (false, false, expectedAmounts);
548:         }
... SNIP ...
554:     }
555: 

Impact

Inflated coefficientX96 is used as numerator on L545 calculating the expectedAmounts. Which will be inflated and rounding is in favor of user. So he might get more than he deserves and also this will definitely revert when last withdrawer tries to withdraw his Lp, it might revert.

Code Snippet

https://github.com/sherlock-audit/2024-06-mellow/blob/26aa0445ec405a4ad637bddeeedec4efe1eba8d2/mellow-lrt/src/Vault.sol#L476-L534

https://github.com/sherlock-audit/2024-06-mellow/blob/26aa0445ec405a4ad637bddeeedec4efe1eba8d2/mellow-lrt/src/Vault.sol#L530

Tool used

Manual Review

Recommendation

Use mulDivUp

https://github.com/sherlock-audit/2024-06-mellow/blob/26aa0445ec405a4ad637bddeeedec4efe1eba8d2/mellow-lrt/src/Vault.sol#L530

 function calculateStack()
 public
 view
 returns (ProcessWithdrawalsStack memory s)
 {
... SNIP ...

 IPriceOracle priceOracle = IPriceOracle(configurator.priceOracle());
 for (uint256 i = 0; i < tokens.length; i++) {
 uint256 priceX96 = priceOracle.priceX96(address(this), tokens[i]);
 s.totalValue += FullMath.mulDiv(amounts[i], priceX96, Q96); 
-           s.ratiosX96Value += FullMath.mulDiv(s.ratiosX96[i], priceX96, Q96); 
+           s.ratiosX96Value += FullMath.mulDivUp(s.ratiosX96[i], priceX96, Q96); 
 s.erc20Balances[i] = IERC20(tokens[i]).balanceOf(address(this));
 }
 }

Duplicate of #61

@sherlock-admin4 sherlock-admin4 changed the title Curved Powder Rooster - Lack of Access control for convertAndDeposit Wrong way of rounding when expectedAmounts calculation on withdrawal processing Jun 28, 2024
@sherlock-admin3 sherlock-admin3 added the Sponsor Confirmed The sponsor acknowledged this issue is valid label Jun 30, 2024
@github-actions github-actions bot changed the title Wrong way of rounding when expectedAmounts calculation on withdrawal processing Beautiful Teal Kookaburra - Wrong way of rounding when expectedAmounts calculation on withdrawal processing Jul 6, 2024
@github-actions github-actions bot closed this as completed Jul 6, 2024
@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Jul 6, 2024
@sherlock-admin3 sherlock-admin3 added Will Fix The sponsor confirmed this issue will be fixed and removed Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Jul 8, 2024
@sherlock-admin3 sherlock-admin3 changed the title Beautiful Teal Kookaburra - Wrong way of rounding when expectedAmounts calculation on withdrawal processing Ironsidesec - Wrong way of rounding when expectedAmounts calculation on withdrawal processing Jul 15, 2024
@sherlock-admin3 sherlock-admin3 added the Reward A payout will be made for this issue label Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

2 participants