security.adoc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. :github-icon: pass:[<svg class="icon"><use href="#github-icon"/></svg>]
  2. :PullPayment: pass:normal[xref:security.adoc#PullPayment[`PullPayment`]]
  3. :ReentrancyGuard: pass:normal[xref:security.adoc#ReentrancyGuard[`ReentrancyGuard`]]
  4. :Pausable: pass:normal[xref:security.adoc#Pausable[`Pausable`]]
  5. :xref-PullPayment-constructor--: xref:security.adoc#PullPayment-constructor--
  6. :xref-PullPayment-withdrawPayments-address-payable-: xref:security.adoc#PullPayment-withdrawPayments-address-payable-
  7. :xref-PullPayment-payments-address-: xref:security.adoc#PullPayment-payments-address-
  8. :xref-PullPayment-_asyncTransfer-address-uint256-: xref:security.adoc#PullPayment-_asyncTransfer-address-uint256-
  9. :ReentrancyGuard: pass:normal[xref:security.adoc#ReentrancyGuard[`ReentrancyGuard`]]
  10. :Escrow: pass:normal[xref:utils.adoc#Escrow[`Escrow`]]
  11. :xref-ReentrancyGuard-nonReentrant--: xref:security.adoc#ReentrancyGuard-nonReentrant--
  12. :xref-ReentrancyGuard-constructor--: xref:security.adoc#ReentrancyGuard-constructor--
  13. :xref-Pausable-whenNotPaused--: xref:security.adoc#Pausable-whenNotPaused--
  14. :xref-Pausable-whenPaused--: xref:security.adoc#Pausable-whenPaused--
  15. :xref-Pausable-constructor--: xref:security.adoc#Pausable-constructor--
  16. :xref-Pausable-paused--: xref:security.adoc#Pausable-paused--
  17. :xref-Pausable-_requireNotPaused--: xref:security.adoc#Pausable-_requireNotPaused--
  18. :xref-Pausable-_requirePaused--: xref:security.adoc#Pausable-_requirePaused--
  19. :xref-Pausable-_pause--: xref:security.adoc#Pausable-_pause--
  20. :xref-Pausable-_unpause--: xref:security.adoc#Pausable-_unpause--
  21. :xref-Pausable-Paused-address-: xref:security.adoc#Pausable-Paused-address-
  22. :xref-Pausable-Unpaused-address-: xref:security.adoc#Pausable-Unpaused-address-
  23. = Security
  24. [.readme-notice]
  25. NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/security
  26. These contracts aim to cover common security practices.
  27. * {PullPayment}: A pattern that can be used to avoid reentrancy attacks.
  28. * {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions.
  29. * {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending.
  30. TIP: For an overview on reentrancy and the possible mechanisms to prevent it, read our article https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
  31. == Contracts
  32. :_escrow: pass:normal[xref:#PullPayment-_escrow-contract-Escrow[`++_escrow++`]]
  33. :constructor: pass:normal[xref:#PullPayment-constructor--[`++constructor++`]]
  34. :withdrawPayments: pass:normal[xref:#PullPayment-withdrawPayments-address-payable-[`++withdrawPayments++`]]
  35. :payments: pass:normal[xref:#PullPayment-payments-address-[`++payments++`]]
  36. :_asyncTransfer: pass:normal[xref:#PullPayment-_asyncTransfer-address-uint256-[`++_asyncTransfer++`]]
  37. [.contract]
  38. [[PullPayment]]
  39. === `++PullPayment++` link:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/security/PullPayment.sol[{github-icon},role=heading-link]
  40. [.hljs-theme-light.nopadding]
  41. ```solidity
  42. import "@openzeppelin/contracts/security/PullPayment.sol";
  43. ```
  44. Simple implementation of a
  45. https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/external-calls/#favor-pull-over-push-for-external-calls[pull-payment]
  46. strategy, where the paying contract doesn't interact directly with the
  47. receiver account, which must withdraw its payments itself.
  48. Pull-payments are often considered the best practice when it comes to sending
  49. Ether, security-wise. It prevents recipients from blocking execution, and
  50. eliminates reentrancy concerns.
  51. TIP: If you would like to learn more about reentrancy and alternative ways
  52. to protect against it, check out our blog post
  53. https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
  54. To use, derive from the `PullPayment` contract, and use {_asyncTransfer}
  55. instead of Solidity's `transfer` function. Payees can query their due
  56. payments with {payments}, and retrieve them with {withdrawPayments}.
  57. [.contract-index]
  58. .Functions
  59. --
  60. * {xref-PullPayment-constructor--}[`++constructor()++`]
  61. * {xref-PullPayment-withdrawPayments-address-payable-}[`++withdrawPayments(payee)++`]
  62. * {xref-PullPayment-payments-address-}[`++payments(dest)++`]
  63. * {xref-PullPayment-_asyncTransfer-address-uint256-}[`++_asyncTransfer(dest, amount)++`]
  64. --
  65. [.contract-item]
  66. [[PullPayment-constructor--]]
  67. ==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#internal#
  68. [.contract-item]
  69. [[PullPayment-withdrawPayments-address-payable-]]
  70. ==== `[.contract-item-name]#++withdrawPayments++#++(address payable payee)++` [.item-kind]#public#
  71. Withdraw accumulated payments, forwarding all gas to the recipient.
  72. Note that _any_ account can call this function, not just the `payee`.
  73. This means that contracts unaware of the `PullPayment` protocol can still
  74. receive funds this way, by having a separate account call
  75. {withdrawPayments}.
  76. WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
  77. Make sure you trust the recipient, or are either following the
  78. checks-effects-interactions pattern or using {ReentrancyGuard}.
  79. [.contract-item]
  80. [[PullPayment-payments-address-]]
  81. ==== `[.contract-item-name]#++payments++#++(address dest) → uint256++` [.item-kind]#public#
  82. Returns the payments owed to an address.
  83. [.contract-item]
  84. [[PullPayment-_asyncTransfer-address-uint256-]]
  85. ==== `[.contract-item-name]#++_asyncTransfer++#++(address dest, uint256 amount)++` [.item-kind]#internal#
  86. Called by the payer to store the sent amount as credit to be pulled.
  87. Funds sent in this way are stored in an intermediate {Escrow} contract, so
  88. there is no danger of them being spent before withdrawal.
  89. :_NOT_ENTERED: pass:normal[xref:#ReentrancyGuard-_NOT_ENTERED-uint256[`++_NOT_ENTERED++`]]
  90. :_ENTERED: pass:normal[xref:#ReentrancyGuard-_ENTERED-uint256[`++_ENTERED++`]]
  91. :_status: pass:normal[xref:#ReentrancyGuard-_status-uint256[`++_status++`]]
  92. :constructor: pass:normal[xref:#ReentrancyGuard-constructor--[`++constructor++`]]
  93. :nonReentrant: pass:normal[xref:#ReentrancyGuard-nonReentrant--[`++nonReentrant++`]]
  94. :_nonReentrantBefore: pass:normal[xref:#ReentrancyGuard-_nonReentrantBefore--[`++_nonReentrantBefore++`]]
  95. :_nonReentrantAfter: pass:normal[xref:#ReentrancyGuard-_nonReentrantAfter--[`++_nonReentrantAfter++`]]
  96. [.contract]
  97. [[ReentrancyGuard]]
  98. === `++ReentrancyGuard++` link:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/security/ReentrancyGuard.sol[{github-icon},role=heading-link]
  99. [.hljs-theme-light.nopadding]
  100. ```solidity
  101. import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
  102. ```
  103. Contract module that helps prevent reentrant calls to a function.
  104. Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
  105. available, which can be applied to functions to make sure there are no nested
  106. (reentrant) calls to them.
  107. Note that because there is a single `nonReentrant` guard, functions marked as
  108. `nonReentrant` may not call one another. This can be worked around by making
  109. those functions `private`, and then adding `external` `nonReentrant` entry
  110. points to them.
  111. TIP: If you would like to learn more about reentrancy and alternative ways
  112. to protect against it, check out our blog post
  113. https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
  114. [.contract-index]
  115. .Modifiers
  116. --
  117. * {xref-ReentrancyGuard-nonReentrant--}[`++nonReentrant()++`]
  118. --
  119. [.contract-index]
  120. .Functions
  121. --
  122. * {xref-ReentrancyGuard-constructor--}[`++constructor()++`]
  123. --
  124. [.contract-item]
  125. [[ReentrancyGuard-nonReentrant--]]
  126. ==== `[.contract-item-name]#++nonReentrant++#++()++` [.item-kind]#modifier#
  127. Prevents a contract from calling itself, directly or indirectly.
  128. Calling a `nonReentrant` function from another `nonReentrant`
  129. function is not supported. It is possible to prevent this from happening
  130. by making the `nonReentrant` function external, and making it call a
  131. `private` function that does the actual work.
  132. [.contract-item]
  133. [[ReentrancyGuard-constructor--]]
  134. ==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#internal#
  135. :Paused: pass:normal[xref:#Pausable-Paused-address-[`++Paused++`]]
  136. :Unpaused: pass:normal[xref:#Pausable-Unpaused-address-[`++Unpaused++`]]
  137. :_paused: pass:normal[xref:#Pausable-_paused-bool[`++_paused++`]]
  138. :constructor: pass:normal[xref:#Pausable-constructor--[`++constructor++`]]
  139. :whenNotPaused: pass:normal[xref:#Pausable-whenNotPaused--[`++whenNotPaused++`]]
  140. :whenPaused: pass:normal[xref:#Pausable-whenPaused--[`++whenPaused++`]]
  141. :paused: pass:normal[xref:#Pausable-paused--[`++paused++`]]
  142. :_requireNotPaused: pass:normal[xref:#Pausable-_requireNotPaused--[`++_requireNotPaused++`]]
  143. :_requirePaused: pass:normal[xref:#Pausable-_requirePaused--[`++_requirePaused++`]]
  144. :_pause: pass:normal[xref:#Pausable-_pause--[`++_pause++`]]
  145. :_unpause: pass:normal[xref:#Pausable-_unpause--[`++_unpause++`]]
  146. [.contract]
  147. [[Pausable]]
  148. === `++Pausable++` link:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/security/Pausable.sol[{github-icon},role=heading-link]
  149. [.hljs-theme-light.nopadding]
  150. ```solidity
  151. import "@openzeppelin/contracts/security/Pausable.sol";
  152. ```
  153. Contract module which allows children to implement an emergency stop
  154. mechanism that can be triggered by an authorized account.
  155. This module is used through inheritance. It will make available the
  156. modifiers `whenNotPaused` and `whenPaused`, which can be applied to
  157. the functions of your contract. Note that they will not be pausable by
  158. simply including this module, only once the modifiers are put in place.
  159. [.contract-index]
  160. .Modifiers
  161. --
  162. * {xref-Pausable-whenNotPaused--}[`++whenNotPaused()++`]
  163. * {xref-Pausable-whenPaused--}[`++whenPaused()++`]
  164. --
  165. [.contract-index]
  166. .Functions
  167. --
  168. * {xref-Pausable-constructor--}[`++constructor()++`]
  169. * {xref-Pausable-paused--}[`++paused()++`]
  170. * {xref-Pausable-_requireNotPaused--}[`++_requireNotPaused()++`]
  171. * {xref-Pausable-_requirePaused--}[`++_requirePaused()++`]
  172. * {xref-Pausable-_pause--}[`++_pause()++`]
  173. * {xref-Pausable-_unpause--}[`++_unpause()++`]
  174. --
  175. [.contract-index]
  176. .Events
  177. --
  178. * {xref-Pausable-Paused-address-}[`++Paused(account)++`]
  179. * {xref-Pausable-Unpaused-address-}[`++Unpaused(account)++`]
  180. --
  181. [.contract-item]
  182. [[Pausable-whenNotPaused--]]
  183. ==== `[.contract-item-name]#++whenNotPaused++#++()++` [.item-kind]#modifier#
  184. Modifier to make a function callable only when the contract is not paused.
  185. Requirements:
  186. - The contract must not be paused.
  187. [.contract-item]
  188. [[Pausable-whenPaused--]]
  189. ==== `[.contract-item-name]#++whenPaused++#++()++` [.item-kind]#modifier#
  190. Modifier to make a function callable only when the contract is paused.
  191. Requirements:
  192. - The contract must be paused.
  193. [.contract-item]
  194. [[Pausable-constructor--]]
  195. ==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#internal#
  196. Initializes the contract in unpaused state.
  197. [.contract-item]
  198. [[Pausable-paused--]]
  199. ==== `[.contract-item-name]#++paused++#++() → bool++` [.item-kind]#public#
  200. Returns true if the contract is paused, and false otherwise.
  201. [.contract-item]
  202. [[Pausable-_requireNotPaused--]]
  203. ==== `[.contract-item-name]#++_requireNotPaused++#++()++` [.item-kind]#internal#
  204. Throws if the contract is paused.
  205. [.contract-item]
  206. [[Pausable-_requirePaused--]]
  207. ==== `[.contract-item-name]#++_requirePaused++#++()++` [.item-kind]#internal#
  208. Throws if the contract is not paused.
  209. [.contract-item]
  210. [[Pausable-_pause--]]
  211. ==== `[.contract-item-name]#++_pause++#++()++` [.item-kind]#internal#
  212. Triggers stopped state.
  213. Requirements:
  214. - The contract must not be paused.
  215. [.contract-item]
  216. [[Pausable-_unpause--]]
  217. ==== `[.contract-item-name]#++_unpause++#++()++` [.item-kind]#internal#
  218. Returns to normal state.
  219. Requirements:
  220. - The contract must be paused.
  221. [.contract-item]
  222. [[Pausable-Paused-address-]]
  223. ==== `[.contract-item-name]#++Paused++#++(address account)++` [.item-kind]#event#
  224. Emitted when the pause is triggered by `account`.
  225. [.contract-item]
  226. [[Pausable-Unpaused-address-]]
  227. ==== `[.contract-item-name]#++Unpaused++#++(address account)++` [.item-kind]#event#
  228. Emitted when the pause is lifted by `account`.