Skip to content

Commit

Permalink
Merge pull request paraswap#99 from paraswap/feature/platypus
Browse files Browse the repository at this point in the history
Feature: Platypus integration
  • Loading branch information
ColonelJ authored Apr 28, 2022
2 parents 8940e4b + 743c15a commit 72625df
Show file tree
Hide file tree
Showing 31 changed files with 3,364 additions and 63 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ build/
yarn-error.log
.env
tests/logs.json
tests/states.json
tests/states.json
tests/configs.json
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ yarn-error.log
.env
tests/logs.json
tests/states.json
tests/configs.json
22 changes: 11 additions & 11 deletions dex-template/__DexName__-e2e.test.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,26 @@ import { StaticJsonRpcProvider } from '@ethersproject/providers';
- Token -> ETH swap
- Token -> Token swap

The template already enumerates the basic structure which involves
The template already enumerates the basic structure which involves
testing simpleSwap, multiSwap, megaSwap contract methods for
ETH <> TOKEN and TOKEN <> TOKEN swaps. You should replace tokenA and
ETH <> TOKEN and TOKEN <> TOKEN swaps. You should replace tokenA and
tokenB with any two highly liquid tokens on __DexName__ for the tests
to work. If the tokens that you would like to use are not defined in
to work. If the tokens that you would like to use are not defined in
Tokens or Holders map, you can update the './tests/constants-e2e'

Other than the standard cases that are already added by the template
it is highly recommended to add test cases which could be specific
to testing __DexName__ (Eg. Tests based on poolType, special tokens,
etc).
Other than the standard cases that are already added by the template
it is highly recommended to add test cases which could be specific
to testing __DexName__ (Eg. Tests based on poolType, special tokens,
etc).

You can run this individual test script by running:
`npx jest src/dex/<dex-name>/<dex-name>-e2e.test.ts`

e2e tests use the Tenderly fork api. Please add the following to your
e2e tests use the Tenderly fork api. Please add the following to your
.env file:
TENDERLY_TOKEN=Find this under Account>Settings>Authorization.
TENDERLY_ACCOUNT_ID=Your Tenderly account name.
TENDERLY_PROJECT=Name of a Tenderly project you have created in your
TENDERLY_PROJECT=Name of a Tenderly project you have created in your
dashboard.

(This comment should be removed from the final implementation)
Expand All @@ -70,15 +70,15 @@ describe('__DexName__ E2E', () => {

// TODO: Add any direct swap contractMethod name if it exists
// TODO: If buy is not supported remove the buy contract methods

const sideToContractMethods = new Map([
[SwapSide.SELL, [
ContractMethod.simpleSwap,
ContractMethod.multiSwap,
ContractMethod.megaSwap,
]],
[SwapSide.BUY, [
ContractMethod.simpleBuy,
ContractMethod.simpleBuy,
ContractMethod.buy
]],
]);
Expand Down
31 changes: 15 additions & 16 deletions dex-template/__DexName__-events.test.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,33 @@ import { Network } from '../../constants';
import { DummyDexHelper } from '../../dex-helper/index';
import { testEventSubscriber } from '../../../tests/utils-events';
import { PoolState } from './types';
import axios from 'axios';

/*
README
======

This test script adds unit tests for __DexName__ event based
system. This is done by fetching the state on-chain before the
event block, manually pushing the block logs to the event-subsriber,
comparing the local state with on-chain state.
This test script adds unit tests for __DexName__ event based
system. This is done by fetching the state on-chain before the
event block, manually pushing the block logs to the event-subsriber,
comparing the local state with on-chain state.

Most of the logic for testing is abstracted by `testEventSubscriber`.
You need to do two things to make the tests work:
You need to do two things to make the tests work:

1. Fetch the block numbers where certain events were released. You
can modify the `./scripts/fetch-event-blocknumber.ts` to get the
can modify the `./scripts/fetch-event-blocknumber.ts` to get the
blocknumbers for different events. Make sure to get sufficient
number of blockNumbers to cover all possible cases for the event
mutations.
mutations.

2. Complete the implementation for fetchPoolState function. The
function should fetch the on-chain state of the event subscriber
using just the blocknumber.
2. Complete the implementation for fetchPoolState function. The
function should fetch the on-chain state of the event subscriber
using just the blocknumber.

The template tests only include the test for a single event
subscriber. There can be cases where multiple event subscribers
exist for a single DEX. In such cases additional tests should be
added.
The template tests only include the test for a single event
subscriber. There can be cases where multiple event subscribers
exist for a single DEX. In such cases additional tests should be
added.

You can run this individual test script by running:
`npx jest src/dex/<dex-name>/<dex-name>-events.test.ts`
Expand Down
36 changes: 18 additions & 18 deletions dex-template/__DexName__.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export class __DexName__EventPool extends StatefulEventSubscriber<PoolState> {
}

/**
* The function is called everytime any of the subscribed
* The function is called everytime any of the subscribed
* addresses release log. The function accepts the current
* state, updates the state according to the log, and returns
* the updated state.
* the updated state.
* @param state - Current state of event subscriber
* @param log - Log released by one of the subscribed addresses
* @returns Updates state of the event subscriber after the log
Expand Down Expand Up @@ -87,9 +87,9 @@ export class __DexName__EventPool extends StatefulEventSubscriber<PoolState> {

/**
* The function generates state using on-chain calls. This
* function is called to regenrate state if the event based
* system fails to fetch events and the local state is no
* more correct.
* function is called to regenrate state if the event based
* system fails to fetch events and the local state is no
* more correct.
* @param blockNumber - Blocknumber for which the state should
* should be generated
* @returns state of the event subsriber at blocknumber
Expand Down Expand Up @@ -129,9 +129,9 @@ export class __DexName__
);
}

// Initialize pricing is called once in the start of
// Initialize pricing is called once in the start of
// pricing service. It is intended to setup the integration
// for pricing requests. It is optional for a DEX to
// for pricing requests. It is optional for a DEX to
// implement this function
async initializePricing(blockNumber: number) {
// TODO: complete me!
Expand All @@ -143,10 +143,10 @@ export class __DexName__
return this.adapters[side];
}

// Returns list of pool identifiers that can be used
// Returns list of pool identifiers that can be used
// for a given swap. poolIdentifers must be unique
// across DEXes. It is recommended to use
// ${dexKey}_${poolAddress} as a poolIdentifier
// across DEXes. It is recommended to use
// ${dexKey}_${poolAddress} as a poolIdentifier
async getPoolIdentifiers(
srcToken: Token,
destToken: Token,
Expand All @@ -159,7 +159,7 @@ export class __DexName__
// Returns pool prices for amounts.
// If limitPools is defined only pools in limitPools
// should be used. If limitPools is undefined then
// any pools can be used.
// any pools can be used.
async getPricesVolume(
srcToken: Token,
destToken: Token,
Expand Down Expand Up @@ -187,7 +187,7 @@ export class __DexName__

// Encode call data used by simpleSwap like routers
// Used for simpleSwap & simpleBuy
// Hint: this.buildSimpleParamWithoutWETHConversion
// Hint: this.buildSimpleParamWithoutWETHConversion
// could be useful
async getSimpleParam(
srcToken: string,
Expand All @@ -200,17 +200,17 @@ export class __DexName__
// TODO: complete me!
}

// This is called once before getTopPoolsForToken is
// called for multiple tokens. This can be helpful to
// update common state required for calculating
// getTopPoolsForToken. It is optional for a DEX
// This is called once before getTopPoolsForToken is
// called for multiple tokens. This can be helpful to
// update common state required for calculating
// getTopPoolsForToken. It is optional for a DEX
// to implement this
updatePoolState(): Promise<void> {
async updatePoolState(): Promise<void> {
// TODO: complete me!
}

// Returns list of top pools based on liquidity. Max
// limit number pools should be returned.
// limit number pools should be returned.
async getTopPoolsForToken(
tokenAddress: Address,
limit: number,
Expand Down
2 changes: 1 addition & 1 deletion dex-template/config.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ export const __DexName__Config: DexConfigMap<DexParams> = {
export const Adapters: {
[chainId: number]: { [side: string]: { name: string; index: number }[] | null };
} = {
// TODO: add adapters for each chain
// TODO: add adapters for each chain
};
10 changes: 5 additions & 5 deletions dex-template/types.ts.template
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { Address } from '../../types';

export type PoolState = {
// TODO: poolState is the state of event
// TODO: poolState is the state of event
// subsrciber. This should be the minimum
// set of parameters required to compute
// set of parameters required to compute
// pool prices. Complete me!
};

export type __DexName__Data = {
// TODO: __DexName__Data is the dex data that is
// returned by the API that can be used for
// returned by the API that can be used for
// tx building. The data structure should be minimal.
// Complete me!
};

export type DexParams = {
// TODO: DexParams is set of parameters the can
// be used to initiate a DEX fork.
// Complete me!
// be used to initiate a DEX fork.
// Complete me!
}
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ module.exports = {
'/src/dex/.*\\.(test|spec)\\.(ts)$',
],
moduleFileExtensions: ['ts', 'js', 'json', 'node'],
testTImeout: 30 * 1000,
testTimeout: 30 * 1000,
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@paraswap/dex-lib",
"version": "2.0.22",
"version": "2.0.24",
"main": "build/index.js",
"types": "build/index.d.ts",
"repository": "https://github.com/paraswap/paraswap-dex-lib",
Expand Down Expand Up @@ -40,6 +40,7 @@
"@ethersproject/abi": "5.4.0",
"@ethersproject/contracts": "5.4.1",
"@ethersproject/providers": "5.4.1",
"lens.ts": "^0.5.1",
"lodash": "4.17.21",
"log4js": "6.3.0",
"paraswap": "5.1.0",
Expand Down
15 changes: 11 additions & 4 deletions scripts/fetch-event-blocknumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ dotenv.config();

import { Contract } from '@ethersproject/contracts';
import { StaticJsonRpcProvider, Provider } from '@ethersproject/providers';
import VaultABI from '../src/abi/balancer-v2/vault.json';
import ABI from '../src/abi/balancer-v2/vault.json';
import { ProviderURL, Network } from '../src/constants';
import { Address } from '../src/types';

Expand All @@ -13,15 +13,22 @@ async function getBlockNumbersForEvents(
contractAddress: Address,
contractABI: any,
eventNames: string[],
blocksBack: number,
blocksToCheck: number,
provider: Provider,
) {
const blockNumber = await provider.getBlockNumber();
const blockNumber = (await provider.getBlockNumber()) - blocksBack;
const contract = new Contract(contractAddress, contractABI, provider);
for (let eventName of eventNames) {
console.log(
eventName,
'topic',
contract.interface.getEventTopic(eventName),
);
const logs = await contract.queryFilter(
contract.filters[eventName](),
blockNumber - blocksToCheck,
blockNumber,
);
console.log(
eventName,
Expand All @@ -32,7 +39,7 @@ async function getBlockNumbersForEvents(

const network = Network.MAINNET;
const eventNames = ['Swap', 'PoolBalanceChanged'];
const vaultAddress = '0xBA12222222228d8Ba445958a75a0704d566BF2C8';
const address = '0xBA12222222228d8Ba445958a75a0704d566BF2C8';
const provider = new StaticJsonRpcProvider(ProviderURL[network], network);

getBlockNumbersForEvents(vaultAddress, VaultABI, eventNames, 3000, provider);
getBlockNumbersForEvents(address, ABI, eventNames, 0, 2000, provider);
Loading

0 comments on commit 72625df

Please sign in to comment.