Address.sol
1 // SPDX-License-Identifier: MIT 2 3 pragma solidity >=0.6.0; 4 5 /** 6 * @dev Collection of functions related to the address type 7 */ 8 library Address { 9 /** 10 * @dev Returns true if `account` is a contract. 11 * 12 * [IMPORTANT] 13 * ==== 14 * It is unsafe to assume that an address for which this function returns 15 * false is an externally-owned account (EOA) and not a contract. 16 * 17 * Among others, `isContract` will return false for the following 18 * types of addresses: 19 * 20 * - an externally-owned account 21 * - a contract in construction 22 * - an address where a contract will be created 23 * - an address where a contract lived, but was destroyed 24 * ==== 25 */ 26 function isContract(address account) internal view returns (bool) { 27 // This method relies on extcodesize, which returns 0 for contracts in 28 // construction, since the code is only stored at the end of the 29 // constructor execution. 30 31 uint256 size; 32 assembly { 33 size := extcodesize(account) 34 } 35 return size > 0; 36 } 37 38 /** 39 * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 40 * `recipient`, forwarding all available gas and reverting on errors. 41 * 42 * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 43 * of certain opcodes, possibly making contracts go over the 2300 gas limit 44 * imposed by `transfer`, making them unable to receive funds via 45 * `transfer`. {sendValue} removes this limitation. 46 * 47 * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 48 * 49 * IMPORTANT: because control is transferred to `recipient`, care must be 50 * taken to not create reentrancy vulnerabilities. Consider using 51 * {ReentrancyGuard} or the 52 * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 53 */ 54 function sendValue(address payable recipient, uint256 amount) internal { 55 require(address(this).balance >= amount, "Address: insufficient balance"); 56 57 (bool success, ) = recipient.call.value(amount)(bytes("")); 58 require(success, "Address: unable to send value, recipient may have reverted"); 59 } 60 61 /** 62 * @dev Performs a Solidity function call using a low level `call`. A 63 * plain `call` is an unsafe replacement for a function call: use this 64 * function instead. 65 * 66 * If `target` reverts with a revert reason, it is bubbled up by this 67 * function (like regular Solidity function calls). 68 * 69 * Returns the raw returned data. To convert to the expected return value, 70 * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 71 * 72 * Requirements: 73 * 74 * - `target` must be a contract. 75 * - calling `target` with `data` must not revert. 76 * 77 * _Available since v3.1._ 78 */ 79 function functionCall(address target, bytes memory data) internal returns (bytes memory) { 80 return functionCall(target, data, "Address: low-level call failed"); 81 } 82 83 /** 84 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 85 * `errorMessage` as a fallback revert reason when `target` reverts. 86 * 87 * _Available since v3.1._ 88 */ 89 function functionCall( 90 address target, 91 bytes memory data, 92 string memory errorMessage 93 ) internal returns (bytes memory) { 94 return functionCallWithValue(target, data, 0, errorMessage); 95 } 96 97 /** 98 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 99 * but also transferring `value` wei to `target`. 100 * 101 * Requirements: 102 * 103 * - the calling contract must have an ETH balance of at least `value`. 104 * - the called Solidity function must be `payable`. 105 * 106 * _Available since v3.1._ 107 */ 108 function functionCallWithValue( 109 address target, 110 bytes memory data, 111 uint256 value 112 ) internal returns (bytes memory) { 113 return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 114 } 115 116 /** 117 * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 118 * with `errorMessage` as a fallback revert reason when `target` reverts. 119 * 120 * _Available since v3.1._ 121 */ 122 function functionCallWithValue( 123 address target, 124 bytes memory data, 125 uint256 value, 126 string memory errorMessage 127 ) internal returns (bytes memory) { 128 require(address(this).balance >= value, "Address: insufficient balance for call"); 129 require(isContract(target), "Address: call to non-contract"); 130 131 (bool success, bytes memory returndata) = target.call.value(value)(data); 132 return verifyCallResult(success, returndata, errorMessage); 133 } 134 135 /** 136 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 137 * but performing a static call. 138 * 139 * _Available since v3.3._ 140 */ 141 function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 142 return functionStaticCall(target, data, "Address: low-level static call failed"); 143 } 144 145 /** 146 * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 147 * but performing a static call. 148 * 149 * _Available since v3.3._ 150 */ 151 function functionStaticCall( 152 address target, 153 bytes memory data, 154 string memory errorMessage 155 ) internal view returns (bytes memory) { 156 require(isContract(target), "Address: static call to non-contract"); 157 158 (bool success, bytes memory returndata) = target.staticcall(data); 159 return verifyCallResult(success, returndata, errorMessage); 160 } 161 162 /** 163 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 164 * but performing a delegate call. 165 * 166 * _Available since v3.4._ 167 */ 168 function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 169 return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 170 } 171 172 /** 173 * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 174 * but performing a delegate call. 175 * 176 * _Available since v3.4._ 177 */ 178 function functionDelegateCall( 179 address target, 180 bytes memory data, 181 string memory errorMessage 182 ) internal returns (bytes memory) { 183 require(isContract(target), "Address: delegate call to non-contract"); 184 185 (bool success, bytes memory returndata) = target.delegatecall(data); 186 return verifyCallResult(success, returndata, errorMessage); 187 } 188 189 /** 190 * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the 191 * revert reason using the provided one. 192 * 193 * _Available since v4.3._ 194 */ 195 function verifyCallResult( 196 bool success, 197 bytes memory returndata, 198 string memory errorMessage 199 ) internal pure returns (bytes memory) { 200 if (success) { 201 return returndata; 202 } else { 203 // Look for revert reason and bubble it up if present 204 if (returndata.length > 0) { 205 // The easiest way to bubble the revert reason is using memory via assembly 206 207 assembly { 208 let returndata_size := mload(returndata) 209 revert(add(32, returndata), returndata_size) 210 } 211 } else { 212 revert(errorMessage); 213 } 214 } 215 } 216 217 function toAsciiString(address x) internal pure returns (string memory) { 218 bytes memory s = new bytes(40); 219 for (uint i = 0; i < 20; i++) { 220 bytes1 b = bytes1(uint8(uint(uint160(x)) / (2**(8*(19 - i))))); 221 bytes1 hi = bytes1(uint8(b) / 16); 222 bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi)); 223 s[2*i] = char(hi); 224 s[2*i+1] = char(lo); 225 } 226 return string(s); 227 } 228 229 function char(bytes1 b) internal pure returns (bytes1 c) { 230 if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); 231 else return bytes1(uint8(b) + 0x57); 232 } 233 }