Call to new EVM account results in nonzero nonce
Summary of the problem
On a call to an uninitialized account the target account is initialized with a nonce of 1. This is likely connected to the fact that contract accounts should be initialized with a nonce of 1.
Manticore version
0.3.4
Python version
3.8.5
Step to reproduce the behavior
The following test shows the behavior of a call to an empty account created with m.create_account vs. a call to an uninitialized account. If the account is uninitialized before the call, it is initialized with a nonce of 1.
def test_recipient_nonce_unchanged(self):
with disposable_mevm() as m:
recipient = m.create_account(
address=0xffffffffffffffffffffffffffffffffffffffff,
balance=0,
nonce=0,
code=b''
)
caller = m.create_account(
address=0x222222222222222222222222222222222222222,
balance=1000000000000000000
)
m.transaction(
caller=caller,
address=recipient,
data=b'',
value=0
)
self.assertEqual(m.count_ready_states(), 1)
state = next(m.ready_states)
self.assertEqual(state.platform.get_nonce(recipient), 0)
new_recipient = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
m.transaction(
caller=caller,
address=new_recipient,
data=b'',
value=0
)
self.assertEqual(m.count_ready_states(), 1)
state = next(m.ready_states)
# AssertionError: 1 != 0
self.assertEqual(state.platform.get_nonce(new_recipient), 0)
Expected behavior
It's possible this exists for a reason, but it seems logical that a call to an unitialized account would result in the same poststate as a call to an account created with m.create_account(address=....).
I think the nonce in this line in EVMWorld._open_transaction should be int(sort == "CREATE") instead of int(sort != "CREATE"), but there are a few more spots where the nonce of a new account is determined that could maybe be combined or streamlined.