Skip to content

Commit

Permalink
Add beefy oracle for native conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
prevostc committed Dec 27, 2024
1 parent 90e6d1b commit 2a966b9
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 52 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ yarn test:lint # run prettier linter
- `"priceOracleType" : "pyth"`
- Find the pyth contract address [on pyth's documentation](https://docs.pyth.network/price-feeds/contract-addresses/evm). Put the address in `pythPriceFeedAddress`.
- Grab the `Crypto.<native>/USD` price feed ID [on pyth's documentation](https://pyth.network/developers/price-feed-ids). Put the ID in `pythPriceFeedId`.
- Use umbrella
- `"priceOracleType" : "umbrella"`
- Find the `umbrellaRegistryAddress` [on umbrella's documentation](https://umbrella-network.readme.io/docs/umb-token-contracts#contract-registry)
- Use beefy
- `"priceOracleType" : "beefy"`
- define `"beefyOracleAddress"` based [on the beefy's addressbook](https://github.com/beefyfinance/beefy-api/blob/master/packages/address-book/src/address-book/sonic/platforms/beefyfinance.ts#L34C17-L34C59)
2. Add the chain name in the Release script in [.github/workflows/Release.yml](.github/workflows/Release.yml).
3. Add the endpoint link to the [README](README.md) in alphabetical order.
4. Release the first version of the subgraph for the new network using the [./bin/release.sh](./bin/release.sh) script.
Expand Down
2 changes: 1 addition & 1 deletion config/sonic.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"wrappedNativeAddress": "0x039e2fb66102314ce7b64ce5ce3e5183bc94ad38",
"wrappedNativeDecimals": 18,

"priceOracleType": "pyth",
"priceOracleType": "beefy",
"chainlinkNativePriceFeedAddress": "0x0000000000000000000000000000000000000000",
"chainlinkNativePriceFeedDecimals": 8,
"pythPriceFeedAddress": "0x2880ab155794e7179c9ee2e38200202908c17b43",
Expand Down
62 changes: 34 additions & 28 deletions src/classic/utils/classic-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,30 @@ export function fetchClassicData(classic: Classic): ClassicData {
calls.push(new Multicall3Params(rewardPoolTokenAddress, "totalSupply()", "uint256"))
}

const tokensToRefresh = new Array<Address>()
tokensToRefresh.push(WNATIVE_TOKEN_ADDRESS)
for (let i = 0; i < boostRewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(boostRewardTokenAddresses[i]))
}
for (let i = 0; i < rewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(rewardTokenAddresses[i]))
}
for (let i = 0; i < underlyingBreakdownTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(underlyingBreakdownTokenAddresses[i]))
}
if (clm) {
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken0))
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken1))
}

for (let i = 0; i < tokensToRefresh.length; i++) {
calls.push(
new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [
ethereum.Value.fromAddress(tokensToRefresh[i]),
]),
)
}

if (PRICE_ORACLE_TYPE == "chainlink") {
calls.push(
new Multicall3Params(
Expand All @@ -78,7 +102,6 @@ export function fetchClassicData(classic: Classic): ClassicData {
)
} else if (PRICE_ORACLE_TYPE === "umbrella") {
// get the price feeds contract address

const res = multicall([
new Multicall3Params(UMBRELLA_REGISTRY_ADDRESS, "getAddress(bytes32)", "address", [
ethereum.Value.fromFixedBytes(UMBRELLA_REGISTRY_FEED_KEY_BYTES_32),
Expand All @@ -97,33 +120,15 @@ export function fetchClassicData(classic: Classic): ClassicData {
ethereum.Value.fromFixedBytes(UMBRELLA_REGISTRY_PRICE_FEED_NAME_BYTES_32),
]),
)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
}

const tokensToRefresh = new Array<Address>()
tokensToRefresh.push(WNATIVE_TOKEN_ADDRESS)
for (let i = 0; i < boostRewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(boostRewardTokenAddresses[i]))
}
for (let i = 0; i < rewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(rewardTokenAddresses[i]))
}
for (let i = 0; i < underlyingBreakdownTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(underlyingBreakdownTokenAddresses[i]))
}
if (clm) {
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken0))
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken1))
}

for (let i = 0; i < tokensToRefresh.length; i++) {
} else if (PRICE_ORACLE_TYPE === "beefy") {
calls.push(
new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [
ethereum.Value.fromAddress(tokensToRefresh[i]),
new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getPrice(address)", "uint256", [
ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS),
]),
)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
}

for (let i = 0; i < boostRewardTokenAddresses.length; i++) {
Expand Down Expand Up @@ -186,10 +191,8 @@ export function fetchClassicData(classic: Classic): ClassicData {
for (let i = 0; i < rewardPoolTokenAddresses.length; i++) {
rewardPoolsTotalSupplyRes.push(results[idx++])
}
idx = idx + tokensToRefresh.length
const priceFeedRes = results[idx++]
for (let i = 0; i < tokensToRefresh.length; i++) {
idx++
}
const boostRewardTokenOutputAmountsRes = new Array<MulticallResult>()
for (let i = 0; i < boostRewardTokenAddresses.length; i++) {
boostRewardTokenOutputAmountsRes.push(results[idx++])
Expand Down Expand Up @@ -238,6 +241,9 @@ export function fetchClassicData(classic: Classic): ClassicData {
const umbrellaAnswer = priceFeedRes.value.toTuple()
const value = umbrellaAnswer[3].toBigInt()
nativeToUSDPrice = changeValueEncoding(value, UMBRELLA_REGISTRY_PRICE_FEED_DECIMALS, PRICE_STORE_DECIMALS_USD)
} else if (PRICE_ORACLE_TYPE === "beefy") {
const beefyAnswer = priceFeedRes.value.toBigInt()
nativeToUSDPrice = changeValueEncoding(beefyAnswer, WNATIVE_DECIMALS, PRICE_STORE_DECIMALS_USD)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
Expand Down
53 changes: 30 additions & 23 deletions src/clm/utils/clm-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ export function fetchCLMData(clm: CLM): CLMData {
calls.push(new Multicall3Params(rewardPoolTokenAddress, "totalSupply()", "uint256"))
}

// warm up beefy swapper oracle
const tokensToRefresh = new Array<Address>()
tokensToRefresh.push(WNATIVE_TOKEN_ADDRESS)
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken0))
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken1))
for (let i = 0; i < outputTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(outputTokenAddresses[i]))
}
for (let i = 0; i < rewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(rewardTokenAddresses[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(tokenAddress),
]),
)
}

// wnative price to usd
if (PRICE_ORACLE_TYPE == "chainlink") {
calls.push(
Expand Down Expand Up @@ -81,29 +101,15 @@ export function fetchCLMData(clm: CLM): CLMData {
ethereum.Value.fromFixedBytes(UMBRELLA_REGISTRY_PRICE_FEED_NAME_BYTES_32),
]),
)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
}

// warm up beefy swapper oracle
const tokensToRefresh = new Array<Address>()
tokensToRefresh.push(WNATIVE_TOKEN_ADDRESS)
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken0))
tokensToRefresh.push(Address.fromBytes(clm.underlyingToken1))
for (let i = 0; i < outputTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(outputTokenAddresses[i]))
}
for (let i = 0; i < rewardTokenAddresses.length; i++) {
tokensToRefresh.push(Address.fromBytes(rewardTokenAddresses[i]))
}
for (let i = 0; i < tokensToRefresh.length; i++) {
const tokenAddress = tokensToRefresh[i]
} else if (PRICE_ORACLE_TYPE === "beefy") {
calls.push(
new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getFreshPrice(address)", "(uint256,bool)", [
ethereum.Value.fromAddress(tokenAddress),
new Multicall3Params(BEEFY_ORACLE_ADDRESS, "getPrice(address)", "uint256", [
ethereum.Value.fromAddress(WNATIVE_TOKEN_ADDRESS),
]),
)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
}

// underlying token 0/1 prices
Expand Down Expand Up @@ -162,10 +168,8 @@ export function fetchCLMData(clm: CLM): CLMData {
for (let i = 0; i < rewardPoolTokenAddresses.length; i++) {
rewardPoolsTotalSupplyRes.push(results[idx++])
}
idx = idx + tokensToRefresh.length
const priceFeedRes = results[idx++]
for (let i = 0; i < tokensToRefresh.length; i++) {
idx++
}
const token0ToNativePriceRes = results[idx++]
const token1ToNativePriceRes = results[idx++]
const rewardTokenOutputAmountsRes = new Array<MulticallResult>()
Expand Down Expand Up @@ -283,6 +287,9 @@ export function fetchCLMData(clm: CLM): CLMData {
const value = umbrellaAnswer[3].toBigInt()

nativeToUSDPrice = changeValueEncoding(value, UMBRELLA_REGISTRY_PRICE_FEED_DECIMALS, PRICE_STORE_DECIMALS_USD)
} else if (PRICE_ORACLE_TYPE === "beefy") {
const beefyAnswer = priceFeedRes.value.toBigInt()
nativeToUSDPrice = changeValueEncoding(beefyAnswer, WNATIVE_DECIMALS, PRICE_STORE_DECIMALS_USD)
} else {
log.error("Unsupported price oracle type {}", [PRICE_ORACLE_TYPE])
throw new Error("Unsupported price oracle type")
Expand Down

0 comments on commit 2a966b9

Please sign in to comment.