|Author||Sergio Demian Lerner|
Add a new opcode,
0xf6, which is similar in idea to
CALL (0xF1), except that it impersonates a sender, i.e. the callee sees a sender different from the real caller. The impersonated sender address is derived from the real caller address and a salt.
This proposal enables native multi-user wallets (wallets that serve multiple users) that can be commanded by EIP-712 based messages and therefore enable meta-transactions. Multi-user wallets also enable the aggregation of transfer operations in batches similar to rollups, but maintaining the same address space as normal onchain transactions, so the sender’s wallet does not need to be upgraded to support sinding ether or tokens to a user of a multi-user wallet. Additionally, many times a sponsor company wants to deploy non-custodial smart wallets for all its users. The sponsor does not want to pay the deployment cost of each user contract in advance. Counterfactual contract creation enables this, yet it forces the sponsor to create the smart wallet (or a proxy contract to it) when the user wants to transfer ether or tokens out of his/her account for the first time. This proposal avoids this extra cost, which is at least 42000 gas per user.
0xf6, takes 7 operands:
gas: the amount of gas the code may use in order to execute;
to: the destination address whose code is to be executed;
in_offset: the offset into memory of the input;
in_size: the size of the input in bytes;
ret_offset: the offset into memory of the output;
ret_size: the size of the scratch pad for the output.
32bytes value (a stack item).
The impersonated sender address is computed as
keccak256( 0xff ++ address ++ salt ++ zeros32)[12:].
0xffis a single byte,
20bytes, and represents the address of the real caller contract.
- The field zeros32 corresponds to 32 zero bytes.
This scheme emulates
CREATE2 address derivation, but it cannot practically collude with the
CREATE2 address space.
- The opcode behaves exactly as
CALLin terms of gas consumption.
- In the called context
CALLER (0x33)returns the impersonated address.
- If value transfer is non-zero in the call, the value is transferred from the impersonated account, and not from the real caller. This can be used to transfer ether out of an impersonated account.
IMPERSONATECALL requires hashing 3 words, implying an additional cost of 180 gas, we think the benefit of accounting for hashing doesn’t not compensate increasing the complexity of the implementation.
We use the zeros32 field to base address derivation in a pre-image of similar size than CREATE2 and reuse the existing address derivation functions. We also avoid worrying about address collisions between EOA derivation (65 bytes pre-image), CREATE derivation (from 23 to 27 bytes pre-image, for a 32bit nonce) and CREATE2 derivation (85 bytes pre-image).
An option is to omit the zeros32 field: the resulting length of the Keccak pre-image for IMPERSONATECALL address is 53 bytes , which does not generate address collision.
While the same functionality could be provided in a pre-compiled contract, we believe using a new opcode is a cleaner solution.
This EIP makes address collisions possible, yet practically impossible.
If a contract already exists with an impersonated address, the
IMPERSONATECALLis executed in the same way, and the existing code will not be executed. It should be noted that
0xff) cannot be executed directly with
IMPERSONATECALLas no opcode is executed in the context of the impersonated account.
The opcode number
0xf6 is currently unused and results in an out-of-gas (OOG) exception. Solidity uses the
INVALID (0xfe) opcode (called
ABORT by EIP-1803) to raise OOG exceptions, so the
0xf6 opcode does not appear in normal Solidity programs. Programmers are already advised not to include this opcode in contracts written in EVM assembly. Therefore is does not pose any backward compatibility risk.
We present 4 examples of impersonated address derivation:
The address derivation scheme prevents address collision with another deployed contract or an externally owned account, as the impersonated sender address is derived from the real caller address and a salt.
Copyright and related rights waived via CC0.
Please cite this document as:
Sergio Demian Lerner, "EIP-2997: IMPERSONATECALL Opcode [DRAFT]," Ethereum Improvement Proposals, no. 2997, September 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2997.