Address.sol 7.7 KB

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