@@ -284,3 +284,231 @@ pub fn execute(
284
284
) -> Result < Output , ActorError > {
285
285
Machine :: new ( system, runtime, bytecode) . execute ( )
286
286
}
287
+
288
+ #[ cfg( test) ]
289
+ mod tests {
290
+ use crate :: evm_unit_test;
291
+
292
+ macro_rules! check_underflow_err {
293
+ ( $( $ins: ident, ) * ) => {
294
+ $( do_check_underflow_err!( $ins) ; ) *
295
+ }
296
+ }
297
+
298
+ macro_rules! check_underflow_none {
299
+ ( $( $ins: ident, ) * ) => {
300
+ $( do_check_underflow_none!( $ins) ; ) *
301
+ }
302
+ }
303
+
304
+ macro_rules! do_check_underflow_err {
305
+ ( $ins: ident) => {
306
+ {
307
+ evm_unit_test! {
308
+ ( m) { $ins; }
309
+ let result = m. step( ) ;
310
+ assert!( result. is_err( ) , stringify!( $ins) ) ;
311
+ assert_eq!( result. unwrap_err( ) . exit_code( ) , crate :: EVM_CONTRACT_STACK_UNDERFLOW , stringify!( $ins) ) ;
312
+ } ;
313
+ }
314
+ }
315
+ }
316
+
317
+ macro_rules! do_check_underflow_none {
318
+ ( $ins: ident) => { {
319
+ evm_unit_test! {
320
+ ( m) { $ins; }
321
+ let result = m. step( ) ;
322
+ assert!( result. is_ok( ) , stringify!( $ins) ) ;
323
+ } ;
324
+ } } ;
325
+ }
326
+
327
+ #[ test]
328
+ fn test_execution_underflow ( ) {
329
+ check_underflow_err ! (
330
+ ADD ,
331
+ MUL ,
332
+ SUB ,
333
+ DIV ,
334
+ SDIV ,
335
+ MOD ,
336
+ SMOD ,
337
+ ADDMOD ,
338
+ MULMOD ,
339
+ EXP ,
340
+ SIGNEXTEND ,
341
+ LT ,
342
+ GT ,
343
+ SLT ,
344
+ SGT ,
345
+ EQ ,
346
+ ISZERO ,
347
+ AND ,
348
+ OR ,
349
+ XOR ,
350
+ NOT ,
351
+ BYTE ,
352
+ SHL ,
353
+ SHR ,
354
+ SAR ,
355
+ DUP1 ,
356
+ DUP2 ,
357
+ DUP3 ,
358
+ DUP4 ,
359
+ DUP5 ,
360
+ DUP6 ,
361
+ DUP7 ,
362
+ DUP8 ,
363
+ DUP9 ,
364
+ DUP10 ,
365
+ DUP11 ,
366
+ DUP12 ,
367
+ DUP13 ,
368
+ DUP14 ,
369
+ DUP15 ,
370
+ DUP16 ,
371
+ SWAP1 ,
372
+ SWAP2 ,
373
+ SWAP3 ,
374
+ SWAP4 ,
375
+ SWAP5 ,
376
+ SWAP6 ,
377
+ SWAP7 ,
378
+ SWAP8 ,
379
+ SWAP9 ,
380
+ SWAP10 ,
381
+ SWAP11 ,
382
+ SWAP12 ,
383
+ SWAP13 ,
384
+ SWAP14 ,
385
+ SWAP15 ,
386
+ SWAP16 ,
387
+ POP ,
388
+ KECCAK256 ,
389
+ BALANCE ,
390
+ CALLDATALOAD ,
391
+ CALLDATACOPY ,
392
+ EXTCODESIZE ,
393
+ EXTCODECOPY ,
394
+ EXTCODEHASH ,
395
+ RETURNDATACOPY ,
396
+ BLOCKHASH ,
397
+ MLOAD ,
398
+ MSTORE ,
399
+ MSTORE8 ,
400
+ SLOAD ,
401
+ SSTORE ,
402
+ LOG0 ,
403
+ LOG1 ,
404
+ LOG2 ,
405
+ LOG3 ,
406
+ LOG4 ,
407
+ CALL ,
408
+ DELEGATECALL ,
409
+ STATICCALL ,
410
+ CODECOPY ,
411
+ CREATE ,
412
+ CREATE2 ,
413
+ RETURN ,
414
+ REVERT ,
415
+ SELFDESTRUCT ,
416
+ JUMP ,
417
+ JUMPI ,
418
+ ) ;
419
+
420
+ check_underflow_none ! (
421
+ PUSH0 ,
422
+ PUSH1 ,
423
+ PUSH2 ,
424
+ PUSH3 ,
425
+ PUSH4 ,
426
+ PUSH5 ,
427
+ PUSH6 ,
428
+ PUSH7 ,
429
+ PUSH8 ,
430
+ PUSH9 ,
431
+ PUSH10 ,
432
+ PUSH11 ,
433
+ PUSH12 ,
434
+ PUSH13 ,
435
+ PUSH14 ,
436
+ PUSH15 ,
437
+ PUSH16 ,
438
+ PUSH17 ,
439
+ PUSH18 ,
440
+ PUSH19 ,
441
+ PUSH20 ,
442
+ PUSH21 ,
443
+ PUSH22 ,
444
+ PUSH23 ,
445
+ PUSH24 ,
446
+ PUSH25 ,
447
+ PUSH26 ,
448
+ PUSH27 ,
449
+ PUSH28 ,
450
+ PUSH29 ,
451
+ PUSH30 ,
452
+ PUSH31 ,
453
+ PUSH32 ,
454
+ ADDRESS ,
455
+ ORIGIN ,
456
+ CALLER ,
457
+ CALLVALUE ,
458
+ CALLDATASIZE ,
459
+ GASPRICE ,
460
+ RETURNDATASIZE ,
461
+ COINBASE ,
462
+ TIMESTAMP ,
463
+ NUMBER ,
464
+ GASLIMIT ,
465
+ CHAINID ,
466
+ BASEFEE ,
467
+ SELFBALANCE ,
468
+ MSIZE ,
469
+ CODESIZE ,
470
+ JUMPDEST ,
471
+ STOP ,
472
+ PC ,
473
+ ) ;
474
+
475
+ // manual checks
476
+ {
477
+ evm_unit_test ! {
478
+ ( rt) {
479
+ let epoch = 1234 ;
480
+ rt. set_epoch( epoch) ;
481
+ rt. expect_get_randomness_from_beacon(
482
+ fil_actors_runtime:: runtime:: DomainSeparationTag :: EvmPrevRandao ,
483
+ epoch,
484
+ Vec :: from( * b"prevrandao" ) ,
485
+ [ 0xff ; 32 ]
486
+ ) ;
487
+ }
488
+ ( m) { PREVRANDAO ; }
489
+ let result = m. step( ) ;
490
+ assert!( result. is_ok( ) ) ;
491
+ } ;
492
+ }
493
+
494
+ {
495
+ evm_unit_test ! {
496
+ ( rt) {
497
+ rt. expect_gas_available( 1234 ) ;
498
+ }
499
+ ( m) { GAS ; }
500
+ let result = m. step( ) ;
501
+ assert!( result. is_ok( ) ) ;
502
+ } ;
503
+ }
504
+
505
+ {
506
+ evm_unit_test ! {
507
+ ( m) { INVALID ; }
508
+ let result = m. step( ) ;
509
+ assert!( result. is_err( ) ) ;
510
+ assert_eq!( result. unwrap_err( ) . exit_code( ) , crate :: EVM_CONTRACT_INVALID_INSTRUCTION ) ;
511
+ } ;
512
+ }
513
+ }
514
+ }
0 commit comments