hats-finance / Possum-Labs--Portals--0xed8965d49b8aeca763447d56e6da7f4e0506b2d3

GNU General Public License v2.0
0 stars 2 forks source link

Rounding error when calculating with quoteBuyPortalEnergy #34

Open hats-bug-reporter[bot] opened 1 year ago

hats-bug-reporter[bot] commented 1 year ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0x7f7b4d7433c296008670e9150291f5bea0cf93f38bdfab335460f451079d0c67 Severity: low

Description: Description\ The function quoteBuyPortalEnergy is used to simulate buying portalEnergy with PSM tokens. However, it does a division before multiplication between Ln 592-595. This can cause the division to round down to zero when reserve0 is more than constantProduct.

function quoteBuyPortalEnergy(uint256 _amountInput) external view returns(uint256) { 
        /// @dev Calculate the PSM token reserve (input)
        uint256 reserve0 = IERC20(PSM_ADDRESS).balanceOf(address(this)) - fundingRewardPool;

        /// @dev Calculate the reserve of portalEnergy (output)
        uint256 reserve1 = constantProduct / reserve0;

        /// @dev Calculate the amount of portalEnergy received based on the amount of PSM tokens sold
        uint256 amountReceived = (_amountInput * reserve1) / (_amountInput + reserve0);

        return (amountReceived);
    }

Attack Scenario\

  1. The function can provide incorrect values to external applications using the function to calculate call input values leading to a degraded user experience. Attachments

  2. Proof of Concept (PoC) File

  3. Revised Code File (Optional)

Remove Ln 592 and refactor Ln 595 thus:

uint256 amountReceived = ((_amountInput * constantProduct) / reserve0) / (_amountInput + reserve0);
PossumLabsCrypto commented 1 year ago

The same was remarked by Shieldify in the first audit (informational hence not included in the report) but we did not adjust because it can create an overflow issue.

constantProduct is already a massive number because it multiplies two token amounts, for example 1,000,000 1e18 50,000,000 * 1e18. If we multiply this again with a token number (input), it is 1e54 from the token decimals alone. Given that the maximum number in a uint256 is of the magnitude 1e77, this calculation could overflow when tokens with large supplies are involved.

The rounding error is insignificant by all measures, hence this finding is dismissed.