From 8062522523b1945f410950f250d03c268d20ee5e Mon Sep 17 00:00:00 2001 From: Verisana Date: Wed, 16 Aug 2023 13:18:25 +0100 Subject: [PATCH 01/12] fix: tick bitmap --- src/dex/algebra/algebra-integration.test.ts | 102 ++++++++++++++++++++ src/dex/algebra/config.ts | 2 +- src/dex/algebra/lib/TickTable.ts | 15 ++- tests/constants-e2e.ts | 8 +- 4 files changed, 118 insertions(+), 9 deletions(-) diff --git a/src/dex/algebra/algebra-integration.test.ts b/src/dex/algebra/algebra-integration.test.ts index 97017d03a..9946b7252 100644 --- a/src/dex/algebra/algebra-integration.test.ts +++ b/src/dex/algebra/algebra-integration.test.ts @@ -155,6 +155,108 @@ 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]; + + const srcTokenSymbol = 'USDCe'; + const destTokenSymbol = 'GRAIL'; + // const destTokenSymbol = 'USDC'; + + const amountsForSell = [ + 0n, + 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 20000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 100_000n * 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; diff --git a/src/dex/algebra/config.ts b/src/dex/algebra/config.ts index f8f942067..83ade331a 100644 --- a/src/dex/algebra/config.ts +++ b/src/dex/algebra/config.ts @@ -82,7 +82,7 @@ export const AlgebraConfig: DexConfigMap = { uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984', deployer: '0x6dd3fb9653b10e806650f107c3b5a0a6ff974f65', version: 'v1.9', - forceRPC: true, + forceRPC: false, }, }, }; diff --git a/src/dex/algebra/lib/TickTable.ts b/src/dex/algebra/lib/TickTable.ts index c90dd50c9..5bb8365f8 100644 --- a/src/dex/algebra/lib/TickTable.ts +++ b/src/dex/algebra/lib/TickTable.ts @@ -91,11 +91,12 @@ export class TickTable { ), ); } - const [rowNumber, bitNumber] = TickTable.position(tick); - isWordPosOut(rowNumber, state.startTickBitmap, isPriceQuery); - let tickBitmapValue = state.tickBitmap[rowNumber.toString()]; - tickBitmapValue = tickBitmapValue === undefined ? 0n : tickBitmapValue; if (lte) { + const [rowNumber, bitNumber] = TickTable.position(tick); + isWordPosOut(rowNumber, state.startTickBitmap, isPriceQuery); + let tickBitmapValue = state.tickBitmap[rowNumber.toString()]; + tickBitmapValue = tickBitmapValue === undefined ? 0n : tickBitmapValue; + const _row = tickBitmapValue << (255n - bitNumber); if (_row != 0n) { tick -= BigInt.asIntN(24, 255n - TickTable.getMostSignificantBit(_row)); @@ -106,6 +107,12 @@ export class TickTable { } } else { tick += 1n; + + const [rowNumber, bitNumber] = TickTable.position(tick); + isWordPosOut(rowNumber, state.startTickBitmap, isPriceQuery); + let tickBitmapValue = state.tickBitmap[rowNumber.toString()]; + tickBitmapValue = tickBitmapValue === undefined ? 0n : tickBitmapValue; + const _row = tickBitmapValue >> bitNumber; if (_row !== 0n) { tick += BigInt.asIntN( diff --git a/tests/constants-e2e.ts b/tests/constants-e2e.ts index 004aa98b0..cf0284848 100644 --- a/tests/constants-e2e.ts +++ b/tests/constants-e2e.ts @@ -785,14 +785,14 @@ export const Tokens: { address: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', decimals: 8, }, - USDCe: { - address: '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', - decimals: 6, - }, LEX: { address: '0x6bB7A17AcC227fd1F6781D1EEDEAE01B42047eE0', decimals: 18, }, + GRAIL: { + address: '0x3d9907f9a368ad0a51be60f7da3b97cf940982d8', + decimals: 18, + }, }, [Network.OPTIMISM]: { DAI: { From 9352c584bb75679e718217b914693ebb22520fa8 Mon Sep 17 00:00:00 2001 From: Verisana Date: Wed, 16 Aug 2023 13:19:49 +0100 Subject: [PATCH 02/12] fix: leave only one test case --- src/dex/algebra/algebra-integration.test.ts | 317 ++++++++++---------- 1 file changed, 159 insertions(+), 158 deletions(-) diff --git a/src/dex/algebra/algebra-integration.test.ts b/src/dex/algebra/algebra-integration.test.ts index 9946b7252..3a067f806 100644 --- a/src/dex/algebra/algebra-integration.test.ts +++ b/src/dex/algebra/algebra-integration.test.ts @@ -172,34 +172,35 @@ describe('CamelotV3', function () { const amountsForSell = [ 0n, - 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], 20000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 100_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 100_000n * 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], - ]; + // 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(); + // blockNumber = await dexHelper.web3Provider.eth.getBlockNumber(); + blockNumber = 121923156; algebra = new Algebra(network, dexKey, dexHelper); if (algebra.initializePricing) { await algebra.initializePricing(blockNumber); @@ -221,140 +222,140 @@ describe('CamelotV3', function () { ); }); - 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; - let algebra: Algebra; - - describe('Polygon', () => { - const network = Network.POLYGON; - const dexHelper = new DummyDexHelper(network); - - const tokens = Tokens[network]; - - const srcTokenSymbol = 'WMATIC'; - const destTokenSymbol = 'DAI'; - // const destTokenSymbol = 'USDC'; - - const amountsForSell = [ - 0n, - 1n * BI_POWS[tokens[srcTokenSymbol].decimals], - 2n * BI_POWS[tokens[srcTokenSymbol].decimals], - 3n * BI_POWS[tokens[srcTokenSymbol].decimals], - 4n * BI_POWS[tokens[srcTokenSymbol].decimals], - 5n * BI_POWS[tokens[srcTokenSymbol].decimals], - 6n * BI_POWS[tokens[srcTokenSymbol].decimals], - 7n * BI_POWS[tokens[srcTokenSymbol].decimals], - 8n * BI_POWS[tokens[srcTokenSymbol].decimals], - 9n * BI_POWS[tokens[srcTokenSymbol].decimals], - 10n * 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, - ); - } - }); + // 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; + // let algebra: Algebra; + // + // describe('Polygon', () => { + // const network = Network.POLYGON; + // const dexHelper = new DummyDexHelper(network); + // + // const tokens = Tokens[network]; + // + // const srcTokenSymbol = 'WMATIC'; + // const destTokenSymbol = 'DAI'; + // // const destTokenSymbol = 'USDC'; + // + // const amountsForSell = [ + // 0n, + // 1n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 2n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 3n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 4n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 5n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 6n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 7n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 8n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 9n * BI_POWS[tokens[srcTokenSymbol].decimals], + // 10n * 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, + // ); + // } + // }); }); }); From 12f25290f934fd8b9aae6b8ec6704fff27e3ec89 Mon Sep 17 00:00:00 2001 From: Verisana Date: Wed, 16 Aug 2023 14:51:11 +0100 Subject: [PATCH 03/12] fix: use propoer bitwise operators --- src/dex/algebra/algebra-integration.test.ts | 336 ++++++++++---------- src/dex/algebra/algebra.ts | 2 +- src/dex/algebra/lib/TickTable.ts | 113 +++---- 3 files changed, 213 insertions(+), 238 deletions(-) diff --git a/src/dex/algebra/algebra-integration.test.ts b/src/dex/algebra/algebra-integration.test.ts index 3a067f806..ede850b48 100644 --- a/src/dex/algebra/algebra-integration.test.ts +++ b/src/dex/algebra/algebra-integration.test.ts @@ -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//-integration.test.ts` - - (This comment should be removed from the final implementation) -*/ - function getReaderCalldata( exchangeAddress: string, readerIface: Interface, @@ -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; @@ -172,35 +157,34 @@ describe('CamelotV3', function () { const amountsForSell = [ 0n, - // 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 20000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 100_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 20_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], + 100_000n * 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], - // ]; + 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(); - blockNumber = 121923156; + blockNumber = await dexHelper.web3Provider.eth.getBlockNumber(); algebra = new Algebra(network, dexKey, dexHelper); if (algebra.initializePricing) { await algebra.initializePricing(blockNumber); @@ -222,140 +206,140 @@ describe('CamelotV3', function () { ); }); - // 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; - // let algebra: Algebra; - // - // describe('Polygon', () => { - // const network = Network.POLYGON; - // const dexHelper = new DummyDexHelper(network); - // - // const tokens = Tokens[network]; - // - // const srcTokenSymbol = 'WMATIC'; - // const destTokenSymbol = 'DAI'; - // // const destTokenSymbol = 'USDC'; - // - // const amountsForSell = [ - // 0n, - // 1n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 2n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 3n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 4n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 5n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 6n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 7n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 8n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 9n * BI_POWS[tokens[srcTokenSymbol].decimals], - // 10n * 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, - // ); - // } - // }); + 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; + let algebra: Algebra; + + describe('Polygon', () => { + const network = Network.POLYGON; + const dexHelper = new DummyDexHelper(network); + + const tokens = Tokens[network]; + + const srcTokenSymbol = 'WMATIC'; + const destTokenSymbol = 'DAI'; + // const destTokenSymbol = 'USDC'; + + const amountsForSell = [ + 0n, + 1n * BI_POWS[tokens[srcTokenSymbol].decimals], + 2n * BI_POWS[tokens[srcTokenSymbol].decimals], + 3n * BI_POWS[tokens[srcTokenSymbol].decimals], + 4n * BI_POWS[tokens[srcTokenSymbol].decimals], + 5n * BI_POWS[tokens[srcTokenSymbol].decimals], + 6n * BI_POWS[tokens[srcTokenSymbol].decimals], + 7n * BI_POWS[tokens[srcTokenSymbol].decimals], + 8n * BI_POWS[tokens[srcTokenSymbol].decimals], + 9n * BI_POWS[tokens[srcTokenSymbol].decimals], + 10n * 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, + ); + } + }); }); }); diff --git a/src/dex/algebra/algebra.ts b/src/dex/algebra/algebra.ts index 8814861a5..3b4ad6e55 100644 --- a/src/dex/algebra/algebra.ts +++ b/src/dex/algebra/algebra.ts @@ -88,7 +88,7 @@ export class Algebra extends SimpleExchange implements IDex { 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); diff --git a/src/dex/algebra/lib/TickTable.ts b/src/dex/algebra/lib/TickTable.ts index 5bb8365f8..afd86c816 100644 --- a/src/dex/algebra/lib/TickTable.ts +++ b/src/dex/algebra/lib/TickTable.ts @@ -130,80 +130,71 @@ export class TickTable { static getSingleSignificantBit(word: bigint): bigint { let singleBitPos = 0n; singleBitPos = Yul.iszero( - word && - BigInt( - '0x5555555555555555555555555555555555555555555555555555555555555555', - ), + word & + 0x5555555555555555555555555555555555555555555555555555555555555555n, ); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff', - ), - ) << 7n; + singleBitPos | + (Yul.iszero( + word & + 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffffn, + ) << + 7n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff', - ), - ) << 6n; + singleBitPos | + (Yul.iszero( + word & + 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffffn, + ) << + 6n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff', - ), - ) << 5n; + singleBitPos | + (Yul.iszero( + word & + 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffffn, + ) << + 5n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff', - ), - ) << 4n; + singleBitPos | + (Yul.iszero( + word & + 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffffn, + ) << + 4n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff', - ), - ) << 3n; + singleBitPos | + (Yul.iszero( + word & + 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ffn, + ) << + 3n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f', - ), - ) << 2n; + singleBitPos | + (Yul.iszero( + word & + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0fn, + ) << + 2n); singleBitPos = - singleBitPos || - Yul.iszero( - word && - BigInt( - '0x3333333333333333333333333333333333333333333333333333333333333333', - ), - ) << 1n; + singleBitPos | + (Yul.iszero( + word & + 0x3333333333333333333333333333333333333333333333333333333333333333n, + ) << + 1n); return BigInt.asUintN(8, singleBitPos); } static getMostSignificantBit(word: bigint): bigint { - word = word || word >> 1n; - word = word || word >> 2n; - word = word || word >> 4n; - word = word || word >> 8n; - word = word || word >> 16n; - word = word || word >> 32n; - word = word || word >> 64n; - word = word || word >> 128n; + word = word | (word >> 1n); + word = word | (word >> 2n); + word = word | (word >> 4n); + word = word | (word >> 8n); + word = word | (word >> 16n); + word = word | (word >> 32n); + word = word | (word >> 64n); + word = word | (word >> 128n); word = word - (word >> 1n); return TickTable.getSingleSignificantBit(BigInt.asUintN(256, word)); } From 495f4df4dab165c1b6688fe1529141d63617d469 Mon Sep 17 00:00:00 2001 From: Verisana Date: Wed, 16 Aug 2023 14:55:15 +0100 Subject: [PATCH 04/12] chore: remove commented token --- src/dex/algebra/algebra-integration.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dex/algebra/algebra-integration.test.ts b/src/dex/algebra/algebra-integration.test.ts index ede850b48..d64181c11 100644 --- a/src/dex/algebra/algebra-integration.test.ts +++ b/src/dex/algebra/algebra-integration.test.ts @@ -153,7 +153,6 @@ describe('CamelotV3', function () { const srcTokenSymbol = 'USDCe'; const destTokenSymbol = 'GRAIL'; - // const destTokenSymbol = 'USDC'; const amountsForSell = [ 0n, From 9274e31c32e8c5ba7309c19168551bac832f3d29 Mon Sep 17 00:00:00 2001 From: Verisana Date: Wed, 16 Aug 2023 14:55:56 +0100 Subject: [PATCH 05/12] 2.28.10-camelot-v3-tick-bugs.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4aa5e4e84..7f5f60c32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@paraswap/dex-lib", - "version": "2.28.9", + "version": "2.28.10-camelot-v3-tick-bugs.0", "main": "build/index.js", "types": "build/index.d.ts", "repository": "https://github.com/paraswap/paraswap-dex-lib", From 8ae8059fd04ba20495e6603d6c552da7619ef725 Mon Sep 17 00:00:00 2001 From: Verisana Date: Thu, 17 Aug 2023 12:54:51 +0100 Subject: [PATCH 06/12] fix: wrap in truncated 256 bit bigint row --- src/dex/algebra/algebra-integration.test.ts | 252 +++++++++++++------- src/dex/algebra/lib/TickTable.ts | 21 +- 2 files changed, 184 insertions(+), 89 deletions(-) diff --git a/src/dex/algebra/algebra-integration.test.ts b/src/dex/algebra/algebra-integration.test.ts index d64181c11..54c674fb7 100644 --- a/src/dex/algebra/algebra-integration.test.ts +++ b/src/dex/algebra/algebra-integration.test.ts @@ -151,92 +151,184 @@ describe('CamelotV3', function () { const tokens = Tokens[network]; - const srcTokenSymbol = 'USDCe'; - const destTokenSymbol = 'GRAIL'; - - const amountsForSell = [ - 0n, - 10_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 20_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 30_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 40_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 50_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 60_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 70_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 80_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 90_000n * BI_POWS[tokens[srcTokenSymbol].decimals], - 100_000n * 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', - ); - }); + 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('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, + ); + } + }); }); - 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); + 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', + ); + }); - if (!newAlgebra.hasConstantPriceLargeAmounts) { - checkPoolsLiquidity( - poolLiquidity, - Tokens[network][srcTokenSymbol].address, + 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, + ); + } + }); }); }); }); diff --git a/src/dex/algebra/lib/TickTable.ts b/src/dex/algebra/lib/TickTable.ts index afd86c816..9066c66db 100644 --- a/src/dex/algebra/lib/TickTable.ts +++ b/src/dex/algebra/lib/TickTable.ts @@ -43,7 +43,7 @@ export class TickTable { // wordPos BigInt.asIntN(16, tick >> 8n), // bitPos - BigInt.asUintN(8, tick & BigInt(0xff)), + BigInt.asUintN(8, tick & 0xffn), ]; } @@ -56,7 +56,7 @@ export class TickTable { tick /= tickSpacing; } const [rowNumber, bitNumber] = TickTable.position(tick); - const mask = 1n << bitNumber; + const mask = BigInt.asUintN(256, 1n << bitNumber); // toggleTick is used only in _updatePosition which is always state changing event // Therefore it is never used in price query @@ -83,11 +83,14 @@ export class TickTable { tickSpacing?: bigint, ): [bigint, boolean] { if (tickSpacing !== undefined) { - tick = Yul.sub( - Yul.sdiv(tick, tickSpacing), - Yul.and( - Yul.slt(tick, 0n), - Yul.not(Yul.iszero(Yul.smod(tick, tickSpacing))), + tick = BigInt.asIntN( + 24, + Yul.sub( + Yul.sdiv(tick, tickSpacing), + Yul.and( + Yul.slt(tick, 0n), + Yul.not(Yul.iszero(Yul.smod(tick, tickSpacing))), + ), ), ); } @@ -97,7 +100,7 @@ export class TickTable { let tickBitmapValue = state.tickBitmap[rowNumber.toString()]; tickBitmapValue = tickBitmapValue === undefined ? 0n : tickBitmapValue; - const _row = tickBitmapValue << (255n - bitNumber); + const _row = BigInt.asUintN(256, tickBitmapValue << (255n - bitNumber)); if (_row != 0n) { tick -= BigInt.asIntN(24, 255n - TickTable.getMostSignificantBit(_row)); return [TickTable.boundTick(tick, tickSpacing), true]; @@ -113,7 +116,7 @@ export class TickTable { let tickBitmapValue = state.tickBitmap[rowNumber.toString()]; tickBitmapValue = tickBitmapValue === undefined ? 0n : tickBitmapValue; - const _row = tickBitmapValue >> bitNumber; + const _row = BigInt.asUintN(256, tickBitmapValue >> bitNumber); if (_row !== 0n) { tick += BigInt.asIntN( 24, From f20b869ec935cd1acdc6f152d4376fe7ecb75b52 Mon Sep 17 00:00:00 2001 From: Verisana Date: Thu, 17 Aug 2023 12:55:22 +0100 Subject: [PATCH 07/12] 2.28.10-camelot-v3-tick-bugs.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f5f60c32..286432b96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@paraswap/dex-lib", - "version": "2.28.10-camelot-v3-tick-bugs.0", + "version": "2.28.10-camelot-v3-tick-bugs.1", "main": "build/index.js", "types": "build/index.d.ts", "repository": "https://github.com/paraswap/paraswap-dex-lib", From 6b4c3433544d6e6a0d45f957ca94835d3c2a7065 Mon Sep 17 00:00:00 2001 From: Verisana Date: Thu, 17 Aug 2023 17:43:53 +0100 Subject: [PATCH 08/12] feat: move force RPC to config service --- src/config.ts | 12 +++++++++++- src/dex/algebra/algebra.ts | 3 +++ src/dex/algebra/config.ts | 1 - src/types.ts | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/config.ts b/src/config.ts index bef159a5b..45b466f84 100644 --- a/src/config.ts +++ b/src/config.ts @@ -30,6 +30,7 @@ type BaseConfig = { hashFlowAuthToken?: string; hashFlowDisabledMMs: string[]; swaapV2AuthToken?: string; + forceRpcFallbackDexs: string[]; }; const baseConfigs: { [network: number]: BaseConfig } = { @@ -115,6 +116,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { }, }, }, + forceRpcFallbackDexs: [], }, [Network.ROPSTEN]: { network: Network.ROPSTEN, @@ -142,6 +144,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { rfqConfigs: {}, rpcPollingMaxAllowedStateDelayInBlocks: 5, rpcPollingBlocksBackToTriggerUpdate: 3, + forceRpcFallbackDexs: [], }, [Network.BSC]: { network: Network.BSC, @@ -168,6 +171,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { uniswapV2ExchangeRouterAddress: '0x53e693c6C7FFC4446c53B205Cf513105Bf140D7b', rfqConfigs: {}, + forceRpcFallbackDexs: [], }, [Network.POLYGON]: { network: Network.POLYGON, @@ -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, @@ -224,6 +229,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { rfqConfigs: {}, rpcPollingMaxAllowedStateDelayInBlocks: 2, rpcPollingBlocksBackToTriggerUpdate: 1, + forceRpcFallbackDexs: [], }, [Network.FANTOM]: { network: Network.FANTOM, @@ -251,6 +257,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { rfqConfigs: {}, rpcPollingMaxAllowedStateDelayInBlocks: 2, rpcPollingBlocksBackToTriggerUpdate: 1, + forceRpcFallbackDexs: [], }, [Network.ARBITRUM]: { network: Network.ARBITRUM, @@ -279,6 +286,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { rfqConfigs: {}, rpcPollingMaxAllowedStateDelayInBlocks: 4, rpcPollingBlocksBackToTriggerUpdate: 3, + forceRpcFallbackDexs: [], }, [Network.OPTIMISM]: { network: Network.OPTIMISM, @@ -307,6 +315,7 @@ const baseConfigs: { [network: number]: BaseConfig } = { rfqConfigs: {}, rpcPollingMaxAllowedStateDelayInBlocks: 5, rpcPollingBlocksBackToTriggerUpdate: 3, + forceRpcFallbackDexs: [], }, }; @@ -350,6 +359,7 @@ export function generateConfig(network: number): Config { hashFlowAuthToken: baseConfig.hashFlowAuthToken, swaapV2AuthToken: baseConfig.swaapV2AuthToken, hashFlowDisabledMMs: baseConfig.hashFlowDisabledMMs, + forceRpcFallbackDexs: baseConfig.forceRpcFallbackDexs, }; } @@ -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(); diff --git a/src/dex/algebra/algebra.ts b/src/dex/algebra/algebra.ts index 3b4ad6e55..d64ef8c02 100644 --- a/src/dex/algebra/algebra.ts +++ b/src/dex/algebra/algebra.ts @@ -104,6 +104,9 @@ export class Algebra extends SimpleExchange implements IDex { 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); this.notExistingPoolSetKey = `${CACHE_PREFIX}_${network}_${dexKey}_not_existings_pool_set`.toLowerCase(); diff --git a/src/dex/algebra/config.ts b/src/dex/algebra/config.ts index 83ade331a..9b6147a17 100644 --- a/src/dex/algebra/config.ts +++ b/src/dex/algebra/config.ts @@ -82,7 +82,6 @@ export const AlgebraConfig: DexConfigMap = { uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984', deployer: '0x6dd3fb9653b10e806650f107c3b5a0a6ff974f65', version: 'v1.9', - forceRPC: false, }, }, }; diff --git a/src/types.ts b/src/types.ts index 6d63f0ba2..9d914b038 100644 --- a/src/types.ts +++ b/src/types.ts @@ -276,6 +276,7 @@ export type Config = { hashFlowDisabledMMs: string[]; uniswapV3EventLoggingSampleRate?: number; swaapV2AuthToken?: string; + forceRpcFallbackDexs: string[]; }; export type BigIntAsString = string; From ef625822c3aad6fc9d606ffca483d1127fb6e5c3 Mon Sep 17 00:00:00 2001 From: Verisana Date: Thu, 17 Aug 2023 18:05:12 +0100 Subject: [PATCH 09/12] feat: get fallback force from config service --- src/dex/algebra/algebra.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dex/algebra/algebra.ts b/src/dex/algebra/algebra.ts index d64ef8c02..0cbe60fd5 100644 --- a/src/dex/algebra/algebra.ts +++ b/src/dex/algebra/algebra.ts @@ -105,8 +105,9 @@ export class Algebra extends SimpleExchange implements IDex { this.config = this._toLowerForAllConfigAddresses(); // External configuration has priority over internal - this.config.forceRPC = - dexHelper.config.data.forceRpcFallbackDexs.includes(dexKey); + this.config.forceRPC = dexHelper.config.data.forceRpcFallbackDexs.includes( + dexKey.toLowerCase(), + ); this.notExistingPoolSetKey = `${CACHE_PREFIX}_${network}_${dexKey}_not_existings_pool_set`.toLowerCase(); From 8d762f8bbcb771bf862e4f8ac707ae950449b1f4 Mon Sep 17 00:00:00 2001 From: Verisana Date: Thu, 17 Aug 2023 18:05:54 +0100 Subject: [PATCH 10/12] 2.28.10-camelot-v3-tick-bugs.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 286432b96..1e8668077 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@paraswap/dex-lib", - "version": "2.28.10-camelot-v3-tick-bugs.1", + "version": "2.28.10-camelot-v3-tick-bugs.2", "main": "build/index.js", "types": "build/index.d.ts", "repository": "https://github.com/paraswap/paraswap-dex-lib", From f8ee5a4921676af1f78b62db631637f7f82253e0 Mon Sep 17 00:00:00 2001 From: Verisana Date: Fri, 18 Aug 2023 17:05:30 +0100 Subject: [PATCH 11/12] chore: set to latest version pckage number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e8668077..6449d4439 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@paraswap/dex-lib", - "version": "2.28.10-camelot-v3-tick-bugs.2", + "version": "2.28.10", "main": "build/index.js", "types": "build/index.d.ts", "repository": "https://github.com/paraswap/paraswap-dex-lib", From 4722f0b9286d3a2b8541d18c848544273b7d8dd5 Mon Sep 17 00:00:00 2001 From: Verisana Date: Fri, 18 Aug 2023 17:06:08 +0100 Subject: [PATCH 12/12] 2.28.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6449d4439..d7547d5cd 100644 --- a/package.json +++ b/package.json @@ -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",