diff --git a/src/configs/sepolia.json b/src/configs/sepolia.json index 3a3205d..7f17947 100644 --- a/src/configs/sepolia.json +++ b/src/configs/sepolia.json @@ -1,6 +1,6 @@ { "network": "sepolia", - "startBlock": 5329297, - "registry": "0x03E8E6e4F272214f6eb0706289f436a5644C271F", - "factory": "0x74eC8C933d25CA52F3F9d75b9dCdf2eAAcD2c9E0" + "startBlock": 5609300, + "registry": "0xa2E793Bac100975c8cf84B2Bb72d8c9a26f03bAB", + "factory": "0x0F005688919916FD64052F29Cf1DcBDcBd28A0a9" } diff --git a/src/constants.ts b/src/constants.ts index 8423dbf..8122571 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -14,6 +14,6 @@ export const ZERO_ADDRESS = Address.fromString( export const SECONDS_PER_DAY = 86400 export const DAYS_PER_YEAR_BD = BigDecimal.fromString("364.25") -export const SECONDS_PER_YEAR = BigInt.fromString("31556926") +export const SECONDS_PER_YEAR = BigDecimal.fromString("31556926") export const DAY_ID_0 = "0" diff --git a/src/entities/CurvePool.ts b/src/entities/CurvePool.ts index 6f45364..d0b3e8c 100644 --- a/src/entities/CurvePool.ts +++ b/src/entities/CurvePool.ts @@ -134,6 +134,7 @@ export const getPoolCoins = (poolAddress: Address): Address[] => { return [token0Call.value, token1Call.value] } +// With 10 decimals precision export const getIBTtoPTRate = (poolAddress: Address, input: BigInt): BigInt => { let curvePoolContract = CurvePool.bind(poolAddress) diff --git a/src/entities/FutureVault.ts b/src/entities/FutureVault.ts index de95929..f72af96 100644 --- a/src/entities/FutureVault.ts +++ b/src/entities/FutureVault.ts @@ -90,6 +90,7 @@ export function getIBT(address: Address): Address { return ZERO_ADDRESS } +// With 27 decimals precision export function getIBTRate(address: Address): BigInt { const principalTokenContract = PrincipalToken.bind(address) @@ -132,6 +133,7 @@ export function getTotalAssets(address: Address): BigInt { return ZERO_BI } +// With 27 decimals precision export function getIBTUnit(address: Address): BigInt { const principalTokenContract = PrincipalToken.bind(address) diff --git a/src/tests/.latest.json b/src/tests/.latest.json index 601e8d3..be23194 100644 --- a/src/tests/.latest.json +++ b/src/tests/.latest.json @@ -1,4 +1,4 @@ { "version": "0.6.0", - "timestamp": 1708607136346 + "timestamp": 1712055992092 } diff --git a/src/tests/amm.test.ts b/src/tests/amm.test.ts index b8e0196..1ec5652 100644 --- a/src/tests/amm.test.ts +++ b/src/tests/amm.test.ts @@ -35,7 +35,7 @@ import { generateFutureDailyStatsId, } from "../utils" import { generateTransactionId } from "../utils/idGenerators" -import { toPrecision } from "../utils/toPrecision" +import { RAYS_PRECISION, toPrecision } from "../utils/toPrecision" import { emitFactoryUpdated } from "./events/Factory" import { emiCurveFactoryChange, @@ -147,7 +147,7 @@ describe("handleAddLiquidity()", () => { createConvertToAssetsCallMock(IBT_ADDRESS_MOCK, 1) createConvertToSharesCallMock( IBT_ADDRESS_MOCK, - toPrecision(BigInt.fromI32(10), 0, 18) + toPrecision(BigInt.fromI32(10), 1, 18) ) emitFactoryUpdated() @@ -943,7 +943,7 @@ describe("handleTokenExchange()", () => { APR_IN_TIME_ENTITY, `${SECOND_POOL_ADDRESS_MOCK.toHex()}-0`, "apr", - "-7883709037.95" + "-2366769450" ) }) }) @@ -1169,21 +1169,21 @@ describe("handleRemoveLiquidityOne()", () => { APR_IN_TIME_ENTITY, aprInTimeId, "spotPrice", - "90000000000000000000" + "9000000000000000000" ) assert.fieldEquals( APR_IN_TIME_ENTITY, aprInTimeId, "ibtRate", - "2000000000000000000" + "200000000000000000" ) assert.fieldEquals( APR_IN_TIME_ENTITY, aprInTimeId, "underlyingToPT", - "90000000000000000000" + "9000000000000000000" ) assert.fieldEquals( diff --git a/src/tests/mocks/CurvePool.ts b/src/tests/mocks/CurvePool.ts index 18f4c22..0cc8b5f 100644 --- a/src/tests/mocks/CurvePool.ts +++ b/src/tests/mocks/CurvePool.ts @@ -122,9 +122,7 @@ const createGetDyCallMock = (addressMock: Address): void => { ), ]) .returns([ - ethereum.Value.fromSignedBigInt( - BigInt.fromString("900000000000000000") - ), + ethereum.Value.fromSignedBigInt(BigInt.fromString("9000000000")), ]) } @@ -142,9 +140,7 @@ const createNegativeGetDyCallMock = (addressMock: Address): void => { ), ]) .returns([ - ethereum.Value.fromSignedBigInt( - BigInt.fromString("70000000000000") - ), + ethereum.Value.fromSignedBigInt(BigInt.fromString("700000000")), ]) } diff --git a/src/tests/mocks/FutureVault.ts b/src/tests/mocks/FutureVault.ts index 083c66a..530780d 100644 --- a/src/tests/mocks/FutureVault.ts +++ b/src/tests/mocks/FutureVault.ts @@ -1,7 +1,7 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts" import { createMockedFunction } from "matchstick-as/assembly" -import { toPrecision } from "../../utils/toPrecision" +import { RAYS_PRECISION, toPrecision } from "../../utils/toPrecision" import { ETH_ADDRESS_MOCK, STANDARD_DECIMALS_MOCK } from "./ERC20" import { FACTORY_ADDRESS_MOCK } from "./Factory" import { PRINCIPAL_TOKEN_ADDRESS_MOCK } from "./LPVault" @@ -50,7 +50,7 @@ export const YIELD_USER_YIELD_IN_IBT_MOCK = BigInt.fromString("110") export const SENDER_YIELD_IN_IBT_MOCK = BigInt.fromString("220") export const RECEIVER_YIELD_IN_IBT_MOCK = BigInt.fromString("330") -const IBT_RATE_MOCK = toPrecision(BigInt.fromI32(2), 0, STANDARD_DECIMALS_MOCK) +const IBT_RATE_MOCK = toPrecision(BigInt.fromI32(2), 1, RAYS_PRECISION) export function mockFutureVaultFunctions(): void { ;[ @@ -124,7 +124,7 @@ export function mockFutureVaultFunctions(): void { "getIBTUnit():(uint256)" ).returns([ ethereum.Value.fromUnsignedBigInt( - toPrecision(BigInt.fromI32(10), 0, STANDARD_DECIMALS_MOCK) + toPrecision(BigInt.fromI32(10), 1, RAYS_PRECISION) ), ]) diff --git a/src/utils/calculateAPR.ts b/src/utils/calculateAPR.ts index 0154574..78e424c 100644 --- a/src/utils/calculateAPR.ts +++ b/src/utils/calculateAPR.ts @@ -13,6 +13,7 @@ import { getIBTUnit, } from "../entities/FutureVault" import { bigDecimalToBigInt } from "./bigDecimalToBigInt" +import { CURVE_PRECISION, RAYS_PRECISION, toPrecision } from "./toPrecision" export function updatePoolAPR( poolAddress: Address, @@ -26,19 +27,31 @@ export function updatePoolAPR( let ibtDecimals = getERC20Decimals(ibtAddress) let smallInput = BigInt.fromI32(10).pow((ibtDecimals as u8) - 1) // small input to ensure correct rate for small amount - const ibtToPT = getIBTtoPTRate(poolAddress, smallInput) + const ibtToPT = toPrecision( + getIBTtoPTRate(poolAddress, smallInput), + CURVE_PRECISION, + ibtDecimals + ) const principalTokenExpiration = getExpirationTimestamp(principalToken) - const ibtRate = getIBTRate(principalToken) + const ibtRate = toPrecision( + getIBTRate(principalToken), + RAYS_PRECISION, + ibtDecimals + ) const spotPrice = ibtToPT.toBigDecimal().div(smallInput.toBigDecimal()) // Remove input - const ibtUnit = getIBTUnit(principalToken) + const ibtUnit = toPrecision( + getIBTUnit(principalToken), + RAYS_PRECISION, + ibtDecimals + ) // Form rate to BigNumber value for calculations with better precision const spotPriceBigInt = bigDecimalToBigInt( spotPrice.times(ibtUnit.toBigDecimal()) ) - const ibtSharesRate = getSharesRate(ibtAddress, getIBTUnit(principalToken)) + const ibtSharesRate = getSharesRate(ibtAddress, ibtUnit) poolAPR.spotPrice = spotPriceBigInt poolAPR.ibtRate = ibtRate @@ -51,12 +64,16 @@ export function updatePoolAPR( poolAPR.underlyingToPT = underlyingToPTRate + const underlyingToPTRatePerSecond = principalTokenExpiration + .minus(currentTimestamp) + .toBigDecimal() + let apr = underlyingToPTRate .minus(ibtUnit) - .div(principalTokenExpiration.minus(currentTimestamp)) // Get rate per second - .times(SECONDS_PER_YEAR) // Convert to rate per year - .times(BigInt.fromI32(100)) // to percentage .toBigDecimal() + .div(underlyingToPTRatePerSecond) // Get rate per second + .times(SECONDS_PER_YEAR) // Convert to rate per year + .times(BigDecimal.fromString("100")) // to percentage .div(ibtRate.toBigDecimal()) poolAPR.apr = apr diff --git a/src/utils/toPrecision.ts b/src/utils/toPrecision.ts index e065171..5f65a0c 100644 --- a/src/utils/toPrecision.ts +++ b/src/utils/toPrecision.ts @@ -1,5 +1,7 @@ import { BigInt } from "@graphprotocol/graph-ts" +export const CURVE_PRECISION = 10 +export const RAYS_PRECISION = 27 export const toPrecision = ( value: BigInt, fromPrecision: i32,