Kinetic Disclosed Report

Audit report Kinetic Audit Contest

Reward Distribution Precision Loss Could Lead to Zero Rewards

Company
Created date
Feb 18 2025

Target

https://github.com/kinetic-market/public-money-market-contracts

Vulnerability Details

Description

Attackers can exploit the precision loss in reward calculations by frequently calling the updateRewardSupplyIndex and updateRewardBorrowIndex functions, causing the rewards to be effectively zero. In particular, when attackers repeatedly call these functions, the downwards rounding may result in no increase in the rewardSupplyState.index or rewardBorrowState.index. This issue is more prominent in chains with low gas costs and fast block times.

Here’s the relevant part of the code:

function updateRewardSupplyIndex(uint8 rewardType, address cToken) internal {
    require(rewardType < rewardTokens.length, "IR"); 
    RewardMarketState storage supplyState = rewardSupplyState[rewardType][cToken];
    uint supplySpeed = supplyRewardSpeeds[rewardType][cToken];
    uint blockTimestamp = getBlockTimestamp();
    uint deltaTimestamps = sub_(blockTimestamp, uint(supplyState.timestamp));
    if (deltaTimestamps > 0 && supplySpeed > 0) {
        uint supplyTokens = CToken(cToken).totalSupply();
        uint rewardsAccrued = mul_(deltaTimestamps, supplySpeed);
        Double memory ratio = supplyTokens > 0 ? fraction(rewardsAccrued, supplyTokens) : Double({mantissa: 0});
        Double memory index = add_(Double({mantissa: supplyState.index}), ratio);
        rewardSupplyState[rewardType][cToken] = RewardMarketState({
            index: safe224(index.mantissa, "224"),
            timestamp: safe32(blockTimestamp, "32")
        });
    } else if (deltaTimestamps > 0) {
        supplyState.timestamp = safe32(blockTimestamp, "32");
    }
}

In this function, the reward index might not increase as expected because of rounding, causing a situation where no rewards are distributed. The problem is exacerbated in environments where transactions are cheap, and blocks are mined quickly, allowing an attacker to repeatedly call the function and manipulate the rewards.

Recommendations

Implement additional precision or checks to ensure that the reward index is updated correctly even when small values are involved.

Validation steps

https://github.com/kinetic-market/public-money-market-contracts/blob/d46f5223344ff6502349549ad858588e496483df/contracts/Comptroller.sol#L932-L950

https://github.com/kinetic-market/public-money-market-contracts/blob/d46f5223344ff6502349549ad858588e496483df/contracts/Comptroller.sol#L957-L975

CommentsReport History
Comments on this report are hidden
Details
Statedisclosed
Severity
None
Bounty$143
Visibilitypartially
VulnerabilityBlockchain
Participants (3)
company admin
author