From efc958d58692b563db46b0004a9f4e16984ebeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pr=C3=A9vost?= <998369+prevostc@users.noreply.github.com> Date: Sat, 29 Jun 2024 10:21:44 +0200 Subject: [PATCH] Use beefy swapper for all token prices to native --- README.md | 2 - config/optimism-tmp.json | 31 ---------- config/optimism.json | 4 +- package.json | 1 - src/clm/utils/clm-data.ts | 118 ++++++++++++++++++++++---------------- src/config.template.ts | 2 +- 6 files changed, 71 insertions(+), 87 deletions(-) delete mode 100644 config/optimism-tmp.json diff --git a/README.md b/README.md index c8264b5..b10cc13 100644 --- a/README.md +++ b/README.md @@ -190,8 +190,6 @@ yarn test:lint # run prettier linter - clmStrategy.range() - clmStrategy.output() // optional - clmStrategy.balanceOfPool() -- clmStrategy.lpToken1ToNativePrice() -- clmStrategy.lpToken0ToNativePrice() - clmStrategy: Initialized(uint8) - clmStrategy: Paused(address) - clmStrategy: Unpaused(address) diff --git a/config/optimism-tmp.json b/config/optimism-tmp.json deleted file mode 100644 index 1b80432..0000000 --- a/config/optimism-tmp.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "network": "optimism", - - "multicall3Address": "0xcA11bde05977b3631167028862bE2a173976CA11", - "shareTokenMintAddress": "0x0000000000000000000000000000000000000000", - "burnAddress": "0x000000000000000000000000000000000000dead", - - "clmManagerFactoryAddress": "0xf14e1bd3315CfADE440Ba29B3cF62CBc811F9DEd", - "clmManagerFactoryStartBlock": 121087159, - "clmStrategyFactoryAddress": "0x919DF115ef9cA36DD8D5F5aFC81a9f0267CD905C", - "clmStrategyFactoryStartBlock": 121087169, - "rewardPoolFactoryAddress": "0xdb1f80B4ea250e3e6CAaB28f9e2C92A035157560", - "rewardPoolFactoryStartBlock": 121087164, - "beefyClassicVaultFactoryAddress": "0xA6D3769faC465FC0415e7E9F16dcdC96B83C240B", - "beefyClassicVaultFactoryStartBlock": 121087159, - "beefyClassicBoostFactoryAddress": "0xf0a7626eccbee00af144bb1f77cd187af85bbf41", - "beefyClassicBoostFactoryStartBlock": 121087159, - "clockTickBlocks": 250, - - "wrappedNativeAddress": "0x4200000000000000000000000000000000000006", - "wrappedNativeDecimals": 18, - - "priceOracleType": "chainlink", - "chainlinkNativePriceFeedAddress": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", - "chainlinkNativePriceFeedDecimals": 8, - "pythPriceFeedAddress": "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - "pythNativePriceId": "0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", - - "beefySwapperAddress": "0xe115b50c52cB5624fD76232cDF498ADA6ECD1e69", - "beefyOracleAddress": "0x7066606233Cc8b5ede0925003F8910FF7B15219C" -} diff --git a/config/optimism.json b/config/optimism.json index 051f2e1..0822e2d 100644 --- a/config/optimism.json +++ b/config/optimism.json @@ -11,8 +11,8 @@ "clmStrategyFactoryStartBlock": 121125469, "rewardPoolFactoryAddress": "0x4399457CB360fC37242d2BE326579Caf3981c769", "rewardPoolFactoryStartBlock": 121125461, - "beefyClassicVaultFactoryAddress": "0xf14e1bd3315CfADE440Ba29B3cF62CBc811F9DEd", - "beefyClassicVaultFactoryStartBlock": 121125456, + "beefyClassicVaultFactoryAddress": "0xA6D3769faC465FC0415e7E9F16dcdC96B83C240B", + "beefyClassicVaultFactoryStartBlock": 121101589, "beefyClassicBoostFactoryAddress": "0xf0a7626eccbee00af144bb1f77cd187af85bbf41", "beefyClassicBoostFactoryStartBlock": 121125456, "clockTickBlocks": 250, diff --git a/package.json b/package.json index 6f8a062..97143db 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "prepare:linea": "./bin/prepare.sh linea", "prepare:manta": "./bin/prepare.sh manta", "prepare:moonbeam": "./bin/prepare.sh moonbeam", - "prepare:optimism-tmp": "./bin/prepare.sh optimism-tmp", "prepare:optimism": "./bin/prepare.sh optimism", "prepare:polygon": "./bin/prepare.sh polygon", "prepare:zksync": "./bin/prepare.sh zksync" diff --git a/src/clm/utils/clm-data.ts b/src/clm/utils/clm-data.ts index 8defd59..8639bf2 100644 --- a/src/clm/utils/clm-data.ts +++ b/src/clm/utils/clm-data.ts @@ -12,6 +12,7 @@ import { PYTH_PRICE_FEED_ADDRESS, PYTH_NATIVE_PRICE_ID, PRICE_ORACLE_TYPE, + WNATIVE_DECIMALS, } from "../../config" import { Multicall3Params, MulticallResult, multicall } from "../../common/utils/multicall" import { getToken, isNullToken } from "../../common/entity/token" @@ -23,8 +24,10 @@ export function fetchCLMData(clm: CLM): CLMData { const strategyAddress = clm.strategy const rewardPoolAddress = clm.rewardPoolToken - const token1 = getToken(clm.underlyingToken0) + const token0 = getToken(clm.underlyingToken0) + const token1 = getToken(clm.underlyingToken1) const rewardPoolToken = getToken(clm.rewardPoolToken) + const hasRewardPool = !isNullToken(rewardPoolToken) const calls = [ new Multicall3Params(managerAddress, "totalSupply()", "uint256"), @@ -32,10 +35,10 @@ export function fetchCLMData(clm: CLM): CLMData { new Multicall3Params(strategyAddress, "balancesOfPool()", "(uint256,uint256,uint256,uint256,uint256,uint256)"), new Multicall3Params(strategyAddress, "price()", "uint256"), new Multicall3Params(strategyAddress, "range()", "(uint256,uint256)"), - new Multicall3Params(strategyAddress, "lpToken0ToNativePrice()", "uint256"), - new Multicall3Params(strategyAddress, "lpToken1ToNativePrice()", "uint256"), + new Multicall3Params(rewardPoolAddress, "totalSupply()", "uint256"), ] + // wnative price to usd if (PRICE_ORACLE_TYPE == "chainlink") { calls.push( new Multicall3Params( @@ -55,51 +58,62 @@ export function fetchCLMData(clm: CLM): CLMData { throw new Error("Unsupported price oracle type") } - const hasRewardPool = !isNullToken(rewardPoolToken) - const rewardTokens = clm.rewardTokens - let rewardCallStartIndex = calls.length - if (hasRewardPool) { - calls.push(new Multicall3Params(rewardPoolAddress, "totalSupply()", "uint256")) + // warm up beefy swapper oracle + const tokensToRefresh = new Array
() + tokensToRefresh.push(WNATIVE_TOKEN_ADDRESS) + tokensToRefresh.push(Address.fromBytes(clm.underlyingToken0)) + tokensToRefresh.push(Address.fromBytes(clm.underlyingToken1)) + for (let i = 0; i < clm.outputTokens.length; i++) { + tokensToRefresh.push(Address.fromBytes(clm.outputTokens[i])) + } + for (let i = 0; i < clm.rewardTokens.length; i++) { + tokensToRefresh.push(Address.fromBytes(clm.rewardTokens[i])) + } + for (let i = 0; i < tokensToRefresh.length; i++) { + const tokenAddress = tokensToRefresh[i] calls.push( new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [ - ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS), + ethereum.Value.fromAddress(tokenAddress), ]), ) - - rewardCallStartIndex = calls.length // ignore the first two calls, those just warm up the prices - for (let i = 0; i < rewardTokens.length; i++) { - const rewardTokenAddress = Address.fromBytes(rewardTokens[i]) - const rewardToken = getToken(rewardTokenAddress) - calls.push( - new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [ - ethereum.Value.fromAddress(rewardTokenAddress), - ]), - ) - - const amountIn = changeValueEncoding(ONE_BI, ZERO_BI, rewardToken.decimals).div(BEEFY_SWAPPER_VALUE_SCALER) - calls.push( - new Multicall3Params(BEEFY_SWAPPER_ADDRESS, "getAmountOut(address,address,uint256)", "uint256", [ - ethereum.Value.fromAddress(rewardTokenAddress), - ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS), - ethereum.Value.fromUnsignedBigInt(amountIn), - ]), - ) - } } - const rewardCallsEndIndex = calls.length - const outputCallsStartIndex = calls.length - const outputTokens = clm.outputTokens - for (let i = 0; i < outputTokens.length; i++) { - const outputTokenAddress = Address.fromBytes(outputTokens[i]) + // underlying token 0/1 prices + const amount0In = changeValueEncoding(ONE_BI, ZERO_BI, token0.decimals).div(BEEFY_SWAPPER_VALUE_SCALER) + calls.push( + new Multicall3Params(BEEFY_SWAPPER_ADDRESS, "getAmountOut(address,address,uint256)", "uint256", [ + ethereum.Value.fromAddress(Address.fromBytes(clm.underlyingToken0)), + ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS), + ethereum.Value.fromUnsignedBigInt(amount0In), + ]), + ) + const amount1In = changeValueEncoding(ONE_BI, ZERO_BI, token1.decimals).div(BEEFY_SWAPPER_VALUE_SCALER) + calls.push( + new Multicall3Params(BEEFY_SWAPPER_ADDRESS, "getAmountOut(address,address,uint256)", "uint256", [ + ethereum.Value.fromAddress(Address.fromBytes(clm.underlyingToken1)), + ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS), + ethereum.Value.fromUnsignedBigInt(amount1In), + ]), + ) + const rewardTokens = clm.rewardTokens + for (let i = 0; i < rewardTokens.length; i++) { + const rewardTokenAddress = Address.fromBytes(rewardTokens[i]) + const rewardToken = getToken(rewardTokenAddress) + const amountIn = changeValueEncoding(ONE_BI, ZERO_BI, rewardToken.decimals).div(BEEFY_SWAPPER_VALUE_SCALER) calls.push( - new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [ - ethereum.Value.fromAddress(outputTokenAddress), + new Multicall3Params(BEEFY_SWAPPER_ADDRESS, "getAmountOut(address,address,uint256)", "uint256", [ + ethereum.Value.fromAddress(rewardTokenAddress), + ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS), + ethereum.Value.fromUnsignedBigInt(amountIn), ]), ) + } - const amountIn = changeValueEncoding(ONE_BI, ZERO_BI, token1.decimals).div(BEEFY_SWAPPER_VALUE_SCALER) + const outputTokens = clm.outputTokens + for (let i = 0; i < outputTokens.length; i++) { + const outputTokenAddress = Address.fromBytes(outputTokens[i]) + const amountIn = changeValueEncoding(ONE_BI, ZERO_BI, WNATIVE_DECIMALS).div(BEEFY_SWAPPER_VALUE_SCALER) calls.push( new Multicall3Params(BEEFY_SWAPPER_ADDRESS, "getAmountOut(address,address,uint256)", "uint256", [ ethereum.Value.fromAddress(outputTokenAddress), @@ -108,29 +122,33 @@ export function fetchCLMData(clm: CLM): CLMData { ]), ) } - const outputCallsEndIndex = calls.length + // map multicall indices to variables const results = multicall(calls) const totalSupplyRes = results[0] const balanceRes = results[1] const balanceOfPoolRes = results[2] const priceRes = results[3] const rangeRes = results[4] - const token0ToNativePriceRes = results[5] - const token1ToNativePriceRes = results[6] - const priceFeedRes = results[7] - const rewardPoolTotalSupplyRes = hasRewardPool ? results[8] : null + const rewardPoolTotalSupplyRes = results[5] + const priceFeedRes = results[6] + let idxAfterRefresh = 6 + tokensToRefresh.length + const token0ToNativePriceRes = results[idxAfterRefresh + 1] + const token1ToNativePriceRes = results[idxAfterRefresh + 2] const rewardTokenOutputAmountsRes = new Array