Skip to content

Instantly share code, notes, and snippets.

@pcaversaccio
Last active March 28, 2025 23:05
Show Gist options
  • Save pcaversaccio/36e8fde5c8ad1a4fb0c2d86e9daf3964 to your computer and use it in GitHub Desktop.
Save pcaversaccio/36e8fde5c8ad1a4fb0c2d86e9daf3964 to your computer and use it in GitHub Desktop.
`CREATE`, `CREATE2`, and `CREATE3` Vyper utility functions.
# pragma version ~=0.4.2
"""
@title `CREATE`, `CREATE2`, and `CREATE3` Utility Functions
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
"""
PROXY_CHILD_BYTECODE: constant(Bytes[16]) = x"67363d3d37363d34f03d5260086018f3"
@external
@payable
def deploy_create(init_code: Bytes[4_096], create2: bool = False, salt: bytes32 = empty(bytes32)) -> address:
"""
@dev `CREATE` or `CREATE2` deploys a contract.
@notice Please note that the `init_code` represents the complete
contract creation code, including the ABI-encoded constructor
arguments. When using `CREATE2`, if no `salt` value is provided,
the default `salt` will be the zero value of the `bytes32` type.
"""
return raw_create(init_code, value=msg.value, salt=salt) if create2 else raw_create(init_code, value=msg.value)
@external
@payable
def deploy_create3(init_code: Bytes[4_096], salt: bytes32) -> address:
"""
@dev `CREATE3` (i.e. without an initcode factor) deploys a contract.
@notice Please note that the `init_code` represents the complete
contract creation code, including the ABI-encoded constructor
arguments.
"""
proxy: address = raw_create(PROXY_CHILD_BYTECODE, salt=salt)
raw_call(proxy, init_code, value=msg.value)
new_contract: address = self._compute_create3_address(proxy)
assert new_contract.is_contract, "Contract creation failed"
return new_contract
@internal
@pure
def _compute_create3_address(proxy: address) -> address:
"""
@dev Returns the address where a contract will be stored if
deployed via this contract using the `CREATE3` pattern
(i.e. without an initcode factor).
"""
return convert(
convert(keccak256(concat(x"d694", convert(proxy, bytes20), x"01")), uint256)
& convert(max_value(uint160), uint256),
address,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment