0

I want to make a function for my token contract that allows me to swap a dynamic amount of tokens in exchange for 1 eth.

Is it possible to calculate how many tokens are worth 1 eth and then swap with Uniswap V2 to get exactly that amount of eth out?

2 Answers 2

0

Something like this should work? Calling UniswapV2's getAmountsOut.

In the example below I'm using the Uni token contract address for the token on Goerli: 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984

pragma solidity ^0.8.0;

import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract TokenSwap {

    address private constant TOKEN_ADDRESS = 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984; // Uni token on Goerli
    address private constant ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // Uniswap V2 router
    
    IUniswapV2Router02 private uniswapRouter;
    IERC20 private token;

    constructor() {
        uniswapRouter = IUniswapV2Router02(ROUTER_ADDRESS);
        token = IERC20(TOKEN_ADDRESS);
    }

    function swapTokens() external payable {
        require(msg.value == 1 ether, "Must send exactly 1 ETH");
        
        address[] memory path = new address[](2);
        path[0] = uniswapRouter.WETH();
        path[1] = TOKEN_ADDRESS;
        
        uint[] memory amounts = uniswapRouter.getAmountsOut(msg.value, path);
        uint256 amountOut = amounts[1]; // Amount of tokens for 1 ETH through Uniswap V2
        
        uint deadline = block.timestamp + 15;
        uniswapRouter.swapExactETHForTokens{ value: msg.value }(amountOut, path, msg.sender, deadline);
        
        // Refund remaining ETH to user
        if (address(this).balance > 0) {
            payable(msg.sender).transfer(address(this).balance);
        }
    }

    receive() external payable {}
}

Here's an example deployment on Goerli: 0x9ef84b761224d95B46d39D972499eDe90Af54ead

0

The router function is called getAmountIn. You can incorporate the calculation in or just call it from your tax-on-transfer contract.

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
        require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        uint numerator = reserveIn.mul(amountOut).mul(1000);
        uint denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);

We use getAmountIn, since we know the output amount, and want the amount needed in for that exact amount out.

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.