Skip to content

Commit

Permalink
FXPool: fixed bug with pricing not set after a token missing (like US…
Browse files Browse the repository at this point in the history
…DC.e on Polygon)
  • Loading branch information
andreiashu committed Apr 10, 2024
1 parent b43f8b9 commit 7e875f4
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
4 changes: 2 additions & 2 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,6 @@ type ProtocolIdData @entity {
type FXOracle @entity {
id: ID! # FX oracle aggregator address
tokens: [Bytes!]! # token addresses using this oracle
divisor: String! # some oracles require conversion
decimals: Int!
divisor: String # some oracles require conversion
decimals: Int
}
13 changes: 10 additions & 3 deletions src/mappings/poolFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
} from './helpers/misc';
import { updatePoolWeights } from './helpers/weighted';

import { BigInt, Address, Bytes, ethereum } from '@graphprotocol/graph-ts';
import { BigInt, Address, Bytes, ethereum, log } from '@graphprotocol/graph-ts';

import { PoolCreated } from '../types/WeightedPoolFactory/WeightedPoolFactory';
import { AaveLinearPoolCreated } from '../types/AaveLinearPoolV3Factory/AaveLinearPoolV3Factory';
import { ProtocolIdRegistered } from '../types/ProtocolIdRegistry/ProtocolIdRegistry';
Expand Down Expand Up @@ -696,6 +697,11 @@ function handleNewFXPool(event: ethereum.Event, permissionless: boolean): void {
// Create templates for each token Offchain Aggregator
let tokensAddresses: Address[] = changetype<Address[]>(tokens);

log.info('handleNewFXPool NEW POOL poolAddress {}; permissionless {};', [
poolAddress.toHexString(),
permissionless.toString(),
]);

if (!permissionless) {
// For FXPoolFactory, use hardcoded aggregator addresses
tokensAddresses.forEach((tokenAddress) => {
Expand Down Expand Up @@ -740,13 +746,14 @@ function handleNewFXPool(event: ethereum.Event, permissionless: boolean): void {
// oracle returns the price in troy ounces. We need to convert the price to grams
const gramPerTroyOunceCall = OunceToGramOracle.bind(oracleCall.value).try_GRAM_PER_TROYOUNCE();
if (!gramPerTroyOunceCall.reverted) {
// VNXAU oracle (deprecated)
// VNXAUGramOracle.sol oracle convertor (deprecated)
oracle.decimals = BigInt.fromString('8').toI32();
oracle.divisor = gramPerTroyOunceCall.value.toString();
} else {
// AggregatorConverter (current version)
// if the Oracle contract has a DIVISOR and DECIMALS function, it is an AggregatorConverter contract
const aggregatorConverterDivisorCall = AggregatorConverter.bind(oracleCall.value).try_DIVISOR();
if (!aggregatorConverterDivisorCall.reverted) {
// AggregatorConverter (current version)
const divisor = aggregatorConverterDivisorCall.value;
const aggregatorConverterDecimalsCall = AggregatorConverter.bind(oracleCall.value).try_DECIMALS();
if (!aggregatorConverterDecimalsCall.reverted) {
Expand Down
11 changes: 8 additions & 3 deletions src/mappings/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
MAX_TIME_DIFF_FOR_PRICING,
} from './helpers/constants';
import { AnswerUpdated } from '../types/templates/OffchainAggregator/AccessControlledOffchainAggregator';

import { getFXOracle } from './helpers/misc';
export function isPricingAsset(asset: Address): boolean {
for (let i: i32 = 0; i < PRICING_ASSETS.length; i++) {
if (PRICING_ASSETS[i] == asset) return true;
Expand Down Expand Up @@ -388,19 +388,25 @@ export function handleAnswerUpdated(event: AnswerUpdated): void {
for (let i = 0; i < oracle.tokens.length; i++) {
const tokenAddress = Address.fromBytes(oracle.tokens[i]);
const tokenExists = tokenAddressesToUpdate.includes(tokenAddress);
oracle.tokens[i].toHexString(),
tokenExists.toString(),
]);
if (!tokenExists) {
tokenAddressesToUpdate.push(tokenAddress);
}
}
} else {
log.warning('Oracle not found: {}', [aggregatorAddress.toHexString()]);
}

// Update all tokens using this aggregator
for (let i = 0; i < tokenAddressesToUpdate.length; i++) {
const tokenAddress = tokenAddressesToUpdate[i];

const token = Token.load(tokenAddress.toHexString());
if (token == null) {
log.warning('Token with address {} not found', [tokenAddress.toHexString()]);
return;
continue;
}

// All tokens we track have oracles with 8 decimals
Expand All @@ -419,7 +425,6 @@ export function handleAnswerUpdated(event: AnswerUpdated): void {
const updatedAnswer = answer
.times(BigInt.fromString('10').pow(oracle.decimals as u8))
.div(BigInt.fromString(oracle.divisor!));
log.info('Converted Oracle answer from {} to {}', [answer.toString(), updatedAnswer.toString()]);
token.latestFXPrice = scaleDown(updatedAnswer, 8);
} else {
token.latestFXPrice = scaleDown(answer, 8);
Expand Down

0 comments on commit 7e875f4

Please sign in to comment.