Skip to content

Commit

Permalink
Merge pull request #499 from balancer/staging-dev
Browse files Browse the repository at this point in the history
staging dev
  • Loading branch information
mendesfabio authored Aug 4, 2023
2 parents e3b8ce5 + 8e596e0 commit 6b55a17
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 35 deletions.
4 changes: 0 additions & 4 deletions assets/avalanche.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
{
"address": "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70",
"symbol": "DAI"
},
{
"address": "0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD",
"symbol": "EUROC"
}
],
"pricingAssets": [
Expand Down
18 changes: 9 additions & 9 deletions networks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,16 @@ goerli:
polygon:
network: matic
graft:
# Jul 9
block: 44889400
# Aug 4
block: 45900000
# this will be the base of the unpruned deployment, so make sure it has not been pruned
# it should be possible to run time travel queries on it going back to the vault's startBlock
base: QmegAtzM2Lv1tbJaaHrh3SgKDK9K3CcjtqbLsKUAHzdtdB
base: QmTqmUs4xp7zQkdfPB4jNv5fZfeF7jp9iKjZ3FGvRpYqUz
graft_pruned:
# Jul 9
block: 44889400
# Aug 4
block: 45900000
# this will be the base of the pruned deployment, so it is ok if it is a pruned subgraph
base: QmegAtzM2Lv1tbJaaHrh3SgKDK9K3CcjtqbLsKUAHzdtdB
base: QmRkFHajzzSbLX1yvMV9vrYL9XEaiuSb2dmGV1eyEX43VN
EventEmitter:
address: "0xcdcECFa416EE3022030E707dC3EA13a8997D74c8"
startBlock: 38152461
Expand Down Expand Up @@ -345,11 +345,11 @@ polygon:
arbitrum:
network: arbitrum-one
graft:
# Jul 14
block: 111100000
# Aug 4
block: 118100000
# always make sure the base subgraph has not been pruned
# it should be possible to run time travel queries on it going back to the vault's startBlock
base: QmW4Lxqgx5UUKpqExMpFEPoxoAGvKMyz4guBMF9z9cjAL4
base: QmVGGmBgze1tSc85fG9RpfGKSX1C5RjmWo2EpffEZyyKHa
EventEmitter:
address: "0x8f32D631093B5418d0546f77442c5fa66187E59D"
startBlock: 53475240
Expand Down
13 changes: 12 additions & 1 deletion schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ type Balancer @entity {
totalSwapVolume: BigDecimal!
totalSwapFee: BigDecimal!
totalProtocolFee: BigDecimal # TODO: make mandatory at next full sync

protocolFeesCollector: Bytes # TODO: make mandatory at next full sync
}

Expand All @@ -23,7 +22,16 @@ type Pool @entity {
oracleEnabled: Boolean!
symbol: String
name: String

"Indicates if a pool can be swapped against. Combines multiple sources, including offchain curation"
swapEnabled: Boolean!

"The native swapEnabled boolean. internal to the pool. Only applies to Gyro, LBPs and InvestmentPools"
swapEnabledInternal: Boolean

"External indication from an offchain permissioned actor"
swapEnabledCurationSignal: Boolean

swapFee: BigDecimal!
owner: Bytes
isPaused: Boolean
Expand All @@ -32,6 +40,7 @@ type Pool @entity {
totalSwapVolume: BigDecimal!
totalSwapFee: BigDecimal!
totalLiquidity: BigDecimal!
totalLiquiditySansBPT: BigDecimal # TODO: make mandatory at next full sync
totalShares: BigDecimal!
totalProtocolFee: BigDecimal # TODO: make mandatory at next full sync
createTime: Int!
Expand All @@ -54,6 +63,8 @@ type Pool @entity {

# StablePool Only
amp: BigInt
latestAmpUpdate: AmpUpdate
ampUpdates: [AmpUpdate!] @derivedFrom(field: "poolId")

# MetaStablePool and LinearPool Only
priceRateProviders: [PriceRateProvider!] @derivedFrom(field: "poolId")
Expand Down
5 changes: 4 additions & 1 deletion src/mappings/eventEmitter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LogArgument } from '../types/EventEmitter/EventEmitter';
import { Pool, Token } from '../types/schema';
import { BigDecimal } from '@graphprotocol/graph-ts';
import { computeCuratedSwapEnabled } from './helpers/misc';

export function handleLogArgument(event: LogArgument): void {
const identifier = event.params.identifier.toHexString();
Expand Down Expand Up @@ -28,9 +29,11 @@ function setSwapEnabled(event: LogArgument): void {
if (!pool) return;

if (event.params.value.toI32() == 0) {
pool.swapEnabledCurationSignal = false;
pool.swapEnabled = false;
} else {
pool.swapEnabled = true;
pool.swapEnabledCurationSignal = true;
pool.swapEnabled = computeCuratedSwapEnabled(pool.isPaused, true, pool.swapEnabledInternal);
}
pool.save();
}
Expand Down
10 changes: 10 additions & 0 deletions src/mappings/helpers/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export function newPoolEntity(poolId: string): Pool {
pool.totalSwapFee = ZERO_BD;
pool.totalProtocolFee = ZERO_BD;
pool.totalLiquidity = ZERO_BD;
pool.totalLiquiditySansBPT = ZERO_BD;
pool.totalShares = ZERO_BD;
pool.swapsCount = BigInt.fromI32(0);
pool.holdersCount = BigInt.fromI32(0);
Expand Down Expand Up @@ -455,6 +456,15 @@ export function getBalancerSnapshot(vaultId: string, timestamp: i32): BalancerSn
return snapshot;
}

export function computeCuratedSwapEnabled(
isPaused: boolean,
swapEnabledCurationSignal: boolean,
internalSwapEnabled: boolean
): boolean {
if (isPaused) return false;
return swapEnabledCurationSignal && internalSwapEnabled;
}

export function getProtocolFeeCollector(): Address | null {
let vaultContract = Vault.bind(VAULT_ADDRESS);
let feesCollector = vaultContract.try_getProtocolFeesCollector();
Expand Down
1 change: 1 addition & 0 deletions src/mappings/helpers/pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function hasVirtualSupply(pool: Pool): boolean {
pool.poolType == PoolType.SiloLinear ||
pool.poolType == PoolType.YearnLinear ||
pool.poolType == PoolType.StablePhantom ||
pool.poolType == PoolType.Managed ||
isComposableStablePool(pool)
);
}
Expand Down
39 changes: 33 additions & 6 deletions src/mappings/helpers/stable.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Address, BigInt, log } from '@graphprotocol/graph-ts';
import { Pool } from '../../types/schema';
import { StablePool } from '../../types/templates/StablePool/StablePool';
import { AmpUpdate, Pool } from '../../types/schema';
import { ZERO, ONE } from './constants';
import { StablePool } from '../../types/templates/StablePool/StablePool';

export const AMP_PRECISION = BigInt.fromI32(1000);

export function updateAmpFactor(pool: Pool): void {
let poolContract = StablePool.bind(changetype<Address>(pool.address));

pool.amp = getAmp(poolContract);
export function updateAmpFactor(pool: Pool, blockTimestamp: BigInt): void {
let latestAmpUpdateId = pool.latestAmpUpdate;
if (latestAmpUpdateId === null) {
let poolContract = StablePool.bind(changetype<Address>(pool.address));
pool.amp = getAmp(poolContract);
} else {
let latestAmpUpdate = AmpUpdate.load(latestAmpUpdateId) as AmpUpdate;
pool.amp = calculateAmp(latestAmpUpdate, blockTimestamp);
}

pool.save();
}
Expand All @@ -25,6 +30,28 @@ export function getAmp(poolContract: StablePool): BigInt {
return amp;
}

function calculateAmp(latestAmpUpdate: AmpUpdate, blockTimestamp: BigInt): BigInt {
let startValue = latestAmpUpdate.startAmp;
let endValue = latestAmpUpdate.endAmp;
let startTime = latestAmpUpdate.startTimestamp;
let endTime = latestAmpUpdate.endTimestamp;

let value = ZERO;
if (blockTimestamp.lt(endTime)) {
const duration = endTime.minus(startTime);
const elapsedTime = blockTimestamp.minus(startTime);
if (endValue.gt(startValue)) {
value = startValue.plus(endValue.minus(startValue).times(elapsedTime).div(duration));
} else {
value = startValue.minus(startValue.minus(endValue).times(elapsedTime).div(duration));
}
} else {
value = endValue;
}

return value;
}

export function calculateInvariant(amp: BigInt, balances: BigInt[], swapId: string): BigInt {
let numTokens = balances.length;
let sum = balances.reduce((a, b) => a.plus(b), ZERO);
Expand Down
32 changes: 26 additions & 6 deletions src/mappings/poolController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
getPoolTokenId,
loadPriceRateProvider,
getPoolShare,
computeCuratedSwapEnabled,
createPoolTokenEntity,
bytesToAddress,
getProtocolFeeCollector,
Expand Down Expand Up @@ -249,7 +250,9 @@ export function handleSwapEnabledSet(event: SwapEnabledSet): void {
if (poolContract == null) return;

let pool = Pool.load(poolContract.pool) as Pool;
pool.swapEnabled = event.params.swapEnabled;
let swapEnabledInternal = event.params.swapEnabled;
pool.swapEnabledInternal = swapEnabledInternal;
pool.swapEnabled = computeCuratedSwapEnabled(pool.isPaused, pool.swapEnabledCurationSignal, swapEnabledInternal);
pool.save();
}

Expand All @@ -258,8 +261,9 @@ export function handlePausedStateChanged(event: PausedStateChanged): void {
let poolContract = PoolContract.load(poolAddress.toHexString());
if (poolContract == null) return;
let pool = Pool.load(poolContract.pool) as Pool;
pool.swapEnabled = !event.params.paused;
pool.isPaused = event.params.paused;
let isPaused = event.params.paused;
pool.isPaused = isPaused;
pool.swapEnabled = computeCuratedSwapEnabled(isPaused, pool.swapEnabledCurationSignal, pool.swapEnabledInternal);
pool.save();
}

Expand Down Expand Up @@ -294,6 +298,7 @@ export function handlePauseGyroPool(event: PausedLocally): void {

let pool = Pool.load(poolContract.pool) as Pool;
pool.isPaused = true;
pool.swapEnabledInternal = false;
pool.swapEnabled = false;
pool.save();
}
Expand All @@ -305,7 +310,8 @@ export function handleUnpauseGyroPool(event: UnpausedLocally): void {

let pool = Pool.load(poolContract.pool) as Pool;
pool.isPaused = false;
pool.swapEnabled = true;
pool.swapEnabledInternal = true;
pool.swapEnabled = computeCuratedSwapEnabled(pool.isPaused, pool.swapEnabledCurationSignal, true);
pool.save();
}

Expand Down Expand Up @@ -338,15 +344,25 @@ export function handleAmpUpdateStarted(event: AmpUpdateStarted): void {
let poolContract = PoolContract.load(poolAddress.toHexString());
if (poolContract == null) return;

let poolId = poolContract.pool;

let id = event.transaction.hash.toHexString().concat(event.transactionLogIndex.toString());
let ampUpdate = new AmpUpdate(id);
ampUpdate.poolId = poolContract.pool;
ampUpdate.poolId = poolId;
ampUpdate.scheduledTimestamp = event.block.timestamp.toI32();
ampUpdate.startTimestamp = event.params.startTime;
ampUpdate.endTimestamp = event.params.endTime;
ampUpdate.startAmp = event.params.startValue;
ampUpdate.endAmp = event.params.endValue;
ampUpdate.save();

let pool = Pool.load(poolId);
if (pool == null) return;

pool.latestAmpUpdate = ampUpdate.id;
pool.save();

updateAmpFactor(pool, event.block.timestamp);
}

export function handleAmpUpdateStopped(event: AmpUpdateStopped): void {
Expand All @@ -368,7 +384,11 @@ export function handleAmpUpdateStopped(event: AmpUpdateStopped): void {

let pool = Pool.load(poolId);
if (pool == null) return;
updateAmpFactor(pool);

pool.latestAmpUpdate = ampUpdate.id;
pool.save();

updateAmpFactor(pool, event.block.timestamp);
}

/************************************
Expand Down
1 change: 1 addition & 0 deletions src/mappings/poolFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ function handleNewPool(event: PoolCreated, poolId: Bytes, swapFee: BigInt): Pool
pool.oracleEnabled = false;
pool.tx = event.transaction.hash;
pool.swapEnabled = true;
pool.swapEnabledInternal = true;
pool.isPaused = false;

let bpt = getToken(poolAddress);
Expand Down
48 changes: 42 additions & 6 deletions src/mappings/pricing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Address, Bytes, BigInt, BigDecimal, log } from '@graphprotocol/graph-ts';
import { Address, Bytes, BigInt, BigDecimal, log, dataSource } from '@graphprotocol/graph-ts';
import { Pool, TokenPrice, Balancer, PoolHistoricalLiquidity, LatestPrice, Token } from '../types/schema';
import {
ZERO_BD,
Expand All @@ -8,7 +8,7 @@ import {
ZERO_ADDRESS,
MIN_POOL_LIQUIDITY,
} from './helpers/constants';
import { hasVirtualSupply, isComposableStablePool, isLinearPool, PoolType } from './helpers/pools';
import { hasVirtualSupply, isComposableStablePool, isLinearPool, isFXPool, PoolType } from './helpers/pools';
import {
bytesToAddress,
createPoolSnapshot,
Expand Down Expand Up @@ -124,6 +124,7 @@ export function updatePoolLiquidity(poolId: string, block_number: BigInt, timest
if (pool == null) return false;
let tokensList: Bytes[] = pool.tokensList;
let newPoolLiquidity: BigDecimal = ZERO_BD;
let newPoolLiquiditySansBPT: BigDecimal = ZERO_BD;

for (let j: i32 = 0; j < tokensList.length; j++) {
let tokenAddress: Address = Address.fromString(tokensList[j].toHexString());
Expand All @@ -136,14 +137,36 @@ export function updatePoolLiquidity(poolId: string, block_number: BigInt, timest
if (poolToken == null) continue;

let poolTokenQuantity: BigDecimal = poolToken.balance;
let poolTokenValue = valueInUSD(poolTokenQuantity, tokenAddress);
let poolTokenValue: BigDecimal = ZERO_BD;
if (!isFXPool(pool)) {
poolTokenValue = valueInUSD(poolTokenQuantity, tokenAddress);
} else {
// Custom computation for FXPool tokens
poolTokenValue = valueInFX(poolTokenQuantity, tokenAddress);
}

newPoolLiquidity = newPoolLiquidity.plus(poolTokenValue);
}

let oldPoolLiquidity: BigDecimal = pool.totalLiquidity;
let liquidityChange: BigDecimal = newPoolLiquidity.minus(oldPoolLiquidity);
let token = getToken(tokenAddress);
if (token.pool == null) {
newPoolLiquiditySansBPT = newPoolLiquiditySansBPT.plus(poolTokenValue);
}
}

// Update pool stats
let liquidityChange = ZERO_BD;
let oldPoolLiquidity = pool.totalLiquidity;
let oldPoolLiquiditySansBPT = pool.totalLiquiditySansBPT;

if (dataSource.network() == 'arbitrum' || dataSource.network() == 'matic') {
// keep old logic on arbitrum and polygon to avoid breaking liquidity charts
liquidityChange = newPoolLiquidity.minus(oldPoolLiquidity);
} else if (oldPoolLiquiditySansBPT) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
liquidityChange = newPoolLiquiditySansBPT.minus(oldPoolLiquiditySansBPT!);
}

pool.totalLiquiditySansBPT = newPoolLiquiditySansBPT;
pool.totalLiquidity = newPoolLiquidity;
pool.save();

Expand Down Expand Up @@ -189,6 +212,19 @@ export function valueInUSD(value: BigDecimal, asset: Address): BigDecimal {
return usdValue;
}

export function valueInFX(value: BigDecimal, asset: Address): BigDecimal {
let token = getToken(asset);

if (token.latestFXPrice) {
// convert to USD using latestFXPrice
const latestFXPrice = token.latestFXPrice as BigDecimal;
return value.times(latestFXPrice);
} else {
// fallback if latestFXPrice is not available
return valueInUSD(value, asset);
}
}

export function updateBptPrice(pool: Pool): void {
if (pool.totalShares.equals(ZERO_BD)) return;

Expand Down
2 changes: 1 addition & 1 deletion src/mappings/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ export function handleSwapEvent(event: SwapEvent): void {
updatePoolWeights(poolId.toHexString());
} else if (isStableLikePool(pool)) {
// Stablelike pools' amplification factors update over time so we need to update them after each swap
updateAmpFactor(pool);
updateAmpFactor(pool, event.block.timestamp);
}

// If swapping on a pool with preminted BPT and the BPT itself is being swapped then this is equivalent to a mint/burn in a regular pool
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8274,4 +8274,4 @@ zen-observable-ts@^1.2.5:
[email protected], zen-observable@^0.8.0:
version "0.8.15"
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==

0 comments on commit 6b55a17

Please sign in to comment.