Lucene search

K
code423n4Code4renaCODE423N4:2022-08-MIMO-FINDINGS-ISSUES-150
HistoryAug 07, 2022 - 12:00 a.m.

Everyone can perform emptyVaultOperation. Everyone can steal leftover par after repaying the loan from any vault. This pattern also applied to other files.

2022-08-0700:00:00
Code4rena
github.com
6

Lines of code
<https://github.com/code-423n4/2022-08-mimo/blob/eb1a5016b69f72bc1e4fd3600a65e908bd228f13/contracts/actions/MIMOSwap.sol#L40-L65&gt;

Vulnerability details

Impact

Everyone can perform emptyVaultOperation. Everyone can steal leftover par after repaying the loan from any vault. It is intended to only be able to call from executeOperation through MIMOProxy callback but in fact everyone can execute it.

Proof of Concept

There aren’t any check on msg.sender which mean everyone can execute it as seen below

  function emptyVaultOperation(
    IERC20 vaultCollateral,
    uint256 vaultId,
    uint256 swapAmount,
    SwapData calldata swapData
  ) external {
    IVaultsCore core = a.core();

    _aggregatorSwap(vaultCollateral, swapAmount, swapData);

    IERC20 stablex = IERC20(a.stablex());
    stablex.safeIncreaseAllowance(address(core), stablex.balanceOf(address(this)));
    core.repayAll(vaultId);

    uint256 withdrawAmount = a.vaultsData().vaultCollateralBalance(vaultId);

    core.withdraw(vaultId, withdrawAmount);
    vaultCollateral.safeTransfer(msg.sender, withdrawAmount);
  }

...

  function _aggregatorSwap(
    IERC20 token,
    uint256 amount,
    SwapData calldata swapData
  ) internal {
    (address proxy, address router) = dexAP.getDex(swapData.dexIndex);

    require(proxy != address(0), Errors.INVALID_AGGREGATOR);
    require(router != address(0), Errors.INVALID_AGGREGATOR);

    token.safeIncreaseAllowance(proxy, amount);

    (bool success, bytes memory response) = router.call(swapData.dexTxData);

    if (!success) {
      // If there is return data, the call reverted with a reason or a custom error.
      if (response.length &gt; 0) {
        assembly {
          let returndata_size := mload(response)
          revert(add(32, response), returndata_size)
        }
      } else {
        revert(Errors.AGGREGATOR_CALL_FAILED);
      }
    }
  }

After core.repayAll(vaultId); There will likely be some leftover par after repaying the loan; that will also be sent back to everyone that call emptyVaultOperation.

This pattern also applied to other files such as leverageOperation in MIMOLeverage can be used to steal flashloanRepayAmount

Tools Used

Manual review

Recommended Mitigation Steps

Check msg.sender before executing the logic in emptyVaultOperation


The text was updated successfully, but these errors were encountered:

All reactions