sherlock-audit / 2023-04-blueberry-judging

8 stars 5 forks source link

Bauer - The protocol does not return all of the rewards to user #42

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

Bauer

high

The protocol does not return all of the rewards to user

Summary

When user calls the openPositionFarm() function to add liquidity to Balancer pool, with staking to Aura, if user has a collateral and the protocol does not return all of the rewards to user upon withdrawal.

Vulnerability Detail

The AuraSpell.openPositionFarm() function allows users to open a new position on a specific farming pool using collateral and borrowed tokens. The function follows a series of steps to deposit collateral, borrow tokens, add liquidity to a Balancer pool, and validate the maximum loan-to-value (LTV) and position size. Inside the function,it takes out any existing collateral and burns the corresponding pool tokens.

        // 6. Take out existing collateral and burn
        IBank.Position memory pos = bank.getCurrentPositionInfo();
        if (pos.collateralSize > 0) {
            (uint256 pid, ) = wAuraPools.decodeId(pos.collId);
            if (param.farmingPoolId != pid)
                revert Errors.INCORRECT_PID(param.farmingPoolId);
            if (pos.collToken != address(wAuraPools))
                revert Errors.INCORRECT_COLTOKEN(pos.collToken);
            bank.takeCollateral(pos.collateralSize);
            wAuraPools.burn(pos.collId, pos.collateralSize);
            _doRefundRewards(AURA);
        }

For the WAuraPools.burn() function ,it retrieves any pending rewards for the burned tokens by calling the "pendingRewards" function and transfers the corresponding reward tokens and amounts back to the AuraSpell protocol using a loop that iterates over the reward tokens and calls the "safeTransfer" function.

function burn(
        uint256 id,
        uint256 amount
    )
        external
        nonReentrant
        returns (address[] memory rewardTokens, uint256[] memory rewards)
    {
        if (amount == type(uint256).max) {
            amount = balanceOf(msg.sender, id);
        }
        (uint256 pid, ) = decodeId(id);
        _burn(msg.sender, id, amount);

        (address lpToken, , , address balRewarder, , ) = getPoolInfoFromPoolId(
            pid
        );
        // Claim Rewards
        IAuraRewarder(balRewarder).withdraw(amount, true);
        // Withdraw LP
        auraPools.withdraw(pid, amount);

        // Transfer LP Tokens
        IERC20Upgradeable(lpToken).safeTransfer(msg.sender, amount);

        // Transfer Reward Tokens
        (rewardTokens, rewards) = pendingRewards(id, amount);

        for (uint i = 0; i < rewardTokens.length; i++) {
            IERC20Upgradeable(rewardTokens[i]).safeTransfer(
                msg.sender,
                rewards[i]
            );
        }
    }

However, the AuraSpell protocol only refunds any earned rewards in AURA tokens by calling the "_doRefundRewards" function.

Impact

The reward tokens were not returned to the user

Code Snippet

https://github.com/sherlock-audit/2023-04-blueberry/blob/main/blueberry-core/contracts/spell/AuraSpell.sol#L131-L140

Tool used

Manual Review

Recommendation

Swap rewards tokens to corresponding token and reward to user.

Duplicate of #101