code-423n4 / 2024-02-wise-lending-findings

11 stars 8 forks source link

Wrong `NORMALISATION_FACTOR` constant leads to the malfunctioning of the LASA algorithm #249

Closed c4-bot-9 closed 5 months ago

c4-bot-9 commented 5 months ago

Lines of code

https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/WiseLendingDeclaration.sol#L304-L307 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/PoolManager.sol#L301 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/PoolManager.sol#L201-L204 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/PoolManager.sol#L224 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/PoolManager.sol#L73-L76 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/PoolManager.sol#L90 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/MainHelper.sol#L1103-L1104 https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/MainHelper.sol#L1132-L1133

Vulnerability details

Impact

The NORMALISATION_FACTOR constant was set with the wrong number. This constant is used to calculate the deltaPole variable, which will be used to calculate an increasing and decreasing step of the LASA algorithm's resonanceFactor variable.

Therefore, the wrong NORMALISATION_FACTOR constant leads to the malfunctioning of the LASA algorithm.

Proof of Concept

The NORMALISATION_FACTOR constant was set to 4838400. This constant represents an amount of seconds for two months that should be 5259492 (ref: https://www.calculateme.com/time/months/to-seconds/2) instead.

    // Two months in seconds:
    // Norming change in pole value that it steps from min to max value
    // within two month (if nothing changes)
@1  uint256 internal constant NORMALISATION_FACTOR = 4838400; //@audit -- Wrong constant (two months in seconds must be 5_259_492)

The wrong NORMALISATION_FACTOR constant is used to calculate the deltaPole variable in the PoolManager::_getDeltaPole().

This incorrectly calculated deltaPole will then be utilized by PoolManager::_createPool() and PoolManager::setParamsLASA() in order to configure it into the borrowRatesData[_params.poolToken] mapping.

    function _getDeltaPole(
        uint256 _maxPole,
        uint256 _minPole
    )
        private
        pure
        returns (uint256)
    {
@2      return (_maxPole - _minPole) / NORMALISATION_FACTOR; //@audit -- The wrong constant is used to calculate the deltaPole
    }

    ...

    function _createPool(
        CreatePool calldata _params
    )
        private
    {
        ...

        // Calculating fraction for algorithm step
@3.1     uint256 staticDeltaPole = _getDeltaPole( //@audit -- The incorrectly calculated deltaPole is utilized by the _createPool()
@3.1        staticMaxPole,
@3.1        staticMinPole
@3.1    );

        ...

        // Rates Pool Data
        borrowRatesData[_params.poolToken] = BorrowRatesEntry(
            startValuePole,
@3.2        staticDeltaPole, //@audit -- The incorrectly calculated deltaPole is configured into the BorrowRatesEntry struct
            staticMinPole,
            staticMaxPole,
            _params.poolMulFactor
        );

        ...
    }

    ...

    function setParamsLASA(
        address _poolToken,
        uint256 _poolMulFactor,
        uint256 _upperBoundMaxRate,
        uint256 _lowerBoundMaxRate,
        bool _steppingDirection,
        bool _isFinal
    )
        external
        onlyMaster
    {
        ...

@4.1    uint256 staticDeltaPole = _getDeltaPole( //@audit -- The incorrectly calculated deltaPole is utilized by the setParamsLASA()
@4.1        staticMaxPole,
@4.1        staticMinPole
@4.1    );

        ...

        borrowRatesData[_poolToken] = BorrowRatesEntry(
            startValuePole,
@4.2        staticDeltaPole, //@audit -- The incorrectly calculated deltaPole is configured into the BorrowRatesEntry struct
            staticMinPole,
            staticMaxPole,
            _poolMulFactor
        );

        ...
    }

Later, the incorrectly calculated deltaPole will be used to calculate an increasing step of the LASA algorithm's resonanceFactor variable in the MainHelper::_increaseResonanceFactor().

Also, the incorrect deltaPole will be used to calculate a decreasing step of the LASA algorithm's resonanceFactor variable in the MainHelper::_decreaseResonanceFactor().

For this reason, the wrong NORMALISATION_FACTOR constant leads to the malfunctioning of the LASA algorithm.

    function _increaseResonanceFactor(
        address _poolToken
    )
        private
    {
        BorrowRatesEntry memory borrowData = borrowRatesData[
            _poolToken
        ];

@5.1    uint256 delta = borrowData.deltaPole //@audit -- The incorrectly calculated deltaPole is used to calculate an increasing step of the LASA algorithm's resonanceFactor
@5.1        * (block.timestamp - timestampsPoolData[_poolToken].timeStampScaling);

        uint256 sum = delta
            + borrowData.pole;

        uint256 setValue = sum > borrowData.maxPole
            ? borrowData.maxPole
            : sum;

        _setPole(
            _poolToken,
            setValue
        );
    }

    ...

    function _decreaseResonanceFactor(
        address _poolToken
    )
        private
    {
        uint256 minValue = borrowRatesData[_poolToken].minPole;

@5.2    uint256 delta = borrowRatesData[_poolToken].deltaPole //@audit -- The incorrectly calculated deltaPole is used to calculate a decreasing step of the LASA algorithm's resonanceFactor
@5.2        * (block.timestamp - timestampsPoolData[_poolToken].timeStampScaling);

        uint256 sub = borrowRatesData[_poolToken].pole > delta
            ? borrowRatesData[_poolToken].pole - delta
            : 0;

        uint256 setValue = sub < minValue
            ? minValue
            : sub;

        _setPole(
            _poolToken,
            setValue
        );
    }

Tools Used

Manual Review

Recommended Mitigation Steps

Correct the value of the NORMALISATION_FACTOR constant.

The correct amount of seconds for two months should be 5259492 (ref: https://www.calculateme.com/time/months/to-seconds/2).

Assessed type

Other

GalloDaSballo commented 5 months ago

I believe this should be QA

The constant is 56 days which is 8 weeks

c4-pre-sort commented 5 months ago

GalloDaSballo marked the issue as insufficient quality report

c4-pre-sort commented 5 months ago

GalloDaSballo marked the issue as duplicate of #141

c4-judge commented 5 months ago

trust1995 changed the severity to QA (Quality Assurance)