I'm trying to swap USDC to/from DAI. USDC to DAI swap works fine, but the revers ALWAYS fails

The smart contract im using is EXACTLY simpletokenswap.sol, the only modification I made was that uint(-1) in the original contract breaks the compiler, so i modified it to "type(uint256).max" instead.

The fillquote code in entirety:

function fillQuote(
        // The `sellTokenAddress` field from the API response.
        IERC20 sellToken,
        // The `buyTokenAddress` field from the API response.
        IERC20 buyToken,
        // The `allowanceTarget` field from the API response.
        address spender,
        // The `to` field from the API response.
        address payable swapTarget,
        // The `data` field from the API response.
        bytes calldata swapCallData
        payable // Must attach ETH equal to the `value` field from the API response.
        // Track our balance of the buyToken to determine how much we've bought.
        uint256 boughtAmount = buyToken.balanceOf(address(this));

        // Give `spender` an infinite allowance to spend this contract's `sellToken`.
        // Note that for some tokens (e.g., USDT, KNC), you must first reset any existing
        // allowance to 0 before being able to update it.
        require(sellToken.approve(spender, type(uint256).max));
        // Call the encoded swap function call on the contract at `swapTarget`,
        // passing along any ETH attached to this function call to cover protocol fees.
        (bool success,) = swapTarget.call{value: msg.value}(swapCallData);
        require(success, 'SWAP_CALL_FAILED');
        // Refund any unspent protocol fees to the sender.

        // Use our current buyToken balance to determine how much we've bought.
        boughtAmount = buyToken.balanceOf(address(this)) - boughtAmount;

Code for web3.js (for quote request)

const sellToken = "DAI";
const buyToken  = "USDC";

 selllAmount = value of DAI balance of smart contract
 after USDC-DAI swap, which you can see here
const sellAmount= "1507099614911829913"; 

const swap = {
    "sellToken"         : sellToken, 
    "buyToken"          : buyToken, 
    "sellAmount"        : sellAmount

const qs = createQueryString({
    "sellToken" : sellToken,
    "buyToken"  : buyToken,
    "sellAmount": sellAmount,
    "slippagePercentage" : 0.001

const API_QUOTE_URL=`https://ropsten.api.0x.org/swap/v1/quote`;
const quoteUrl = `${API_QUOTE_URL}?${qs}`;

const q1 = {
    "json" : await fetch(quoteUrl);

await the_contract.methods.fillQuote(
    from: account.address,
    value: q1.json.value,
    gasPrice: q1.json.gasPrice,
    gas: 500000

Error from smart contract:


Im not sure how to fix this issue.. it would be helpful if there was some more "verbose" response from the swap fails. Could this be

  1. slippagePercentage being set too low? i tried setting slippagePercentage as high as 0.1 but still getting same error
  2. lack of liquidity issue on ropsten network?
  3. am I selling too much weth? (i.e gas being paid by weth) I am using the ENTIRE balance of weth in sellAmount

Would appreciate any insight

EDIT - This is happening also with WETH (ie. USDC<=> WETH)

  • 1
    Looks like it reverted in Uniswap V3. The contract we're using on Ropsten appears to be old. I'll update this and do some testing. When an EOA uses the API we can provide better revert reasons since we can fully validate the transaction. This is done by supplying takerAddress. Unfortunately it is left up to the developer when a contract is used. Mar 7, 2022 at 0:34
  • Give it a try now. There was a mismatched deploy which went out to Ropsten ~5 days ago. From our end it looks fixed now. Mar 7, 2022 at 1:50
  • Seems to work fine now. Thanks Jacob. Love the quick response. I'll remember that "takerAddress" trick. Was that in the docs? I dont recall reading it.
    – TaeWoo
    Mar 7, 2022 at 6:49


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.