You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 3, 2024. It is now read-only.
sherlock-admin opened this issue
Aug 30, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Performing the liquidation process reverts due to failing to swap the reward tokens
Summary
The liquidateVaultsForToken function in the LiquidationRow contract fails to properly swap the reward tokens, causing the liquidation process to fail.
Vulnerability Detail
During the liquidation process, destination vault LP rewards are claimed, reward tokens are swapped to the desired token (usually the base asset WETH), and distributed to the respective rewarder contracts of the destination vaults. The actual token swap is performed via the swap function of the BaseAsyncSwapper contract.
The liquidation process fails due to two issues:
The LiquidationRow.liquidateVaultsForToken does not approve the BaseAsyncSwapper contract to spend the reward tokens, and the BaseAsyncSwapper contract does not pull in the reward tokens from the LiquidationRow contract. Thus, the swap function fails due to insufficient funds.
The swap function sells the given sellTokenAddress for the desired buyTokenAddress via a configured aggregator service. After the successful swap via the aggregator, the swap function determines the actual amount of buyTokenAddress received (buyTokenAmountReceived) and reverts if it is less than the buyAmount specified in the SwapParams struct, we can conclude that the BaseAsyncSwapper is expected to be the receiver of the swapped tokens.
The swap function does not transfer the bought buyToken tokens to the caller. This is expected in the case of the LMPVaultRouter contract as the swap function is called via a delegatecall.
However, the LiquidationRow contract calls the swap function with an ordinary call in the _performLiquidation function, as seen in line 251. Consequently, the LiquidationRow contract does not receive the bought tokens from the swapper, and the liquidation process fails when attempting to queue new rewards in the reward contract due to insufficient funds.
Impact
The second step of the liquidation process within the LiquidationRow contract, specifically, the liquidateVaultsForToken function, is broken and reverts anytime a liquidation is performed.
240: function _performLiquidation(
241: uint256gasBefore,
242: addressfromToken,
243: addressasyncSwapper,
244: IDestinationVault[] memoryvaultsToLiquidate,
245: SwapParams memoryparams,
246: uint256totalBalanceToLiquidate,
247: uint256[] memoryvaultsBalances248: ) private {
249: uint256 length = vaultsToLiquidate.length;
250: // the swapper checks that the amount received is greater or equal than the params.buyAmount251: ❌ uint256 amountReceived =IAsyncSwapper(asyncSwapper).swap(params);
252:
253: // if the fee feature is turned on, send the fee to the fee receiver254: if (feeReceiver !=address(0) && feeBps >0) {
255: uint256 fee =calculateFee(amountReceived);
256: emitFeesTransfered(feeReceiver, amountReceived, fee);
257:
Consider also using a delegatecall in the LiquidationRow._performLiquidation function to call the BaseAsyncSwapper.swap function, similar to the LMPVaultRouter contract.
sherlock-admin2
changed the title
Nice Maroon Frog - Performing the liquidation process reverts due to failing to swap the reward tokens
berndartmueller - Performing the liquidation process reverts due to failing to swap the reward tokens
Oct 3, 2023
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
berndartmueller
high
Performing the liquidation process reverts due to failing to swap the reward tokens
Summary
The
liquidateVaultsForToken
function in theLiquidationRow
contract fails to properly swap the reward tokens, causing the liquidation process to fail.Vulnerability Detail
During the liquidation process, destination vault LP rewards are claimed, reward tokens are swapped to the desired token (usually the base asset WETH), and distributed to the respective rewarder contracts of the destination vaults. The actual token swap is performed via the
swap
function of theBaseAsyncSwapper
contract.The liquidation process fails due to two issues:
The
LiquidationRow.liquidateVaultsForToken
does not approve theBaseAsyncSwapper
contract to spend the reward tokens, and theBaseAsyncSwapper
contract does not pull in the reward tokens from theLiquidationRow
contract. Thus, theswap
function fails due to insufficient funds.The
swap
function sells the givensellTokenAddress
for the desiredbuyTokenAddress
via a configured aggregator service. After the successful swap via the aggregator, theswap
function determines the actual amount ofbuyTokenAddress
received (buyTokenAmountReceived
) and reverts if it is less than thebuyAmount
specified in theSwapParams
struct, we can conclude that theBaseAsyncSwapper
is expected to be the receiver of the swapped tokens.The
swap
function does not transfer the boughtbuyToken
tokens to the caller. This is expected in the case of theLMPVaultRouter
contract as theswap
function is called via adelegatecall
.However, the
LiquidationRow
contract calls theswap
function with an ordinarycall
in the_performLiquidation
function, as seen in line 251. Consequently, theLiquidationRow
contract does not receive the bought tokens from the swapper, and the liquidation process fails when attempting to queue new rewards in the reward contract due to insufficient funds.Impact
The second step of the liquidation process within the
LiquidationRow
contract, specifically, theliquidateVaultsForToken
function, is broken and reverts anytime a liquidation is performed.Code Snippet
src/liquidation/LiquidationRow.sol#L251
src/liquidation/BaseAsyncSwapper.sol#L63
Tool used
Manual Review
Recommendation
Consider also using a
delegatecall
in theLiquidationRow._performLiquidation
function to call theBaseAsyncSwapper.swap
function, similar to theLMPVaultRouter
contract.Duplicate of #205
The text was updated successfully, but these errors were encountered: