manticore icon indicating copy to clipboard operation
manticore copied to clipboard

Call to new EVM account results in nonzero nonce

Open wolflo opened this issue 5 years ago • 1 comments

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=....).

wolflo avatar Sep 01 '20 06:09 wolflo

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.

wolflo avatar Sep 01 '20 12:09 wolflo