1
- // SPDX-License-Identifier: AGPL-3.0
2
- pragma solidity 0.8.10 ;
1
+ // SPDX-License-Identifier: MIT
2
+ // OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
3
+
4
+ pragma solidity ^ 0.8.0 ;
3
5
4
6
/**
5
7
* @dev Collection of functions related to the address type
@@ -23,16 +25,15 @@ library Address {
23
25
* ====
24
26
*/
25
27
function isContract (address account ) internal view returns (bool ) {
26
- // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
27
- // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
28
- // for accounts without code, i.e. `keccak256('')`
29
- bytes32 codehash;
30
- bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 ;
31
- // solhint-disable-next-line no-inline-assembly
28
+ // This method relies on extcodesize, which returns 0 for contracts in
29
+ // construction, since the code is only stored at the end of the
30
+ // constructor execution.
31
+
32
+ uint256 size;
32
33
assembly {
33
- codehash := extcodehash (account)
34
+ size := extcodesize (account)
34
35
}
35
- return (codehash != accountHash && codehash != 0x0 ) ;
36
+ return size > 0 ;
36
37
}
37
38
38
39
/**
@@ -54,8 +55,166 @@ library Address {
54
55
function sendValue (address payable recipient , uint256 amount ) internal {
55
56
require (address (this ).balance >= amount, 'Address: insufficient balance ' );
56
57
57
- // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
58
58
(bool success , ) = recipient.call {value: amount}('' );
59
59
require (success, 'Address: unable to send value, recipient may have reverted ' );
60
60
}
61
+
62
+ /**
63
+ * @dev Performs a Solidity function call using a low level `call`. A
64
+ * plain `call` is an unsafe replacement for a function call: use this
65
+ * function instead.
66
+ *
67
+ * If `target` reverts with a revert reason, it is bubbled up by this
68
+ * function (like regular Solidity function calls).
69
+ *
70
+ * Returns the raw returned data. To convert to the expected return value,
71
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
72
+ *
73
+ * Requirements:
74
+ *
75
+ * - `target` must be a contract.
76
+ * - calling `target` with `data` must not revert.
77
+ *
78
+ * _Available since v3.1._
79
+ */
80
+ function functionCall (address target , bytes memory data ) internal returns (bytes memory ) {
81
+ return functionCall (target, data, 'Address: low-level call failed ' );
82
+ }
83
+
84
+ /**
85
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
86
+ * `errorMessage` as a fallback revert reason when `target` reverts.
87
+ *
88
+ * _Available since v3.1._
89
+ */
90
+ function functionCall (
91
+ address target ,
92
+ bytes memory data ,
93
+ string memory errorMessage
94
+ ) internal returns (bytes memory ) {
95
+ return functionCallWithValue (target, data, 0 , errorMessage);
96
+ }
97
+
98
+ /**
99
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
100
+ * but also transferring `value` wei to `target`.
101
+ *
102
+ * Requirements:
103
+ *
104
+ * - the calling contract must have an ETH balance of at least `value`.
105
+ * - the called Solidity function must be `payable`.
106
+ *
107
+ * _Available since v3.1._
108
+ */
109
+ function functionCallWithValue (
110
+ address target ,
111
+ bytes memory data ,
112
+ uint256 value
113
+ ) internal returns (bytes memory ) {
114
+ return functionCallWithValue (target, data, value, 'Address: low-level call with value failed ' );
115
+ }
116
+
117
+ /**
118
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
119
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
120
+ *
121
+ * _Available since v3.1._
122
+ */
123
+ function functionCallWithValue (
124
+ address target ,
125
+ bytes memory data ,
126
+ uint256 value ,
127
+ string memory errorMessage
128
+ ) internal returns (bytes memory ) {
129
+ require (address (this ).balance >= value, 'Address: insufficient balance for call ' );
130
+ require (isContract (target), 'Address: call to non-contract ' );
131
+
132
+ (bool success , bytes memory returndata ) = target.call {value: value}(data);
133
+ return verifyCallResult (success, returndata, errorMessage);
134
+ }
135
+
136
+ /**
137
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
138
+ * but performing a static call.
139
+ *
140
+ * _Available since v3.3._
141
+ */
142
+ function functionStaticCall (
143
+ address target ,
144
+ bytes memory data
145
+ ) internal view returns (bytes memory ) {
146
+ return functionStaticCall (target, data, 'Address: low-level static call failed ' );
147
+ }
148
+
149
+ /**
150
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
151
+ * but performing a static call.
152
+ *
153
+ * _Available since v3.3._
154
+ */
155
+ function functionStaticCall (
156
+ address target ,
157
+ bytes memory data ,
158
+ string memory errorMessage
159
+ ) internal view returns (bytes memory ) {
160
+ require (isContract (target), 'Address: static call to non-contract ' );
161
+
162
+ (bool success , bytes memory returndata ) = target.staticcall (data);
163
+ return verifyCallResult (success, returndata, errorMessage);
164
+ }
165
+
166
+ /**
167
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
168
+ * but performing a delegate call.
169
+ *
170
+ * _Available since v3.4._
171
+ */
172
+ function functionDelegateCall (address target , bytes memory data ) internal returns (bytes memory ) {
173
+ return functionDelegateCall (target, data, 'Address: low-level delegate call failed ' );
174
+ }
175
+
176
+ /**
177
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
178
+ * but performing a delegate call.
179
+ *
180
+ * _Available since v3.4._
181
+ */
182
+ function functionDelegateCall (
183
+ address target ,
184
+ bytes memory data ,
185
+ string memory errorMessage
186
+ ) internal returns (bytes memory ) {
187
+ require (isContract (target), 'Address: delegate call to non-contract ' );
188
+
189
+ (bool success , bytes memory returndata ) = target.delegatecall (data);
190
+ return verifyCallResult (success, returndata, errorMessage);
191
+ }
192
+
193
+ /**
194
+ * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
195
+ * revert reason using the provided one.
196
+ *
197
+ * _Available since v4.3._
198
+ */
199
+ function verifyCallResult (
200
+ bool success ,
201
+ bytes memory returndata ,
202
+ string memory errorMessage
203
+ ) internal pure returns (bytes memory ) {
204
+ if (success) {
205
+ return returndata;
206
+ } else {
207
+ // Look for revert reason and bubble it up if present
208
+ if (returndata.length > 0 ) {
209
+ // The easiest way to bubble the revert reason is using memory via assembly
210
+
211
+ assembly {
212
+ let returndata_size := mload (returndata)
213
+ revert (add (32 , returndata), returndata_size)
214
+ }
215
+ } else {
216
+ revert (errorMessage);
217
+ }
218
+ }
219
+ }
61
220
}
0 commit comments