Skip to content

Commit 7bb905b

Browse files
committed
refactor: add tests and transition to labeled units, mantissa values
1 parent 1e64f60 commit 7bb905b

20 files changed

+1368
-140
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@venusprotocol/governance-contracts": "^1.0.0",
5252
"@venusprotocol/isolated-pools": "1.0.0",
5353
"@venusprotocol/oracle": "^1.4.1",
54-
"@venusprotocol/venus-protocol": "^0.6.0",
54+
"@venusprotocol/venus-protocol": "^3.0.0-dev.7",
5555
"assemblyscript": "0.19.23",
5656
"chai": "^4.3.6",
5757
"eslint": "^8.25.0",

subgraphs/venus/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
],
1212
"scripts": {
1313
"codegen": "graph codegen",
14-
"create:local": "graph create venusprotocol/venus-subgraph --node http://127.0.0.1:8020",
15-
"build:local": "graph build --ipfs http://localhost:5001",
16-
"build:mainnet": "graph build --ipfs https://api.thegraph.com/ipfs/ ",
17-
"deploy:local": "npx mustache config/local.json template.yaml > subgraph.yaml && graph deploy venusprotocol/venus-subgraph --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020/",
18-
"deploy:testnet": "npx mustache config/testnet.json template.yaml > subgraph.yaml && graph deploy venusprotocol/venus-subgraph-chapel --debug --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
19-
"deploy:mainnet": "npx mustache config/mainnet.json template.yaml > subgraph.yaml && graph deploy venusprotocol/venus-subgraph --debug --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
14+
"create:local": "LOCAL=true npx graph create venusprotocol/venus-subgraph --node http://127.0.0.1:8020/",
15+
"build:local": "LOCAL=true npx graph build --ipfs http://127.0.0.1:5001",
16+
"build:mainnet": "npx graph build --ipfs https://api.thegraph.com/ipfs/ ",
17+
"deploy:local": "LOCAL=true npx mustache config/local.json template.yaml > subgraph.yaml && npx graph deploy venusprotocol/venus-isolated-pools --debug --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020/",
18+
"deploy:testnet": "npx mustache config/testnet.json template.yaml > subgraph.yaml && npx graph deploy venusprotocol/venus-isolated-pools-chapel --debug --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
19+
"deploy:mainnet": "npx mustache config/mainnet.json template.yaml > subgraph.yaml && npx graph deploy venusprotocol/venus-isolated-pools --debug --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
2020
"prepare:local": "npx mustache config/local.json template.yaml > subgraph.yaml",
2121
"prepare:testnet": "npx mustache config/testnet.json template.yaml > subgraph.yaml",
2222
"prepare:mainnet": "npx mustache config/mainnet.json template.yaml > subgraph.yaml",

subgraphs/venus/schema.graphql

+11-9
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,27 @@ Market stores all high level variables for a vToken market
2020
type Market @entity {
2121
#Fields that match Venus API
2222
"Borrow rate per block"
23-
borrowRate: BigDecimal!
23+
borrowRateMantissa: BigInt!
2424
"The vToken contract balance of BEP20 or BNB"
2525
cash: BigDecimal!
2626
"Collateral factor determining how much one can borrow"
2727
collateralFactor: BigDecimal!
2828
"Exchange rate of tokens / vTokens"
29-
exchangeRate: BigDecimal!
29+
exchangeRateMantissa: BigInt!
3030
"Address of the interest rate model"
3131
interestRateModelAddress: Bytes!
3232
"Name of the vToken"
3333
name: String!
3434
"Reserves stored in the contract"
35-
reservesWei: BigInt!
35+
reservesMantissa: BigInt!
3636
"Supply rate per block"
37-
supplyRate: BigDecimal!
37+
supplyRateMantissa: BigInt!
3838
"VToken symbol"
3939
symbol: String!
4040
"VToken address"
4141
id: ID!
4242
"Borrows in the market"
43-
totalBorrows: BigDecimal!
43+
treasuryTotalBorrowsMantissa: BigInt!
4444
"VToken supply. VTokens have 8 decimals"
4545
totalSupply: BigDecimal!
4646
"Underlying token address"
@@ -58,7 +58,7 @@ type Market @entity {
5858
"Timestamp the market was most recently updated"
5959
blockTimestamp: Int!
6060
"The history of the markets borrow index return (Think S&P 500)"
61-
borrowIndex: BigDecimal!
61+
borrowIndexMantissa: BigInt!
6262
"The factor determining interest that goes to reserves"
6363
reserveFactor: BigInt!
6464
"Underlying token price in USD"
@@ -67,6 +67,8 @@ type Market @entity {
6767
underlyingDecimals: Int!
6868
"Total XVS Distributed for this market"
6969
totalXvsDistributedMantissa: BigInt!
70+
"vToken decimal length"
71+
vTokenDecimals: Int!
7072
}
7173

7274
"""
@@ -120,11 +122,11 @@ type AccountVToken @entity {
120122
"VToken balance of the user"
121123
vTokenBalance: BigDecimal!
122124
"Total amount of underlying supplied"
123-
totalUnderlyingSupplied: BigDecimal!
125+
totalUnderlyingSuppliedMantissa: BigInt!
124126
"Total amount of underling redeemed"
125-
totalUnderlyingRedeemed: BigDecimal!
127+
totalUnderlyingRedeemedMantissa: BigInt!
126128
"The value of the borrow index upon users last interaction"
127-
accountBorrowIndex: BigDecimal!
129+
accountBorrowIndexMantissa: BigInt!
128130
"Total amount underlying borrowed, exclusive of interest"
129131
totalUnderlyingBorrowed: BigDecimal!
130132
"Total amount underlying repaid"
+25-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts';
2+
import { exponentToBigDecimal } from '../utilities';
3+
4+
export const BORROW = 'BORROW';
5+
export const MINT = 'MINT';
6+
export const REDEEM = 'REDEEM';
7+
export const REPAY = 'REPAY';
8+
export const SEIZE = 'SEIZE';
9+
export const LIQUIDATE = 'LIQUIDATE';
10+
export const TRANSFER = 'TRANSFER';
11+
export const ENTER_MARKET = 'ENTER_MARKET';
12+
export const EXIT_MARKET = 'EXIT_MARKET';
213

314
export const mantissaFactor = 18;
4-
export const vTokenDecimals = 8;
15+
export const mantissaFactorBigDecimal: BigDecimal = exponentToBigDecimal(mantissaFactor);
16+
517
export const zeroBigDecimal = BigDecimal.fromString('0');
618
export const zeroBigInt32 = BigInt.fromString('0');
719
export const oneBigInt = BigInt.fromString('1');
20+
21+
export const Actions = [
22+
MINT,
23+
REDEEM,
24+
BORROW,
25+
REPAY,
26+
SEIZE,
27+
LIQUIDATE,
28+
TRANSFER,
29+
ENTER_MARKET,
30+
EXIT_MARKET,
31+
];

subgraphs/venus/src/mappings/comptroller.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { createAccount, createMarket } from '../operations/create';
1818
import { getOrCreateComptroller } from '../operations/getOrCreate';
1919
import { updateCommonVTokenStats } from '../operations/update';
2020
import { ensureComptrollerSynced } from '../utilities';
21-
import { mantissaFactorBD } from '../utilities/exponentToBigDecimal';
21+
import { mantissaFactorBigDecimal } from '../constants';
2222

2323
export const handleMarketListed = (event: MarketListed): void => {
2424
// Dynamically index all new listed tokens
@@ -112,7 +112,7 @@ export const handleNewCollateralFactor = (event: NewCollateralFactor): void => {
112112
if (market != null) {
113113
market.collateralFactor = event.params.newCollateralFactorMantissa
114114
.toBigDecimal()
115-
.div(mantissaFactorBD);
115+
.div(mantissaFactorBigDecimal);
116116
market.save();
117117
}
118118
};

subgraphs/venus/src/mappings/vtoken.ts

+24-19
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ import {
2222
Transfer,
2323
} from '../../generated/templates/VToken/VToken';
2424
import { nullAddress } from '../constants/addresses';
25-
import { vTokenDecimals } from '../constants';
2625
import { createAccount } from '../operations/create';
2726
import { createMarket } from '../operations/create';
2827
import { updateCommonVTokenStats } from '../operations/update';
2928
import { updateMarket } from '../operations/update';
30-
import { exponentToBigDecimal, vTokenDecimalsBD } from '../utilities/exponentToBigDecimal';
29+
import { exponentToBigDecimal } from '../utilities/exponentToBigDecimal';
3130

3231
/* Account supplies assets into market and receives vTokens in exchange
3332
*
@@ -52,9 +51,11 @@ export const handleMint = (event: Mint): void => {
5251
.concat('-')
5352
.concat(event.transactionLogIndex.toString());
5453

54+
const vTokenDecimals = market.vTokenDecimals;
55+
5556
let vTokenAmount = event.params.mintTokens
5657
.toBigDecimal()
57-
.div(vTokenDecimalsBD)
58+
.div(exponentToBigDecimal(vTokenDecimals))
5859
.truncate(vTokenDecimals);
5960
let underlyingAmount = event.params.mintAmount
6061
.toBigDecimal()
@@ -89,14 +90,15 @@ export const handleRedeem = (event: Redeem): void => {
8990
if (!market) {
9091
market = createMarket(event.address.toHexString());
9192
}
93+
let vTokenDecimals = market.vTokenDecimals;
9294
let redeemID = event.transaction.hash
9395
.toHexString()
9496
.concat('-')
9597
.concat(event.transactionLogIndex.toString());
9698

9799
let vTokenAmount = event.params.redeemTokens
98100
.toBigDecimal()
99-
.div(vTokenDecimalsBD)
101+
.div(exponentToBigDecimal(vTokenDecimals))
100102
.truncate(vTokenDecimals);
101103
let underlyingAmount = event.params.redeemAmount
102104
.toBigDecimal()
@@ -157,7 +159,7 @@ export const handleBorrow = (event: Borrow): void => {
157159
.div(exponentToBigDecimal(market.underlyingDecimals))
158160
.truncate(market.underlyingDecimals);
159161

160-
vTokenStats.accountBorrowIndex = market.borrowIndex;
162+
vTokenStats.accountBorrowIndexMantissa = market.borrowIndexMantissa;
161163
vTokenStats.totalUnderlyingBorrowed = vTokenStats.totalUnderlyingBorrowed.plus(borrowAmountBD);
162164
vTokenStats.save();
163165

@@ -232,7 +234,7 @@ export const handleRepayBorrow = (event: RepayBorrow): void => {
232234
.div(exponentToBigDecimal(market.underlyingDecimals))
233235
.truncate(market.underlyingDecimals);
234236

235-
vTokenStats.accountBorrowIndex = market.borrowIndex;
237+
vTokenStats.accountBorrowIndexMantissa = market.borrowIndexMantissa;
236238
vTokenStats.totalUnderlyingRepaid = vTokenStats.totalUnderlyingRepaid.plus(repayAmountBD);
237239
vTokenStats.save();
238240

@@ -311,10 +313,10 @@ export const handleLiquidateBorrow = (event: LiquidateBorrow): void => {
311313
.toHexString()
312314
.concat('-')
313315
.concat(event.transactionLogIndex.toString());
314-
316+
let vTokenDecimals = marketRepayToken.vTokenDecimals;
315317
let vTokenAmount = event.params.seizeTokens
316318
.toBigDecimal()
317-
.div(vTokenDecimalsBD)
319+
.div(exponentToBigDecimal(vTokenDecimals))
318320
.truncate(vTokenDecimals);
319321
let underlyingRepayAmount = event.params.repayAmount
320322
.toBigDecimal()
@@ -359,11 +361,14 @@ export const handleTransfer = (event: Transfer): void => {
359361
if (market.accrualBlockNumber != event.block.number.toI32()) {
360362
market = updateMarket(event.address, event.block.number.toI32(), event.block.timestamp.toI32());
361363
}
362-
363-
let amountUnderlying = market.exchangeRate.times(
364-
event.params.amount.toBigDecimal().div(vTokenDecimalsBD),
364+
let vTokenDecimals = market.vTokenDecimals;
365+
let amountUnderlying = market.exchangeRateMantissa.times(
366+
event.params.amount,
365367
);
366-
let amountUnderylingTruncated = amountUnderlying.truncate(market.underlyingDecimals);
368+
// const exchangeRateBigDecimal = getExchangeRateBigDecimal(exchangeRate, underlyingDecimals);
369+
// const amountUnderlyingMantissa = exchangeRateBigDecimal
370+
// .times(exponentToBigDecimal(underlyingDecimals))
371+
// .times(amount.toBigDecimal());
367372

368373
// Checking if the tx is FROM the vToken contract (i.e. this will not run when minting)
369374
// If so, it is a mint, and we don't need to run these calculations
@@ -387,11 +392,11 @@ export const handleTransfer = (event: Transfer): void => {
387392
);
388393

389394
vTokenStatsFrom.vTokenBalance = vTokenStatsFrom.vTokenBalance.minus(
390-
event.params.amount.toBigDecimal().div(vTokenDecimalsBD).truncate(vTokenDecimals),
395+
event.params.amount.toBigDecimal().div(exponentToBigDecimal(vTokenDecimals)).truncate(vTokenDecimals),
391396
);
392397

393-
vTokenStatsFrom.totalUnderlyingRedeemed =
394-
vTokenStatsFrom.totalUnderlyingRedeemed.plus(amountUnderylingTruncated);
398+
vTokenStatsFrom.totalUnderlyingRedeemedMantissa =
399+
vTokenStatsFrom.totalUnderlyingRedeemedMantissa.plus(amountUnderlying);
395400
vTokenStatsFrom.save();
396401
}
397402

@@ -419,11 +424,11 @@ export const handleTransfer = (event: Transfer): void => {
419424
);
420425

421426
vTokenStatsTo.vTokenBalance = vTokenStatsTo.vTokenBalance.plus(
422-
event.params.amount.toBigDecimal().div(vTokenDecimalsBD).truncate(vTokenDecimals),
427+
event.params.amount.toBigDecimal().div(exponentToBigDecimal(vTokenDecimals)).truncate(vTokenDecimals),
423428
);
424429

425-
vTokenStatsTo.totalUnderlyingSupplied =
426-
vTokenStatsTo.totalUnderlyingSupplied.plus(amountUnderylingTruncated);
430+
vTokenStatsTo.totalUnderlyingSuppliedMantissa =
431+
vTokenStatsTo.totalUnderlyingSuppliedMantissa.plus(amountUnderlying);
427432
vTokenStatsTo.save();
428433
}
429434

@@ -433,7 +438,7 @@ export const handleTransfer = (event: Transfer): void => {
433438
.concat(event.transactionLogIndex.toString());
434439

435440
let transfer = new TransferEvent(transferID);
436-
transfer.amount = event.params.amount.toBigDecimal().div(vTokenDecimalsBD);
441+
transfer.amount = event.params.amount.toBigDecimal().div(exponentToBigDecimal(vTokenDecimals));
437442
transfer.to = event.params.to;
438443
transfer.from = event.params.from;
439444
transfer.blockNumber = event.block.number.toI32();

subgraphs/venus/src/operations/create.ts

+34-32
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,49 @@ import { Address, BigDecimal, BigInt, log } from '@graphprotocol/graph-ts';
33
import { Account, AccountVToken, Market } from '../../generated/schema';
44
import { BEP20 } from '../../generated/templates/VToken/BEP20';
55
import { VToken } from '../../generated/templates/VToken/VToken';
6+
import { VBep20Storage } from '../../generated/templates/VToken/VBep20Storage';
67
import { zeroBigInt32, zeroBigDecimal } from '../constants';
78
import { nullAddress, vBnbAddress } from '../constants/addresses';
89
import { getUnderlyingPrice } from '../utilities/getUnderlyingPrice';
910

10-
export const createAccountVToken = (
11-
vTokenStatsID: string,
11+
export function createAccountVToken(
12+
accountVTokenId: string,
1213
symbol: string,
1314
account: string,
14-
marketID: string,
15-
): AccountVToken => {
16-
const vTokenStats = new AccountVToken(vTokenStatsID);
17-
vTokenStats.symbol = symbol;
18-
vTokenStats.market = marketID;
19-
vTokenStats.account = account;
20-
vTokenStats.accrualBlockNumber = BigInt.fromI32(0);
21-
// we need to set an initial real onchain value to this otherwise it will never
22-
// be accurate
23-
const vTokenContract = BEP20.bind(Address.fromString(marketID));
24-
vTokenStats.vTokenBalance = new BigDecimal(vTokenContract.balanceOf(Address.fromString(account)));
25-
// log.debug('[createAccountVToken] vTokenBalance: {}, account: {}, vToken: {}', [vTokenStats.vTokenBalance.toString(), account, marketID]);
15+
marketId: string,
16+
): AccountVToken {
17+
const accountVToken = new AccountVToken(accountVTokenId);
18+
accountVToken.symbol = symbol;
19+
accountVToken.market = marketId;
20+
accountVToken.account = account;
21+
accountVToken.accrualBlockNumber = BigInt.fromI32(0);
22+
// we need to set an initial real onchain value to this otherwise it will never be accurate
23+
const vTokenContract = BEP20.bind(Address.fromString(marketId));
24+
accountVToken.vTokenBalance = new BigDecimal(vTokenContract.balanceOf(Address.fromString(account)));
2625

27-
vTokenStats.totalUnderlyingSupplied = zeroBigDecimal;
28-
vTokenStats.totalUnderlyingRedeemed = zeroBigDecimal;
29-
vTokenStats.accountBorrowIndex = zeroBigDecimal;
30-
vTokenStats.totalUnderlyingBorrowed = zeroBigDecimal;
31-
vTokenStats.totalUnderlyingRepaid = zeroBigDecimal;
32-
vTokenStats.storedBorrowBalance = zeroBigDecimal;
33-
vTokenStats.enteredMarket = false;
34-
return vTokenStats;
26+
accountVToken.totalUnderlyingSuppliedMantissa = zeroBigInt32;
27+
accountVToken.totalUnderlyingRedeemedMantissa = zeroBigInt32;
28+
accountVToken.accountBorrowIndexMantissa = zeroBigInt32;
29+
accountVToken.totalUnderlyingBorrowed = zeroBigDecimal;
30+
accountVToken.totalUnderlyingRepaid = zeroBigDecimal;
31+
accountVToken.storedBorrowBalance = zeroBigDecimal;
32+
accountVToken.enteredMarket = false;
33+
return accountVToken;
3534
};
3635

37-
export const createAccount = (accountID: string): Account => {
38-
const account = new Account(accountID);
36+
export function createAccount(accountId: string): Account {
37+
const account = new Account(accountId);
3938
account.countLiquidated = 0;
4039
account.countLiquidator = 0;
4140
account.hasBorrowed = false;
4241
account.save();
4342
return account;
4443
};
4544

46-
export const createMarket = (marketAddress: string): Market => {
45+
export function createMarket(marketAddress: string): Market {
4746
let market: Market;
4847
const contract = VToken.bind(Address.fromString(marketAddress));
48+
const marketBep20Storage = VBep20Storage.bind(Address.fromString(marketAddress))
4949

5050
log.debug('[createMarket] market address: {}', [marketAddress]);
5151

@@ -61,7 +61,7 @@ export const createMarket = (marketAddress: string): Market => {
6161
// It is all other VBEP20 contracts
6262
} else {
6363
market = new Market(marketAddress);
64-
market.underlyingAddress = contract.underlying();
64+
market.underlyingAddress = marketBep20Storage.underlying();
6565
log.debug('[createMarket] market underlying address: {}', [
6666
market.underlyingAddress.toHexString(),
6767
]);
@@ -75,26 +75,28 @@ export const createMarket = (marketAddress: string): Market => {
7575
market.underlyingPriceUSD = underlyingValue.underlyingPriceUsd;
7676
}
7777

78+
market.vTokenDecimals = contract.decimals();
79+
7880
const interestRateModelAddress = contract.try_interestRateModel();
7981
const reserveFactor = contract.try_reserveFactorMantissa();
8082

81-
market.borrowRate = zeroBigDecimal;
83+
market.borrowRateMantissa = zeroBigInt32;
8284
market.cash = zeroBigDecimal;
8385
market.collateralFactor = zeroBigDecimal;
84-
market.exchangeRate = zeroBigDecimal;
86+
market.exchangeRateMantissa = zeroBigInt32;
8587
market.interestRateModelAddress = interestRateModelAddress.reverted
8688
? nullAddress
8789
: interestRateModelAddress.value;
8890
market.name = contract.name();
89-
market.reservesWei = BigInt.fromI32(0);
90-
market.supplyRate = zeroBigDecimal;
91+
market.reservesMantissa = BigInt.fromI32(0);
92+
market.supplyRateMantissa = zeroBigInt32;
9193
market.symbol = contract.symbol();
92-
market.totalBorrows = zeroBigDecimal;
94+
market.treasuryTotalBorrowsMantissa = zeroBigInt32;
9395
market.totalSupply = zeroBigDecimal;
9496

9597
market.accrualBlockNumber = 0;
9698
market.blockTimestamp = 0;
97-
market.borrowIndex = zeroBigDecimal;
99+
market.borrowIndexMantissa = zeroBigInt32;
98100
market.reserveFactor = reserveFactor.reverted ? BigInt.fromI32(0) : reserveFactor.value;
99101
market.totalXvsDistributedMantissa = zeroBigInt32;
100102

0 commit comments

Comments
 (0)