diff --git a/schema.graphql b/schema.graphql index b3daef0..2644ee8 100644 --- a/schema.graphql +++ b/schema.graphql @@ -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." @@ -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! @@ -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! @@ -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! } """ @@ -346,6 +354,8 @@ 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") @@ -353,15 +363,15 @@ type InvestorPosition @entity { 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) { @@ -388,6 +398,8 @@ 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" @@ -395,6 +407,8 @@ type InvestorPositionInteraction @entity(immutable: true) { "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" diff --git a/src/clock.ts b/src/clock.ts index a445dd3..53300ed 100644 --- a/src/clock.ts +++ b/src/clock.ts @@ -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 { @@ -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 @@ -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 diff --git a/src/entity/position.ts b/src/entity/position.ts index 4bdf33e..bf634d6 100644 --- a/src/entity/position.ts +++ b/src/entity/position.ts @@ -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 } diff --git a/src/entity/vault.ts b/src/entity/vault.ts index 42e0187..4ea6a1a 100644 --- a/src/entity/vault.ts +++ b/src/entity/vault.ts @@ -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" @@ -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 @@ -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 @@ -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 diff --git a/src/mapping/reward-pool.ts b/src/mapping/reward-pool.ts index 012c59a..84dc238 100644 --- a/src/mapping/reward-pool.ts +++ b/src/mapping/reward-pool.ts @@ -1 +1,2 @@ export { handleRewardPoolInitialized as handleInitialized } from "../vault-lifecycle" +export { handleRewardPoolTransfer as handleTransfer } from "../vault-interaction" diff --git a/src/utils/price.ts b/src/utils/vault-data.ts similarity index 90% rename from src/utils/price.ts rename to src/utils/vault-data.ts index 9d99270..1489066 100644 --- a/src/utils/price.ts +++ b/src/utils/vault-data.ts @@ -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 { @@ -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() @@ -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, @@ -100,6 +101,7 @@ export function fetchVaultLatestData( class VaultData { constructor( public sharesTotalSupply: BigInt, + public rewardPoolTotalSupply: BigInt, public token0Balance: BigInt, public token1Balance: BigInt, diff --git a/src/vault-compound.ts b/src/vault-compound.ts index c115c1e..d2e2187 100644 --- a/src/vault-compound.ts +++ b/src/vault-compound.ts @@ -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) @@ -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) @@ -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 @@ -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() @@ -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) @@ -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 @@ -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 @@ -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 diff --git a/src/vault-interaction.ts b/src/vault-interaction.ts index 34d7fba..38dcfd0 100644 --- a/src/vault-interaction.ts +++ b/src/vault-interaction.ts @@ -1,18 +1,25 @@ -import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts" -import { Transfer as TransferEvent } from "../generated/templates/BeefyCLVault/BeefyVaultConcLiq" -import { getBeefyCLStrategy, getBeefyCLVault, getBeefyCLVaultSnapshot, isVaultInitialized } from "./entity/vault" +import { Address, BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts" +import { Transfer as VaultShareTransferEvent } from "../generated/templates/BeefyCLVault/BeefyVaultConcLiq" +import { Transfer as RewardPoolTransferEvent } from "../generated/templates/BeefyCLRewardPool/BeefyRewardPool" +import { + getBeefyCLRewardPool, + getBeefyCLStrategy, + getBeefyCLVault, + getBeefyCLVaultSnapshot, + isVaultInitialized, +} from "./entity/vault" import { getTransaction } from "./entity/transaction" import { getInvestor } from "./entity/investor" import { ZERO_BI } from "./utils/decimal" import { VAULT_SNAPSHOT_PERIODS } from "./utils/time" import { getToken } from "./entity/token" import { getInvestorPosition } from "./entity/position" -import { fetchVaultLatestData } from "./utils/price" -import { InvestorPositionInteraction } from "../generated/schema" +import { fetchVaultLatestData } from "./utils/vault-data" +import { BeefyCLVault, InvestorPositionInteraction } from "../generated/schema" import { getEventIdentifier } from "./utils/event" import { SHARE_TOKEN_MINT_ADDRESS } from "./config" -export function handleVaultTransfer(event: TransferEvent): void { +export function handleVaultTransfer(event: VaultShareTransferEvent): void { // sending to self if (event.params.from.equals(event.params.to)) { return @@ -23,24 +30,56 @@ export function handleVaultTransfer(event: TransferEvent): void { return } - // don't duplicate processing between Transfer and Deposit/Withdraw + const vault = getBeefyCLVault(event.address) + + // don't store transfers to/from the share token mint address if (!event.params.from.equals(SHARE_TOKEN_MINT_ADDRESS)) { - updateUserPosition(event, event.params.from, event.params.value.neg()) + updateUserPosition(vault, event, event.params.from, event.params.value.neg(), ZERO_BI) } if (!event.params.to.equals(SHARE_TOKEN_MINT_ADDRESS)) { - updateUserPosition(event, event.params.to, event.params.value) + updateUserPosition(vault, event, event.params.to, event.params.value, ZERO_BI) } } -function updateUserPosition(event: ethereum.Event, investorAddress: Address, sharesDelta: BigInt): void { - let vault = getBeefyCLVault(event.address) +export function handleRewardPoolTransfer(event: RewardPoolTransferEvent): void { + // sending to self + if (event.params.from.equals(event.params.to)) { + return + } + + // transfering nothing + if (event.params.value.equals(ZERO_BI)) { + return + } + + const rewardPool = getBeefyCLRewardPool(event.address) + const vault = getBeefyCLVault(rewardPool.vault) + + // don't store transfers to/from the share token mint address + if (!event.params.from.equals(SHARE_TOKEN_MINT_ADDRESS) && !event.params.from.equals(rewardPool.id)) { + updateUserPosition(vault, event, event.params.from, ZERO_BI, event.params.value.neg()) + } + + if (!event.params.to.equals(SHARE_TOKEN_MINT_ADDRESS) && !event.params.to.equals(rewardPool.id)) { + updateUserPosition(vault, event, event.params.to, ZERO_BI, event.params.value) + } +} + +function updateUserPosition( + vault: BeefyCLVault, + event: ethereum.Event, + investorAddress: Address, + sharesDelta: BigInt, + rewardPoolDelta: BigInt, +): void { if (!isVaultInitialized(vault)) { return } 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) const investor = getInvestor(investorAddress) @@ -51,11 +90,12 @@ function updateUserPosition(event: ethereum.Event, investorAddress: Address, sha /////// // fetch data on chain - 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 @@ -71,6 +111,7 @@ function updateUserPosition(event: ethereum.Event, investorAddress: Address, sha 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 @@ -90,32 +131,74 @@ function updateUserPosition(event: ethereum.Event, investorAddress: Address, sha /////// // investor position - if (position.sharesBalance.equals(ZERO_BI)) { + if (position.sharesBalance.equals(ZERO_BI) && position.rewardPoolBalance.equals(ZERO_BI)) { position.createdWith = event.transaction.hash } position.sharesBalance = position.sharesBalance.plus(sharesDelta) + position.rewardPoolBalance = position.rewardPoolBalance.plus(rewardPoolDelta) position.save() /////// // interaction - const interaction = new InvestorPositionInteraction(getEventIdentifier(event)) + const isSharesTransfer = !sharesDelta.equals(ZERO_BI) + const isRewardPoolTransfer = !rewardPoolDelta.equals(ZERO_BI) + + // if both shares and reward pool are transferred, we need to create two interactions + let interactionId = investor.id.concat(getEventIdentifier(event)) + if (isSharesTransfer) { + interactionId = interactionId.concat(Bytes.fromI32(0)) + } else if (isRewardPoolTransfer) { + interactionId = interactionId.concat(Bytes.fromI32(1)) + } + const interaction = new InvestorPositionInteraction(interactionId) interaction.vault = vault.id interaction.investor = investor.id interaction.investorPosition = position.id interaction.createdWith = event.transaction.hash interaction.blockNumber = event.block.number interaction.timestamp = event.block.timestamp - interaction.type = sharesDelta.gt(ZERO_BI) ? "DEPOSIT" : "WITHDRAW" + if (isSharesTransfer) { + interaction.type = sharesDelta.gt(ZERO_BI) ? "VAULT_DEPOSIT" : "VAULT_WITHDRAW" + } else if (isRewardPoolTransfer) { + interaction.type = rewardPoolDelta.gt(ZERO_BI) ? "REWARD_POOL_STAKE" : "REWARD_POOL_UNSTAKE" + } interaction.sharesBalance = position.sharesBalance - interaction.underlyingBalance0 = vaultData.token0Balance - .times(position.sharesBalance) - .div(vaultData.sharesTotalSupply) - interaction.underlyingBalance1 = vaultData.token1Balance - .times(position.sharesBalance) - .div(vaultData.sharesTotalSupply) + interaction.rewardPoolBalance = position.rewardPoolBalance interaction.sharesBalanceDelta = sharesDelta - interaction.underlyingBalance0Delta = vaultData.token0Balance.times(sharesDelta).div(vaultData.sharesTotalSupply) - interaction.underlyingBalance1Delta = vaultData.token1Balance.times(sharesDelta).div(vaultData.sharesTotalSupply) + interaction.rewardPoolBalanceDelta = rewardPoolDelta + + interaction.underlyingBalance0 = ZERO_BI + interaction.underlyingBalance1 = ZERO_BI + interaction.underlyingBalance0Delta = ZERO_BI + interaction.underlyingBalance1Delta = ZERO_BI + if (!vaultData.sharesTotalSupply.equals(ZERO_BI)) { + interaction.underlyingBalance0 = interaction.underlyingBalance0.plus( + vaultData.token0Balance.times(position.sharesBalance).div(vaultData.sharesTotalSupply), + ) + interaction.underlyingBalance1 = interaction.underlyingBalance1.plus( + vaultData.token1Balance.times(position.sharesBalance).div(vaultData.sharesTotalSupply), + ) + interaction.underlyingBalance0Delta = interaction.underlyingBalance0Delta.plus( + vaultData.token0Balance.times(sharesDelta).div(vaultData.sharesTotalSupply), + ) + interaction.underlyingBalance1Delta = interaction.underlyingBalance1Delta.plus( + vaultData.token1Balance.times(sharesDelta).div(vaultData.sharesTotalSupply), + ) + } + if (!vaultData.rewardPoolTotalSupply.equals(ZERO_BI)) { + interaction.underlyingBalance0 = interaction.underlyingBalance0.plus( + vaultData.token0Balance.times(position.rewardPoolBalance).div(vaultData.rewardPoolTotalSupply), + ) + interaction.underlyingBalance1 = interaction.underlyingBalance1.plus( + vaultData.token1Balance.times(position.rewardPoolBalance).div(vaultData.rewardPoolTotalSupply), + ) + interaction.underlyingBalance0Delta = interaction.underlyingBalance0Delta.plus( + vaultData.token0Balance.times(rewardPoolDelta).div(vaultData.rewardPoolTotalSupply), + ) + interaction.underlyingBalance1Delta = interaction.underlyingBalance1Delta.plus( + vaultData.token1Balance.times(rewardPoolDelta).div(vaultData.rewardPoolTotalSupply), + ) + } interaction.token0ToNativePrice = vaultData.token0ToNativePrice interaction.token1ToNativePrice = vaultData.token1ToNativePrice interaction.nativeToUSDPrice = vaultData.nativeToUSDPrice diff --git a/src/vault-lifecycle.ts b/src/vault-lifecycle.ts index 1368ca8..102daa6 100644 --- a/src/vault-lifecycle.ts +++ b/src/vault-lifecycle.ts @@ -210,8 +210,11 @@ export function handleRewardPoolInitialized(event: RewardPoolInitialized): void rewardPool.vault = vaultAddress rewardPool.save() + const rewardPoolToken = fetchAndSaveTokenData(rewardPoolAddress) + const vault = getBeefyCLVault(vaultAddress) vault.rewardPool = rewardPool.id + vault.rewardPoolToken = rewardPoolToken.id vault.save() log.info("handleRewardPoolInitialized: Reward pool {} initialized for vault {} on block {}", [ diff --git a/subgraph.template.yaml b/subgraph.template.yaml index 38e76af..8fe6f1d 100644 --- a/subgraph.template.yaml +++ b/subgraph.template.yaml @@ -48,8 +48,6 @@ dataSources: file: ./abis/beefy/concliq/BeefyRewardPoolFactory.json - name: BeefyRewardPool file: ./abis/beefy/concliq/BeefyRewardPool.json - - name: ChainLinkPriceFeed - file: ./abis/chainlink/AggregatorV3Interface.json - name: IERC20 file: ./abis/IERC20/IERC20.json - name: Multicall3 @@ -95,11 +93,11 @@ dataSources: handler: handleRewardPoolCreated - kind: ethereum/contract - name: ChainLinkPriceFeed + name: Clock network: {{network}} source: - address: "{{chainlinkNativePriceFeedAddress}}" - abi: ChainLinkPriceFeed + address: "{{vaultFactoryAddress}}" + abi: BeefyVaultConcLiqFactory startBlock: {{vaultFactoryStartBlock}} # same as BeefyCLVaultFactory mapping: kind: ethereum/events @@ -164,7 +162,7 @@ templates: kind: ethereum/contract network: {{network}} source: - abi: BeefyStrategy + abi: BeefyRewardPool mapping: kind: ethereum/events apiVersion: 0.0.7 # 0xgraph's version @@ -175,3 +173,5 @@ templates: eventHandlers: - event: Initialized(uint8) handler: handleInitialized + - event: Transfer(indexed address,indexed address,uint256) + handler: handleTransfer