From 1321417dd4bffe2dc54af2b5f445261febf56914 Mon Sep 17 00:00:00 2001 From: ChouAndy Date: Thu, 14 Dec 2023 18:32:48 +0800 Subject: [PATCH] feat: lending sdk lending protocols config test --- .eslintrc.js | 1 + .../src/protocols/aave-v2/config.test.ts | 30 ++++++++++++ .../src/protocols/aave-v3/config.test.ts | 48 +++++++++++++++++++ .../lending/src/protocols/aave-v3/configs.ts | 2 +- .../aave-v3/tokens/data/arbitrum.json | 15 ++++-- .../src/protocols/compound-v3/config.test.ts | 34 +++++++++++++ .../src/protocols/compound-v3/configs.ts | 4 +- .../src/protocols/radiant-v2/config.test.ts | 29 +++++++++++ 8 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 packages/lending/src/protocols/aave-v2/config.test.ts create mode 100644 packages/lending/src/protocols/aave-v3/config.test.ts create mode 100644 packages/lending/src/protocols/compound-v3/config.test.ts create mode 100644 packages/lending/src/protocols/radiant-v2/config.test.ts diff --git a/.eslintrc.js b/.eslintrc.js index d56c4990..bc4b5f82 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,6 +4,7 @@ module.exports = { 'max-len': ['error', { code: 120, ignoreUrls: true, ignoreStrings: true, ignorePattern: 'class [a-zA-Z]+' }], '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-unused-vars': [ 'warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }, diff --git a/packages/lending/src/protocols/aave-v2/config.test.ts b/packages/lending/src/protocols/aave-v2/config.test.ts new file mode 100644 index 00000000..118d3794 --- /dev/null +++ b/packages/lending/src/protocols/aave-v2/config.test.ts @@ -0,0 +1,30 @@ +import { ProtocolDataProvider__factory } from './contracts'; +import * as common from '@protocolink/common'; +import { configs } from './configs'; +import { expect } from 'chai'; + +describe('check configs', function () { + for (const { chainId, contractMap, reserves } of configs) { + it(`${common.toNetworkId(chainId)}`, async () => { + const iface = ProtocolDataProvider__factory.createInterface(); + const calls: common.Multicall3.CallStruct[] = reserves.map(({ asset }) => ({ + target: contractMap.ProtocolDataProvider, + callData: iface.encodeFunctionData('getReserveTokensAddresses', [asset.wrapped.address]), + })); + + const web3Toolkit = new common.Web3Toolkit(chainId); + const { returnData } = await web3Toolkit.multicall3.callStatic.aggregate(calls); + for (let i = 0; i < reserves.length; i++) { + const reserve = reserves[i]; + const [aTokenAddress, stableDebtTokenAddress, variableDebtTokenAddress] = iface.decodeFunctionResult( + 'getReserveTokensAddresses', + returnData[i] + ); + + expect(aTokenAddress).to.eq(reserve.aToken.address); + expect(stableDebtTokenAddress).to.eq(reserve.stableDebtTokenAddress); + expect(variableDebtTokenAddress).to.eq(reserve.variableDebtTokenAddress); + } + }); + } +}); diff --git a/packages/lending/src/protocols/aave-v3/config.test.ts b/packages/lending/src/protocols/aave-v3/config.test.ts new file mode 100644 index 00000000..42534fc6 --- /dev/null +++ b/packages/lending/src/protocols/aave-v3/config.test.ts @@ -0,0 +1,48 @@ +import { PoolDataProvider__factory } from './contracts'; +import * as common from '@protocolink/common'; +import { configs } from './configs'; +import { expect } from 'chai'; + +describe('check configs', function () { + for (const { chainId, contractMap, reserves } of configs) { + it(`${common.toNetworkId(chainId)}`, async () => { + const iface = PoolDataProvider__factory.createInterface(); + const calls: common.Multicall3.CallStruct[] = []; + for (const { asset } of reserves) { + calls.push({ + target: contractMap.PoolDataProvider, + callData: iface.encodeFunctionData('getReserveTokensAddresses', [asset.wrapped.address]), + }); + if (!asset.isNative) { + calls.push({ + target: contractMap.PoolDataProvider, + callData: iface.encodeFunctionData('getFlashLoanEnabled', [asset.address]), + }); + } + } + + const web3Toolkit = new common.Web3Toolkit(chainId); + const { returnData } = await web3Toolkit.multicall3.callStatic.aggregate(calls); + + let j = 0; + for (const reserve of reserves) { + const [aTokenAddress, stableDebtTokenAddress, variableDebtTokenAddress] = iface.decodeFunctionResult( + 'getReserveTokensAddresses', + returnData[j] + ); + expect(aTokenAddress).to.eq(reserve.aToken.address); + expect(stableDebtTokenAddress).to.eq(reserve.stableDebtTokenAddress); + expect(variableDebtTokenAddress).to.eq(reserve.variableDebtTokenAddress); + j++; + + if (!reserve.asset.isNative) { + const [flashLoanEnabled] = iface.decodeFunctionResult('getFlashLoanEnabled', returnData[j]); + if (flashLoanEnabled) { + expect(reserve.used.flashLoan).to.be.true; + } + j++; + } + } + }); + } +}); diff --git a/packages/lending/src/protocols/aave-v3/configs.ts b/packages/lending/src/protocols/aave-v3/configs.ts index 3c59f021..f4d3be73 100644 --- a/packages/lending/src/protocols/aave-v3/configs.ts +++ b/packages/lending/src/protocols/aave-v3/configs.ts @@ -371,7 +371,7 @@ export const configs: Config[] = [ used: { deposit: true, withdraw: true, borrow: true, repay: true, flashLoan: true }, }, { - asset: arbitrumTokens.USDC, // USDC.e + asset: arbitrumTokens['USDC.e'], aToken: arbitrumTokens.aArbUSDC, stableDebtTokenAddress: '0x307ffe186F84a3bc2613D1eA417A5737D69A7007', variableDebtTokenAddress: '0xFCCf3cAbbe80101232d343252614b6A3eE81C989', diff --git a/packages/lending/src/protocols/aave-v3/tokens/data/arbitrum.json b/packages/lending/src/protocols/aave-v3/tokens/data/arbitrum.json index f368f20d..0f8afd37 100644 --- a/packages/lending/src/protocols/aave-v3/tokens/data/arbitrum.json +++ b/packages/lending/src/protocols/aave-v3/tokens/data/arbitrum.json @@ -27,12 +27,12 @@ "symbol": "aArbLINK", "name": "Aave Arbitrum LINK" }, - "USDC": { + "USDC.e": { "chainId": 42161, - "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + "address": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", "decimals": 6, - "symbol": "USDC", - "name": "USD Coin" + "symbol": "USDC.e", + "name": "USD Coin (Arb1)" }, "aArbUSDC": { "chainId": 42161, @@ -160,6 +160,13 @@ "symbol": "aArbLUSD", "name": "Aave Arbitrum LUSD" }, + "USDC": { + "chainId": 42161, + "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + "decimals": 6, + "symbol": "USDC", + "name": "USD Coin" + }, "aArbUSDCn": { "chainId": 42161, "address": "0x724dc807b04555b71ed48a6896b6F41593b8C637", diff --git a/packages/lending/src/protocols/compound-v3/config.test.ts b/packages/lending/src/protocols/compound-v3/config.test.ts new file mode 100644 index 00000000..744b9745 --- /dev/null +++ b/packages/lending/src/protocols/compound-v3/config.test.ts @@ -0,0 +1,34 @@ +import { Comet__factory } from './contracts'; +import * as common from '@protocolink/common'; +import { configs } from './configs'; +import { expect } from 'chai'; + +describe('check configs', function () { + for (const { chainId, markets } of configs) { + for (const market of markets) { + it(`${common.toNetworkId(chainId)}: ${market.baseToken.symbol}`, async () => { + const iface = Comet__factory.createInterface(); + const web3Toolkit = new common.Web3Toolkit(chainId); + + const calls: common.Multicall3.CallStruct[] = [ + { + target: market.cometAddress, + callData: iface.encodeFunctionData('baseToken'), + }, + { + target: market.cometAddress, + callData: iface.encodeFunctionData('baseTokenPriceFeed'), + }, + ]; + + const { returnData } = await web3Toolkit.multicall3.callStatic.aggregate(calls); + + const [baseTokenAddress] = iface.decodeFunctionResult('baseToken', returnData[0]); + expect(baseTokenAddress).to.eq(market.baseToken.address); + + const [baseTokenPriceFeedAddress] = iface.decodeFunctionResult('baseTokenPriceFeed', returnData[1]); + expect(baseTokenPriceFeedAddress).to.eq(market.baseTokenPriceFeedAddress); + }); + } + } +}); diff --git a/packages/lending/src/protocols/compound-v3/configs.ts b/packages/lending/src/protocols/compound-v3/configs.ts index 6e6c5163..82e238f7 100644 --- a/packages/lending/src/protocols/compound-v3/configs.ts +++ b/packages/lending/src/protocols/compound-v3/configs.ts @@ -58,7 +58,7 @@ export const configs: Config[] = [ { cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', baseToken: polygonTokens.USDC, - baseTokenPriceFeedAddress: '0xfe4a8cc5b5b2366c1b58bea3858e81843581b2f7', + baseTokenPriceFeedAddress: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7', }, ], }, @@ -68,7 +68,7 @@ export const configs: Config[] = [ { cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', baseToken: arbitrumTokens.USDC, // USDC.e - baseTokenPriceFeedAddress: '0x50834f3163758fcc1df9973b6e91f0f0f0434ad3', + baseTokenPriceFeedAddress: '0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3', }, ], }, diff --git a/packages/lending/src/protocols/radiant-v2/config.test.ts b/packages/lending/src/protocols/radiant-v2/config.test.ts new file mode 100644 index 00000000..abc88c44 --- /dev/null +++ b/packages/lending/src/protocols/radiant-v2/config.test.ts @@ -0,0 +1,29 @@ +import { ProtocolDataProvider__factory } from './contracts'; +import * as common from '@protocolink/common'; +import { configs } from './configs'; +import { expect } from 'chai'; + +describe('check configs', function () { + for (const { chainId, contractMap, reserves } of configs) { + it(`${common.toNetworkId(chainId)}`, async () => { + const iface = ProtocolDataProvider__factory.createInterface(); + const calls: common.Multicall3.CallStruct[] = reserves.map(({ asset }) => ({ + target: contractMap.ProtocolDataProvider, + callData: iface.encodeFunctionData('getReserveTokensAddresses', [asset.wrapped.address]), + })); + + const web3Toolkit = new common.Web3Toolkit(chainId); + const { returnData } = await web3Toolkit.multicall3.callStatic.aggregate(calls); + for (let i = 0; i < reserves.length; i++) { + const reserve = reserves[i]; + const { rTokenAddress, variableDebtTokenAddress } = iface.decodeFunctionResult( + 'getReserveTokensAddresses', + returnData[i] + ); + + expect(rTokenAddress).to.eq(reserve.rToken.address); + expect(variableDebtTokenAddress).to.eq(reserve.variableDebtTokenAddress); + } + }); + } +});