claimFees may cause some external rewards to be locked in the contract
claimFees will update rewardToken.lastBalance so that if there are unaccrued reward tokens in the contract, users will not be able to claim them.\\n_accumulateExternalRewards takes the difference between the contract's reward token balance and lastBalance as the reward. and the accumulated reward tokens are updated by _updateExternalRewardState.\\n```\\n    function _accumulateExternalRewards() internal override returns (uint256[] memory) {\\n        uint256 numExternalRewards = externalRewardTokens.length;\\n\\n        auraPool.rewardsPool.getReward(address(this), true);\\n\\n        uint256[] memory rewards = new uint256[](numExternalRewards);\\n        for (uint256 i; i < numExternalRewards; ) {\\n            ExternalRewardToken storage rewardToken = externalRewardTokens[i];\\n            uint256 newBalance = ERC20(rewardToken.token).balanceOf(address(this));\\n\\n            // This shouldn't happen but adding a sanity check in case\\n            if (newBalance < rewardToken.lastBalance) {\\n                emit LiquidityVault_ExternalAccumulationError(rewardToken.token);\\n                continue;\\n            }\\n\\n            rewards[i] = newBalance - rewardToken.lastBalance;\\n            rewardToken.lastBalance = newBalance;\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n        return rewards;\\n    }\\n// rest of code\\n    function _updateExternalRewardState(uint256 id_, uint256 amountAccumulated_) internal {\\n        // This correctly uses 1e18 because the LP tokens of all major DEXs have 18 decimals\\n        if (totalLP != 0)\\n            externalRewardTokens[id_].accumulatedRewardsPerShare +=\\n                (amountAccumulated_ * 1e18) /\\n                totalLP;\\n    }\\n```\\n\\nauraPool.rewardsPool.getReward can be called by anyone to send the reward tokens to the contract\\n```\\n    function getReward(address _account, bool _claimExtras) public updateReward(_account) returns(bool){\\n        uint256 reward = earned(_account);\\n        if (reward > 0) {\\n            rewards[_account] = 0;\\n            rewardToken.safeTransfer(_account, reward);\\n            IDeposit(operator).rewardClaimed(pid, _account, reward);\\n            emit RewardPaid(_account, reward);\\n        }\\n\\n        //also get rewards from linked rewards\\n        if(_claimExtras){\\n            for(uint i=0; i < extraRewards.length; i++){\\n                IRewards(extraRewards[i]).getReward(_account);\\n            }\\n        }\\n        return true;\\n    }\\n```\\n\\nHowever, in claimFees, the rewardToken.lastBalance will be updated to the current contract balance after the admin has claimed the fees.\\n```\\n    function claimFees() external onlyRole("liquidityvault_admin") {\\n        uint256 numInternalRewardTokens = internalRewardTokens.length;\\n        uint256 numExternalRewardTokens = externalRewardTokens.length;\\n\\n        for (uint256 i; i < numInternalRewardTokens; ) {\\n            address rewardToken = internalRewardTokens[i].token;\\n            uint256 feeToSend = accumulatedFees[rewardToken];\\n\\n            accumulatedFees[rewardToken] = 0;\\n\\n            ERC20(rewardToken).safeTransfer(msg.sender, feeToSend);\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n\\n        for (uint256 i; i < numExternalRewardTokens; ) {\\n            ExternalRewardToken storage rewardToken = externalRewardTokens[i];\\n            uint256 feeToSend = accumulatedFees[rewardToken.token];\\n\\n            accumulatedFees[rewardToken.token] = 0;\\n\\n            ERC20(rewardToken.token).safeTransfer(msg.sender, feeToSend);\\n            rewardToken.lastBalance = ERC20(rewardToken.token).balanceOf(address(this));\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n    }\\n```\\n\\nConsider the following scenario.\\nStart with rewardToken.lastBalance = 200.\\nAfter some time, the rewardToken in aura is increased by 100.\\nSomeone calls getReward to claim the reward tokens to the contract, and the 100 reward tokens increased have not yet been accumulated via _accumulateExternalRewards and _updateExternalRewardState.\\nThe admin calls claimFees to update rewardToken.lastBalance to 290(10 as fees).\\nUsers call claimRewards and receives 0 reward tokens. 90 reward tokens will be locked in the contract
Use _accumulateExternalRewards and _updateExternalRewardState in claimFees to accrue rewards.\\n```\\n    function claimFees() external onlyRole("liquidityvault_admin") {\\n        uint256 numInternalRewardTokens = internalRewardTokens.length;\\n        uint256 numExternalRewardTokens = externalRewardTokens.length;\\n\\n        for (uint256 i; i < numInternalRewardTokens; ) {\\n            address rewardToken = internalRewardTokens[i].token;\\n            uint256 feeToSend = accumulatedFees[rewardToken];\\n\\n            accumulatedFees[rewardToken] = 0;\\n\\n            ERC20(rewardToken).safeTransfer(msg.sender, feeToSend);\\n\\n            unchecked {\\n                // Add the line below\\n// Add the line below\\ni;\\n            }\\n        }\\n// Add the line below\\n       uint256[] memory accumulatedExternalRewards = _accumulateExternalRewards();\\n        for (uint256 i; i < numExternalRewardTokens; ) {\\n// Add the line below\\n           _updateExternalRewardState(i, accumulatedExternalRewards[i]);\\n            ExternalRewardToken storage rewardToken = externalRewardTokens[i];\\n            uint256 feeToSend = accumulatedFees[rewardToken.token];\\n\\n            accumulatedFees[rewardToken.token] = 0;\\n\\n            ERC20(rewardToken.token).safeTransfer(msg.sender, feeToSend);\\n            rewardToken.lastBalance = ERC20(rewardToken.token).balanceOf(address(this));\\n\\n            unchecked {\\n                // Add the line below\\n// Add the line below\\ni;\\n            }\\n        }\\n    }\\n```\\n
It will cause some external rewards to be locked in the contract
```\\n    function _accumulateExternalRewards() internal override returns (uint256[] memory) {\\n        uint256 numExternalRewards = externalRewardTokens.length;\\n\\n        auraPool.rewardsPool.getReward(address(this), true);\\n\\n        uint256[] memory rewards = new uint256[](numExternalRewards);\\n        for (uint256 i; i < numExternalRewards; ) {\\n            ExternalRewardToken storage rewardToken = externalRewardTokens[i];\\n            uint256 newBalance = ERC20(rewardToken.token).balanceOf(address(this));\\n\\n            // This shouldn't happen but adding a sanity check in case\\n            if (newBalance < rewardToken.lastBalance) {\\n                emit LiquidityVault_ExternalAccumulationError(rewardToken.token);\\n                continue;\\n            }\\n\\n            rewards[i] = newBalance - rewardToken.lastBalance;\\n            rewardToken.lastBalance = newBalance;\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n        return rewards;\\n    }\\n// rest of code\\n    function _updateExternalRewardState(uint256 id_, uint256 amountAccumulated_) internal {\\n        // This correctly uses 1e18 because the LP tokens of all major DEXs have 18 decimals\\n        if (totalLP != 0)\\n            externalRewardTokens[id_].accumulatedRewardsPerShare +=\\n                (amountAccumulated_ * 1e18) /\\n                totalLP;\\n    }\\n```\\n