Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bitter Ash Mink - Incorrect Denominator Scaling in Kappa Calculation Leading to Inflation of Kappa Result #142

Open
sherlock-admin2 opened this issue Mar 11, 2025 · 0 comments

Comments

@sherlock-admin2
Copy link

Bitter Ash Mink

Medium

Incorrect Denominator Scaling in Kappa Calculation Leading to Inflation of Kappa Result

Summary

The _calculateKappa function in the DistributionModule incorrectly scales the denominator due to the use of BPS_SCALAR (10^4) instead of the required 10^5 scaling factor. This discrepancy inflates the resulting Kappa value, leading to incorrect token distribution calculations and break of proper protocol functionality.

Root Cause

    function _calculateKappa(DistributionModuleStorageV0 storage $, uint256 ratet)
        internal
        view
        returns (uint256)
    {
        uint256 maxRate = ratet > $.rateMin ? ratet : $.rateMin; // scaled by 10_000
        uint256 numerator = Math.mulDiv($.m0, maxRate, BPS_SCALAR); // scaled by 10**18 * 10_000 /10_000 = 10**18
>>>        uint256 denominator = Math.mulDiv(_calculateGamma($), $.rate0, BPS_SCALAR); // scaled by 10**18 * 10**5 / 10**5 = 10**18
        return Math.mulDiv(numerator, SCALAR_ONE, denominator, Math.Rounding.Floor); // scales numerator 10*18 then divides to keep 10**18 scale
    }

https://github.com/sherlock-audit/2025-02-usual-labs/blob/main/pegasus/packages/solidity/src/distribution/DistributionModule.sol#L928
The root cause lies in the denominator calculation within the _calculateKappa function. The comment explicitly states that the denominator should follow a scaling system of 1018 * 105 / 105 = 1018. However, the implementation uses BPS_SCALAR (10^4) instead of the required 10^5 scaling factor. This mismatch causes the denominator to be smaller than intended, inflating the Kappa value.

Internal Pre-conditions

  1. The _calculateKappa function is invoked during token distribution calculations.

  2. The rate0 and _calculateGamma($) values are non-zero and valid.

External Pre-conditions

  1. The system relies on accurate Kappa calculations for fair token distribution.

  2. Users and external contracts interact with the DistributionModule expecting correct token allocations.

Attack Path

  1. An attacker or user observes the incorrect scaling in the _calculateKappa function.

  2. They exploit the inflated Kappa value by interacting with the DistributionModule to receive disproportionately higher token allocations.

  3. The attacker benefits from the inflated token distribution, potentially draining the system of resources or disrupting its protocol economic balance.

Impact

  1. Economic Disruption: Incorrect Kappa values lead to unfair token distribution, potentially disadvantaging legitimate users.

  2. Financial Loss: The protocol would suffer financial losses due to inflated token allocations.

  3. Loss of Trust: Users would lose confidence in the protocol's fairness and reliability.

PoC

The issue is evident in the following code snippet:

uint256 denominator = Math.mulDiv(_calculateGamma($), $.rate0, BPS_SCALAR); // scaled by 10**18 * 10**5 / 10**5 = 10**18  

Here, BPS_SCALAR is defined as 10^4, but the comment indicates that the scaling should be 10^5. This mismatch results in a denominator that is 10 times smaller than intended, inflating the Kappa value by a factor of 10.

Mitigation

Protocol should update the denominator calculation to use the correct scaling factor of 10^5 instead of 10^4 as noted in comment description.

    function _calculateKappa(DistributionModuleStorageV0 storage $, uint256 ratet)
        internal
        view
        returns (uint256)
    {
        uint256 maxRate = ratet > $.rateMin ? ratet : $.rateMin; // scaled by 10_000
        uint256 numerator = Math.mulDiv($.m0, maxRate, BPS_SCALAR); // scaled by 10**18 * 10_000 /10_000 = 10**18
---        uint256 denominator = Math.mulDiv(_calculateGamma($), $.rate0, BPS_SCALAR); // scaled by 10**18 * 10**5 / 10**5 = 10**18
+++    ---        uint256 denominator = Math.mulDiv(_calculateGamma($), $.rate0, 10**5);
        return Math.mulDiv(numerator, SCALAR_ONE, denominator, Math.Rounding.Floor); // scales numerator 10*18 then divides to keep 10**18 scale
    }
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant