Skip to content

Commit

Permalink
Merge pull request #470 from paraswap/fix/1233-camelotv3-tick-bug
Browse files Browse the repository at this point in the history
BACK-1233: Fix: CamelotV3 tick calculation bug
  • Loading branch information
Verisana authored Aug 18, 2023
2 parents 3a98160 + 4722f0b commit 7581781
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 98 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@paraswap/dex-lib",
"version": "2.28.10",
"version": "2.28.11",
"main": "build/index.js",
"types": "build/index.d.ts",
"repository": "https://github.com/paraswap/paraswap-dex-lib",
Expand Down
12 changes: 11 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type BaseConfig = {
hashFlowAuthToken?: string;
hashFlowDisabledMMs: string[];
swaapV2AuthToken?: string;
forceRpcFallbackDexs: string[];
};

const baseConfigs: { [network: number]: BaseConfig } = {
Expand Down Expand Up @@ -115,6 +116,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
},
},
},
forceRpcFallbackDexs: [],
},
[Network.ROPSTEN]: {
network: Network.ROPSTEN,
Expand Down Expand Up @@ -142,6 +144,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rfqConfigs: {},
rpcPollingMaxAllowedStateDelayInBlocks: 5,
rpcPollingBlocksBackToTriggerUpdate: 3,
forceRpcFallbackDexs: [],
},
[Network.BSC]: {
network: Network.BSC,
Expand All @@ -168,6 +171,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
uniswapV2ExchangeRouterAddress:
'0x53e693c6C7FFC4446c53B205Cf513105Bf140D7b',
rfqConfigs: {},
forceRpcFallbackDexs: [],
},
[Network.POLYGON]: {
network: Network.POLYGON,
Expand Down Expand Up @@ -197,6 +201,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rpcPollingMaxAllowedStateDelayInBlocks: 2,
rpcPollingBlocksBackToTriggerUpdate: 1,
swaapV2AuthToken: process.env.API_KEY_SWAAP_V2_AUTH_TOKEN || '',
forceRpcFallbackDexs: [],
},
[Network.AVALANCHE]: {
network: Network.AVALANCHE,
Expand Down Expand Up @@ -224,6 +229,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rfqConfigs: {},
rpcPollingMaxAllowedStateDelayInBlocks: 2,
rpcPollingBlocksBackToTriggerUpdate: 1,
forceRpcFallbackDexs: [],
},
[Network.FANTOM]: {
network: Network.FANTOM,
Expand Down Expand Up @@ -251,6 +257,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rfqConfigs: {},
rpcPollingMaxAllowedStateDelayInBlocks: 2,
rpcPollingBlocksBackToTriggerUpdate: 1,
forceRpcFallbackDexs: [],
},
[Network.ARBITRUM]: {
network: Network.ARBITRUM,
Expand Down Expand Up @@ -279,6 +286,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rfqConfigs: {},
rpcPollingMaxAllowedStateDelayInBlocks: 4,
rpcPollingBlocksBackToTriggerUpdate: 3,
forceRpcFallbackDexs: [],
},
[Network.OPTIMISM]: {
network: Network.OPTIMISM,
Expand Down Expand Up @@ -307,6 +315,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
rfqConfigs: {},
rpcPollingMaxAllowedStateDelayInBlocks: 5,
rpcPollingBlocksBackToTriggerUpdate: 3,
forceRpcFallbackDexs: [],
},
};

Expand Down Expand Up @@ -350,6 +359,7 @@ export function generateConfig(network: number): Config {
hashFlowAuthToken: baseConfig.hashFlowAuthToken,
swaapV2AuthToken: baseConfig.swaapV2AuthToken,
hashFlowDisabledMMs: baseConfig.hashFlowDisabledMMs,
forceRpcFallbackDexs: baseConfig.forceRpcFallbackDexs,
};
}

Expand All @@ -359,7 +369,7 @@ export class ConfigHelper {
constructor(
public isSlave: boolean,
public data: Config,
private masterCachePrefix: string,
masterCachePrefix: string,
) {
this.masterBlockNumberCacheKey =
`${masterCachePrefix}_${data.network}_bn`.toLowerCase();
Expand Down
210 changes: 194 additions & 16 deletions src/dex/algebra/algebra-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,6 @@ import {
import { Tokens } from '../../../tests/constants-e2e';
import { Address } from '@paraswap/core';

/*
README
======
This test script adds tests for Algebra general integration
with the DEX interface. The test cases below are example tests.
It is recommended to add tests which cover Algebra specific
logic.
You can run this individual test script by running:
`npx jest src/dex/<dex-name>/<dex-name>-integration.test.ts`
(This comment should be removed from the final implementation)
*/

function getReaderCalldata(
exchangeAddress: string,
readerIface: Interface,
Expand Down Expand Up @@ -70,7 +55,7 @@ async function checkOnChainPricing(
tokenOut: Address,
amounts: bigint[],
) {
const exchangeAddress = '0xa15f0d7377b2a0c0c10db057f641bed21028fc89'; // Quoter address
const exchangeAddress = algebra.config.quoter;

const readerIface = algebra.quoterIface;

Expand Down Expand Up @@ -155,6 +140,199 @@ async function testPricingOnNetwork(
);
}

describe('CamelotV3', function () {
const dexKey = 'CamelotV3';
let blockNumber: number;
let algebra: Algebra;

describe('Arbitrum', () => {
const network = Network.ARBITRUM;
const dexHelper = new DummyDexHelper(network);

const tokens = Tokens[network];

describe('GRAIL => USDCe', () => {
const srcTokenSymbol = 'GRAIL';
const destTokenSymbol = 'USDCe';

const amountsForSell = [
0n,
10n * BI_POWS[tokens[srcTokenSymbol].decimals],
20n * BI_POWS[tokens[srcTokenSymbol].decimals],
30n * BI_POWS[tokens[srcTokenSymbol].decimals],
40n * BI_POWS[tokens[srcTokenSymbol].decimals],
50n * BI_POWS[tokens[srcTokenSymbol].decimals],
60n * BI_POWS[tokens[srcTokenSymbol].decimals],
70n * BI_POWS[tokens[srcTokenSymbol].decimals],
80n * BI_POWS[tokens[srcTokenSymbol].decimals],
90n * BI_POWS[tokens[srcTokenSymbol].decimals],
100n * BI_POWS[tokens[srcTokenSymbol].decimals],
];

const amountsForBuy = [
0n,
1n * BI_POWS[tokens[destTokenSymbol].decimals],
2n * BI_POWS[tokens[destTokenSymbol].decimals],
3n * BI_POWS[tokens[destTokenSymbol].decimals],
4n * BI_POWS[tokens[destTokenSymbol].decimals],
5n * BI_POWS[tokens[destTokenSymbol].decimals],
6n * BI_POWS[tokens[destTokenSymbol].decimals],
7n * BI_POWS[tokens[destTokenSymbol].decimals],
8n * BI_POWS[tokens[destTokenSymbol].decimals],
9n * BI_POWS[tokens[destTokenSymbol].decimals],
10n * BI_POWS[tokens[destTokenSymbol].decimals],
];

beforeAll(async () => {
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
algebra = new Algebra(network, dexKey, dexHelper);
if (algebra.initializePricing) {
await algebra.initializePricing(blockNumber);
}
});

it('getPoolIdentifiers and getPricesVolume SELL', async function () {
await testPricingOnNetwork(
algebra,
network,
dexKey,
dexHelper,
blockNumber,
srcTokenSymbol,
destTokenSymbol,
SwapSide.SELL,
amountsForSell,
'quoteExactInputSingle',
);
});

it('getPoolIdentifiers and getPricesVolume BUY', async function () {
await testPricingOnNetwork(
algebra,
network,
dexKey,
dexHelper,
blockNumber,
srcTokenSymbol,
destTokenSymbol,
SwapSide.BUY,
amountsForBuy,
'quoteExactOutputSingle',
);
});

it('getTopPoolsForToken', async function () {
// We have to check without calling initializePricing, because
// pool-tracker is not calling that function
const newAlgebra = new Algebra(network, dexKey, dexHelper);
const poolLiquidity = await newAlgebra.getTopPoolsForToken(
tokens[srcTokenSymbol].address,
10,
);
console.log(`${srcTokenSymbol} Top Pools:`, poolLiquidity);

if (!newAlgebra.hasConstantPriceLargeAmounts) {
checkPoolsLiquidity(
poolLiquidity,
Tokens[network][srcTokenSymbol].address,
dexKey,
);
}
});
});

describe('USDCe => GRAIL', () => {
const srcTokenSymbol = 'USDCe';
const destTokenSymbol = 'GRAIL';

const amountsForSell = [
0n,
10n * BI_POWS[tokens[srcTokenSymbol].decimals],
20n * BI_POWS[tokens[srcTokenSymbol].decimals],
30n * BI_POWS[tokens[srcTokenSymbol].decimals],
40n * BI_POWS[tokens[srcTokenSymbol].decimals],
50n * BI_POWS[tokens[srcTokenSymbol].decimals],
60n * BI_POWS[tokens[srcTokenSymbol].decimals],
70n * BI_POWS[tokens[srcTokenSymbol].decimals],
80n * BI_POWS[tokens[srcTokenSymbol].decimals],
90n * BI_POWS[tokens[srcTokenSymbol].decimals],
100n * BI_POWS[tokens[srcTokenSymbol].decimals],
];

const amountsForBuy = [
0n,
1n * BI_POWS[tokens[destTokenSymbol].decimals],
2n * BI_POWS[tokens[destTokenSymbol].decimals],
3n * BI_POWS[tokens[destTokenSymbol].decimals],
4n * BI_POWS[tokens[destTokenSymbol].decimals],
5n * BI_POWS[tokens[destTokenSymbol].decimals],
6n * BI_POWS[tokens[destTokenSymbol].decimals],
7n * BI_POWS[tokens[destTokenSymbol].decimals],
8n * BI_POWS[tokens[destTokenSymbol].decimals],
9n * BI_POWS[tokens[destTokenSymbol].decimals],
10n * BI_POWS[tokens[destTokenSymbol].decimals],
];

beforeAll(async () => {
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
algebra = new Algebra(network, dexKey, dexHelper);
if (algebra.initializePricing) {
await algebra.initializePricing(blockNumber);
}
});

it('getPoolIdentifiers and getPricesVolume SELL', async function () {
await testPricingOnNetwork(
algebra,
network,
dexKey,
dexHelper,
blockNumber,
srcTokenSymbol,
destTokenSymbol,
SwapSide.SELL,
amountsForSell,
'quoteExactInputSingle',
);
});

it('getPoolIdentifiers and getPricesVolume BUY', async function () {
await testPricingOnNetwork(
algebra,
network,
dexKey,
dexHelper,
blockNumber,
srcTokenSymbol,
destTokenSymbol,
SwapSide.BUY,
amountsForBuy,
'quoteExactOutputSingle',
);
});

it('getTopPoolsForToken', async function () {
// We have to check without calling initializePricing, because
// pool-tracker is not calling that function
const newAlgebra = new Algebra(network, dexKey, dexHelper);
const poolLiquidity = await newAlgebra.getTopPoolsForToken(
tokens[srcTokenSymbol].address,
10,
);
console.log(`${srcTokenSymbol} Top Pools:`, poolLiquidity);

if (!newAlgebra.hasConstantPriceLargeAmounts) {
checkPoolsLiquidity(
poolLiquidity,
Tokens[network][srcTokenSymbol].address,
dexKey,
);
}
});
});
});
});

describe('Algebra', function () {
const dexKey = 'QuickSwapV3';
let blockNumber: number;
Expand Down
6 changes: 5 additions & 1 deletion src/dex/algebra/algebra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
protected adapters = Adapters[network] || {},
readonly routerIface = new Interface(UniswapV3RouterABI), // same abi as uniswapV3
readonly quoterIface = new Interface(AlgebraQuoterABI),
protected config = AlgebraConfig[dexKey][network],
readonly config = AlgebraConfig[dexKey][network],
) {
super(dexHelper, dexKey);
this.logger = dexHelper.getLogger(dexKey + '-' + network);
Expand All @@ -104,6 +104,10 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
this.dexHelper.web3Provider.eth.handleRevert = false;

this.config = this._toLowerForAllConfigAddresses();
// External configuration has priority over internal
this.config.forceRPC = dexHelper.config.data.forceRpcFallbackDexs.includes(
dexKey.toLowerCase(),
);

this.notExistingPoolSetKey =
`${CACHE_PREFIX}_${network}_${dexKey}_not_existings_pool_set`.toLowerCase();
Expand Down
1 change: 0 additions & 1 deletion src/dex/algebra/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export const AlgebraConfig: DexConfigMap<DexParams> = {
uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984',
deployer: '0x6dd3fb9653b10e806650f107c3b5a0a6ff974f65',
version: 'v1.9',
forceRPC: true,
},
},
};
Expand Down
Loading

0 comments on commit 7581781

Please sign in to comment.