Skip to content

Commit

Permalink
Move block handler to its own datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
soilking committed Apr 5, 2024
1 parent 6dbe0b7 commit 02f1493
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 74 deletions.
75 changes: 3 additions & 72 deletions projects/subgraph-bean/src/BeanWellHandler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Address, BigDecimal, BigInt, ethereum, log } from "@graphprotocol/graph-ts";
import { BEANSTALK_PRICE, BEANSTALK_PRICE_BLOCK, BEAN_ERC20 } from "../../subgraph-core/utils/Constants";
import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts";
import { BEANSTALK_PRICE, BEAN_ERC20 } from "../../subgraph-core/utils/Constants";
import { ZERO_BD, ZERO_BI, deltaBigIntArray, toDecimal } from "../../subgraph-core/utils/Decimals";
import { BeanstalkPrice } from "../generated/BeanWETHCP2w/BeanstalkPrice";
import { AddLiquidity, RemoveLiquidity, RemoveLiquidityOneToken, Shift, Swap, Sync } from "../generated/BeanWETHCP2w/Well";
import { loadBean, updateBeanSupplyPegPercent, updateBeanValues } from "./utils/Bean";
import { getPoolLiquidityUSD, loadOrCreatePool, setPoolReserves, updatePoolPrice, updatePoolValues } from "./utils/Pool";
import { checkBeanCross, checkPoolCross } from "./utils/Cross";
import { BEAN_WELLS, WellFunction } from "./utils/BeanWells";
import { checkBeanCross } from "./utils/Cross";

export function handleAddLiquidity(event: AddLiquidity): void {
handleLiquidityChange(
Expand Down Expand Up @@ -75,74 +74,6 @@ export function handleShift(event: Shift): void {
);
}

export function handleBlock(block: ethereum.Block): void {
// BeanstalkPrice contract was not deployed until about 20 mins after the first Well's deployment.
// In practice no data is lost by discarding these blocks, and the same is done elsewhere.
if (block.number.lt(BEANSTALK_PRICE_BLOCK)) {
return;
}

const beanstalkPrice = BeanstalkPrice.bind(BEANSTALK_PRICE);
const beanPrice = beanstalkPrice.try_price();
const bean = loadBean(BEAN_ERC20.toHexString());
const prevPrice = bean.price;
const newPrice = toDecimal(beanPrice.value.price);

log.debug("Prev/New bean price {} / {}", [prevPrice.toString(), newPrice.toString()]);

// Check for overall peg cross
const beanCrossed = checkBeanCross(BEAN_ERC20.toHexString(), block.timestamp, block.number, prevPrice, newPrice);

// Update pool price for each pool - necessary for checking pool cross
let totalLiquidity = ZERO_BD;
for (let i = 0; i < BEAN_WELLS.length; ++i) {
const wellInfo = BEAN_WELLS[i];
if (block.number.lt(wellInfo.startBlock)) {
continue;
}

const well = loadOrCreatePool(wellInfo.address.toHexString(), block.number);

// Currently there is only one Well function, this needs to be expanded as more Bean wells are added.
// wellInfo.wellFunction == WellFunction.ConstantProduct ? ...
const newWellPrice = beanstalkPrice.try_getConstantProductWell(wellInfo.address).value;
const poolCrossed = checkPoolCross(
wellInfo.address.toHexString(),
block.timestamp,
block.number,
well.lastPrice,
toDecimal(newWellPrice.price)
);

if (poolCrossed || beanCrossed) {
totalLiquidity = totalLiquidity.plus(toDecimal(newWellPrice.liquidity));
updatePoolValues(
wellInfo.address.toHexString(),
block.timestamp,
block.number,
ZERO_BI,
ZERO_BD,
toDecimal(newWellPrice.liquidity).minus(well.liquidityUSD),
newWellPrice.deltaB
);
updatePoolPrice(wellInfo.address.toHexString(), block.timestamp, block.number, toDecimal(newWellPrice.price), false);
}
}

// Update bean values at the end now that the summation of pool liquidity is known
if (beanCrossed) {
updateBeanValues(
BEAN_ERC20.toHexString(),
block.timestamp,
newPrice,
ZERO_BI,
ZERO_BI,
ZERO_BD,
totalLiquidity.minus(bean.liquidityUSD)
);
}
}

function handleLiquidityChange(
poolAddress: string,
timestamp: BigInt,
Expand Down
63 changes: 63 additions & 0 deletions projects/subgraph-bean/src/BlockHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { ethereum, log } from "@graphprotocol/graph-ts";
import { BEANSTALK_PRICE, BEAN_ERC20 } from "../../subgraph-core/utils/Constants";
import { ZERO_BD, ZERO_BI, toDecimal } from "../../subgraph-core/utils/Decimals";
import { BeanstalkPrice } from "../generated/BeanWETHCP2w/BeanstalkPrice";
import { loadBean, updateBeanValues } from "./utils/Bean";
import { loadOrCreatePool, updatePoolPrice, updatePoolValues } from "./utils/Pool";
import { checkBeanCross, checkPoolCross } from "./utils/Cross";

// Processing as each new ethereum block is created
export function handleBlock(block: ethereum.Block): void {
const beanstalkPrice = BeanstalkPrice.bind(BEANSTALK_PRICE);
const priceResult = beanstalkPrice.try_price();
const bean = loadBean(BEAN_ERC20.toHexString());
const prevPrice = bean.price;
const newPrice = toDecimal(priceResult.value.price);

log.debug("Prev/New bean price {} / {}", [prevPrice.toString(), newPrice.toString()]);

// Check for overall peg cross
const beanCrossed = checkBeanCross(BEAN_ERC20.toHexString(), block.timestamp, block.number, prevPrice, newPrice);

// Update pool price for each pool - necessary for checking pool cross
let totalLiquidity = ZERO_BD;
for (let i = 0; i < priceResult.value.ps.length; ++i) {
const poolPriceInfo = priceResult.value.ps[i];
const pool = loadOrCreatePool(poolPriceInfo.pool.toHexString(), block.number);

const poolCrossed = checkPoolCross(
poolPriceInfo.pool.toHexString(),
block.timestamp,
block.number,
pool.lastPrice,
toDecimal(poolPriceInfo.price)
);

if (poolCrossed || beanCrossed) {
totalLiquidity = totalLiquidity.plus(toDecimal(poolPriceInfo.liquidity));
updatePoolValues(
poolPriceInfo.pool.toHexString(),
block.timestamp,
block.number,
ZERO_BI,
ZERO_BD,
toDecimal(poolPriceInfo.liquidity).minus(pool.liquidityUSD),
poolPriceInfo.deltaB
);
updatePoolPrice(poolPriceInfo.pool.toHexString(), block.timestamp, block.number, toDecimal(poolPriceInfo.price), false);
}
}

// Update bean values at the end now that the summation of pool liquidity is known
if (beanCrossed) {
updateBeanValues(
BEAN_ERC20.toHexString(),
block.timestamp,
newPrice,
ZERO_BI,
ZERO_BI,
ZERO_BD,
totalLiquidity.minus(bean.liquidityUSD)
);
}
}
26 changes: 25 additions & 1 deletion projects/subgraph-bean/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ dataSources:
handler: handleShift
- event: Sync(uint256[],uint256,address)
handler: handleSync
file: ./src/BeanWellHandler.ts
- kind: ethereum/contract
name: BlockHandler
network: mainnet
source:
address: "0xb01CE0008CaD90104651d6A84b6B11e182a9B62A"
abi: BeanstalkPrice
startBlock: 17978222
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Bean
- BeanHourlySnapshot
- BeanDailySnapshot
- BeanCross
- PoolCross
- Pool
- PoolHourlySnapshot
- PoolDailySnapshot
abis:
- name: BeanstalkPrice
file: ../subgraph-core/abis/BeanstalkPrice.json
blockHandlers:
- handler: handleBlock
file: ./src/BeanWellHandler.ts
file: ./src/BlockHandler.ts
2 changes: 1 addition & 1 deletion projects/subgraph-bean/tests/Cross.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { beforeEach, afterEach, assert, clearStore, describe, test } from "match
import { log } from "matchstick-as/assembly/log";
import { BigInt } from "@graphprotocol/graph-ts";

import { handleBlock } from "../src/BeanWellHandler";
import { handleBlock } from "../src/BlockHandler";
import { mockBlock } from "../../subgraph-core/tests/event-mocking/Block";
import { setMockBeanPrice } from "../../subgraph-core/tests/event-mocking/Price";

Expand Down

0 comments on commit 02f1493

Please sign in to comment.