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.
INFURA_URL_TESTNET=
WALLET_ADDRESS=
WALLET_SECRET=
[
{
"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"
}
]
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
}
{
"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"
}
}
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()
@alanhamid
Copy link

Thanks you, for doing such a good job.

@HaceneKouidri
Copy link

Hi thanks for your job,
The slot in the state on getPoolState dosen't work,
I fix it with this (line 17): const slot = await poolContract.slot0(),

@zuko-firelord
Copy link

from where u get the poolAddress(0x4D7C363DED4B3b4e1F954494d2Bc3955e49699cC) ?

@andersoncampolina
Copy link

Thanks for the help.

@zangen-ismail
Copy link

from where u get the poolAddress(0x4D7C363DED4B3b4e1F954494d2Bc3955e49699cC) ?

@zangen-ismail
Copy link

Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (data="0x", transaction={"to":"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984","data":"0x0dfe1681","accessList":null}, error={"reason":"processing response error","code":"SERVER_ERROR","body":"{"jsonrpc":"2.0","id":44,"error":{"code":-32000,"message":"execution reverted"}}","error":{"code":-32000},"requestBody":"{"method":"eth_call","params":[{"to":"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984","data":"0x0dfe1681"},"latest"],"id":44,"jsonrpc":"2.0"}","requestMethod":"POST","url":"https://mainnet.infura.io/v3/9d1a6626357d45c2b69196940857d20b"}, code=CALL_EXCEPTION, version=providers/5.7.2)
at Logger.makeError (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/logger/lib/index.js:238:21)
at Logger.throwError (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/logger/lib/index.js:247:20)
at checkError (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:108:16)
at JsonRpcProvider. (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:751:47)
at step (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:48:23)
at Object.throw (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:29:53)
at rejected (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:21:65)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'missing revert data in call exception; Transaction reverted without a reason string',
code: 'CALL_EXCEPTION',
data: '0x',
transaction: {
to: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
data: '0x0dfe1681',
accessList: null
},
error: Error: processing response error (body="{"jsonrpc":"2.0","id":44,"error":{"code":-32000,"message":"execution reverted"}}", error={"code":-32000}, requestBody="{"method":"eth_call","params":[{"to":"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984","data":"0x0dfe1681"},"latest"],"id":44,"jsonrpc":"2.0"}", requestMethod="POST", url="https://mainnet.infura.io/v3/9d1a6626357d45c2b69196940857d20b", code=SERVER_ERROR, version=web/5.7.1)
at Logger.makeError (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/logger/lib/index.js:238:21)
at Logger.throwError (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/logger/lib/index.js:247:20)
at /home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:313:32
at step (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'processing response error',
code: 'SERVER_ERROR',
body: '{"jsonrpc":"2.0","id":44,"error":{"code":-32000,"message":"execution reverted"}}',
error: Error: execution reverted
at getResult (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:191:21)
at processJsonFunc (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:356:22)
at /home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:288:46
at step (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/home/zangen/BLOOKMAN/UuniswapTrader/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: -32000,
data: undefined

@zangen-ismail
Copy link

pleas can some one tel me how i resolve this

@Bitcoinera
Copy link

@zangen-ismail in this gist you may find the code to get the pool address for a certain tokens pair: https://gist.github.com/BlockmanCodes/61810d1ff788d9d79f3e5643f58e6f9d

@Bitcoinera
Copy link

Bitcoinera commented Apr 17, 2023

Now I just need to find out how to get the swapRouterAddress 😆

EDIT: Using 0x4648a43b2c14da09fdf82b161150d3f634f40491 for Goerli, but getting all my txs rejected for some reason 😞
Need to figure this one out
EDIT: the swapRouter is actually the same address. Doesn't change for Goerli 😆

@kosalayb
Copy link

kosalayb commented Aug 4, 2023

I tried to test the above on a forked mainnet and getting the following Error.

node_modules/@ethersproject/logger/lib/index.js:233
var error = new Error(message);
^

Error: processing response error (body="{"id":67,"jsonrpc":"2.0","result":"0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826","error":{"message":"VM Exception while processing transaction: revert STF","code":-32000,"data":{"0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826":{"error":"revert","program_counter":6047,"return":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000035354460000000000000000000000000000000000000000000000000000000000","reason":"STF"},"stack":"c: VM Exception while processing transaction: revert STF\n at Function.c.fromResults (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)\n at A.w.processBlock (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)\n at runMicrotasks ()\n at processTicksAndRejections (node:internal/process/task_queues:96:5)","name":"c"}}}", error={"code":-32000,"data":{"0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826":{"error":"revert","program_counter":6047,"return":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000035354460000000000000000000000000000000000000000000000000000000000","reason":"STF"},"stack":"c: VM Exception while processing transaction: revert STF\n at Function.c.fromResults (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)\n at A.w.processBlock (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)\n at runMicrotasks ()\n at processTicksAndRejections (node:internal/process/task_queues:96:5)","name":"c"}}, requestBody="{"method":"eth_sendRawTransaction","params":["0xf9016e81868504a817c800830f424094e592427a0aece92de3edee1f18e0157c0586156480b90104414bf3890000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000248cf0ecafe080a721e30e2889acb76d6cf1ce7c0000000000000000000000000000000000000000000000000000000064cd03a90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000820a96a0dcc7b683e88ff18cd5847460e8e561b2c9fb779837824362c1edd48dbf610fcda02473b0cc7ff57f44b3076bfc7ee474a04ea0992cfe286e875ae6d9f69e967c06"],"id":67,"jsonrpc":"2.0"}", requestMethod="POST", url="http://localhost:8545", code=SERVER_ERROR, version=web/5.6.0)
at Logger.makeError (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/logger/lib/index.js:233:21)
at Logger.throwError (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/logger/lib/index.js:242:20)
at /Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:305:32
at step (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'processing response error',
code: 'SERVER_ERROR',
body: '{"id":67,"jsonrpc":"2.0","result":"0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826","error":{"message":"VM Exception while processing transaction: revert STF","code":-32000,"data":{"0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826":{"error":"revert","program_counter":6047,"return":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000035354460000000000000000000000000000000000000000000000000000000000","reason":"STF"},"stack":"c: VM Exception while processing transaction: revert STF\n at Function.c.fromResults (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)\n at A.w.processBlock (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)\n at runMicrotasks ()\n at processTicksAndRejections (node:internal/process/task_queues:96:5)","name":"c"}}}',
error: Error: VM Exception while processing transaction: revert STF
at getResult (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:170:21)
at processJsonFunc (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:348:22)
at /Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:280:46
at step (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/Users/admin/MEVWS/Relay/node_modules/ethers/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: -32000,
data: {
'0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826': {
error: 'revert',
program_counter: 6047,
return: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000035354460000000000000000000000000000000000000000000000000000000000',
reason: 'STF'
},
stack: 'c: VM Exception while processing transaction: revert STF\n' +
' at Function.c.fromResults (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)\n' +
' at A.w.processBlock (/usr/local/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)\n' +
' at runMicrotasks ()\n' +
' at processTicksAndRejections (node:internal/process/task_queues:96:5)',
name: 'c'
}
},
requestBody: '{"method":"eth_sendRawTransaction","params":["0xf9016e81868504a817c800830f424094e592427a0aece92de3edee1f18e0157c0586156480b90104414bf3890000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000248cf0ecafe080a721e30e2889acb76d6cf1ce7c0000000000000000000000000000000000000000000000000000000064cd03a90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000820a96a0dcc7b683e88ff18cd5847460e8e561b2c9fb779837824362c1edd48dbf610fcda02473b0cc7ff57f44b3076bfc7ee474a04ea0992cfe286e875ae6d9f69e967c06"],"id":67,"jsonrpc":"2.0"}',
requestMethod: 'POST',
url: 'http://localhost:8545',
transaction: {
nonce: 134,
gasPrice: BigNumber { _hex: '0x04a817c800', _isBigNumber: true },
gasLimit: BigNumber { _hex: '0x0f4240', _isBigNumber: true },
to: '0xE592427A0AEce92De3Edee1F18E0157C05861564',
value: BigNumber { _hex: '0x00', _isBigNumber: true },
data: '0x414bf3890000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000248cf0ecafe080a721e30e2889acb76d6cf1ce7c0000000000000000000000000000000000000000000000000000000064cd03a90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
chainId: 1337,
v: 2710,
r: '0xdcc7b683e88ff18cd5847460e8e561b2c9fb779837824362c1edd48dbf610fcd',
s: '0x2473b0cc7ff57f44b3076bfc7ee474a04ea0992cfe286e875ae6d9f69e967c06',
from: '0x248Cf0EcaFE080a721e30e2889ACb76d6cF1CE7C',
hash: '0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826',
type: null,
confirmations: 0
},
transactionHash: '0x72808324a933527bc5b6643dc6cf77db0e51ee2424cc4f2560d65807ad464826'
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment