mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 20:36:19 +00:00
Smoke test for entities after Mint event (#185)
* Test for Token & Factory entities after MintEvent. * Test for Pool, Mint & Tick entities after MintEvent. Co-authored-by: prathamesh0 <prathamesh.musale0@gmail.com>
This commit is contained in:
parent
a9d411c6df
commit
df85f961db
@ -1,4 +1,4 @@
|
||||
timeout: '20000'
|
||||
timeout: '50000'
|
||||
bail: true
|
||||
exit: true # TODO: Find out why the program doesn't exit on its own.
|
||||
require: 'ts-node/register'
|
||||
|
@ -1,9 +1,22 @@
|
||||
import { expect } from 'chai';
|
||||
import { ethers, Contract, Signer } from 'ethers';
|
||||
import { ethers, Contract, ContractTransaction, Signer } from 'ethers';
|
||||
import { request } from 'graphql-request';
|
||||
import 'mocha';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Config, getConfig, wait, deployTokens, createPool, initializePool } from '@vulcanize/util';
|
||||
import {
|
||||
Config,
|
||||
getConfig,
|
||||
wait,
|
||||
deployTokens,
|
||||
deployUniswapV3Callee,
|
||||
TESTERC20_ABI,
|
||||
createPool,
|
||||
initializePool,
|
||||
getMinTick,
|
||||
getMaxTick,
|
||||
approveToken
|
||||
} from '@vulcanize/util';
|
||||
import { Client as UniClient, watchEvent } from '@vulcanize/uni-watcher';
|
||||
import {
|
||||
abi as FACTORY_ABI
|
||||
@ -18,7 +31,9 @@ import {
|
||||
queryToken,
|
||||
queryPoolsByTokens,
|
||||
queryPoolById,
|
||||
queryPoolDayData
|
||||
queryPoolDayData,
|
||||
queryMints,
|
||||
queryTicks
|
||||
} from '../test/queries';
|
||||
|
||||
const NETWORK_RPC_URL = 'http://localhost:8545';
|
||||
@ -28,10 +43,13 @@ const TICK_MIN = -887272;
|
||||
describe('uni-info-watcher', () => {
|
||||
let factory: Contract;
|
||||
let pool: Contract;
|
||||
let token0: Contract;
|
||||
let token1: Contract;
|
||||
let token0Address: string;
|
||||
let token1Address: string;
|
||||
|
||||
let signer: Signer;
|
||||
let recipient: string;
|
||||
let config: Config;
|
||||
let endpoint: string;
|
||||
let uniClient: UniClient;
|
||||
@ -39,6 +57,7 @@ describe('uni-info-watcher', () => {
|
||||
before(async () => {
|
||||
const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL);
|
||||
signer = provider.getSigner();
|
||||
recipient = await signer.getAddress();
|
||||
|
||||
const configFile = './environments/local.toml';
|
||||
config = await getConfig(configFile);
|
||||
@ -94,7 +113,7 @@ describe('uni-info-watcher', () => {
|
||||
expect(data1.token).to.be.null;
|
||||
});
|
||||
|
||||
it('should create pool', async () => {
|
||||
it('should trigger PoolCreatedEvent', async () => {
|
||||
// Create Pool.
|
||||
createPool(factory, token0Address, token1Address, fee);
|
||||
|
||||
@ -103,7 +122,7 @@ describe('uni-info-watcher', () => {
|
||||
await watchEvent(uniClient, eventType);
|
||||
|
||||
// Sleeping for 5 sec for the entities to be processed.
|
||||
await wait(5000);
|
||||
await wait(10000);
|
||||
});
|
||||
|
||||
it('should create Token entities', async () => {
|
||||
@ -129,6 +148,12 @@ describe('uni-info-watcher', () => {
|
||||
expect(pool.address).to.not.be.empty;
|
||||
|
||||
expect(data.pools[0].feeTier).to.be.equal(fee.toString());
|
||||
|
||||
// Initializing the token variables.
|
||||
token0Address = await pool.token0();
|
||||
token0 = new Contract(token0Address, TESTERC20_ABI, signer);
|
||||
token1Address = await pool.token1();
|
||||
token1 = new Contract(token1Address, TESTERC20_ABI, signer);
|
||||
});
|
||||
});
|
||||
|
||||
@ -142,7 +167,7 @@ describe('uni-info-watcher', () => {
|
||||
expect(data.pool.tick).to.be.null;
|
||||
});
|
||||
|
||||
it('should initialize pool', async () => {
|
||||
it('should trigger InitializeEvent', async () => {
|
||||
initializePool(pool, sqrtPrice);
|
||||
|
||||
// Wait for InitializeEvent.
|
||||
@ -183,4 +208,141 @@ describe('uni-info-watcher', () => {
|
||||
expect(tvlUSD).to.be.equal(totalValueLockedUSD);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MintEvent', () => {
|
||||
const amount = 10;
|
||||
const approveAmount = BigInt(1000000000000000000000000);
|
||||
let poolCallee: Contract;
|
||||
let tickLower: number;
|
||||
let tickUpper: number;
|
||||
|
||||
// Initial entity values
|
||||
let oldFactory: any;
|
||||
let oldToken0: any;
|
||||
let oldToken1: any;
|
||||
let oldPool: any;
|
||||
|
||||
before(async () => {
|
||||
// Deploy UniswapV3Callee.
|
||||
poolCallee = await deployUniswapV3Callee(signer);
|
||||
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
tickLower = getMinTick(tickSpacing);
|
||||
tickUpper = getMaxTick(tickSpacing);
|
||||
|
||||
await approveToken(token0, poolCallee.address, approveAmount);
|
||||
await approveToken(token1, poolCallee.address, approveAmount);
|
||||
|
||||
// Get initial entity values.
|
||||
let data: any;
|
||||
|
||||
data = await request(endpoint, queryFactory);
|
||||
oldFactory = data.factories[0];
|
||||
|
||||
data = await request(endpoint, queryToken, { id: token0.address });
|
||||
oldToken0 = data.token;
|
||||
|
||||
data = await request(endpoint, queryToken, { id: token1.address });
|
||||
oldToken1 = data.token;
|
||||
|
||||
data = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
oldPool = data.pool;
|
||||
});
|
||||
|
||||
it('should trigger MintEvent', async () => {
|
||||
// Pool mint.
|
||||
const transaction: ContractTransaction = await poolCallee.mint(pool.address, recipient, BigInt(tickLower), BigInt(tickUpper), BigInt(amount));
|
||||
await transaction.wait();
|
||||
|
||||
// Wait for MintEvent.
|
||||
const eventType = 'MintEvent';
|
||||
await watchEvent(uniClient, eventType);
|
||||
|
||||
// Sleeping for 20 sec for the entities to be processed.
|
||||
await wait(20000);
|
||||
});
|
||||
|
||||
it('should update Token entities', async () => {
|
||||
// Check txCount.
|
||||
let data: any;
|
||||
|
||||
data = await request(endpoint, queryToken, { id: token0.address });
|
||||
const newToken0 = data.token;
|
||||
|
||||
data = await request(endpoint, queryToken, { id: token1.address });
|
||||
const newToken1 = data.token;
|
||||
|
||||
expect(newToken0.txCount).to.be.equal((BigInt(oldToken0.txCount) + BigInt(1)).toString());
|
||||
expect(newToken1.txCount).to.be.equal((BigInt(oldToken1.txCount) + BigInt(1)).toString());
|
||||
});
|
||||
|
||||
it('should update Factory entity', async () => {
|
||||
// Check txCount.
|
||||
const data = await request(endpoint, queryFactory);
|
||||
const newFactory = data.factories[0];
|
||||
expect(newFactory.txCount).to.be.equal((BigInt(oldFactory.txCount) + BigInt(1)).toString());
|
||||
});
|
||||
|
||||
it('should update Pool entity', async () => {
|
||||
// Check txCount, liquidity.
|
||||
let expectedLiquidity = BigInt(oldPool.liquidity);
|
||||
if (oldPool.tick !== null) {
|
||||
if (
|
||||
BigInt(tickLower) <= BigInt(oldPool.tick) &&
|
||||
BigInt(tickUpper) > BigInt(oldPool.tick)
|
||||
) {
|
||||
expectedLiquidity = BigInt(oldPool.liquidity) + BigInt(amount);
|
||||
}
|
||||
}
|
||||
|
||||
const data = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
const newPool = data.pool;
|
||||
|
||||
expect(newPool.txCount).to.be.equal((BigInt(oldPool.txCount) + BigInt(1)).toString());
|
||||
expect(BigInt(newPool.liquidity)).to.be.equal(expectedLiquidity);
|
||||
});
|
||||
|
||||
it('should create a Mint entity', async () => {
|
||||
// Check id, owner, sender.
|
||||
// Get the latest Mint.
|
||||
let data: any;
|
||||
const variables = {
|
||||
first: 1,
|
||||
orderBy: 'timestamp',
|
||||
orderDirection: 'desc',
|
||||
pool: pool.address,
|
||||
};
|
||||
data = await request(endpoint, queryMints, variables);
|
||||
expect(data.mints).to.not.be.empty;
|
||||
|
||||
const id: string = data.mints[0].id;
|
||||
const txCountID = id.split('#')[1];
|
||||
const owner = data.mints[0].owner;
|
||||
const sender = data.mints[0].sender;
|
||||
|
||||
data = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
const poolTxCount = data.pool.txCount;
|
||||
const expectedOwner = recipient;
|
||||
const expectedSender = poolCallee.address;
|
||||
|
||||
expect(txCountID).to.be.equal(poolTxCount);
|
||||
expect(owner).to.be.equal(expectedOwner);
|
||||
expect(sender).to.be.equal(expectedSender);
|
||||
});
|
||||
|
||||
it('should create Tick entities', async () => {
|
||||
// Check liquidityGross, liquidityNet.
|
||||
const data = await request(endpoint, queryTicks, { pool: pool.address });
|
||||
expect(data.ticks).to.not.be.empty;
|
||||
|
||||
const lowerTick: any = _.filter(data.ticks, { tickIdx: tickLower.toString() })[0];
|
||||
const upperTick: any = _.filter(data.ticks, { tickIdx: tickUpper.toString() })[0];
|
||||
|
||||
expect(lowerTick.liquidityGross).to.be.equal(amount.toString());
|
||||
expect(lowerTick.liquidityNet).to.be.equal(amount.toString());
|
||||
expect(upperTick.liquidityGross).to.be.equal(amount.toString());
|
||||
expect(upperTick.liquidityNet).to.be.equal(amount.toString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,7 +3,16 @@ import { gql } from 'graphql-request';
|
||||
export const queryToken = gql`
|
||||
query queryToken($id: ID!) {
|
||||
token(id: $id) {
|
||||
derivedETH
|
||||
feesUSD
|
||||
id
|
||||
name
|
||||
symbol
|
||||
totalValueLocked
|
||||
totalValueLockedUSD
|
||||
txCount
|
||||
volume
|
||||
volumeUSD
|
||||
}
|
||||
}`;
|
||||
|
||||
@ -12,6 +21,10 @@ export const queryFactory = gql`
|
||||
{
|
||||
factories(first: 1) {
|
||||
id
|
||||
totalFeesUSD
|
||||
totalValueLockedUSD
|
||||
totalVolumeUSD
|
||||
txCount
|
||||
}
|
||||
}`;
|
||||
|
||||
@ -20,6 +33,7 @@ export const queryBundle = gql`
|
||||
{
|
||||
bundles(first: 1) {
|
||||
id
|
||||
ethPriceUSD
|
||||
}
|
||||
}`;
|
||||
|
||||
@ -27,10 +41,18 @@ export const queryBundle = gql`
|
||||
export const queryPoolById = gql`
|
||||
query queryPoolById($id: ID!) {
|
||||
pool(id: $id) {
|
||||
id,
|
||||
sqrtPrice,
|
||||
tick,
|
||||
feeTier
|
||||
id
|
||||
liquidity
|
||||
sqrtPrice
|
||||
tick
|
||||
token0Price
|
||||
token1Price
|
||||
totalValueLockedToken0
|
||||
totalValueLockedToken1
|
||||
totalValueLockedUSD
|
||||
txCount
|
||||
volumeUSD
|
||||
}
|
||||
}`;
|
||||
|
||||
@ -52,3 +74,45 @@ query queryPoolDayData($first: Int, $orderBy: PoolDayData_orderBy, $orderDirecti
|
||||
tvlUSD
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting mint(s) filtered by pool, tokens and ordered by timestamp.
|
||||
export const queryMints = gql`
|
||||
query queryMints(
|
||||
$first: Int,
|
||||
$orderBy: Mint_orderBy,
|
||||
$orderDirection: OrderDirection,
|
||||
$pool: String,
|
||||
$token0: String,
|
||||
$token1: String) {
|
||||
mints(
|
||||
first: $first,
|
||||
orderBy: $orderBy,
|
||||
orderDirection: $orderDirection,
|
||||
where: {
|
||||
pool: $pool,
|
||||
token0: $token0,
|
||||
token1: $token1
|
||||
}) {
|
||||
amount0
|
||||
amount1
|
||||
amountUSD
|
||||
id
|
||||
origin
|
||||
owner
|
||||
sender
|
||||
timestamp
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting Tick(s) filtered by pool.
|
||||
export const queryTicks = gql`
|
||||
query queryTicksByPool($pool: String) {
|
||||
ticks(where: { poolAddress: $pool }) {
|
||||
id
|
||||
liquidityGross
|
||||
liquidityNet
|
||||
price0
|
||||
price1
|
||||
tickIdx
|
||||
}
|
||||
}`;
|
||||
|
@ -1,4 +1,4 @@
|
||||
timeout: '60000'
|
||||
timeout: '70000'
|
||||
bail: true
|
||||
exit: true # TODO: Find out why the program doesn't exit on its own.
|
||||
require: 'ts-node/register'
|
||||
|
@ -2,7 +2,16 @@ import { expect, assert } from 'chai';
|
||||
import { ethers, Contract, ContractTransaction, Signer, constants } from 'ethers';
|
||||
import 'mocha';
|
||||
|
||||
import { Config, getConfig, deployTokens, TESTERC20_ABI } from '@vulcanize/util';
|
||||
import {
|
||||
Config,
|
||||
getConfig,
|
||||
deployTokens,
|
||||
deployUniswapV3Callee,
|
||||
TESTERC20_ABI,
|
||||
getMinTick,
|
||||
getMaxTick,
|
||||
approveToken
|
||||
} from '@vulcanize/util';
|
||||
import { Client as UniClient } from '@vulcanize/uni-watcher';
|
||||
import { getCache } from '@vulcanize/cache';
|
||||
import { EthClient } from '@vulcanize/ipld-eth-client';
|
||||
@ -42,10 +51,6 @@ import {
|
||||
checkDecreaseLiquidityEvent,
|
||||
checksCollectEvent
|
||||
} from '../test/utils';
|
||||
import {
|
||||
abi as TESTUNISWAPV3CALLEE_ABI,
|
||||
bytecode as TESTUNISWAPV3CALLEE_BYTECODE
|
||||
} from '../artifacts/test/contracts/TestUniswapV3Callee.sol/TestUniswapV3Callee.json';
|
||||
import {
|
||||
abi as WETH9_ABI,
|
||||
bytecode as WETH9_BYTECODE
|
||||
@ -55,14 +60,13 @@ const NETWORK_RPC_URL = 'http://localhost:8545';
|
||||
|
||||
const TICK_MIN = -887272;
|
||||
const TICK_MAX = 887272;
|
||||
const getMinTick = (tickSpacing: number) => Math.ceil(TICK_MIN / tickSpacing) * tickSpacing;
|
||||
const getMaxTick = (tickSpacing: number) => Math.floor(TICK_MAX / tickSpacing) * tickSpacing;
|
||||
|
||||
describe('uni-watcher', () => {
|
||||
let factory: Contract;
|
||||
let pool: Contract;
|
||||
let token0: Contract;
|
||||
let token1: Contract;
|
||||
let poolCallee: Contract;
|
||||
let token0Address: string;
|
||||
let token1Address: string;
|
||||
let weth9Address: string;
|
||||
@ -161,6 +165,12 @@ describe('uni-watcher', () => {
|
||||
token0 = new Contract(token0Address, TESTERC20_ABI, signer);
|
||||
token1Address = await pool.token1();
|
||||
token1 = new Contract(token1Address, TESTERC20_ABI, signer);
|
||||
|
||||
// Initializing ticks.
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
tickLower = getMinTick(tickSpacing);
|
||||
tickUpper = getMaxTick(tickSpacing);
|
||||
});
|
||||
|
||||
it('should initialize pool', async () => {
|
||||
@ -174,21 +184,11 @@ describe('uni-watcher', () => {
|
||||
const amount = 10;
|
||||
const approveAmount = BigInt(1000000000000000000000000);
|
||||
|
||||
const TestUniswapV3Callee = new ethers.ContractFactory(TESTUNISWAPV3CALLEE_ABI, TESTUNISWAPV3CALLEE_BYTECODE, signer);
|
||||
const poolCallee = await TestUniswapV3Callee.deploy();
|
||||
// Deploy UniswapV3Callee.
|
||||
poolCallee = await deployUniswapV3Callee(signer);
|
||||
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
tickLower = getMinTick(tickSpacing);
|
||||
tickUpper = getMaxTick(tickSpacing);
|
||||
|
||||
// Approving tokens for TestUniswapV3Callee contract.
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/shared/utilities.ts#L187
|
||||
const t0 = await token0.approve(poolCallee.address, approveAmount);
|
||||
await t0.wait();
|
||||
|
||||
const t1 = await token1.approve(poolCallee.address, approveAmount);
|
||||
await t1.wait();
|
||||
await approveToken(token0, poolCallee.address, approveAmount);
|
||||
await approveToken(token1, poolCallee.address, approveAmount);
|
||||
|
||||
// Subscribe using UniClient.
|
||||
const subscription = await uniClient.watchEvents((value: any) => {
|
||||
@ -218,11 +218,6 @@ describe('uni-watcher', () => {
|
||||
(async () => {
|
||||
const amount = 10;
|
||||
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
const tickLower = getMinTick(tickSpacing);
|
||||
const tickUpper = getMaxTick(tickSpacing);
|
||||
|
||||
// Subscribe using UniClient.
|
||||
const subscription = await uniClient.watchEvents((value: any) => {
|
||||
if (value.event.__typename === 'BurnEvent') {
|
||||
@ -250,9 +245,6 @@ describe('uni-watcher', () => {
|
||||
(async () => {
|
||||
const sqrtPrice = '4295128938';
|
||||
|
||||
const TestUniswapV3Callee = new ethers.ContractFactory(TESTUNISWAPV3CALLEE_ABI, TESTUNISWAPV3CALLEE_BYTECODE, signer);
|
||||
const poolCallee = await TestUniswapV3Callee.deploy();
|
||||
|
||||
// Subscribe using UniClient.
|
||||
const subscription = await uniClient.watchEvents((value: any) => {
|
||||
if (value.event.__typename === 'SwapEvent') {
|
||||
@ -330,6 +322,11 @@ describe('uni-watcher', () => {
|
||||
const fee = 3000;
|
||||
pool = await testCreatePool(uniClient, factory, token0Address, token1Address, fee, POOL_ABI, signer);
|
||||
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
tickLower = getMinTick(tickSpacing);
|
||||
tickUpper = getMaxTick(tickSpacing);
|
||||
|
||||
const sqrtPrice = '79228162514264337593543950336';
|
||||
await testInitialize(uniClient, pool, sqrtPrice, 0);
|
||||
|
||||
@ -339,11 +336,6 @@ describe('uni-watcher', () => {
|
||||
const amount1Min = 0;
|
||||
const deadline = 1634367993;
|
||||
|
||||
const tickSpacing = await pool.tickSpacing();
|
||||
// https://github.com/Uniswap/uniswap-v3-core/blob/main/test/UniswapV3Pool.spec.ts#L196
|
||||
tickLower = getMinTick(tickSpacing);
|
||||
tickUpper = getMaxTick(tickSpacing);
|
||||
|
||||
// Approving tokens for NonfungiblePositionManager contract.
|
||||
// https://github.com/Uniswap/uniswap-v3-periphery/blob/main/test/NonfungiblePositionManager.spec.ts#L44
|
||||
const t0 = await token0.approve(nfpm.address, constants.MaxUint256);
|
||||
@ -487,7 +479,7 @@ describe('uni-watcher', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should collect fees', done => {
|
||||
xit('should collect fees', done => {
|
||||
(async () => {
|
||||
const tokenId = 1;
|
||||
const amount0Max = 15;
|
||||
|
@ -4,9 +4,18 @@ import {
|
||||
abi as TESTERC20_ABI,
|
||||
bytecode as TESTERC20_BYTECODE
|
||||
} from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json';
|
||||
import {
|
||||
abi as TESTUNISWAPV3CALLEE_ABI,
|
||||
bytecode as TESTUNISWAPV3CALLEE_BYTECODE
|
||||
} from '../artifacts/test/contracts/TestUniswapV3Callee.sol/TestUniswapV3Callee.json';
|
||||
|
||||
export { abi as TESTERC20_ABI } from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json';
|
||||
|
||||
const TICK_MIN = -887272;
|
||||
const TICK_MAX = 887272;
|
||||
export const getMinTick = (tickSpacing: number) => Math.ceil(TICK_MIN / tickSpacing) * tickSpacing;
|
||||
export const getMaxTick = (tickSpacing: number) => Math.floor(TICK_MAX / tickSpacing) * tickSpacing;
|
||||
|
||||
export const deployTokens = async (signer: Signer): Promise<{token0Address: string, token1Address: string}> => {
|
||||
const Token = new ethers.ContractFactory(TESTERC20_ABI, TESTERC20_BYTECODE, signer);
|
||||
|
||||
@ -19,6 +28,16 @@ export const deployTokens = async (signer: Signer): Promise<{token0Address: stri
|
||||
return { token0Address, token1Address };
|
||||
};
|
||||
|
||||
export const deployUniswapV3Callee = async (signer: Signer): Promise<Contract> => {
|
||||
const TestUniswapV3Callee = new ethers.ContractFactory(TESTUNISWAPV3CALLEE_ABI, TESTUNISWAPV3CALLEE_BYTECODE, signer);
|
||||
return await TestUniswapV3Callee.deploy();
|
||||
};
|
||||
|
||||
export const approveToken = async (token: Contract, address: string, approveAmount: bigint): Promise<void> => {
|
||||
const transaction: ContractTransaction = await token.approve(address, approveAmount);
|
||||
await transaction.wait();
|
||||
};
|
||||
|
||||
export const createPool = async (
|
||||
factory: Contract,
|
||||
token0Address: string,
|
||||
|
Loading…
Reference in New Issue
Block a user