Agreeable Gunmetal Lark
high
Wrong token address is inputted while calling donate function inside claimAndDonateRewards function
Following is claimAndDonateRewards function
function claimAndDonateRewards(address token, uint256 minimumAmountOut) external returns (uint256) {
require(msg.sender == rewardRouter, "Must be Reward Router");
// Amount of reward token claimed plus any sent to this contract from grants.
uint256 amountRewardToken = IERC20(rewardToken).balanceOf(address(this));
if (amountRewardToken == 0) return 0;
if (debtToken == 0xCB8FA9a76b8e203D8C3797bF438d8FB81Ea3326A) {
// Velodrome Swap Routes: OP -> USDC -> alUSD
IVelodromeSwapRouter.Route[] memory routes = new IVelodromeSwapRouter.Route[](2);
routes[0] = IVelodromeSwapRouter.Route(0x4200000000000000000000000000000000000042, 0x7F5c764cBc14f9669B88837ca1490cCa17c31607, false, 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a);
routes[1] = IVelodromeSwapRouter.Route(0x7F5c764cBc14f9669B88837ca1490cCa17c31607, 0xCB8FA9a76b8e203D8C3797bF438d8FB81Ea3326A, true, 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a);
TokenUtils.safeApprove(rewardToken, swapRouter, amountRewardToken);
IVelodromeSwapRouter(swapRouter).swapExactTokensForTokens(amountRewardToken, minimumAmountOut, routes, address(this), block.timestamp);
} else if (debtToken == 0x3E29D3A9316dAB217754d13b28646B76607c5f04) {
// Velodrome Swap Routes: OP -> alETH
IVelodromeSwapRouter.Route[] memory routes = new IVelodromeSwapRouter.Route[](2);
routes[0] = IVelodromeSwapRouter.Route(0x4200000000000000000000000000000000000042, 0x4200000000000000000000000000000000000006, false, 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a);
routes[1] = IVelodromeSwapRouter.Route(0x4200000000000000000000000000000000000006, 0x3E29D3A9316dAB217754d13b28646B76607c5f04, true, 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a);
TokenUtils.safeApprove(rewardToken, swapRouter, amountRewardToken);
IVelodromeSwapRouter(swapRouter).swapExactTokensForTokens(amountRewardToken, minimumAmountOut, routes, address(this), block.timestamp);
} else {
revert IllegalState("Reward collector `debtToken` is not supported");
}
// Donate to alchemist depositors
uint256 debtReturned = IERC20(debtToken).balanceOf(address(this));
TokenUtils.safeApprove(debtToken, alchemist, debtReturned);
IAlchemistV2(alchemist).donate(token, debtReturned);
return amountRewardToken;
}
Note following lines are where the wrong address is inputted
// Donate to alchemist depositors
uint256 debtReturned = IERC20(debtToken).balanceOf(address(this));
TokenUtils.safeApprove(debtToken, alchemist, debtReturned);
IAlchemistV2(alchemist).donate(token, debtReturned);
As can be seen in the following line IAlchemistV2(alchemist).donate(token, debtReturned) Donate is called with the yield token as input instead it should be IAlchemistV2(alchemist).donate(debtToken, debtReturned) because safeApprove is called for debtToken.
I am marking this as high because it would cause the function to revert as there wouldn't be token available in the contract for which donate function is called and hence causes a key functionality to break.
It will cause debtTokens to remain in the contract and not be donated.Also the function would revert as alchemist contract is not approved for token instead it is approved to spend debtToken.
Manual Review
Make the following change
IAlchemistV2(alchemist).donate(debtToken, debtReturned)