diff --git a/abis/cERC20.json b/abis/cERC20.json index b85403f..7b9929f 100644 --- a/abis/cERC20.json +++ b/abis/cERC20.json @@ -328,7 +328,7 @@ { "constant": true, "inputs": [], - "name": "accrualBlockNumber", + "name": "accrualBlockTimestamp", "outputs": [ { "name": "", diff --git a/abis/cETH.json b/abis/cETH.json index 897b2b9..c7fbf8c 100644 --- a/abis/cETH.json +++ b/abis/cETH.json @@ -304,7 +304,7 @@ { "constant": true, "inputs": [], - "name": "accrualBlockNumber", + "name": "accrualBlockTimestamp", "outputs": [ { "name": "", diff --git a/abis/priceOracle.json b/abis/priceOracle.json deleted file mode 100644 index cfd5b64..0000000 --- a/abis/priceOracle.json +++ /dev/null @@ -1,552 +0,0 @@ -[ - { - "constant": true, - "inputs": [], - "name": "anchorAdmin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "maxSwingMantissa", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "_assetPrices", - "outputs": [ - { - "name": "mantissa", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "pendingAnchorAdmin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "numBlocksPerPeriod", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "readers", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "paused", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "anchors", - "outputs": [ - { - "name": "period", - "type": "uint256" - }, - { - "name": "priceMantissa", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "poster", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "pendingAnchors", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "maxSwing", - "outputs": [ - { - "name": "mantissa", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "name": "_poster", - "type": "address" - }, - { - "name": "addr0", - "type": "address" - }, - { - "name": "reader0", - "type": "address" - }, - { - "name": "addr1", - "type": "address" - }, - { - "name": "reader1", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "msgSender", - "type": "address" - }, - { - "indexed": false, - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "name": "error", - "type": "uint256" - }, - { - "indexed": false, - "name": "info", - "type": "uint256" - }, - { - "indexed": false, - "name": "detail", - "type": "uint256" - } - ], - "name": "OracleFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "anchorAdmin", - "type": "address" - }, - { - "indexed": false, - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "name": "oldScaledPrice", - "type": "uint256" - }, - { - "indexed": false, - "name": "newScaledPrice", - "type": "uint256" - } - ], - "name": "NewPendingAnchor", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "name": "previousPriceMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "requestedPriceMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "newPriceMantissa", - "type": "uint256" - } - ], - "name": "PricePosted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "name": "requestedPriceMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "anchorPriceMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "cappedPriceMantissa", - "type": "uint256" - } - ], - "name": "CappedPricePosted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "newState", - "type": "bool" - } - ], - "name": "SetPaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldPendingAnchorAdmin", - "type": "address" - }, - { - "indexed": false, - "name": "newPendingAnchorAdmin", - "type": "address" - } - ], - "name": "NewPendingAnchorAdmin", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldAnchorAdmin", - "type": "address" - }, - { - "indexed": false, - "name": "newAnchorAdmin", - "type": "address" - } - ], - "name": "NewAnchorAdmin", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "error", - "type": "uint256" - }, - { - "indexed": false, - "name": "info", - "type": "uint256" - }, - { - "indexed": false, - "name": "detail", - "type": "uint256" - } - ], - "name": "Failure", - "type": "event" - }, - { - "constant": false, - "inputs": [ - { - "name": "asset", - "type": "address" - }, - { - "name": "newScaledPrice", - "type": "uint256" - } - ], - "name": "_setPendingAnchor", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "requestedState", - "type": "bool" - } - ], - "name": "_setPaused", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newPendingAnchorAdmin", - "type": "address" - } - ], - "name": "_setPendingAnchorAdmin", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "_acceptAnchorAdmin", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "asset", - "type": "address" - } - ], - "name": "assetPrices", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "asset", - "type": "address" - } - ], - "name": "getPrice", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "asset", - "type": "address" - }, - { - "name": "requestedPriceMantissa", - "type": "uint256" - } - ], - "name": "setPrice", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "assets", - "type": "address[]" - }, - { - "name": "requestedPriceMantissas", - "type": "uint256[]" - } - ], - "name": "setPrices", - "outputs": [ - { - "name": "", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index fdba162..6d22ffc 100644 --- a/schema.graphql +++ b/schema.graphql @@ -44,8 +44,8 @@ interface MarketInfo { underlyingPrice: BigDecimal! # Fields that are not in compounds api - "Block the market is updated to" - accrualBlockNumber: BigInt + "Block timestamp the market is updated to" + accrualBlockTimestamp: BigInt "Timestamp the market was most recently updated" blockTimestamp: BigInt! "The history of the markets borrow index return (Think S&P 500)" @@ -100,7 +100,7 @@ type Market implements MarketInfo @entity { # Fields that are not in compounds api "Block the market is updated to" - accrualBlockNumber: BigInt + accrualBlockTimestamp: BigInt "Timestamp the market was most recently updated" blockTimestamp: BigInt! "The history of the markets borrow index return (Think S&P 500)" @@ -191,7 +191,7 @@ type MarketHourlySnapshot implements MarketInfo @entity { # Fields that are not in compounds api "Block the market is updated to" - accrualBlockNumber: BigInt + accrualBlockTimestamp: BigInt "Timestamp the market was most recently updated" blockTimestamp: BigInt! "The history of the markets borrow index return (Think S&P 500)" @@ -254,7 +254,7 @@ type MarketDailySnapshot implements MarketInfo @entity { # Fields that are not in compounds api "Block the market is updated to" - accrualBlockNumber: BigInt + accrualBlockTimestamp: BigInt "Timestamp the market was most recently updated" blockTimestamp: BigInt! "The history of the markets borrow index return (Think S&P 500)" @@ -279,7 +279,7 @@ type AccountMarketSnapshot @entity { "AccountId-MarketId" id: ID! accountMarket: AccountCToken! - accrualBlockNumber: BigInt + accrualBlockTimestamp: BigInt blockNumber: BigInt! timestamp: BigInt! totalSupplyAmount: BigDecimal! @@ -334,7 +334,7 @@ type AccountCToken @entity { "Relation to user" account: Account! "Block number this asset was updated at in the contract" - accrualBlockNumber: BigInt! + accrualBlockTimestamp: BigInt! "True if user is entered, false if they are exited" enteredMarket: Boolean! @@ -350,7 +350,7 @@ type AccountCToken @entity { totalUnderlyingBorrowed: BigDecimal! "Total amount underlying repaid" totalUnderlyingRepaid: BigDecimal! - "Current borrow balance stored in contract (exclusive of interest since accrualBlockNumber)" + "Current borrow balance stored in contract (exclusive of interest since accrualBlockTimestamp)" storedBorrowBalance: BigDecimal! "Historical snapshots for this Account-Market association" diff --git a/src/mappings/comptroller.ts b/src/mappings/comptroller.ts index 2d10ec4..b23b61b 100644 --- a/src/mappings/comptroller.ts +++ b/src/mappings/comptroller.ts @@ -40,7 +40,7 @@ export function handleMarketEntered(event: MarketEntered): void { market.id, market.symbol, accountID, - event.block.number + event.block.timestamp ); cTokenStats.enteredMarket = true; cTokenStats.save(); @@ -132,10 +132,6 @@ export function handleNewPriceOracle(event: NewPriceOracle): void { comptroller.save(); } -export function handlehandleNewBlock(block: ethereum.Block): void { - // Define the granularity of blocks to skip to create a periodic snapshot -} - export function getOrCreateComptroller(): Comptroller { let comptroller = Comptroller.load("1"); if (comptroller == null) { diff --git a/src/mappings/ctoken.ts b/src/mappings/ctoken.ts index a38dce0..f3f78c0 100644 --- a/src/mappings/ctoken.ts +++ b/src/mappings/ctoken.ts @@ -387,7 +387,7 @@ export function handleTransfer(event: Transfer): void { if (market == null) { market = createMarket(marketID); } - if (market.accrualBlockNumber != event.block.number) { + if (market.accrualBlockTimestamp != event.block.timestamp) { market = updateMarket(event.address, event.block.number, event.block.timestamp, event.block.hash); } diff --git a/src/mappings/helpers.ts b/src/mappings/helpers.ts index 2a6d195..2eaeb9b 100644 --- a/src/mappings/helpers.ts +++ b/src/mappings/helpers.ts @@ -30,7 +30,7 @@ export function createAccountCToken( cTokenStats.symbol = symbol; cTokenStats.market = marketID; cTokenStats.account = account; - cTokenStats.accrualBlockNumber = BigInt.fromI32(0); + cTokenStats.accrualBlockTimestamp = BigInt.fromI32(0); cTokenStats.cTokenBalance = zeroBD; cTokenStats.totalUnderlyingSupplied = zeroBD; cTokenStats.totalUnderlyingRedeemed = zeroBD; @@ -55,14 +55,14 @@ export function updateCommonCTokenStats( marketID: string, marketSymbol: string, accountID: string, - blockNumber: BigInt + blockTimestamp: BigInt ): AccountCToken { let cTokenStatsID = getAccountCTokenId(marketID, accountID); let cTokenStats = AccountCToken.load(cTokenStatsID); if (cTokenStats == null) { cTokenStats = createAccountCToken(cTokenStatsID, marketSymbol, accountID, marketID); } - cTokenStats.accrualBlockNumber = blockNumber; + cTokenStats.accrualBlockTimestamp = blockTimestamp; return cTokenStats as AccountCToken; } diff --git a/src/mappings/markets.ts b/src/mappings/markets.ts index be1986e..252f573 100644 --- a/src/mappings/markets.ts +++ b/src/mappings/markets.ts @@ -2,10 +2,8 @@ // For each division by 10, add one to exponent to truncate one significant figure import { Address, BigDecimal, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; -import { Market, Comptroller, Token } from "../types/schema"; -// PriceOracle is valid from Comptroller deployment until block 8498421 -import { PriceOracle } from "../types/templates/CToken/PriceOracle"; -// PriceOracle2 is valid from 8498422 until present block (until another proxy upgrade) +import { Market, Token } from "../types/schema"; +// PriceOracle2 is valid from deployment until present block (until another proxy upgrade) import { PriceOracle2 } from "../types/templates/CToken/PriceOracle2"; import { ERC20 } from "../types/templates/CToken/ERC20"; import { CToken } from "../types/templates/CToken/CToken"; @@ -15,92 +13,35 @@ import { MANTISSA_FACTOR, QIAVAX_TOKEN_ADDRESS, WAVAX_TOKEN_ADDRESS } from "./co import { getOrCreateComptroller } from './comptroller'; import { saveMarketSnapshots } from './snapshots'; -let cUSDCAddress = "0x39aa39c021dfbae8fac545936693ac917d5e7563"; -let cETHAddress = "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5"; -let daiAddress = "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"; +let cAVAXAddress = "0x5C0401e81Bc07Ca70fAD469b451682c0d747Ef1c"; // Used for all cERC20 contracts function getTokenPrice( - // @ts-ignore - blockNumber: i32, eventAddress: Address, - underlyingAddress: Address, // @ts-ignore underlyingDecimals: i32 ): BigDecimal { let comptroller = getOrCreateComptroller(); let oracleAddress = comptroller.priceOracle as Address; let underlyingPrice: BigDecimal; - let priceOracle1Address = Address.fromString("02557a5e05defeffd4cae6d83ea3d173b272c904"); - /* PriceOracle2 is used at the block the Comptroller starts using it. - * see here https://etherscan.io/address/0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b#events - * Search for event topic 0xd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22, - * and see block 7715908. - * + /* * This must use the cToken address. * * Note this returns the value without factoring in token decimals and wei, so we must divide * the number by (ethDecimals - tokenDecimals) and again by the mantissa. * USDC would be 10 ^ ((18 - 6) + 18) = 10 ^ 30 - * - * Note that they deployed 3 different PriceOracles at the beginning of the Comptroller, - * and that they handle the decimals different, which can break the subgraph. So we actually - * defer to Oracle 1 before block 7715908, which works, - * until this one is deployed, which was used for 121 days */ - if (blockNumber > 7715908) { - let mantissaDecimalFactor = 18 - underlyingDecimals + 18; - let bdFactor = exponentToBigDecimal(mantissaDecimalFactor); - let oracle2 = PriceOracle2.bind(oracleAddress); - let tryPrice = oracle2.try_getUnderlyingPrice(eventAddress); - - underlyingPrice = tryPrice.reverted ? zeroBD : tryPrice.value.toBigDecimal().div(bdFactor); - - /* PriceOracle(1) is used (only for the first ~100 blocks of Comptroller. Annoying but we must - * handle this. We use it for more than 100 blocks, see reason at top of if statement - * of PriceOracle2. - * - * This must use the token address, not the cToken address. - * - * Note this returns the value already factoring in token decimals and wei, therefore - * we only need to divide by the mantissa, 10^18 */ - } else { - let oracle1 = PriceOracle.bind(priceOracle1Address); - underlyingPrice = oracle1 - .getPrice(underlyingAddress) - .toBigDecimal() - .div(mantissaFactorBD); - } + */ + let mantissaDecimalFactor = 18 - underlyingDecimals + 18; + let bdFactor = exponentToBigDecimal(mantissaDecimalFactor); + let oracle2 = PriceOracle2.bind(oracleAddress); + let tryPrice = oracle2.try_getUnderlyingPrice(eventAddress); + + underlyingPrice = tryPrice.reverted ? zeroBD : tryPrice.value.toBigDecimal().div(bdFactor); + return underlyingPrice; } -// Returns the price of USDC in eth. i.e. 0.005 would mean ETH is $200 -// @ts-ignore -function getUSDCpriceETH(blockNumber: i32): BigDecimal { - let comptroller = getOrCreateComptroller(); - let oracleAddress = comptroller.priceOracle as Address; - let priceOracle1Address = Address.fromString("02557a5e05defeffd4cae6d83ea3d173b272c904"); - let USDCAddress = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 "; - let usdPrice: BigDecimal; - - // See notes on block number if statement in getTokenPrices() - if (blockNumber > 7715908) { - let oracle2 = PriceOracle2.bind(oracleAddress); - let mantissaDecimalFactorUSDC = 18 - 6 + 18; - let bdFactorUSDC = exponentToBigDecimal(mantissaDecimalFactorUSDC); - let tryPrice = oracle2.try_getUnderlyingPrice(Address.fromString(cUSDCAddress)); - - usdPrice = tryPrice.reverted ? zeroBD : tryPrice.value.toBigDecimal().div(bdFactorUSDC); - } else { - let oracle1 = PriceOracle.bind(priceOracle1Address); - usdPrice = oracle1 - .getPrice(Address.fromString(USDCAddress)) - .toBigDecimal() - .div(mantissaFactorBD); - } - return usdPrice; -} - export function createMarket(marketAddress: string): Market { let ctokenAddress = Address.fromString(marketAddress); let ctoken = CToken.bind(ctokenAddress); @@ -178,7 +119,7 @@ function getOrCreateMarket(id: string, token: Token): Market { market.borrowRate = zeroBD; market.collateralFactor = zeroBD; market.cash = zeroBD; - market.accrualBlockNumber = zeroBI; + market.accrualBlockTimestamp = zeroBI; market.blockTimestamp = zeroBI; market.borrowIndex = zeroBD; market.name = ""; @@ -207,79 +148,18 @@ function amountToDenomination(amount: BigInt, decimals: i32): BigDecimal { ); } -//TODO @yhayun - old create Market function from compound fork - replaced with benqi implementation. -export function createMarketDEPRECATED(marketAddress: string): Market { - let market: Market; - let contract = CToken.bind(Address.fromString(marketAddress)); - - // It is CETH, which has a slightly different interface - 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"; - market.underlyingPriceUSD = zeroBD; - // It is all other CERC20 contracts - } 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"; - } - market.underlyingPriceUSD = zeroBD; - market.underlyingPrice = zeroBD; - if (marketAddress == cUSDCAddress) { - market.underlyingPriceUSD = BigDecimal.fromString("1"); - } - } - - let interestRateModelAddress = contract.try_interestRateModel(); - let reserveFactor = contract.try_reserveFactorMantissa(); - - market.borrowRate = zeroBD; - market.cash = zeroBD; - market.collateralFactor = zeroBD; - market.exchangeRate = zeroBD; - market.interestRateModelAddress = interestRateModelAddress.reverted - ? Address.fromString("0x0000000000000000000000000000000000000000") - : interestRateModelAddress.value; - market.name = contract.name(); - market.reserves = zeroBD; - market.supplyRate = zeroBD; - market.symbol = contract.symbol(); - market.totalBorrows = zeroBD; - market.totalSupply = zeroBD; - - market.accrualBlockNumber = zeroBI; - market.blockTimestamp = zeroBI; - market.borrowIndex = zeroBD; - market.reserveFactor = (reserveFactor.reverted ? BigInt.fromI32(0) : reserveFactor.value).toBigDecimal(); - - return market; -} - // Only to be used after block 10678764, since it's aimed to fix the change to USD based price oracle. -// @ts-ignore -function getETHinUSD(blockNumber: i32): BigDecimal { +function getAVAXinUSD(): BigDecimal { let comptroller = getOrCreateComptroller(); let oracleAddress = comptroller.priceOracle as Address; let oracle = PriceOracle2.bind(oracleAddress); - let tryPrice = oracle.try_getUnderlyingPrice(Address.fromString(cETHAddress)); + let tryPrice = oracle.try_getUnderlyingPrice(Address.fromString(cAVAXAddress)); let ethPriceInUSD = tryPrice.reverted ? zeroBD : tryPrice.value.toBigDecimal().div(mantissaFactorBD); return ethPriceInUSD; } -// @ts-ignore export function updateMarket(marketAddress: Address, blockNumber: BigInt, blockTimestamp: BigInt, blockHash: Bytes): Market { let marketID = marketAddress.toHexString(); let market = Market.load(marketID); @@ -288,54 +168,25 @@ export function updateMarket(marketAddress: Address, blockNumber: BigInt, blockT } // Only updateMarket if it has not been updated this block - if (market.accrualBlockNumber != blockNumber) { + if (market.accrualBlockTimestamp != blockTimestamp) { let contractAddress = Address.fromString(market.id); let contract = CToken.bind(contractAddress); - //TODO - @yhayun - disable underlying price calc: - // // After block 10678764 price is calculated based on USD instead of ETH - // if (blockNumber > 10678764) { - // let ethPriceInUSD = getETHinUSD(blockNumber); - - // // if cETH, we only update USD price - // if (market.id == cETHAddress) { - // market.underlyingPriceUSD = ethPriceInUSD.truncate(market.underlyingDecimals); - // } else { - // let tokenPriceUSD = getTokenPrice( - // blockNumber, - // contractAddress, - // market.underlyingAddress as Address, - // market.underlyingDecimals - // ); - // market.underlyingPrice = tokenPriceUSD.div(ethPriceInUSD).truncate(market.underlyingDecimals); - // // if USDC, we only update ETH price - // if (market.id != cUSDCAddress) { - // market.underlyingPriceUSD = tokenPriceUSD.truncate(market.underlyingDecimals); - // } - // } - // } else { - // let usdPriceInEth = getUSDCpriceETH(blockNumber); + let avaxPriceInUSD = getAVAXinUSD(); - // // if cETH, we only update USD price - // 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 USDC, we only update ETH price - // if (market.id != cUSDCAddress) { - // market.underlyingPriceUSD = market.underlyingPrice.div(usdPriceInEth).truncate(market.underlyingDecimals); - // } - // } - // } + // if cAVAX, we only update USD price + if (market.id == cAVAXAddress) { + market.underlyingPriceUSD = avaxPriceInUSD.truncate(market.underlyingDecimals); + } else { + let tokenPriceUSD = getTokenPrice( + contractAddress, + market.underlyingDecimals + ); + market.underlyingPrice = tokenPriceUSD.div(avaxPriceInUSD).truncate(market.underlyingDecimals); + market.underlyingPriceUSD = tokenPriceUSD.truncate(market.underlyingDecimals); + } - //TODO @yhayun - // market.accrualBlockNumber = contract.accrualBlockNumber() + market.accrualBlockTimestamp = contract.accrualBlockTimestamp() market.blockTimestamp = blockTimestamp; market.totalSupply = contract .totalSupply() @@ -385,24 +236,21 @@ export function updateMarket(marketAddress: Address, blockNumber: BigInt, blockT market.borrowRate = contract .borrowRatePerTimestamp() .toBigDecimal() - .times(BigDecimal.fromString("2102400")) + .times(BigDecimal.fromString("31536000")) // 31.536.000 seconds per year .div(mantissaFactorBD) .truncate(mantissaFactor); - // This fails on only the first call to cZRX. It is unclear why, but otherwise it works. - // So we handle it like this. - //TODO @yhayun - // let supplyRatePerBlock = contract.su() - // if (supplyRatePerBlock.reverted) { - // log.info('***CALL FAILED*** : cERC20 supplyRatePerBlock() reverted', []) - // market.supplyRate = zeroBD - // } else { - // market.supplyRate = supplyRatePerBlock.value - // .toBigDecimal() - // .times(BigDecimal.fromString('2102400')) - // .div(mantissaFactorBD) - // .truncate(mantissaFactor) - // } + let supplyRatePerTimestamp = contract.try_supplyRatePerTimestamp(); + if (supplyRatePerTimestamp.reverted) { + log.info('***CALL FAILED*** : cERC20 supplyRatePerBlock() reverted', []) + market.supplyRate = zeroBD + } else { + market.supplyRate = supplyRatePerTimestamp.value + .toBigDecimal() + .times(BigDecimal.fromString('31536000')) + .div(mantissaFactorBD) + .truncate(mantissaFactor) + } market.save(); saveMarketSnapshots(market!, blockTimestamp, blockNumber, blockHash); diff --git a/src/mappings/snapshots.ts b/src/mappings/snapshots.ts index fad3e50..e985943 100644 --- a/src/mappings/snapshots.ts +++ b/src/mappings/snapshots.ts @@ -62,7 +62,7 @@ export function updateAccountMarketSnapshot(accountMarket: AccountCToken, market snapshot.totalSupplyAmount = accountMarket.cTokenBalance; snapshot.accountBorrowIndex = accountMarket.accountBorrowIndex; snapshot.exchangeRate = market.exchangeRate; - snapshot.accrualBlockNumber = market.accrualBlockNumber; + snapshot.accrualBlockTimestamp = market.accrualBlockTimestamp; snapshot.storedBorrowBalance = accountMarket.storedBorrowBalance; snapshot.marketBorrowIndex = market.borrowIndex; @@ -130,35 +130,6 @@ function fillMarketSnapshotValues(snapshot: S, ma snapshot.lastBlockNumber = blockNumber; snapshot.timestamp = normalizedTimestamp; snapshot.market = market.id; - - // The code below manually copies the market fields into the snapshot. Only to be used if the "automatic" code above does not work - /* - snapshot.accrualBlockNumber = market.accrualBlockNumber; - snapshot.blockTimestamp = market.blockTimestamp; - snapshot.borrowIndex = market.borrowIndex; - snapshot.borrowRate = market.borrowRate; - snapshot.borrowersCount = market.borrowersCount; - snapshot.cash = market.cash; - snapshot.collateralFactor = market.collateralFactor; - snapshot.exchangeRate = market.exchangeRate; - snapshot.interestRateModelAddress = market.interestRateModelAddress; - snapshot.market = market.id; - snapshot.reserveFactor = market.reserveFactor; - snapshot.reserves = market.reserves; - snapshot.suppliersCount = market.suppliersCount; - snapshot.supplyRate = market.supplyRate; - snapshot.totalBorrows = market.totalBorrows; - snapshot.totalFeesGenerated = market.totalFeesGenerated; - snapshot.totalProtocolFeesGenerated = market.totalProtocolFeesGenerated; - snapshot.totalRewardsDistributed = market.totalRewardsDistributed; - snapshot.totalSupply = market.totalSupply; - snapshot.underlyingPrice = market.underlyingPrice; - snapshot.underlyingPriceUSD = market.underlyingPriceUSD; - - snapshot.lastBlockHash = blockHash; - snapshot.lastBlockNumber = blockNumber; - snapshot.timestamp = normalizedTimestamp; - */ } function extractHourlyTimestamp(timestamp: BigInt): BigInt { diff --git a/src/types/schema.ts b/src/types/schema.ts index 9f21fde..40503ee 100644 --- a/src/types/schema.ts +++ b/src/types/schema.ts @@ -265,8 +265,8 @@ export class Market extends Entity { this.set("underlyingPrice", Value.fromBigDecimal(value)); } - get accrualBlockNumber(): BigInt | null { - let value = this.get("accrualBlockNumber"); + get accrualBlockTimestamp(): BigInt | null { + let value = this.get("accrualBlockTimestamp"); if (value === null || value.kind == ValueKind.NULL) { return null; } else { @@ -274,11 +274,11 @@ export class Market extends Entity { } } - set accrualBlockNumber(value: BigInt | null) { + set accrualBlockTimestamp(value: BigInt | null) { if (value === null) { - this.unset("accrualBlockNumber"); + this.unset("accrualBlockTimestamp"); } else { - this.set("accrualBlockNumber", Value.fromBigInt(value as BigInt)); + this.set("accrualBlockTimestamp", Value.fromBigInt(value as BigInt)); } } @@ -654,8 +654,8 @@ export class MarketHourlySnapshot extends Entity { this.set("underlyingPrice", Value.fromBigDecimal(value)); } - get accrualBlockNumber(): BigInt | null { - let value = this.get("accrualBlockNumber"); + get accrualBlockTimestamp(): BigInt | null { + let value = this.get("accrualBlockTimestamp"); if (value === null || value.kind == ValueKind.NULL) { return null; } else { @@ -663,11 +663,11 @@ export class MarketHourlySnapshot extends Entity { } } - set accrualBlockNumber(value: BigInt | null) { + set accrualBlockTimestamp(value: BigInt | null) { if (value === null) { - this.unset("accrualBlockNumber"); + this.unset("accrualBlockTimestamp"); } else { - this.set("accrualBlockNumber", Value.fromBigInt(value as BigInt)); + this.set("accrualBlockTimestamp", Value.fromBigInt(value as BigInt)); } } @@ -933,8 +933,8 @@ export class MarketDailySnapshot extends Entity { this.set("underlyingPrice", Value.fromBigDecimal(value)); } - get accrualBlockNumber(): BigInt | null { - let value = this.get("accrualBlockNumber"); + get accrualBlockTimestamp(): BigInt | null { + let value = this.get("accrualBlockTimestamp"); if (value === null || value.kind == ValueKind.NULL) { return null; } else { @@ -942,11 +942,11 @@ export class MarketDailySnapshot extends Entity { } } - set accrualBlockNumber(value: BigInt | null) { + set accrualBlockTimestamp(value: BigInt | null) { if (value === null) { - this.unset("accrualBlockNumber"); + this.unset("accrualBlockTimestamp"); } else { - this.set("accrualBlockNumber", Value.fromBigInt(value as BigInt)); + this.set("accrualBlockTimestamp", Value.fromBigInt(value as BigInt)); } } @@ -1059,8 +1059,8 @@ export class AccountMarketSnapshot extends Entity { this.set("accountMarket", Value.fromString(value)); } - get accrualBlockNumber(): BigInt | null { - let value = this.get("accrualBlockNumber"); + get accrualBlockTimestamp(): BigInt | null { + let value = this.get("accrualBlockTimestamp"); if (value === null || value.kind == ValueKind.NULL) { return null; } else { @@ -1068,11 +1068,11 @@ export class AccountMarketSnapshot extends Entity { } } - set accrualBlockNumber(value: BigInt | null) { + set accrualBlockTimestamp(value: BigInt | null) { if (value === null) { - this.unset("accrualBlockNumber"); + this.unset("accrualBlockTimestamp"); } else { - this.set("accrualBlockNumber", Value.fromBigInt(value as BigInt)); + this.set("accrualBlockTimestamp", Value.fromBigInt(value as BigInt)); } } @@ -1282,13 +1282,13 @@ export class AccountCToken extends Entity { this.set("account", Value.fromString(value)); } - get accrualBlockNumber(): BigInt { - let value = this.get("accrualBlockNumber"); + get accrualBlockTimestamp(): BigInt { + let value = this.get("accrualBlockTimestamp"); return value.toBigInt(); } - set accrualBlockNumber(value: BigInt) { - this.set("accrualBlockNumber", Value.fromBigInt(value)); + set accrualBlockTimestamp(value: BigInt) { + this.set("accrualBlockTimestamp", Value.fromBigInt(value)); } get enteredMarket(): boolean { diff --git a/subgraph.yaml b/subgraph.yaml index d6ce007..f538ff0 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -37,8 +37,6 @@ dataSources: file: ./abis/comptroller.json - name: CToken file: ./abis/ctoken.json - - name: PriceOracle - file: ./abis/priceOracle.json - name: PriceOracle2 file: ./abis/priceOracle2.json - name: ERC20 @@ -76,8 +74,6 @@ templates: abis: - name: CToken file: ./abis/ctoken.json - - name: PriceOracle - file: ./abis/priceOracle.json - name: PriceOracle2 file: ./abis/priceOracle2.json - name: ERC20