0

I am trying to create a simple function that buys a token from uniswap (v1) and then immediately sells the token back to ether. I am able to buy successfully but when adding the calls to the sell function (after buy) it fails.

I am using remix to deploy to Ropsten. Here's my code:

pragma solidity >=0.6.2;
pragma experimental ABIEncoderV2;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.1.0/contracts/token/ERC20/ERC20.sol";

interface UniswapExchangeInterface {
    // Address of ERC20 token sold on this exchange
    function tokenAddress() external view returns (address token);
    // Address of Uniswap Factory
    function factoryAddress() external view returns (address factory);
    // Provide Liquidity
    function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256);

    function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256);
    // Get Prices
    function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought);

    function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold);

    function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought);

    function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold);
    // Trade ETH to ERC20
    function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256 tokens_bought);

    function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought);

    function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256 eth_sold);

    function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold);
    // Trade ERC20 to ETH
    function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256 eth_bought);

    function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256 eth_bought);

    function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256 tokens_sold);

    function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold);
    // Trade ERC20 to ERC20
    function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256 tokens_bought);

    function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought);

    function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256 tokens_sold);

    function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold);
    // Trade ERC20 to Custom Pool
    function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256 tokens_bought);

    function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_bought);

    function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256 tokens_sold);

    function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_sold);
    // ERC20 comaptibility for liquidity tokens
    //bytes32 public name;
    //bytes32 public symbol;
    //uint256 public decimals;
    function transfer(address _to, uint256 _value) external returns (bool);

    function transferFrom(address _from, address _to, uint256 value) external returns (bool);

    function approve(address _spender, uint256 _value) external returns (bool);

    function allowance(address _owner, address _spender) external view returns (uint256);

    function balanceOf(address _owner) external view returns (uint256);

    function totalSupply() external view returns (uint256);
    // Never use
    function setup(address token_addr) external;
}

interface UniswapFactoryInterface {
    // Public Variables
    //address public exchangeTemplate;
    //uint256 public tokenCount;
    // Create Exchange
    function createExchange(address token) external returns (address exchange);
    // Get Exchange and Token Info
    function getExchange(address token) external view returns (address exchange);

    function getToken(address exchange) external view returns (address token);

    function getTokenWithId(uint256 tokenId) external view returns (address token);
    // Never use
    function initializeFactory(address template) external;
}

interface ERC20Interface {
    function totalSupply() external view returns (uint);

    function balanceOf(address tokenOwner) external view returns (uint balance);

    function allowance(address tokenOwner, address spender) external view returns (uint remaining);

    function transfer(address to, uint tokens) external returns (bool success);

    function approve(address spender, uint tokens) external returns (bool success);

    function transferFrom(address from, address to, uint tokens) external returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

contract MyContract {
    function buyAndSell() payable public {
        uint256 tradeSize = msg.value;

        address daiExchangeAddress = 0xc0fc958f7108be4060F33a699a92d3ea49b0B5f0;
        ERC20 daiToken = ERC20(0xaD6D458402F60fD3Bd25163575031ACDce07538D);

        UniswapExchangeInterface usi = UniswapExchangeInterface(daiExchangeAddress);

        uint256 daiAmount = buyCurrencyUniswapV1(usi, daiToken, tradeSize);
        emit successfulTrade(tradeSize, "ETH", daiAmount, "DAI");
        uint256 ethFromDai = sellCurrencyUniswapV1(usi, daiAmount);
        emit successfulTrade(daiAmount, "DAI", ethFromDai, "ETH");
    }

    function buyCurrencyUniswapV1(UniswapExchangeInterface usi, ERC20 token, uint256 tradeSize) private returns (uint256) {
        //do the exchange
        uint256 tokensBack = usi.ethToTokenSwapInput.value(tradeSize)(1, block.timestamp);

        //send tokens to sender
        //token.transfer(msg.sender, tokensBack);

        return tokensBack;
    }

    function sellCurrencyUniswapV1(UniswapExchangeInterface usi, uint256 tradeSize) private returns (uint256) {
        uint256 etherBack = usi.tokenToEthSwapInput(tradeSize, 1, block.timestamp);

        //send ether to sender
        //msg.sender.transfer(etherBack);

        return etherBack;
    }

    event successfulTrade(uint256 fromAmount, string fromCurrency, uint256 toAmount, string toCurrency);
}

I am not xfering the tokens from the smart contract back to the sender, so they should be available for the 2nd trade (sell). What am I doing wrong?

Thanks

  • Please post: 1. The exact sequence of functions that you are executing, including the parameters that you are passing to each function. 2. The addresses of all related contracts (uniswap, tokens, etc) on ropsten. – goodvibration Jul 1 at 11:44
  • @goodvibration 1. i'm calling buyAndSell() with a ether value of 0.01 (payable). 2. all the contract addresses are hardcoded in the buyAndSell functions. see the daiExchangeAddress and daiTokenAddress in that function. thanks – Spyros Jul 1 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.