Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Unbounded number of bonusTokens #114

Closed
code423n4 opened this issue May 27, 2022 · 3 comments
Closed

Unbounded number of bonusTokens #114

code423n4 opened this issue May 27, 2022 · 3 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate This issue or pull request already exists sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L629
https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L270

Vulnerability details

Impact

Each additional bonus token added to the BathToken.bonusTokens[] array will cause the gas fee of BathToken.withdraw() calls to be more expensive.

The BathToken does not impose any upper limit on the BathToken.bonusTokens[] array. It also does not implement any function to reduce the size of the BathToken.bonusTokens[] array.

As such, it is possible to append new bonus token to the BathToken.bonusTokens[] array until a point where an "Out of Gas" error or a "Block Gas Limit" error happens when BathToken.withdraw() is called. At this point, none of the BathToken LPs will be able to withdraw their funds from the affected BathToken pools.

Proof-of-Concept

The following shows that the distributeBonusTokenRewards function, which is called by withdraw function, looping through the BathToken.bonusTokens[] array and execute the code for the rewards/bonus distribution in each iteration.

https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L629

function distributeBonusTokenRewards(
    address receiver,
    uint256 sharesWithdrawn,
    uint256 initialTotalSupply
) internal {
    if (bonusTokens.length > 0) {
        for (uint256 index = 0; index < bonusTokens.length; index++) {
            IERC20 token = IERC20(bonusTokens[index]);
            // Note: Shares already burned in Bath Token _withdraw

            // Pair each bonus token with a lightly adapted OZ Vesting wallet. Each time a user withdraws, they
            //  are released their relative share of this pool, of vested BathBuddy rewards
            // The BathBuddy pool should accrue ERC-20 rewards just like OZ VestingWallet and simply just release the withdrawer's relative share of releaseable() tokens
            if (rewardsVestingWallet != IBathBuddy(0)) {
                rewardsVestingWallet.release(
                    (token),
                    receiver,
                    sharesWithdrawn,
                    initialTotalSupply,
                    feeBPS
                );
            }
        }
    }
}

The following shows the new bonus token address appends to the BathToken.bonusTokens[] array without checking for the upper limit.

https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L270

/// @notice Admin-only function to add a bonus token to bonusTokens for pool incentives
function setBonusToken(address newBonusERC20) external onlyBathHouse {
    bonusTokens.push(newBonusERC20);
}

Recommended Mitigation Steps

Define a max number of bonus tokens in a pool, and have the array's length checked. Additionally, implement function to reduce the array size so that it is possible to remove some of the bonus token from the array if needed.

@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels May 27, 2022
code423n4 added a commit that referenced this issue May 27, 2022
@bghughes bghughes added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Jun 3, 2022
@bghughes
Copy link
Collaborator

bghughes commented Jun 3, 2022

See #45

@HickupHH3
Copy link
Collaborator

Valid concern; protocol availability is potentially affected

@HickupHH3
Copy link
Collaborator

Duplicate of #249, last example.

@HickupHH3 HickupHH3 added the duplicate This issue or pull request already exists label Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate This issue or pull request already exists sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

3 participants