sherlock-audit / 2023-04-blueberry-judging

8 stars 5 forks source link

Ch_301 - the core logic of `ShortLongSpell` is breaked #138

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

Ch_301

medium

the core logic of ShortLongSpell is breaked

Summary

Vulnerability Detail

on ShortLongSpell.openPosition() from this check

        if (
            address(ISoftVault(strategy.vault).uToken()) != param.borrowToken ||
            swapData.fromToken != param.borrowToken
        ) revert Errors.INCORRECT_LP(param.borrowToken);

we know address(ISoftVault(strategy.vault).uToken()) == param.borrowToken and swapData.fromToken == param.borrowToken now in ShortLongSpell.openPosition()._deposit() this is the computation of strTokenAmt

        // 2. Borrow specific amounts
        uint256 strTokenAmt = _doBorrow(param.borrowToken, param.borrowAmount);

        // 3. Swap borrowed token to strategy token
        IERC20Upgradeable swapToken = ISoftVault(strategy.vault).uToken();
        // swapData.fromAmount = strTokenAmt;
        PSwapLib.megaSwap(augustusSwapper, tokenTransferProxy, swapData);
        strTokenAmt = swapToken.balanceOf(address(this)) - strTokenAmt;
        if (strTokenAmt < swapData.expectedAmount)
            revert Errors.SWAP_FAILED(address(swapToken));

the strTokenAmt is the borrowed amount of param.borrowToken token swapToken is the same param.borrowToken

swapToken.balanceOf(address(this)) == IERC20(param.borrowToken).balanceOf(address(this)) 

After the swap swapToken.balanceOf(address(this)) will be <= with strTokenAmt so it will revert or the strTokenAmt will be zero strTokenAmt == 0

Now If swapData.expectedAmount > 0 (this is normal otherwise you will get frontrun) this check is always true and it will keep reverting

        if (strTokenAmt < swapData.expectedAmount)
            revert Errors.SWAP_FAILED(address(swapToken));

Impact

ShortLongSpell.openPosition() will keep reverting

Code Snippet

Tool used

Manual Review

Recommendation

use before and after balanceOf()

Duplicate of #133