import { Address , BigDecimal , BigInt , log } from '@graphprotocol/graph-ts/index' ; import { Market , Comptroller } from '../types/schema' ; import { PriceOracle } from '../types/cREP/PriceOracle' ; import { PriceOracle2 } from '../types/cREP/PriceOracle2' ; import { ERC20 } from '../types/cREP/ERC20' ; import { CToken } from '../types/cREP/CToken' ; import { exponentToBigDecimal , mantissaFactor , mantissaFactorBD , cTokenDecimalsBD , zeroBD , } from './helpers' ; let cUSDCAddress = '0x39aa39c021dfbae8fac545936693ac917d5e7563' ; let cETHAddress = '0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5' ; let daiAddress = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359' ; function getTokenPrice ( blockNumber , eventAddress , underlyingAddress , underlyingDecimals ) { let comptroller = Comptroller . load ( '1' ) ; let oracleAddress = comptroller . priceOracle as Address ; let underlyingPrice ; let priceOracle1Address = Address . fromString ( '02557a5e05defeffd4cae6d83ea3d173b272c904' ) ; if ( blockNumber > 7715908 ) { let mantissaDecimalFactor = 18 - underlyingDecimals + 18 ; let bdFactor = exponentToBigDecimal ( mantissaDecimalFactor ) ; let oracle2 = PriceOracle2 . bind ( oracleAddress ) ; underlyingPrice = oracle2 . getUnderlyingPrice ( eventAddress ) . toBigDecimal ( ) . div ( bdFactor ) ; } else { let oracle1 = PriceOracle . bind ( priceOracle1Address ) ; underlyingPrice = oracle1 . getPrice ( underlyingAddress ) . toBigDecimal ( ) . div ( mantissaFactorBD ) ; } return underlyingPrice ; } function getUSDCpriceETH ( blockNumber ) { let comptroller = Comptroller . load ( '1' ) ; let oracleAddress = comptroller . priceOracle as Address ; let priceOracle1Address = Address . fromString ( '02557a5e05defeffd4cae6d83ea3d173b272c904' ) ; let USDCAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 ' ; let usdPrice ; if ( blockNumber > 7715908 ) { let oracle2 = PriceOracle2 . bind ( oracleAddress ) ; let mantissaDecimalFactorUSDC = 18 - 6 + 18 ; let bdFactorUSDC = exponentToBigDecimal ( mantissaDecimalFactorUSDC ) ; usdPrice = oracle2 . getUnderlyingPrice ( Address . fromString ( cUSDCAddress ) ) . toBigDecimal ( ) . div ( bdFactorUSDC ) ; } else { let oracle1 = PriceOracle . bind ( priceOracle1Address ) ; usdPrice = oracle1 . getPrice ( Address . fromString ( USDCAddress ) ) . toBigDecimal ( ) . div ( mantissaFactorBD ) ; } return usdPrice ; } export function createMarket ( marketAddress ) { let market ; let contract = CToken . bind ( Address . fromString ( marketAddress ) ) ; if ( marketAddress == cETHAddress ) { market = new Market ( marketAddress ) ; market . underlyingAddress = Address . fromString ( '0x0000000000000000000000000000000000000000' ) ; market . underlyingDecimals = 18 ; market . underlyingPrice = BigDecimal . fromString ( '1' ) ; market . underlyingName = 'Ether' ; market . underlyingSymbol = 'ETH' ; } else { market = new Market ( marketAddress ) ; market . underlyingAddress = contract . underlying ( ) ; let underlyingContract = ERC20 . bind ( market . underlyingAddress as Address ) ; market . underlyingDecimals = underlyingContract . decimals ( ) ; if ( market . underlyingAddress . toHexString ( ) != daiAddress ) { market . underlyingName = underlyingContract . name ( ) ; market . underlyingSymbol = underlyingContract . symbol ( ) ; } else { market . underlyingName = 'Dai Stablecoin v1.0 (DAI)' ; market . underlyingSymbol = 'DAI' ; } if ( marketAddress == cUSDCAddress ) { market . underlyingPriceUSD = BigDecimal . fromString ( '1' ) ; } } market . borrowRate = zeroBD ; market . cash = zeroBD ; market . collateralFactor = zeroBD ; market . exchangeRate = zeroBD ; market . interestRateModelAddress = Address . fromString ( '0x0000000000000000000000000000000000000000' ) ; market . name = contract . name ( ) ; market . numberOfBorrowers = 0 ; market . numberOfSuppliers = 0 ; market . reserves = zeroBD ; market . supplyRate = zeroBD ; market . symbol = contract . symbol ( ) ; market . totalBorrows = zeroBD ; market . totalSupply = zeroBD ; market . underlyingPrice = zeroBD ; market . accrualBlockNumber = 0 ; market . blockTimestamp = 0 ; market . borrowIndex = zeroBD ; market . reserveFactor = BigInt . fromI32 ( 0 ) ; market . underlyingPriceUSD = zeroBD ; return market ; } export function updateMarket ( marketAddress , blockNumber , blockTimestamp ) { let marketID = marketAddress . toHexString ( ) ; let market = Market . load ( marketID ) ; if ( market == null ) { market = createMarket ( marketID ) ; } if ( market . accrualBlockNumber != blockNumber ) { let contractAddress = Address . fromString ( market . id ) ; let contract = CToken . bind ( contractAddress ) ; let usdPriceInEth = getUSDCpriceETH ( blockNumber ) ; if ( market . id == cETHAddress ) { market . underlyingPriceUSD = market . underlyingPrice . div ( usdPriceInEth ) . truncate ( market . underlyingDecimals ) ; } else { let tokenPriceEth = getTokenPrice ( blockNumber , contractAddress , market . underlyingAddress as Address , market . underlyingDecimals ) ; market . underlyingPrice = tokenPriceEth . truncate ( market . underlyingDecimals ) ; if ( market . id != cUSDCAddress ) { market . underlyingPriceUSD = market . underlyingPrice . div ( usdPriceInEth ) . truncate ( market . underlyingDecimals ) ; } } market . accrualBlockNumber = contract . accrualBlockNumber ( ) . toI32 ( ) ; market . blockTimestamp = blockTimestamp ; market . totalSupply = contract . totalSupply ( ) . toBigDecimal ( ) . div ( cTokenDecimalsBD ) ; market . exchangeRate = contract . exchangeRateStored ( ) . toBigDecimal ( ) . div ( exponentToBigDecimal ( market . underlyingDecimals ) ) . times ( cTokenDecimalsBD ) . div ( mantissaFactorBD ) . truncate ( mantissaFactor ) ; market . borrowIndex = contract . borrowIndex ( ) . toBigDecimal ( ) . div ( mantissaFactorBD ) . truncate ( mantissaFactor ) ; market . reserves = contract . totalReserves ( ) . toBigDecimal ( ) . div ( exponentToBigDecimal ( market . underlyingDecimals ) ) . truncate ( market . underlyingDecimals ) ; market . totalBorrows = contract . totalBorrows ( ) . toBigDecimal ( ) . div ( exponentToBigDecimal ( market . underlyingDecimals ) ) . truncate ( market . underlyingDecimals ) ; market . cash = contract . getCash ( ) . toBigDecimal ( ) . div ( exponentToBigDecimal ( market . underlyingDecimals ) ) . truncate ( market . underlyingDecimals ) ; market . supplyRate = contract . borrowRatePerBlock ( ) . toBigDecimal ( ) . times ( BigDecimal . fromString ( '2102400' ) ) . div ( mantissaFactorBD ) . truncate ( mantissaFactor ) ; let supplyRatePerBlock = contract . try_supplyRatePerBlock ( ) ; if ( supplyRatePerBlock . reverted ) { log . info ( '***CALL FAILED*** : cERC20 supplyRatePerBlock() reverted' , [ ] ) ; market . borrowRate = zeroBD ; } else { market . borrowRate = supplyRatePerBlock . value . toBigDecimal ( ) . times ( BigDecimal . fromString ( '2102400' ) ) . div ( mantissaFactorBD ) . truncate ( mantissaFactor ) ; } market . save ( ) ; } return market as Market ; }