DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: medium
Invalid

Potential Issues with Tokens That Have Fee-on-Transfer or Deflationary Mechanics

Description

The StrategyOp contract assumes that the asset and underlying tokens (alETH and WETH) conform to the standard ERC20 behavior, where the amount of tokens transferred is equal to the amount specified in the transfer or transferFrom function calls. However, if a token implements a fee-on-transfer (deflationary token), where a portion of the tokens is burned or taken as a fee during transfers, this assumption fails.

For example, in the _swapUnderlyingToAsset function:

function _swapUnderlyingToAsset(
uint256 _amount,
uint256 minOut,
IVeloRouter.route[] calldata _path
) internal {
require(minOut > _amount, "minOut too low");
uint256 underlyingBalance = underlying.balanceOf(address(this));
require(underlyingBalance >= _amount, "not enough underlying balance");
IVeloRouter(router).swapExactTokensForTokens(
_amount,
minOut,
_path,
address(this),
block.timestamp
);
}

If the underlying token (WETH) were a deflationary token, transferring _amount to the router could result in the router receiving fewer tokens than _amount, potentially causing the swap to fail or receive less output than expected.

Similarly, when depositing or withdrawing from the transmuter, the contract could experience discrepancies in the amounts due to the token's deflationary mechanics.

Impact

  • Swap Failures: Swaps might fail or result in receiving fewer tokens than expected, leading to slippage or unmet minOut requirements.

  • Incorrect Accounting: The strategy's internal accounting might become inaccurate, leading to potential losses or miscalculations in yields and shares.

  • Operational Issues: Repeated failures or discrepancies could affect the strategy's performance and reliability.

Proof of Concept (PoC)

  1. Scenario:

    • Assume that the underlying token starts charging a 1% fee on every transfer.

  2. Swap Attempt:

    • The strategy attempts to swap 100 WETH for alETH.

    • Due to the fee, only 99 WETH are received by the router.

  3. Outcome:

    • The swap may fail because the router did not receive the expected amount.

    • Alternatively, the swap completes but results in fewer asset tokens received, potentially violating the minOut condition.

Recommendations

  • Implement Amount Checks Post-Transfer:

    • After transferring tokens, verify the actual amount received or remaining balances to adjust calculations accordingly.

  • Use safeTransferFrom and Check Return Values:

    • When using SafeERC20.safeTransferFrom, confirm that the actual transferred amount matches expectations.

  • Adjust for Fee-on-Transfer Tokens:

    • Introduce logic to handle tokens with transfer fees.

      function _swapUnderlyingToAsset(
      uint256 _amount,
      uint256 minOut,
      IVeloRouter.route[] calldata _path
      ) internal {
      uint256 balanceBefore = underlying.balanceOf(address(this));
      IVeloRouter(router).swapExactTokensForTokens(
      _amount,
      minOut,
      _path,
      address(this),
      block.timestamp
      );
      uint256 balanceAfter = underlying.balanceOf(address(this));
      uint256 actualTransferred = balanceBefore - balanceAfter;
      // Use 'actualTransferred' in further calculations
      }
Updates

Appeal created

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.