-
-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathCreate2Address.vy
90 lines (78 loc) · 3.29 KB
/
Create2Address.vy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# @version ^0.3.7
"""
@title `CREATE2` EVM Opcode Utility Functions for Address Calculations
@license GNU Affero General Public License v3.0
@author pcaversaccio
@notice These functions can be used to compute in advance the address
where a smart contract will be deployed if deployed via the
`CREATE2` opcode. The implementation is inspired by OpenZeppelin's
implementation here:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Create2.sol.
"""
_COLLISION_OFFSET: constant(bytes1) = 0xFF
@external
@payable
def __init__():
"""
@dev To omit the opcodes for checking the `msg.value`
in the creation-time EVM bytecode, the constructor
is declared as `payable`.
"""
pass
@external
@view
def compute_address_self(salt: bytes32, bytecode_hash: bytes32) -> address:
"""
@dev Returns the address where a contract will be stored if
deployed via this contract using the `CREATE2` opcode.
Any change in the `bytecode_hash` or `salt` values will
result in a new destination address.
@param salt The 32-byte random value used to create the contract
address.
@param bytecode_hash The 32-byte bytecode digest of the contract
creation bytecode.
@return address The 20-byte address where a contract will be stored.
"""
return self._compute_address(salt, bytecode_hash, self)
@external
@pure
def compute_address(salt: bytes32, bytecode_hash: bytes32, deployer: address) -> address:
"""
@dev Returns the address where a contract will be stored if
deployed via `deployer` using the `CREATE2` opcode.
Any change in the `bytecode_hash` or `salt` values will
result in a new destination address.
@param salt The 32-byte random value used to create the contract
address.
@param bytecode_hash The 32-byte bytecode digest of the contract
creation bytecode.
@param deployer The 20-byte deployer address.
@return address The 20-byte address where a contract will be stored.
"""
return self._compute_address(salt, bytecode_hash, deployer)
@internal
@pure
def _compute_address(salt: bytes32, bytecode_hash: bytes32, deployer: address) -> address:
"""
@dev An `internal` helper function that returns the address
where a contract will be stored if deployed via `deployer`
using the `CREATE2` opcode. Any change in the `bytecode_hash`
or `salt` values will result in a new destination address.
@param salt The 32-byte random value used to create the contract
address.
@param bytecode_hash The 32-byte bytecode digest of the contract
creation bytecode.
@param deployer The 20-byte deployer address.
@return address The 20-byte address where a contract will be stored.
"""
data: bytes32 = keccak256(concat(_COLLISION_OFFSET, convert(deployer, bytes20), salt, bytecode_hash))
return self._convert_keccak256_2_address(data)
@internal
@pure
def _convert_keccak256_2_address(digest: bytes32) -> address:
"""
@dev Converts a 32-byte keccak256 digest to an address.
@param digest The 32-byte keccak256 digest.
@return address The converted 20-byte address.
"""
return convert(convert(digest, uint256) & max_value(uint160), address)