-
-
Save tcitds1/cb7b5632b30a67c37b7949b542484572 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
INFURA_URL_TESTNET= | |
WALLET_ADDRESS= | |
WALLET_SECRET= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"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" | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment