mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-06 19:38:05 +00:00
Smoke test for uni-info-watcher (#184)
* Smoke test for uni-info-watcher and refactor token deployment code. * Test for Token entity after PoolCreated event. * Test for Pool entity after PoolCreated event. * Tests for entities after InitializeEvent. Co-authored-by: prathamesh0 <prathamesh.musale0@gmail.com>
This commit is contained in:
parent
73e0475dfa
commit
a9d411c6df
@ -23,5 +23,13 @@
|
||||
"allowArgumentsExplicitlyTypedAsAny": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.test.ts"],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
4
packages/uni-info-watcher/.mocharc.yml
Normal file
4
packages/uni-info-watcher/.mocharc.yml
Normal file
@ -0,0 +1,4 @@
|
||||
timeout: '20000'
|
||||
bail: true
|
||||
exit: true # TODO: Find out why the program doesn't exit on its own.
|
||||
require: 'ts-node/register'
|
@ -22,7 +22,8 @@
|
||||
"lint": "eslint .",
|
||||
"build": "tsc",
|
||||
"generate:schema": "get-graphql-schema https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-alt > docs/analysis/schema/full-schema.graphql",
|
||||
"lint:schema": "graphql-schema-linter"
|
||||
"lint:schema": "graphql-schema-linter",
|
||||
"smoke-test": "mocha src/smoke.test.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chance": "^1.1.2",
|
||||
@ -41,6 +42,8 @@
|
||||
"get-graphql-schema": "^2.1.2",
|
||||
"graphql-schema-linter": "^2.0.1",
|
||||
"mocha": "^8.4.0",
|
||||
"nodemon": "^2.0.7"
|
||||
"nodemon": "^2.0.7",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.3.2"
|
||||
}
|
||||
}
|
||||
|
186
packages/uni-info-watcher/src/smoke.test.ts
Normal file
186
packages/uni-info-watcher/src/smoke.test.ts
Normal file
@ -0,0 +1,186 @@
|
||||
import { expect } from 'chai';
|
||||
import { ethers, Contract, Signer } from 'ethers';
|
||||
import { request } from 'graphql-request';
|
||||
import 'mocha';
|
||||
|
||||
import { Config, getConfig, wait, deployTokens, createPool, initializePool } from '@vulcanize/util';
|
||||
import { Client as UniClient, watchEvent } from '@vulcanize/uni-watcher';
|
||||
import {
|
||||
abi as FACTORY_ABI
|
||||
} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json';
|
||||
import {
|
||||
abi as POOL_ABI
|
||||
} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json';
|
||||
|
||||
import {
|
||||
queryFactory,
|
||||
queryBundle,
|
||||
queryToken,
|
||||
queryPoolsByTokens,
|
||||
queryPoolById,
|
||||
queryPoolDayData
|
||||
} from '../test/queries';
|
||||
|
||||
const NETWORK_RPC_URL = 'http://localhost:8545';
|
||||
|
||||
const TICK_MIN = -887272;
|
||||
|
||||
describe('uni-info-watcher', () => {
|
||||
let factory: Contract;
|
||||
let pool: Contract;
|
||||
let token0Address: string;
|
||||
let token1Address: string;
|
||||
|
||||
let signer: Signer;
|
||||
let config: Config;
|
||||
let endpoint: string;
|
||||
let uniClient: UniClient;
|
||||
|
||||
before(async () => {
|
||||
const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL);
|
||||
signer = provider.getSigner();
|
||||
|
||||
const configFile = './environments/local.toml';
|
||||
config = await getConfig(configFile);
|
||||
|
||||
const { upstream, server: { host, port } } = config;
|
||||
endpoint = `http://${host}:${port}/graphql`;
|
||||
|
||||
const { uniWatcher: { gqlEndpoint, gqlSubscriptionEndpoint } } = upstream;
|
||||
uniClient = new UniClient({
|
||||
gqlEndpoint,
|
||||
gqlSubscriptionEndpoint
|
||||
});
|
||||
});
|
||||
|
||||
it('should have a Factory entity', async () => {
|
||||
// Getting the Factory from uni-info-watcher graphQL endpoint.
|
||||
const data = await request(endpoint, queryFactory);
|
||||
expect(data.factories).to.not.be.empty;
|
||||
|
||||
// Initializing the factory variable.
|
||||
const factoryAddress = data.factories[0].id;
|
||||
factory = new ethers.Contract(factoryAddress, FACTORY_ABI, signer);
|
||||
expect(factory.address).to.not.be.empty;
|
||||
});
|
||||
|
||||
it('should have a Bundle entity', async () => {
|
||||
// Getting the Bundle from uni-info-watcher graphQL endpoint.
|
||||
const data = await request(endpoint, queryBundle);
|
||||
expect(data.bundles).to.not.be.empty;
|
||||
|
||||
const bundleId = '1';
|
||||
expect(data.bundles[0].id).to.equal(bundleId);
|
||||
});
|
||||
|
||||
describe('PoolCreatedEvent', () => {
|
||||
// NOTE Skipping checking entity updates that cannot be gotten using queries.
|
||||
|
||||
const fee = 500;
|
||||
|
||||
before(async () => {
|
||||
// Deploy 2 tokens.
|
||||
({ token0Address, token1Address } = await deployTokens(signer));
|
||||
expect(token0Address).to.not.be.empty;
|
||||
expect(token1Address).to.not.be.empty;
|
||||
});
|
||||
|
||||
it('should not have Token entities', async () => {
|
||||
// Check that Token entities are absent.
|
||||
const data0 = await request(endpoint, queryToken, { id: token0Address });
|
||||
expect(data0.token).to.be.null;
|
||||
|
||||
const data1 = await request(endpoint, queryToken, { id: token0Address });
|
||||
expect(data1.token).to.be.null;
|
||||
});
|
||||
|
||||
it('should create pool', async () => {
|
||||
// Create Pool.
|
||||
createPool(factory, token0Address, token1Address, fee);
|
||||
|
||||
// Wait for PoolCreatedEvent.
|
||||
const eventType = 'PoolCreatedEvent';
|
||||
await watchEvent(uniClient, eventType);
|
||||
|
||||
// Sleeping for 5 sec for the entities to be processed.
|
||||
await wait(5000);
|
||||
});
|
||||
|
||||
it('should create Token entities', async () => {
|
||||
// Check that Token entities are present.
|
||||
const data0 = await request(endpoint, queryToken, { id: token0Address });
|
||||
expect(data0.token).to.not.be.null;
|
||||
|
||||
const data1 = await request(endpoint, queryToken, { id: token0Address });
|
||||
expect(data1.token).to.not.be.null;
|
||||
});
|
||||
|
||||
it('should create a Pool entity', async () => {
|
||||
const variables = {
|
||||
tokens: [token0Address, token1Address]
|
||||
};
|
||||
// Getting the Pool that has the deployed tokens.
|
||||
const data = await request(endpoint, queryPoolsByTokens, variables);
|
||||
expect(data.pools).to.have.lengthOf(1);
|
||||
|
||||
// Initializing the pool variable.
|
||||
const poolAddress = data.pools[0].id;
|
||||
pool = new Contract(poolAddress, POOL_ABI, signer);
|
||||
expect(pool.address).to.not.be.empty;
|
||||
|
||||
expect(data.pools[0].feeTier).to.be.equal(fee.toString());
|
||||
});
|
||||
});
|
||||
|
||||
describe('InitializeEvent', () => {
|
||||
const sqrtPrice = '4295128939';
|
||||
const tick = TICK_MIN;
|
||||
|
||||
it('should not have pool entity initialized', async () => {
|
||||
const data = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
expect(data.pool.sqrtPrice).to.not.be.equal(sqrtPrice);
|
||||
expect(data.pool.tick).to.be.null;
|
||||
});
|
||||
|
||||
it('should initialize pool', async () => {
|
||||
initializePool(pool, sqrtPrice);
|
||||
|
||||
// Wait for InitializeEvent.
|
||||
const eventType = 'InitializeEvent';
|
||||
await watchEvent(uniClient, eventType);
|
||||
|
||||
// Sleeping for 5 sec for the entities to be processed.
|
||||
await wait(5000);
|
||||
|
||||
const data = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
expect(data.pool.sqrtPrice).to.be.equal(sqrtPrice);
|
||||
expect(data.pool.tick).to.be.equal(tick.toString());
|
||||
});
|
||||
|
||||
it('should update PoolDayData entity', async () => {
|
||||
// Get the latest PoolDayData.
|
||||
const variables = {
|
||||
first: 1,
|
||||
orderBy: 'date',
|
||||
orderDirection: 'desc',
|
||||
pool: pool.address
|
||||
};
|
||||
const data = await request(endpoint, queryPoolDayData, variables);
|
||||
expect(data.poolDayDatas).to.not.be.empty;
|
||||
|
||||
const dayPoolID: string = data.poolDayDatas[0].id;
|
||||
const poolID: string = dayPoolID.split('-')[0];
|
||||
const dayID: number = +dayPoolID.split('-')[1];
|
||||
const date = data.poolDayDatas[0].date;
|
||||
const tvlUSD = data.poolDayDatas[0].tvlUSD;
|
||||
|
||||
const dayStartTimestamp = dayID * 86400;
|
||||
const poolData = await request(endpoint, queryPoolById, { id: pool.address });
|
||||
const totalValueLockedUSD: string = poolData.pool.totalValueLockedUSD;
|
||||
|
||||
expect(poolID).to.be.equal(pool.address);
|
||||
expect(date).to.be.equal(dayStartTimestamp);
|
||||
expect(tvlUSD).to.be.equal(totalValueLockedUSD);
|
||||
});
|
||||
});
|
||||
});
|
54
packages/uni-info-watcher/test/queries.ts
Normal file
54
packages/uni-info-watcher/test/queries.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { gql } from 'graphql-request';
|
||||
|
||||
export const queryToken = gql`
|
||||
query queryToken($id: ID!) {
|
||||
token(id: $id) {
|
||||
id
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting the first Factory entity.
|
||||
export const queryFactory = gql`
|
||||
{
|
||||
factories(first: 1) {
|
||||
id
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting the first Bundle entity.
|
||||
export const queryBundle = gql`
|
||||
{
|
||||
bundles(first: 1) {
|
||||
id
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting Pool by id.
|
||||
export const queryPoolById = gql`
|
||||
query queryPoolById($id: ID!) {
|
||||
pool(id: $id) {
|
||||
id,
|
||||
sqrtPrice,
|
||||
tick,
|
||||
totalValueLockedUSD
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting Pool(s) filtered by tokens.
|
||||
export const queryPoolsByTokens = gql`
|
||||
query queryPoolsByTokens($tokens: [String!]) {
|
||||
pools(where: { token0_in: $tokens, token1_in: $tokens }) {
|
||||
id,
|
||||
feeTier
|
||||
}
|
||||
}`;
|
||||
|
||||
// Getting PoolDayData(s) filtered by pool and ordered by date.
|
||||
export const queryPoolDayData = gql`
|
||||
query queryPoolDayData($first: Int, $orderBy: PoolDayData_orderBy, $orderDirection: OrderDirection, $pool: String) {
|
||||
poolDayDatas(first: $first, orderBy: $orderBy, orderDirection: $orderDirection, where: { pool: $pool }) {
|
||||
id,
|
||||
date,
|
||||
tvlUSD
|
||||
}
|
||||
}`;
|
@ -29,7 +29,7 @@
|
||||
"files": ["*.test.ts", "test/*.ts"],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off",
|
||||
"no-prototype-builtins":"off"
|
||||
"no-prototype-builtins": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './src/client';
|
||||
export * from './src/utils/index';
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { expect, assert } from 'chai';
|
||||
import { ethers, Contract, ContractTransaction, Signer, constants } from 'ethers';
|
||||
import 'reflect-metadata';
|
||||
import 'mocha';
|
||||
|
||||
import { Config, getConfig } from '@vulcanize/util';
|
||||
import { Config, getConfig, deployTokens, TESTERC20_ABI } from '@vulcanize/util';
|
||||
import { Client as UniClient } from '@vulcanize/uni-watcher';
|
||||
import { getCache } from '@vulcanize/cache';
|
||||
import { EthClient } from '@vulcanize/ipld-eth-client';
|
||||
@ -43,10 +42,6 @@ import {
|
||||
checkDecreaseLiquidityEvent,
|
||||
checksCollectEvent
|
||||
} from '../test/utils';
|
||||
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
|
||||
@ -56,6 +51,8 @@ import {
|
||||
bytecode as WETH9_BYTECODE
|
||||
} from '../artifacts/test/contracts/WETH9.sol/WETH9.json';
|
||||
|
||||
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;
|
||||
@ -119,7 +116,7 @@ describe('uni-watcher', () => {
|
||||
gqlSubscriptionEndpoint
|
||||
});
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
|
||||
const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL);
|
||||
signer = provider.getSigner();
|
||||
recipient = await signer.getAddress();
|
||||
});
|
||||
@ -147,15 +144,10 @@ describe('uni-watcher', () => {
|
||||
|
||||
it('should deploy 2 tokens', async () => {
|
||||
// Deploy 2 tokens.
|
||||
const Token = new ethers.ContractFactory(TESTERC20_ABI, TESTERC20_BYTECODE, signer);
|
||||
|
||||
// Not initializing global token contract variables just yet; initialized in `create pool` to maintatin order coherency.
|
||||
const token0 = await Token.deploy(ethers.BigNumber.from(2).pow(255));
|
||||
token0Address = token0.address;
|
||||
({ token0Address, token1Address } = await deployTokens(signer));
|
||||
expect(token0Address).to.not.be.empty;
|
||||
|
||||
const token1 = await Token.deploy(ethers.BigNumber.from(2).pow(255));
|
||||
token1Address = token1.address;
|
||||
expect(token1Address).to.not.be.empty;
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
import { Database } from '../database';
|
||||
import { Client as UniClient } from '../client';
|
||||
|
||||
export async function watchContract (db: Database, address: string, kind: string, startingBlock: number): Promise<void> {
|
||||
// Always use the checksum address (https://docs.ethers.io/v5/api/utils/address/#utils-getAddress).
|
||||
@ -8,3 +9,22 @@ export async function watchContract (db: Database, address: string, kind: string
|
||||
|
||||
await db.saveContract(contractAddress, kind, startingBlock);
|
||||
}
|
||||
|
||||
export const watchEvent = async (uniClient: UniClient, eventType: string): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
(async () => {
|
||||
try {
|
||||
const subscription = await uniClient.watchEvents((value: any) => {
|
||||
if (value.event.__typename === eventType) {
|
||||
if (subscription) {
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
resolve(value);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
})();
|
||||
});
|
||||
};
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { ethers, utils, Contract, Signer, BigNumber, ContractTransaction } from 'ethers';
|
||||
import { ethers, utils, Contract, Signer } from 'ethers';
|
||||
import { expect } from 'chai';
|
||||
import 'mocha';
|
||||
|
||||
import { Client as UniClient } from '@vulcanize/uni-watcher';
|
||||
import { createPool, initializePool } from '@vulcanize/util';
|
||||
|
||||
// https://github.com/ethers-io/ethers.js/issues/195
|
||||
export function linkLibraries (
|
||||
export const linkLibraries = (
|
||||
{
|
||||
bytecode,
|
||||
linkReferences
|
||||
@ -13,7 +14,7 @@ export function linkLibraries (
|
||||
bytecode: string
|
||||
linkReferences: { [fileName: string]: { [contractName: string]: { length: number; start: number }[] } }
|
||||
},
|
||||
libraries: { [libraryName: string]: string }): string {
|
||||
libraries: { [libraryName: string]: string }): string => {
|
||||
Object.keys(linkReferences).forEach((fileName) => {
|
||||
Object.keys(linkReferences[fileName]).forEach((contractName) => {
|
||||
if (!libraries.hasOwnProperty(contractName)) {
|
||||
@ -31,16 +32,16 @@ export function linkLibraries (
|
||||
});
|
||||
});
|
||||
return bytecode;
|
||||
}
|
||||
};
|
||||
|
||||
export async function testCreatePool (
|
||||
export const testCreatePool = async (
|
||||
uniClient: UniClient,
|
||||
factory: Contract,
|
||||
token0Address: string,
|
||||
token1Address: string,
|
||||
fee: number,
|
||||
poolAbi: any,
|
||||
signer: Signer): Promise<Contract> {
|
||||
signer: Signer): Promise<Contract> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
(async () => {
|
||||
try {
|
||||
@ -60,20 +61,19 @@ export async function testCreatePool (
|
||||
});
|
||||
|
||||
// Create pool.
|
||||
const transaction: ContractTransaction = await factory.createPool(token0Address, token1Address, fee);
|
||||
await transaction.wait();
|
||||
await createPool(factory, token0Address, token1Address, fee);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
})();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export function testInitialize (
|
||||
export const testInitialize = async (
|
||||
uniClient: UniClient,
|
||||
pool: Contract,
|
||||
sqrtPrice: string,
|
||||
tick: number): Promise<void> {
|
||||
tick: number): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
(async () => {
|
||||
@ -92,30 +92,29 @@ export function testInitialize (
|
||||
});
|
||||
|
||||
// Pool initialize.
|
||||
const transaction: ContractTransaction = await pool.initialize(BigNumber.from(sqrtPrice));
|
||||
await transaction.wait();
|
||||
await initializePool(pool, sqrtPrice);
|
||||
})();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function checkEventCommonValues (value: any, expectedContract: string) {
|
||||
const checkEventCommonValues = (value: any, expectedContract: string) => {
|
||||
expect(value.block).to.not.be.empty;
|
||||
expect(value.tx).to.not.be.empty;
|
||||
expect(value.contract).to.equal(expectedContract);
|
||||
expect(value.eventIndex).to.be.a('number');
|
||||
|
||||
expect(value.proof).to.not.be.empty;
|
||||
}
|
||||
};
|
||||
|
||||
export function checkPoolCreatedEvent (
|
||||
export const checkPoolCreatedEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
token0Address: string,
|
||||
token1Address: string,
|
||||
fee: number): string {
|
||||
fee: number): string => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('PoolCreatedEvent');
|
||||
@ -126,28 +125,28 @@ export function checkPoolCreatedEvent (
|
||||
expect(value.event.pool).to.not.be.empty;
|
||||
|
||||
return value.event.pool;
|
||||
}
|
||||
};
|
||||
|
||||
export function checkInitializeEvent (
|
||||
export const checkInitializeEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
sqrtPrice: string,
|
||||
tick: number): void {
|
||||
tick: number): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('InitializeEvent');
|
||||
expect(value.event.sqrtPriceX96).to.equal(sqrtPrice);
|
||||
expect(value.event.tick).to.equal(tick.toString());
|
||||
}
|
||||
};
|
||||
|
||||
export function checkMintEvent (
|
||||
export const checkMintEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
expectedSender: string,
|
||||
exptectedOwner: string,
|
||||
tickLower: number,
|
||||
tickUpper: number,
|
||||
amount: number): void {
|
||||
amount: number): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('MintEvent');
|
||||
@ -158,15 +157,15 @@ export function checkMintEvent (
|
||||
expect(value.event.amount).to.equal(amount.toString());
|
||||
expect(value.event.amount0).to.not.be.empty;
|
||||
expect(value.event.amount1).to.not.be.empty;
|
||||
}
|
||||
};
|
||||
|
||||
export function checkBurnEvent (
|
||||
export const checkBurnEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
exptectedOwner: string,
|
||||
tickLower: number,
|
||||
tickUpper: number,
|
||||
amount: number): void {
|
||||
amount: number): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('BurnEvent');
|
||||
@ -176,16 +175,16 @@ export function checkBurnEvent (
|
||||
expect(value.event.amount).to.equal(amount.toString());
|
||||
expect(value.event.amount0).to.not.be.empty;
|
||||
expect(value.event.amount1).to.not.be.empty;
|
||||
}
|
||||
};
|
||||
|
||||
export function checkSwapEvent (
|
||||
export const checkSwapEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
expectedSender: string,
|
||||
recipient: string,
|
||||
sqrtPrice: string,
|
||||
tick: number
|
||||
): void {
|
||||
): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('SwapEvent');
|
||||
@ -196,40 +195,40 @@ export function checkSwapEvent (
|
||||
expect(value.event.sqrtPriceX96).to.equal(sqrtPrice);
|
||||
expect(value.event.liquidity).to.not.be.empty;
|
||||
expect(value.event.tick).to.equal(tick.toString());
|
||||
}
|
||||
};
|
||||
|
||||
export function checkTransferEvent (
|
||||
export const checkTransferEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
from: string,
|
||||
recipient: string
|
||||
): void {
|
||||
): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('TransferEvent');
|
||||
expect(value.event.from).to.equal(from);
|
||||
expect(value.event.to).to.equal(recipient);
|
||||
expect(value.event.tokenId).to.equal('1');
|
||||
}
|
||||
};
|
||||
|
||||
export function checkIncreaseLiquidityEvent (
|
||||
export const checkIncreaseLiquidityEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
amount1Desired: number
|
||||
): void {
|
||||
): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.tokenId).to.equal('1');
|
||||
expect(value.event.liquidity).to.equal(amount1Desired.toString());
|
||||
expect(value.event.amount0).to.equal(amount1Desired.toString());
|
||||
expect(value.event.amount1).to.equal(amount1Desired.toString());
|
||||
}
|
||||
};
|
||||
|
||||
export function checkDecreaseLiquidityEvent (
|
||||
export const checkDecreaseLiquidityEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
liquidity: number
|
||||
): void {
|
||||
): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('DecreaseLiquidityEvent');
|
||||
@ -237,13 +236,13 @@ export function checkDecreaseLiquidityEvent (
|
||||
expect(value.event.liquidity).to.equal(liquidity.toString());
|
||||
expect(value.event.amount0).to.not.be.empty;
|
||||
expect(value.event.amount1).to.not.be.empty;
|
||||
}
|
||||
};
|
||||
|
||||
export function checksCollectEvent (
|
||||
export const checksCollectEvent = (
|
||||
value: any,
|
||||
expectedContract: string,
|
||||
recipient: string
|
||||
): void {
|
||||
): void => {
|
||||
checkEventCommonValues(value, expectedContract);
|
||||
|
||||
expect(value.event.__typename).to.equal('CollectEvent');
|
||||
@ -251,4 +250,4 @@ export function checksCollectEvent (
|
||||
expect(value.event.recipient).to.equal(recipient);
|
||||
expect(value.event.amount0).to.not.be.empty;
|
||||
expect(value.event.amount1).to.not.be.empty;
|
||||
}
|
||||
};
|
||||
|
10
packages/util/.gitignore
vendored
Normal file
10
packages/util/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
node_modules/
|
||||
build/
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
#Hardhat files
|
||||
cache
|
||||
artifacts
|
18
packages/util/hardhat.config.ts
Normal file
18
packages/util/hardhat.config.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { HardhatUserConfig } from 'hardhat/config';
|
||||
import '@nomiclabs/hardhat-waffle';
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
defaultNetwork: 'localhost',
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: '0.7.6'
|
||||
}
|
||||
]
|
||||
},
|
||||
paths: {
|
||||
sources: './test/contracts'
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
@ -3,3 +3,4 @@ export * from './src/database';
|
||||
export * from './src/job-queue';
|
||||
export * from './src/constants';
|
||||
export * from './src/index';
|
||||
export * from './test/actions';
|
||||
|
@ -12,10 +12,10 @@
|
||||
"toml": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vulcanize/cache": "^0.1.0",
|
||||
"@types/fs-extra": "^9.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
||||
"@typescript-eslint/parser": "^4.25.0",
|
||||
"@vulcanize/cache": "^0.1.0",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-config-semistandard": "^15.0.1",
|
||||
@ -24,11 +24,13 @@
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"hardhat": "^2.3.0",
|
||||
"mocha": "^8.4.0",
|
||||
"typeorm": "^0.2.32"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"build": "tsc"
|
||||
"build": "tsc",
|
||||
"test:compile": "hardhat compile"
|
||||
}
|
||||
}
|
||||
|
34
packages/util/test/actions.ts
Normal file
34
packages/util/test/actions.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { ethers, Contract, ContractTransaction, Signer, BigNumber } from 'ethers';
|
||||
|
||||
import {
|
||||
abi as TESTERC20_ABI,
|
||||
bytecode as TESTERC20_BYTECODE
|
||||
} from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json';
|
||||
|
||||
export { abi as TESTERC20_ABI } from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json';
|
||||
|
||||
export const deployTokens = async (signer: Signer): Promise<{token0Address: string, token1Address: string}> => {
|
||||
const Token = new ethers.ContractFactory(TESTERC20_ABI, TESTERC20_BYTECODE, signer);
|
||||
|
||||
const token0 = await Token.deploy(ethers.BigNumber.from(2).pow(255));
|
||||
const token0Address = token0.address;
|
||||
|
||||
const token1 = await Token.deploy(ethers.BigNumber.from(2).pow(255));
|
||||
const token1Address = token1.address;
|
||||
|
||||
return { token0Address, token1Address };
|
||||
};
|
||||
|
||||
export const createPool = async (
|
||||
factory: Contract,
|
||||
token0Address: string,
|
||||
token1Address: string,
|
||||
fee: number): Promise<void> => {
|
||||
const transaction: ContractTransaction = await factory.createPool(token0Address, token1Address, fee);
|
||||
await transaction.wait();
|
||||
};
|
||||
|
||||
export const initializePool = async (pool: Contract, sqrtPrice: string): Promise<void> => {
|
||||
const transaction: ContractTransaction = await pool.initialize(BigNumber.from(sqrtPrice));
|
||||
await transaction.wait();
|
||||
};
|
@ -72,6 +72,6 @@
|
||||
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
|
||||
"resolveJsonModule": true /* Enabling the option allows importing JSON, and validating the types in that JSON file. */
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["src", "test"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user