Skip to content

Commit

Permalink
test: test coverage for @nftx/core
Browse files Browse the repository at this point in the history
  • Loading branch information
jackmellis committed Jan 9, 2024
1 parent 3d1b88f commit ec23c33
Show file tree
Hide file tree
Showing 6 changed files with 774 additions and 80 deletions.
115 changes: 115 additions & 0 deletions packages/core/src/univ3-helpers/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import Decimal from 'decimal.js';
import {
bigintToDecimal,
bigintToJsbi,
calculatePriceFromTick,
decimalToBigint,
decimalToEthers,
ethersToDecimal,
getNearestValidTick,
getSqrtRatioAtTick,
getSqrtRatioX96,
getTickAtSqrtRatio,
sqrtX96,
} from '..';
import { FeeTier, WeiPerEther, feeTierToTickSpacing } from '@nftx/constants';
import JSBI from 'jsbi';
import { formatEther, parseEther } from 'viem';

describe('bigintToDecimal', () => {
it('converts a bigint to a decimal', () => {
expect(bigintToDecimal(100n)).toEqual(new Decimal(100));
});
});

describe('ethersToDecimal', () => {
it('converts a ETHER bigint to a decimal', () => {
expect(ethersToDecimal(WeiPerEther * 100n)).toEqual(new Decimal(100));
});
});

describe('decimalToEthers', () => {
it('converts a decimal to a ETHER bigint', () => {
expect(decimalToEthers(new Decimal(100))).toEqual(WeiPerEther * 100n);
});
});

describe('decimalToBigint', () => {
it('converts a decimal to a bigint', () => {
expect(decimalToBigint(new Decimal(100))).toEqual(100n);
});
});

describe('bigintToJsbi', () => {
it('converts a bigint to a JSBI', () => {
expect(bigintToJsbi(100n)).toEqual(JSBI.BigInt(100));
});
});

describe('sqrtX96', () => {
it('calculates the X96 square root', () => {
expect(formatEther(sqrtX96(WeiPerEther))).toEqual(
'79228162514264337594000000000'
);
});
});

describe('getSqrtRatioX96', () => {
it('calculates the X96 square root ratio', () => {
expect(
formatEther(getSqrtRatioX96(WeiPerEther, WeiPerEther * 20n))
).toEqual('17715955711.42957103');
});
});

describe('getTickAtSqrtRatio', () => {
it('calculates the tick at the sqrt ratio', () => {
const feetier: FeeTier = 3000;
const tickSpacing = feeTierToTickSpacing(feetier);

expect(
getTickAtSqrtRatio(
parseEther('17732633948.828052598660473723'),
tickSpacing
)
).toEqual(-29940);
});
});

describe('getSqrtRatioAtTick', () => {
it('calculates the sqrt ratio at the tick', () => {
expect(formatEther(getSqrtRatioAtTick(-29940))).toEqual(
'17732633948.828052598660473723'
);
});
});

describe('calculatePriceFromTick', () => {
it('calculates the price from the tick', () => {
expect(formatEther(calculatePriceFromTick(-29940))).toEqual(
'0.050094186778981481'
);
});
describe('when the tick is below the minimum tick', () => {
it('returns the minimum price', () => {
expect(formatEther(calculatePriceFromTick(-887220))).toEqual('0');
});
});
describe('when the tick is above the maximum tick', () => {
it('returns the maximum price', () => {
expect(formatEther(calculatePriceFromTick(887220))).toEqual(
'338492131855223783700000000000000000000'
);
});
});
});

describe('getNearestValidTick', () => {
it('returns the nearest valid tick', () => {
const feetier: FeeTier = 3000;
const tickSpacing = feeTierToTickSpacing(feetier);
const tick = Math.floor(-29940 - tickSpacing / 3);

expect(getNearestValidTick(tick, tickSpacing)).toEqual(-29940);
});
});
261 changes: 261 additions & 0 deletions packages/core/src/vaults/__tests__/fetchVaultActivity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
import { formatJson } from '@nftx/utils';
import { makeFetchVaultActivity } from '../fetchVaultActivity';

let subgraphResponse: any;
let querySubgraph: jest.Mock;
let fetchVaultActivity: ReturnType<typeof makeFetchVaultActivity>;
let args: Parameters<typeof fetchVaultActivity>[0];
let run: () => ReturnType<typeof fetchVaultActivity>;

beforeEach(() => {
const defaultActivityEvent = {
source: 'source',
date: '1',
vault: {
id: '0x1',
vaultId: '1',
},
feeReceipt: {
transfers: [
{
amount: '1',
},
],
},
};

subgraphResponse = {
activityEvents: [
// Mint
{
...defaultActivityEvent,
id: 'MINT-0x0',
type: 'Mint',
mintIds: ['1'],
},
// Sell
{
...defaultActivityEvent,
id: 'MINT-0x0',
type: 'ZapSell',
mintIds: ['1'],
},
// Rdeem
{
...defaultActivityEvent,
id: 'REDEEM-0x0',
type: 'Redeem',
redeemIds: ['1'],
},
// Buy
{
...defaultActivityEvent,
id: 'REDEEM-0x0',
type: 'ZapBuy',
redeemIds: ['1'],
},
// Swap
{
...defaultActivityEvent,
id: 'SWAP-0x0',
type: 'Swap',
swapMintIds: ['1'],
swapRedeemIds: ['2'],
},
// LP Stake
{
...defaultActivityEvent,
id: 'DEPOSIT-0x0',
type: 'AddLiquidity',
},
// IP Stake
{
...defaultActivityEvent,
id: 'DEPOSIT-0x0',
type: 'InventoryDeposit',
},
// LP Unstake
{
...defaultActivityEvent,
id: 'WITHDRAW-0x0',
type: 'RemoveLiquidity',
},
// IP Unstake
{
...defaultActivityEvent,
id: 'WITHDRAW-0x0',
type: 'InventoryWithdraw',
},
// Created
{
...defaultActivityEvent,
id: 'VAULT_CREATED-0x0',
type: 'VaultCreated',
},
// Updated
{
...defaultActivityEvent,
id: 'VAULT_FEE_UPDATE-0x0',
type: 'VaultFeeUpdate',
},
// Shutdown
{
...defaultActivityEvent,
id: 'VAULT_SHUTDOWN-0x0',
type: 'VaultShutdown',
},
],
};
querySubgraph = jest.fn().mockResolvedValue(subgraphResponse);
fetchVaultActivity = makeFetchVaultActivity({ querySubgraph });
args = {
network: 1,
};
run = () => fetchVaultActivity(args);
});

it('returns a list of vault activity', async () => {
const result = await run();

const expected = [
{
type: 'mint',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'Mint',
source: 'source',
tokenIds: ['1'],
txId: '0x0',
feeAmount: '0',
},
{
type: 'sell',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'ZapSell',
source: 'source',
tokenIds: ['1'],
txId: '0x0',
feeAmount: '1',
},
{
type: 'redeem',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'Redeem',
source: 'source',
tokenIds: ['1'],
txId: '0x0',
feeAmount: '1',
},
{
type: 'buy',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'ZapBuy',
source: 'source',
tokenIds: ['1'],
txId: '0x0',
feeAmount: '1',
},
{
type: 'swap',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'Swap',
source: 'source',
tokenIds: ['1'],
txId: '0x0',
feeAmount: '1',
swapTokenIds: ['2'],
},
{
type: 'stake',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'AddLiquidity',
source: 'source',
txId: '0x0',
stakeType: 'liquidity',
amount: '0',
},
{
type: 'stake',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'InventoryDeposit',
source: 'source',
txId: '0x0',
stakeType: 'inventory',
amount: '0',
},
];

expect(result.length).toBe(7);
expect(formatJson(result)).toEqual(expected);
});

describe('when includeAllActivity is true', () => {
beforeEach(() => {
args.includeAllActivity = true;
});

it('returns create update and shutdown events', async () => {
const result = (await run()).slice(7);

const expected = [
{
type: 'create',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'VaultCreated',
source: 'source',
txId: '0x0',
},
{
type: 'update',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'VaultFeeUpdate',
source: 'source',
txId: '0x0',
},
{
type: 'shutdown',
vaultId: '1',
vaultAddress: '0x1',
date: 1,
eventType: 'VaultShutdown',
source: 'source',
txId: '0x0',
},
];

expect(formatJson(result)).toEqual(expected);
});
});

describe('when there are more than 1000 events', () => {
beforeEach(() => {
querySubgraph.mockResolvedValueOnce({
...subgraphResponse,
activityEvents: Array(1000).fill(subgraphResponse.activityEvents[0]),
});
});

it('recursively fetches more activity', async () => {
const result = await run();

expect(result.length).toBe(1007);
expect(querySubgraph).toHaveBeenCalledTimes(2);
});
});
Loading

0 comments on commit ec23c33

Please sign in to comment.