Skip to content

Latest commit

 

History

History
80 lines (50 loc) · 2.42 KB

089.md

File metadata and controls

80 lines (50 loc) · 2.42 KB

Salty Powder Sealion

Medium

Missing Approval Checks in Core Swap Functions

Summary

The core swap functions (StablecoinHandler::_stablecoinSwap and AmirX::swap) lack explicit approval checks for tokens being transferred, despite the protocol specification requiring such checks. https://github.com/sherlock-audit/2024-11-telcoin/blob/main/telcoin-audit/contracts/stablecoin/StablecoinHandler.sol#L144 https://github.com/sherlock-audit/2024-11-telcoin/blob/main/telcoin-audit/contracts/swap/AmirX.sol#L73

Root Cause

The root cause is a design oversight where the protocol relies on implicit approval checks through safeTransferFrom failures rather than implementing explicit pre-flight approval validation.

Internal pre-conditions

  1. SWAPPER_ROLE needs to call stablecoinSwap() or swap() with valid parameters.

  2. Contract needs to be unpaused

External pre-conditions

No response

Attack Path

  1. SWAPPER_ROLE calls the swap functions.
  2. Functions attempts safeTransferFrom without checking approvals
  3. Transaction reverts due to insufficient allowance

Impact

  1. Transactions will silently revert if approvals aren't set
  2. Poor user experience
  3. Wasted gas on failed transactions
  4. Violates protocol specification

PoC

No response

Mitigation

Adding explicit approval check:

   function _stablecoinSwap(address wallet, StablecoinSwap memory ss) internal {
        if (ss.stablecoinFeeCurrency != address(0) && ss.stablecoinFeeSafe != address(0)) {
+            require(ERC20(ss.stablecoinFeeCurrency).allowance(wallet, address(this)) >= ss.feeAmount,
                "Insufficient fee token allowance"
            );
            ERC20PermitUpgradeable(ss.stablecoinFeeCurrency).safeTransferFrom(
                wallet, ss.stablecoinFeeSafe, ss.feeAmount
            );
        }

        if (isXYZ(ss.origin)) {
           
 
+        require(ERC20(ss.origin).allowance(wallet,address(this))>=ss.oAmount,"Insufficient origin token allowance"
            Stablecoin(ss.origin).burnFrom(wallet, ss.oAmount);
        } else {
            ERC20PermitUpgradeable(ss.origin).safeTransferFrom(wallet, ss.liquiditySafe, ss.oAmount);
        }

        if (isXYZ(ss.target)) {
            Stablecoin(ss.target).mintTo(ss.destination, ss.tAmount);
        } else {
            ERC20PermitUpgradeable(ss.target).safeTransferFrom(ss.liquiditySafe, ss.destination, ss.tAmount);
        }
    }

    ```