import { log , ethereum , Address } from '@graphprotocol/graph-ts' ; import { IERC20Detailed } from '../../generated/OracleAnchor/IERC20Detailed' ; import { EACAggregatorProxy } from '../../generated/OracleAnchor/EACAggregatorProxy' ; import { IExtendedPriceAggregator } from '../../generated/OracleAnchor/IExtendedPriceAggregator' ; import { AssetSourceUpdated , OracleSystemMigrated , } from '../../generated/OracleAnchor/OracleAnchor' ; import { PriceOracle , PriceOracleAsset } from '../../generated/schema' ; import { getChainlinkAggregator , getOrInitENS , getOrInitPriceOracle , getPriceOracleAsset , } from '../helpers/initializers' ; import { genericPriceUpdate , usdEthPriceUpdate } from '../helpers/price-updates' ; import { MOCK_USD_ADDRESS } from '../utils/constants' ; import { convertToLowerCase , formatUsdEthChainlinkPrice , generateSymbol , namehash , zeroAddress , zeroBI , } from '../utils/converters' ; import { ChainlinkAggregator as ChainlinkAggregatorContract } from '../../generated/templates' ; export function priceFeedUpdated ( event , assetAddress , assetOracleAddress , priceOracleAsset , priceOracle ) { let sAssetAddress = assetAddress . toHexString ( ) ; if ( ! assetOracleAddress . equals ( zeroAddress ( ) ) ) { let chainlinkProxyInstance = EACAggregatorProxy . bind ( assetOracleAddress ) ; let aggregatorAddressCall = chainlinkProxyInstance . try_aggregator ( ) ; if ( aggregatorAddressCall . reverted ) { log . error ( `ANCHOR: Simple Type must be a chainlink proxy. || asset: {} | assetOracleAddress: {}` , [ sAssetAddress , assetOracleAddress . toHexString ( ) ] ) ; return ; } let aggregatorAddress = aggregatorAddressCall . value ; priceOracleAsset . priceSource = aggregatorAddress ; ChainlinkAggregatorContract . create ( aggregatorAddress ) ; let symbol = '' ; let descriptionCall = chainlinkProxyInstance . try_description ( ) ; if ( descriptionCall . reverted ) { log . warning ( 'No description in proxy: {} for asset: {}' , [ assetOracleAddress . toHexString ( ) , assetAddress . toHexString ( ) , ] ) ; return ; } let description = descriptionCall . value ; symbol = generateSymbol ( description ) ; log . warning ( `description: {} || symbol: {}` , [ description , symbol ] ) ; let domain = [ 'aggregator' , symbol , 'data' , 'eth' ] ; let node = namehash ( domain ) ; let ens = getOrInitENS ( node ) ; ens . aggregatorAddress = aggregatorAddress ; ens . underlyingAddress = assetAddress ; ens . symbol = symbol ; ens . save ( ) ; let priceAggregatorInstance = IExtendedPriceAggregator . bind ( assetOracleAddress ) ; let priceAggregatorlatestAnswerCall = priceAggregatorInstance . try_latestAnswer ( ) ; priceOracleAsset . isFallbackRequired = priceAggregatorlatestAnswerCall . reverted || priceAggregatorlatestAnswerCall . value . isZero ( ) ; let priceFromOracle = priceAggregatorlatestAnswerCall . value || zeroBI ( ) ; let chainlinkAggregator = getChainlinkAggregator ( aggregatorAddress . toHexString ( ) ) ; chainlinkAggregator . oracleAsset = assetAddress . toHexString ( ) ; chainlinkAggregator . save ( ) ; 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 handleOracleSystemMigrated ( event ) { let priceOracle = getOrInitPriceOracle ( ) ; priceOracle . version = 2 ; priceOracle . save ( ) ; } export function handleAssetSourceUpdatedAnchor ( event ) { let assetAddress = event . params . token ; let sAssetAddress = assetAddress . toHexString ( ) ; let assetOracleAddress = event . params . source ; if ( sAssetAddress . split ( '0' ) . length > 38 ) { log . warning ( 'skipping wrong asset registration {}' , [ sAssetAddress ] ) ; return ; } let priceOracle = getOrInitPriceOracle ( ) ; if ( priceOracle . proxyPriceProvider . equals ( zeroAddress ( ) ) ) { log . error ( `aave oracle should already have been deployed : {}` , [ event . address . toHexString ( ) ] ) ; } let priceOracleAsset = getPriceOracleAsset ( assetAddress . toHexString ( ) ) ; if ( priceOracle . version > 1 ) { priceFeedUpdated ( event , assetAddress , assetOracleAddress , priceOracleAsset , priceOracle ) ; } else { log . error ( `version should be 2` , [ ] ) ; } }