Skip to content

Instantly share code, notes, and snippets.

@BlockmanCodes
Created April 22, 2022 01:32
Show Gist options
  • Save BlockmanCodes/1ed5e4b3cd597f02e539049c3473f7b3 to your computer and use it in GitHub Desktop.
Save BlockmanCodes/1ed5e4b3cd597f02e539049c3473f7b3 to your computer and use it in GitHub Desktop.

Revisions

  1. BlockmanCodes created this gist Apr 22, 2022.
    3 changes: 3 additions & 0 deletions .env
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    INFURA_URL_TESTNET=
    WALLET_ADDRESS=
    WALLET_SECRET=
    277 changes: 277 additions & 0 deletions abi.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,277 @@
    [
    {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "owner",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "address",
    "name": "spender",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "uint256",
    "name": "value",
    "type": "uint256"
    }
    ],
    "name": "Approval",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "from",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "uint256",
    "name": "value",
    "type": "uint256"
    }
    ],
    "name": "Transfer",
    "type": "event"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "owner",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    }
    ],
    "name": "allowance",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    }
    ],
    "name": "approve",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "account",
    "type": "address"
    }
    ],
    "name": "balanceOf",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "decimals",
    "outputs": [
    {
    "internalType": "uint8",
    "name": "",
    "type": "uint8"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "subtractedValue",
    "type": "uint256"
    }
    ],
    "name": "decreaseAllowance",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "addedValue",
    "type": "uint256"
    }
    ],
    "name": "increaseAllowance",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "name",
    "outputs": [
    {
    "internalType": "string",
    "name": "",
    "type": "string"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "symbol",
    "outputs": [
    {
    "internalType": "string",
    "name": "",
    "type": "string"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    }
    ],
    "name": "transfer",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "from",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    }
    ],
    "name": "transferFrom",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
    }
    ]
    24 changes: 24 additions & 0 deletions helpers.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    exports.getPoolImmutables = async (poolContract) => {
    const [token0, token1, fee] = await Promise.all([
    poolContract.token0(),
    poolContract.token1(),
    poolContract.fee()
    ])

    const immutables = {
    token0: token0,
    token1: token1,
    fee: fee
    }
    return immutables
    }

    exports.getPoolState = async (poolContract) => {
    const slot = poolContract.slot0()

    const state = {
    sqrtPriceX96: slot[0]
    }

    return state
    }
    18 changes: 18 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    {
    "name": "uniswaptrader",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
    "@uniswap/sdk-core": "^3.0.1",
    "@uniswap/v3-sdk": "^3.8.2",
    "dotenv": "^16.0.0",
    "ethers": "^5.6.4"
    }
    }
    84 changes: 84 additions & 0 deletions uniswapTrader.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    const { ethers } = require('ethers')
    const { abi: IUniswapV3PoolABI } = require('@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json')
    const { abi: SwapRouterABI} = require('@uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
    const { getPoolImmutables, getPoolState } = require('./helpers')
    const ERC20ABI = require('./abi.json')

    require('dotenv').config()
    const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET
    const WALLET_ADDRESS = process.env.WALLET_ADDRESS
    const WALLET_SECRET = process.env.WALLET_SECRET

    const provider = new ethers.providers.JsonRpcProvider(INFURA_URL_TESTNET) // Ropsten
    const poolAddress = "0x4D7C363DED4B3b4e1F954494d2Bc3955e49699cC" // UNI/WETH
    const swapRouterAddress = '0xE592427A0AEce92De3Edee1F18E0157C05861564'

    const name0 = 'Wrapped Ether'
    const symbol0 = 'WETH'
    const decimals0 = 18
    const address0 = '0xc778417e063141139fce010982780140aa0cd5ab'

    const name1 = 'Uniswap Token'
    const symbol1 = 'UNI'
    const decimals1 = 18
    const address1 = '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984'

    async function main() {
    const poolContract = new ethers.Contract(
    poolAddress,
    IUniswapV3PoolABI,
    provider
    )

    const immutables = await getPoolImmutables(poolContract)
    const state = await getPoolState(poolContract)

    const wallet = new ethers.Wallet(WALLET_SECRET)
    const connectedWallet = wallet.connect(provider)

    const swapRouterContract = new ethers.Contract(
    swapRouterAddress,
    SwapRouterABI,
    provider
    )

    const inputAmount = 0.001
    // .001 => 1 000 000 000 000 000
    const amountIn = ethers.utils.parseUnits(
    inputAmount.toString(),
    decimals0
    )

    const approvalAmount = (amountIn * 100000).toString()
    const tokenContract0 = new ethers.Contract(
    address0,
    ERC20ABI,
    provider
    )
    const approvalResponse = await tokenContract0.connect(connectedWallet).approve(
    swapRouterAddress,
    approvalAmount
    )

    const params = {
    tokenIn: immutables.token1,
    tokenOut: immutables.token0,
    fee: immutables.fee,
    recipient: WALLET_ADDRESS,
    deadline: Math.floor(Date.now() / 1000) + (60 * 10),
    amountIn: amountIn,
    amountOutMinimum: 0,
    sqrtPriceLimitX96: 0,
    }

    const transaction = swapRouterContract.connect(connectedWallet).exactInputSingle(
    params,
    {
    gasLimit: ethers.utils.hexlify(1000000)
    }
    ).then(transaction => {
    console.log(transaction)
    })
    }

    main()