From 1e69a0838f338435902be9869d3e694c05c1ce27 Mon Sep 17 00:00:00 2001 From: dv Date: Wed, 1 May 2024 20:43:21 +0700 Subject: [PATCH] fix token seller scripts --- .../token-seller/Univ3TokenSellerResolver.sol | 1 - scripts/token-seller/DeployTokenSeller.ts | 12 ++--- .../token-seller/DeployTokenSellerUtils.ts | 15 +++++-- scripts/token-seller/GetStatus.ts | 26 ++++++++--- scripts/token-seller/MakeTestSwap.ts | 45 ++++++++++++++----- scripts/token-seller/SetTokenSeller.ts | 37 +++++++++++++++ scripts/utils/EnvSetup.ts | 2 +- .../SpookySwapTokenSellerTest2.ts | 45 +++++++++++-------- 8 files changed, 137 insertions(+), 46 deletions(-) create mode 100644 scripts/token-seller/SetTokenSeller.ts diff --git a/contracts/token-seller/Univ3TokenSellerResolver.sol b/contracts/token-seller/Univ3TokenSellerResolver.sol index 2ed7475f..b3de6cd6 100644 --- a/contracts/token-seller/Univ3TokenSellerResolver.sol +++ b/contracts/token-seller/Univ3TokenSellerResolver.sol @@ -10,7 +10,6 @@ contract Univ3TokenSellerResolver { string public constant VERSION = "1.0.0"; //endregion ---------------------- Constants - //region ---------------------- Variables IUniv3TokenSeller public tokenSeller; diff --git a/scripts/token-seller/DeployTokenSeller.ts b/scripts/token-seller/DeployTokenSeller.ts index 08690bf0..8e343f33 100644 --- a/scripts/token-seller/DeployTokenSeller.ts +++ b/scripts/token-seller/DeployTokenSeller.ts @@ -14,14 +14,15 @@ async function main() { const net = await ethers.provider.getNetwork(); console.log(net, `network name="${network.name}"`); - const tokenA = FtmAddresses.WFTM_TOKEN; - const tokenB = FtmAddresses.USDC_LZ_TOKEN; + const tokenA = "0xe4436821e403e78a6dd62f7a9f5611f97a18f44c"; // sacra (token to sell) + const tokenB = "0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83"; // ftm - const POOL = "0xf6021f2f63ab3bcdddbaf32939cd66a8b9e4c21c"; // SpookySwap pool + const POOL = "0x56e837286dc7366ef6d6464d332ac6f9d32bc5a0"; // SpookySwap pool const tickRangeSize = 10; const SIGNER_AMOUNT_A = "1"; const thresholdRatio = "0.1"; - const thresholdLastRefreshPoolSec = 100; + const thresholdLastRefreshPoolSec = 60; + const tickLimit = 40810; const tokenSeller = await DeployTokenSellerUtils.deployTokenSeller( signer, @@ -31,7 +32,8 @@ async function main() { SIGNER_AMOUNT_A, tickRangeSize, thresholdRatio, - thresholdLastRefreshPoolSec + thresholdLastRefreshPoolSec, + tickLimit ); console.log("tokenSeller", tokenSeller); writeFileSyncRestoreFolder(destPathTxt, `tokenSeller: ${tokenSeller}\n`, { encoding: 'utf8', flag: 'a' }); diff --git a/scripts/token-seller/DeployTokenSellerUtils.ts b/scripts/token-seller/DeployTokenSellerUtils.ts index b355f598..3a2ad799 100644 --- a/scripts/token-seller/DeployTokenSellerUtils.ts +++ b/scripts/token-seller/DeployTokenSellerUtils.ts @@ -4,6 +4,8 @@ import {SignerWithAddress} from "@nomiclabs/hardhat-ethers/signers"; import {parseUnits} from "ethers/lib/utils"; import {Univ3TokenSellerLib} from "../../typechain/contracts/token-seller/Univ3TokenSeller"; import TokenSellerConfigStruct = Univ3TokenSellerLib.TokenSellerConfigStruct; +import {BigNumber} from "ethers"; +import {Misc} from "../utils/Misc"; export class DeployTokenSellerUtils { public static async deployTokenSeller( @@ -15,24 +17,29 @@ export class DeployTokenSellerUtils { tickRangeSize: number = 1, thresholdRatio: string = "0.1", thresholdLastRefreshPoolSec: number = 1000, + tickLimit: number = 0 ): Promise { const decimalsA = await IERC20Metadata__factory.connect(tokenA, signer).decimals(); const slot0 = await UniswapV3Pool__factory.connect(pool, signer).slot0(); - const poolTokenA = await UniswapV3Pool__factory.connect(pool, signer).token0(); - const poolSwapTokens = poolTokenA.toLowerCase() === tokenA; + const poolToken0 = await UniswapV3Pool__factory.connect(pool, signer).token0(); + const poolSwapTokens = poolToken0.toLowerCase() !== tokenA.toLowerCase(); const sqrtPriceX96Limit = poolSwapTokens ? slot0.sqrtPriceX96.mul(100) // upper limit : slot0.sqrtPriceX96.div(100); // lowest limit + // const q96 = BigNumber.from(2).pow(96); + // const priceReal = (sqrtPriceX96Limit.mul(Misc.ONE18).mul(sqrtPriceX96Limit).div(q96).div(q96)).toNumber(); + // console.log("priceLimit", priceReal); + const config: TokenSellerConfigStruct = { amountA: parseUnits(amountA, decimalsA), thresholdLastRefreshPoolSec, thresholdRatio: parseUnits(thresholdRatio, 5), thresholdTokenB: 0, tickRangeSize, - tickLimit: 0, // auto calculated + tickLimit, } const tokenSeller = (await DeployerUtils.deployContract( @@ -42,7 +49,7 @@ export class DeployTokenSellerUtils { tokenB, pool, config, - sqrtPriceX96Limit, + tickLimit === 0 ? sqrtPriceX96Limit : 0, signer.address )) as Univ3TokenSeller; diff --git a/scripts/token-seller/GetStatus.ts b/scripts/token-seller/GetStatus.ts index eee08876..cbf1faf5 100644 --- a/scripts/token-seller/GetStatus.ts +++ b/scripts/token-seller/GetStatus.ts @@ -1,8 +1,8 @@ -import {parseUnits} from "ethers/lib/utils"; +import {formatUnits, parseUnits} from "ethers/lib/utils"; import { IERC20Metadata__factory, MockToken__factory, - UniswapV3Callee__factory, + UniswapV3Callee__factory, UniswapV3Pool__factory, Univ3TokenSeller__factory } from "../../typechain"; import {ethers, network} from "hardhat"; @@ -18,7 +18,8 @@ async function main() { const POOL = "0x11aB7c23B6d05Aa08D69A1eD669Ad19f3eAC52d9"; const TOKEN_SELLER = "0x8E294388A3E91cdac5FEA95b5b75f509b85dC5E2"; - const signer = (await ethers.getSigners())[0]; + // const signer = (await ethers.getSigners())[0]; + const signer = await Misc.impersonate("0xF1dCce3a6c321176C62b71c091E3165CC9C3816E"); console.log("signer", signer.address); const net = await ethers.provider.getNetwork(); @@ -33,13 +34,24 @@ async function main() { const decimalsB = await tokenB.decimals(); const tokenSeller = Univ3TokenSeller__factory.connect(TOKEN_SELLER, signer); + const pool = UniswapV3Pool__factory.connect(POOL, signer); const owner = await tokenSeller.owner(); - console.log("Need to refresh", await tokenSeller.needToRefresh()); - console.log("TokenSeller.state", await tokenSeller.state()); + const state = await tokenSeller.state(); + const slot0 = await pool.slot0(); + const config = await tokenSeller.config(); + console.log("owner", owner); - console.log("BalanceA", await tokenA.balanceOf(owner)); - console.log("BalanceB", await tokenB.balanceOf(owner)); + console.log("TokenSeller.config", config); + console.log("TokenSeller.config.tickLimit", config.tickLimit); + console.log("TokenSeller.state", state); + + console.log("Need to refresh", await tokenSeller.needToRefresh()); + console.log("BalanceA", +formatUnits(await tokenA.balanceOf(signer.address), decimalsA)); + console.log("BalanceB", +formatUnits(await tokenB.balanceOf(signer.address), decimalsB)); + console.log("TokenSeller.state.lowerTick", state.lowerTick); + console.log("TokenSeller.state.upperTick", state.upperTick); + console.log("slot0Before.tick", slot0.tick); } main() diff --git a/scripts/token-seller/MakeTestSwap.ts b/scripts/token-seller/MakeTestSwap.ts index f3d04fc7..795c98fc 100644 --- a/scripts/token-seller/MakeTestSwap.ts +++ b/scripts/token-seller/MakeTestSwap.ts @@ -1,8 +1,12 @@ -import {parseUnits} from "ethers/lib/utils"; -import {IERC20Metadata__factory, MockToken__factory, UniswapV3Callee__factory} from "../../typechain"; +import {formatUnits, parseUnits} from "ethers/lib/utils"; +import { + MockToken__factory, + UniswapV3Callee__factory, UniswapV3Pool__factory, + Univ3TokenSeller__factory +} from "../../typechain"; import {ethers, network} from "hardhat"; -import {Misc} from "../utils/Misc"; import {RunHelper} from "../utils/RunHelper"; +import {Misc} from "../utils/Misc"; /** * npx hardhat run scripts/token-seller/MakeTestSwap.ts @@ -12,6 +16,7 @@ async function main() { const TOKEN_B = "0xF992a90B4F2D59B65548bF9766a02ee8170E7F07"; const POOL = "0x11aB7c23B6d05Aa08D69A1eD669Ad19f3eAC52d9"; const UNISWAP_V3_CALEE = "0x848A49De3f59C62A337463f1D856Ad30FE85675e"; + const TOKEN_SELLER = "0x8E294388A3E91cdac5FEA95b5b75f509b85dC5E2"; const signer = (await ethers.getSigners())[0]; // const signer = await Misc.impersonate("0xF1dCce3a6c321176C62b71c091E3165CC9C3816E"); @@ -20,18 +25,25 @@ async function main() { const net = await ethers.provider.getNetwork(); console.log(net, `network name="${network.name}"`); - const swapTokenA = false; - const tokenA = MockToken__factory.connect(TOKEN_A, signer); const tokenB = MockToken__factory.connect(TOKEN_B, signer); const uniswapV3Callee = UniswapV3Callee__factory.connect(UNISWAP_V3_CALEE, signer); + const tokenSeller = Univ3TokenSeller__factory.connect(TOKEN_SELLER, signer); + const pool = UniswapV3Pool__factory.connect(POOL, signer); const decimalsA = await tokenA.decimals(); const decimalsB = await tokenB.decimals(); - const swapAmount = "1000"; + const swapTokenA = true; + const swapAmount = "2000000"; const amountToSwap = parseUnits(swapAmount, swapTokenA ? decimalsA : decimalsB); + // await RunHelper.runAndWait2ExplicitSigner( + // signer, + // tokenB.connect(signer).populateTransaction.mint(signer.address, amountToSwap) + // ) + // return + if (swapTokenA) { await RunHelper.runAndWait2ExplicitSigner( signer, @@ -44,8 +56,10 @@ async function main() { ); } - console.log("BalanceA", await tokenA.balanceOf(signer.address)); - console.log("BalanceB", await tokenB.balanceOf(signer.address)); + const stateBefore = await tokenSeller.state(); + const slot0Before = await pool.slot0(); + const balanceABefore = +formatUnits(await tokenA.balanceOf(signer.address), decimalsA); + const balanceBBefore = +formatUnits(await tokenB.balanceOf(signer.address), decimalsB); await RunHelper.runAndWait2ExplicitSigner( signer, @@ -57,9 +71,20 @@ async function main() { ) ); - console.log("BalanceA.after", await tokenA.balanceOf(signer.address)); - console.log("BalanceB.after", await tokenB.balanceOf(signer.address)); + const stateAfter = await tokenSeller.state(); + const slot0After = await pool.slot0(); + + console.log("BalanceA", balanceABefore); + console.log("BalanceB", balanceBBefore); + console.log("stateBefore.lowerTick", stateBefore.lowerTick); + console.log("stateBefore.upperTick", stateBefore.upperTick); + console.log("slot0Before.tick", slot0Before.tick); + console.log("BalanceA.after", +formatUnits(await tokenA.balanceOf(signer.address), decimalsA)); + console.log("BalanceB.after", +formatUnits(await tokenB.balanceOf(signer.address), decimalsB)); + console.log("stateAfter.lowerTick", stateAfter.lowerTick); + console.log("stateAfter.upperTick", stateAfter.upperTick); + console.log("slot0After.tick", slot0After.tick); } main() diff --git a/scripts/token-seller/SetTokenSeller.ts b/scripts/token-seller/SetTokenSeller.ts new file mode 100644 index 00000000..4553386a --- /dev/null +++ b/scripts/token-seller/SetTokenSeller.ts @@ -0,0 +1,37 @@ +import {parseUnits} from "ethers/lib/utils"; +import { + IERC20Metadata__factory, + MockToken__factory, + UniswapV3Callee__factory, + Univ3TokenSeller__factory, Univ3TokenSellerResolver__factory +} from "../../typechain"; +import {ethers, network} from "hardhat"; +import {Misc} from "../utils/Misc"; +import {RunHelper} from "../utils/RunHelper"; + +/** + * npx hardhat run scripts/token-seller/SetTokenSeller.ts + */ +async function main() { + const NEW_TOKEN_SELLER = "0x8E294388A3E91cdac5FEA95b5b75f509b85dC5E2"; + const RESOLVER = "0xd2538f5f7c328a7027a5e0dea1938931601d1684"; + + const signer = (await ethers.getSigners())[0]; + console.log("signer", signer.address); + + const net = await ethers.provider.getNetwork(); + console.log(net, `network name="${network.name}"`); + + const resolver = Univ3TokenSellerResolver__factory.connect(RESOLVER, signer); + await RunHelper.runAndWait2ExplicitSigner( + signer, + resolver.populateTransaction.setTokenSeller(NEW_TOKEN_SELLER) + ); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/utils/EnvSetup.ts b/scripts/utils/EnvSetup.ts index 3a0ddc29..419ca775 100644 --- a/scripts/utils/EnvSetup.ts +++ b/scripts/utils/EnvSetup.ts @@ -72,7 +72,7 @@ export class EnvSetup { ftmForkBlock: { type: 'number', - default: 80210808, + default: 80265574, }, /////// NETWORK EXPLORERS diff --git a/test/token-seller/SpookySwapTokenSellerTest2.ts b/test/token-seller/SpookySwapTokenSellerTest2.ts index 16517481..26027aa5 100644 --- a/test/token-seller/SpookySwapTokenSellerTest2.ts +++ b/test/token-seller/SpookySwapTokenSellerTest2.ts @@ -26,9 +26,13 @@ describe('SpookySwapTokenSellerTest2', () => { const MAX_AMOUNT_TO_SWAP_A = "100"; const MAX_AMOUNT_TO_SWAP_B = "100"; - const TOKEN_A = "0xF21ABFC5D68819EA0044fdB256d0AA854DC3034b"; - const TOKEN_B = "0xF992a90B4F2D59B65548bF9766a02ee8170E7F07"; - const POOL = "0x11aB7c23B6d05Aa08D69A1eD669Ad19f3eAC52d9"; + // const TOKEN_A = "0xF21ABFC5D68819EA0044fdB256d0AA854DC3034b"; + // const TOKEN_B = "0xF992a90B4F2D59B65548bF9766a02ee8170E7F07"; + // const POOL = "0x11aB7c23B6d05Aa08D69A1eD669Ad19f3eAC52d9"; + + const POOL = "0x56e837286dc7366ef6d6464d332ac6f9d32bc5a0"; + const TOKEN_A = "0xe4436821e403e78a6dd62f7a9f5611f97a18f44c"; // sacra (token to sell) + const TOKEN_B = "0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83"; // ftm let snapshotBefore: string; let signer: SignerWithAddress; @@ -64,6 +68,11 @@ describe('SpookySwapTokenSellerTest2', () => { saveToCsv(states, ""); }); + it("calculate prices and ticks", async () => { + const tickCurrent = 40810; + const tickLimit = 46600; + }); + //region Data types interface ISwapParams { tag: string; @@ -295,9 +304,9 @@ describe('SpookySwapTokenSellerTest2', () => { } //endregion Stat utils - async function getToken(token: string, signer: string, amount: BigNumber) { - await MockToken__factory.connect(token, await Misc.impersonate(signer)).mint(signer, amount); - } + // async function getToken(token: string, signer: string, amount: BigNumber) { + // await MockToken__factory.connect(token, await Misc.impersonate(signer)).mint(signer, amount); + // } describe("refreshPool (init => {swap => refreshPool} * N => withdraw)", () => { const SWAP_SETS: ISwapParams[] = [ @@ -315,26 +324,21 @@ describe('SpookySwapTokenSellerTest2', () => { console.log("Set up token seller"); snapshot2 = await TimeUtils.snapshot(); - // await TokenUtils.getToken(tokenA.address, signer.address, parseUnits(SIGNER_BALANCE_A, decimalsA)); - // await TokenUtils.getToken(tokenA.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_A, decimalsA)); - // await TokenUtils.getToken(tokenB.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_B, decimalsB)); + await TokenUtils.getToken(tokenA.address, signer.address, parseUnits(SIGNER_BALANCE_A, decimalsA)); + await TokenUtils.getToken(tokenA.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_A, decimalsA)); + await TokenUtils.getToken(tokenB.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_B, decimalsB)); - await getToken(tokenA.address, signer.address, parseUnits(SIGNER_BALANCE_A, decimalsA)); - await getToken(tokenA.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_A, decimalsA)); - await getToken(tokenB.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_B, decimalsB)); + // await getToken(tokenA.address, signer.address, parseUnits(SIGNER_BALANCE_A, decimalsA)); + // await getToken(tokenA.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_A, decimalsA)); + // await getToken(tokenB.address, signer2.address, parseUnits(MAX_AMOUNT_TO_SWAP_B, decimalsB)); tokenSeller = Univ3TokenSeller__factory.connect( await DeployTokenSellerUtils.deployTokenSeller(signer, tokenA.address, tokenB.address, POOL, SIGNER_AMOUNT_A, tickRangeSize), signer ); - console.log("5"); poolSwapTokens = await tokenSeller.poolSwapTokens(); - console.log("6"); - await tokenA.transfer(tokenSeller.address, parseUnits(SIGNER_AMOUNT_A, decimalsA)); - console.log("7"); await tokenSeller.openPosition(); - console.log("8"); const poolInfo = await pool.slot0(); init = { @@ -348,13 +352,18 @@ describe('SpookySwapTokenSellerTest2', () => { balancesAbSigner1: await getBalancesAB(signer1.address), balancesAbSigner2: await getBalancesAB(signer2.address), } - console.log("9"); + console.log("init", init); const config = await tokenSeller.config(); derivedValues = { tickLimit: config.tickLimit, tickSpacing: await tokenSeller.tickSpacing(), } + + console.log("config", config); + console.log("poolSwapTokens", await tokenSeller.poolSwapTokens()); + console.log("tokenA", await tokenSeller.tokenA()); + console.log("tokenB", await tokenSeller.tokenB()); }); after(async function () { await TimeUtils.rollback(snapshot2);