Hello, I am testing currently following uniswap code with Remix but always getting following error:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
I've filled the data like following:
My goal is it to swap from custom token to BNB and vice versa.
What I am doing wrong?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// https://uniswap.org/docs/v2/smart-contracts
interface IUniswapV2Router01 {
function WETH() external pure returns (address);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
interface IUniswapV2Router is IUniswapV2Router01 {
function getAmountsOut(uint amountIn, address[] memory path)
external
view
returns (uint[] memory amounts);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
)
external
returns (
uint amountA,
uint amountB,
uint liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
}
interface IUniswapV2Pair {
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function swap(
uint amount0Out,
uint amount1Out,
address to,
bytes calldata data
) external;
}
interface IUniswapV2Factory {
function getPair(address token0, address token1) external view returns (address);
}
contract TestUniswap {
address private UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address owner;
IUniswapV2Router router;
constructor() {
owner = msg.sender;
router = IUniswapV2Router(UNISWAP_V2_ROUTER);
}
event Paid(address indexed _from, uint _value);
modifier _onlyOwner() {
require(msg.sender == owner);
_;
}
function getWBNBAddress() public view returns(address) {
return router.WETH();
}
function swap(
address _tokenIn,
address _tokenOut,
uint256 _amountIn,
uint256 _amountOutMin,
address _to
) external {
IERC20(_tokenIn).transferFrom(msg.sender, address(this), _amountIn);
IERC20(_tokenIn).approve(UNISWAP_V2_ROUTER, _amountIn);
IERC20(_tokenIn).allowance(address(this), UNISWAP_V2_ROUTER);
address[] memory path;
if (_tokenIn == router.WETH() || _tokenOut == router.WETH()) {
path = new address[](2);
path[0] = _tokenIn;
path[1] = _tokenOut;
} else {
path = new address[](3);
path[0] = _tokenIn;
path[1] = router.WETH();
path[2] = _tokenOut;
}
IUniswapV2Router(UNISWAP_V2_ROUTER).swapExactTokensForTokens(
_amountIn,
_amountOutMin,
path,
_to,
block.timestamp);
}
function swapTokensForETH (
uint amountOutMin, address tokenOut) external payable {
address[] memory path = new address[](2);
path[0] = router.WETH();
path[1] = tokenOut;
IUniswapV2Router(UNISWAP_V2_ROUTER).swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
msg.sender,
block.timestamp);
}
function getAmountOutMin(
address _tokenIn,
address _tokenOut,
uint _amountIn
) external view returns (uint) {
address[] memory path;
if (_tokenIn == router.WETH() || _tokenOut == router.WETH()) {
path = new address[](2);
path[0] = _tokenIn;
path[1] = _tokenOut;
} else {
path = new address[](3);
path[0] = _tokenIn;
path[1] = router.WETH();
path[2] = _tokenOut;
}
// same length as path
uint[] memory amountOutMins =
IUniswapV2Router(UNISWAP_V2_ROUTER).getAmountsOut(_amountIn, path);
return amountOutMins[path.length - 1];
}
function setUniswapRouter(address _router) external _onlyOwner {
UNISWAP_V2_ROUTER = _router;
}
receive() external payable {
emit Paid(msg.sender, msg.value);
}
}