Address.sol 8.6 KB

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