Skip to content

Contract Bug Report #1

@DarkCoder-01

Description

@DarkCoder-01

Problem description

I tried to interact with the contract through JavaScript, but during the interaction, I was affected by the getAmountsOut contract interface, which resulted in an indirect loss of over $500 in my two interactions. I hope that the official can provide a response.

POC

Here is the code poc.js

import { ethers } from 'ethers';
import { Wallet, Provider } from "zksync-web3";

// Please replace with your infura provider API key
const infuraProviderApiKey = "c0************************662";

// Please replace with your wallet private key
const privateKey = "e**********************************************a"

const wEthAddress = "0x5aea5775959fbc2557cc8789bc1bf90a239d9a91";
const usdcAddress = "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4";

const muteSwitchRouterAddress = "0x8B791913eB07C32779a16750e3868aA8495F5964";

// For a more comprehensive ABI, please refer to https://wiki.mute.io/mute/mute-switch-api/abis
const routerABI = [
    {
        "inputs": [{
            "internalType": "uint256",
            "name": "amountIn",
            "type": "uint256"
        }, {
            "internalType": "address[]",
            "name": "path",
            "type": "address[]"
        }, {
            "internalType": "bool[]",
            "name": "stable",
            "type": "bool[]"
        }],
        "name": "getAmountsOut",
        "outputs": [{
            "internalType": "uint256[]",
            "name": "amounts",
            "type": "uint256[]"
        }],
        "stateMutability": "view",
        "type": "function"
    }
]

async function getAmountsOut(wallet, _tokenIn, _tokenOut, _amountIn, _stable) {
    const router = new ethers.Contract(muteSwitchRouterAddress, routerABI, wallet);

    const amountIn = _tokenIn === wEthAddress ? ethers.utils.parseEther(_amountIn) : ethers.utils.parseUnits(_amountIn, 6);
    const path = [_tokenIn, _tokenOut];

    const amountOutRes = await router.getAmountsOut(amountIn, path, _stable);
    // console.log(amountOutRes);
    const amountOutMin = amountOutRes[1];

    const amountOut = _tokenOut === wEthAddress ? ethers.utils.formatEther(amountOutMin) : ethers.utils.formatUnits(amountOutMin, 6);

    console.log(`Swap ${_amountIn} ${_tokenIn === wEthAddress ? 'ETH' : 'USDC'} to ${_tokenOut === wEthAddress ? 'ETH' : 'USDC'} you will received: ${amountOut} by using parameters [${_stable}]`);
    return amountOutMin;
}

async function compare() {
    const ethersProvider = new ethers.providers.InfuraProvider("homestead", infuraProviderApiKey);
    const zkSyncProvider = new Provider("https://mainnet.era.zksync.io");
    const wallet = new Wallet(privateKey, zkSyncProvider, ethersProvider);

    var stable = [true, false];
    await getAmountsOut(wallet, wEthAddress, usdcAddress, "0.5", stable);

    stable = [false, true];
    await getAmountsOut(wallet, wEthAddress, usdcAddress, "0.5", stable);
}

await compare();

package.json

"dependencies": {
    "ethers": "^5.7.2",
    "zksync-web3": "^0.16.0"
  }

Run Step

npm install
node poc.js

Result

Swap 0.5 ETH to USDC you will received: 832.881692 by using parameters [true,false]
Swap 0.5 ETH to USDC you will received: 1123.559205 by using parameters [false,true]

Conclusion

As you can see, the stable parameter is very confusing, and both parameters can complete the interaction normally, but the amount difference is very significant, which leads to a direct loss of over $500 for my following interaction.
https://explorer.zksync.io/tx/0xd9b3975447a9864c168317f62fb32559d066d9f89fd08db79ba300153b82e5b8
https://explorer.zksync.io/tx/0xe4edcccd8123e65e499ccbb9adb0ffcceb8227cbaff8ecefd44e3daf6349ec2c

I am looking forward to the official reply. Is this a contract specific mechanism or should it be considered a contract defect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions