Skip to content
This repository has been archived by the owner on Dec 10, 2023. It is now read-only.

chaduke - MarketUtils.getFundingAmountPerSizeDelta() has a rounding logical error. #164

Open
sherlock-admin opened this issue Jun 4, 2023 · 9 comments
Labels
Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin
Copy link
Contributor

chaduke

medium

MarketUtils.getFundingAmountPerSizeDelta() has a rounding logical error.

Summary

MarketUtils.getFundingAmountPerSizeDelta() has a rounding logical error. The main problem is the divisor always use a roundupDivision regardless of the input roundUp rounding mode. Actually the correct use should be: the divisor should use the opposite of roundup to achieve the same logic of rounding.

Vulnerability Detail

MarketUtils.getFundingAmountPerSizeDelta() is used to calculate the FundingAmountPerSizeDelta with a roundup input mode parameter.

https://github.com/sherlock-audit/2023-04-gmx/blob/main/gmx-synthetics/contracts/market/MarketUtils.sol#L1126-L1136

This function is used for example by the IncreaseLimit order via flow OrderHandler.executeOrder() -> _executeOrder() -> OrderUtils.executeOrder() -> processOrder() -> IncreaseOrderUtils.processOrder() -> IncreasePositionUtils.increasePosition() -> PositionUtils.updateFundingAndBorrowingState() -> MarketUtils.updateFundingAmoutPerSize() -> getFundingAmountPerSizeDelta().

However, the main problem is the divisor always use a roundupDivision regardless of the input roundUp rounding mode. Actually the correct use should be: the divisor should use the opposite of roundup to achieve the same logic of rounding.

My POC code confirms my finding: given fundingAmount = 2e15, openInterest = 1e15+1, and roundup = true, the correct answer should be: 1999999999999998000000000000001999999999999999. However, the implementation returns the wrong solution of : 1000000000000000000000000000000000000000000000. The reason is that the divisor uses a roundup and gets a divisor of 2, as a result, the final result is actually rounded down rather than rounding up!

function testGetFundingAmountPerSizeDelta() public{
        uint result = MarketUtils.getFundingAmountPerSizeDelta(2e15, 1e15+1, true);
        console2.log("result: %d", result);
        uint256 correctResult = 2e15 * 1e15 * 1e30 + 1e15; // this is a real round up
        correctResult = correctResult/(1e15+1);
        console2.log("correctResult: %d", correctResult);
        assertTrue(result  == 1e15 * 1e30);
    }

Impact

MarketUtils.getFundingAmountPerSizeDelta() has a rounding logical error, sometimes, when roundup = true, the result, instead of rounding up, it becomes a rounding down!

Code Snippet

Tool used

VScode

Manual Review

Recommendation

Change the rounding mode of the divisor to the opposite of the input roundup mode. Or, the solution can be just as follows:

function getFundingAmountPerSizeDelta(
        uint256 fundingAmount,
        uint256 openInterest,
        bool roundUp
    ) internal pure returns (uint256) {
        if (fundingAmount == 0 || openInterest == 0) { return 0; }
     
       

        // how many units in openInterest
-        uint256 divisor = Calc.roundUpDivision(openInterest, Precision.FLOAT_PRECISION_SQRT);

-        return Precision.toFactor(fundingAmount, divisor, roundUp);
+       return Precision.toFactor(fundingAmount*Precision.FLOAT_PRECISION_SQRT, openInterest, roundUp
    }
@github-actions github-actions bot added the Medium A valid Medium severity issue label Jun 9, 2023
@xvi10 xvi10 added Sponsor Confirmed The sponsor acknowledged this issue is valid Disagree With Severity The sponsor disputed the severity of this issue Will Fix The sponsor confirmed this issue will be fixed labels Jun 12, 2023
@xvi10
Copy link

xvi10 commented Jun 12, 2023

would classify this as a low since the impact should be very small

@xvi10 xvi10 added Sponsor Disputed The sponsor disputed this issue's validity and removed Sponsor Confirmed The sponsor acknowledged this issue is valid labels Jun 12, 2023
@IllIllI000
Copy link
Collaborator

a fix was done for this one, so I don't think this can be low: gmx-io/gmx-synthetics@f8cdb4d

@xvi10
Copy link

xvi10 commented Jun 13, 2023

we will fix valid low issues if it can improve the accuracy of calculations, even if the issue may not lead to a significant difference

was referencing this for the criteria, "Medium: There is a viable scenario (even if unlikely) that could cause the protocol to enter a state where a material amount of funds can be lost. The attack path is possible with assumptions that either mimic on-chain conditions or reflect conditions that have a reasonable chance of becoming true in the future."

the rounding issues need to lead to a material impact to be considered for a medium?

@IllIllI000
Copy link
Collaborator

IllIllI000 commented Jun 13, 2023

won't this lead to funding miscalculations for every second, for every user, and become larger as the funding amounts grow?

@xvi10 xvi10 added Sponsor Confirmed The sponsor acknowledged this issue is valid and removed Sponsor Disputed The sponsor disputed this issue's validity Disagree With Severity The sponsor disputed the severity of this issue labels Jun 13, 2023
@xvi10
Copy link

xvi10 commented Jun 13, 2023

that's true, have updated the issue to confirmed

@IllIllI000
Copy link
Collaborator

@xvi10 Also, if the precision loss is enough to make you want to add a fix, I would say it should be medium - let me know if you intend to fix any of the other precision loss submissions

@xvi10
Copy link

xvi10 commented Jun 14, 2023

not sure i agree with that since it doesn't seem to match the criteria in https://docs.sherlock.xyz/audits/judging/judging

but will notify and let Sherlock decide

the MarketUtils.getFundingFeeAmount was also updated, not due to precision but to avoid the risk of overflow, it was mentioned as a precision issue in:
#193

@hrishibhat
Copy link

Considering this issue as valid medium based on the following comment which the sponsor agrees too.

won't this lead to funding miscalculations for every second, for every user, and become larger as the funding amounts grow?

@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Jun 20, 2023
@xvi10
Copy link

xvi10 commented Jul 5, 2023

fixed in gmx-io/gmx-synthetics@f8cdb4d

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

4 participants