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:
Ashwin Phatak 2021-08-04 18:57:44 +05:30 committed by GitHub
parent 73e0475dfa
commit a9d411c6df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 395 additions and 63 deletions

View File

@ -23,5 +23,13 @@
"allowArgumentsExplicitlyTypedAsAny": true "allowArgumentsExplicitlyTypedAsAny": true
} }
] ]
},
"overrides": [
{
"files": ["*.test.ts"],
"rules": {
"no-unused-expressions": "off"
} }
} }
]
}

View 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'

View File

@ -22,7 +22,8 @@
"lint": "eslint .", "lint": "eslint .",
"build": "tsc", "build": "tsc",
"generate:schema": "get-graphql-schema https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-alt > docs/analysis/schema/full-schema.graphql", "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": { "devDependencies": {
"@types/chance": "^1.1.2", "@types/chance": "^1.1.2",
@ -41,6 +42,8 @@
"get-graphql-schema": "^2.1.2", "get-graphql-schema": "^2.1.2",
"graphql-schema-linter": "^2.0.1", "graphql-schema-linter": "^2.0.1",
"mocha": "^8.4.0", "mocha": "^8.4.0",
"nodemon": "^2.0.7" "nodemon": "^2.0.7",
"ts-node": "^10.0.0",
"typescript": "^4.3.2"
} }
} }

View 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);
});
});
});

View 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
}
}`;

View File

@ -1 +1,2 @@
export * from './src/client'; export * from './src/client';
export * from './src/utils/index';

View File

@ -1,9 +1,8 @@
import { expect, assert } from 'chai'; import { expect, assert } from 'chai';
import { ethers, Contract, ContractTransaction, Signer, constants } from 'ethers'; import { ethers, Contract, ContractTransaction, Signer, constants } from 'ethers';
import 'reflect-metadata';
import 'mocha'; 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 { Client as UniClient } from '@vulcanize/uni-watcher';
import { getCache } from '@vulcanize/cache'; import { getCache } from '@vulcanize/cache';
import { EthClient } from '@vulcanize/ipld-eth-client'; import { EthClient } from '@vulcanize/ipld-eth-client';
@ -43,10 +42,6 @@ import {
checkDecreaseLiquidityEvent, checkDecreaseLiquidityEvent,
checksCollectEvent checksCollectEvent
} from '../test/utils'; } from '../test/utils';
import {
abi as TESTERC20_ABI,
bytecode as TESTERC20_BYTECODE
} from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json';
import { import {
abi as TESTUNISWAPV3CALLEE_ABI, abi as TESTUNISWAPV3CALLEE_ABI,
bytecode as TESTUNISWAPV3CALLEE_BYTECODE bytecode as TESTUNISWAPV3CALLEE_BYTECODE
@ -56,6 +51,8 @@ import {
bytecode as WETH9_BYTECODE bytecode as WETH9_BYTECODE
} from '../artifacts/test/contracts/WETH9.sol/WETH9.json'; } from '../artifacts/test/contracts/WETH9.sol/WETH9.json';
const NETWORK_RPC_URL = 'http://localhost:8545';
const TICK_MIN = -887272; const TICK_MIN = -887272;
const TICK_MAX = 887272; const TICK_MAX = 887272;
const getMinTick = (tickSpacing: number) => Math.ceil(TICK_MIN / tickSpacing) * tickSpacing; const getMinTick = (tickSpacing: number) => Math.ceil(TICK_MIN / tickSpacing) * tickSpacing;
@ -119,7 +116,7 @@ describe('uni-watcher', () => {
gqlSubscriptionEndpoint gqlSubscriptionEndpoint
}); });
const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545'); const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL);
signer = provider.getSigner(); signer = provider.getSigner();
recipient = await signer.getAddress(); recipient = await signer.getAddress();
}); });
@ -147,15 +144,10 @@ describe('uni-watcher', () => {
it('should deploy 2 tokens', async () => { it('should deploy 2 tokens', async () => {
// Deploy 2 tokens. // 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. // 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, token1Address } = await deployTokens(signer));
token0Address = token0.address;
expect(token0Address).to.not.be.empty; 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; expect(token1Address).to.not.be.empty;
}); });

View File

@ -1,6 +1,7 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { Database } from '../database'; import { Database } from '../database';
import { Client as UniClient } from '../client';
export async function watchContract (db: Database, address: string, kind: string, startingBlock: number): Promise<void> { 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). // 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); 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);
}
})();
});
};

View File

@ -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 { expect } from 'chai';
import 'mocha'; import 'mocha';
import { Client as UniClient } from '@vulcanize/uni-watcher'; import { Client as UniClient } from '@vulcanize/uni-watcher';
import { createPool, initializePool } from '@vulcanize/util';
// https://github.com/ethers-io/ethers.js/issues/195 // https://github.com/ethers-io/ethers.js/issues/195
export function linkLibraries ( export const linkLibraries = (
{ {
bytecode, bytecode,
linkReferences linkReferences
@ -13,7 +14,7 @@ export function linkLibraries (
bytecode: string bytecode: string
linkReferences: { [fileName: string]: { [contractName: string]: { length: number; start: number }[] } } 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).forEach((fileName) => {
Object.keys(linkReferences[fileName]).forEach((contractName) => { Object.keys(linkReferences[fileName]).forEach((contractName) => {
if (!libraries.hasOwnProperty(contractName)) { if (!libraries.hasOwnProperty(contractName)) {
@ -31,16 +32,16 @@ export function linkLibraries (
}); });
}); });
return bytecode; return bytecode;
} };
export async function testCreatePool ( export const testCreatePool = async (
uniClient: UniClient, uniClient: UniClient,
factory: Contract, factory: Contract,
token0Address: string, token0Address: string,
token1Address: string, token1Address: string,
fee: number, fee: number,
poolAbi: any, poolAbi: any,
signer: Signer): Promise<Contract> { signer: Signer): Promise<Contract> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
(async () => { (async () => {
try { try {
@ -60,20 +61,19 @@ export async function testCreatePool (
}); });
// Create pool. // Create pool.
const transaction: ContractTransaction = await factory.createPool(token0Address, token1Address, fee); await createPool(factory, token0Address, token1Address, fee);
await transaction.wait();
} catch (error) { } catch (error) {
reject(error); reject(error);
} }
})(); })();
}); });
} };
export function testInitialize ( export const testInitialize = async (
uniClient: UniClient, uniClient: UniClient,
pool: Contract, pool: Contract,
sqrtPrice: string, sqrtPrice: string,
tick: number): Promise<void> { tick: number): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
(async () => { (async () => {
@ -92,30 +92,29 @@ export function testInitialize (
}); });
// Pool initialize. // Pool initialize.
const transaction: ContractTransaction = await pool.initialize(BigNumber.from(sqrtPrice)); await initializePool(pool, sqrtPrice);
await transaction.wait();
})(); })();
} catch (error) { } catch (error) {
reject(error); reject(error);
} }
}); });
} };
function checkEventCommonValues (value: any, expectedContract: string) { const checkEventCommonValues = (value: any, expectedContract: string) => {
expect(value.block).to.not.be.empty; expect(value.block).to.not.be.empty;
expect(value.tx).to.not.be.empty; expect(value.tx).to.not.be.empty;
expect(value.contract).to.equal(expectedContract); expect(value.contract).to.equal(expectedContract);
expect(value.eventIndex).to.be.a('number'); expect(value.eventIndex).to.be.a('number');
expect(value.proof).to.not.be.empty; expect(value.proof).to.not.be.empty;
} };
export function checkPoolCreatedEvent ( export const checkPoolCreatedEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
token0Address: string, token0Address: string,
token1Address: string, token1Address: string,
fee: number): string { fee: number): string => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('PoolCreatedEvent'); expect(value.event.__typename).to.equal('PoolCreatedEvent');
@ -126,28 +125,28 @@ export function checkPoolCreatedEvent (
expect(value.event.pool).to.not.be.empty; expect(value.event.pool).to.not.be.empty;
return value.event.pool; return value.event.pool;
} };
export function checkInitializeEvent ( export const checkInitializeEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
sqrtPrice: string, sqrtPrice: string,
tick: number): void { tick: number): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('InitializeEvent'); expect(value.event.__typename).to.equal('InitializeEvent');
expect(value.event.sqrtPriceX96).to.equal(sqrtPrice); expect(value.event.sqrtPriceX96).to.equal(sqrtPrice);
expect(value.event.tick).to.equal(tick.toString()); expect(value.event.tick).to.equal(tick.toString());
} };
export function checkMintEvent ( export const checkMintEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
expectedSender: string, expectedSender: string,
exptectedOwner: string, exptectedOwner: string,
tickLower: number, tickLower: number,
tickUpper: number, tickUpper: number,
amount: number): void { amount: number): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('MintEvent'); 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.amount).to.equal(amount.toString());
expect(value.event.amount0).to.not.be.empty; expect(value.event.amount0).to.not.be.empty;
expect(value.event.amount1).to.not.be.empty; expect(value.event.amount1).to.not.be.empty;
} };
export function checkBurnEvent ( export const checkBurnEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
exptectedOwner: string, exptectedOwner: string,
tickLower: number, tickLower: number,
tickUpper: number, tickUpper: number,
amount: number): void { amount: number): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('BurnEvent'); 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.amount).to.equal(amount.toString());
expect(value.event.amount0).to.not.be.empty; expect(value.event.amount0).to.not.be.empty;
expect(value.event.amount1).to.not.be.empty; expect(value.event.amount1).to.not.be.empty;
} };
export function checkSwapEvent ( export const checkSwapEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
expectedSender: string, expectedSender: string,
recipient: string, recipient: string,
sqrtPrice: string, sqrtPrice: string,
tick: number tick: number
): void { ): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('SwapEvent'); expect(value.event.__typename).to.equal('SwapEvent');
@ -196,40 +195,40 @@ export function checkSwapEvent (
expect(value.event.sqrtPriceX96).to.equal(sqrtPrice); expect(value.event.sqrtPriceX96).to.equal(sqrtPrice);
expect(value.event.liquidity).to.not.be.empty; expect(value.event.liquidity).to.not.be.empty;
expect(value.event.tick).to.equal(tick.toString()); expect(value.event.tick).to.equal(tick.toString());
} };
export function checkTransferEvent ( export const checkTransferEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
from: string, from: string,
recipient: string recipient: string
): void { ): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('TransferEvent'); expect(value.event.__typename).to.equal('TransferEvent');
expect(value.event.from).to.equal(from); expect(value.event.from).to.equal(from);
expect(value.event.to).to.equal(recipient); expect(value.event.to).to.equal(recipient);
expect(value.event.tokenId).to.equal('1'); expect(value.event.tokenId).to.equal('1');
} };
export function checkIncreaseLiquidityEvent ( export const checkIncreaseLiquidityEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
amount1Desired: number amount1Desired: number
): void { ): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.tokenId).to.equal('1'); expect(value.event.tokenId).to.equal('1');
expect(value.event.liquidity).to.equal(amount1Desired.toString()); expect(value.event.liquidity).to.equal(amount1Desired.toString());
expect(value.event.amount0).to.equal(amount1Desired.toString()); expect(value.event.amount0).to.equal(amount1Desired.toString());
expect(value.event.amount1).to.equal(amount1Desired.toString()); expect(value.event.amount1).to.equal(amount1Desired.toString());
} };
export function checkDecreaseLiquidityEvent ( export const checkDecreaseLiquidityEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
liquidity: number liquidity: number
): void { ): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('DecreaseLiquidityEvent'); 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.liquidity).to.equal(liquidity.toString());
expect(value.event.amount0).to.not.be.empty; expect(value.event.amount0).to.not.be.empty;
expect(value.event.amount1).to.not.be.empty; expect(value.event.amount1).to.not.be.empty;
} };
export function checksCollectEvent ( export const checksCollectEvent = (
value: any, value: any,
expectedContract: string, expectedContract: string,
recipient: string recipient: string
): void { ): void => {
checkEventCommonValues(value, expectedContract); checkEventCommonValues(value, expectedContract);
expect(value.event.__typename).to.equal('CollectEvent'); expect(value.event.__typename).to.equal('CollectEvent');
@ -251,4 +250,4 @@ export function checksCollectEvent (
expect(value.event.recipient).to.equal(recipient); expect(value.event.recipient).to.equal(recipient);
expect(value.event.amount0).to.not.be.empty; expect(value.event.amount0).to.not.be.empty;
expect(value.event.amount1).to.not.be.empty; expect(value.event.amount1).to.not.be.empty;
} };

10
packages/util/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
.idea/
.vscode/
node_modules/
build/
tmp/
temp/
#Hardhat files
cache
artifacts

View 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;

View File

@ -3,3 +3,4 @@ export * from './src/database';
export * from './src/job-queue'; export * from './src/job-queue';
export * from './src/constants'; export * from './src/constants';
export * from './src/index'; export * from './src/index';
export * from './test/actions';

View File

@ -12,10 +12,10 @@
"toml": "^3.0.0" "toml": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@vulcanize/cache": "^0.1.0",
"@types/fs-extra": "^9.0.11", "@types/fs-extra": "^9.0.11",
"@typescript-eslint/eslint-plugin": "^4.25.0", "@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0", "@typescript-eslint/parser": "^4.25.0",
"@vulcanize/cache": "^0.1.0",
"chai": "^4.3.4", "chai": "^4.3.4",
"eslint": "^7.27.0", "eslint": "^7.27.0",
"eslint-config-semistandard": "^15.0.1", "eslint-config-semistandard": "^15.0.1",
@ -24,11 +24,13 @@
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0", "eslint-plugin-promise": "^5.1.0",
"eslint-plugin-standard": "^5.0.0", "eslint-plugin-standard": "^5.0.0",
"hardhat": "^2.3.0",
"mocha": "^8.4.0", "mocha": "^8.4.0",
"typeorm": "^0.2.32" "typeorm": "^0.2.32"
}, },
"scripts": { "scripts": {
"lint": "eslint .", "lint": "eslint .",
"build": "tsc" "build": "tsc",
"test:compile": "hardhat compile"
} }
} }

View 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();
};

View File

@ -72,6 +72,6 @@
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ "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. */ "resolveJsonModule": true /* Enabling the option allows importing JSON, and validating the types in that JSON file. */
}, },
"include": ["src"], "include": ["src", "test"],
"exclude": ["dist"] "exclude": ["dist"]
} }