@@ -204,7 +204,6 @@ func TestIDTableManyNodes(t *testing.T) {
204204 })
205205
206206 approvedNodesDict := generateCadenceNodeDictionary (approvedNodesStringArray )
207-
208207 // End staking auction
209208 t .Run ("Should end staking auction, pay rewards, and move tokens" , func (t * testing.T ) {
210209
@@ -362,6 +361,139 @@ func TestIDTableManyNodes(t *testing.T) {
362361
363362}
364363
364+ func TestIDTableOutOfBoundsAccess (t * testing.T ) {
365+
366+ t .Parallel ()
367+
368+ b , adapter := newBlockchain (emulator .WithTransactionMaxGasLimit (10000000 ))
369+
370+ env := templates.Environment {
371+ FungibleTokenAddress : emulatorFTAddress ,
372+ FlowTokenAddress : emulatorFlowTokenAddress ,
373+ BurnerAddress : emulatorServiceAccount ,
374+ StorageFeesAddress : emulatorServiceAccount ,
375+ }
376+
377+ accountKeys := test .AccountKeyGenerator ()
378+
379+ // Create new keys for the ID table account
380+ IDTableAccountKey , IDTableSigner := accountKeys .NewWithSigner ()
381+ idTableAddress , _ := deployStakingContract (t , b , IDTableAccountKey , IDTableSigner , & env , true , []uint64 {10000 , 10000 , 10000 , 10000 , 10000 })
382+
383+ env .IDTableAddress = idTableAddress .Hex ()
384+
385+ var nodeAccountKey * flow.AccountKey
386+ var nodeSigner crypto.Signer
387+ var nodeAddress flow.Address
388+
389+ // Create a new node account for nodes
390+ nodeAccountKey , nodeSigner = accountKeys .NewWithSigner ()
391+ nodeAddress , _ = adapter .CreateAccount (context .Background (), []* flow.AccountKey {nodeAccountKey }, nil )
392+
393+ approvedNodes := make ([]cadence.Value , numberOfNodes )
394+ approvedNodesStringArray := make ([]string , numberOfNodes )
395+ nodeRoles := make ([]cadence.Value , numberOfNodes )
396+ nodeNetworkingAddresses := make ([]cadence.Value , numberOfNodes )
397+ nodeNetworkingKeys := make ([]cadence.Value , numberOfNodes )
398+ nodeStakingKeys := make ([]cadence.Value , numberOfNodes )
399+ nodeStakingAmounts := make ([]cadence.Value , numberOfNodes )
400+ nodePaths := make ([]cadence.Value , numberOfNodes )
401+
402+ totalMint := numberOfNodes * nodeMintAmount
403+ mintAmount := fmt .Sprintf ("%d.0" , totalMint )
404+
405+ script := templates .GenerateMintFlowScript (env )
406+ tx := createTxWithTemplateAndAuthorizer (b , script , b .ServiceKey ().Address )
407+ _ = tx .AddArgument (cadence .NewAddress (nodeAddress ))
408+ _ = tx .AddArgument (CadenceUFix64 (mintAmount ))
409+
410+ signAndSubmit (
411+ t , b , tx ,
412+ []flow.Address {},
413+ []crypto.Signer {},
414+ false ,
415+ )
416+
417+ tx = flow .NewTransaction ().
418+ SetScript (templates .GenerateStartStakingScript (env )).
419+ SetGasLimit (9999 ).
420+ SetProposalKey (b .ServiceKey ().Address , b .ServiceKey ().Index , b .ServiceKey ().SequenceNumber ).
421+ SetPayer (b .ServiceKey ().Address ).
422+ AddAuthorizer (idTableAddress )
423+
424+ signAndSubmit (
425+ t , b , tx ,
426+ []flow.Address {idTableAddress },
427+ []crypto.Signer {IDTableSigner },
428+ false ,
429+ )
430+
431+ t .Run ("Should be able to create many valid Node structs" , func (t * testing.T ) {
432+
433+ for i := 0 ; i < numberOfNodes ; i ++ {
434+
435+ id := fmt .Sprintf ("%064d" , i )
436+
437+ approvedNodes [i ] = CadenceString (id )
438+ approvedNodesStringArray [i ] = id
439+
440+ nodeRoles [i ] = cadence .NewUInt8 (uint8 ((i % 4 ) + 1 ))
441+
442+ networkingAddress := fmt .Sprintf ("%0128d" , i )
443+
444+ nodeNetworkingAddresses [i ] = CadenceString (networkingAddress )
445+
446+ _ , stakingKey , _ , networkingKey := generateKeysForNodeRegistration (t )
447+
448+ nodeNetworkingKeys [i ] = CadenceString (networkingKey )
449+
450+ nodeStakingKeys [i ] = CadenceString (stakingKey )
451+
452+ tokenAmount , err := cadence .NewUFix64 ("1500000.0" )
453+ require .NoError (t , err )
454+
455+ nodeStakingAmounts [i ] = tokenAmount
456+ nodePaths [i ] = cadence.Path {Domain : common .PathDomainStorage , Identifier : fmt .Sprintf ("node%06d" , i )}
457+
458+ }
459+
460+ assertCandidateLimitsEquals (t , b , env , []uint64 {10000 , 10000 , 10000 , 10000 , 10000 })
461+
462+ tx := flow .NewTransaction ().
463+ SetScript (templates .GenerateRegisterManyNodesScript (env )).
464+ SetGasLimit (5000000 ).
465+ SetProposalKey (b .ServiceKey ().Address , b .ServiceKey ().Index , b .ServiceKey ().SequenceNumber ).
466+ SetPayer (b .ServiceKey ().Address ).
467+ AddAuthorizer (nodeAddress )
468+
469+ tx .AddArgument (cadence .NewArray (approvedNodes ))
470+ tx .AddArgument (cadence .NewArray (nodeRoles ))
471+ tx .AddArgument (cadence .NewArray (nodeNetworkingAddresses ))
472+ tx .AddArgument (cadence .NewArray (nodeNetworkingKeys ))
473+ tx .AddArgument (cadence .NewArray (nodeStakingKeys ))
474+ tx .AddArgument (cadence .NewArray (nodeStakingAmounts ))
475+ tx .AddArgument (cadence .NewArray (nodePaths ))
476+
477+ signAndSubmit (
478+ t , b , tx ,
479+ []flow.Address {nodeAddress },
480+ []crypto.Signer {nodeSigner },
481+ false ,
482+ )
483+ })
484+
485+ t .Run ("Should end staking auction with no approved nodes which should not fail because of out of bounds array access" , func (t * testing.T ) {
486+
487+ setNodeRoleSlotLimits (t , b , env , idTableAddress , IDTableSigner , [5 ]uint16 {5 , 5 , 5 , 5 , 2 })
488+
489+ scriptResult , err := b .ExecuteScript (templates .GenerateEndStakingTestScript (env ), nil )
490+ require .NoError (t , err )
491+ if ! assert .True (t , scriptResult .Succeeded ()) {
492+ t .Log (scriptResult .Error .Error ())
493+ }
494+ })
495+ }
496+
365497func TestIDTableUnstakeAllManyDelegators (t * testing.T ) {
366498
367499 t .Parallel ()
0 commit comments