@@ -61,7 +61,7 @@ export class RewardsService {
61
61
}
62
62
63
63
protected async updateRewards ( ) : Promise < void > {
64
- const rewardsPerFrame = await this . getLastTotalRewardsPerFrame ( ) ;
64
+ const rewardsPerFrame = await this . getMinLastTotalRewardsPerFrame ( ) ;
65
65
66
66
if ( ! rewardsPerFrame ) {
67
67
return ;
@@ -72,15 +72,11 @@ export class RewardsService {
72
72
this . rewardsStorage . setElRewardsPerFrame ( rewardsPerFrame . elRewards ) ;
73
73
}
74
74
75
- public async getLastTotalRewardsPerFrame ( ) : Promise < {
76
- clRewards : BigNumber ;
77
- elRewards : BigNumber ;
78
- allRewards : BigNumber ;
79
- } | null > {
80
- const framesFromLastReport = await this . getFramesFromLastReport ( ) ;
81
- if ( framesFromLastReport === null ) {
75
+ public async getMinLastTotalRewardsPerFrame ( ) {
76
+ const framesFromLastReports = await this . getFramesFromLastReports ( ) ;
77
+ if ( framesFromLastReports === null ) {
82
78
this . logger . warn (
83
- 'last rewards was not updated because last TokenRebase events were not found during last 48 hours .' ,
79
+ 'last reward reports were not found because last TokenRebase events were not found during last week .' ,
84
80
{ service : RewardsService . SERVICE_LOG_NAME } ,
85
81
) ;
86
82
return {
@@ -90,41 +86,57 @@ export class RewardsService {
90
86
} ;
91
87
}
92
88
93
- const { blockNumber, frames } = framesFromLastReport ;
89
+ const rewards = await Promise . all (
90
+ framesFromLastReports . map ( async ( { blockNumber, frames } ) => {
91
+ const { clRewards, elRewards } = await this . getRewardsByBlockNumber ( blockNumber , frames ) ;
94
92
95
- if ( frames . eq ( 0 ) ) {
96
- this . logger . warn ( 'last rewards set to 0 because frames passed from last event is 0.' , {
97
- service : RewardsService . SERVICE_LOG_NAME ,
98
- } ) ;
99
- return {
100
- clRewards : BigNumber . from ( 0 ) ,
101
- elRewards : BigNumber . from ( 0 ) ,
102
- allRewards : BigNumber . from ( 0 ) ,
103
- } ;
104
- }
93
+ return {
94
+ clRewards : clRewards ,
95
+ elRewards : elRewards ,
96
+ } ;
97
+ } ) ,
98
+ ) ;
105
99
106
- const { preCLBalance, postCLBalance } = await this . getEthDistributed ( blockNumber ) ;
107
- const elRewards = ( await this . getElRewards ( blockNumber ) ) ?? BigNumber . from ( 0 ) ;
108
- const withdrawalsReceived = ( await this . getWithdrawalsReceived ( blockNumber ) ) ?? BigNumber . from ( 0 ) ;
100
+ let minCL = rewards [ 0 ] . clRewards ;
101
+ let minEL = rewards [ 0 ] . elRewards ;
109
102
110
- const clValidatorsBalanceDiff = postCLBalance . sub ( preCLBalance ) ;
111
- const clRewards = clValidatorsBalanceDiff . add ( withdrawalsReceived ) ;
103
+ rewards . forEach ( ( r ) => {
104
+ if ( minCL . lt ( r . clRewards ) ) {
105
+ minCL = r . clRewards ;
106
+ }
107
+
108
+ if ( minEL . lt ( r . elRewards ) ) {
109
+ minEL = r . elRewards ;
110
+ }
111
+ } ) ;
112
+
113
+ const allRewards = minEL . add ( minEL ) ;
112
114
113
- const allRewards = clRewards . add ( elRewards ) . div ( frames ) ;
114
115
this . logger . log ( `rewardsPerFrame are updated to ${ allRewards . toString ( ) } ` , {
115
116
service : RewardsService . SERVICE_LOG_NAME ,
116
117
} ) ;
117
118
118
119
return {
119
- clRewards : clRewards . div ( frames ) ,
120
- elRewards : elRewards . div ( frames ) ,
120
+ clRewards : minCL ,
121
+ elRewards : minEL ,
121
122
allRewards,
122
123
} ;
123
124
}
124
125
125
- protected async get48HoursAgoBlock ( ) {
126
+ protected async getRewardsByBlockNumber ( blockNumber : number , framesPassed : BigNumber ) {
127
+ const { preCLBalance, postCLBalance } = await this . getEthDistributed ( blockNumber ) ;
128
+ const elRewards = ( await this . getElRewards ( blockNumber ) ) ?? BigNumber . from ( 0 ) ;
129
+ const withdrawalsReceived = ( await this . getWithdrawalsReceived ( blockNumber ) ) ?? BigNumber . from ( 0 ) ;
130
+
131
+ const clValidatorsBalanceDiff = postCLBalance . sub ( preCLBalance ) ;
132
+ const clRewards = clValidatorsBalanceDiff . add ( withdrawalsReceived ) ;
133
+
134
+ return { clRewards : clRewards . div ( framesPassed ) , elRewards : elRewards . div ( framesPassed ) } ;
135
+ }
136
+
137
+ protected async getHoursAgoBlock ( hours : number ) {
126
138
const currentBlock = await this . provider . getBlockNumber ( ) ;
127
- return currentBlock - Math . ceil ( ( 2 * 24 * 60 * 60 ) / SECONDS_PER_SLOT ) ;
139
+ return currentBlock - Math . ceil ( ( hours * 60 * 60 ) / SECONDS_PER_SLOT ) ;
128
140
}
129
141
130
142
protected async getElRewards ( fromBlock : number ) : Promise < BigNumber > {
@@ -135,7 +147,7 @@ export class RewardsService {
135
147
fromBlock,
136
148
address : res . address ,
137
149
} ) ;
138
- const lastLog = logs [ logs . length - 1 ] ;
150
+ const lastLog = logs [ 0 ] ;
139
151
140
152
if ( ! lastLog ) {
141
153
return BigNumber . from ( 0 ) ;
@@ -166,7 +178,7 @@ export class RewardsService {
166
178
167
179
this . logger . log ( 'ETHDistributed event logs' , { service : RewardsService . SERVICE_LOG_NAME , logsCount : logs . length } ) ;
168
180
169
- const lastLog = logs [ logs . length - 1 ] ;
181
+ const lastLog = logs [ 0 ] ;
170
182
171
183
if ( ! lastLog ) {
172
184
this . logger . warn ( 'ETHDistributed event is not found for CL balance.' , {
@@ -215,7 +227,7 @@ export class RewardsService {
215
227
logsCount : logs . length ,
216
228
} ) ;
217
229
218
- const lastLog = logs [ logs . length - 1 ] ;
230
+ const lastLog = logs [ 0 ] ;
219
231
if ( ! lastLog ) {
220
232
return BigNumber . from ( 0 ) ;
221
233
}
@@ -233,11 +245,8 @@ export class RewardsService {
233
245
}
234
246
235
247
// reports can be skipped, so we need timeElapsed (time from last report)
236
- protected async getFramesFromLastReport ( ) : Promise < {
237
- blockNumber : number ;
238
- frames : BigNumber ;
239
- } | null > {
240
- const last48HoursAgoBlock = await this . get48HoursAgoBlock ( ) ;
248
+ protected async getFramesFromLastReports ( ) {
249
+ const weekAgoBlock = await this . getHoursAgoBlock ( 24 * 7 ) ;
241
250
242
251
const res = this . contractLido . filters . TokenRebased ( ) ;
243
252
@@ -246,51 +255,55 @@ export class RewardsService {
246
255
{
247
256
topics : res . topics ,
248
257
toBlock : 'latest' ,
249
- fromBlock : last48HoursAgoBlock ,
258
+ fromBlock : weekAgoBlock ,
250
259
address : res . address ,
251
260
} ,
252
261
this . logger ,
253
262
'TokenRebased' ,
254
263
) ;
255
264
256
- this . logger . log ( 'TokenRebase event logs for last 48 hours ' , {
265
+ this . logger . log ( 'TokenRebase event logs for last week ' , {
257
266
service : RewardsService . SERVICE_LOG_NAME ,
258
267
logsCount : logs . length ,
259
268
} ) ;
260
269
261
270
if ( logs . length === 0 ) {
262
- this . logger . warn ( 'TokenRebase events are not found for last 48 hours .' , {
271
+ this . logger . warn ( 'TokenRebase events are not found for last week .' , {
263
272
service : RewardsService . SERVICE_LOG_NAME ,
264
273
} ) ;
265
274
266
275
return null ;
267
276
}
268
277
269
- const lastLog = logs [ logs . length - 1 ] ;
270
- const parser = new Interface ( [ LIDO_TOKEN_REBASED_EVENT ] ) ;
271
- const parsedData = parser . parseLog ( lastLog ) ;
278
+ const rewardsBlocks = logs . map ( ( log ) => {
279
+ const parser = new Interface ( [ LIDO_TOKEN_REBASED_EVENT ] ) ;
280
+ const parsedData = parser . parseLog ( log ) ;
272
281
273
- this . logger . log ( 'last TokenRebase event for last 48 hours' , {
282
+ return {
283
+ blockNumber : log . blockNumber ,
284
+ frames : BigNumber . from ( parsedData . args . getValue ( 'timeElapsed' ) ) . div (
285
+ SECONDS_PER_SLOT * SLOTS_PER_EPOCH * this . contractConfig . getEpochsPerFrame ( ) ,
286
+ ) ,
287
+ } ;
288
+ } ) ;
289
+
290
+ this . logger . log ( 'last TokenRebase events for last week' , {
274
291
service : RewardsService . SERVICE_LOG_NAME ,
275
- args : parsedData . args ,
276
- timeElapsed : parsedData . args . getValue ( 'timeElapsed' ) ,
277
- blockNumber : lastLog . blockNumber ,
292
+ rewardsBlocks,
278
293
} ) ;
279
294
280
- return {
281
- blockNumber : lastLog . blockNumber ,
282
- frames : BigNumber . from ( parsedData . args . getValue ( 'timeElapsed' ) ) . div (
283
- SECONDS_PER_SLOT * SLOTS_PER_EPOCH * this . contractConfig . getEpochsPerFrame ( ) ,
284
- ) ,
285
- } ;
295
+ return rewardsBlocks ;
286
296
}
287
297
288
298
// it includes WithdrawalVault balance and diff between rewards and cached rewards from previous report
289
- async getVaultsBalance ( ) {
299
+ async getVaultsBalance ( blockNumber : number ) {
290
300
const chainId = this . configService . get ( 'CHAIN_ID' ) ;
291
- const withdrawalVaultAddress = await this . lidoLocator . withdrawalVault ( ) ;
292
- const withdrawalVaultBalance = await this . provider . getBalance ( withdrawalVaultAddress ) ;
293
- const rewardsVaultBalance = await this . provider . getBalance ( EXECUTION_REWARDS_VAULT_CONTRACT_ADDRESSES [ chainId ] ) ;
301
+ const withdrawalVaultAddress = await this . lidoLocator . withdrawalVault ( { blockTag : blockNumber } ) ;
302
+ const withdrawalVaultBalance = await this . provider . getBalance ( withdrawalVaultAddress , blockNumber ) ;
303
+ const rewardsVaultBalance = await this . provider . getBalance (
304
+ EXECUTION_REWARDS_VAULT_CONTRACT_ADDRESSES [ chainId ] ,
305
+ blockNumber ,
306
+ ) ;
294
307
const elRewards = this . rewardsStorage . getElRewardsPerFrame ( ) ;
295
308
const clRewards = this . rewardsStorage . getClRewardsPerFrame ( ) ;
296
309
0 commit comments