diff --git a/arb.db b/arb.db index 799ce4f91..8f0d679cf 100644 Binary files a/arb.db and b/arb.db differ diff --git a/avax.db b/avax.db index 00d856286..580f6b45a 100644 Binary files a/avax.db and b/avax.db differ diff --git a/base.db b/base.db index f274b738e..4eb593c13 100644 Binary files a/base.db and b/base.db differ diff --git a/ethereum.db b/ethereum.db index 2d890ff0d..87236c8db 100644 Binary files a/ethereum.db and b/ethereum.db differ diff --git a/linea.db b/linea.db index 9e1b45ddb..3dbbfd513 100644 Binary files a/linea.db and b/linea.db differ diff --git a/matic.db b/matic.db index ab1a20a15..8e0060fab 100644 Binary files a/matic.db and b/matic.db differ diff --git a/op.db b/op.db index 077660c5e..de246be6d 100644 Binary files a/op.db and b/op.db differ diff --git a/package.json b/package.json index 9fa9a9932..56c0ffdae 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "build:watch": "npm run build:watch -w packages/adapters-library", "adapters-cli": "node --env-file=.env packages/adapters-library/dist/scripts/index.js", "build-metadata-db": "npm run adapters-cli build-metadata-db --", + "delete-adapter-metadata": "npm run adapters-cli delete-adapter-metadata --", "check-metadata-type": "npm run adapters-cli check-metadata-type --", "check-db-totals": "npm run adapters-cli check-db-totals --", "check-bad-snapshots": "npm run adapters-cli check-bad-snapshots --", diff --git a/packages/adapters-library/src/adapters/beefy/products/cow-token/tests/snapshots/arb.positions.cow-token.json b/packages/adapters-library/src/adapters/beefy/products/cow-token/tests/snapshots/arb.positions.cow-token.json index 43872df4e..ba8d867e3 100644 --- a/packages/adapters-library/src/adapters/beefy/products/cow-token/tests/snapshots/arb.positions.cow-token.json +++ b/packages/adapters-library/src/adapters/beefy/products/cow-token/tests/snapshots/arb.positions.cow-token.json @@ -55,15 +55,15 @@ "a3e4474df9052353b8b8dbfa8e0e3a90": { "result": "0x000000000000000000000000000000000000000000000000000000000096fb63" }, - "e74c02fad89642c9c831daf768b09296": { - "result": "0x000000000000000000000000000000000000000000000000156d11ae1d6fad9e00000000000000000000000000000000000000000000000000000000c68b9cf3" - }, "c08559f21e6dae77b5e2c77c82f1e0a4": { "result": "0x00000000000000000000000000000000000000000000000000000001fcee5979" }, "a0d7c4aaf7651d65734fcd5dd2ccce94": { "result": "0x00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831" }, + "e74c02fad89642c9c831daf768b09296": { + "result": "0x000000000000000000000000000000000000000000000000156d11ae1d6fad9e00000000000000000000000000000000000000000000000000000000c68b9cf3" + }, "384c7c494bba6adf0a332dc46f3590e1": { "result": "0x0000000000000000000000000000000000000000000000010000000000096bec0000000000000000000000000000000000000000000000000000004cbdc10ca0000000000000000000000000000000000000000000000000000000006685417000000000000000000000000000000000000000000000000000000000668541700000000000000000000000000000000000000000000000010000000000096bec" }, diff --git a/packages/adapters-library/src/adapters/beefy/products/moo-token/beefyMooTokenAdapter.ts b/packages/adapters-library/src/adapters/beefy/products/moo-token/beefyMooTokenAdapter.ts index 5cfa7dbf1..73dad401e 100644 --- a/packages/adapters-library/src/adapters/beefy/products/moo-token/beefyMooTokenAdapter.ts +++ b/packages/adapters-library/src/adapters/beefy/products/moo-token/beefyMooTokenAdapter.ts @@ -23,21 +23,13 @@ import { TokenType, UnwrapExchangeRate, UnwrapInput, + UnwrappedTokenExchangeRate, } from '../../../../types/adapter' import { Erc20Metadata } from '../../../../types/erc20Metadata' import { Protocol } from '../../../protocols' -import { breakdownFetcherMap, chainIdMap, protocolMap } from '../../sdk/config' -import { - ApiClmManager, - ApiVault, - BeefyProductType, - ProtocolUnwrapType, -} from '../../sdk/types' - -type AdditionalMetadata = { - unwrapType: ProtocolUnwrapType - underlyingLPToken: Erc20Metadata -} +import { BeefyVaultV7__factory } from '../../contracts' +import { chainIdMap } from '../../sdk/config' +import { ApiClmManager, ApiVault, BeefyProductType } from '../../sdk/types' export class BeefyMooTokenAdapter implements IProtocolAdapter { productId = BeefyProductType.MOO_TOKEN @@ -82,20 +74,9 @@ export class BeefyMooTokenAdapter implements IProtocolAdapter { } @CacheToDb - async getProtocolTokens(): Promise[]> { + async getProtocolTokens(): Promise { const chain = chainIdMap[this.chainId] - const cowTokenAddresses = await fetch( - `https://api.beefy.finance/cow-vaults/${chain}`, - ) - .then((res) => res.json()) - .then((res) => - (res as ApiClmManager[]).map((r) => - r.earnedTokenAddress.toLocaleLowerCase(), - ), - ) - .then((res) => new Set(res)) - const vaults = await fetch(`https://api.beefy.finance/vaults/${chain}`) .then((res) => res.json()) .then((res) => @@ -111,86 +92,77 @@ export class BeefyMooTokenAdapter implements IProtocolAdapter { // for each vault, get the latest breakdown to get the token list return await filterMapAsync(vaults, async (vault) => { - const platformConfig = protocolMap[vault.platformId] - const protocolType = - vault.tokenAddress && - cowTokenAddresses.has(vault.tokenAddress.toLocaleLowerCase()) - ? 'beefy_clm' - : typeof platformConfig === 'string' || !platformConfig - ? platformConfig - : platformConfig[vault.strategyTypeId || 'default'] - - if (!protocolType) { - logger.debug( - { - productId: this.productId, - vaultId: vault.id, - platformId: vault.platformId, - vaultAddress: vault.earnedTokenAddress, - poolAddress: vault.tokenAddress, - strategyTypeId: vault.strategyTypeId, - chain, - }, - 'Protocol type not found', - ) - return undefined - } - - // test that we can indeed fetch the breakdown, otherwise we don't include the vault - // in the list - const [protocolToken, underlyingToken, breakdown] = await Promise.all([ - this.helpers.getTokenMetadata(vault.earnedTokenAddress), - this.helpers.getTokenMetadata(vault.tokenAddress), - breakdownFetcherMap[protocolType]( - { - protocolTokenAddress: vault.earnedTokenAddress, - underlyingLPTokenAddress: vault.tokenAddress, - blockSpec: { blockTag: undefined }, - }, - this.provider, - ), - ]) - - const breakdownTokenMetadata = await Promise.all( - breakdown.balances.map((balance) => - this.helpers.getTokenMetadata(balance.tokenAddress), - ), - ) - - return { - ...protocolToken, - underlyingTokens: breakdownTokenMetadata, - underlyingLPToken: underlyingToken, - unwrapType: protocolType, + try { + const [protocolToken, underlyingToken] = await Promise.all([ + this.helpers.getTokenMetadata(vault.earnedTokenAddress), + this.helpers.getTokenMetadata(vault.tokenAddress), + ]) + + return { + ...protocolToken, + underlyingTokens: [underlyingToken], + } + } catch (error) { + return } }) } async unwrap({ - protocolTokenAddress, blockNumber, + protocolTokenAddress, }: UnwrapInput): Promise { - const { - underlyingTokens, - unwrapType, - underlyingLPToken, - ...protocolToken - } = await this.getProtocolTokenByAddress(protocolTokenAddress) + const protocolTokenMetadata = + await this.getProtocolTokenByAddress(protocolTokenAddress) + + const underlyingTokenConversionRate = await this.unwrapProtocolToken( + protocolTokenMetadata, + blockNumber, + ) return { - ...protocolToken, + ...protocolTokenMetadata, baseRate: 1, - type: TokenType['Protocol'], - tokens: [ - { - ...underlyingLPToken, - underlyingRateRaw: BigInt(10 ** underlyingLPToken.decimals), - type: TokenType['Underlying'], - }, - ], + type: TokenType.Protocol, + tokens: underlyingTokenConversionRate, } } + protected async unwrapProtocolToken( + protocolTokenMetadata: Erc20Metadata, + blockNumber?: number | undefined, + ): Promise { + const { + underlyingTokens: [underlyingToken], + } = await this.getProtocolTokenByAddress(protocolTokenMetadata.address) + + const wstEthContract = BeefyVaultV7__factory.connect( + protocolTokenMetadata.address, + this.provider, + ) + + const pricePerShareRaw = await wstEthContract.getPricePerFullShare({ + blockTag: blockNumber, + }) + + return [ + { + ...underlyingToken!, + type: TokenType.Underlying, + underlyingRateRaw: pricePerShareRaw, + }, + ] + } + + protected async getUnderlyingTokens( + protocolTokenAddress: string, + ): Promise { + const { underlyingTokens } = + await this.getProtocolTokenByAddress(protocolTokenAddress) + + return underlyingTokens + } + async getPositions(input: GetPositionsInput): Promise { return this.helpers.getBalanceOfTokens({ ...input, @@ -237,7 +209,7 @@ export class BeefyMooTokenAdapter implements IProtocolAdapter { private async getProtocolTokenByAddress( protocolTokenAddress: string, - ): Promise> { + ): Promise { return this.helpers.getProtocolTokenByAddress({ protocolTokens: await this.getProtocolTokens(), protocolTokenAddress, diff --git a/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/ethereum.positions.moo-token.json b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/ethereum.positions.moo-token.json index 2d8189644..51267d279 100644 --- a/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/ethereum.positions.moo-token.json +++ b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/ethereum.positions.moo-token.json @@ -1,7 +1,7 @@ { - "blockNumber": 21270814, - "latency": "Latency: 2.191 seconds", - "aggregatedValues": ["USD6.84"], + "blockNumber": 21342510, + "latency": "Latency: 1.601 seconds", + "aggregatedValues": ["USD2.91"], "snapshot": [ { "protocolId": "beefy", @@ -16,140 +16,73 @@ "success": true, "tokens": [ { - "address": "0x5dA90BA82bED0AB701E6762D2bF44E08634d9776", - "name": "Moo Aura weETH/ezETH/rsETH", - "symbol": "mooAuraweETH/ezETH/rsETH", + "address": "0x4D75a9342113c106F48117d81e2952A5828d1B5F", + "name": "Moo Aura Gyro GYD-USDC", + "symbol": "mooAuraGyroGYD-USDC", "decimals": 18, - "balanceRaw": "1992424932580756n", + "balanceRaw": "5257076158446163091n", "type": "protocol", "tokens": [ { - "address": "0x848a5564158d84b8A8fb68ab5D004Fae11619A54", - "name": "Balancer weETH/ezETH/rswETH", - "symbol": "weETH/ezETH/rswETH", + "address": "0xC2AA60465BfFa1A88f5bA471a59cA0435c3ec5c1", + "name": "Gyroscope ECLP GYD/USDC", + "symbol": "ECLP-GYD-USDC", "decimals": 18, "type": "underlying", - "balanceRaw": "1992424932580756n", + "balanceRaw": "5494825011180244949n", "tokens": [ { - "address": "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110", - "name": "Renzo Restaked ETH", - "symbol": "ezETH", - "decimals": 18, - "type": "underlying", - "balanceRaw": "549060233465202n", - "tokens": [ - { - "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", - "name": "Ethereum", - "symbol": "ETH", - "decimals": 18, - "type": "underlying", - "balanceRaw": "564446160749280n", - "balance": 0.00056444616074928, - "price": 3362.61634367, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png" - } - ], - "balance": 0.000549060233465202, - "price": 3456.844567450548, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xbf5495Efe5DB9ce00f80364C8B423567e58d2110/logo.png" - }, - { - "address": "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee", - "name": "Wrapped eETH", - "symbol": "weETH", - "decimals": 18, + "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6, "type": "underlying", - "balanceRaw": "473921834355169n", - "tokens": [ - { - "address": "0x35fA164735182de50811E8e2E824cFb9B6118ac2", - "name": "ether.fi ETH", - "symbol": "eETH", - "decimals": 18, - "type": "underlying", - "balanceRaw": "499390496766600n", - "tokens": [ - { - "address": "0x0000000000000000000000000000000000000000", - "name": "Ethereum", - "symbol": "ETH", - "decimals": 18, - "type": "underlying", - "balanceRaw": "499390496766600n", - "balance": 0.0004993904967666, - "price": 3362.61634367, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png" - } - ], - "balance": 0.0004993904967666, - "price": 3362.61634367, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x35fA164735182de50811E8e2E824cFb9B6118ac2/logo.png" - } - ], - "balance": 0.000473921834355169, - "price": 3543.324077029906, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee/logo.png" + "balanceRaw": "2910432n", + "balance": 2.910432, + "price": 0.9984879963186358, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png" }, { - "address": "0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0", - "name": "rswETH", - "symbol": "rswETH", + "address": "0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A", + "name": "Gyro Dollar", + "symbol": "GYD", "decimals": 18, "type": "underlying", - "balanceRaw": "949762392785408n", - "balance": 0.000949762392785408, - "price": 3434.3820248325205, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0/logo.png" + "balanceRaw": "2599931548269010542n", + "balance": 2.5999315482690104, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A/logo.png" } ], - "balance": 0.001992424932580756, - "price": 3432.5616535744143, - "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x848a5564158d84b8A8fb68ab5D004Fae11619A54/logo.png" + "balance": 5.494825011180245, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC2AA60465BfFa1A88f5bA471a59cA0435c3ec5c1/logo.png" } ], - "balance": 0.001992424932580756 + "balance": 5.257076158446163 } ] } ], "rpcResponses": { - "cff862862aa17152ed93923842066c9a": { - "result": "0x0000000000000000000000000000000000000000000000000007141994591d94" - }, - "d683ef0e0360dc16bc66e3449549ccff": { - "result": "0x00000000000000000000000000000000000000000000000a405aa28b7d225aaa" - }, - "d67f1c128f4ebf28506b9605e245fa37": { - "result": "0x000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8" - }, - "b85d862233ca8e06dfbce73d8bd1dbac": { - "result": "0x848a5564158d84b8a8fb68ab5d004fae11619a5400000000000000000000066a" - }, - "d1dd2dc6cadfbcb3c8ca1fde95274f46": { - "result": "0x0000000000000000000000000000000000000000000000597873ba136410cca9" - }, - "e5f133f84849e01438d54c6c286b945f": { - "result": "0x000000000000000000000000000000000000000000000009f9e5316a4763988f" + "1bfa629d23b0f32e6d09e788bdd27470": { + "result": "0x00000000000000000000000000000000000000000000000048f4e2e9b55bd493" }, - "44415a67c28ea019afb5a191cbe04c95": { - "result": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001448fea0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000848a5564158d84b8a8fb68ab5d004fae11619a54000000000000000000000000bf5495efe5db9ce00f80364c8b423567e58d2110000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee000000000000000000000000fae103dc9cf190ed75350761e95403b7b8afa6c0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000080000000002326c24027875f0820000000000000000000000000000000000000000000000018a7de49a4617c299a00000000000000000000000000000000000000000000001548184575a643d6a200000000000000000000000000000000000000000000002aa63f2fda826c9bba" + "62a33e2be51d78c85b5970042dcd3fcb": { + "result": "0x0000000000000000000000000000000000000000000000000e81622e7cc2c406" }, - "e96fe24c9e4e37c32c90388bb1962f9c": { - "result": "0x00000000000000000000000000000000000080000000007c9f35fa3aeb6fd4c9" + "ceded32450a0f27bcf0de7ed943a4459": { + "result": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000145a59d0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000e07f9d810a48ab5c3c914ba3ca53af14e4491e8a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000075fa0b52ea000000000000000000000000000000000000000000005fda1df49298377f55f8" }, - "63653cab6f336e0ca092ec86f77a3480": { - "result": "0x0000000000000000000000000000000000000000000000000e9fa3250ffe7b19" + "dfd71fdf93d343cb048ef0e1b50ae702": { + "result": "0x00000000000000000000000000000000000000000000ca9414942b5696881c00" }, - "d6e653334621e4bd98aad2df3e77352d": { - "result": "0x0000000000000000000000000000000000000000000000070000000000000b530000000000000000000000000000000000000000000000000000004e4ac1593f00000000000000000000000000000000000000000000000000000000674583e500000000000000000000000000000000000000000000000000000000674584070000000000000000000000000000000000000000000000070000000000000b53" + "7dcf710f1acb5589bca7c939a2a8bcb1": { + "result": "0x0000000000000000000000000000000000000000000000070000000000000d3900000000000000000000000000000000000000000000000000000059f660f937000000000000000000000000000000000000000000000000000000006752c0f2000000000000000000000000000000000000000000000000000000006752c0ff0000000000000000000000000000000000000000000000070000000000000d39" }, - "8be7bf2e9ede0ef46c41ef9d3261ff82": { - "result": "0x0000000000000000000000000000000000000000000000000e4444d466db902d" + "39b304f4388d1e0fae86d568b5be4a5a": { + "result": "0x0000000000000000000000000000000000000000000000000000000000000000" }, - "92e6d0792deed61aa4d23b727c0ee847": { - "result": "0x0000000000000000000000000000000000000000000000000e2c8955529d22b4" + "186b7efde4b895c3e75eda93da5c047c": { + "result": "0x000000000000000000000000000000000000000000d5c207247f81108989ddcb" } } } diff --git a/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/linea.positions.eth.json b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/linea.positions.eth.json new file mode 100644 index 000000000..315dfbd74 --- /dev/null +++ b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/snapshots/linea.positions.eth.json @@ -0,0 +1,104 @@ +{ + "blockNumber": 12929711, + "latency": "Latency: 30.29 seconds", + "aggregatedValues": [], + "snapshot": [ + { + "protocolId": "beefy", + "name": "Beefy", + "description": "Beefy defi adapter", + "siteUrl": "https://beefy.com", + "iconUrl": "https://beefy.com/icons/icon-96x96.png", + "positionType": "supply", + "chainId": 59144, + "productId": "moo-token", + "chainName": "linea", + "success": true, + "tokens": [ + { + "address": "0x3289Cc896E661e3a252609efA4380875F0ce66Ec", + "name": "Moo StargateV2 WETH", + "symbol": "mooStargateV2WETH", + "decimals": 18, + "balanceRaw": "740171648608789815n", + "type": "protocol", + "tokens": [ + { + "address": "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "type": "underlying", + "balanceRaw": "742917305032686149n", + "balance": 0.7429173050326862, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/linea/assets/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/logo.png" + } + ], + "balance": 0.7401716486087898 + }, + { + "address": "0x3d80b49fc4DC9E450efAc1BD34cdEB2F303c2E81", + "name": "Moo Mendi WETH", + "symbol": "mooMendiWETH", + "decimals": 18, + "balanceRaw": "755853080356746718n", + "type": "protocol", + "tokens": [ + { + "address": "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "type": "underlying", + "balanceRaw": "798483489398881384n", + "balance": 0.7984834893988814, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/linea/assets/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/logo.png" + } + ], + "balance": 0.7558530803567467 + }, + { + "address": "0xE7e6a718218d737945E6f039c161D3C3c550CBA8", + "name": "Moo Mendi USDC", + "symbol": "mooMendiUSDC", + "decimals": 18, + "balanceRaw": "129843249n", + "type": "protocol", + "tokens": [ + { + "address": "0x176211869cA2b568f2A7D4EE941E073a821EE1ff", + "name": "USDC", + "symbol": "USDC", + "decimals": 6, + "type": "underlying", + "balanceRaw": "141472650n", + "balance": 141.47265, + "iconUrl": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/linea/assets/0x176211869cA2b568f2A7D4EE941E073a821EE1ff/logo.png" + } + ], + "balance": 1.29843249e-10 + } + ] + } + ], + "rpcResponses": { + "b2b12a54639aae7dd76fe7471a2cc60c": { + "result": "0x0000000000000000000000000000000000000000000000000a459e315c246537" + }, + "f9db193fed5278f7ad8bc389fac2008a": { + "result": "0x0000000000000000000000000000000000000000000000000000000007bd4031" + }, + "9acd2a668fe6a33daf2c2736c1e5550b": { + "result": "0x0000000000000000000000000000000000000000000000000a7d545f350c75de" + }, + "ac7955172fc59ca72de353696d781458": { + "result": "0x0000000000000000000000000000000000000000000000000f1ee9886b2fe422" + }, + "e1b88921c9f11d28e5442e8230d70a6a": { + "result": "0x0000000000000000000000000000000000000000000000000dede475af365179" + }, + "1355a89f4bd9176cf4c752525b7ace6d": { + "result": "0x0000000000000000000000000000000000000000000000000ea9168eec1ddd82" + } + } +} diff --git a/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/testCases.ts b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/testCases.ts index c4151fbb9..22cacd64d 100644 --- a/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/testCases.ts +++ b/packages/adapters-library/src/adapters/beefy/products/moo-token/tests/testCases.ts @@ -10,9 +10,26 @@ export const testCases: TestCase[] = [ input: { userAddress: '0x161D61e30284A33Ab1ed227beDcac6014877B3DE', - filterProtocolTokens: ['0x5dA90BA82bED0AB701E6762D2bF44E08634d9776'], + filterProtocolTokens: ['0x4D75a9342113c106F48117d81e2952A5828d1B5F'], }, - blockNumber: 21270814, + blockNumber: 21342510, + }, + { + chainId: Chain.Linea, + key: 'eth', + method: 'positions', + + input: { + userAddress: '0x3130d2b8cbf0798bb1cbf2a4f527dbae953ff27f', + + filterProtocolTokens: [ + '0x3289Cc896E661e3a252609efA4380875F0ce66Ec', + '0x3d80b49fc4DC9E450efAc1BD34cdEB2F303c2E81', + '0xE7e6a718218d737945E6f039c161D3C3c550CBA8', + ], + }, + + blockNumber: 12929711, }, ] diff --git a/packages/adapters-library/src/scripts/deleteAdapterMetadata.ts b/packages/adapters-library/src/scripts/deleteAdapterMetadata.ts new file mode 100644 index 000000000..0b3216f9b --- /dev/null +++ b/packages/adapters-library/src/scripts/deleteAdapterMetadata.ts @@ -0,0 +1,227 @@ +import fs from 'node:fs' +import path from 'node:path' +import Database, { Database as DatabaseType } from 'better-sqlite3' +import chalk from 'chalk' +import { Command } from 'commander' +import { Protocol } from '../adapters/protocols' +import { supportedProtocols } from '../adapters/supportedProtocols' +import { AdaptersController } from '../core/adaptersController' +import { ZERO_ADDRESS } from '../core/constants/ZERO_ADDRESS' +import { Chain, ChainIdToChainNameMap } from '../core/constants/chains' +import { ProviderMissingError } from '../core/errors/errors' +import { CustomJsonRpcProvider } from '../core/provider/CustomJsonRpcProvider' +import { filterMapSync } from '../core/utils/filters' +import { logger } from '../core/utils/logger' +import { + AdditionalMetadataWithReservedFields, + Erc20ExtendedMetadata, + IProtocolAdapter, + ProtocolToken, +} from '../types/IProtocolAdapter' +import { Erc20Metadata } from '../types/erc20Metadata' +import { getInvalidAddresses } from './addressValidation' +import { multiChainFilter, multiProtocolFilter } from './commandFilters' + +export function deleteAdapterMetadata( + program: Command, + chainProviders: Record, + adaptersController: AdaptersController, +) { + program + .command('delete-adapter-metadata') + .option( + '-p, --protocols ', + 'protocol id (e.g. stargate or aave-v2)', + ) + .option( + '-pd, --products ', + 'product id (e.g. voting-escrow or market-borrow)', + ) + .option( + '-c, --chains ', + 'chains id or name (e.g. ethereum,arbitrum,linea)', + ) + .showHelpAfterError() + .action( + async ({ + protocols, + products, + chains, + }: { protocols: string; products: string; chains: string }) => { + console.log('Starting deletion process...') + console.log('Protocols:', protocols) + console.log('Products:', products) + console.log('Chains:', chains) + + const filterProtocolIds = multiProtocolFilter(protocols)! + if ( + !protocols || + (filterProtocolIds && filterProtocolIds.length !== 1) + ) { + throw new Error('One protocol must be supplied at a time') + } + const protocolId = filterProtocolIds.pop()! + + const filterProductIds = products?.split(',') + if (!products || (filterProductIds && filterProductIds.length !== 1)) { + throw new Error('One product must be supplied at a time') + } + const productId = filterProductIds?.pop()! + + const filterChainIds = multiChainFilter(chains)! + if (!chains || (filterChainIds && filterChainIds.length !== 1)) { + throw new Error('One chain must be supplied at a time') + } + const chainId = filterChainIds.pop()! + + const db = new Database(`./${ChainIdToChainNameMap[chainId]}.db`, { + verbose: console.log, + }) + + const poolIds = await getPoolIds(db, protocolId, productId) + + // Deleting rows in underlying_tokens + checkAndDelete( + db, + ` + SELECT * FROM underlying_tokens + WHERE pool_id IN ( + ? + ) + `, + ` + DELETE FROM underlying_tokens + WHERE pool_id IN ( + ? + ) + `, + [poolIds], + ) + + // Deleting rows in reward_tokens + checkAndDelete( + db, + ` + SELECT * FROM reward_tokens + WHERE pool_id IN ( + ? + ) + `, + ` + DELETE FROM reward_tokens + WHERE pool_id IN ( + ? + ) + `, + [poolIds], + ) + + // Deleting rows in extra_reward_tokens + checkAndDelete( + db, + ` + SELECT * FROM extra_reward_tokens + WHERE pool_id IN ( + ? + ) + `, + ` + DELETE FROM extra_reward_tokens + WHERE pool_id IN ( + ? + ) + `, + [poolIds], + ) + + // Deleting rows in pools + checkAndDelete( + db, + ` + SELECT * FROM pools + WHERE pool_id IN ( + ? + ) + `, + ` + DELETE FROM pools + WHERE pool_id IN ( + ? + ) + `, + [poolIds], + ) + + // Deleting rows in tokens + checkAndDelete( + db, + ` + SELECT * FROM tokens + WHERE token_address IS NULL OR token_address IN ( + SELECT t.token_address + FROM tokens t + WHERE NOT EXISTS (SELECT 1 FROM pools WHERE pool_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM underlying_tokens WHERE token_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM reward_tokens WHERE token_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM extra_reward_tokens WHERE token_address = t.token_address) + ) + `, + ` + DELETE FROM tokens + WHERE token_address IS NULL OR token_address IN ( + SELECT t.token_address + FROM tokens t + WHERE NOT EXISTS (SELECT 1 FROM pools WHERE pool_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM underlying_tokens WHERE token_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM reward_tokens WHERE token_address = t.token_address) + AND NOT EXISTS (SELECT 1 FROM extra_reward_tokens WHERE token_address = t.token_address) + ) + `, + [], + ) + + console.log('Deletion process completed.') + + db.close() + }, + ) +} + +// Utility function to log rows to be deleted and verify after deletion +const checkAndDelete = ( + db: DatabaseType, + selectQuery: string, + deleteQuery: string, + // biome-ignore lint/suspicious/noExplicitAny: + params: any[] | [], +) => { + // Count rows before deletion + const rowsBefore = db.prepare(selectQuery).all(...params) + console.log(`Rows to be deleted (${rowsBefore.length}):`) + console.table(rowsBefore) + + // Perform the deletion + db.prepare(deleteQuery).run(...params) + + // Verify rows after deletion + const rowsAfter = db.prepare(selectQuery).all(...params) + console.log(`Rows remaining after deletion (${rowsAfter.length}):`) + console.table(rowsAfter) +} + +const getPoolIds = ( + db: DatabaseType, + protocolId: string, + productId: string, +): string[] => { + const query = ` + SELECT p.pool_id + FROM adapters a + JOIN pools p ON p.adapter_id = a.adapter_id + WHERE a.protocol_id = ? AND a.product_id = ? + ` + const rows = db.prepare(query).all(protocolId, productId) as { + pool_id: string + }[] + return rows.map((row) => row.pool_id) +} diff --git a/packages/adapters-library/src/scripts/index.ts b/packages/adapters-library/src/scripts/index.ts index b59dbb8dc..cc3852a30 100644 --- a/packages/adapters-library/src/scripts/index.ts +++ b/packages/adapters-library/src/scripts/index.ts @@ -12,6 +12,7 @@ import { buildContractTypes } from './buildTypes' import { checkBadSnapshots } from './checkBadSnapshots' import { checkDbTotals } from './checkDbTotals' import { checkMetadataType } from './checkMetadataType' +import { deleteAdapterMetadata } from './deleteAdapterMetadata' import { featureCommands } from './featureCommands' import { performance } from './performance' import { simulateTxCommand } from './simulateTxCommand' @@ -35,6 +36,8 @@ buildContractTypes(program) buildMetadataDb(program, chainProviders, adaptersController) +deleteAdapterMetadata(program, chainProviders, adaptersController) + checkDbTotals(program, chainProviders, adaptersController) buildSnapshots(program, defiProvider)