@@ -121,6 +121,161 @@ describe("Accounting.sol:report", () => {
121121 expect ( simulated . postTotalShares ) . to . equal ( preTotalShares ) ;
122122 expect ( simulated . postTotalPooledEther ) . to . equal ( preTotalPooledEther ) ;
123123 } ) ;
124+
125+ context ( "should match handleOracleReport results" , ( ) => {
126+ it ( "happy path" , async ( ) => {
127+ const simulated = await accounting . simulateOracleReport ( report ( ) ) ;
128+
129+ await accounting . handleOracleReport ( report ( ) ) ;
130+
131+ const postExternalShares = await lido . getExternalShares ( ) ;
132+
133+ expect ( simulated . withdrawalsVaultTransfer ) . to . equal ( 0n ) ;
134+ expect ( simulated . elRewardsVaultTransfer ) . to . equal ( 0n ) ;
135+ expect ( simulated . etherToFinalizeWQ ) . to . equal ( 0n ) ;
136+ expect ( simulated . sharesToFinalizeWQ ) . to . equal ( 0n ) ;
137+ expect ( simulated . sharesToBurnForWithdrawals ) . to . equal ( 0n ) ;
138+ expect ( simulated . totalSharesToBurn ) . to . equal ( 0n ) ;
139+ expect ( simulated . sharesToMintAsFees ) . to . equal ( 0n ) ;
140+
141+ expect ( simulated . principalClBalance ) . to . equal ( 0n ) ;
142+
143+ expect ( simulated . preTotalShares ) . to . equal ( await lido . getTotalShares ( ) ) ;
144+ expect ( simulated . preTotalPooledEther ) . to . equal ( await lido . getTotalPooledEther ( ) ) ;
145+
146+ expect ( simulated . postTotalShares ) . to . equal ( simulated . preTotalShares + simulated . sharesToMintAsFees ) ;
147+ expect ( simulated . postInternalShares ) . to . equal (
148+ simulated . preTotalShares - postExternalShares + simulated . sharesToMintAsFees ,
149+ ) ;
150+ } ) ;
151+
152+ it ( "with CL validators increase" , async ( ) => {
153+ const depositedValidators = 100n ;
154+ const clValidators = 50n ;
155+
156+ await lido . mock__setDepositedValidators ( depositedValidators ) ;
157+
158+ const reportData = report ( { clValidators, clBalance : 0n } ) ;
159+ const simulated = await accounting . simulateOracleReport ( reportData ) ;
160+ const tx = await accounting . handleOracleReport ( reportData ) ;
161+ const receipt = await tx . wait ( ) ;
162+
163+ const collectEvent = receipt ?. logs
164+ . map ( ( log ) => {
165+ try {
166+ return lido . interface . parseLog ( { topics : [ ...log . topics ] , data : log . data } ) ;
167+ } catch {
168+ return null ;
169+ }
170+ } )
171+ . find ( ( e ) => e ?. name === "Mock__CollectRewardsAndProcessWithdrawals" ) ;
172+
173+ if ( collectEvent ) {
174+ expect ( simulated . principalClBalance ) . to . equal ( collectEvent . args . _principalCLBalance ) ;
175+ expect ( simulated . withdrawalsVaultTransfer ) . to . equal ( collectEvent . args . _withdrawalsToWithdraw ) ;
176+ expect ( simulated . elRewardsVaultTransfer ) . to . equal ( collectEvent . args . _elRewardsToWithdraw ) ;
177+ }
178+
179+ const postExternalShares = await lido . getExternalShares ( ) ;
180+
181+ expect ( simulated . withdrawalsVaultTransfer ) . to . equal ( 0n ) ;
182+ expect ( simulated . elRewardsVaultTransfer ) . to . equal ( 0n ) ;
183+ expect ( simulated . etherToFinalizeWQ ) . to . equal ( 0n ) ;
184+ expect ( simulated . sharesToFinalizeWQ ) . to . equal ( 0n ) ;
185+ expect ( simulated . sharesToBurnForWithdrawals ) . to . equal ( 0n ) ;
186+ expect ( simulated . totalSharesToBurn ) . to . equal ( 0n ) ;
187+ expect ( simulated . sharesToMintAsFees ) . to . equal ( 0n ) ;
188+
189+ const expectedPrincipalCl = 0n + clValidators * 32n * 10n ** 18n ;
190+ expect ( simulated . principalClBalance ) . to . equal ( expectedPrincipalCl ) ;
191+
192+ expect ( simulated . preTotalShares ) . to . equal ( await lido . getTotalShares ( ) ) ;
193+ expect ( simulated . preTotalPooledEther ) . to . equal ( await lido . getTotalPooledEther ( ) ) ;
194+
195+ expect ( simulated . postTotalShares ) . to . equal ( simulated . preTotalShares + simulated . sharesToMintAsFees ) ;
196+ expect ( simulated . postInternalShares ) . to . equal (
197+ simulated . preTotalShares - postExternalShares + simulated . sharesToMintAsFees ,
198+ ) ;
199+ } ) ;
200+
201+ it ( "with withdrawal finalization" , async ( ) => {
202+ const depositedValidators = 100n ;
203+ const clValidators = 100n ;
204+ const clBalance = ether ( "3200" ) ;
205+ const withdrawalFinalizationBatches = [ 1n , 2n , 3n ] ;
206+ const simulatedShareRate = 10n ** 27n ;
207+
208+ await lido . mock__setDepositedValidators ( depositedValidators ) ;
209+ await withdrawalQueue . mock__prefinalizeReturn ( ether ( "10" ) , ether ( "0.01" ) ) ;
210+
211+ const reportData = report ( {
212+ clValidators,
213+ clBalance,
214+ withdrawalFinalizationBatches,
215+ simulatedShareRate,
216+ } ) ;
217+
218+ const simulated = await accounting . simulateOracleReport ( reportData ) ;
219+
220+ await accounting . handleOracleReport ( reportData ) ;
221+
222+ const postExternalShares = await lido . getExternalShares ( ) ;
223+
224+ expect ( simulated . withdrawalsVaultTransfer ) . to . equal ( 0n ) ;
225+ expect ( simulated . elRewardsVaultTransfer ) . to . equal ( 0n ) ;
226+ expect ( simulated . etherToFinalizeWQ ) . to . equal ( ether ( "10" ) ) ;
227+ expect ( simulated . sharesToFinalizeWQ ) . to . equal ( ether ( "0.01" ) ) ;
228+ expect ( simulated . sharesToBurnForWithdrawals ) . to . equal ( 0n ) ;
229+ expect ( simulated . totalSharesToBurn ) . to . equal ( 0n ) ;
230+ expect ( simulated . sharesToMintAsFees ) . to . equal ( 0n ) ;
231+
232+ const expectedPrincipalCl = 0n + clValidators * 32n * 10n ** 18n ;
233+ expect ( simulated . principalClBalance ) . to . equal ( expectedPrincipalCl ) ;
234+
235+ expect ( simulated . preTotalShares ) . to . equal ( await lido . getTotalShares ( ) ) ;
236+ expect ( simulated . preTotalPooledEther ) . to . equal ( await lido . getTotalPooledEther ( ) ) ;
237+
238+ expect ( simulated . postTotalShares ) . to . equal ( simulated . preTotalShares + simulated . sharesToMintAsFees ) ;
239+ expect ( simulated . postInternalShares ) . to . equal (
240+ simulated . preTotalShares - postExternalShares + simulated . sharesToMintAsFees ,
241+ ) ;
242+ } ) ;
243+
244+ it ( "with bad debt and external shares" , async ( ) => {
245+ const totalShares = ether ( "1000" ) ;
246+ const externalShares = ether ( "100" ) ;
247+ const badDebtToInternalize = ether ( "50" ) ;
248+
249+ await lido . mock__setTotalShares ( totalShares ) ;
250+ await lido . mock__setExternalShares ( externalShares ) ;
251+ await vaultHub . setBadDebtToInternalize ( badDebtToInternalize ) ;
252+
253+ const simulated = await accounting . simulateOracleReport ( report ( ) ) ;
254+
255+ await accounting . handleOracleReport ( report ( ) ) ;
256+
257+ const preExternalShares = externalShares ;
258+ const preInternalShares = totalShares - preExternalShares ;
259+
260+ expect ( simulated . withdrawalsVaultTransfer ) . to . equal ( 0n ) ;
261+ expect ( simulated . elRewardsVaultTransfer ) . to . equal ( 0n ) ;
262+ expect ( simulated . etherToFinalizeWQ ) . to . equal ( 0n ) ;
263+ expect ( simulated . sharesToFinalizeWQ ) . to . equal ( 0n ) ;
264+ expect ( simulated . sharesToBurnForWithdrawals ) . to . equal ( 0n ) ;
265+ expect ( simulated . totalSharesToBurn ) . to . equal ( 0n ) ;
266+ expect ( simulated . sharesToMintAsFees ) . to . equal ( 0n ) ;
267+
268+ expect ( simulated . principalClBalance ) . to . equal ( 0n ) ;
269+
270+ expect ( simulated . preTotalShares ) . to . equal ( await lido . getTotalShares ( ) ) ;
271+ expect ( simulated . preTotalPooledEther ) . to . equal ( await lido . getTotalPooledEther ( ) ) ;
272+
273+ expect ( simulated . postTotalShares ) . to . equal ( simulated . preTotalShares + simulated . sharesToMintAsFees ) ;
274+ expect ( simulated . postInternalShares ) . to . equal (
275+ preInternalShares + simulated . sharesToMintAsFees + badDebtToInternalize ,
276+ ) ;
277+ } ) ;
278+ } ) ;
124279 } ) ;
125280
126281 context ( "handleOracleReport" , ( ) => {
0 commit comments