Ghost-Contract icon indicating copy to clipboard operation
Ghost-Contract copied to clipboard

FYI: CREATE and CREATE2 don't work this way

Open mattdf opened this issue 2 years ago • 6 comments

Saw this pop up on my feed, posting this so you don't waste any more time.

The address for both CREATE and CREATE2 is chosen before the init payload even starts executing, therefore msg.sender will always be filled in for that account even before the CREATE* call returns.

If you saw the msg.sender = 0x0 behaviour somewhere, then it was probably an error in the testing suite simulating the EVM exec environment.

See: https://mirror.xyz/pfeffunit.eth/yIzhjtR_gzr2DkHNPa1EZAoGftSSJIaZpsFva08oguk

mattdf avatar Apr 15 '22 16:04 mattdf

Yes I noticed that, thanks for the link! Im currently experimenting to see if there is a way to send a transaction from a contract, where the msg.sender has a codesize of 0. I originally thought that the msg.sender could render as 0x00 but as you mentioned and I later found out, it doesn't look to be possible. However, do you know if it is possible call another contract using the CREATE opcode to executing the deployment bytecode but return nothing so that the msg.sender has a code size of 0? This is what I am currently exploring.

0xKitsune avatar Apr 15 '22 17:04 0xKitsune

Yes, that's possible, before a create() call returns, EXTCODESIZE for that address is 0. So EXTCODESIZE(msg.sender) would return 0 if it's being called from within a create() context.

This has been used to exploit contracts in the past that rely on isContract type of functions for security: https://old.reddit.com/r/ethereum/comments/916xni/how_to_pwn_fomo3d_a_beginners_guide/

mattdf avatar Apr 15 '22 17:04 mattdf

Awesome! This is exactly what I have been looking to answer, thank you for the links! So I guess there is no way to definitively know if a smart contract is calling your contract or if an EOA is.

0xKitsune avatar Apr 15 '22 17:04 0xKitsune

There is right now, you can check msg.sender == tx.origin. If account abstraction actually ever happens, that will no longer work, but, in general, you will probably always be able to know if a caller is an EOA or not by just forcing the caller to include a secp256k1 signature, and doing ecrecover(signature) == msg.sender.

Since contract addresses aren't generated by hashing public key, in theory there would never be a case where someone can sign from a contract address, because they'd have to break keccak/sha3 for that.

mattdf avatar Apr 15 '22 17:04 mattdf

The amount of information I just learned in 10 minutes > the past 10 hours haha. Thanks again for this info.

0xKitsune avatar Apr 15 '22 17:04 0xKitsune

There is right now, you can check msg.sender == tx.origin. If account abstraction actually ever happens, that will no longer work, but, in general, you will probably always be able to know if a caller is an EOA or not by just forcing the caller to include a secp256k1 signature, and doing ecrecover(signature) == msg.sender.

Since contract addresses aren't generated by hashing public key, in theory there would never be a case where someone can sign from a contract address, because they'd have to break keccak/sha3 for that.

On the part where you say "...in theory there would never be a case where someone can sign from a contract address, because they'd have to break keccak/sha3 for that." it has been observed that there have been coinbase addresses that are, smart contracts. What's going on there?

Sorry to hijack this thread @0xKitsune <3

sambacha avatar Apr 17 '22 13:04 sambacha