code-423n4 / 2023-10-canto-findings

0 stars 1 forks source link

Calculation Issue in claimConcentratedRewards Function Can Prevent Reward Distribution for Narrow Tick Ranges #187

Closed c4-submissions closed 1 year ago

c4-submissions commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-10-canto/blob/main/canto_ambient/contracts/mixins/LiquidityMining.sol#L184 https://github.com/code-423n4/2023-10-canto/blob/main/canto_ambient/contracts/mixins/LiquidityMining.sol#L190

Vulnerability details

Impact

The code contains a calculation issue in the claimConcentratedRewards function. When the tick range (upperTick - lowerTick) is less than 20, the rewards calculation remains zero, causing users with narrow tick ranges to not receive their rewards. This issue can lead to unfair outcomes, where eligible users do not receive the expected rewards.

Proof of Concept

The code calculates rewardsToSend based on the inRangeLiquidityOfPosition value, which is determined in a loop from lowerTick + 10 to upperTick - 10. However, if the difference between upperTick and lowerTick is less than 20, the loop won't execute because the condition lowerTick + 10 <= upperTick - 10 won't be satisfied. As a result, inRangeLiquidityOfPosition and rewardsToSend will both remain zero. condition wont excute if uppertick - lowertick < 20, inRangeLiquidityOfPosition ll stay 0, rewardsToSend d stay 0

function claimConcentratedRewards(
    address payable owner,
    bytes32 poolIdx,
    int24 lowerTick,
    int24 upperTick,
    uint32[] memory weeksToClaim
) internal {
    accrueConcentratedPositionTimeWeightedLiquidity(
        owner,
        poolIdx,
        lowerTick,
        upperTick
    );
    ..
            for (int24 j = lowerTick + 10; j <= upperTick - 10; ++j) {
                inRangeLiquidityOfPosition += timeWeightedWeeklyPositionInRangeConcLiquidity_[poolIdx][posKey][week][j];
            }
            // Percentage of this weeks overall in range liquidity that was provided by the user times the overall weekly rewards
            rewardsToSend += inRangeLiquidityOfPosition * concRewardPerWeek_[poolIdx][week] / overallInRangeLiquidity;
        }
        concLiquidityRewardsClaimed_[poolIdx][posKey][week] = true; 
    }
    if (rewardsToSend > 0) {
        (bool sent, ) = owner.call{value: rewardsToSend}("");
        require(sent, "Sending rewards failed");
    }
}

concLiquidityRewardsClaimed_[poolIdx][posKey][week] d be set to true, thus he user wont claim his reward when he retry.

Tools Used

Manual review

Recommended Mitigation Steps

Modify the calculation of rewards to consider a different factor or approach when the tick range is less than 20.

Assessed type

Invalid Validation

c4-pre-sort commented 1 year ago

141345 marked the issue as duplicate of #146

c4-pre-sort commented 1 year ago

141345 marked the issue as sufficient quality report

c4-judge commented 1 year ago

dmvt marked the issue as unsatisfactory: Overinflated severity