Skip to content

Latest commit

 

History

History
74 lines (57 loc) · 2.52 KB

008.md

File metadata and controls

74 lines (57 loc) · 2.52 KB

Gorgeous Maroon Stallion

High

defiToStablecoinSwap should change the value of ss.oAmount first before calling _verifyDefiSwap

Vulnerability Details

In defiToStablecoinSwap:

function defiToStablecoinSwap(
    address wallet,
    StablecoinSwap memory ss,
    DefiSwap memory defi
) external payable onlyRole(SWAPPER_ROLE) whenNotPaused {
      // checks if defi will fail
      _verifyDefiSwap(wallet, defi);
      // checks if stablecoin swap will fail
1.)-> _verifyStablecoinSwap(wallet, ss);

      //check balance to adjust second swap
      uint256 iBalance = ERC20(ss.origin).balanceOf(wallet);
      _defiSwap(wallet, defi);
      uint256 fBalance = ERC20(ss.origin).balanceOf(wallet);
2.)-> ss.oAmount = fBalance - iBalance;
      //change balance to reflect change
      _stablecoinSwap(wallet, ss);
}

_verifyStablecoinSwap is in charge of making sure Stablecoin(ss.origin).totalSupply() - ss.oAmount >= getMinLimit(ss.origin).

By calling _verifyStablecoinSwap, before the real value of ss.oAmount is set, causes the code to check with the wrong value of ss.oAmount.

Impact

The real ss.oAmount could cause Stablecoin(ss.origin).totalSupply() to drop below getMinLimit(ss.origin).

This is because after ss.oAmount is set to its new value, the internal function _stablecoinSwap is called, and unlike the external function stablecoinSwap, the internal function does not call _verifyStablecoinSwap to check.

Hence, the invalid transaction will end up going through, wrongly allowing totalSupply to break below getMinLimit(ss.origin).

Tools Used

Manual Review VSCode

Code Snippet

https://github.com/sherlock-audit/2024-11-telcoin/blob/b9c751b59e78a7123a636e31ecafc9147046f190/telcoin-audit/contracts/swap/AmirX.sol#L111-L128

Mitigation

Move the _verifyStablecoinSwap call to below the line where ss.oAmount changes.

function defiToStablecoinSwap(
    address wallet,
    StablecoinSwap memory ss,
    DefiSwap memory defi
) external payable onlyRole(SWAPPER_ROLE) whenNotPaused {
    // checks if defi will fail
    _verifyDefiSwap(wallet, defi);
    // checks if stablecoin swap will fail
-   _verifyStablecoinSwap(wallet, ss);

    //check balance to adjust second swap
    uint256 iBalance = ERC20(ss.origin).balanceOf(wallet);
    _defiSwap(wallet, defi);
    uint256 fBalance = ERC20(ss.origin).balanceOf(wallet);
    ss.oAmount = fBalance - iBalance;
    //change balance to reflect change
+   _verifyStablecoinSwap(wallet, ss);    
    _stablecoinSwap(wallet, ss);
}