Compare commits

...

2 Commits

Author SHA1 Message Date
zimpha
460e457d60 fix abi 2023-04-14 11:19:59 +08:00
zimpha
ed42d9db77 add script to swap WETH => USDC 2023-04-13 13:03:24 +08:00
5 changed files with 395 additions and 1 deletions

View File

@@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]

View File

@@ -0,0 +1,99 @@
[
{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "indexed": true, "internalType": "int24", "name": "tickSpacing", "type": "int24" }
],
"name": "FeeAmountEnabled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "oldOwner", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "OwnerChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "token0", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "token1", "type": "address" },
{ "indexed": true, "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "indexed": false, "internalType": "int24", "name": "tickSpacing", "type": "int24" },
{ "indexed": false, "internalType": "address", "name": "pool", "type": "address" }
],
"name": "PoolCreated",
"type": "event"
},
{
"inputs": [
{ "internalType": "address", "name": "tokenA", "type": "address" },
{ "internalType": "address", "name": "tokenB", "type": "address" },
{ "internalType": "uint24", "name": "fee", "type": "uint24" }
],
"name": "createPool",
"outputs": [{ "internalType": "address", "name": "pool", "type": "address" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "internalType": "int24", "name": "tickSpacing", "type": "int24" }
],
"name": "enableFeeAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }],
"name": "feeAmountTickSpacing",
"outputs": [{ "internalType": "int24", "name": "", "type": "int24" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "uint24", "name": "", "type": "uint24" }
],
"name": "getPool",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "parameters",
"outputs": [
{ "internalType": "address", "name": "factory", "type": "address" },
{ "internalType": "address", "name": "token0", "type": "address" },
{ "internalType": "address", "name": "token1", "type": "address" },
{ "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "internalType": "int24", "name": "tickSpacing", "type": "int24" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_owner", "type": "address" }],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

View File

@@ -0,0 +1,231 @@
[
{
"inputs": [
{ "internalType": "address", "name": "_factory", "type": "address" },
{ "internalType": "address", "name": "_WETH9", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "WETH9",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "bytes", "name": "path", "type": "bytes" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
{ "internalType": "uint256", "name": "amountIn", "type": "uint256" },
{ "internalType": "uint256", "name": "amountOutMinimum", "type": "uint256" }
],
"internalType": "struct ISwapRouter.ExactInputParams",
"name": "params",
"type": "tuple"
}
],
"name": "exactInput",
"outputs": [{ "internalType": "uint256", "name": "amountOut", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "tokenIn", "type": "address" },
{ "internalType": "address", "name": "tokenOut", "type": "address" },
{ "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "amountIn", "type": "uint256" },
{ "internalType": "uint256", "name": "amountOutMinimum", "type": "uint256" },
{ "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" }
],
"internalType": "struct ISwapRouter.ExactInputSingleParams",
"name": "params",
"type": "tuple"
}
],
"name": "exactInputSingle",
"outputs": [{ "internalType": "uint256", "name": "amountOut", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "bytes", "name": "path", "type": "bytes" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
{ "internalType": "uint256", "name": "amountOut", "type": "uint256" },
{ "internalType": "uint256", "name": "amountInMaximum", "type": "uint256" }
],
"internalType": "struct ISwapRouter.ExactOutputParams",
"name": "params",
"type": "tuple"
}
],
"name": "exactOutput",
"outputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "tokenIn", "type": "address" },
{ "internalType": "address", "name": "tokenOut", "type": "address" },
{ "internalType": "uint24", "name": "fee", "type": "uint24" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
{ "internalType": "uint256", "name": "amountOut", "type": "uint256" },
{ "internalType": "uint256", "name": "amountInMaximum", "type": "uint256" },
{ "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" }
],
"internalType": "struct ISwapRouter.ExactOutputSingleParams",
"name": "params",
"type": "tuple"
}
],
"name": "exactOutputSingle",
"outputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "factory",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }],
"name": "multicall",
"outputs": [{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }],
"stateMutability": "payable",
"type": "function"
},
{ "inputs": [], "name": "refundETH", "outputs": [], "stateMutability": "payable", "type": "function" },
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "value", "type": "uint256" },
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"name": "selfPermit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "nonce", "type": "uint256" },
{ "internalType": "uint256", "name": "expiry", "type": "uint256" },
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"name": "selfPermitAllowed",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "nonce", "type": "uint256" },
{ "internalType": "uint256", "name": "expiry", "type": "uint256" },
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"name": "selfPermitAllowedIfNecessary",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "value", "type": "uint256" },
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"name": "selfPermitIfNecessary",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
{ "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "sweepToken",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "feeBips", "type": "uint256" },
{ "internalType": "address", "name": "feeRecipient", "type": "address" }
],
"name": "sweepTokenWithFee",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "int256", "name": "amount0Delta", "type": "int256" },
{ "internalType": "int256", "name": "amount1Delta", "type": "int256" },
{ "internalType": "bytes", "name": "_data", "type": "bytes" }
],
"name": "uniswapV3SwapCallback",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
{ "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "unwrapWETH9",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "feeBips", "type": "uint256" },
{ "internalType": "address", "name": "feeRecipient", "type": "address" }
],
"name": "unwrapWETH9WithFee",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]

View File

@@ -0,0 +1,62 @@
/* eslint-disable node/no-missing-import */
import { Contract, providers, utils, Wallet } from "ethers";
import * as dotenv from "dotenv";
import ERC20ABI from "./abi/ERC20.json";
import UniswapV3RouterABI from "./abi/UniswapV3Router.json";
import UniswapV3FactoryABI from "./abi/UniswapV3Factory.json";
dotenv.config();
async function main() {
const provider = new providers.JsonRpcProvider("https://staging-rpc.scroll.io/l2");
const fee = parseInt(process.env.FEE!);
const signer = new Wallet(process.env.PRIVATE_KEY!, provider);
const UniswapV3Router = new Contract("0xC18394cf6555B541Efdb83083F720eCB1dF4692e", UniswapV3RouterABI, signer);
const USDC: string = "0x429C6C7b33Edb8cB19BD8cC0d1940B13Cca746C4";
const WETH: string = await UniswapV3Router.WETH9();
const factory: string = await UniswapV3Router.factory();
const UniswapV3Factory = new Contract(factory, UniswapV3FactoryABI, signer);
const usdc = new Contract(USDC, ERC20ABI, signer);
const weth = new Contract(WETH, ERC20ABI, signer);
const pool = await UniswapV3Factory.getPool(WETH, USDC, fee);
console.log("Signer address:", signer.address);
console.log("Pool address:", pool);
console.log("USDC in pool:", (await usdc.balanceOf(pool)).toString());
console.log("WETH in pool:", (await weth.balanceOf(pool)).toString());
let nonce = await signer.getTransactionCount();
for (let i = 0; i < 100; i++) {
const data = UniswapV3Router.interface.encodeFunctionData("exactInputSingle", [
{
tokenIn: WETH,
tokenOut: USDC,
fee,
recipient: signer.address,
amountIn: utils.parseEther("0.0001"),
amountOutMinimum: 0,
sqrtPriceLimitX96: 0,
},
]);
const tx = await signer.sendTransaction({
to: UniswapV3Router.address,
data,
nonce,
value: utils.parseEther("0.0001"),
});
nonce = nonce + 1;
console.log(tx);
console.log("send tx with hash:", tx.hash, "nonce:", nonce);
}
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

View File

@@ -5,7 +5,8 @@
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"declaration": true
"declaration": true,
"resolveJsonModule": true
},
"include": ["./scripts", "integration-test", "./typechain"],
"files": ["./hardhat.config.ts", "./circomlib.d.ts"]