-
-
Save BlockmanCodes/1ed5e4b3cd597f02e539049c3473f7b3 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
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'
}