import { PriceOracle , PriceOracleAsset } from '../../../generated/schema' ; import { AaveOracle , AssetSourceUpdated } from '../../../generated/AaveOracle/AaveOracle' ; import { Address , ethereum , log } from '@graphprotocol/graph-ts' ; import { formatUsdEthChainlinkPrice , getPriceOracleAssetType , PRICE_ORACLE_ASSET_TYPE_SIMPLE , zeroAddress , zeroBI , } from '../../utils/converters' ; import { IExtendedPriceAggregator } from '../../../generated/AaveOracle/IExtendedPriceAggregator' ; import { EACAggregatorProxy } from '../../../generated/AaveOracle/EACAggregatorProxy' ; import { ChainlinkAggregator as ChainlinkAggregatorContract } from '../../../generated/templates' ; import { getChainlinkAggregator , getOrInitPriceOracle , getPriceOracleAsset , } from '../../helpers/initializers' ; import { MOCK_USD_ADDRESS } from '../../utils/constants' ; import { genericPriceUpdate , usdEthPriceUpdate } from '../../helpers/price-updates' ; import { AggregatorUpdated } from '../../../generated/ChainlinkSourcesRegistry/ChainlinkSourcesRegistry' ; export { handleFallbackOracleUpdated , handleWethSet } from './proxy-price-provider' ; export function priceFeedUpdated ( event , assetAddress , assetOracleAddress , priceOracleAsset , priceOracle ) { let sAssetAddress = assetAddress . toHexString ( ) ; let proxyPriceProvider = AaveOracle . bind ( Address . fromString ( priceOracle . proxyPriceProvider . toHexString ( ) ) ) ; let priceFromOracle = zeroBI ( ) ; let priceFromProxyCall = proxyPriceProvider . try_getAssetPrice ( assetAddress ) ; if ( ! priceFromProxyCall . reverted ) { priceFromOracle = priceFromProxyCall . value ; } else { log . error ( `this asset has not been registered. || asset: {} | assetOracle: {}` , [ sAssetAddress , assetOracleAddress . toHexString ( ) , ] ) ; return ; } priceOracleAsset . isFallbackRequired = true ; if ( ! assetOracleAddress . equals ( zeroAddress ( ) ) ) { let priceAggregatorInstance = IExtendedPriceAggregator . bind ( assetOracleAddress ) ; let tokenTypeCall = priceAggregatorInstance . try_getTokenType ( ) ; if ( ! tokenTypeCall . reverted ) { priceOracleAsset . type = getPriceOracleAssetType ( tokenTypeCall . value ) ; } if ( priceOracleAsset . type == PRICE_ORACLE_ASSET_TYPE_SIMPLE ) { let chainlinkProxyInstance = EACAggregatorProxy . bind ( assetOracleAddress ) ; let aggregatorAddressCall = chainlinkProxyInstance . try_aggregator ( ) ; if ( aggregatorAddressCall . reverted ) { log . error ( `PROXY: Simple Type must be a chainlink proxy. || asset: {} | assetOracleAddress: {}` , [ sAssetAddress , assetOracleAddress . toHexString ( ) ] ) ; return ; } let aggregatorAddress = aggregatorAddressCall . value ; priceOracleAsset . priceSource = aggregatorAddress ; ChainlinkAggregatorContract . create ( aggregatorAddress ) ; let priceAggregatorlatestAnswerCall = priceAggregatorInstance . try_latestAnswer ( ) ; priceOracleAsset . isFallbackRequired = priceAggregatorlatestAnswerCall . reverted || priceAggregatorlatestAnswerCall . value . isZero ( ) ; let chainlinkAggregator = getChainlinkAggregator ( aggregatorAddress . toHexString ( ) ) ; chainlinkAggregator . oracleAsset = assetAddress . toHexString ( ) ; chainlinkAggregator . save ( ) ; } else { priceOracleAsset . isFallbackRequired = false ; priceOracleAsset . priceSource = assetOracleAddress ; let dependencies = priceAggregatorInstance . getSubTokens ( ) ; for ( let i = 0 ; i < dependencies . length ; i += 1 ) { let dependencyAddress = dependencies [ i ] . toHexString ( ) ; if ( dependencyAddress == MOCK_USD_ADDRESS ) { let usdDependentAssets = priceOracle . usdDependentAssets ; if ( ! usdDependentAssets . includes ( sAssetAddress ) ) { usdDependentAssets . push ( sAssetAddress ) ; priceOracle . usdDependentAssets = usdDependentAssets ; } } else { let dependencyOracleAsset = getPriceOracleAsset ( dependencyAddress ) ; let dependentAssets = dependencyOracleAsset . dependentAssets ; if ( ! dependentAssets . includes ( sAssetAddress ) ) { dependentAssets . push ( sAssetAddress ) ; dependencyOracleAsset . dependentAssets = dependentAssets ; dependencyOracleAsset . save ( ) ; } } } } } else { log . error ( 'registry of asset: {} | oracle: {} | price: {}' , [ assetAddress . toHexString ( ) , assetOracleAddress . toHexString ( ) , priceFromOracle . toString ( ) , ] ) ; } if ( sAssetAddress == MOCK_USD_ADDRESS ) { priceOracle . usdPriceEthFallbackRequired = priceOracleAsset . isFallbackRequired ; priceOracle . usdPriceEthMainSource = priceOracleAsset . priceSource ; usdEthPriceUpdate ( priceOracle , formatUsdEthChainlinkPrice ( priceFromOracle ) , event ) ; genericPriceUpdate ( priceOracleAsset , priceFromOracle , event ) ; } else { if ( ! assetOracleAddress . equals ( zeroAddress ( ) ) && priceOracle . tokensWithFallback . includes ( sAssetAddress ) && ! priceOracleAsset . isFallbackRequired ) { priceOracle . tokensWithFallback = priceOracle . tokensWithFallback . filter ( token => token != assetAddress . toHexString ( ) ) ; } if ( ! priceOracle . tokensWithFallback . includes ( sAssetAddress ) && ( assetOracleAddress . equals ( zeroAddress ( ) ) || priceOracleAsset . isFallbackRequired ) ) { let updatedTokensWithFallback = priceOracle . tokensWithFallback ; updatedTokensWithFallback . push ( sAssetAddress ) ; priceOracle . tokensWithFallback = updatedTokensWithFallback ; } priceOracle . save ( ) ; genericPriceUpdate ( priceOracleAsset , priceFromOracle , event ) ; } } export function handleAssetSourceUpdated ( event ) { let assetAddress = event . params . asset ; let assetOracleAddress = event . params . source ; let priceOracle = getOrInitPriceOracle ( ) ; if ( priceOracle . proxyPriceProvider . equals ( zeroAddress ( ) ) ) { priceOracle . proxyPriceProvider = event . address ; } let priceOracleAsset = getPriceOracleAsset ( assetAddress . toHexString ( ) ) ; priceOracleAsset . fromChainlinkSourcesRegistry = false ; log . error ( '1 ------------------------' , [ ] ) ; priceFeedUpdated ( event , assetAddress , assetOracleAddress , priceOracleAsset , priceOracle ) ; } export function handleChainlinkAggregatorUpdated ( event ) { let assetAddress = event . params . token ; let assetOracleAddress = event . params . aggregator ; let priceOracle = getOrInitPriceOracle ( ) ; let priceOracleAsset = getPriceOracleAsset ( assetAddress . toHexString ( ) ) ; priceOracleAsset . fromChainlinkSourcesRegistry = true ; log . error ( '2 ------------------------' , [ ] ) ; priceFeedUpdated ( event , assetAddress , assetOracleAddress , priceOracleAsset , priceOracle ) ; }