diff --git a/src/dex/usual-bond/config.ts b/src/dex/usual-bond/config.ts deleted file mode 100644 index 09fe45eca..000000000 --- a/src/dex/usual-bond/config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { DexParams } from './types'; -import { DexConfigMap } from '../../types'; -import { Network } from '../../constants'; - -export const UsualBondConfig: DexConfigMap = { - UsualBond: { - [Network.MAINNET]: { - usd0Address: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5', - usd0ppAddress: '0x35D8949372D46B7a3D5A56006AE77B215fc69bC0', - }, - }, -}; diff --git a/src/dex/usual-bond/types.ts b/src/dex/usual-bond/types.ts deleted file mode 100644 index ce90c4eb4..000000000 --- a/src/dex/usual-bond/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Address } from '../../types'; - -export type PoolState = {}; - -export type UsualBondData = {}; - -export type DexParams = { - usd0Address: Address; - usd0ppAddress: Address; -}; diff --git a/src/dex/usual-bond/usual-bond-e2e.test.ts b/src/dex/usual-bond/usual-bond-e2e.test.ts deleted file mode 100644 index f6d987514..000000000 --- a/src/dex/usual-bond/usual-bond-e2e.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { testE2E } from '../../../tests/utils-e2e'; -import { - Tokens, - Holders, - NativeTokenSymbols, -} from '../../../tests/constants-e2e'; -import { Network, ContractMethod, SwapSide } from '../../constants'; -import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { generateConfig } from '../../config'; - -function testForNetwork( - network: Network, - dexKey: string, - tokenASymbol: string, - tokenBSymbol: string, - tokenAAmount: string, - tokenBAmount: string, -) { - const provider = new StaticJsonRpcProvider( - generateConfig(network).privateHttpProvider, - network, - ); - const tokens = Tokens[network]; - const holders = Holders[network]; - - const sideToContractMethods = new Map([ - [SwapSide.SELL, [ContractMethod.swapExactAmountIn]], - ]); - - describe(`${network}`, () => { - sideToContractMethods.forEach((contractMethods, side) => - describe(`${side}`, () => { - contractMethods.forEach((contractMethod: ContractMethod) => { - describe(`${contractMethod}`, () => { - it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => { - await testE2E( - tokens[tokenASymbol], - tokens[tokenBSymbol], - holders[tokenASymbol], - side === SwapSide.SELL ? tokenAAmount : tokenBAmount, - side, - dexKey, - contractMethod, - network, - provider, - ); - }); - }); - }); - }), - ); - }); -} - -describe('UsualBond E2E', () => { - const dexKey = 'UsualBond'; - - describe('Mainnet', () => { - const network = Network.MAINNET; - - const tokenASymbol: string = 'USD0'; - const tokenBSymbol: string = 'USD0++'; - - const tokenAAmount: string = '100000'; - const tokenBAmount: string = '100000'; - - testForNetwork( - network, - dexKey, - tokenASymbol, - tokenBSymbol, - tokenAAmount, - tokenBAmount, - ); - }); -}); diff --git a/src/dex/usual-bond/usual-bond-integration.test.ts b/src/dex/usual-bond/usual-bond-integration.test.ts deleted file mode 100644 index 3844bc200..000000000 --- a/src/dex/usual-bond/usual-bond-integration.test.ts +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { Interface } from '@ethersproject/abi'; -import { DummyDexHelper } from '../../dex-helper/index'; -import { Network, SwapSide } from '../../constants'; -import { BI_POWS } from '../../bigint-constants'; -import { UsualBond } from './usual-bond'; -import { - checkPoolPrices, - checkConstantPoolPrices, - checkPoolsLiquidity, -} from '../../../tests/utils'; -import { Tokens } from '../../../tests/constants-e2e'; - -async function testPricingOnNetwork( - usualBond: UsualBond, - network: Network, - dexKey: string, - blockNumber: number, - srcTokenAddress: string, - destTokenAddress: string, - side: SwapSide, - amounts: bigint[], - funcNameToCheck: string, -) { - const networkTokens = Tokens[network]; - - console.log(amounts); - - const pools = await usualBond.getPoolIdentifiers( - networkTokens['USD0'], - networkTokens['USD0++'], - side, - blockNumber, - ); - console.log(`${'USD0'} <> ${'USD0++'} Pool Identifiers: `, pools); - - expect(pools.length).toBeGreaterThan(0); - - const poolPrices = await usualBond.getPricesVolume( - networkTokens['USD0'], - networkTokens['USD0++'], - amounts, - side, - blockNumber, - pools, - ); - console.log(`${'USD0'} <> ${'USD0++'} Pool Prices: `, poolPrices); - - expect(poolPrices).not.toBeNull(); - if (usualBond.hasConstantPriceLargeAmounts) { - checkConstantPoolPrices(poolPrices!, amounts, dexKey); - } else { - checkPoolPrices(poolPrices!, amounts, side, dexKey); - } - - // Check if onchain pricing equals to calculated ones - checkPoolPrices(poolPrices!, amounts, side, dexKey); -} - -describe('UsualBond', function () { - const dexKey = 'UsualBond'; - let blockNumber: number; - let usualBond: UsualBond; - - describe('Mainnet', () => { - const network = Network.MAINNET; - const dexHelper = new DummyDexHelper(network); - - // Don't forget to update relevant tokens in constant-e2e.ts - - const amountsForSell = [ - 0n, - 1n * BI_POWS[18], - 2n * BI_POWS[18], - 3n * BI_POWS[18], - 4n * BI_POWS[18], - 5n * BI_POWS[18], - 6n * BI_POWS[18], - 7n * BI_POWS[18], - 8n * BI_POWS[18], - 9n * BI_POWS[18], - 10n * BI_POWS[18], - ]; - - beforeAll(async () => { - blockNumber = await dexHelper.web3Provider.eth.getBlockNumber(); - usualBond = new UsualBond(network, dexKey, dexHelper); - if (usualBond.initializePricing) { - await usualBond.initializePricing(blockNumber); - } - }); - - it('getPoolIdentifiers and getPricesVolume SELL', async function () { - await testPricingOnNetwork( - usualBond, - network, - dexKey, - blockNumber, - 'USD0', - 'USD0++', - SwapSide.SELL, - amountsForSell, - '', - ); - }); - - it('getTopPoolsForToken: USD0', async function () { - const tokenA = Tokens[network]['USD0']; - const dexHelper = new DummyDexHelper(network); - const usualBond = new UsualBond(network, dexKey, dexHelper); - - const poolLiquidity = await usualBond.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - - it('getTopPoolsForToken: USD0++', async function () { - const tokenA = Tokens[network]['USD0++']; - const dexHelper = new DummyDexHelper(network); - const usualBond = new UsualBond(network, dexKey, dexHelper); - - const poolLiquidity = await usualBond.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - }); -}); diff --git a/src/dex/usual-bond/usual-bond.ts b/src/dex/usual-bond/usual-bond.ts deleted file mode 100644 index 295dc0db4..000000000 --- a/src/dex/usual-bond/usual-bond.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { - Token, - Address, - ExchangePrices, - PoolPrices, - AdapterExchangeParam, - Logger, - NumberAsString, - DexExchangeParam, - PoolLiquidity, -} from '../../types'; -import { SwapSide, Network } from '../../constants'; -import * as CALLDATA_GAS_COST from '../../calldata-gas-cost'; -import { getDexKeysWithNetwork } from '../../utils'; -import { IDex } from '../idex'; -import { IDexHelper } from '../../dex-helper/idex-helper'; -import { UsualBondData, DexParams } from './types'; -import { SimpleExchange } from '../simple-exchange'; -import { UsualBondConfig } from './config'; -import { Interface, JsonFragment } from '@ethersproject/abi'; -import USD0PP_ABI from '../../abi/usual-bond/usd0pp.abi.json'; -import { BI_POWS } from '../../bigint-constants'; - -export class UsualBond extends SimpleExchange implements IDex { - protected config: DexParams; - - readonly hasConstantPriceLargeAmounts = true; - readonly needWrapNative = false; - readonly isFeeOnTransferSupported = false; - - public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = - getDexKeysWithNetwork(UsualBondConfig); - - usd0ppIface: Interface; - logger: Logger; - - constructor( - readonly network: Network, - readonly dexKey: string, - readonly dexHelper: IDexHelper, - ) { - super(dexHelper, dexKey); - const config = UsualBondConfig[dexKey][network]; - this.usd0ppIface = new Interface(USD0PP_ABI as JsonFragment[]); - this.config = { - usd0Address: config.usd0Address.toLowerCase(), - usd0ppAddress: config.usd0ppAddress.toLowerCase(), - }; - this.logger = dexHelper.getLogger(dexKey); - } - - async initializePricing(blockNumber: number) { - // No initialization needed for constant price - } - - getConfig() { - return this.config; - } - - is_usd0(token: string) { - return token.toLowerCase() === this.config.usd0Address.toLowerCase(); - } - - is_usd0pp(token: string) { - return token.toLowerCase() === this.config.usd0ppAddress.toLowerCase(); - } - - is_usd0_swap_token(srcToken: string, destToken: string) { - return this.is_usd0(srcToken) && this.is_usd0pp(destToken); - } - - getAdapters() { - return null; - } - - async getPoolIdentifiers( - srcToken: Token, - destToken: Token, - side: SwapSide, - blockNumber: number, - ): Promise { - if (!srcToken || !destToken) { - this.logger.error('Source or destination token is undefined'); - return []; - } - - const srcTokenAddress = srcToken.address?.toLowerCase(); - const destTokenAddress = destToken.address?.toLowerCase(); - - if (!srcTokenAddress || !destTokenAddress) { - this.logger.error('Source or destination token address is undefined'); - return []; - } - - if (this.is_usd0_swap_token(srcTokenAddress, destTokenAddress)) { - return [`${this.dexKey}_${this.config.usd0ppAddress}`]; - } - - return []; - } - - async getPricesVolume( - srcToken: Token, - destToken: Token, - amounts: bigint[], - side: SwapSide, - blockNumber: number, - limitPools?: string[], - ): Promise> { - if (side === SwapSide.BUY) { - return null; - } - - const isUSD0SwapToken = this.is_usd0_swap_token( - srcToken.address, - destToken.address, - ); - - if (!isUSD0SwapToken) { - return null; - } - - const unitOut = BI_POWS[18]; // 1:1 swap - const amountsOut = amounts; // 1:1 swap, so output amounts are the same as input - - return [ - { - unit: unitOut, - prices: amountsOut, - data: {}, - poolAddresses: [this.config.usd0ppAddress], - exchange: this.dexKey, - gasCost: 70000, - poolIdentifier: this.dexKey, - }, - ]; - } - - getCalldataGasCost(poolPrices: PoolPrices): number | number[] { - return CALLDATA_GAS_COST.DEX_NO_PAYLOAD; - } - - getAdapterParam( - srcToken: string, - destToken: string, - srcAmount: string, - destAmount: string, - data: UsualBondData, - side: SwapSide, - ): AdapterExchangeParam { - const payload = '0x'; - - return { - targetExchange: this.config.usd0ppAddress, - payload, - networkFee: '0', - }; - } - - async getDexParam( - srcToken: Address, - destToken: Address, - srcAmount: NumberAsString, - destAmount: NumberAsString, - recipient: Address, - data: UsualBondData, - side: SwapSide, - ): Promise { - if (this.is_usd0(srcToken) && this.is_usd0pp(destToken)) { - const exchangeData = this.usd0ppIface.encodeFunctionData('mint', [ - srcAmount, - ]); - - return { - needWrapNative: false, - dexFuncHasRecipient: false, - exchangeData, - targetExchange: this.config.usd0ppAddress, - returnAmountPos: undefined, - }; - } - throw new Error('LOGIC ERROR'); - } - - async getTopPoolsForToken( - tokenAddress: Address, - limit: number, - ): Promise { - const isUsd0 = this.is_usd0(tokenAddress); - if (!isUsd0 && !this.is_usd0pp(tokenAddress)) return []; - - return [ - { - exchange: this.dexKey, - address: this.config.usd0ppAddress, - connectorTokens: [ - { - decimals: 18, - address: isUsd0 - ? this.config.usd0ppAddress - : this.config.usd0Address, - }, - ], - liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred - }, - ]; - } -} diff --git a/src/dex/usual-m-smart-m/config.ts b/src/dex/usual-m-smart-m/config.ts deleted file mode 100644 index 108c7f7b8..000000000 --- a/src/dex/usual-m-smart-m/config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { DexParams } from './types'; -import { DexConfigMap } from '../../types'; -import { Network, SwapSide } from '../../constants'; - -export const UsualMSmartMConfig: DexConfigMap = { - UsualMSmartM: { - [Network.MAINNET]: { - smartMAddress: '0x437cc33344a0B27A429f795ff6B469C72698B291', - usualMAddress: '0xFe274C305b365dC38e188E8f01c4FAe2171ce927', - }, - }, -}; diff --git a/src/dex/usual-m-smart-m/types.ts b/src/dex/usual-m-smart-m/types.ts deleted file mode 100644 index 0684a394e..000000000 --- a/src/dex/usual-m-smart-m/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Address } from '../../types'; - -export type PoolState = {}; - -export type UsualMSmartMData = {}; - -export type DexParams = { - smartMAddress: Address; - usualMAddress: Address; -}; diff --git a/src/dex/usual-m-smart-m/usual-m-smart-m-e2e.test.ts b/src/dex/usual-m-smart-m/usual-m-smart-m-e2e.test.ts deleted file mode 100644 index 530395578..000000000 --- a/src/dex/usual-m-smart-m/usual-m-smart-m-e2e.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { testE2E } from '../../../tests/utils-e2e'; -import { Tokens, Holders } from '../../../tests/constants-e2e'; -import { Network, ContractMethod, SwapSide } from '../../constants'; -import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { generateConfig } from '../../config'; - -function testForNetwork( - network: Network, - dexKey: string, - tokenASymbol: string, - tokenBSymbol: string, - tokenAAmount: string, - tokenBAmount: string, -) { - const provider = new StaticJsonRpcProvider( - generateConfig(network).privateHttpProvider, - network, - ); - const tokens = Tokens[network]; - const holders = Holders[network]; - - const sideToContractMethods = new Map([ - [SwapSide.SELL, [ContractMethod.swapExactAmountIn]], - ]); - - describe(`${network}`, () => { - sideToContractMethods.forEach((contractMethods, side) => - describe(`${side}`, () => { - contractMethods.forEach((contractMethod: ContractMethod) => { - describe(`${contractMethod}`, () => { - it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => { - await testE2E( - tokens[tokenASymbol], - tokens[tokenBSymbol], - holders[tokenASymbol], - side === SwapSide.SELL ? tokenAAmount : tokenBAmount, - side, - dexKey, - contractMethod, - network, - provider, - ); - }); - }); - }); - }), - ); - }); -} - -describe('UsualMSmartM E2E', () => { - const dexKey = 'UsualMSmartM'; - - describe('Mainnet', () => { - const network = Network.MAINNET; - - const tokenASymbol: string = 'SmartM'; - const tokenBSymbol: string = 'UsualM'; - - const tokenAAmount: string = '100000'; - const tokenBAmount: string = '100000'; - - testForNetwork( - network, - dexKey, - tokenASymbol, - tokenBSymbol, - tokenAAmount, - tokenBAmount, - ); - }); -}); diff --git a/src/dex/usual-m-smart-m/usual-m-smart-m-integration.test.ts b/src/dex/usual-m-smart-m/usual-m-smart-m-integration.test.ts deleted file mode 100644 index a647324ca..000000000 --- a/src/dex/usual-m-smart-m/usual-m-smart-m-integration.test.ts +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { Interface } from '@ethersproject/abi'; -import { DummyDexHelper } from '../../dex-helper/index'; -import { Network, SwapSide } from '../../constants'; -import { BI_POWS } from '../../bigint-constants'; -import { UsualMSmartM } from './usual-m-smart-m'; -import { - checkPoolPrices, - checkConstantPoolPrices, - checkPoolsLiquidity, -} from '../../../tests/utils'; -import { Tokens } from '../../../tests/constants-e2e'; - -async function testPricingOnNetwork( - usualMSmartM: UsualMSmartM, - network: Network, - dexKey: string, - blockNumber: number, - srcTokenAddress: string, - destTokenAddress: string, - side: SwapSide, - amounts: bigint[], - funcNameToCheck: string, -) { - const networkTokens = Tokens[network]; - - console.log(amounts); - - const pools = await usualMSmartM.getPoolIdentifiers( - networkTokens['SmartM'], - networkTokens['UsualM'], - side, - blockNumber, - ); - console.log(`${'SmartM'} <> ${'UsualM'} Pool Identifiers: `, pools); - - expect(pools.length).toBeGreaterThan(0); - - const poolPrices = await usualMSmartM.getPricesVolume( - networkTokens['SmartM'], - networkTokens['UsualM'], - amounts, - side, - blockNumber, - pools, - ); - console.log(`${'SmartM'} <> ${'UsualM'} Pool Prices: `, poolPrices); - - expect(poolPrices).not.toBeNull(); - if (usualMSmartM.hasConstantPriceLargeAmounts) { - checkConstantPoolPrices(poolPrices!, amounts, dexKey); - } else { - checkPoolPrices(poolPrices!, amounts, side, dexKey); - } - - // Check if onchain pricing equals to calculated ones - checkPoolPrices(poolPrices!, amounts, side, dexKey); -} - -describe('SmartM<>UsualM', function () { - const dexKey = 'UsualMSmartM'; - let blockNumber: number; - let usualMSmartM: UsualMSmartM; - - describe('Mainnet', () => { - const network = Network.MAINNET; - const dexHelper = new DummyDexHelper(network); - - // Don't forget to update relevant tokens in constant-e2e.ts - - const amountsForSell = [ - 0n, - 1n * BI_POWS[18], - 2n * BI_POWS[18], - 3n * BI_POWS[18], - 4n * BI_POWS[18], - 5n * BI_POWS[18], - 6n * BI_POWS[18], - 7n * BI_POWS[18], - 8n * BI_POWS[18], - 9n * BI_POWS[18], - 10n * BI_POWS[18], - ]; - - beforeAll(async () => { - blockNumber = await dexHelper.web3Provider.eth.getBlockNumber(); - usualMSmartM = new UsualMSmartM(network, dexKey, dexHelper); - if (usualMSmartM.initializePricing) { - await usualMSmartM.initializePricing(blockNumber); - } - }); - - it('getPoolIdentifiers and getPricesVolume SELL', async function () { - await testPricingOnNetwork( - usualMSmartM, - network, - dexKey, - blockNumber, - 'SmartM', - 'UsualM', - SwapSide.SELL, - amountsForSell, - '', - ); - }); - - it('getTopPoolsForToken: SmartM', async function () { - const tokenA = Tokens[network]['SmartM']; - const dexHelper = new DummyDexHelper(network); - const usualMSmartM = new UsualMSmartM(network, dexKey, dexHelper); - - const poolLiquidity = await usualMSmartM.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - - it('getTopPoolsForToken: UsualM', async function () { - const tokenA = Tokens[network]['UsualM']; - const dexHelper = new DummyDexHelper(network); - const usualMSmartM = new UsualMSmartM(network, dexKey, dexHelper); - - const poolLiquidity = await usualMSmartM.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - }); -}); diff --git a/src/dex/usual-m-smart-m/usual-m-smart-m.ts b/src/dex/usual-m-smart-m/usual-m-smart-m.ts deleted file mode 100644 index 9cfd62d07..000000000 --- a/src/dex/usual-m-smart-m/usual-m-smart-m.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { - Token, - Address, - ExchangePrices, - PoolPrices, - AdapterExchangeParam, - Logger, - NumberAsString, - DexExchangeParam, - PoolLiquidity, -} from '../../types'; -import { SwapSide, Network } from '../../constants'; -import * as CALLDATA_GAS_COST from '../../calldata-gas-cost'; -import { getDexKeysWithNetwork } from '../../utils'; -import { IDex } from '../idex'; -import { IDexHelper } from '../../dex-helper/idex-helper'; -import { UsualMSmartMData, DexParams } from './types'; -import { SimpleExchange } from '../simple-exchange'; -import { UsualMSmartMConfig } from './config'; -import { Interface, JsonFragment } from '@ethersproject/abi'; -import USUALM_ABI from '../../abi/usual-m-smart-m/usualM.abi.json'; -import { BI_POWS } from '../../bigint-constants'; - -export class UsualMSmartM - extends SimpleExchange - implements IDex -{ - protected config: DexParams; - - readonly hasConstantPriceLargeAmounts = true; - readonly needWrapNative = false; - readonly isFeeOnTransferSupported = false; - - public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = - getDexKeysWithNetwork(UsualMSmartMConfig); - - usualMIface: Interface; - logger: Logger; - - constructor( - readonly network: Network, - readonly dexKey: string, - readonly dexHelper: IDexHelper, - ) { - super(dexHelper, dexKey); - const config = UsualMSmartMConfig[dexKey][network]; - this.usualMIface = new Interface(USUALM_ABI as JsonFragment[]); - this.config = { - smartMAddress: config.smartMAddress.toLowerCase(), - usualMAddress: config.usualMAddress.toLowerCase(), - }; - this.logger = dexHelper.getLogger(dexKey); - } - - async initializePricing(blockNumber: number) { - // No initialization needed for constant price - } - - getConfig() { - return this.config; - } - - is_smartM(token: string) { - return token.toLowerCase() === this.config.smartMAddress.toLowerCase(); - } - - is_usualM(token: string) { - return token.toLowerCase() === this.config.usualMAddress.toLowerCase(); - } - - is_usualM_swap_token(srcToken: string, destToken: string) { - return this.is_smartM(srcToken) && this.is_usualM(destToken); - } - - getAdapters() { - return null; - } - - async getPoolIdentifiers( - srcToken: Token, - destToken: Token, - side: SwapSide, - blockNumber: number, - ): Promise { - if (!srcToken || !destToken) { - this.logger.error('Source or destination token is undefined'); - return []; - } - - const srcTokenAddress = srcToken.address?.toLowerCase(); - const destTokenAddress = destToken.address?.toLowerCase(); - - if (!srcTokenAddress || !destTokenAddress) { - this.logger.error('Source or destination token address is undefined'); - return []; - } - - if (this.is_usualM_swap_token(srcTokenAddress, destTokenAddress)) { - return [`${this.dexKey}_${this.config.usualMAddress}`]; - } - - return []; - } - - async getPricesVolume( - srcToken: Token, - destToken: Token, - amounts: bigint[], - side: SwapSide, - blockNumber: number, - limitPools?: string[], - ): Promise> { - if (side === SwapSide.BUY) { - return null; - } - - const isUsualMSwapToken = this.is_usualM_swap_token( - srcToken.address, - destToken.address, - ); - - if (!isUsualMSwapToken) { - return null; - } - - const unitOut = BI_POWS[18]; // 1:1 swap - const amountsOut = amounts; // 1:1 swap, so output amounts are the same as input - - return [ - { - unit: unitOut, - prices: amountsOut, - data: {}, - poolAddresses: [this.config.usualMAddress], - exchange: this.dexKey, - gasCost: 70000, - poolIdentifier: this.dexKey, - }, - ]; - } - - getCalldataGasCost( - poolPrices: PoolPrices, - ): number | number[] { - return CALLDATA_GAS_COST.DEX_NO_PAYLOAD; - } - - getAdapterParam( - srcToken: string, - destToken: string, - srcAmount: string, - destAmount: string, - data: UsualMSmartMData, - side: SwapSide, - ): AdapterExchangeParam { - const payload = '0x'; - - return { - targetExchange: this.config.usualMAddress, - payload, - networkFee: '0', - }; - } - - async getDexParam( - srcToken: Address, - destToken: Address, - srcAmount: NumberAsString, - destAmount: NumberAsString, - recipient: Address, - data: UsualMSmartMData, - side: SwapSide, - ): Promise { - if (this.is_smartM(srcToken) && this.is_usualM(destToken)) { - const exchangeData = this.usualMIface.encodeFunctionData('wrap', [ - recipient, - srcAmount, - ]); - - return { - needWrapNative: false, - dexFuncHasRecipient: true, - exchangeData, - targetExchange: this.config.usualMAddress, - returnAmountPos: undefined, - }; - } - - throw new Error('LOGIC ERROR'); - } - - async getTopPoolsForToken( - tokenAddress: Address, - limit: number, - ): Promise { - const isSmartM = this.is_smartM(tokenAddress); - if (!isSmartM && !this.is_usualM(tokenAddress)) return []; - - return [ - { - exchange: this.dexKey, - address: this.config.usualMAddress, - connectorTokens: [ - { - decimals: 6, - address: isSmartM - ? this.config.usualMAddress - : this.config.smartMAddress, - }, - ], - liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred - }, - ]; - } -} diff --git a/src/dex/usual-m-usd0/config.ts b/src/dex/usual-m-usd0/config.ts deleted file mode 100644 index 0ccdcabe9..000000000 --- a/src/dex/usual-m-usd0/config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DexParams } from './types'; -import { DexConfigMap } from '../../types'; -import { Network, SwapSide } from '../../constants'; - -export const UsualMUsd0Config: DexConfigMap = { - UsualMUsd0: { - [Network.MAINNET]: { - usualMAddress: '0xFe274C305b365dC38e188E8f01c4FAe2171ce927', - usd0Address: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5', - usualDaoCollateralAddress: '0xde6e1F680C4816446C8D515989E2358636A38b04', - }, - }, -}; diff --git a/src/dex/usual-m-usd0/types.ts b/src/dex/usual-m-usd0/types.ts deleted file mode 100644 index 43ff7d8c8..000000000 --- a/src/dex/usual-m-usd0/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Address } from '../../types'; - -export type PoolState = {}; - -export type UsualMUsd0Data = {}; - -export type DexParams = { - usualMAddress: Address; - usd0Address: Address; - usualDaoCollateralAddress: Address; -}; diff --git a/src/dex/usual-m-usd0/usual-m-usd0-e2e.test.ts b/src/dex/usual-m-usd0/usual-m-usd0-e2e.test.ts deleted file mode 100644 index 7f42f6f75..000000000 --- a/src/dex/usual-m-usd0/usual-m-usd0-e2e.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { testE2E } from '../../../tests/utils-e2e'; -import { Tokens, Holders } from '../../../tests/constants-e2e'; -import { Network, ContractMethod, SwapSide } from '../../constants'; -import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { generateConfig } from '../../config'; - -function testForNetwork( - network: Network, - dexKey: string, - tokenASymbol: string, - tokenBSymbol: string, - tokenAAmount: string, - tokenBAmount: string, -) { - const provider = new StaticJsonRpcProvider( - generateConfig(network).privateHttpProvider, - network, - ); - const tokens = Tokens[network]; - const holders = Holders[network]; - - const sideToContractMethods = new Map([ - [SwapSide.SELL, [ContractMethod.swapExactAmountIn]], - ]); - - describe(`${network}`, () => { - sideToContractMethods.forEach((contractMethods, side) => - describe(`${side}`, () => { - contractMethods.forEach((contractMethod: ContractMethod) => { - describe(`${contractMethod}`, () => { - it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => { - await testE2E( - tokens[tokenASymbol], - tokens[tokenBSymbol], - holders[tokenASymbol], - side === SwapSide.SELL ? tokenAAmount : tokenBAmount, - side, - dexKey, - contractMethod, - network, - provider, - ); - }); - }); - }); - }), - ); - }); -} - -describe('UsualM<>Usd0 E2E', () => { - const dexKey = 'UsualMUsd0'; - - describe('Mainnet', () => { - const network = Network.MAINNET; - - const tokenASymbol: string = 'UsualM'; - const tokenBSymbol: string = 'USD0'; - - const tokenAAmount: string = '100000'; - const tokenBAmount: string = '100000'; - - testForNetwork( - network, - dexKey, - tokenASymbol, - tokenBSymbol, - tokenAAmount, - tokenBAmount, - ); - }); -}); diff --git a/src/dex/usual-m-usd0/usual-m-usd0-integration.test.ts b/src/dex/usual-m-usd0/usual-m-usd0-integration.test.ts deleted file mode 100644 index c4ce6881a..000000000 --- a/src/dex/usual-m-usd0/usual-m-usd0-integration.test.ts +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable no-console */ -import dotenv from 'dotenv'; -dotenv.config(); - -import { Interface } from '@ethersproject/abi'; -import { DummyDexHelper } from '../../dex-helper/index'; -import { Network, SwapSide } from '../../constants'; -import { BI_POWS } from '../../bigint-constants'; -import { UsualMUsd0 } from './usual-m-usd0'; -import { - checkPoolPrices, - checkConstantPoolPrices, - checkPoolsLiquidity, -} from '../../../tests/utils'; -import { Tokens } from '../../../tests/constants-e2e'; - -async function testPricingOnNetwork( - usualMSmartM: UsualMUsd0, - network: Network, - dexKey: string, - blockNumber: number, - srcTokenAddress: string, - destTokenAddress: string, - side: SwapSide, - amounts: bigint[], - funcNameToCheck: string, -) { - const networkTokens = Tokens[network]; - - console.log(amounts); - - const pools = await usualMSmartM.getPoolIdentifiers( - networkTokens['UsualM'], - networkTokens['USD0'], - side, - blockNumber, - ); - console.log(`${'UsualM'} <> ${'USD0'} Pool Identifiers: `, pools); - - expect(pools.length).toBeGreaterThan(0); - - const poolPrices = await usualMSmartM.getPricesVolume( - networkTokens['UsualM'], - networkTokens['USD0'], - amounts, - side, - blockNumber, - pools, - ); - console.log(`${'UsualM'} <> ${'USD0'} Pool Prices: `, poolPrices); - - expect(poolPrices).not.toBeNull(); - if (usualMSmartM.hasConstantPriceLargeAmounts) { - checkConstantPoolPrices(poolPrices!, amounts, dexKey); - } else { - checkPoolPrices(poolPrices!, amounts, side, dexKey); - } - - // Check if onchain pricing equals to calculated ones - checkPoolPrices(poolPrices!, amounts, side, dexKey); -} - -describe('UsualM<>USD0', function () { - const dexKey = 'UsualMUsd0'; - let blockNumber: number; - let usualMUsd0: UsualMUsd0; - - describe('Mainnet', () => { - const network = Network.MAINNET; - const dexHelper = new DummyDexHelper(network); - - // Don't forget to update relevant tokens in constant-e2e.ts - - const amountsForSell = [ - 0n, - 1n * BI_POWS[18], - 2n * BI_POWS[18], - 3n * BI_POWS[18], - 4n * BI_POWS[18], - 5n * BI_POWS[18], - 6n * BI_POWS[18], - 7n * BI_POWS[18], - 8n * BI_POWS[18], - 9n * BI_POWS[18], - 10n * BI_POWS[18], - ]; - - beforeAll(async () => { - blockNumber = await dexHelper.web3Provider.eth.getBlockNumber(); - usualMUsd0 = new UsualMUsd0(network, dexKey, dexHelper); - if (usualMUsd0.initializePricing) { - await usualMUsd0.initializePricing(blockNumber); - } - }); - - it('getPoolIdentifiers and getPricesVolume SELL', async function () { - await testPricingOnNetwork( - usualMUsd0, - network, - dexKey, - blockNumber, - 'UsualM', - 'USD0', - SwapSide.SELL, - amountsForSell, - '', - ); - }); - - it('getTopPoolsForToken: UsualM', async function () { - const tokenA = Tokens[network]['UsualM']; - const dexHelper = new DummyDexHelper(network); - const usualMUsd0 = new UsualMUsd0(network, dexKey, dexHelper); - - const poolLiquidity = await usualMUsd0.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - - it('getTopPoolsForToken: USD0', async function () { - const tokenA = Tokens[network]['USD0']; - const dexHelper = new DummyDexHelper(network); - const usualMUsd0 = new UsualMUsd0(network, dexKey, dexHelper); - - const poolLiquidity = await usualMUsd0.getTopPoolsForToken( - tokenA.address, - 10, - ); - console.log( - `${tokenA.symbol} Top Pools:`, - JSON.stringify(poolLiquidity, null, 2), - ); - - checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey); - }); - }); -}); diff --git a/src/dex/usual-m-usd0/usual-m-usd0.ts b/src/dex/usual-m-usd0/usual-m-usd0.ts deleted file mode 100644 index 9d3c89d82..000000000 --- a/src/dex/usual-m-usd0/usual-m-usd0.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { - Token, - Address, - ExchangePrices, - PoolPrices, - AdapterExchangeParam, - Logger, - NumberAsString, - DexExchangeParam, - PoolLiquidity, -} from '../../types'; -import { SwapSide, Network } from '../../constants'; -import * as CALLDATA_GAS_COST from '../../calldata-gas-cost'; -import { getDexKeysWithNetwork } from '../../utils'; -import { IDex } from '../idex'; -import { IDexHelper } from '../../dex-helper/idex-helper'; -import { UsualMUsd0Data, DexParams } from './types'; -import { SimpleExchange } from '../simple-exchange'; -import { UsualMUsd0Config } from './config'; -import { Interface, JsonFragment } from '@ethersproject/abi'; -import USUAL_DAO_COLLATERAL_ABI from '../../abi/usual-m-usd0/usualCollateralDao.abi.json'; -import { BI_POWS } from '../../bigint-constants'; - -export class UsualMUsd0 extends SimpleExchange implements IDex { - protected config: DexParams; - - readonly hasConstantPriceLargeAmounts = true; - readonly needWrapNative = false; - readonly isFeeOnTransferSupported = false; - - public static dexKeysWithNetwork: { key: string; networks: Network[] }[] = - getDexKeysWithNetwork(UsualMUsd0Config); - - usualDaoCollateralIface: Interface; - logger: Logger; - - constructor( - readonly network: Network, - readonly dexKey: string, - readonly dexHelper: IDexHelper, - ) { - super(dexHelper, dexKey); - const config = UsualMUsd0Config[dexKey][network]; - this.usualDaoCollateralIface = new Interface( - USUAL_DAO_COLLATERAL_ABI as JsonFragment[], - ); - this.config = { - usualMAddress: config.usualMAddress.toLowerCase(), - usd0Address: config.usd0Address.toLowerCase(), - usualDaoCollateralAddress: config.usualDaoCollateralAddress.toLowerCase(), - }; - this.logger = dexHelper.getLogger(dexKey); - } - - async initializePricing(blockNumber: number) { - // No initialization needed for constant price - } - - getConfig() { - return this.config; - } - - is_usualM(token: string) { - return token.toLowerCase() === this.config.usualMAddress.toLowerCase(); - } - - is_usd0(token: string) { - return token.toLowerCase() === this.config.usd0Address.toLowerCase(); - } - - is_usd0_swap_token(srcToken: string, destToken: string) { - return this.is_usualM(srcToken) && this.is_usd0(destToken); - } - - getAdapters() { - return null; - } - - async getPoolIdentifiers( - srcToken: Token, - destToken: Token, - side: SwapSide, - blockNumber: number, - ): Promise { - if (!srcToken || !destToken) { - this.logger.error('Source or destination token is undefined'); - return []; - } - - const srcTokenAddress = srcToken.address?.toLowerCase(); - const destTokenAddress = destToken.address?.toLowerCase(); - - if (!srcTokenAddress || !destTokenAddress) { - this.logger.error('Source or destination token address is undefined'); - return []; - } - - if (this.is_usd0_swap_token(srcTokenAddress, destTokenAddress)) { - return [`${this.dexKey}_${this.config.usd0Address}`]; - } - - return []; - } - - async getPricesVolume( - srcToken: Token, - destToken: Token, - amounts: bigint[], - side: SwapSide, - blockNumber: number, - limitPools?: string[], - ): Promise> { - if (side === SwapSide.BUY) { - return null; - } - - const isUsd0SwapToken = this.is_usd0_swap_token( - srcToken.address, - destToken.address, - ); - - if (!isUsd0SwapToken) { - return null; - } - - const unitOut = BI_POWS[18]; // 1:1 swap - const amountsOut = amounts; // 1:1 swap, so output amounts are the same as input - - return [ - { - unit: unitOut, - prices: amountsOut, - data: {}, - poolAddresses: [this.config.usd0Address], - exchange: this.dexKey, - gasCost: 70000, - poolIdentifier: this.dexKey, - }, - ]; - } - - getCalldataGasCost( - poolPrices: PoolPrices, - ): number | number[] { - return CALLDATA_GAS_COST.DEX_NO_PAYLOAD; - } - - getAdapterParam( - srcToken: string, - destToken: string, - srcAmount: string, - destAmount: string, - data: UsualMUsd0Data, - side: SwapSide, - ): AdapterExchangeParam { - const payload = '0x'; - - return { - targetExchange: this.config.usualMAddress, - payload, - networkFee: '0', - }; - } - - async getDexParam( - srcToken: Address, - destToken: Address, - srcAmount: NumberAsString, - destAmount: NumberAsString, - recipient: Address, - data: UsualMUsd0Data, - side: SwapSide, - ): Promise { - if (this.is_usualM(srcToken) && this.is_usd0(destToken)) { - const exchangeData = this.usualDaoCollateralIface.encodeFunctionData( - 'swap', - [srcToken, srcAmount, destAmount], - ); - - return { - needWrapNative: false, - dexFuncHasRecipient: false, - exchangeData, - targetExchange: this.config.usualDaoCollateralAddress, - returnAmountPos: undefined, - }; - } - - throw new Error('LOGIC ERROR'); - } - - async getTopPoolsForToken( - tokenAddress: Address, - limit: number, - ): Promise { - const isUsualM = this.is_usualM(tokenAddress); - if (!isUsualM && !this.is_usd0(tokenAddress)) return []; - - return [ - { - exchange: this.dexKey, - address: this.config.usualMAddress, - connectorTokens: [ - { - decimals: isUsualM ? 6 : 18, // TODO: check this one - address: isUsualM - ? this.config.usd0Address - : this.config.usualMAddress, - }, - ], - liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred - }, - ]; - } -}