Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

obront - LP tokens are not sent back to withdrawing user #151

Open
github-actions bot opened this issue Mar 1, 2023 · 1 comment
Open

obront - LP tokens are not sent back to withdrawing user #151

github-actions bot opened this issue Mar 1, 2023 · 1 comment
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@github-actions
Copy link

github-actions bot commented Mar 1, 2023

obront

high

LP tokens are not sent back to withdrawing user

Summary

When users withdraw their assets from IchiVaultSpell.sol, the function unwinds their position and sends them back their assets, but it never sends them back the amount they requested to withdraw, leaving the tokens stuck in the Spell contract.

Vulnerability Detail

When a user withdraws from IchiVaultSpell.sol, they either call closePosition() or closePositionFarm(), both of which make an internal call to withdrawInternal().

The following arguments are passed to the function:

  • strategyId: an index into the strategies array, which specifies the Ichi vault in question
  • collToken: the underlying token, which is withdrawn from Compound
  • amountShareWithdraw: the number of underlying tokens to withdraw from Compound
  • borrowToken: the token that was borrowed from Compound to create the position, one of the underlying tokens of the vault
  • amountRepay: the amount of the borrow token to repay to Compound
  • amountLpWithdraw: the amount of the LP token to withdraw, rather than trade back into borrow tokens

In order to accomplish these goals, the contract does the following...

  1. Removes the LP tokens from the ERC1155 holding them for collateral.
doTakeCollateral(strategies[strategyId].vault, lpTakeAmt);
  1. Calculates the number of LP tokens to withdraw from the vault.
uint256 amtLPToRemove = vault.balanceOf(address(this)) - amountLpWithdraw;
vault.withdraw(amtLPToRemove, address(this));
  1. Converts the non-borrowed token that was withdrawn in the borrowed token (not copying the code in, as it's not relevant to this issue).

  2. Withdraw the underlying token from Compound.

doWithdraw(collToken, amountShareWithdraw);
  1. Pay back the borrowed token to Compound.
doRepay(borrowToken, amountRepay);
  1. Validate that this situation does not put us above the maxLTV for our loans.
_validateMaxLTV(strategyId);
  1. Sends the remaining borrow token that weren't paid back and withdrawn underlying tokens to the user.
doRefund(borrowToken);
doRefund(collToken);

Crucially, the step of sending the remaining LP tokens to the user is skipped, even though the function specifically does the calculations to ensure that amountLpWithdraw is held back from being taken out of the vault.

Impact

Users who close their positions and choose to keep LP tokens (rather than unwinding the position for the constituent tokens) will have their LP tokens stuck permanently in the IchiVaultSpell contract.

Code Snippet

https://github.com/sherlock-audit/2023-02-blueberry/blob/main/contracts/spell/IchiVaultSpell.sol#L276-L330

Tool used

Manual Review

Recommendation

Add an additional line to the withdrawInternal() function to refund all LP tokens as well:

  doRefund(borrowToken);
  doRefund(collToken);
+ doRefund(address(vault));
@github-actions github-actions bot added Has Duplicates A valid issue with 1+ other issues describing the same vulnerability High A valid High severity issue labels Mar 1, 2023
@Gornutz Gornutz added Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Mar 8, 2023
@Gornutz
Copy link

Gornutz commented Mar 10, 2023

duplicate of 34

@sherlock-admin sherlock-admin added Reward A payout will be made for this issue and removed Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Mar 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

3 participants
@Gornutz @sherlock-admin and others