From 9d8051e7a62e810da97ec9b054a8d956c747ddd9 Mon Sep 17 00:00:00 2001 From: graykode Date: Wed, 25 Sep 2024 15:25:45 +0900 Subject: [PATCH] test: add tc for add liquidity without swap --- test/add-liquidity.test.ts | 350 +++++++++++++++++++++++++++++++++++++ test/utils/currency.ts | 40 +++++ 2 files changed, 390 insertions(+) create mode 100644 test/add-liquidity.test.ts diff --git a/test/add-liquidity.test.ts b/test/add-liquidity.test.ts new file mode 100644 index 0000000..d9d5c07 --- /dev/null +++ b/test/add-liquidity.test.ts @@ -0,0 +1,350 @@ +import { expect, beforeEach, test } from 'vitest' +import { addLiquidity, getPool } from '@clober/v2-sdk' +import { formatUnits, zeroHash } from 'viem' + +import { cloberTestChain } from '../src/constants/test-chain' + +import { account, FORK_URL } from './utils/constants' +import { createProxyClients } from './utils/utils' +import { fetchLPBalance, fetchTokenBalance } from './utils/currency' + +const clients = createProxyClients( + Array.from({ length: 2 }, () => Math.floor(new Date().getTime())).map( + (id) => id, + ), +) + +beforeEach(async () => { + await Promise.all( + clients.map(({ testClient }) => { + return testClient.reset({ + jsonRpcUrl: FORK_URL, + blockNumber: 83907945n, + }) + }), + ) +}) + +test('Add liquidity without swap - 1', async () => { + const { publicClient, walletClient } = clients[0] as any + + const pool = await getPool({ + chainId: cloberTestChain.id, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + let [beforeUSDCBalance, beforeWETHBalance, beforeLPBalance] = + await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + const { transaction: tx1, result: result1 } = await addLiquidity({ + chainId: cloberTestChain.id, + userAddress: account.address, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + amount0: '2000', + amount1: '1.0', + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + const hash1 = await walletClient.sendTransaction({ + ...tx1!, + account, + gasPrice: tx1!.gasPrice! * 2n, + }) + await publicClient.waitForTransactionReceipt({ hash: hash1 }) + let [afterUSDCBalance, afterWETHBalance, afterLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + expect(formatUnits(beforeUSDCBalance - afterUSDCBalance, 6)).toBe( + result1.currencyA.amount, + ) + expect(formatUnits(beforeWETHBalance - afterWETHBalance, 18)).toBe( + result1.currencyB.amount, + ) + expect(formatUnits(afterLPBalance - beforeLPBalance, 18)).toBe( + result1.lpCurrency.amount, + ) + + // add liquidity more + ;[beforeUSDCBalance, beforeWETHBalance, beforeLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + const { transaction: tx2, result: result2 } = await addLiquidity({ + chainId: cloberTestChain.id, + userAddress: account.address, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + amount0: '2000', + amount1: '0.7', + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + const hash2 = await walletClient.sendTransaction({ + ...tx2!, + account, + gasPrice: tx2!.gasPrice! * 2n, + }) + await publicClient.waitForTransactionReceipt({ hash: hash2 }) + ;[afterUSDCBalance, afterWETHBalance, afterLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + expect(formatUnits(beforeUSDCBalance - afterUSDCBalance, 6)).toBe( + result2.currencyA.amount, + ) + expect(formatUnits(beforeWETHBalance - afterWETHBalance, 18)).toBe( + result2.currencyB.amount, + ) + expect(formatUnits(afterLPBalance - beforeLPBalance, 18)).toBe( + result2.lpCurrency.amount, + ) +}) + +test('Add liquidity without swap - 2', async () => { + const { publicClient, walletClient } = clients[0] as any + + const pool = await getPool({ + chainId: cloberTestChain.id, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + let [beforeUSDCBalance, beforeWETHBalance, beforeLPBalance] = + await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + const { transaction: tx1, result: result1 } = await addLiquidity({ + chainId: cloberTestChain.id, + userAddress: account.address, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + amount0: '2000', + amount1: '0.7', + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + const hash1 = await walletClient.sendTransaction({ + ...tx1!, + account, + gasPrice: tx1!.gasPrice! * 2n, + }) + await publicClient.waitForTransactionReceipt({ hash: hash1 }) + let [afterUSDCBalance, afterWETHBalance, afterLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + expect(formatUnits(beforeUSDCBalance - afterUSDCBalance, 6)).toBe( + result1.currencyA.amount, + ) + expect(formatUnits(beforeWETHBalance - afterWETHBalance, 18)).toBe( + result1.currencyB.amount, + ) + expect(formatUnits(afterLPBalance - beforeLPBalance, 18)).toBe( + result1.lpCurrency.amount, + ) + + // add liquidity more + ;[beforeUSDCBalance, beforeWETHBalance, beforeLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + const { transaction: tx2, result: result2 } = await addLiquidity({ + chainId: cloberTestChain.id, + userAddress: account.address, + token0: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + token1: '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + salt: zeroHash, + amount0: '2000', + amount1: '1.0', + options: { + rpcUrl: publicClient.transport.url!, + useSubgraph: false, + }, + }) + + const hash2 = await walletClient.sendTransaction({ + ...tx2!, + account, + gasPrice: tx2!.gasPrice! * 2n, + }) + await publicClient.waitForTransactionReceipt({ hash: hash2 }) + ;[afterUSDCBalance, afterWETHBalance, afterLPBalance] = await Promise.all([ + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0', + account.address, + ), + fetchTokenBalance( + publicClient, + cloberTestChain.id, + '0xF2e615A933825De4B39b497f6e6991418Fb31b78', + account.address, + ), + fetchLPBalance( + publicClient, + cloberTestChain.id, + BigInt(pool.key), + account.address, + ), + ]) + + expect(formatUnits(beforeUSDCBalance - afterUSDCBalance, 6)).toBe( + result2.currencyA.amount, + ) + expect(formatUnits(beforeWETHBalance - afterWETHBalance, 18)).toBe( + result2.currencyB.amount, + ) + expect(formatUnits(afterLPBalance - beforeLPBalance, 18)).toBe( + result2.lpCurrency.amount, + ) +}) + +// test('Add liquidity with swap', async () => { +// const { publicClient, walletClient } = clients[0] as any +// }) diff --git a/test/utils/currency.ts b/test/utils/currency.ts index 38527cc..07fe51a 100644 --- a/test/utils/currency.ts +++ b/test/utils/currency.ts @@ -1,6 +1,7 @@ import { PublicClient } from 'viem' import { CHAIN_IDS } from '../../src' +import { CONTRACT_ADDRESSES } from '../../src/constants/addresses' const _abi = [ { @@ -37,3 +38,42 @@ export const fetchTokenBalance = async ( args: [userAddress], }) } + +export const fetchLPBalance = async ( + publicClient: PublicClient, + chainId: CHAIN_IDS, + tokenId: bigint, + userAddress: `0x${string}`, +): Promise => { + return publicClient.readContract({ + address: CONTRACT_ADDRESSES[chainId]!.Rebalancer, + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ] as const, + functionName: 'balanceOf', + args: [userAddress, tokenId], + }) +}