Skip to content

Instantly share code, notes, and snippets.

@0age
Last active May 24, 2023 10:24
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 0age/9a4541cce380a1b2c7e477af06ba6376 to your computer and use it in GitHub Desktop.
Save 0age/9a4541cce380a1b2c7e477af06ba6376 to your computer and use it in GitHub Desktop.
Metamorphic Contract Initialization Code
* @title Metamorphic Contract
* @author 0age, derived from cloner contract by @mhswende
* @notice This contract will create a metamorphic contract, or an upgradeable
* contract that does not rely on a transparent proxy, when deployed using
* CREATE2. It expects the deployer to provide a getImplementation() function
* that will return an implementation address, which it will then clone and
* deploy. Unlike with upgradeable transparent proxies, the state of a
* metamorphic contract will be wiped clean with each upgrade. With great power
* comes great responsibility - implement appropriate controls and educate the
* users of your contract if it will be interacted with!
Initialization Code (29 bytes):
0x5860208158601c335a63aaf10f428752fa158151803b80938091923cf3
Description:
pc|op|name | [stack] | <memory>
*** set the first stack item to zero - used later ***
00 58 getpc [0] <>
*** set the second stack item to 32, length of word returned from staticcall ***
01 60 push1
02 20 outsize [0, 32] <>
*** set the third stack item to 0, position of word returned from staticcall ***
03 81 dup2 [0, 32, 0] <>
*** set the fourth stack item to 4, length of selector given to staticcall ***
04 58 getpc [0, 32, 0, 4] <>
*** set the fifth stack item to 28, position of selector given to staticcall ***
05 60 push1
06 1c inpos [0, 32, 0, 4, 28] <>
*** set the sixth stack item to msg.sender, target address for staticcall ***
07 33 caller [0, 32, 0, 4, 28, caller] <>
*** set the seventh stack item to msg.gas, gas to forward for staticcall ***
08 5a gas [0, 32, 0, 4, 28, caller, gas] <>
*** set the eighth stack item to selector, "what" to store via mstore ***
09 63 push4
10 aaf10f42 selector [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42] <>
*** set the ninth stack item to 0, "where" to store via mstore ***
11 87 dup8 [0, 32, 0, 4, 28, caller, gas, 0xaaf10f42, 0] <>
*** call mstore, consume 8 and 9 from the stack, place selector in memory ***
12 52 mstore [0, 32, 0, 4, 28, caller, gas] <0xaaf10f42>
*** call staticcall, consume 2 through 7 from stack, place address in memory ***
13 fa staticcall [0, 1 (if successful)] <address>
*** flip success bit in second stack item to set to 0 ***
14 15 iszero [0, 0] <address>
*** push a third 0 to the stack, position of address in memory ***
15 81 dup2 [0, 0, 0] <address>
*** place address from position in memory onto third stack item ***
16 51 mload [0, 0, address] <>
*** place address to fourth stack item for extcodesize to consume ***
17 80 dup1 [0, 0, address, address] <>
*** get extcodesize on fourth stack item for extcodecopy ***
18 3b extcodesize [0, 0, address, size] <>
*** dup and swap size for use by return at end of init code ***
19 80 dup1 [0, 0, address, size, size] <>
20 93 swap4 [size, 0, address, size, 0] <>
*** push 0 (code position) to stack and reorder stack items for extcodecopy ***
21 80 dup1 [size, 0, address, size, 0, 0] <>
22 91 swap2 [size, 0, address, 0, 0, size] <>
23 92 swap3 [size, 0, size, 0, 0, address] <>
*** call extcodecopy, consume four stack items, clone runtime code to memory ***
24 3c extcodecopy [size, 0] <code>
*** return to deploy final code in memory ***
25 f3 return [] *deployed!*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment