Skip to content

Commit

Permalink
Index reward pool deposit, withdrawal and transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
prevostc committed May 12, 2024
1 parent 0faea43 commit c550974
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 61 deletions.
30 changes: 22 additions & 8 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ type BeefyCLVault @entity {

"The token data of the vault. The vault is also an ERC20 token. This tokens represents the shares of the vault."
sharesToken: Token!
"The reward pool token of the vault. This is where the vault's earnings are sent if the vault does not automatically compound."
rewardPoolToken: Token!
"The underlying tokens contained in the vault. This is the first token."
underlyingToken0: Token!
"The underlying tokens contained in the vault. This is the second token."
Expand All @@ -120,6 +122,8 @@ type BeefyCLVault @entity {

"The total supply of the shares token in circulation. Express with `sharesToken.decimals` decimals."
totalSupply: BigInt!
"Total supply of the reward pool token. Express with `rewardPoolToken.decimals` decimals."
rewardPoolTotalSupply: BigInt!

"Token 0 price in native at the time of the interaction. Expressed with 18 decimals."
token0ToNativePrice: BigInt!
Expand Down Expand Up @@ -189,6 +193,8 @@ type BeefyCLVaultSnapshot @entity {

"The total supply of the shares token in circulation. Express with `sharesToken.decimals` decimals."
totalSupply: BigInt!
"Total supply of the reward pool token. Express with `rewardPoolToken.decimals` decimals."
rewardPoolTotalSupply: BigInt!

"Token 0 price in native at the time of the interaction. Expressed with 18 decimals."
token0ToNativePrice: BigInt!
Expand Down Expand Up @@ -275,6 +281,8 @@ type BeefyCLVaultHarvestEvent @entity(immutable: true) {

"Total amount of liquidity at time of harvest"
totalSupply: BigInt!
"Total amount of reward pool shares at time of harvest"
rewardPoolTotalSupply: BigInt!
}

"""
Expand Down Expand Up @@ -346,22 +354,24 @@ type InvestorPosition @entity {

"The amount of shares the investor holds"
sharesBalance: BigInt!
"Amount of reward pool shares the investor holds"
rewardPoolBalance: BigInt!

"All investor position interactions"
interactions: [InvestorPositionInteraction!]! @derivedFrom(field: "investorPosition")
}

enum InvestorPositionInteractionType {
"The investor deposited funds into the vault"
DEPOSIT
VAULT_DEPOSIT
"The investor withdrew funds from the vault"
WITHDRAW
"Boosts are given to investors in the form of a dedicated incentive token"
BOOST_START
"The investor claimed a boost"
BOOST_CLAIM
"The investor's position was closed"
BOOST_STOP
VAULT_WITHDRAW
"The investor staked in the reward pool of the vault and received reward pool shares"
REWARD_POOL_STAKE
"The investor unstaked from the reward pool of the vault and received underlying tokens"
REWARD_POOL_UNSTAKE
"The investor claimed their rewards from the reward pool of the vault"
REWARD_POOL_CLAIM
}

type InvestorPositionInteraction @entity(immutable: true) {
Expand All @@ -388,13 +398,17 @@ type InvestorPositionInteraction @entity(immutable: true) {

"The amount of shares the investor holds at the time of the interaction"
sharesBalance: BigInt!
"The amount of reward pool shares the investor holds at the time of the interaction"
rewardPoolBalance: BigInt!
"The amount of first underlying tokens the investor is entitled to at the time of the interaction"
underlyingBalance0: BigInt!
"The amount of second underlying tokens the investor is entitled to at the time of the interaction"
underlyingBalance1: BigInt!

"Amount of shares change in the interaction"
sharesBalanceDelta: BigInt!
"Amount of reward pool shares change in the interaction"
rewardPoolBalanceDelta: BigInt!
"Amount of underlying token 0 change in the interaction"
underlyingBalance0Delta: BigInt!
"Amount of underlying token 0 change in the interaction"
Expand Down
7 changes: 5 additions & 2 deletions src/clock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HOUR, VAULT_SNAPSHOT_PERIODS } from "./utils/time"
import { getClockTick } from "./entity/clock"
import { getBeefyCLProtocol } from "./entity/protocol"
import { getToken } from "./entity/token"
import { fetchVaultLatestData } from "./utils/price"
import { fetchVaultLatestData } from "./utils/vault-data"
import { getBeefyCLStrategy, getBeefyCLVaultSnapshot, isVaultInitialized } from "./entity/vault"

export function handleClockTick(block: ethereum.Block): void {
Expand Down Expand Up @@ -32,15 +32,17 @@ function updateDataOnClockTick(tick: ClockTick): void {

const strategy = getBeefyCLStrategy(vault.strategy)
const sharesToken = getToken(vault.sharesToken)
const rewardPoolToken = getToken(vault.rewardPoolToken)
const token0 = getToken(vault.underlyingToken0)
const token1 = getToken(vault.underlyingToken1)

///////
// fetch data on chain for that vault
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, token0, token1)
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, rewardPoolToken, token0, token1)

// update vault data
vault.totalSupply = vaultData.sharesTotalSupply
vault.rewardPoolTotalSupply = vaultData.rewardPoolTotalSupply
vault.token0ToNativePrice = vaultData.token0ToNativePrice
vault.token1ToNativePrice = vaultData.token1ToNativePrice
vault.nativeToUSDPrice = vaultData.nativeToUSDPrice
Expand All @@ -56,6 +58,7 @@ function updateDataOnClockTick(tick: ClockTick): void {
const period = VAULT_SNAPSHOT_PERIODS[i]
const snapshot = getBeefyCLVaultSnapshot(vault, tick.timestamp, period)
snapshot.totalSupply = vault.totalSupply
snapshot.rewardPoolTotalSupply = vault.rewardPoolTotalSupply
snapshot.token0ToNativePrice = vault.token0ToNativePrice
snapshot.token1ToNativePrice = vault.token1ToNativePrice
snapshot.nativeToUSDPrice = vault.nativeToUSDPrice
Expand Down
1 change: 1 addition & 0 deletions src/entity/position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export function getInvestorPosition(vault: BeefyCLVault, investor: Investor): In
position.investor = investor.id
position.createdWith = ADDRESS_ZERO
position.sharesBalance = ZERO_BI
position.rewardPoolBalance = ZERO_BI
}
return position
}
Expand Down
21 changes: 19 additions & 2 deletions src/entity/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ZERO_BI } from "../utils/decimal"
import { getIntervalFromTimestamp } from "../utils/time"
import { getPreviousSnapshotIdSuffix, getSnapshotIdSuffix } from "../utils/snapshot"
import { getBeefyCLProtocol } from "./protocol"
import { getNullToken } from "./token"

export const BEEFY_CL_VAULT_LIFECYCLE_INITIALIZING = "INITIALIZING"
export const BEEFY_CL_VAULT_LIFECYCLE_RUNNING = "RUNNING"
Expand All @@ -26,21 +27,30 @@ export function getBeefyCLVault(vaultAddress: Bytes): BeefyCLVault {
let vault = BeefyCLVault.load(vaultAddress)
if (!vault) {
vault = new BeefyCLVault(vaultAddress)

vault.protocol = getBeefyCLProtocol().id
vault.createdWith = ADDRESS_ZERO
vault.sharesToken = ADDRESS_ZERO
vault.strategy = ADDRESS_ZERO
vault.rewardPool = null
vault.isInitialized = false
vault.lifecycle = BEEFY_CL_VAULT_LIFECYCLE_INITIALIZING

vault.sharesToken = ADDRESS_ZERO
vault.rewardPoolToken = getNullToken().id
vault.underlyingToken0 = ADDRESS_ZERO
vault.underlyingToken1 = ADDRESS_ZERO

vault.totalSupply = ZERO_BI
vault.rewardPoolTotalSupply = ZERO_BI

vault.token0ToNativePrice = ZERO_BI
vault.token1ToNativePrice = ZERO_BI
vault.nativeToUSDPrice = ZERO_BI

vault.priceOfToken0InToken1 = ZERO_BI
vault.priceRangeMin1 = ZERO_BI
vault.priceRangeMax1 = ZERO_BI

vault.underlyingMainAmount0 = ZERO_BI
vault.underlyingMainAmount1 = ZERO_BI
vault.underlyingAltAmount0 = ZERO_BI
Expand Down Expand Up @@ -76,16 +86,22 @@ export function getBeefyCLVaultSnapshot(vault: BeefyCLVault, timestamp: BigInt,
if (!snapshot) {
snapshot = new BeefyCLVaultSnapshot(snapshotId)
snapshot.vault = vault.id

snapshot.period = period
snapshot.timestamp = timestamp
snapshot.roundedTimestamp = interval
snapshot.period = period

snapshot.totalSupply = ZERO_BI
snapshot.rewardPoolTotalSupply = ZERO_BI

snapshot.token0ToNativePrice = ZERO_BI
snapshot.token1ToNativePrice = ZERO_BI
snapshot.nativeToUSDPrice = ZERO_BI

snapshot.priceOfToken0InToken1 = ZERO_BI
snapshot.priceRangeMin1 = ZERO_BI
snapshot.priceRangeMax1 = ZERO_BI

snapshot.underlyingMainAmount0 = ZERO_BI
snapshot.underlyingMainAmount1 = ZERO_BI
snapshot.underlyingAltAmount0 = ZERO_BI
Expand All @@ -96,6 +112,7 @@ export function getBeefyCLVaultSnapshot(vault: BeefyCLVault, timestamp: BigInt,
const previousSnapshot = BeefyCLVaultSnapshot.load(previousSnapshotId)
if (previousSnapshot) {
snapshot.totalSupply = previousSnapshot.totalSupply
snapshot.rewardPoolTotalSupply = previousSnapshot.rewardPoolTotalSupply
snapshot.token0ToNativePrice = previousSnapshot.token0ToNativePrice
snapshot.token1ToNativePrice = previousSnapshot.token1ToNativePrice
snapshot.nativeToUSDPrice = previousSnapshot.nativeToUSDPrice
Expand Down
1 change: 1 addition & 0 deletions src/mapping/reward-pool.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { handleRewardPoolInitialized as handleInitialized } from "../vault-lifecycle"
export { handleRewardPoolTransfer as handleTransfer } from "../vault-interaction"
24 changes: 13 additions & 11 deletions src/utils/price.ts → src/utils/vault-data.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import { BigInt } from "@graphprotocol/graph-ts"
import { BeefyCLStrategy, BeefyCLVault, Token } from "../../generated/schema"
import { ZERO_BI, changeValueEncoding } from "./decimal"
import { ChainLinkPriceFeed } from "../../generated/templates/BeefyCLStrategy/ChainLinkPriceFeed"
import { CHAINLINK_NATIVE_PRICE_FEED_ADDRESS, PRICE_FEED_DECIMALS, PRICE_STORE_DECIMALS_USD } from "../config"
import { Multicall3Params, multicall } from "./multicall"

const nativePriceFeed = ChainLinkPriceFeed.bind(CHAINLINK_NATIVE_PRICE_FEED_ADDRESS)

export function fetchNativePriceUSD(): BigInt {
return changeValueEncoding(
nativePriceFeed.latestRoundData().getAnswer(),
PRICE_FEED_DECIMALS,
PRICE_STORE_DECIMALS_USD,
)
}
import { isNullToken } from "../entity/token"

export function fetchVaultLatestData(
vault: BeefyCLVault,
strategy: BeefyCLStrategy,
sharesToken: Token,
rewardPoolToken: Token,
token0: Token,
token1: Token,
): VaultData {
Expand All @@ -36,6 +27,10 @@ export function fetchVaultLatestData(
"(uint80,int256,uint256,uint256,uint80)",
),
]
if (!isNullToken(rewardPoolToken)) {
signatures.push(new Multicall3Params(rewardPoolToken.id, "totalSupply()", "uint256"))
}

const results = multicall(signatures)

const totalSupply = results[0].value.toBigInt()
Expand Down Expand Up @@ -77,8 +72,14 @@ export function fetchVaultLatestData(
PRICE_STORE_DECIMALS_USD,
)

let rewardPoolTotalSupply = ZERO_BI
if (!isNullToken(rewardPoolToken)) {
rewardPoolTotalSupply = results[8].value.toBigInt()
}

return new VaultData(
totalSupply,
rewardPoolTotalSupply,
token0Balance,
token1Balance,

Expand All @@ -100,6 +101,7 @@ export function fetchVaultLatestData(
class VaultData {
constructor(
public sharesTotalSupply: BigInt,
public rewardPoolTotalSupply: BigInt,
public token0Balance: BigInt,
public token1Balance: BigInt,

Expand Down
20 changes: 11 additions & 9 deletions src/vault-compound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getEventIdentifier } from "./utils/event"
import { getToken } from "./entity/token"
import { ZERO_BI } from "./utils/decimal"
import { VAULT_SNAPSHOT_PERIODS } from "./utils/time"
import { fetchVaultLatestData } from "./utils/price"
import { fetchVaultLatestData } from "./utils/vault-data"

export function handleStrategyHarvest(event: HarvestEvent): void {
let strategy = getBeefyCLStrategy(event.address)
Expand All @@ -21,6 +21,7 @@ export function handleStrategyHarvest(event: HarvestEvent): void {
}

const sharesToken = getToken(vault.sharesToken)
const rewardPoolToken = getToken(vault.rewardPoolToken)
const token0 = getToken(vault.underlyingToken0)
const token1 = getToken(vault.underlyingToken1)

Expand All @@ -29,10 +30,7 @@ export function handleStrategyHarvest(event: HarvestEvent): void {

///////
// fetch data on chain
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, token0, token1)
const vaultBalanceUnderlying0 = vaultData.token0Balance
const vaultBalanceUnderlying1 = vaultData.token1Balance
const sharesTotalSupply = vaultData.sharesTotalSupply
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, rewardPoolToken, token0, token1)

///////
// store the raw harvest event
Expand All @@ -41,9 +39,10 @@ export function handleStrategyHarvest(event: HarvestEvent): void {
harvest.strategy = strategy.id
harvest.createdWith = tx.id
harvest.timestamp = event.block.timestamp
harvest.underlyingAmount0 = vaultBalanceUnderlying0
harvest.underlyingAmount1 = vaultBalanceUnderlying1
harvest.totalSupply = sharesTotalSupply
harvest.underlyingAmount0 = vaultData.token0Balance
harvest.underlyingAmount1 = vaultData.token1Balance
harvest.totalSupply = vaultData.sharesTotalSupply
harvest.rewardPoolTotalSupply = vaultData.rewardPoolTotalSupply
harvest.compoundedAmount0 = event.params.fee0
harvest.compoundedAmount1 = event.params.fee1
harvest.save()
Expand Down Expand Up @@ -74,6 +73,7 @@ function handleStrategyFees(
}

const sharesToken = getToken(vault.sharesToken)
const rewardPoolToken = getToken(vault.rewardPoolToken)
const token0 = getToken(vault.underlyingToken0)
const token1 = getToken(vault.underlyingToken1)

Expand All @@ -82,7 +82,7 @@ function handleStrategyFees(

///////
// fetch data on chain
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, token0, token1)
const vaultData = fetchVaultLatestData(vault, strategy, sharesToken, rewardPoolToken, token0, token1)

///////
// store the raw collect event
Expand All @@ -105,6 +105,7 @@ function handleStrategyFees(
///////
// update vault entity
vault.totalSupply = vaultData.sharesTotalSupply
vault.rewardPoolTotalSupply = vaultData.rewardPoolTotalSupply
vault.token0ToNativePrice = vaultData.token0ToNativePrice
vault.token1ToNativePrice = vaultData.token1ToNativePrice
vault.nativeToUSDPrice = vaultData.nativeToUSDPrice
Expand All @@ -120,6 +121,7 @@ function handleStrategyFees(
const period = VAULT_SNAPSHOT_PERIODS[i]
const snapshot = getBeefyCLVaultSnapshot(vault, event.block.timestamp, period)
snapshot.totalSupply = vault.totalSupply
snapshot.rewardPoolTotalSupply = vault.rewardPoolTotalSupply
snapshot.token0ToNativePrice = vault.token0ToNativePrice
snapshot.token1ToNativePrice = vault.token1ToNativePrice
snapshot.nativeToUSDPrice = vault.nativeToUSDPrice
Expand Down
Loading

0 comments on commit c550974

Please sign in to comment.