From eeefb1700d520c1817505640c2d2b1eb5e14eb52 Mon Sep 17 00:00:00 2001 From: Alexander Belopashentsev <61732514+belopash@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:31:24 +0500 Subject: [PATCH] fix: fix l1 to l2 conversion issues (#61) --- packages/rewards-calculator/src/chain.ts | 29 ++++++++-------- packages/rewards-calculator/src/endpoints.ts | 35 ++++++++++++-------- packages/rewards-calculator/src/rewardBot.ts | 4 +-- packages/rewards-calculator/src/testRPC.ts | 4 --- packages/rewards-calculator/src/workers.ts | 9 ++--- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/packages/rewards-calculator/src/chain.ts b/packages/rewards-calculator/src/chain.ts index f69ab1b..1d80cc1 100644 --- a/packages/rewards-calculator/src/chain.ts +++ b/packages/rewards-calculator/src/chain.ts @@ -10,7 +10,7 @@ import { parseAbiItem, } from "viem"; import { logger } from "./logger"; -import { bigSum, fromBase58, withCache } from "./utils"; +import { bigSum, fromBase58 } from "./utils"; import { Rewards } from "./reward"; import { Workers } from "./workers"; import { fordefiRequest } from "./fordefi/request"; @@ -31,8 +31,8 @@ function getNitroGenesisBlock(chainId: number) { let lastKnowBlockPair: {l1Block: bigint, l2Block: bigint} | undefined = undefined // ref https://github.com/OffchainLabs/arbitrum-sdk/blob/5ef44308d3c89fd956c9dfdc59b6776b88afd251/src/lib/utils/lib.ts#L90 -export async function getFirstBlockForL1Block(targetL1Block: number | bigint | undefined): Promise { - targetL1Block = targetL1Block == null ? await l1Client.getBlockNumber() : BigInt(targetL1Block) +export async function getFirstBlockForL1Block(targetL1Block: number | bigint): Promise { + targetL1Block = BigInt(targetL1Block) let start: bigint if (lastKnowBlockPair == null || lastKnowBlockPair.l1Block > targetL1Block) { @@ -48,7 +48,9 @@ export async function getFirstBlockForL1Block(targetL1Block: number | bigint | u return lastKnowBlockPair.l2Block } - let end = await publicClient.getBlockNumber() + // for some reason .getBlockNumber() returns inconsistent result to .getBlock(), + // so, since we use .getBlock() further down the code, we should use .getBlock() here as well + let end = await publicClient.getBlock().then(block => block.number) let targetL2Block: bigint | undefined while (start <= end) { @@ -127,23 +129,19 @@ export async function getLatestDistributionBlock() { return -1n } -export const currentApy = withCache(_currentApy) +// export const currentApy = withCache(_currentApy) -async function _currentApy(l1BlockNumber: number | bigint) { - assert (l1BlockNumber < 1000000000n, `${l1BlockNumber} should fit into number` ) - - const l2blockNumber = await getFirstBlockForL1Block(l1BlockNumber) - - const tvl = await contracts.rewardCalculation.read.effectiveTVL({ blockNumber: l2blockNumber }); +export async function currentApy(blockNumber: bigint) { + const tvl = await contracts.rewardCalculation.read.effectiveTVL({ blockNumber }); logger.log(`TVL: ${tvl.toString()}`); if (tvl === 0n) { return 2000n; } - const initialRewardPoolsSize = await contracts.rewardCalculation.read.INITIAL_REWARD_POOL_SIZE({ blockNumber: l2blockNumber }); + const initialRewardPoolsSize = await contracts.rewardCalculation.read.INITIAL_REWARD_POOL_SIZE({ blockNumber }); logger.log(`Initial Reward Pool Size: ${initialRewardPoolsSize.toString()}`); - const yearlyRewardCapCoefficient = await contracts.networkController.read.yearlyRewardCapCoefficient({ blockNumber: l2blockNumber }); + const yearlyRewardCapCoefficient = await contracts.networkController.read.yearlyRewardCapCoefficient({ blockNumber }); logger.log(`Yearly Reward Cap Coefficient: ${yearlyRewardCapCoefficient.toString()}`); const apyCap = (BigInt(10000) * yearlyRewardCapCoefficient * initialRewardPoolsSize) / tvl; @@ -172,8 +170,9 @@ export async function bond(blockNumber?: bigint) { return contracts.workerRegistration.read.bondAmount({ blockNumber }); } -export async function getBlockNumber() { - return Number(await l1Client.getBlockNumber()); +export async function getL1BlockNumber() { + const block = await publicClient.getBlock(); + return Number.parseInt((block as any).l1BlockNumber, 16); } export async function lastRewardedBlock() { diff --git a/packages/rewards-calculator/src/endpoints.ts b/packages/rewards-calculator/src/endpoints.ts index 9be1936..d049eca 100644 --- a/packages/rewards-calculator/src/endpoints.ts +++ b/packages/rewards-calculator/src/endpoints.ts @@ -1,7 +1,7 @@ import express from "express"; import { epochStats } from "./reward"; -import { config, l1Client } from "./config"; -import { getBlockNumber, currentApy } from "./chain"; +import { config, l1Client, publicClient } from "./config"; +import { getL1BlockNumber, currentApy, getFirstBlockForL1Block } from "./chain"; import { logger } from "./logger" const app = express(); @@ -106,22 +106,29 @@ app.get("/rewards/:fromBlock/:toBlock", async (req, res) => { await rewards(fromBlock, toBlock, res); }); -app.get("/currentApy/:atBlock", async (req, res) => { - const { atBlock } = req.params - let block - if (!isInteger(atBlock)) { - block = await getBlockNumber() - } else { - block = atBlock +app.get("/currentApy/:atBlock?", async (req, res) => { + try { + const { atBlock } = req.params + let blockNumber: bigint + let l1BlockNumber: bigint + if (!atBlock || !isInteger(atBlock)) { + let block = await publicClient.getBlock() + blockNumber = block.number + l1BlockNumber = BigInt((block as any).l1BlockNumber) + } else { + l1BlockNumber = BigInt(atBlock) + blockNumber = await getFirstBlockForL1Block(l1BlockNumber) + } + const apy = await currentApy(blockNumber); + res.jsonp({ blockNumber, l1BlockNumber, apy}) + } catch (e: any) { + console.error(e); + res.status(500).send(e.message); } - logger.log(`Block: ${block}`) - const apy = await currentApy(Number(block)); - res.jsonp({ block, apy}) }); - app.get("/rewards/:lastNBlocks", async (req, res) => { - const lastBlock = await getBlockNumber(); + const lastBlock = await getL1BlockNumber(); const fromBlock = lastBlock - Number(req.params.lastNBlocks); await rewards(fromBlock.toString(), lastBlock.toString(), res); }); diff --git a/packages/rewards-calculator/src/rewardBot.ts b/packages/rewards-calculator/src/rewardBot.ts index b4b237e..8cc52b5 100644 --- a/packages/rewards-calculator/src/rewardBot.ts +++ b/packages/rewards-calculator/src/rewardBot.ts @@ -3,7 +3,7 @@ import { canCommit, commitRewards, epochLength, - getBlockNumber, + getL1BlockNumber, getFirstBlockForL1Block, getLatestCommitment, getRegistrations, @@ -164,7 +164,7 @@ export class RewardBot { ); } - const currentBlock = await getBlockNumber(); + const currentBlock = await getL1BlockNumber(); const lastConfirmedBlock = currentBlock - config.epochConfirmationBlocks; if (lastConfirmedBlock - _lastRewardedBlock < epochLen) { return { fromBlock: 0, toBlock: 0, epochLen, chunkType: 'even' }; diff --git a/packages/rewards-calculator/src/testRPC.ts b/packages/rewards-calculator/src/testRPC.ts index d7e4658..6c06d5c 100644 --- a/packages/rewards-calculator/src/testRPC.ts +++ b/packages/rewards-calculator/src/testRPC.ts @@ -65,10 +65,6 @@ export async function currentApyTest(blockNumber?: number) { console.log(`Latest Distribution: ${await getLatestDistributionBlock()}`) console.log(`Approve Ranges: ${JSON.stringify(await approveRanges())}`) console.log(`APY: ${await currentApy(21279057n)}`) - console.log(`APY: ${await currentApy(21279057)}`) console.log(`APY: ${await currentApy(21279057n)}`) - console.log(`APY: ${await currentApy(21279057)}`) - console.log(`APY: ${await currentApy(21279057n)}`) - console.log(`APY: ${await currentApy(21279057)}`) })().then(() => console.log('Done')) diff --git a/packages/rewards-calculator/src/workers.ts b/packages/rewards-calculator/src/workers.ts index 7be4be6..b37e338 100644 --- a/packages/rewards-calculator/src/workers.ts +++ b/packages/rewards-calculator/src/workers.ts @@ -41,7 +41,7 @@ export class Workers { private workers: Record = {}; private bond = new Decimal(0); private nextDistributionStartBlockNumber = 0n; - + baseApr = new Decimal(0); stakeFactor = new Decimal(0); rAPR = new Decimal(0); @@ -167,7 +167,7 @@ export class Workers { const baseApr = await currentApy( this.nextDistributionStartBlockNumber, ); - this.baseApr = new Decimal(baseApr.toString()); + this.baseApr = bigIntToDecimal(baseApr); this.stakeFactor = this.calculateStakeFactor(); @@ -309,10 +309,7 @@ export class Workers { dayjs(this.clickhouseClient.from), "second", ); - const apy = bigIntToDecimal( - await currentApy(this.nextDistributionStartBlockNumber), - ); - return apy.mul(this.totalSupply()).mul(duration).div(YEAR).div(10_000); + return this.baseApr.mul(this.totalSupply()).mul(duration).div(YEAR).div(10_000); } private calculateStakeFactor() {