@@ -360,7 +360,7 @@ TEST(MonadChain, can_sender_dip_into_reserve)
360360 .authorities = authorities,
361361 };
362362 EXPECT_FALSE (
363- can_sender_dip_into_reserve (Address{1 }, 1 , NULL_HASH , context));
363+ can_sender_dip_into_reserve (Address{1 }, 1 , false , context));
364364 }
365365
366366 // False because of authority
@@ -378,7 +378,82 @@ TEST(MonadChain, can_sender_dip_into_reserve)
378378 .authorities = authorities,
379379 };
380380 EXPECT_FALSE (
381- can_sender_dip_into_reserve (Address{1 }, 1 , NULL_HASH, context));
381+ can_sender_dip_into_reserve (Address{1 }, 1 , false , context));
382+ }
383+ }
384+
385+ TYPED_TEST (MonadTraitsTest, reserve_checks_code_hash)
386+ {
387+ using traits = typename TestFixture::Trait;
388+ constexpr Address SENDER{1 };
389+ constexpr Address NEW_CONTRACT{2 };
390+ constexpr uint64_t BASE_FEE_PER_GAS = 10 ;
391+ auto const to_wei = [](uint64_t mon) {
392+ return uint256_t {mon} * 1000000000000000000ULL ;
393+ };
394+
395+ InMemoryMachine machine;
396+ mpt::Db db{machine};
397+ TrieDb tdb{db};
398+ vm::VM vm;
399+ BlockState bs{tdb, vm};
400+
401+ {
402+ State init_state{bs, Incarnation{0 , 0 }};
403+ init_state.add_to_balance (SENDER, to_wei (20 ));
404+ init_state.add_to_balance (NEW_CONTRACT, to_wei (3 ));
405+ MONAD_ASSERT (bs.can_merge (init_state));
406+ bs.merge (init_state);
407+ }
408+
409+ Transaction const tx{
410+ .max_fee_per_gas = BASE_FEE_PER_GAS,
411+ .gas_limit = 1 ,
412+ .type = TransactionType::legacy,
413+ .max_priority_fee_per_gas = 0 ,
414+ };
415+ uint256_t const gas_cost =
416+ uint256_t {BASE_FEE_PER_GAS} * uint256_t {tx.gas_limit };
417+
418+ std::vector<Address> const senders = {SENDER};
419+ std::vector<std::vector<std::optional<Address>>> const authorities = {{}};
420+ ankerl::unordered_dense::segmented_set<Address> senders_and_authorities;
421+ senders_and_authorities.insert (SENDER);
422+ MonadChainContext const context{
423+ .grandparent_senders_and_authorities = nullptr ,
424+ .parent_senders_and_authorities = nullptr ,
425+ .senders_and_authorities = senders_and_authorities,
426+ .senders = senders,
427+ .authorities = authorities};
428+
429+ auto const prepare_state = [&](State &state) {
430+ state.subtract_from_balance (SENDER, gas_cost);
431+ state.subtract_from_balance (NEW_CONTRACT, to_wei (3 ));
432+ byte_string const contract_code{0x60 , 0x00 };
433+ state.set_code (NEW_CONTRACT, contract_code);
434+ };
435+
436+ State state{bs, Incarnation{1 , 1 }};
437+ prepare_state (state);
438+
439+ bool const should_revert = revert_monad_transaction (
440+ traits::monad_rev (),
441+ traits::evm_rev (),
442+ SENDER,
443+ tx,
444+ BASE_FEE_PER_GAS,
445+ 0 ,
446+ state,
447+ context);
448+
449+ if constexpr (traits::monad_rev () < MONAD_FOUR) {
450+ EXPECT_FALSE (should_revert);
451+ }
452+ else if constexpr (traits::monad_rev () >= MONAD_NEXT) {
453+ EXPECT_FALSE (should_revert);
454+ }
455+ else {
456+ EXPECT_TRUE (should_revert);
382457 }
383458}
384459
0 commit comments