@@ -3,7 +3,7 @@ import { ethers } from 'hardhat';
33
44import { createInstances } from '../instance' ;
55import { getSigners , initSigners } from '../signers' ;
6- import { getTxHCUFromTxReceipt , mineNBlocks } from '../utils' ;
6+ import { getTxHCUFromTxReceipt , mineNBlocks , waitForPendingTransactions , waitForTransactionReceipt } from '../utils' ;
77import { deployEncryptedERC20Fixture } from './EncryptedERC20.fixture' ;
88
99// Minimal ABI for HCULimit — the contract is deployed by the host-sc stack
@@ -105,6 +105,7 @@ describe('EncryptedERC20:HCU', function () {
105105 } ) ;
106106
107107 describe ( 'block cap scenarios' , function ( ) {
108+ const BATCHED_TRANSFER_GAS_LIMIT = 1_000_000 ;
108109 let savedHCUPerBlock : bigint ;
109110 let savedMaxHCUPerTx : bigint ;
110111 let savedMaxHCUDepthPerTx : bigint ;
@@ -168,43 +169,6 @@ describe('EncryptedERC20:HCU', function () {
168169 }
169170 } ) ;
170171
171- it ( 'should accumulate HCU from multiple users in the same block' , async function ( ) {
172- await mintAndDistribute ( this ) ;
173- await ethers . provider . send ( 'evm_setIntervalMining' , [ 0 ] ) ;
174-
175- // Fresh block after setup: meter should be 0
176- await mineNBlocks ( 1 ) ;
177- const [ , meter0 ] = await this . hcuLimit . getBlockMeter ( ) ;
178- expect ( meter0 ) . to . eq ( 0n ) ;
179-
180- // Single tx (auto-mines its own block)
181- const tx1 = await sendEncryptedTransfer ( this , 'alice' , this . signers . bob . address , 100 ) ;
182- await tx1 . wait ( ) ;
183- const [ , meter1 ] = await this . hcuLimit . getBlockMeter ( ) ;
184- expect ( meter1 ) . to . be . greaterThan ( meter0 ) ;
185-
186- // Two txs batched in same block — meter must exceed the single-tx reading
187- // Disable automine and batch both txs into one block
188- await ethers . provider . send ( 'evm_setAutomine' , [ false ] ) ;
189- const txA = await sendEncryptedTransfer ( this , 'alice' , this . signers . bob . address , 100 ) ;
190- const txB = await sendEncryptedTransfer ( this , 'bob' , this . signers . alice . address , 100 ) ;
191- await ethers . provider . send ( 'evm_mine' ) ;
192- await ethers . provider . send ( 'evm_setAutomine' , [ true ] ) ;
193- const [ receiptA , receiptB ] = await Promise . all ( [ txA . wait ( ) , txB . wait ( ) ] ) ;
194- expect ( receiptA ?. status ) . to . eq ( 1 ) ;
195- expect ( receiptB ?. status ) . to . eq ( 1 ) ;
196- expect ( receiptA ?. blockNumber ) . to . eq ( receiptB ?. blockNumber ) ;
197- const [ , meter2 ] = await this . hcuLimit . getBlockMeter ( ) ;
198- expect ( meter2 ) . to . be . greaterThan ( meter1 ) ;
199-
200- // Single tx in a new block — meter resets (lower than the two-tx block)
201- const tx3 = await sendEncryptedTransfer ( this , 'alice' , this . signers . bob . address , 100 ) ;
202- await tx3 . wait ( ) ;
203- const [ , meter3 ] = await this . hcuLimit . getBlockMeter ( ) ;
204- expect ( meter3 ) . to . be . greaterThan ( 0n ) ;
205- expect ( meter3 ) . to . be . lessThan ( meter2 ) ;
206- } ) ;
207-
208172 describe ( 'with lowered limits' , function ( ) {
209173 const TIGHT_DEPTH_PER_TX = 400_000 ;
210174 const TIGHT_MAX_PER_TX = 600_000 ;
@@ -213,12 +177,12 @@ describe('EncryptedERC20:HCU', function () {
213177 beforeEach ( async function ( ) {
214178 // Narrowest-first when lowering: hcuPerBlock >= maxHCUPerTx >= maxHCUDepthPerTx
215179 const ownerHcuLimit = this . hcuLimit . connect ( this . deployer ) ;
216- await ownerHcuLimit . setMaxHCUDepthPerTx ( TIGHT_DEPTH_PER_TX ) ;
217- await ownerHcuLimit . setMaxHCUPerTx ( TIGHT_MAX_PER_TX ) ;
218- await ownerHcuLimit . setHCUPerBlock ( TIGHT_PER_BLOCK ) ;
180+ await ( await ownerHcuLimit . setMaxHCUDepthPerTx ( TIGHT_DEPTH_PER_TX ) ) . wait ( ) ;
181+ await ( await ownerHcuLimit . setMaxHCUPerTx ( TIGHT_MAX_PER_TX ) ) . wait ( ) ;
182+ await ( await ownerHcuLimit . setHCUPerBlock ( TIGHT_PER_BLOCK ) ) . wait ( ) ;
219183 } ) ;
220184
221- it ( 'should revert when block HCU cap is exhausted' , async function ( ) {
185+ it ( 'should accumulate HCU across users until the block cap is exhausted' , async function ( ) {
222186 await mintAndDistribute ( this ) ;
223187
224188 await mineNBlocks ( 1 ) ;
@@ -227,14 +191,19 @@ describe('EncryptedERC20:HCU', function () {
227191
228192 // Alice fills the cap, Bob would push block total over — use fixed gasLimit
229193 // to bypass estimateGas (which reverts against pending state)
230- const tx1 = await sendEncryptedTransfer ( this , 'alice' , this . signers . carol . address , 100 ) ;
231- const tx2 = await sendEncryptedTransfer ( this , 'bob' , this . signers . carol . address , 100 , { gasLimit : 1_000_000 } ) ;
194+ const tx1 = await sendEncryptedTransfer ( this , 'alice' , this . signers . carol . address , 100 , {
195+ gasLimit : BATCHED_TRANSFER_GAS_LIMIT ,
196+ } ) ;
197+ const tx2 = await sendEncryptedTransfer ( this , 'bob' , this . signers . carol . address , 100 , {
198+ gasLimit : BATCHED_TRANSFER_GAS_LIMIT ,
199+ } ) ;
200+ await waitForPendingTransactions ( [ tx1 . hash , tx2 . hash ] ) ;
232201
233202 await ethers . provider . send ( 'evm_mine' ) ;
234203 await ethers . provider . send ( 'evm_setAutomine' , [ true ] ) ;
235204 await ethers . provider . send ( 'evm_setIntervalMining' , [ 1 ] ) ;
236205
237- const receipt1 = await tx1 . wait ( ) ;
206+ const receipt1 = await waitForTransactionReceipt ( tx1 . hash ) ;
238207 expect ( receipt1 ?. status ) . to . eq ( 1 , 'First transfer should succeed' ) ;
239208
240209 // Use getTransactionReceipt to avoid ethers throwing on reverted tx
@@ -251,14 +220,19 @@ describe('EncryptedERC20:HCU', function () {
251220 await ethers . provider . send ( 'evm_setIntervalMining' , [ 0 ] ) ;
252221 await ethers . provider . send ( 'evm_setAutomine' , [ false ] ) ;
253222
254- const txAlice = await sendEncryptedTransfer ( this , 'alice' , this . signers . carol . address , 100 ) ;
255- const txBob = await sendEncryptedTransfer ( this , 'bob' , this . signers . carol . address , 100 , { gasLimit : 1_000_000 } ) ;
223+ const txAlice = await sendEncryptedTransfer ( this , 'alice' , this . signers . carol . address , 100 , {
224+ gasLimit : BATCHED_TRANSFER_GAS_LIMIT ,
225+ } ) ;
226+ const txBob = await sendEncryptedTransfer ( this , 'bob' , this . signers . carol . address , 100 , {
227+ gasLimit : BATCHED_TRANSFER_GAS_LIMIT ,
228+ } ) ;
229+ await waitForPendingTransactions ( [ txAlice . hash , txBob . hash ] ) ;
256230
257231 await ethers . provider . send ( 'evm_mine' ) ;
258232 await ethers . provider . send ( 'evm_setAutomine' , [ true ] ) ;
259233 await ethers . provider . send ( 'evm_setIntervalMining' , [ 1 ] ) ;
260234
261- const receiptAlice = await txAlice . wait ( ) ;
235+ const receiptAlice = await waitForTransactionReceipt ( txAlice . hash ) ;
262236 expect ( receiptAlice ?. status ) . to . eq ( 1 , 'Alice should succeed' ) ;
263237
264238 const receiptBob = await ethers . provider . getTransactionReceipt ( txBob . hash ) ;
0 commit comments