0

So I finally am almost finished with my flashloan arbitrage how ever when I run it I get this error

'SafeERC20: low-level call failed'

here is my contract code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "https://github.com/sushiswap/sushiswap/blob/master/contracts/uniswapv2/interfaces/IUniswapV2Router01.sol";
import { ILendingPool, ILendingPoolAddressesProvider, IERC20 } from "./Interfaces.sol";
import { FlashLoanReceiverBase } from "./FlashLoanReceiverBase.sol";
import { Withdrawable } from "./Withdrawable.sol";

/** 
!!!
Never keep funds permanently on your FlashLoanReceiverBase contract as they could be 
exposed to a 'griefing' attack, where the stored funds are used by an attacker.
!!!
 */

    contract FlashloanSushiswapToQuickswap is FlashLoanReceiverBase, Withdrawable {

    address Sushiswap_Router = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506;
    address Quickswap_Router = 0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff; 
    address Tether = 0xc2132D05D31c914a87C6611C10748AEb04B58e8F;
    address Wmatic = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270;
    uint256 Amount = ( 1000000 * 1e18 );

    IERC20 token;

    constructor(ILendingPoolAddressesProvider _addressProvider) 
    FlashLoanReceiverBase(_addressProvider) {
        }
     /**
     * @dev This function must be called only be the LENDING_POOL and takes care of 
     repaying
     * active debt positions, migrating collateral and incurring new V2 debt token debt.
     *
     * @param assets The array of flash loaned assets used to repay debts.
     * @param amounts The array of flash loaned asset amounts used to repay debts.
     * @param premiums The array of premiums incurred as additional debts.
     * @param initiator The address that initiated the flash loan, unused.
     * @param params The byte array containing, in this case, the arrays of aTokens and 
     aTokenAmounts.
     */


function executeOperation(
    address[] calldata assets,
    uint256[] calldata amounts,
    uint256[] calldata premiums,
    address initiator,
    bytes calldata params
)
    external
    override
    returns (bool)
{     
    // This contract now has the funds requested.
    // Your logic goes here.

   uint Start = IERC20(Tether).balanceOf(address(this));
    token.approve(Sushiswap_Router, Amount);
    token.approve(Quickswap_Router, Amount);

    address[] memory path1 = new address[](2);
    path1[0] = address(Tether);
    path1[1] = address(Wmatic);

    IUniswapV2Router01(Sushiswap_Router).swapExactTokensForTokens
    (Amount, Amount, path1, address(this), block.timestamp + 300);

    address[] memory path2 = new address[](2);
    path2[0] = address(Wmatic);
    path2[1] = address(Tether);

    IUniswapV2Router01(Quickswap_Router).swapExactTokensForTokens
    (Amount, Amount, path2, address(this), block.timestamp + 300);

    uint End = IERC20(Tether).balanceOf(address(this));
    require(End > Start, "No Profit Made");

    // At the end of your logic above, this contract owes
    // the flashloaned amounts + premiums.
    // Therefore ensure your contract has enough to repay
    // these amounts.

    // Approve the LendingPool contract allowance to *pull* the owed amount
    for (uint i = 0; i < assets.length; i++) {
        uint amountOwing = amounts[i]+(premiums[i]);
        IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
    }

    return true;
}

function _flashloan(address[] memory assets, uint256[] memory amounts) internal {
    address receiverAddress = address(this);

    address onBehalfOf = address(this);
    bytes memory params = "";
    uint16 referralCode = 0;

    uint256[] memory modes = new uint256[](assets.length);

    // 0 = no debt (flash), 1 = stable, 2 = variable
    for (uint256 i = 0; i < assets.length; i++) {
        modes[i] = 0;
    }

    LENDING_POOL.flashLoan(
        receiverAddress,
        assets,
        amounts,
        modes,
        onBehalfOf,
        params,
        referralCode
    );
}

/*
 *  Flash loan wei amount worth of `_asset` 304061637379130
 */
function flashloan(address _asset, uint256 _amount) public {
    bytes memory data = "";
    uint amount = _amount;

    address[] memory assets = new address[](1);
    assets[0] = _asset;

    uint256[] memory amounts = new uint256[](1);
    amounts[0] = ( amount * 1e18 );

    _flashloan(assets, amounts);
}

}

my javascript code is like this

var ethers = require('ethers');
var IUniswapV2Router02 = require('./IUniswapV2Router02.json')
var SushiToQuick = require('./SushiToQuick.json');
var QuickToSushi = require('./QuickToSushi.json');
const maticProvider = new ethers.providers.JsonRpcProvider(procces.env.provider_url);

const TETHER = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F';
const WMATIC = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270';
const TETHER_ = ['0xc2132D05D31c914a87C6611C10748AEb04B58e8F'];

  const Amount = '1000000';
  const Amount_ = ['1000000'];
  const Premiums = ['1'];

  const SushiToQuickflashloanAddress = "0x4Ccb64D17eB9DaB48A5F0C51a27fC1E277708D69";
  const QuickToSushiFlashloanAddress = "0x50332903B054d381cD1De30166683dA4A6d79174";
  const SushiRouterAddress = "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506";
  const QuickRouterAddress = "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff";

  const private_key = process.env.privateKey;
  const myAccount = "0x39D780E2e82b76fCE187C5d4b080E2DD6b32F746";

  if ( private_key === undefined) { throw new Error("Private key is not defined");
  }

 async function SushiTetherToWmaticFlashloanArbitrage() {
 const signer = new ethers.Wallet( private_key, maticProvider );
 const SushiToQuickFlashloan = new ethers.Contract(SushiToQuickflashloanAddress, 
SushiToQuick, signer);
const SushiRouter = new ethers.Contract(SushiRouterAddress, IUniswapV2Router02, signer);
const QuickRouter = new ethers.Contract(QuickRouterAddress, IUniswapV2Router02, signer);
const SushiScanTetherToWmatic = await SushiRouter.getAmountsOut(Amount, [TETHER, 
WMATIC]);
const QuickScanTetherToWmatic = await QuickRouter.getAmountsOut(Amount, [TETHER, WMATIC]);


       if (SushiScanTetherToWmatic >= ( QuickScanTetherToWmatic + ( QuickScanTetherToWmatic / 100 
       * 1 ))) {

       console.log("Trade Is Profitable")  

        await SushiToQuickFlashloan.flashloan(TETHER, Amount, { gasPrice: 
        ethers.utils.parseUnits('30000', 'gwei'), gasLimit: 2500000 
        } )
       SushiToQuickflashloanAddress, 0x000000000, { gasPrice: 
       ethers.utils.parseUnits('30000', 
      'gwei'), gasLimit: 2500000 } )

     }

   else { console.log("No Opportunities For This Trade");

       }
    }

 SushiTetherToWmaticFlashloanArbitrage();

I don't know what it could be as the tokens are being approved and the get amounts out should make sure that it's profitable so I don't seem to know why it doesn't work here is the failed transaction https://polygonscan.com/tx/0x9eccd2f85e4154fb186c410557906adcd7222548e2b3cbbee2c55f9bfae69f67

1 Answer 1

0

So I figured it out theIERC20 token; part of the smart contract had nothing to refer to so I wasn't approving anything

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.