Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add weETHs invariant event indexing #169

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"devDependencies": {
"@chainlink/contracts": "^0.5.1",
"@graphprotocol/client-cli": "3.0.0",
"@graphprotocol/graph-cli": "^0.77.0",
"@graphprotocol/graph-cli": "^0.80.0",
"@graphprotocol/graph-ts": "^0.35.1",
"@layerzerolabs/solidity-examples": "^1.1.0",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.3",
Expand All @@ -50,7 +50,7 @@
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"@venusprotocol/governance-contracts": "2.3.0-dev.4",
"@venusprotocol/isolated-pools": "3.5.0-dev.3",
"@venusprotocol/isolated-pools": "3.5.0-dev.10",
"@venusprotocol/oracle": "2.2.0",
"@venusprotocol/protocol-reserve": "2.3.0-dev.1",
"@venusprotocol/solidity-utilities": "^2.0.3",
Expand Down
19 changes: 9 additions & 10 deletions subgraphs/etherfi-promo/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,29 @@ const main = () => {
docker: {
network: 'hardhat',
vWeEthAddress: sepoliaILDeployments.addresses.VToken_vweETH_LiquidStakedETH,
weEthAddress: '0x3b8b6E96e57f0d1cD366AaCf4CcC68413aF308D0',
startBlock: '0',
vWeEthsAddress: sepoliaILDeployments.addresses.VToken_vweETHs_LiquidStakedETH,
vWeEthStartBlock: '0',
vWeEthsStartBlock: '0',
},
sepolia: {
network: 'sepolia',
vWeEthAddress: sepoliaILDeployments.addresses.VToken_vweETH_LiquidStakedETH,
weEthAddress: '0x3b8b6E96e57f0d1cD366AaCf4CcC68413aF308D0',
startBlock: '5659827',
vWeEthsAddress: sepoliaILDeployments.addresses.VToken_vweETHs_LiquidStakedETH,
vWeEthStartBlock: '5659827',
vWeEthsStartBlock: '6536644',
},
ethereum: {
network: 'mainnet',
vWeEthAddress: ethereumILDeployments.addresses.VToken_vweETH_LiquidStakedETH,
weEthAddress: '0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee',
startBlock: '19076099',
vWeEthsAddress: ethereumILDeployments.addresses.VToken_vweETHs_LiquidStakedETH,
vWeEthStartBlock: '19638180',
vWeEthsStartBlock: '20583508',
},
};

const yamlTemplate = fs.readFileSync('template.yaml', 'utf8');
const yamlOutput = Mustache.render(yamlTemplate, config[network]);
fs.writeFileSync('subgraph.yaml', yamlOutput);

const configTemplate = fs.readFileSync('src/constants/config-template', 'utf8');
const tsOutput = Mustache.render(configTemplate, config[network]);
fs.writeFileSync('src/constants/config.ts', tsOutput);
};

main();
6 changes: 3 additions & 3 deletions subgraphs/etherfi-promo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "etherfi-promo-subgraph",
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"repository": {
"url": "https://github.com/VenusProtocol/subgraphs",
Expand All @@ -26,10 +26,10 @@
"test:integration": "true"
},
"dependencies": {
"@venusprotocol/isolated-pools": "3.3.0"
"@venusprotocol/isolated-pools": "3.5.0-dev.10"
},
"devDependencies": {
"@graphprotocol/graph-cli": "^0.77.0",
"@graphprotocol/graph-cli": "^0.80.0",
"ts-node": "^10.9.2",
"viem": "^2.9.26"
}
Expand Down
34 changes: 17 additions & 17 deletions subgraphs/etherfi-promo/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,52 @@
TVL
"""
type TVL @entity {
id: ID!
id: Bytes!
tvl: BigInt!
}

"""
Entity to iterate over suppliers
"""
type Supply @entity {
"SUPPLY"
id: ID!
suppliers: [SupplierAccount!]! @derivedFrom(field: "type")
"Token Address"
id: Bytes!
suppliers: [SupplierAccount!]! @derivedFrom(field: "token")
}

"""
Entity to iterate over borrowers
"""
type Borrow @entity {
"BORROW"
id: ID!
borrowers: [BorrowerAccount!]! @derivedFrom(field: "type")
"Token Address"
id: Bytes!
borrowers: [BorrowerAccount!]! @derivedFrom(field: "token")
}

"""
Supplier Account
"""
type SupplierAccount @entity {
"Account address"
id: ID!
"Account Address - Token Address"
id: Bytes!
"Account address"
address: Bytes!
"Underlying balance"
effective_balance: BigInt!
"SUPPLY"
type: Supply!
effective_balance: BigDecimal!
"Token Address"
token: Supply!
}

"""
Borrower Account
"""
type BorrowerAccount @entity {
"Account address"
id: ID!
"Account Address - Token Address"
id: Bytes!
"Account address"
address: Bytes!
"Underlying balance"
effective_balance: BigInt!
"BORROW"
type: Borrow!
effective_balance: BigDecimal!
"Token Address"
token: Borrow!
Comment on lines +50 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see EtherFi expects the balance to be in tokens instead of mantissa, what about renaming type to token? Would the new schema affect queries?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 52 is not referencing a value, It is referencing a relationship to make it easy to query all borrowers or suppliers.
line 51 is the name etherfi is expecting

}
4 changes: 0 additions & 4 deletions subgraphs/etherfi-promo/src/constants/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { Address } from '@graphprotocol/graph-ts';

import { vWeEthAddress as vWeEthAddressString, weEthAddress as weEthAddressString } from './config';

export const nullAddress = Address.fromString('0x0000000000000000000000000000000000000000');
export const vWeEthAddress = Address.fromString(vWeEthAddressString);
export const weEthAddress = Address.fromString(weEthAddressString);
4 changes: 0 additions & 4 deletions subgraphs/etherfi-promo/src/constants/config-template

This file was deleted.

4 changes: 0 additions & 4 deletions subgraphs/etherfi-promo/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,3 @@ export const oneBigInt = BigInt.fromString('1');

export const mantissaFactor = 18;
export const nullAddress = Address.fromString('0x0000000000000000000000000000000000000000');

export const SUPPLY = 'SUPPLY';
export const BORROW = 'BORROW';
export const TOTAL_VALUE_LOCKED = 'TOTAL_VALUE_LOCKED';
95 changes: 44 additions & 51 deletions subgraphs/etherfi-promo/src/mappings/vToken.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,34 @@
import { Address } from '@graphprotocol/graph-ts';

import {
AccrueInterest,
Borrow,
Mint,
Redeem,
RepayBorrow,
Transfer,
} from '../../generated/vWeETH/VToken';
import { AccrueInterest, Borrow, Mint, Transfer } from '../../generated/vWeETH/VToken';
import { VToken as VTokenContract } from '../../generated/vWeETH/VToken';
import { nullAddress } from '../constants';
import { vWeEthAddress } from '../constants/addresses';
import { createBorrowerAccount, createSupplierAccount } from '../operations/create';
import { getBorrow, getBorrowerAccount, getSupplierAccount, getSupply } from '../operations/get';
import { getBorrow, getSupply } from '../operations/get';
import { getOrCreateBorrowerAccount, getOrCreateSupplierAccount } from '../operations/getOrCreate';
import { updateBorrowerAccount, updateSupplierAccount, updateTvl } from '../operations/update';
import exponentToBigDecimal from '../utilities/exponentToBigDecimal';
import exponentToBigInt from '../utilities/exponentToBigInt';

export function handleMint(event: Mint): void {
const minter = event.params.minter;
const supplierAccount = getSupplierAccount(minter);
if (supplierAccount) {
updateSupplierAccount(minter, supplierAccount.effective_balance.plus(event.params.mintAmount));
} else {
createSupplierAccount(minter, event.params.mintAmount);
}
}

export function handleRedeem(event: Redeem): void {
const redeemer = event.params.redeemer;
const supplierAccount = getSupplierAccount(redeemer)!;
const supplierAccount = getOrCreateSupplierAccount(minter, event.address);
updateSupplierAccount(
redeemer,
supplierAccount.effective_balance.minus(event.params.redeemAmount),
minter,
event.address,
supplierAccount.effective_balance.plus(
event.params.mintAmount.toBigDecimal().div(exponentToBigDecimal(18)),
),
);
}

export function handleBorrow(event: Borrow): void {
const borrower = event.params.borrower;
const borrowerAccount = getBorrowerAccount(borrower);
if (!borrowerAccount) {
createBorrowerAccount(borrower, event.params.accountBorrows);
}
}

export function handleRepayBorrow(event: RepayBorrow): void {
const borrower = event.params.borrower;
updateBorrowerAccount(borrower, event.params.accountBorrows);
getOrCreateBorrowerAccount(borrower, event.address);
updateBorrowerAccount(
borrower,
event.address,
event.params.accountBorrows.toBigDecimal().div(exponentToBigDecimal(18)),
);
}

export function handleTransfer(event: Transfer): void {
Expand All @@ -55,49 +38,59 @@ export function handleTransfer(event: Transfer): void {
// If the to account is the vToken address we assume it was a redeem
const toAccountAddress = event.params.to;

if (fromAccountAddress != nullAddress && fromAccountAddress != event.address) {
if (
fromAccountAddress.notEqual(event.address) &&
fromAccountAddress.notEqual(nullAddress) &&
toAccountAddress.notEqual(event.address)
) {
const vTokenContract = VTokenContract.bind(event.address);
const exchangeRateMantissa = vTokenContract.exchangeRateCurrent();
const amountUnderlying = exchangeRateMantissa
.times(event.params.amount)
.div(exponentToBigInt(18));
const fromAccount = getSupplierAccount(fromAccountAddress)!;
const fromAccount = getOrCreateSupplierAccount(fromAccountAddress, event.address);
updateSupplierAccount(
fromAccountAddress,
fromAccount.effective_balance.minus(amountUnderlying),
event.address,
fromAccount.effective_balance.minus(
amountUnderlying.toBigDecimal().div(exponentToBigDecimal(18)),
),
);
// To
const toAccount = getSupplierAccount(toAccountAddress);
if (toAccount) {
updateSupplierAccount(toAccountAddress, toAccount.effective_balance.plus(amountUnderlying));
} else if (toAccountAddress != event.address) {
createSupplierAccount(toAccountAddress, amountUnderlying);
}
const toAccount = getOrCreateSupplierAccount(toAccountAddress, event.address);
updateSupplierAccount(
toAccountAddress,
event.address,
toAccount.effective_balance.plus(
amountUnderlying.toBigDecimal().div(exponentToBigDecimal(18)),
),
);
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function handleAccrueInterest(event: AccrueInterest): void {
const supply = getSupply();
const supply = getSupply(event.address);
supply.suppliers.load().forEach(supplier => {
const vTokenContract = VTokenContract.bind(vWeEthAddress);
const vTokenContract = VTokenContract.bind(Address.fromBytes(supplier.token));

const exchangeRateMantissa = vTokenContract.exchangeRateCurrent();
const vTokenBalance = vTokenContract.balanceOf(Address.fromBytes(supplier.address));
const amountUnderlying = exchangeRateMantissa.times(vTokenBalance).div(exponentToBigInt(18));
supplier.effective_balance = amountUnderlying;
supplier.effective_balance = amountUnderlying.toBigDecimal().div(exponentToBigDecimal(18));
supplier.save();
});

const borrow = getBorrow();
const borrow = getBorrow(event.address);
borrow.borrowers.load().forEach(borrower => {
const vTokenContract = VTokenContract.bind(vWeEthAddress);
const underlyingBorrowBalance = vTokenContract.borrowBalanceStored(
const vTokenContract = VTokenContract.bind(Address.fromBytes(borrower.token));
const underlyingBorrowBalance = vTokenContract.borrowBalanceCurrent(
Address.fromBytes(borrower.address),
);
borrower.effective_balance = underlyingBorrowBalance;
borrower.effective_balance = underlyingBorrowBalance
.toBigDecimal()
.div(exponentToBigDecimal(18));
borrower.save();
});

updateTvl();
updateTvl(event);
}
22 changes: 15 additions & 7 deletions subgraphs/etherfi-promo/src/operations/create.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import { Address, BigInt } from '@graphprotocol/graph-ts';

import { BorrowerAccount, SupplierAccount } from '../../generated/schema';
import { getBorrow, getSupply } from './get';
import { getPositionId } from '../utilities/ids';

export function createSupplierAccount(accountAddress: Address, amount: BigInt): SupplierAccount {
const account = new SupplierAccount(accountAddress.toHexString());
export function createSupplierAccount(
accountAddress: Address,
tokenAddress: Address,
amount: BigInt,
): SupplierAccount {
const account = new SupplierAccount(getPositionId(accountAddress, tokenAddress));
account.address = accountAddress;
account.effective_balance = amount;
account.type = getSupply().id;
account.token = tokenAddress;
account.save();
return account;
}

export function createBorrowerAccount(accountAddress: Address, amount: BigInt): BorrowerAccount {
const account = new BorrowerAccount(accountAddress.toHexString());
export function createBorrowerAccount(
accountAddress: Address,
tokenAddress: Address,
amount: BigInt,
): BorrowerAccount {
const account = new BorrowerAccount(getPositionId(accountAddress, tokenAddress));
account.address = accountAddress;
account.effective_balance = amount;
account.type = getBorrow().id;
account.token = tokenAddress;
account.save();
return account;
}
Loading
Loading