I am trying to create my first smart contract based on https://docs.uniswap.org/protocol/guides/swaps/single-swaps I've deployed it on kovan test net using remix successfully but when trying to send the contract the amount of WETH9/DAI to swap i get this error https://kovan.etherscan.io/tx/0x1d038deff09b9dc338286bd9c8fe054ec247c05329072153a76fe545b6d7ab88 it seems that the smart contract is not withdrawing the amount to swap from metamask, I've tried to fix this myself for a few days now, but I'm stuck what is the problem here with the smart contract?
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
interface IUniswapRouter is ISwapRouter {
function refundETH() external payable;
}
contract Uniswap3 {
// This example swaps WETH9/DAI for single path swaps.
IUniswapRouter public constant uniswapRouter = IUniswapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
address public constant DAI = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
address public constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
// For this example, we will set the pool fee to 0.3%.
uint24 public constant poolFee = 3000;
/// @notice swapExactInputSingle swaps a fixed amount of WETH9 for a maximum possible amount of DAI
/// using the WETH9/DAI 0.3% pool by calling `exactInputSingle` in the swap router.
/// @dev The calling address must approve this contract to spend at least `amountIn` worth of its WETH9 for this function to succeed.
/// @param amountIn The exact amount of WETH9 that will be swapped for DAI.
/// @return amountOut The amount of DAI received.
function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {
// msg.sender must approve this contract
// Transfer the specified amount of WETH9 to this contract.
TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn);
// Approve the router to spend WETH9.
TransferHelper.safeApprove(WETH9, address(uniswapRouter), amountIn);
// Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum.
// We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.
ISwapRouter.ExactInputSingleParams memory params =
ISwapRouter.ExactInputSingleParams({
tokenIn: WETH9,
tokenOut: DAI,
fee: poolFee,
recipient: msg.sender,
deadline: block.timestamp,
amountIn: amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
// The call to `exactInputSingle` executes the swap.
amountOut = uniswapRouter.exactInputSingle(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
// important to receive ETH
receive() payable external {}
}