diff --git a/content/contracts/5.x/account-abstraction.mdx b/content/contracts/5.x/account-abstraction.mdx
index 70f62927..b5e82664 100644
--- a/content/contracts/5.x/account-abstraction.mdx
+++ b/content/contracts/5.x/account-abstraction.mdx
@@ -85,13 +85,13 @@ To build your own account, see [accounts](/contracts/5.x/accounts).
The smart contract accounts are created by a Factory contract defined by the Account developer. This factory receives arbitrary bytes as `initData` and returns an `address` where the logic of the account is deployed.
-To build your own factory, see [account factories](/contracts/5.x/accounts#accounts_factory).
+To build your own factory, see [account factories](/contracts/5.x/accounts#accounts-factory).
### Paymaster Contract
A Paymaster is an optional entity that can sponsor gas fees for Accounts, or allow them to pay for those fees in ERC-20 instead of native currency. This abstracts gas away from the user experience in the same way that computational costs of cloud servers are abstracted away from end-users.
-To build your own paymaster, see [paymasters](https://docs.openzeppelin.com/community-contracts/0.0.1/paymasters).
+To build your own paymaster, see [paymasters](/contracts/5.x/paymasters).
## Further notes
diff --git a/content/contracts/5.x/accounts.mdx b/content/contracts/5.x/accounts.mdx
index 2b650e3c..cb91a15c 100644
--- a/content/contracts/5.x/accounts.mdx
+++ b/content/contracts/5.x/accounts.mdx
@@ -25,7 +25,7 @@ Since the minimum requirement of [`Account`](/contracts/5.x/api/account#Account)
* [`SignerRSA`](/contracts/5.x/api/utils/cryptography#SignerRSA): Verifies signatures of traditional PKI systems and X.509 certificates.
* [`SignerEIP7702`](/contracts/5.x/api/utils/cryptography#SignerEIP7702): Checks EOA signatures delegated to this signer using [EIP-7702 authorizations](https://eips.ethereum.org/EIPS/eip-7702#set-code-transaction)
* [`SignerERC7913`](/contracts/5.x/api/utils/cryptography#SignerERC7913): Verifies generalized signatures following [ERC-7913](https://eips.ethereum.org/EIPS/eip-7913).
-* [`SignerZKEmail`](https://docs.openzeppelin.com/community-contracts/0.0.1/api/utils/cryptography#SignerZKEmail): Enables email-based authentication for smart contracts using zero-knowledge proofs of email authority signatures.
+* [`SignerZKEmail`](/community-contracts/api/utils/cryptography#SignerZKEmail): Enables email-based authentication for smart contracts using zero-knowledge proofs of email authority signatures.
* [`MultiSignerERC7913`](/contracts/5.x/api/utils/cryptography#MultiSignerERC7913): Allows using multiple ERC-7913 signers with a threshold-based signature verification system.
* [`MultiSignerERC7913Weighted`](/contracts/5.x/api/utils/cryptography#MultiSignerERC7913Weighted): Overrides the threshold mechanism of [`MultiSignerERC7913`](/contracts/5.x/api/utils/cryptography#MultiSignerERC7913), offering different weights per signer.
@@ -45,7 +45,7 @@ Account factories should be carefully implemented to ensure the account address
#### Handling initialization
-Most smart accounts are deployed by a factory, the best practice is to create [minimal clones](/contracts/5.x/api/proxy#minimal_clones) of initializable contracts. These signer implementations provide an initializable design by default so that the factory can interact with the account to set it up right after deployment in a single transaction.
+Most smart accounts are deployed by a factory, the best practice is to create [minimal clones](/contracts/5.x/api/proxy#minimal-clones) of initializable contracts. These signer implementations provide an initializable design by default so that the factory can interact with the account to set it up right after deployment in a single transaction.
```solidity
import {Account} from "@openzeppelin/community-contracts/account/Account.sol";
@@ -82,7 +82,7 @@ function isValidSignature(bytes32 hash, bytes calldata signature) public view ov
```
-We recommend using [ERC7739](/contracts/5.x/api/utils/cryptography#ERC7739) to avoid replayability across accounts. This defensive rehashing mechanism prevents signatures for this account from being replayed in another account controlled by the same signer. See [ERC-7739 signatures](/contracts/5.x/accounts#erc_7739_signatures).
+We recommend using [ERC7739](/contracts/5.x/api/utils/cryptography#ERC7739) to avoid replayability across accounts. This defensive rehashing mechanism prevents signatures for this account from being replayed in another account controlled by the same signer. See [ERC-7739 signatures](/contracts/5.x/accounts#erc-7739-signatures).
### Batched execution
@@ -152,7 +152,7 @@ const userOpData = encodeFunctionData({
## Bundle a `UserOperation`
-[UserOperations](/contracts/5.x/account-abstraction#useroperation) are a powerful abstraction layer that enable more sophisticated transaction capabilities compared to traditional Ethereum transactions. To get started, you’ll need an account, which you can get by [deploying a factory](/contracts/5.x/accounts#accounts_factory) for your implementation.
+[UserOperations](/contracts/5.x/account-abstraction#useroperation) are a powerful abstraction layer that enable more sophisticated transaction capabilities compared to traditional Ethereum transactions. To get started, you’ll need an account, which you can get by [deploying a factory](/contracts/5.x/accounts#accounts-factory) for your implementation.
### Preparing a UserOp
@@ -356,5 +356,5 @@ Smart accounts have evolved to embrace modularity as a design principle, with po
OpenZeppelin Contracts provides both the building blocks for creating ERC-7579-compliant modules and an [`AccountERC7579`](/contracts/5.x/api/account#AccountERC7579) implementation that supports installing and managing these modules.
-Learn more in our [account modules](https://docs.openzeppelin.com/community-contracts/0.0.1/account-modules) section.
+Learn more in our [account modules](/community-contracts/account-modules) section.
diff --git a/content/contracts/5.x/api/access.mdx b/content/contracts/5.x/api/access.mdx
index d64a0bf4..de4304a9 100644
--- a/content/contracts/5.x/api/access.mdx
+++ b/content/contracts/5.x/api/access.mdx
@@ -50,7 +50,7 @@ This directory provides ways to restrict who can access the functions of a contr
## `AccessControl`
-
+
@@ -335,8 +335,7 @@ Roles are often managed via [`AccessControl.grantRole`](#AccessControl-grantRole
purpose is to provide a mechanism for accounts to lose their privileges
if they are compromised (such as when a trusted device is misplaced).
-If the calling account had been revoked `role`, emits a [`IAccessControl.RoleRevoked`](#IAccessControl-RoleRevoked-bytes32-address-address-)
-event.
+Emits a [`IAccessControl.RoleRevoked`](#IAccessControl-RoleRevoked-bytes32-address-address-) event if the calling account had `role` and this call successfully revoked it.
Requirements:
@@ -429,7 +428,7 @@ May emit a [`IAccessControl.RoleRevoked`](#IAccessControl-RoleRevoked-bytes32-ad
## `IAccessControl`
-
+
@@ -687,7 +686,7 @@ Don't confuse with [`IAccessControl.AccessControlUnauthorizedAccount`](#IAccessC
## `Ownable`
-
+
@@ -926,7 +925,7 @@ The owner is not a valid owner account. (eg. `address(0)`)
## `Ownable2Step`
-
+
@@ -1090,7 +1089,7 @@ The new owner accepts the ownership transfer.
## `AccessControlDefaultAdminRules`
-
+
@@ -1775,7 +1774,7 @@ See [`AccessControlDefaultAdminRules.defaultAdminDelayIncreaseWait`](#AccessCont
## `AccessControlEnumerable`
-
+
@@ -1965,7 +1964,7 @@ Overload [`AccessControl._revokeRole`](#AccessControl-_revokeRole-bytes32-addres
## `IAccessControlDefaultAdminRules`
-
+
@@ -2439,7 +2438,7 @@ the operation must wait until `schedule`.
## `IAccessControlEnumerable`
-
+
@@ -2548,7 +2547,7 @@ together with [`AccessControlEnumerable.getRoleMember`](#AccessControlEnumerable
## `AccessManaged`
-
+
@@ -2760,7 +2759,7 @@ is less than 4 bytes long.
## `AccessManager`
-
+
@@ -2916,6 +2915,7 @@ mindful of the danger associated with functions such as [`Ownable.renounceOwners
- [AccessManagerNotReady(operationId)](#IAccessManager-AccessManagerNotReady-bytes32-)
- [AccessManagerExpired(operationId)](#IAccessManager-AccessManagerExpired-bytes32-)
- [AccessManagerLockedRole(roleId)](#IAccessManager-AccessManagerLockedRole-uint64-)
+- [AccessManagerLockedFunction(selector)](#IAccessManager-AccessManagerLockedFunction-bytes4-)
- [AccessManagerBadConfirmation()](#IAccessManager-AccessManagerBadConfirmation--)
- [AccessManagerUnauthorizedAccount(msgsender, roleId)](#IAccessManager-AccessManagerUnauthorizedAccount-address-uint64-)
- [AccessManagerUnauthorizedCall(caller, target, selector)](#IAccessManager-AccessManagerUnauthorizedCall-address-address-bytes4-)
@@ -3433,7 +3433,7 @@ Emits a [`IAccessControl.RoleAdminChanged`](#IAccessControl-RoleAdminChanged-byt
Setting the admin role as the `PUBLIC_ROLE` is allowed, but it will effectively allow
-anyone to set grant or revoke such role.
+anyone to grant or revoke such role.
@@ -3845,7 +3845,7 @@ The identifier of the public role. Automatically granted to all addresses with n
## `AuthorityUtils`
-
+
@@ -3887,7 +3887,7 @@ This helper function takes care of invoking `canCall` in a backwards compatible
## `IAccessManaged`
-
+
@@ -4044,7 +4044,7 @@ Authority that manages this contract was updated.
## `IAccessManager`
-
+
@@ -4115,6 +4115,7 @@ import "@openzeppelin/contracts/access/manager/IAccessManager.sol";
- [AccessManagerNotReady(operationId)](#IAccessManager-AccessManagerNotReady-bytes32-)
- [AccessManagerExpired(operationId)](#IAccessManager-AccessManagerExpired-bytes32-)
- [AccessManagerLockedRole(roleId)](#IAccessManager-AccessManagerLockedRole-uint64-)
+- [AccessManagerLockedFunction(selector)](#IAccessManager-AccessManagerLockedFunction-bytes4-)
- [AccessManagerBadConfirmation()](#IAccessManager-AccessManagerBadConfirmation--)
- [AccessManagerUnauthorizedAccount(msgsender, roleId)](#IAccessManager-AccessManagerUnauthorizedAccount-address-uint64-)
- [AccessManagerUnauthorizedCall(caller, target, selector)](#IAccessManager-AccessManagerUnauthorizedCall-address-address-bytes4-)
@@ -5071,6 +5072,21 @@ Admin delay for a given `target` will be updated to `delay` when `since` is reac
+
+
+
@@ -5167,7 +5183,7 @@ Admin delay for a given `target` will be updated to `delay` when `since` is reac
## `IAuthority`
-
+
diff --git a/content/contracts/5.x/api/account.mdx b/content/contracts/5.x/api/account.mdx
index 7051687f..971ad9b0 100644
--- a/content/contracts/5.x/api/account.mdx
+++ b/content/contracts/5.x/api/account.mdx
@@ -11,6 +11,11 @@ This directory includes contracts to build accounts for ERC-4337. These include:
* [`ERC7821`](#ERC7821): Minimal batch executor implementation contracts. Useful to enable easy batch execution for smart contracts.
* [`ERC4337Utils`](#ERC4337Utils): Utility functions for working with ERC-4337 user operations.
* [`ERC7579Utils`](#ERC7579Utils): Utility functions for working with ERC-7579 modules and account modularity.
+* [`Paymaster`](#Paymaster): An ERC-4337 paymaster implementation that includes the core logic to validate and pay for user operations.
+* [`PaymasterERC20`](#PaymasterERC20): A paymaster that allows users to pay for user operations using ERC-20 tokens.
+* [`PaymasterERC20Guarantor`](#PaymasterERC20Guarantor): A paymaster that enables third parties to guarantee user operations by pre-funding gas costs, with the option for users to repay or for guarantors to absorb the cost.
+* [`PaymasterERC721Owner`](#PaymasterERC721Owner): A paymaster that sponsors user operations for ERC-721 token holders, covering gas costs based on NFT ownership.
+* [`PaymasterSigner`](#PaymasterSigner): A paymaster that sponsors user operations authorized by a signature.
## Core
@@ -24,6 +29,18 @@ This directory includes contracts to build accounts for ERC-4337. These include:
[`ERC7821`](#ERC7821)
+## Paymasters
+
+[`Paymaster`](#Paymaster)
+
+[`PaymasterERC20`](#PaymasterERC20)
+
+[`PaymasterERC20Guarantor`](#PaymasterERC20Guarantor)
+
+[`PaymasterERC721Owner`](#PaymasterERC721Owner)
+
+[`PaymasterSigner`](#PaymasterSigner)
+
## Utilities
[`ERC4337Utils`](#ERC4337Utils)
@@ -36,7 +53,7 @@ This directory includes contracts to build accounts for ERC-4337. These include:
## `Account`
-
+
@@ -53,7 +70,7 @@ Developers must implement the [`AbstractSigner._rawSignatureValidation`](/contra
This core account doesn't include any mechanism for performing arbitrary external calls. This is an essential
-feature that all Account should have. We leave it up to the developers to implement the mechanism of their choice.
+feature that all Accounts should have. We leave it up to the developers to implement the mechanism of their choice.
Common choices include ERC-6900, ERC-7579 and ERC-7821 (among others).
@@ -258,7 +275,7 @@ userOp will result in undefined behavior.
-Virtual function that returns the signable hash for a user operations. Since v0.8.0 of the entrypoint,
+Virtual function that returns the signable hash for a user operation. Since v0.8.0 of the entrypoint,
`userOpHash` is an EIP-712 hash that can be signed directly.
@@ -356,7 +373,7 @@ Unauthorized call to the account.
## `AccountERC7579`
-
+
@@ -981,7 +998,7 @@ The provided initData/deInitData for a fallback module is too short to extract a
## `AccountERC7579Hooked`
-
+
@@ -1269,7 +1286,7 @@ A hook module is already present. This contract only supports one hook module.
## `ERC7821`
-
+
@@ -1391,13 +1408,1246 @@ function _erc7821AuthorizedExecutor(
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/account/paymaster/Paymaster.sol";
+```
+
+A simple ERC4337 paymaster implementation. This base implementation only includes the minimal logic to validate
+and pay for user operations.
+
+Developers must implement the [`Paymaster._validatePaymasterUserOp`](#Paymaster-_validatePaymasterUserOp-struct-PackedUserOperation-bytes32-uint256-) function to define the paymaster's validation
+and payment logic, and [`Paymaster._postOp`](#Paymaster-_postOp-enum-IPaymaster-PostOpMode-bytes-uint256-uint256-) function to define the post-operation logic. The `context` parameter
+is used to pass data between the validation and post execution phases.
+
+The paymaster includes support to call the [`IEntryPointStake`](/contracts/5.x/api/interfaces#IEntryPointStake) interface to manage the paymaster's deposits and stakes
+through the internal functions [`Paymaster._deposit`](#Paymaster-_deposit-uint256-), [`Paymaster._withdraw`](#Paymaster-_withdraw-address-payable-uint256-), [`Paymaster._addStake`](#Paymaster-_addStake-uint256-uint32-), [`Paymaster._unlockStake`](#Paymaster-_unlockStake--) and [`Paymaster._withdrawStake`](#Paymaster-_withdrawStake-address-payable-).
+
+* Deposits are used to pay for user operations.
+* Stakes are used to guarantee the paymaster's reputation and obtain more flexibility in accessing storage.
+
+
+The deposit and stake functions are `internal` so that developers can expose them under the public interface and
+authorization mechanism of their choice. Public versions of [`Paymaster._withdraw`](#Paymaster-_withdraw-address-payable-uint256-), [`Paymaster._unlockStake`](#Paymaster-_unlockStake--) and [`Paymaster._withdrawStake`](#Paymaster-_withdrawStake-address-payable-) MUST
+be exposed and properly authorized, otherwise the deposit and stake will be permanently locked.
+
+Example implementation exposing the deposit and stake functions using [`AccessControl`](/contracts/5.x/api/access#AccessControl):
+
+```solidity
+contract MyPaymaster is Paymaster, AccessControl {
+ bytes32 private constant WITHDRAWER_ROLE = keccak256("WITHDRAWER_ROLE");
+ bytes32 private constant UNSTAKER_ROLE = keccak256("UNSTAKER_ROLE");
+
+ constructor() {
+ _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
+ }
+
+ function deposit() public payable virtual {
+ _deposit(msg.value);
+ }
+
+ function withdraw(address payable to, uint256 value) public virtual onlyRole(WITHDRAWER_ROLE) {
+ _withdraw(to, value);
+ }
+
+ function addStake(uint32 unstakeDelaySec) public payable virtual {
+ _addStake(msg.value, unstakeDelaySec);
+ }
+
+ function unlockStake() public virtual onlyRole(UNSTAKER_ROLE) {
+ _unlockStake();
+ }
+
+ function withdrawStake(address payable to) public virtual onlyRole(UNSTAKER_ROLE) {
+ _withdrawStake(to);
+ }
+
+ function _validatePaymasterUserOp(
+ PackedUserOperation calldata userOp,
+ bytes32 userOpHash,
+ uint256 requiredPreFund
+ ) internal virtual override returns (bytes memory context, uint256 validationData) {
+ // validation logic
+ }
+}
+```
+
+
+See [Paymaster's unstaked reputation rules](https://eips.ethereum.org/EIPS/eip-7562#unstaked-paymasters-reputation-rules)
+ for more details on the paymaster's storage access limitations.
+
+
+
+
+Validates whether the paymaster is willing to pay for the user operation. See
+[`IAccount.validateUserOp`](/contracts/5.x/api/interfaces#IAccount-validateUserOp-struct-PackedUserOperation-bytes32-uint256-) for additional information on the return value.
+
+
+Bundlers will reject this method if it modifies the state, unless it's whitelisted.
+
+
+
+
+Internal validation of whether the paymaster is willing to pay for the user operation.
+Returns the context to be passed to postOp and the validation data.
+
+The `requiredPreFund` is the amount the paymaster has to pay (in native tokens). It's calculated
+as `requiredGas * userOp.maxFeePerGas`, where `required` gas can be calculated from the user operation
+as `verificationGasLimit + callGasLimit + paymasterVerificationGasLimit + paymasterPostOpGasLimit + preVerificationGas`
+
+
+
+Handles post user operation execution logic. The caller must be the entry point.
+
+It receives the `context` returned by `_validatePaymasterUserOp`. Function is not called if no context
+is returned by [`Paymaster.validatePaymasterUserOp`](#Paymaster-validatePaymasterUserOp-struct-PackedUserOperation-bytes32-uint256-).
+
+
+The `actualUserOpFeePerGas` is not `tx.gasprice`. A user operation can be bundled with other transactions
+making the gas price of the user operation to differ.
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/account/paymaster/extensions/PaymasterERC20.sol";
+```
+
+Extension of [`Paymaster`](#Paymaster) that enables users to pay gas with ERC-20 tokens.
+
+To enable this feature, developers must implement the [`PaymasterERC20._fetchDetails`](#PaymasterERC20-_fetchDetails-struct-PackedUserOperation-bytes32-) function:
+
+```solidity
+function _fetchDetails(
+ PackedUserOperation calldata userOp,
+ bytes32 userOpHash
+) internal view override returns (uint256 validationData, IERC20 token, uint256 tokenPerNative) {
+ // Implement logic to fetch the token, and token price from the userOp
+}
+```
+
+The contract follows a pre-charge and refund model:
+1. During validation, it pre-charges the maximum possible gas cost
+2. After execution, it refunds any unused gas back to the user
+
+
+[`PaymasterERC20._prefund`](#PaymasterERC20-_prefund-struct-PackedUserOperation-bytes32-contract-IERC20-uint256-address-uint256-) performs a `transferFrom` during the validation phase, writing to the token contract's storage.
+ERC-7562 restricts unstaked paymasters from such accesses, and public mempool bundlers will reject these operations.
+Stake the paymaster (see [`Paymaster._addStake`](#Paymaster-_addStake-uint256-uint32-)) when deploying against a public mempool.
+
+
+
+The [`PaymasterERC20._withdrawTokens`](#PaymasterERC20-_withdrawTokens-contract-IERC20-address-uint256-) function is `internal` so that developers can expose it under the public interface and
+authorization mechanism of their choice. Public versions of [`PaymasterERC20._withdrawTokens`](#PaymasterERC20-_withdrawTokens-contract-IERC20-address-uint256-) MUST be exposed and properly authorized,
+otherwise the tokens will be permanently stuck in the paymaster.
+
+Example implementation exposing the [`PaymasterERC20._withdrawTokens`](#PaymasterERC20-_withdrawTokens-contract-IERC20-address-uint256-) function using [`AccessControl`](/contracts/5.x/api/access#AccessControl):
+
+```solidity
+contract MyPaymaster is Paymaster, AccessControl {
+ bytes32 private constant WITHDRAWER_ROLE = keccak256("WITHDRAWER_ROLE");
+
+ constructor() {
+ _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
+ }
+
+ function withdrawTokens(IERC20 token, address recipient, uint256 amount) public virtual onlyRole(WITHDRAWER_ROLE) {
+ _withdrawTokens(token, recipient, amount);
+ }
+
+ ...
+}
+```
+
+
+
+
+See [`Paymaster._validatePaymasterUserOp`](#Paymaster-_validatePaymasterUserOp-struct-PackedUserOperation-bytes32-uint256-).
+
+Attempts to retrieve the `token` and `tokenPerNative` from the user operation (see [`PaymasterERC20._fetchDetails`](#PaymasterERC20-_fetchDetails-struct-PackedUserOperation-bytes32-))
+and prefund the user operation using these values and the `maxCost` argument (see [`PaymasterERC20._prefund`](#PaymasterERC20-_prefund-struct-PackedUserOperation-bytes32-contract-IERC20-uint256-address-uint256-)).
+
+Returns `abi.encodePacked(userOpHash, token, tokenPerNative, prefundAmount, prefunder, prefundContext)` in
+`context` if the prefund is successful. Otherwise, it returns empty bytes.
+
+
+
+Charges `prefundAmount` of `token` from `prefunder_` and returns the effective prefund actually pulled.
+
+The base implementation pulls exactly the requested `prefundAmount`. Extensions may inflate the amount
+(e.g. a guarantor adds the cost of the extra postOp work it performs) and must return the effective value.
+
+Returns `(success, prefunder, effectivePrefundAmount, prefundContext)`. `prefundContext` is forwarded to
+[`Paymaster._postOp`](#Paymaster-_postOp-enum-IPaymaster-PostOpMode-bytes-uint256-uint256-) through its `context` argument and may be used by overrides to carry data into [`PaymasterERC20._refund`](#PaymasterERC20-_refund-contract-IERC20-uint256-uint256-uint256-address-uint256-bytes-).
+
+
+Consider not reverting if the prefund fails when overriding this function. This is to avoid reverting
+during the validation phase of the user operation, which may penalize the paymaster's reputation according
+to ERC-7562 validation rules.
+
+
+
+
+Attempts to refund the user operation after execution. See [`PaymasterERC20._refund`](#PaymasterERC20-_refund-contract-IERC20-uint256-uint256-uint256-address-uint256-bytes-).
+
+Reverts with [`PaymasterERC20.PaymasterERC20FailedRefund`](#PaymasterERC20-PaymasterERC20FailedRefund-contract-IERC20-uint256-uint256-bytes-) if the refund fails.
+
+
+This function may revert after the user operation has been executed without
+reverting the user operation itself. Consider implementing a mechanism to handle
+this case gracefully.
+
+
+
+
+Refunds `prefundAmount - actualAmount` of `token` back to `prefunder` and returns the
+`actualAmount` actually charged.
+
+`actualAmount` is pre-computed by [`Paymaster._postOp`](#Paymaster-_postOp-enum-IPaymaster-PostOpMode-bytes-uint256-uint256-) via [`PaymasterERC20._erc20Cost`](#PaymasterERC20-_erc20Cost-uint256-uint256-). Extensions may change it (e.g. a
+guarantor adds its extra postOp cost or zeroes it out after pulling from the user) and must
+return the value that was effectively charged.
+
+Requirements:
+
+- `actualAmount <= prefundAmount`.
+
+
+
+Retrieves payment details for a user operation.
+
+The values returned by this internal function are:
+
+* `validationData`: ERC-4337 validation data, indicating success/failure and optional time validity (`validAfter`, `validUntil`).
+* `token`: Address of the ERC-20 token used for payment to the paymaster.
+* `tokenPerNative`: Token units charged per unit of native currency. This is scaled by `_tokenPerNativeDenominator()`
+ which defaults to 1e18 (wei per eth), making it effectively a number of token units per eth, and not per wei.
+
+#### Calculating the token price
+
+`tokenPerNative` is the multiplier [`PaymasterERC20._erc20Cost`](#PaymasterERC20-_erc20Cost-uint256-uint256-) applies to a native-currency gas cost to produce a token amount:
+`tokenAmount = (nativeCost * tokenPerNative) / _tokenPerNativeDenominator()`. Each elements is denominated as follows:
+
+* `tokenAmount`: token units.
+* `nativeCost`: wei.
+* `tokenPerNative`: token units per eth.
+* `_tokenPerNativeDenominator()`: wei per native coin (1e18 on EVM chains).
+
+For a token priced from USD oracles, derive `tokenPerNative` from the inverse exchange rate:
+
+`tokenPerNative = ( / 1e18) / ( / 10**) * _tokenPerNativeDenominator()`
+
+For example, suppose the token is USDC ($1 with 6 decimals) and the native currency is ETH ($2524.86 with 18 decimals).
+Then 1 wei of gas costs `(2524.86 / 1e18) / (1 / 1e6) = 2.52486e-9` USDC units, so with
+`_tokenPerNativeDenominator() = 1e18` we have `tokenPerNative = 2_524_860_000` (i.e. `2.52486e-9 * 1e18`). Charging
+`actualGasCost` wei yields `actualGasCost * 2_524_860_000 / 1e18` USDC units.
+
+
+
+Denominator used for interpreting the `tokenPerNative` returned by [`PaymasterERC20._fetchDetails`](#PaymasterERC20-_fetchDetails-struct-PackedUserOperation-bytes32-) as "fixed point" in [`PaymasterERC20._erc20Cost`](#PaymasterERC20-_erc20Cost-uint256-uint256-).
+
+
+
+Lower bound on `tokenPerNative` (see [`PaymasterERC20._fetchDetails`](#PaymasterERC20-_fetchDetails-struct-PackedUserOperation-bytes32-) for units). Operations whose `tokenPerNative`
+is strictly below this value are rejected with `SIG_VALIDATION_FAILED` before [`PaymasterERC20._prefund`](#PaymasterERC20-_prefund-struct-PackedUserOperation-bytes32-contract-IERC20-uint256-address-uint256-) runs.
+
+To pick a value, decide:
+
+* `minCharge`: smallest token amount you want to bill per op (e.g. `0.01 USDC = 10_000` units).
+* `minGasCost`: smallest `actualGasCost + _postOpCost() * actualUserOpFeePerGas` you expect, in wei
+ (= `minGas * minFeePerGas`; `minFeePerGas` can be as low as 1 wei on some L2s).
+
+Then set `_minTokensPerNative() >= minCharge * _tokenPerNativeDenominator() / minGasCost`.
+
+Example: a USDC (6 decimals) paymaster on a chain with `minFeePerGas = 1 gwei`, sponsoring
+ops of at least 100_000 gas and charging at least 0.01 USDC per op:
+
+```solidity
+function _minTokensPerNative() internal view override returns (uint256) {
+ return 100e6; // = 1e4 (0.01 USDC) * 1e18 / 1e14 (100_000 gas * 1 gwei) = 100 USDC/ETH
+}
+```
+
+
+Setting `_minTokensPerNative()` below `minCharge * _tokenPerNativeDenominator() / minGasCost`
+lets [`PaymasterERC20._erc20Cost`](#PaymasterERC20-_erc20Cost-uint256-uint256-) round to zero or to dust for the cheapest ops the paymaster accepts,
+sponsoring them at a low (or zero) price.
+
+
+
+
+Emitted when a user operation identified by `userOpHash` is sponsored by this paymaster
+using the specified ERC-20 `token`. The `tokenAmount` is the amount charged for the operation,
+and `tokenPerNative` is the valuation of the token in units of token per native currency (e.g., ETH).
+
+
+
+```solidity
+import "@openzeppelin/contracts/account/paymaster/extensions/PaymasterERC20Guarantor.sol";
+```
+
+Extension of [`PaymasterERC20`](#PaymasterERC20) that enables third parties to guarantee user operations.
+
+This contract allows a guarantor to pre-fund user operations on behalf of users. The guarantor
+pays the maximum possible gas cost upfront, and after execution:
+1. If the user repays the guarantor, the guarantor gets their funds back
+2. If the user fails to repay, the guarantor absorbs the cost
+
+A common use case is for guarantors to pay for the operations of users claiming airdrops. In this scenario:
+
+* The guarantor pays the gas fees upfront
+* The user claims their airdrop tokens
+* The user repays the guarantor from the claimed tokens
+* If the user fails to repay, the guarantor absorbs the cost
+
+The guarantor is identified through the [`PaymasterERC20Guarantor._fetchGuarantor`](#PaymasterERC20Guarantor-_fetchGuarantor-struct-PackedUserOperation-) function, which must be implemented
+by developers to determine who can guarantee operations. This allows for flexible guarantor selection
+logic based on the specific requirements of the application.
+
+
+
+Prefunds the user operation using either the guarantor or the default prefunder, and
+appends `userOp.sender` to the tail of `prefundContext` so the refund process can identify
+the user operation sender.
+
+For guaranteed ops, `prefundAmount` is inflated by [`PaymasterERC20Guarantor._guaranteedPostOpCost`](#PaymasterERC20Guarantor-_guaranteedPostOpCost--) worth of tokens
+so the prefund pulled from the guarantor covers the extra postOp work done in [`PaymasterERC20._refund`](#PaymasterERC20-_refund-contract-IERC20-uint256-uint256-uint256-address-uint256-bytes-)
+([`SafeERC20.trySafeTransferFrom`](/contracts/5.x/api/token/ERC20#SafeERC20-trySafeTransferFrom-contract-IERC20-address-address-uint256-) from the user + [`SafeERC20.trySafeTransfer`](/contracts/5.x/api/token/ERC20#SafeERC20-trySafeTransfer-contract-IERC20-address-uint256-) to the guarantor).
+
+
+
+Handles the refund process for guaranteed operations.
+
+* **Non-guaranteed** (`prefunder == userOp.sender`): pass the base `actualAmount` through to
+ [`PaymasterERC20._refund`](#PaymasterERC20-_refund-contract-IERC20-uint256-uint256-uint256-address-uint256-bytes-).
+* **Guaranteed**: augment `actualAmount` by [`PaymasterERC20Guarantor._guaranteedPostOpCost`](#PaymasterERC20Guarantor-_guaranteedPostOpCost--) * `actualUserOpFeePerGas`
+ (priced in tokens), pull it from `userOp.sender`, and call [`PaymasterERC20._refund`](#PaymasterERC20-_refund-contract-IERC20-uint256-uint256-uint256-address-uint256-bytes-) with
+ `actualAmount = 0` so the guarantor gets the full `prefundAmount` back. If the user fails to pay,
+ the guarantor absorbs the GUARANTEED cost (not the base cost).
+
+
+
+Fetches the guarantor address and validation data from the user operation.
+
+
+Return `address(0)` to disable the guarantor feature. If supported, ensure
+explicit consent (e.g., signature verification) to prevent unauthorized use.
+
+
+
+
+Over-estimates the cost of the post-operation logic. Added on top of [`PaymasterERC20._postOpCost`](#PaymasterERC20-_postOpCost--) for guaranteed userOps.
+
+
+
+```solidity
+import "@openzeppelin/contracts/account/paymaster/extensions/PaymasterERC721Owner.sol";
+```
+
+Extension of [`Paymaster`](#Paymaster) that supports account based on ownership of an ERC-721 token.
+
+This paymaster will sponsor user operations if the user has at least 1 token of the token specified
+during construction.
+
+
+[`Paymaster._validatePaymasterUserOp`](#Paymaster-_validatePaymasterUserOp-struct-PackedUserOperation-bytes32-uint256-) reads `token.balanceOf` during the validation phase, accessing storage in
+an external contract. ERC-7562 restricts unstaked paymasters from such accesses, and public mempool bundlers
+will reject these operations when the token contract is proxied or upgradeable. Stake the paymaster
+(see [`Paymaster._addStake`](#Paymaster-_addStake-uint256-uint32-)) when deploying against a public mempool.
+
+
+
+
+Internal validation of whether the paymaster is willing to pay for the user operation.
+Returns the context to be passed to postOp and the validation data.
+
+
+The default `context` is `bytes(0)`. Developers that add a context when overriding this function MUST
+also override [`Paymaster._postOp`](#Paymaster-_postOp-enum-IPaymaster-PostOpMode-bytes-uint256-uint256-) to process the context passed along.
+
+
+
+
+Virtual function that returns the signable hash for a user operations. Given the `userOpHash`
+contains the `paymasterAndData` itself, it's not possible to sign that value directly. Instead,
+this function must be used to provide a custom mechanism to authorize an user operation.
+
+
+
+Internal validation of whether the paymaster is willing to pay for the user operation.
+Returns the context to be passed to postOp and the validation data.
+
+
+The `context` returned is `bytes(0)`. Developers overriding this function MUST
+override [`Paymaster._postOp`](#Paymaster-_postOp-enum-IPaymaster-PostOpMode-bytes-uint256-uint256-) to process the context passed along.
+
+
+
+
+Decodes the user operation's data from `paymasterAndData`.
+
+
+
+
## `EIP7702Utils`
-
+
@@ -1441,14 +2691,14 @@ Returns the address of the delegate if `account` has an EIP-7702 delegation setu
## `IEntryPointExtra`
-
+
```solidity
-import "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol";
+import "@openzeppelin/contracts/account/utils/ERC4337Utils.sol";
```
This is available on all entrypoint since v0.4.0, but is not formally part of the ERC.
@@ -1481,14 +2731,14 @@ This is available on all entrypoint since v0.4.0, but is not formally part of th
## `ERC4337Utils`
-
+
```solidity
-import "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol";
+import "@openzeppelin/contracts/account/utils/ERC4337Utils.sol";
```
Library with common ERC-4337 utility functions.
@@ -1879,7 +3129,7 @@ Returns empty bytes if no paymaster signature is present.
## `Mode`
-
+
@@ -1895,7 +3145,7 @@ import "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
## `CallType`
-
+
@@ -1911,7 +3161,7 @@ import "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
## `ExecType`
-
+
@@ -1927,7 +3177,7 @@ import "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
## `ModeSelector`
-
+
@@ -1943,7 +3193,7 @@ import "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
## `ModePayload`
-
+
@@ -1959,7 +3209,7 @@ import "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
## `ERC7579Utils`
-
+
@@ -2344,7 +3594,7 @@ Input calldata not properly formatted and possibly malicious.
## `eqCallType`
-
+
@@ -2379,7 +3629,7 @@ Compares two `CallType` values for equality.
## `eqExecType`
-
+
@@ -2414,7 +3664,7 @@ Compares two `ExecType` values for equality.
## `eqModeSelector`
-
+
@@ -2449,7 +3699,7 @@ Compares two `ModeSelector` values for equality.
## `eqModePayload`
-
+
diff --git a/content/contracts/5.x/api/crosschain.mdx b/content/contracts/5.x/api/crosschain.mdx
index 9e475f3d..08ec3dbb 100644
--- a/content/contracts/5.x/api/crosschain.mdx
+++ b/content/contracts/5.x/api/crosschain.mdx
@@ -6,26 +6,41 @@ description: "Smart contract crosschain utilities and implementations"
This directory contains contracts for sending and receiving cross chain messages that follows the ERC-7786 standard.
* [`CrosschainLinked`](#CrosschainLinked): helper to facilitate communication between a contract on one chain and counterparts on remote chains through ERC-7786 gateways.
+* [`CrosschainRemoteExecutor`](#CrosschainRemoteExecutor): executor contract that relays transaction from a controller on a remote chain.
* [`ERC7786Recipient`](#ERC7786Recipient): generic ERC-7786 crosschain contract that receives messages from a trusted gateway.
Additionally there are multiple bridge constructions:
* [`BridgeFungible`](#BridgeFungible): Core bridging logic for crosschain ERC-20 transfer. Used by [`BridgeERC20`](#BridgeERC20), [`BridgeERC7802`](#BridgeERC7802) and [`ERC20Crosschain`](/contracts/5.x/api/token/ERC20#ERC20Crosschain),
+* [`BridgeNonFungible`](#BridgeNonFungible): Core bridging logic for crosschain ERC-721 transfer. Used by [`BridgeERC721`](#BridgeERC721) and [`ERC721Crosschain`](/contracts/5.x/api/token/ERC721#ERC721Crosschain),
+* [`BridgeMultiToken`](#BridgeMultiToken): Core bridging logic for crosschain ERC-1155 transfer. Used by [`BridgeERC1155`](#BridgeERC1155) and [`ERC1155Crosschain`](/contracts/5.x/api/token/ERC1155#ERC1155Crosschain),
* [`BridgeERC20`](#BridgeERC20): Standalone bridge contract to connect an ERC-20 token contract with counterparts on remote chains,
+* [`BridgeERC721`](#BridgeERC721): Standalone bridge contract to connect an ERC-721 token contract with counterparts on remote chains,
+* [`BridgeERC1155`](#BridgeERC1155): Standalone bridge contract to connect an ERC-1155 token contract with counterparts on remote chains,
* [`BridgeERC7802`](#BridgeERC7802): Standalone bridge contract to connect an ERC-7802 token contract with counterparts on remote chains.
## Helpers
[`CrosschainLinked`](#CrosschainLinked)
+[`CrosschainRemoteExecutor`](#CrosschainRemoteExecutor)
+
[`ERC7786Recipient`](#ERC7786Recipient)
## Bridges
[`BridgeFungible`](#BridgeFungible)
+[`BridgeNonFungible`](#BridgeNonFungible)
+
+[`BridgeMultiToken`](#BridgeMultiToken)
+
[`BridgeERC20`](#BridgeERC20)
+[`BridgeERC721`](#BridgeERC721)
+
+[`BridgeERC1155`](#BridgeERC1155)
+
[`BridgeERC7802`](#BridgeERC7802)
@@ -34,7 +49,7 @@ Additionally there are multiple bridge constructions:
## `CrosschainLinked`
-
+
@@ -51,7 +66,7 @@ gateways. It ensure received messages originate from a counterpart. This is the
[`BridgeFungible`](#BridgeFungible).
Contracts that inherit from this contract can use the internal [`CrosschainLinked._sendMessageToCounterpart`](#CrosschainLinked-_sendMessageToCounterpart-bytes-bytes-bytes---) to send messages to their
-counterpart on a foreign chain. They must override the [`ERC7786Recipient._processMessage`](#ERC7786Recipient-_processMessage-address-bytes32-bytes-bytes-) function to handle messages that have
+counterpart on a foreign chain. They must override the [`CrosschainRemoteExecutor._processMessage`](#CrosschainRemoteExecutor-_processMessage-address-bytes32-bytes-bytes-) function to handle messages that have
been verified.
@@ -225,13 +240,237 @@ Note: the `chain` argument is a "chain-only" InteroperableAddress (empty address
+
+```solidity
+import "@openzeppelin/contracts/crosschain/CrosschainRemoteExecutor.sol";
+```
+
+Helper contract used to relay transactions received from a controller through an ERC-7786 gateway. This is
+used by the [`GovernorCrosschain`](/contracts/5.x/api/governance#GovernorCrosschain) governance module for the execution of cross-chain actions.
+
+A [`CrosschainRemoteExecutor`](#CrosschainRemoteExecutor) address can be seen as the local identity of a remote executor on another chain. It
+holds assets and permissions for the sake of its controller.
+
+
+
+Endpoint allowing the controller to reconfigure the executor. This must be called by the executor itself
+following an instruction from the controller.
+
+
+
+Virtual getter that returns whether an address is a valid ERC-7786 gateway for a given sender.
+
+The `sender` parameter is an interoperable address that include the source chain. The chain part can be
+extracted using the [`InteroperableAddress`](/contracts/5.x/api/utils#InteroperableAddress) library to selectively authorize gateways based on the origin chain
+of a message.
+
+
+
+Virtual function that should contain the logic to execute when a cross-chain message is received.
+
+
+This function should revert on failure. Any silent failure from this function will result in the message
+being marked as received and not being retryable.
+
+
+
+
+Reverted when a non-controller tries to relay instructions to this executor.
+
+
+
+
## `ERC7786Recipient`
-
+
@@ -247,10 +486,10 @@ This abstract contract exposes the `receiveMessage` function that is used for co
destination gateways. This contract leaves two functions unimplemented:
* [`CrosschainLinked._isAuthorizedGateway`](#CrosschainLinked-_isAuthorizedGateway-address-bytes-), an internal getter used to verify whether an address is recognised by the contract as a
-valid ERC-7786 destination gateway. One or multiple gateway can be supported. Note that any malicious address for
+valid ERC-7786 destination gateway. One or multiple gateways can be supported. Note that any malicious address for
which this function returns true would be able to impersonate any account on any other chain sending any message.
-* [`ERC7786Recipient._processMessage`](#ERC7786Recipient-_processMessage-address-bytes32-bytes-bytes-), the internal function that will be called with any message that has been validated.
+* [`CrosschainRemoteExecutor._processMessage`](#CrosschainRemoteExecutor-_processMessage-address-bytes32-bytes-bytes-), the internal function that will be called with any message that has been validated.
ERC-7786 requires the gateway to ensure messages are not delivered more than once. Therefore, we don't need to keep
track of the processed receiveId.
@@ -352,38 +591,47 @@ Error thrown if the gateway is not authorized to send messages to this contract
```solidity
-import "@openzeppelin/contracts/crosschain/bridges/BridgeERC20.sol";
+import "@openzeppelin/contracts/crosschain/bridges/BridgeERC1155.sol";
```
-This is a variant of [`BridgeFungible`](#BridgeFungible) that implements the bridge logic for ERC-20 tokens that do not expose a
-crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
+This is a variant of [`BridgeMultiToken`](#BridgeMultiToken) that implements the bridge logic for ERC-1155 tokens that do not expose
+a crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
-BridgeFungible
+BridgeMultiToken
-- [CrosschainFungibleTransferSent(sendId, from, to, amount)](#BridgeFungible-CrosschainFungibleTransferSent-bytes32-address-bytes-uint256-)
-- [CrosschainFungibleTransferReceived(receiveId, from, to, amount)](#BridgeFungible-CrosschainFungibleTransferReceived-bytes32-bytes-address-uint256-)
+- [CrosschainMultiTokenTransferSent(sendId, from, to, ids, values)](#BridgeMultiToken-CrosschainMultiTokenTransferSent-bytes32-address-bytes-uint256---uint256---)
+- [CrosschainMultiTokenTransferReceived(receiveId, from, to, ids, values)](#BridgeMultiToken-CrosschainMultiTokenTransferReceived-bytes32-bytes-address-uint256---uint256---)
@@ -441,14 +689,14 @@ crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
```solidity
-import "@openzeppelin/contracts/crosschain/bridges/BridgeERC7802.sol";
+import "@openzeppelin/contracts/crosschain/bridges/BridgeERC20.sol";
```
-This is a variant of [`BridgeFungible`](#BridgeFungible) that implements the bridge logic for ERC-7802 compliant tokens.
+This is a variant of [`BridgeFungible`](#BridgeFungible) that implements the bridge logic for ERC-20 tokens that do not expose a
+crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
+
+
+Any mechanism in which the underlying token changes the [`IERC20.balanceOf`](/contracts/5.x/api/token/ERC20#IERC20-balanceOf-address-) of an account without an explicit
+transfer may desynchronize this contract's custodied balance from the supply minted or unlocked on the counterpart
+chain. Once the counterpart chain supply exceeds the custodied balance, redemptions on this chain revert in
+[`SafeERC20.safeTransfer`](/contracts/5.x/api/token/ERC20#SafeERC20-safeTransfer-contract-IERC20-address-uint256-) due to insufficient balance.
+
Functions
-- [constructor(token_)](#BridgeERC7802-constructor-contract-IERC7802-)
-- [token()](#BridgeERC7802-token--)
-- [_onSend(from, amount)](#BridgeERC7802-_onSend-address-uint256-)
-- [_onReceive(to, amount)](#BridgeERC7802-_onReceive-address-uint256-)
+- [constructor(token_)](#BridgeERC20-constructor-contract-IERC20-)
+- [token()](#BridgeERC20-token--)
+- [_onSend(from, amount)](#BridgeERC20-_onSend-address-uint256-)
+- [_onReceive(to, amount)](#BridgeERC20-_onReceive-address-uint256-)
BridgeFungible
@@ -593,14 +921,14 @@ This is a variant of [`BridgeFungible`](#BridgeFungible) that implements the bri
```solidity
-import "@openzeppelin/contracts/crosschain/bridges/abstract/BridgeFungible.sol";
+import "@openzeppelin/contracts/crosschain/bridges/BridgeERC721.sol";
```
-Base contract for bridging ERC-20 between chains using an ERC-7786 gateway.
-
-In order to use this contract, two functions must be implemented to link it to the token:
-* [`BridgeERC20._onSend`](#BridgeERC20-_onSend-address-uint256-): called when a crosschain transfer is going out. Must take the sender tokens or revert.
-* [`BridgeERC20._onReceive`](#BridgeERC20-_onReceive-address-uint256-): called when a crosschain transfer is coming in. Must give tokens to the receiver.
-
-This base contract is used by the [`BridgeERC20`](#BridgeERC20), which interfaces with legacy ERC-20 tokens, and [`BridgeERC7802`](#BridgeERC7802),
-which interface with ERC-7802 to provide an approve-free user experience. It is also used by the [`ERC20Crosschain`](/contracts/5.x/api/token/ERC20#ERC20Crosschain)
-extension, which embeds the bridge logic directly in the token contract.
+This is a variant of [`BridgeNonFungible`](#BridgeNonFungible) that implements the bridge logic for ERC-721 tokens that do not expose
+a crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
Functions
-- [crosschainTransfer(to, amount)](#BridgeFungible-crosschainTransfer-bytes-uint256-)
-- [_crosschainTransfer(from, to, amount)](#BridgeFungible-_crosschainTransfer-address-bytes-uint256-)
-- [_processMessage(, receiveId, , payload)](#BridgeFungible-_processMessage-address-bytes32-bytes-bytes-)
-- [_onSend(from, amount)](#BridgeFungible-_onSend-address-uint256-)
-- [_onReceive(to, amount)](#BridgeFungible-_onReceive-address-uint256-)
+- [constructor(token_)](#BridgeERC721-constructor-contract-IERC721-)
+- [token()](#BridgeERC721-token--)
+- [crosschainTransferFrom(from, to, tokenId)](#BridgeERC721-crosschainTransferFrom-address-bytes-uint256-)
+- [_onSend(from, tokenId)](#BridgeERC721-_onSend-address-uint256-)
+- [_onReceive(to, tokenId)](#BridgeERC721-_onReceive-address-uint256-)
+
+BridgeNonFungible
+
+- [_crosschainTransfer(from, to, tokenId)](#BridgeNonFungible-_crosschainTransfer-address-bytes-uint256-)
+- [_processMessage(, receiveId, , payload)](#BridgeNonFungible-_processMessage-address-bytes32-bytes-bytes-)
+
+CrosschainLinked
@@ -712,8 +1040,13 @@ extension, which embeds the bridge logic directly in the token contract.
Events
-- [CrosschainFungibleTransferSent(sendId, from, to, amount)](#BridgeFungible-CrosschainFungibleTransferSent-bytes32-address-bytes-uint256-)
-- [CrosschainFungibleTransferReceived(receiveId, from, to, amount)](#BridgeFungible-CrosschainFungibleTransferReceived-bytes32-bytes-address-uint256-)
+
+BridgeNonFungible
+
+- [CrosschainNonFungibleTransferSent(sendId, from, to, tokenId)](#BridgeNonFungible-CrosschainNonFungibleTransferSent-bytes32-address-bytes-uint256-)
+- [CrosschainNonFungibleTransferReceived(receiveId, from, to, tokenId)](#BridgeNonFungible-CrosschainNonFungibleTransferReceived-bytes32-bytes-address-uint256-)
+
+CrosschainLinked
@@ -741,128 +1074,840 @@ extension, which embeds the bridge logic directly in the token contract.
-
+
-
crosschainTransfer(bytes to, uint256 amount) → bytes32
-Internal crosschain transfer function.
+Transfer `tokenId` from `from` (on this chain) to `to` (on a different chain).
-Note: The `to` parameter is the full InteroperableAddress (chain ref + address).
+The `to` parameter is the full InteroperableAddress that references both the destination chain and the account
+on that chain. Similarly to the underlying token's [`ERC721.transferFrom`](/contracts/5.x/api/token/ERC721#ERC721-transferFrom-address-address-uint256-) function, this function can be called
+either by the token holder or by anyone that is approved by the token holder. It reuses the token's allowance
+system, meaning that an account that is "approved for all" or "approved for tokenId" can perform the crosschain
+transfer directly without having to take temporary custody of the token.
-Virtual function that should contain the logic to execute when a cross-chain message is received.
-
-
-This function should revert on failure. Any silent failure from this function will result in the message
-being marked as received and not being retryable.
-
+"Locking" tokens is done by taking custody
-Virtual function: implementation is required to handle token being burnt or locked on the source chain.
+"Unlocking" tokens is done by releasing custody
+
+```solidity
+import "@openzeppelin/contracts/crosschain/bridges/BridgeERC7802.sol";
+```
+
+This is a variant of [`BridgeFungible`](#BridgeFungible) that implements the bridge logic for ERC-7802 compliant tokens.
+
+
+
+```solidity
+import "@openzeppelin/contracts/crosschain/bridges/abstract/BridgeFungible.sol";
+```
+
+Base contract for bridging ERC-20 between chains using an ERC-7786 gateway.
+
+In order to use this contract, two functions must be implemented to link it to the token:
+* [`BridgeFungible._onSend`](#BridgeFungible-_onSend-address-uint256-): called when a crosschain transfer is going out. Must take the sender tokens or revert.
+* [`BridgeFungible._onReceive`](#BridgeFungible-_onReceive-address-uint256-): called when a crosschain transfer is coming in. Must give tokens to the receiver.
+
+This base contract is used by the [`BridgeERC20`](#BridgeERC20), which interfaces with legacy ERC-20 tokens, and [`BridgeERC7802`](#BridgeERC7802),
+which interface with ERC-7802 to provide an approve-free user experience. It is also used by the [`ERC20Crosschain`](/contracts/5.x/api/token/ERC20#ERC20Crosschain)
+extension, which embeds the bridge logic directly in the token contract.
+
+
+
+Virtual function that should contain the logic to execute when a cross-chain message is received.
+
+
+This function should revert on failure. Any silent failure from this function will result in the message
+being marked as received and not being retryable.
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/crosschain/bridges/abstract/BridgeMultiToken.sol";
+```
+
+Base contract for bridging ERC-1155 between chains using an ERC-7786 gateway.
+
+In order to use this contract, two functions must be implemented to link it to the token:
+* [`BridgeERC1155._onSend`](#BridgeERC1155-_onSend-address-uint256---uint256---): called when a crosschain transfer is going out. Must take the sender tokens or revert.
+* [`BridgeERC1155._onReceive`](#BridgeERC1155-_onReceive-address-uint256---uint256---): called when a crosschain transfer is coming in. Must give tokens to the receiver.
+
+This base contract is used by the [`BridgeERC1155`](#BridgeERC1155), which interfaces with legacy ERC-1155 tokens. It is also used by
+the [`ERC1155Crosschain`](/contracts/5.x/api/token/ERC1155#ERC1155Crosschain) extension, which embeds the bridge logic directly in the token contract.
+
+This base contract implements the crosschain transfer operation through internal functions. It is for the "child
+contracts" that inherit from this to implement the external interfaces and make these functions accessible.
+
+
+
+Virtual function that should contain the logic to execute when a cross-chain message is received.
+
+
+This function should revert on failure. Any silent failure from this function will result in the message
+being marked as received and not being retryable.
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/crosschain/bridges/abstract/BridgeNonFungible.sol";
+```
+
+Base contract for bridging ERC-721 between chains using an ERC-7786 gateway.
+
+In order to use this contract, two functions must be implemented to link it to the token:
+* [`BridgeNonFungible._onSend`](#BridgeNonFungible-_onSend-address-uint256-): called when a crosschain transfer is going out. Must take the sender tokens or revert.
+* [`BridgeNonFungible._onReceive`](#BridgeNonFungible-_onReceive-address-uint256-): called when a crosschain transfer is coming in. Must give tokens to the receiver.
+
+This base contract is used by the [`BridgeERC721`](#BridgeERC721), which interfaces with legacy ERC-721 tokens. It is also used by
+the [`ERC721Crosschain`](/contracts/5.x/api/token/ERC721#ERC721Crosschain) extension, which embeds the bridge logic directly in the token contract.
+
+
+
+Virtual function that should contain the logic to execute when a cross-chain message is received.
+
+
+This function should revert on failure. Any silent failure from this function will result in the message
+being marked as received and not being retryable.
+
+
+
+
+Emitted when a crosschain ERC-721 transfer is received.
+
diff --git a/content/contracts/5.x/api/finance.mdx b/content/contracts/5.x/api/finance.mdx
index 3b652257..51c331dd 100644
--- a/content/contracts/5.x/api/finance.mdx
+++ b/content/contracts/5.x/api/finance.mdx
@@ -8,18 +8,21 @@ This directory includes primitives for financial systems:
* [`VestingWallet`](#VestingWallet) handles the vesting of Ether and ERC-20 tokens for a given beneficiary. Custody of multiple tokens can
be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting
schedule.
+* [`VestingWalletCliff`](#VestingWalletCliff) is an extension of [`VestingWallet`](#VestingWallet) that adds a cliff to the vesting schedule.
## Contracts
[`VestingWallet`](#VestingWallet)
+[`VestingWalletCliff`](#VestingWalletCliff)
+
## `VestingWallet`
-
+
@@ -397,7 +400,7 @@ an asset given its total historical allocation.
## `VestingWalletCliff`
-
+
diff --git a/content/contracts/5.x/api/governance.mdx b/content/contracts/5.x/api/governance.mdx
index 5fac8d07..5ffd553d 100644
--- a/content/contracts/5.x/api/governance.mdx
+++ b/content/contracts/5.x/api/governance.mdx
@@ -7,7 +7,7 @@ This directory includes primitives for on-chain governance.
## Governor
-This modular system of Governor contracts allows the deployment on-chain voting protocols similar to [Compound’s Governor Alpha & Bravo](https://compound.finance/docs/governance) and beyond, through the ability to easily customize multiple aspects of the protocol.
+This modular system of Governor contracts allows the deployment of on-chain voting protocols similar to [Compound’s Governor Alpha & Bravo](https://docs.compound.xyz/v2/governance/) and beyond, through the ability to easily customize multiple aspects of the protocol.
For a guided experience, set up your Governor contract using [Contracts Wizard](https://wizard.openzeppelin.com/#governor).
@@ -37,12 +37,14 @@ Timelock extensions add a delay for governance decisions to be executed. The wor
Other extensions can customize the behavior or interface in multiple ways.
-* [`GovernorStorage`](#GovernorStorage): Stores the proposal details onchain and provides enumerability of the proposals. This can be useful for some L2 chains where storage is cheap compared to calldata.
-* [`GovernorSettings`](#GovernorSettings): Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiring an upgrade.
+* [`GovernorCrosschain`](#GovernorCrosschain): Helps with the execution of crosschain operation using `CrosschainRemoteExector` and ERC-7786 gateways.
+* [`GovernorNoncesKeyed`](#GovernorNoncesKeyed): An extension of [`Governor`](#Governor) with support for keyed nonces in addition to traditional nonces when voting by signature.
* [`GovernorPreventLateQuorum`](#GovernorPreventLateQuorum): Ensures there is a minimum voting period after quorum is reached as a security protection against large voters.
* [`GovernorProposalGuardian`](#GovernorProposalGuardian): Adds a proposal guardian that can cancel proposals at any stage in their lifecycle--this permission is passed on to the proposers if the guardian is not set.
+* [`GovernorSettings`](#GovernorSettings): Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiring an upgrade.
+* [`GovernorStorage`](#GovernorStorage): Stores the proposal details onchain and provides enumerability of the proposals. This can be useful for some L2 chains where storage is cheap compared to calldata.
* [`GovernorSuperQuorum`](#GovernorSuperQuorum): Extension of [`Governor`](#Governor) with a super quorum. Proposals that meet the super quorum (and have a majority of for votes) advance to the `Succeeded` state before the proposal deadline.
-* [`GovernorNoncesKeyed`](#GovernorNoncesKeyed): An extension of [`Governor`](#Governor) with support for keyed nonces in addition to traditional nonces when voting by signature.
+* [`GovernorSequentialProposalId`](#GovernorSequentialProposalId): An extension of [`Governor`](#Governor) that changes the numbering of proposal ids from the default hash-based approach to sequential ids.
In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications:
@@ -82,20 +84,26 @@ Functions of the `Governor` contract do not include access control. If you want
[`GovernorTimelockCompound`](#GovernorTimelockCompound)
-[`GovernorSettings`](#GovernorSettings)
+[`GovernorCrosschain`](#GovernorCrosschain)
-[`GovernorPreventLateQuorum`](#GovernorPreventLateQuorum)
+[`GovernorNoncesKeyed`](#GovernorNoncesKeyed)
-[`GovernorStorage`](#GovernorStorage)
+[`GovernorPreventLateQuorum`](#GovernorPreventLateQuorum)
[`GovernorProposalGuardian`](#GovernorProposalGuardian)
+[`GovernorSettings`](#GovernorSettings)
+
+[`GovernorStorage`](#GovernorStorage)
+
[`GovernorSuperQuorum`](#GovernorSuperQuorum)
-[`GovernorNoncesKeyed`](#GovernorNoncesKeyed)
+[`GovernorSequentialProposalId`](#GovernorSequentialProposalId)
## Utils
+[`IVotes`](#IVotes)
+
[`Votes`](#Votes)
[`VotesExtended`](#VotesExtended)
@@ -189,7 +197,7 @@ A live contract without at least one proposer and one executor is locked. Make s
## `Governor`
-
+
@@ -341,8 +349,8 @@ This contract is abstract and requires several functions to be implemented in va
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -1485,7 +1493,7 @@ quorum depending on values such as the totalSupply of a token at this timepoint
## `IGovernor`
-
+
@@ -1574,8 +1582,8 @@ Making event parameters `indexed` affects how events are decoded, potentially br
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -2440,36 +2448,36 @@ The provided params buffer is not supported by the counting module.
-Queue operation is not implemented for this governor. Execute should be called directly.
+This operation doesn't require queuing and should be executed directly.
-The proposal hasn't been queued yet.
+Indicates a misconfigured timelock module. (e.g. [`Governor._queueOperations`](#Governor-_queueOperations-uint256-address---uint256---bytes---bytes32-) returned a zero ETA)
@@ -2532,7 +2540,7 @@ The given `account` is unable to cancel the proposal with given `proposalId`.
## `TimelockController`
-
+
@@ -3309,7 +3317,7 @@ The caller account is not authorized.
## `GovernorCountingFractional`
-
+
@@ -3471,8 +3479,8 @@ _Available since v5.1._
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -3678,7 +3686,7 @@ A fractional vote params uses more votes than are available for that user.
## `GovernorCountingOverridable`
-
+
@@ -3833,8 +3841,8 @@ token that inherits [`VotesExtended`](#VotesExtended).
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -4143,7 +4151,7 @@ A delegated vote on `proposalId` was overridden by `weight`
## `GovernorCountingSimple`
-
+
@@ -4282,8 +4290,8 @@ Extension of [`Governor`](#Governor) for simple, 3 options, vote counting.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -4420,13 +4428,214 @@ See [`Governor._countVote`](#Governor-_countVote-uint256-address-uint8-uint256-b
+
+```solidity
+import "@openzeppelin/contracts/governance/extensions/GovernorCrosschain.sol";
+```
+
+Extension of [`Governor`](#Governor) for cross-chain governance through ERC-7786 gateways and [`CrosschainRemoteExecutor`](/contracts/5.x/api/crosschain#CrosschainRemoteExecutor).
+
+
+
+Send crosschain instruction to an arbitrary remote executor via an arbitrary ERC-7786 gateway.
+
+
+
+
## `GovernorNoncesKeyed`
-
+
@@ -4582,8 +4791,8 @@ Traditional (un-keyed) nonces are still supported and can continue to be used as
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -4663,7 +4872,7 @@ Side effects may be skipped depending on the linearization of the function.
## `GovernorPreventLateQuorum`
-
+
@@ -4818,8 +5027,8 @@ proposal.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -4989,7 +5198,7 @@ Emitted when the [`GovernorPreventLateQuorum.lateQuorumVoteExtension`](#Governor
## `GovernorProposalGuardian`
-
+
@@ -5140,8 +5349,8 @@ if the proposal guardian is not configured, then proposers take this role for th
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -5254,7 +5463,7 @@ Override [`Governor._validateCancel`](#Governor-_validateCancel-uint256-address-
## `GovernorSequentialProposalId`
-
+
@@ -5401,8 +5610,8 @@ sequential ids.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -5511,7 +5720,7 @@ The [`GovernorSequentialProposalId.latestProposalId`](#GovernorSequentialProposa
## `GovernorSettings`
-
+
@@ -5664,8 +5873,8 @@ Extension of [`Governor`](#Governor) for settings updatable through governance.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -5910,7 +6119,7 @@ Emits a [`GovernorSettings.ProposalThresholdSet`](#GovernorSettings-ProposalThre
## `GovernorStorage`
-
+
@@ -6065,8 +6274,8 @@ Use cases for this module include:
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -6206,7 +6415,7 @@ Returns the details (including the proposalId) of a proposal given its sequentia
## `GovernorSuperQuorum`
-
+
@@ -6353,8 +6562,8 @@ extension must implement [`GovernorCountingFractional.proposalVotes`](#GovernorC
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -6449,7 +6658,7 @@ types of scenarios.
## `GovernorTimelockAccess`
-
+
@@ -6633,8 +6842,8 @@ the same time. See [`AccessManager.schedule`](/contracts/5.x/api/access#AccessMa
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -6986,7 +7195,7 @@ Emits a [`IGovernor.ProposalCanceled`](#IGovernor-ProposalCanceled-uint256-) eve
## `GovernorTimelockCompound`
-
+
@@ -7001,8 +7210,8 @@ the external timelock to all successful proposals (in addition to the voting dur
the admin of the timelock for any operation to be performed. A public, unrestricted,
[`GovernorTimelockCompound.__acceptAdmin`](#GovernorTimelockCompound-__acceptAdmin--) is available to accept ownership of the timelock.
-Using this model means the proposal will be operated by the [`TimelockController`](#TimelockController) and not by the [`Governor`](#Governor). Thus,
-the assets and permissions must be attached to the [`TimelockController`](#TimelockController). Any asset sent to the [`Governor`](#Governor) will be
+Using this model means the proposal will be operated by the `ICompoundTimelock` and not by the [`Governor`](#Governor). Thus,
+the assets and permissions must be attached to the `ICompoundTimelock`. Any asset sent to the [`Governor`](#Governor) will be
inaccessible from a proposal, unless executed via [`Governor.relay`](#Governor-relay-address-uint256-bytes-).
@@ -7141,8 +7350,8 @@ inaccessible from a proposal, unless executed via [`Governor.relay`](#Governor-r
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -7352,7 +7561,7 @@ It is not recommended to change the timelock while there are other queued govern
-Emitted when the timelock controller used for proposal execution is modified.
+Emitted when the timelock used for proposal execution is modified.
@@ -7363,7 +7572,7 @@ Emitted when the timelock controller used for proposal execution is modified.
## `GovernorTimelockControl`
-
+
@@ -7523,8 +7732,8 @@ proposals that have been approved by the voters, effectively executing a Denial
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -7721,7 +7930,7 @@ Emitted when the timelock controller used for proposal execution is modified.
## `GovernorVotes`
-
+
@@ -7867,8 +8076,8 @@ token.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -7971,7 +8180,7 @@ Machine-readable description of the clock as specified in ERC-6372.
## `GovernorVotesQuorumFraction`
-
+
@@ -8130,8 +8339,8 @@ fraction of the total supply.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -8338,7 +8547,7 @@ The quorum set is not a valid fraction.
## `GovernorVotesSuperQuorumFraction`
-
+
@@ -8528,8 +8737,8 @@ the `Succeeded` state before the proposal deadline.
- [GovernorRestrictedProposer(proposer)](#IGovernor-GovernorRestrictedProposer-address-)
- [GovernorInvalidVoteType()](#IGovernor-GovernorInvalidVoteType--)
- [GovernorInvalidVoteParams()](#IGovernor-GovernorInvalidVoteParams--)
-- [GovernorQueueNotImplemented()](#IGovernor-GovernorQueueNotImplemented--)
-- [GovernorNotQueuedProposal(proposalId)](#IGovernor-GovernorNotQueuedProposal-uint256-)
+- [GovernorProposalQueueingNotRequired(proposalId)](#IGovernor-GovernorProposalQueueingNotRequired-uint256-)
+- [GovernorProposalQueueingFailed(proposalId)](#IGovernor-GovernorProposalQueueingFailed-uint256-)
- [GovernorAlreadyQueuedProposal(proposalId)](#IGovernor-GovernorAlreadyQueuedProposal-uint256-)
- [GovernorInvalidSignature(voter)](#IGovernor-GovernorInvalidSignature-address-)
- [GovernorUnableToCancel(proposalId, account)](#IGovernor-GovernorUnableToCancel-uint256-address-)
@@ -8559,7 +8768,7 @@ the `Succeeded` state before the proposal deadline.
Initialize super quorum as a fraction of the token's total supply.
The super quorum is specified as a fraction of the token's total supply and has to
-be greater than the quorum.
+be greater than or equal to the quorum.
@@ -8755,7 +8964,7 @@ The super quorum set is not valid as it exceeds the quorum denominator.
-The super quorum set is not valid as it is smaller or equal to the quorum.
+The super quorum set is not valid as it is smaller than the quorum.
@@ -8783,7 +8992,7 @@ The quorum set is not valid as it exceeds the super quorum.
## `IVotes`
-
+
@@ -8990,7 +9199,7 @@ The signature used has expired.
## `Votes`
-
+
@@ -9034,7 +9243,7 @@ previous example, it would be included in [`ERC721._update`](/contracts/5.x/api/
- [_transferVotingUnits(from, to, amount)](#Votes-_transferVotingUnits-address-address-uint256-)
- [_moveDelegateVotes(from, to, amount)](#Votes-_moveDelegateVotes-address-address-uint256-)
- [_numCheckpoints(account)](#Votes-_numCheckpoints-address-)
-- [_checkpoints(account, pos)](#Votes-_checkpoints-address-uint32-)
+- [_checkpoints(account, index)](#Votes-_checkpoints-address-uint32-)
- [_getVotingUnits()](#Votes-_getVotingUnits-address-)
Nonces
@@ -9079,7 +9288,6 @@ previous example, it would be included in [`ERC721._update`](/contracts/5.x/api/
Errors
-- [ERC6372InconsistentClock()](#Votes-ERC6372InconsistentClock--)
- [ERC5805FutureLookup(timepoint, clock)](#Votes-ERC5805FutureLookup-uint256-uint48-)
IVotes
@@ -9358,7 +9566,7 @@ Get number of checkpoints for `account`.
```solidity
-import "@openzeppelin/contracts/interfaces/IERC4626.sol";
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
```
-Interface of the ERC-4626 "Tokenized Vault Standard", as defined in
-[ERC-4626](https://eips.ethereum.org/EIPS/eip-4626).
+A [user operation](https://github.com/ethereum/ercs/blob/master/ERCS/erc-4337.md#useroperation) is composed of the following elements:
+- `sender` (`address`): The account making the operation
+- `nonce` (`uint256`): Anti-replay parameter (see “Semi-abstracted Nonce Support” )
+- `factory` (`address`): account factory, only for new accounts
+- `factoryData` (`bytes`): data for account factory (only if account factory exists)
+- `callData` (`bytes`): The data to pass to the sender during the main execution call
+- `callGasLimit` (`uint256`): The amount of gas to allocate the main execution call
+- `verificationGasLimit` (`uint256`): The amount of gas to allocate for the verification step
+- `preVerificationGas` (`uint256`): Extra gas to pay the bundler
+- `maxFeePerGas` (`uint256`): Maximum fee per gas (similar to EIP-1559 max_fee_per_gas)
+- `maxPriorityFeePerGas` (`uint256`): Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas)
+- `paymaster` (`address`): Address of paymaster contract, (or empty, if account pays for itself)
+- `paymasterVerificationGasLimit` (`uint256`): The amount of gas to allocate for the paymaster validation code
+- `paymasterPostOpGasLimit` (`uint256`): The amount of gas to allocate for the paymaster post-operation code
+- `paymasterData` (`bytes`): Data for paymaster (only if paymaster exists)
+- `signature` (`bytes`): Data passed into the account to verify authorization
-
-
Functions
-
-- [asset()](#IERC4626-asset--)
-- [totalAssets()](#IERC4626-totalAssets--)
-- [convertToShares(assets)](#IERC4626-convertToShares-uint256-)
-- [convertToAssets(shares)](#IERC4626-convertToAssets-uint256-)
-- [maxDeposit(receiver)](#IERC4626-maxDeposit-address-)
-- [previewDeposit(assets)](#IERC4626-previewDeposit-uint256-)
-- [deposit(assets, receiver)](#IERC4626-deposit-uint256-address-)
-- [maxMint(receiver)](#IERC4626-maxMint-address-)
-- [previewMint(shares)](#IERC4626-previewMint-uint256-)
-- [mint(shares, receiver)](#IERC4626-mint-uint256-address-)
-- [maxWithdraw(owner)](#IERC4626-maxWithdraw-address-)
-- [previewWithdraw(assets)](#IERC4626-previewWithdraw-uint256-)
-- [withdraw(assets, receiver, owner)](#IERC4626-withdraw-uint256-address-address-)
-- [maxRedeem(owner)](#IERC4626-maxRedeem-address-)
-- [previewRedeem(shares)](#IERC4626-previewRedeem-uint256-)
-- [redeem(shares, receiver, owner)](#IERC4626-redeem-uint256-address-address-)
-
-IERC20Metadata
+When passed to on-chain contracts, the following packed version is used.
+- `sender` (`address`)
+- `nonce` (`uint256`)
+- `initCode` (`bytes`): concatenation of factory address and factoryData (or empty)
+- `callData` (`bytes`)
+- `accountGasLimits` (`bytes32`): concatenation of verificationGas (16 bytes) and callGas (16 bytes)
+- `preVerificationGas` (`uint256`)
+- `gasFees` (`bytes32`): concatenation of maxPriorityFeePerGas (16 bytes) and maxFeePerGas (16 bytes)
+- `paymasterAndData` (`bytes`): concatenation of paymaster fields (or empty)
+ For EntryPoint v0.9+, may optionally include `paymasterSignature` at the end:
+ `paymaster || paymasterVerificationGasLimit || paymasterPostOpGasLimit || paymasterData || paymasterSignature || paymasterSignatureSize || PAYMASTER_SIG_MAGIC`
+- `signature` (`bytes`)
-- [name()](#IERC20Metadata-name--)
-- [symbol()](#IERC20Metadata-symbol--)
-- [decimals()](#IERC20Metadata-decimals--)
+
-
-
-IERC20
+
-- [Deposit(sender, owner, assets, shares)](#IERC4626-Deposit-address-address-uint256-uint256-)
-- [Withdraw(sender, receiver, owner, assets, shares)](#IERC4626-Withdraw-address-address-address-uint256-uint256-)
-
-IERC20
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
+```
-- [Transfer(from, to, value)](#IERC20-Transfer-address-address-uint256-)
-- [Approval(owner, spender, value)](#IERC20-Approval-address-address-uint256-)
+Aggregates and validates multiple signatures for a batch of user operations.
-
+A contract could implement this interface with custom validation schemes that allow signature aggregation,
+enabling significant optimizations and gas savings for execution and transaction data cost.
+
+Bundlers and clients whitelist supported aggregators.
+
+See [ERC-7766](https://eips.ethereum.org/EIPS/eip-7766)
+
+
-Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
-
-- MUST be an ERC-20 token contract.
-- MUST NOT revert.
+Validates the signature for a user operation.
+Returns an alternative signature that should be used during bundling.
-Returns the total amount of the underlying asset that is “managed” by Vault.
-
-- SHOULD include any compounding that occurs from yield.
-- MUST be inclusive of any fees that are charged against assets in the Vault.
-- MUST NOT revert.
+Returns an aggregated signature for a batch of user operation's signatures.
-Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
-scenario where all the conditions are met.
+Validates that the aggregated signature is valid for the user operations.
-- MUST NOT be inclusive of any fees that are charged against assets in the Vault.
-- MUST NOT show any variations depending on the caller.
-- MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
-- MUST NOT revert.
+Requirements:
-
-This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
-“average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
-from.
-
+- The aggregated signature MUST match the given list of operations.
-Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
-scenario where all the conditions are met.
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
+```
-- MUST NOT be inclusive of any fees that are charged against assets in the Vault.
-- MUST NOT show any variations depending on the caller.
-- MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
-- MUST NOT revert.
+Handle nonce management for accounts.
-
-This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
-“average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
-from.
-
+Nonces are used in accounts as a replay protection mechanism and to ensure the order of user operations.
+To avoid limiting the number of operations an account can perform, the interface allows using parallel
+nonces by using a `key` parameter.
+
+See [ERC-4337 semi-abstracted nonce support](https://eips.ethereum.org/EIPS/eip-4337#semi-abstracted-nonce-support).
+
-Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
-through a deposit call.
+Returns the nonce for a `sender` account and a `key`.
-- MUST return a limited value if receiver is subject to some deposit limit.
-- MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
-- MUST NOT revert.
+Nonces for a certain `key` are always increasing.
+
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
+```
+
+Handle stake management for entities (i.e. accounts, paymasters, factories).
+
+The EntryPoint must implement the following API to let entities like paymasters have a stake,
+and thus have more flexibility in their storage access
+(see [reputation, throttling and banning.](https://eips.ethereum.org/EIPS/eip-4337#reputation-scoring-and-throttlingbanning-for-global-entities))
+
+
-Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
-current on-chain conditions.
-
-- MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
- call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
- in the same transaction.
-- MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
- deposit would be accepted, regardless if the user has enough tokens approved, etc.
-- MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
-- MUST NOT revert.
-
-
-any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
-share price or some other type of condition, meaning the depositor will lose assets by depositing.
-
+Returns the balance of the account.
-Deposit `assets` underlying tokens and send the corresponding number of vault shares (`shares`) to `receiver`.
-
-- MUST emit the Deposit event.
-- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
- deposit execution, and are accounted for during deposit.
-- MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
- approving enough underlying tokens to the Vault contract, etc).
-
-
-most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
-
+Deposits `msg.value` to the account.
-Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
-- MUST return a limited value if receiver is subject to some mint limit.
-- MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
-- MUST NOT revert.
+Withdraws `withdrawAmount` from the account to `withdrawAddress`.
-Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
-current on-chain conditions.
-
-- MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
- in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
- same transaction.
-- MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
- would be accepted, regardless if the user has enough tokens approved, etc.
-- MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
-- MUST NOT revert.
-
-
-any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
-share price or some other type of condition, meaning the depositor will lose assets by minting.
-
+Adds stake to the account with an unstake delay of `unstakeDelaySec`.
-Mints exactly `shares` vault shares to `receiver` in exchange for `assets` underlying tokens.
-
-- MUST emit the Deposit event.
-- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
- execution, and are accounted for during mint.
-- MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
- approving enough underlying tokens to the Vault contract, etc).
-
-
-most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
-
+Unlocks the stake of the account.
-Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
-Vault, through a withdraw call.
+Withdraws the stake of the account to `withdrawAddress`.
-- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
-- MUST NOT revert.
+
+
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
+```
+
+Entry point for user operations.
+
+User operations are validated and executed by this contract.
+
-Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
-given current on-chain conditions.
-
-- MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
- call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
- called
- in the same transaction.
-- MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
- the withdrawal would be accepted, regardless if the user has enough shares, etc.
-- MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
-- MUST NOT revert.
-
-
-any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
-share price or some other type of condition, meaning the depositor will lose assets by depositing.
-
+Executes a batch of user operations.
-Burns shares from owner and sends exactly assets of underlying tokens to receiver.
-
-- MUST emit the Withdraw event.
-- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
- withdraw execution, and are accounted for during withdraw.
-- MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
- not having enough shares, etc).
-
-Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
-Those methods should be performed separately.
+Executes a batch of aggregated user operations per aggregator.
-Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
-through a redeem call.
-
-- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
-- MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
-- MUST NOT revert.
+A user operation at `opIndex` failed with `reason`.
-Allows an on-chain or off-chain user to simulate the effects of their redemption at the current block,
-given current on-chain conditions.
+A user operation at `opIndex` failed with `reason` and `inner` returned data.
-- MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
- in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
- same transaction.
-- MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
- redemption would be accepted, regardless if the user has enough shares, etc.
-- MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
-- MUST NOT revert.
+
+
-
-any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
-share price or some other type of condition, meaning the depositor will lose assets by redeeming.
-
+
+
+
-Burns exactly shares from owner and sends assets of underlying tokens to receiver.
+Validates a user operation.
-- MUST emit the Withdraw event.
-- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
- redeem execution, and are accounted for during redeem.
-- MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
- not having enough shares, etc).
+* MUST validate the caller is a trusted EntryPoint
+* MUST validate that the signature is a valid signature of the userOpHash, and SHOULD
+ return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert.
+* MUST pay the entryPoint (caller) at least the “missingAccountFunds” (which might
+ be zero, in case the current account’s deposit is high enough)
-
-some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
-Those methods should be performed separately.
-
+Returns an encoded packed validation data that is composed of the following elements:
+
+- `authorizer` (`address`): 0 for success, 1 for failure, otherwise the address of an authorizer contract
+- `validUntil` (`uint48`): The UserOp is valid only up to this time. Zero for “infinite”.
+- `validAfter` (`uint48`): The UserOp is valid only after this time.
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC4337.sol";
+```
+
+Support for executing user operations by prepending the [`IAccountExecute.executeUserOp`](#IAccountExecute-executeUserOp-struct-PackedUserOperation-bytes32-) function selector
+to the UserOperation's `callData`.
+
-
-IERC721
-
-- [balanceOf(owner)](#IERC721-balanceOf-address-)
-- [ownerOf(tokenId)](#IERC721-ownerOf-uint256-)
-- [safeTransferFrom(from, to, tokenId, data)](#IERC721-safeTransferFrom-address-address-uint256-bytes-)
-- [safeTransferFrom(from, to, tokenId)](#IERC721-safeTransferFrom-address-address-uint256-)
-- [transferFrom(from, to, tokenId)](#IERC721-transferFrom-address-address-uint256-)
-- [approve(to, tokenId)](#IERC721-approve-address-uint256-)
-- [setApprovalForAll(operator, approved)](#IERC721-setApprovalForAll-address-bool-)
-- [getApproved(tokenId)](#IERC721-getApproved-uint256-)
-- [isApprovedForAll(owner, operator)](#IERC721-isApprovedForAll-address-address-)
-
-
-
-IERC165
-
-- [supportsInterface(interfaceId)](#IERC165-supportsInterface-bytes4-)
+Interface for a paymaster contract that agrees to pay for the gas costs of a user operation.
-
-
-
+
+A paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.
+
-This event emits when the metadata of a token is changed.
-So that the third-party platforms such as NFT market could
-timely update the images and related attributes of the NFT.
+Validates whether the paymaster is willing to pay for the user operation. See
+[`IAccount.validateUserOp`](#IAccount-validateUserOp-struct-PackedUserOperation-bytes32-uint256-) for additional information on the return value.
+
+
+Bundlers will reject this method if it modifies the state, unless it's whitelisted.
+
-This event emits when the metadata of a range of tokens is changed.
-So that the third-party platforms such as NFT market could
-timely update the images and related attributes of the NFTs.
+Verifies the sender is the entrypoint.
```solidity
-import "@openzeppelin/contracts/interfaces/IERC5267.sol";
+import "@openzeppelin/contracts/interfaces/IERC4626.sol";
```
+Interface of the ERC-4626 "Tokenized Vault Standard", as defined in
+[ERC-4626](https://eips.ethereum.org/EIPS/eip-4626).
+
-returns the fields and values that describe the domain separator used by this contract for EIP-712
-signature.
+Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
+
+- MUST be an ERC-20 token contract.
+- MUST NOT revert.
-MAY be emitted to signal that the domain could have changed.
+Returns the total amount of the underlying asset that is “managed” by Vault.
+
+- SHOULD include any compounding that occurs from yield.
+- MUST be inclusive of any fees that are charged against assets in the Vault.
+- MUST NOT revert.
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC5313.sol";
-```
+Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
+scenario where all the conditions are met.
-Interface for the Light Contract Ownership Standard.
+- MUST NOT be inclusive of any fees that are charged against assets in the Vault.
+- MUST NOT show any variations depending on the caller.
+- MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
+- MUST NOT revert.
-A standardized minimal interface required to identify an account that controls a contract
+
+This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
+“average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
+from.
+
-
+Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
+scenario where all the conditions are met.
-## `IERC5805`
+- MUST NOT be inclusive of any fees that are charged against assets in the Vault.
+- MUST NOT show any variations depending on the caller.
+- MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
+- MUST NOT revert.
-
-
-
+
+This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
+“average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
+from.
+
+
-
-IVotes
+Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
+through a deposit call.
-- [DelegateChanged(delegator, fromDelegate, toDelegate)](#IVotes-DelegateChanged-address-address-address-)
-- [DelegateVotesChanged(delegate, previousVotes, newVotes)](#IVotes-DelegateVotesChanged-address-uint256-uint256-)
+- MUST return a limited value if receiver is subject to some deposit limit.
+- MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
+- MUST NOT revert.
-
-
-## `IERC6372`
-
-
-
-
+Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
+current on-chain conditions.
-
+- MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
+ call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
+ in the same transaction.
+- MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
+ deposit would be accepted, regardless if the user has enough tokens approved, etc.
+- MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
+- MUST NOT revert.
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC6372.sol";
-```
+
+any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
+share price or some other type of condition, meaning the depositor will lose assets by depositing.
+
-
-Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).
+Deposit `assets` underlying tokens and send the corresponding number of vault shares (`shares`) to `receiver`.
+
+- MUST emit the Deposit event.
+- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
+ deposit execution, and are accounted for during deposit.
+- MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
+ approving enough underlying tokens to the Vault contract, etc).
+
+
+most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
+
-Description of the clock
+Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
+- MUST return a limited value if receiver is subject to some mint limit.
+- MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
+- MUST NOT revert.
-## `IERC6909`
+Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
+current on-chain conditions.
-
-
-
+- MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
+ in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
+ same transaction.
+- MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
+ would be accepted, regardless if the user has enough tokens approved, etc.
+- MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
+- MUST NOT revert.
+
+
+any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
+share price or some other type of condition, meaning the depositor will lose assets by minting.
+
+
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC6909.sol";
-```
+
-Required interface of an ERC-6909 compliant contract, as defined in the
-[ERC](https://eips.ethereum.org/EIPS/eip-6909).
+
-- [balanceOf(owner, id)](#IERC6909-balanceOf-address-uint256-)
-- [allowance(owner, spender, id)](#IERC6909-allowance-address-address-uint256-)
-- [isOperator(owner, spender)](#IERC6909-isOperator-address-address-)
-- [approve(spender, id, amount)](#IERC6909-approve-address-uint256-uint256-)
-- [setOperator(spender, approved)](#IERC6909-setOperator-address-bool-)
-- [transfer(receiver, id, amount)](#IERC6909-transfer-address-uint256-uint256-)
-- [transferFrom(sender, receiver, id, amount)](#IERC6909-transferFrom-address-address-uint256-uint256-)
-
-IERC165
+Mints exactly `shares` vault shares to `receiver` in exchange for `assets` underlying tokens.
-- [supportsInterface(interfaceId)](#IERC165-supportsInterface-bytes4-)
+- MUST emit the Deposit event.
+- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
+ execution, and are accounted for during mint.
+- MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
+ approving enough underlying tokens to the Vault contract, etc).
-
-
-
+
+most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
+
-
-Returns the amount of tokens of type `id` owned by `owner`.
+Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
+Vault, through a withdraw call.
+
+- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
+- MUST NOT revert.
-Returns the amount of tokens of type `id` that `spender` is allowed to spend on behalf of `owner`.
+Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
+given current on-chain conditions.
+
+- MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
+ call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
+ called
+ in the same transaction.
+- MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
+ the withdrawal would be accepted, regardless if the user has enough shares, etc.
+- MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
+- MUST NOT revert.
-Does not include operator allowances.
+any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
+share price or some other type of condition, meaning the depositor will lose assets by depositing.
-Returns true if `spender` is set as an operator for `owner`.
+Burns shares from owner and sends exactly assets of underlying tokens to receiver.
+
+- MUST emit the Withdraw event.
+- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
+ withdraw execution, and are accounted for during withdraw.
+- MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
+ not having enough shares, etc).
+
+Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
+Those methods should be performed separately.
-Sets an approval to `spender` for `amount` of tokens of type `id` from the caller's tokens. An `amount` of
-`type(uint256).max` signifies an unlimited approval.
+Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
+through a redeem call.
-Must return true.
+- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
+- MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
+- MUST NOT revert.
-Grants or revokes unlimited transfer permission of any token id to `spender` for the caller's tokens.
+Allows an on-chain or off-chain user to simulate the effects of their redemption at the current block,
+given current on-chain conditions.
-Must return true.
+- MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
+ in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
+ same transaction.
+- MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
+ redemption would be accepted, regardless if the user has enough shares, etc.
+- MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
+- MUST NOT revert.
+
+
+any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
+share price or some other type of condition, meaning the depositor will lose assets by redeeming.
+
-Transfers `amount` of token type `id` from the caller's account to `receiver`.
+Burns exactly shares from owner and sends assets of underlying tokens to receiver.
-Must return true.
+- MUST emit the Withdraw event.
+- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
+ redeem execution, and are accounted for during redeem.
+- MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
+ not having enough shares, etc).
+
+
+some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
+Those methods should be performed separately.
+
+
+
+- [MetadataUpdate(_tokenId)](#IERC4906-MetadataUpdate-uint256-)
+- [BatchMetadataUpdate(_fromTokenId, _toTokenId)](#IERC4906-BatchMetadataUpdate-uint256-uint256-)
+
+IERC721
-Emitted when the allowance of a `spender` for an `owner` is set for a token of type `id`.
-The new allowance is `amount`.
+- [Transfer(from, to, tokenId)](#IERC721-Transfer-address-address-uint256-)
+- [Approval(owner, approved, tokenId)](#IERC721-Approval-address-address-uint256-)
+- [ApprovalForAll(owner, operator, approved)](#IERC721-ApprovalForAll-address-address-bool-)
+
-Emitted when `owner` grants or revokes operator status for a `spender`.
+This event emits when the metadata of a token is changed.
+So that the third-party platforms such as NFT market could
+timely update the images and related attributes of the NFT.
-Emitted when `amount` tokens of type `id` are moved from `sender` to `receiver` initiated by `caller`.
+This event emits when the metadata of a range of tokens is changed.
+So that the third-party platforms such as NFT market could
+timely update the images and related attributes of the NFTs.
-Returns the name of the token of type `id`.
+returns the fields and values that describe the domain separator used by this contract for EIP-712
+signature.
+
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC5313.sol";
+```
+
+Interface for the Light Contract Ownership Standard.
+
+A standardized minimal interface required to identify an account that controls a contract
+
+
-Returns the URI for the token of type `id`.
+Description of the clock
-
+
-## `IERC6909TokenSupply`
+## `IERC6909`
-
+
@@ -2382,15 +2557,12 @@ Returns the URI for the token of type `id`.
import "@openzeppelin/contracts/interfaces/IERC6909.sol";
```
-Optional extension of [`IERC6909`](#IERC6909) that adds a token supply function.
+Required interface of an ERC-6909 compliant contract, as defined in the
+[ERC](https://eips.ethereum.org/EIPS/eip-6909).
Functions
-- [totalSupply(id)](#IERC6909TokenSupply-totalSupply-uint256-)
-
-IERC6909
-
- [balanceOf(owner, id)](#IERC6909-balanceOf-address-uint256-)
- [allowance(owner, spender, id)](#IERC6909-allowance-address-address-uint256-)
- [isOperator(owner, spender)](#IERC6909-isOperator-address-address-)
@@ -2398,8 +2570,6 @@ Optional extension of [`IERC6909`](#IERC6909) that adds a token supply function.
- [setOperator(spender, approved)](#IERC6909-setOperator-address-bool-)
- [transfer(receiver, id, amount)](#IERC6909-transfer-address-uint256-uint256-)
- [transferFrom(sender, receiver, id, amount)](#IERC6909-transferFrom-address-address-uint256-uint256-)
-
-IERC165
@@ -2412,1332 +2582,1359 @@ Optional extension of [`IERC6909`](#IERC6909) that adds a token supply function.
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC7751.sol";
-```
+Returns the amount of tokens of type `id` that `spender` is allowed to spend on behalf of `owner`.
-Wrapping of bubbled up reverts
-Interface of the [ERC-7751](https://eips.ethereum.org/EIPS/eip-7751) wrapping of bubbled up reverts.
+
+Does not include operator allowances.
+
-
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC777.sol";
-```
-
-Interface of the ERC-777 Token standard as defined in the ERC.
-
-This contract uses the
-[ERC-1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
-token holders and recipients react to token movements by using setting implementers
-for the associated interfaces in said registry. See [`IERC1820Registry`](#IERC1820Registry) and
-[`IERC1820Implementer`](#IERC1820Implementer).
+Sets an approval to `spender` for `amount` of tokens of type `id` from the caller's tokens. An `amount` of
+`type(uint256).max` signifies an unlimited approval.
-
-Returns the name of the token.
+Grants or revokes unlimited transfer permission of any token id to `spender` for the caller's tokens.
+
+Must return true.
-Returns the symbol of the token, usually a shorter version of the
-name.
+Transfers `amount` of token type `id` from the caller's account to `receiver`.
+
+Must return true.
-Returns the smallest part of the token that is not divisible. This
-means all token operations (creation, movement and destruction) must have
-amounts that are a multiple of this number.
+Transfers `amount` of token type `id` from `sender` to `receiver`.
-For most token contracts, this value will equal 1.
+Must return true.
-Returns the amount of tokens in existence.
+Emitted when the allowance of a `spender` for an `owner` is set for a token of type `id`.
+The new allowance is `amount`.
-Moves `amount` tokens from the caller's account to `recipient`.
+Emitted when `amount` tokens of type `id` are moved from `sender` to `receiver` initiated by `caller`.
-If send or receive hooks are registered for the caller and `recipient`,
-the corresponding functions will be called with `data` and empty
-`operatorData`. See [`IERC777Sender`](#IERC777Sender) and [`IERC777Recipient`](#IERC777Recipient).
+
+
-Emits a [`IERC777.Sent`](#IERC777-Sent-address-address-address-uint256-bytes-bytes-) event.
+
-Requirements
+
-- the caller must have at least `amount` tokens.
-- `recipient` cannot be the zero address.
-- if `recipient` is a contract, it must implement the [`IERC777Recipient`](#IERC777Recipient)
-interface.
+## `IERC6909Metadata`
+
+
+
+
-
-Returns true if an account is an operator of `tokenHolder`.
-Operators can send and burn tokens on behalf of their owners. All
-accounts are their own operator.
-
-See [`IERC777.operatorSend`](#IERC777-operatorSend-address-address-uint256-bytes-bytes-) and [`IERC777.operatorBurn`](#IERC777-operatorBurn-address-uint256-bytes-bytes-).
+Returns the name of the token of type `id`.
-Make an account an operator of the caller.
-
-See [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-).
-
-Emits an [`IERC777.AuthorizedOperator`](#IERC777-AuthorizedOperator-address-address-) event.
-
-Requirements
-
-- `operator` cannot be calling address.
+Returns the ticker symbol of the token of type `id`.
-Revoke an account's operator status for the caller.
+Returns the number of decimals for the token of type `id`.
-See [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-) and [`IERC777.defaultOperators`](#IERC777-defaultOperators--).
+
+
-Emits a [`IERC777.RevokedOperator`](#IERC777-RevokedOperator-address-address-) event.
+
-Requirements
+
+Optional extension of [`IERC6909`](#IERC6909) that adds content URI functions.
-Returns the list of default operators. These accounts are operators
-for all token holders, even if [`IERC777.authorizeOperator`](#IERC777-authorizeOperator-address-) was never called on
-them.
+
+
Functions
+
+- [contractURI()](#IERC6909ContentURI-contractURI--)
+- [tokenURI(id)](#IERC6909ContentURI-tokenURI-uint256-)
+
+IERC6909
-This list is immutable, but individual holders may revoke these via
-[`IERC777.revokeOperator`](#IERC777-revokeOperator-address-), in which case [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-) will return false.
+- [balanceOf(owner, id)](#IERC6909-balanceOf-address-uint256-)
+- [allowance(owner, spender, id)](#IERC6909-allowance-address-address-uint256-)
+- [isOperator(owner, spender)](#IERC6909-isOperator-address-address-)
+- [approve(spender, id, amount)](#IERC6909-approve-address-uint256-uint256-)
+- [setOperator(spender, approved)](#IERC6909-setOperator-address-bool-)
+- [transfer(receiver, id, amount)](#IERC6909-transfer-address-uint256-uint256-)
+- [transferFrom(sender, receiver, id, amount)](#IERC6909-transferFrom-address-address-uint256-uint256-)
-
-
-Moves `amount` tokens from `sender` to `recipient`. The caller must
-be an operator of `sender`.
-
-If send or receive hooks are registered for `sender` and `recipient`,
-the corresponding functions will be called with `data` and
-`operatorData`. See [`IERC777Sender`](#IERC777Sender) and [`IERC777Recipient`](#IERC777Recipient).
-
-Emits a [`IERC777.Sent`](#IERC777-Sent-address-address-address-uint256-bytes-bytes-) event.
-Requirements
+
+
Events
+
+
+IERC6909
-- `sender` cannot be the zero address.
-- `sender` must have at least `amount` tokens.
-- the caller must be an operator for `sender`.
-- `recipient` cannot be the zero address.
-- if `recipient` is a contract, it must implement the [`IERC777Recipient`](#IERC777Recipient)
-interface.
+- [Approval(owner, spender, id, amount)](#IERC6909-Approval-address-address-uint256-uint256-)
+- [OperatorSet(owner, spender, approved)](#IERC6909-OperatorSet-address-address-bool-)
+- [Transfer(caller, sender, receiver, id, amount)](#IERC6909-Transfer-address-address-address-uint256-uint256-)
+
-Destroys `amount` tokens from `account`, reducing the total supply.
-The caller must be an operator of `account`.
-
-If a send hook is registered for `account`, the corresponding function
-will be called with `data` and `operatorData`. See [`IERC777Sender`](#IERC777Sender).
-
-Emits a [`IERC777.Burned`](#IERC777-Burned-address-address-uint256-bytes-bytes-) event.
-
-Requirements
-
-- `account` cannot be the zero address.
-- `account` must have at least `amount` tokens.
-- the caller must be an operator for `account`.
+Returns URI for the contract.
-Emitted when `amount` tokens are created by `operator` and assigned to `to`.
-
-Note that some additional user `data` and `operatorData` can be logged in the event.
+Returns the URI for the token of type `id`.
-Emitted when `operator` destroys `amount` tokens from `account`.
+## `IERC6909TokenSupply`
-Note that some additional user `data` and `operatorData` can be logged in the event.
+
+
+
```solidity
-import "@openzeppelin/contracts/interfaces/IERC777Recipient.sol";
+import "@openzeppelin/contracts/interfaces/IERC7751.sol";
```
-Interface of the ERC-777 Tokens Recipient standard as defined in the ERC.
-
-Accounts can be notified of [`IERC777`](#IERC777) tokens being sent to them by having a
-contract implement this interface (contract holders can be their own
-implementer) and registering it on the
-[ERC-1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
-
-See [`IERC1820Registry`](#IERC1820Registry) and [`IERC1820Implementer`](#IERC1820Implementer).
+Wrapping of bubbled up reverts
+Interface of the [ERC-7751](https://eips.ethereum.org/EIPS/eip-7751) wrapping of bubbled up reverts.
-Called by an [`IERC777`](#IERC777) token contract whenever tokens are being
-moved or created into a registered account (`to`). The type of operation
-is conveyed by `from` being the zero address or not.
-
-This call occurs _after_ the token contract's state is updated, so
-[`IERC777.balanceOf`](#IERC777-balanceOf-address-), etc., can be used to query the post-operation state.
-
-This function may revert to prevent the operation from being executed.
-
```solidity
-import "@openzeppelin/contracts/interfaces/IERC777Sender.sol";
+import "@openzeppelin/contracts/interfaces/IERC777.sol";
```
-Interface of the ERC-777 Tokens Sender standard as defined in the ERC.
-
-[`IERC777`](#IERC777) Token holders can be notified of operations performed on their
-tokens by having a contract implement this interface (contract holders can be
-their own implementer) and registering it on the
-[ERC-1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+Interface of the ERC-777 Token standard as defined in the ERC.
-See [`IERC1820Registry`](#IERC1820Registry) and [`IERC1820Implementer`](#IERC1820Implementer).
+This contract uses the
+[ERC-1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
+token holders and recipients react to token movements by using setting implementers
+for the associated interfaces in said registry. See [`IERC1820Registry`](#IERC1820Registry) and
+[`IERC1820Implementer`](#IERC1820Implementer).
-Called by an [`IERC777`](#IERC777) token contract whenever a registered holder's
-(`from`) tokens are about to be moved or destroyed. The type of operation
-is conveyed by `to` being the zero address or not.
-
-This call occurs _before_ the token contract's state is updated, so
-[`IERC777.balanceOf`](#IERC777-balanceOf-address-), etc., can be used to query the pre-operation state.
-
-This function may revert to prevent the operation from being executed.
+Returns the name of the token.
-```solidity
-import "@openzeppelin/contracts/interfaces/IERC7913.sol";
-```
-
-Signature verifier interface.
+Returns the symbol of the token, usually a shorter version of the
+name.
-
-Verifies `signature` as a valid signature of `hash` by `key`.
+Returns the smallest part of the token that is not divisible. This
+means all token operations (creation, movement and destruction) must have
+amounts that are a multiple of this number.
-MUST return the bytes4 magic value IERC7913SignatureVerifier.verify.selector if the signature is valid.
-SHOULD return 0xffffffff or revert if the signature is not valid.
-SHOULD return 0xffffffff or revert if the key is empty
+For most token contracts, this value will equal 1.
-```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
-```
-
-ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
-proxy whose upgrades are fully controlled by the current implementation.
+Returns the amount of tokens in existence.
-
-Returns the storage slot that the proxiable contract assumes is being used to store the implementation
-address.
-
-
-A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
-bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
-function revert if invoked through a proxy.
-
+Returns the amount of tokens owned by an account (`owner`).
-```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
-```
+Moves `amount` tokens from the caller's account to `recipient`.
-A [user operation](https://github.com/ethereum/ercs/blob/master/ERCS/erc-4337.md#useroperation) is composed of the following elements:
-- `sender` (`address`): The account making the operation
-- `nonce` (`uint256`): Anti-replay parameter (see “Semi-abstracted Nonce Support” )
-- `factory` (`address`): account factory, only for new accounts
-- `factoryData` (`bytes`): data for account factory (only if account factory exists)
-- `callData` (`bytes`): The data to pass to the sender during the main execution call
-- `callGasLimit` (`uint256`): The amount of gas to allocate the main execution call
-- `verificationGasLimit` (`uint256`): The amount of gas to allocate for the verification step
-- `preVerificationGas` (`uint256`): Extra gas to pay the bundler
-- `maxFeePerGas` (`uint256`): Maximum fee per gas (similar to EIP-1559 max_fee_per_gas)
-- `maxPriorityFeePerGas` (`uint256`): Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas)
-- `paymaster` (`address`): Address of paymaster contract, (or empty, if account pays for itself)
-- `paymasterVerificationGasLimit` (`uint256`): The amount of gas to allocate for the paymaster validation code
-- `paymasterPostOpGasLimit` (`uint256`): The amount of gas to allocate for the paymaster post-operation code
-- `paymasterData` (`bytes`): Data for paymaster (only if paymaster exists)
-- `signature` (`bytes`): Data passed into the account to verify authorization
+If send or receive hooks are registered for the caller and `recipient`,
+the corresponding functions will be called with `data` and empty
+`operatorData`. See [`IERC777Sender`](#IERC777Sender) and [`IERC777Recipient`](#IERC777Recipient).
-When passed to on-chain contracts, the following packed version is used.
-- `sender` (`address`)
-- `nonce` (`uint256`)
-- `initCode` (`bytes`): concatenation of factory address and factoryData (or empty)
-- `callData` (`bytes`)
-- `accountGasLimits` (`bytes32`): concatenation of verificationGas (16 bytes) and callGas (16 bytes)
-- `preVerificationGas` (`uint256`)
-- `gasFees` (`bytes32`): concatenation of maxPriorityFeePerGas (16 bytes) and maxFeePerGas (16 bytes)
-- `paymasterAndData` (`bytes`): concatenation of paymaster fields (or empty)
- For EntryPoint v0.9+, may optionally include `paymasterSignature` at the end:
- `paymaster || paymasterVerificationGasLimit || paymasterPostOpGasLimit || paymasterData || paymasterSignature || paymasterSignatureSize || PAYMASTER_SIG_MAGIC`
-- `signature` (`bytes`)
+Emits a [`IERC777.Sent`](#IERC777-Sent-address-address-address-uint256-bytes-bytes-) event.
-
+Requirements
-
+- the caller must have at least `amount` tokens.
+- `recipient` cannot be the zero address.
+- if `recipient` is a contract, it must implement the [`IERC777Recipient`](#IERC777Recipient)
+interface.
-## `IAggregator`
+
-```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
-```
+Destroys `amount` tokens from the caller's account, reducing the
+total supply.
-Aggregates and validates multiple signatures for a batch of user operations.
+If a send hook is registered for the caller, the corresponding function
+will be called with `data` and empty `operatorData`. See [`IERC777Sender`](#IERC777Sender).
-A contract could implement this interface with custom validation schemes that allow signature aggregation,
-enabling significant optimizations and gas savings for execution and transaction data cost.
+Emits a [`IERC777.Burned`](#IERC777-Burned-address-address-uint256-bytes-bytes-) event.
-Bundlers and clients whitelist supported aggregators.
+Requirements
-See [ERC-7766](https://eips.ethereum.org/EIPS/eip-7766)
+- the caller must have at least `amount` tokens.
-
-Validates the signature for a user operation.
-Returns an alternative signature that should be used during bundling.
+Returns true if an account is an operator of `tokenHolder`.
+Operators can send and burn tokens on behalf of their owners. All
+accounts are their own operator.
+
+See [`IERC777.operatorSend`](#IERC777-operatorSend-address-address-uint256-bytes-bytes-) and [`IERC777.operatorBurn`](#IERC777-operatorBurn-address-uint256-bytes-bytes-).
-Returns an aggregated signature for a batch of user operation's signatures.
+Make an account an operator of the caller.
+
+See [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-).
+
+Emits an [`IERC777.AuthorizedOperator`](#IERC777-AuthorizedOperator-address-address-) event.
+
+Requirements
+
+- `operator` cannot be calling address.
-Validates that the aggregated signature is valid for the user operations.
-
-Requirements:
-
-- The aggregated signature MUST match the given list of operations.
-
-
-
+Revoke an account's operator status for the caller.
-
+See [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-) and [`IERC777.defaultOperators`](#IERC777-defaultOperators--).
-
+Emits a [`IERC777.RevokedOperator`](#IERC777-RevokedOperator-address-address-) event.
-## `IEntryPointNonces`
+Requirements
-
-
-
+- `operator` cannot be calling address.
+
-Nonces are used in accounts as a replay protection mechanism and to ensure the order of user operations.
-To avoid limiting the number of operations an account can perform, the interface allows using parallel
-nonces by using a `key` parameter.
+Returns the list of default operators. These accounts are operators
+for all token holders, even if [`IERC777.authorizeOperator`](#IERC777-authorizeOperator-address-) was never called on
+them.
-See [ERC-4337 semi-abstracted nonce support](https://eips.ethereum.org/EIPS/eip-4337#semi-abstracted-nonce-support).
+This list is immutable, but individual holders may revoke these via
+[`IERC777.revokeOperator`](#IERC777-revokeOperator-address-), in which case [`IERC777.isOperatorFor`](#IERC777-isOperatorFor-address-address-) will return false.
-
-Returns the nonce for a `sender` account and a `key`.
+Moves `amount` tokens from `sender` to `recipient`. The caller must
+be an operator of `sender`.
-Nonces for a certain `key` are always increasing.
+If send or receive hooks are registered for `sender` and `recipient`,
+the corresponding functions will be called with `data` and
+`operatorData`. See [`IERC777Sender`](#IERC777Sender) and [`IERC777Recipient`](#IERC777Recipient).
-
-
+Emits a [`IERC777.Sent`](#IERC777-Sent-address-address-address-uint256-bytes-bytes-) event.
-
+Requirements
-
+- `sender` cannot be the zero address.
+- `sender` must have at least `amount` tokens.
+- the caller must be an operator for `sender`.
+- `recipient` cannot be the zero address.
+- if `recipient` is a contract, it must implement the [`IERC777Recipient`](#IERC777Recipient)
+interface.
-## `IEntryPointStake`
+
-```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
-```
+Destroys `amount` tokens from `account`, reducing the total supply.
+The caller must be an operator of `account`.
-Handle stake management for entities (i.e. accounts, paymasters, factories).
+If a send hook is registered for `account`, the corresponding function
+will be called with `data` and `operatorData`. See [`IERC777Sender`](#IERC777Sender).
-The EntryPoint must implement the following API to let entities like paymasters have a stake,
-and thus have more flexibility in their storage access
-(see [reputation, throttling and banning.](https://eips.ethereum.org/EIPS/eip-4337#reputation-scoring-and-throttlingbanning-for-global-entities))
+Emits a [`IERC777.Burned`](#IERC777-Burned-address-address-uint256-bytes-bytes-) event.
+
+Requirements
+
+- `account` cannot be the zero address.
+- `account` must have at least `amount` tokens.
+- the caller must be an operator for `account`.
-
-Returns the balance of the account.
+Emitted when `amount` tokens are created by `operator` and assigned to `to`.
+
+Note that some additional user `data` and `operatorData` can be logged in the event.
-Deposits `msg.value` to the account.
+Emitted when `operator` destroys `amount` tokens from `account`.
+
+Note that some additional user `data` and `operatorData` can be logged in the event.
+
+```solidity
+import "@openzeppelin/contracts/interfaces/IERC777Recipient.sol";
+```
+
+Interface of the ERC-777 Tokens Recipient standard as defined in the ERC.
+
+Accounts can be notified of [`IERC777`](#IERC777) tokens being sent to them by having a
+contract implement this interface (contract holders can be their own
+implementer) and registering it on the
+[ERC-1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+
+See [`IERC1820Registry`](#IERC1820Registry) and [`IERC1820Implementer`](#IERC1820Implementer).
+
+
Functions
+
+- [tokensReceived(operator, from, to, amount, userData, operatorData)](#IERC777Recipient-tokensReceived-address-address-address-uint256-bytes-bytes-)
-Withdraws the stake of the account to `withdrawAddress`.
+Called by an [`IERC777`](#IERC777) token contract whenever tokens are being
+moved or created into a registered account (`to`). The type of operation
+is conveyed by `from` being the zero address or not.
+
+This call occurs _after_ the token contract's state is updated, so
+[`IERC777.balanceOf`](#IERC777-balanceOf-address-), etc., can be used to query the post-operation state.
+
+This function may revert to prevent the operation from being executed.
```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
+import "@openzeppelin/contracts/interfaces/IERC777Sender.sol";
```
-Entry point for user operations.
-
-User operations are validated and executed by this contract.
-
-
-
Functions
-
-- [handleOps(ops, beneficiary)](#IEntryPoint-handleOps-struct-PackedUserOperation---address-payable-)
-- [handleAggregatedOps(opsPerAggregator, beneficiary)](#IEntryPoint-handleAggregatedOps-struct-IEntryPoint-UserOpsPerAggregator---address-payable-)
-
-IEntryPointStake
-
-- [balanceOf(account)](#IEntryPointStake-balanceOf-address-)
-- [depositTo(account)](#IEntryPointStake-depositTo-address-)
-- [withdrawTo(withdrawAddress, withdrawAmount)](#IEntryPointStake-withdrawTo-address-payable-uint256-)
-- [addStake(unstakeDelaySec)](#IEntryPointStake-addStake-uint32-)
-- [unlockStake()](#IEntryPointStake-unlockStake--)
-- [withdrawStake(withdrawAddress)](#IEntryPointStake-withdrawStake-address-payable-)
-
-
-
-IEntryPointNonces
+Interface of the ERC-777 Tokens Sender standard as defined in the ERC.
-- [getNonce(sender, key)](#IEntryPointNonces-getNonce-address-uint192-)
+[`IERC777`](#IERC777) Token holders can be notified of operations performed on their
+tokens by having a contract implement this interface (contract holders can be
+their own implementer) and registering it on the
+[ERC-1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
-
-
-
+See [`IERC1820Registry`](#IERC1820Registry) and [`IERC1820Implementer`](#IERC1820Implementer).
-Executes a batch of user operations.
+Called by an [`IERC777`](#IERC777) token contract whenever a registered holder's
+(`from`) tokens are about to be moved or destroyed. The type of operation
+is conveyed by `to` being the zero address or not.
+
+This call occurs _before_ the token contract's state is updated, so
+[`IERC777.balanceOf`](#IERC777-balanceOf-address-), etc., can be used to query the pre-operation state.
+
+This function may revert to prevent the operation from being executed.
-Executes a batch of aggregated user operations per aggregator.
+Verifies `signature` as a valid signature of `hash` by `key`.
+
+MUST return the bytes4 magic value IERC7913SignatureVerifier.verify.selector if the signature is valid.
+SHOULD return 0xffffffff or revert if the signature is not valid.
+SHOULD return 0xffffffff or revert if the key is empty
-A user operation at `opIndex` failed with `reason`.
+```solidity
+import "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
+```
+
+ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
+proxy whose upgrades are fully controlled by the current implementation.
+
-A user operation at `opIndex` failed with `reason` and `inner` returned data.
+Returns the storage slot that the proxiable contract assumes is being used to store the implementation
+address.
+
+
+A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
+bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
+function revert if invoked through a proxy.
+
```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
+import "@openzeppelin/contracts/interfaces/draft-IERC3009.sol";
```
-Base interface for an ERC-4337 account.
+Interface of the ERC-3009 standard as defined in [ERC-3009](https://eips.ethereum.org/EIPS/eip-3009).
-Validates a user operation.
+Returns whether the `nonce` has been used by `authorizer`. A `true` value means the authorization
+has already been consumed (either transferred or canceled) and can no longer be used; a `false` value
+means the nonce is still available.
-* MUST validate the caller is a trusted EntryPoint
-* MUST validate that the signature is a valid signature of the userOpHash, and SHOULD
- return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert.
-* MUST pay the entryPoint (caller) at least the “missingAccountFunds” (which might
- be zero, in case the current account’s deposit is high enough)
+Nonces are randomly generated 32-byte values unique to the authorizer's address.
-Returns an encoded packed validation data that is composed of the following elements:
+
+
-- `authorizer` (`address`): 0 for success, 1 for failure, otherwise the address of an authorizer contract
-- `validUntil` (`uint48`): The UserOp is valid only up to this time. Zero for “infinite”.
-- `validAfter` (`uint48`): The UserOp is valid only after this time.
+
+
-
+Executes a transfer with a signed authorization.
-
+Requirements:
-## `IAccountExecute`
+* `validAfter` must be less than the current block timestamp.
+* `validBefore` must be greater than the current block timestamp.
+* `nonce` must not have been used by the `from` account.
+* the signature must be valid for the authorization.
-
-
-
+
-```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
-```
+Receives a transfer with a signed authorization from the payer.
-Support for executing user operations by prepending the [`IAccountExecute.executeUserOp`](#IAccountExecute-executeUserOp-struct-PackedUserOperation-bytes32-) function selector
-to the UserOperation's `callData`.
+Includes an additional check to ensure that the payee's address (`to`) matches the caller
+to prevent front-running attacks.
+
+Requirements:
+
+* `to` must be the caller of this function.
+* `validAfter` must be less than the current block timestamp.
+* `validBefore` must be greater than the current block timestamp.
+* `nonce` must not have been used by the `from` account.
+* the signature must be valid for the authorization.
-
```solidity
-import "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
+import "@openzeppelin/contracts/interfaces/draft-IERC3009.sol";
```
-Interface for a paymaster contract that agrees to pay for the gas costs of a user operation.
-
-
-A paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.
-
+Extension of [`IERC3009`](#IERC3009) that adds the ability to cancel authorizations.
-Validates whether the paymaster is willing to pay for the user operation. See
-[`IAccount.validateUserOp`](#IAccount-validateUserOp-struct-PackedUserOperation-bytes32-uint256-) for additional information on the return value.
+Cancels an authorization.
-
-Bundlers will reject this method if it modifies the state, unless it's whitelisted.
-
+Requirements:
+
+* `nonce` must not have been used by the `authorizer` account.
+* the signature must be valid for the cancellation.
-Verifies the sender is the entrypoint.
+Emitted when an authorization is canceled.
@@ -3748,7 +3945,7 @@ Verifies the sender is the entrypoint.
## `IERC20Errors`
-
+
@@ -3881,7 +4078,7 @@ Indicates a failure with the `spender` to be approved. Used in approvals.
## `IERC721Errors`
-
+
@@ -4051,7 +4248,7 @@ Indicates a failure with the `operator` to be approved. Used in approvals.
## `IERC1155Errors`
-
+
@@ -4203,7 +4400,7 @@ Used in batch transfers.
## `VALIDATION_SUCCESS`
-
+
@@ -4219,7 +4416,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `VALIDATION_FAILED`
-
+
@@ -4235,7 +4432,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `MODULE_TYPE_VALIDATOR`
-
+
@@ -4251,7 +4448,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `MODULE_TYPE_EXECUTOR`
-
+
@@ -4267,7 +4464,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `MODULE_TYPE_FALLBACK`
-
+
@@ -4283,7 +4480,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `MODULE_TYPE_HOOK`
-
+
@@ -4299,7 +4496,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `IERC7579Module`
-
+
@@ -4377,7 +4574,7 @@ Returns boolean value if module is a certain type
## `IERC7579Validator`
-
+
@@ -4447,7 +4644,7 @@ Validates a signature using ERC-1271
## `IERC7579Hook`
-
+
@@ -4518,7 +4715,7 @@ Called by the smart account after execution
## `Execution`
-
+
@@ -4534,7 +4731,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7579.sol";
## `IERC7579Execution`
-
+
@@ -4597,7 +4794,7 @@ Executes a transaction on behalf of the account.
## `IERC7579AccountConfig`
-
+
@@ -4677,7 +4874,7 @@ Function to check if the account supports a certain module typeId
## `IERC7579ModuleConfig`
-
+
@@ -4796,7 +4993,7 @@ Returns whether a module is installed on the smart account
## `IERC7674`
-
+
@@ -4863,7 +5060,7 @@ held by the caller.
## `IERC7786GatewaySource`
-
+
@@ -4982,7 +5179,7 @@ This error is thrown when a message creation fails because of an unsupported att
## `IERC7786Recipient`
-
+
@@ -5028,7 +5225,7 @@ This function may be called directly by the gateway.
## `IERC7802`
-
+
@@ -5127,7 +5324,7 @@ import "@openzeppelin/contracts/interfaces/draft-IERC7802.sol";
## `IERC7821`
-
+
diff --git a/content/contracts/5.x/api/metatx.mdx b/content/contracts/5.x/api/metatx.mdx
index a6629c1f..bad5f956 100644
--- a/content/contracts/5.x/api/metatx.mdx
+++ b/content/contracts/5.x/api/metatx.mdx
@@ -22,7 +22,7 @@ This directory includes contracts for adding meta-transaction capabilities (i.e.
## `ERC2771Context`
-
+
@@ -170,7 +170,7 @@ ERC-2771 specifies the context as being a single address (20 bytes).
## `ERC2771Forwarder`
-
+
@@ -267,6 +267,7 @@ used to execute arbitrary code.
Errors
+- [ERC2771ForwarderFailureInAtomicBatch()](#ERC2771Forwarder-ERC2771ForwarderFailureInAtomicBatch--)
- [ERC2771ForwarderInvalidSigner(signer, from)](#ERC2771Forwarder-ERC2771ForwarderInvalidSigner-address-address-)
- [ERC2771ForwarderMismatchedValue(requestedValue, msgValue)](#ERC2771Forwarder-ERC2771ForwarderMismatchedValue-uint256-uint256-)
- [ERC2771ForwarderExpiredRequest(deadline)](#ERC2771Forwarder-ERC2771ForwarderExpiredRequest-uint48-)
@@ -505,6 +506,23 @@ the requested call to run out of gas.
+
+One of the calls in an atomic batch failed.
+
+
+
+
diff --git a/content/contracts/5.x/api/proxy.mdx b/content/contracts/5.x/api/proxy.mdx
index ac6ee605..ff681e69 100644
--- a/content/contracts/5.x/api/proxy.mdx
+++ b/content/contracts/5.x/api/proxy.mdx
@@ -13,6 +13,7 @@ In order to avoid clashes with the storage variables of the implementation contr
* [`ERC1967Utils`](#ERC1967Utils): Internal functions to get and set the storage slots defined in ERC-1967.
* [`ERC1967Proxy`](#ERC1967Proxy): A proxy using ERC-1967 storage slots. Not upgradeable by default.
+* [`ERC1967Clones`](#ERC1967Clones): A library that can deploy minimal ERC-1967 proxies that replicate the behavior of [`ERC1967Proxy`](#ERC1967Proxy) with a bytecode optimized for cheap deployment and usage. Unlike [`ERC1967Proxy`](#ERC1967Proxy), the clones do not accept initialization data at construction, so the deployer is expected to initialize the proxy in the same transaction as the deployment.
There are two alternative ways to add upgradeability to an ERC-1967 proxy. Their differences are explained below in [Transparent vs UUPS Proxies](#transparent-vs-uups-proxies).
@@ -60,6 +61,8 @@ The current implementation of this security mechanism uses [ERC-1822](https://ei
[`ERC1967Proxy`](#ERC1967Proxy)
+[`ERC1967Clones`](#ERC1967Clones)
+
[`ERC1967Utils`](#ERC1967Utils)
## Transparent Proxy
@@ -92,7 +95,7 @@ The current implementation of this security mechanism uses [ERC-1822](https://ei
## `Clones`
-
+
@@ -470,13 +473,207 @@ Get the immutable args attached to a clone.
+
+```solidity
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Clones.sol";
+```
+
+[ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) is the standard for upgradeable proxies that
+store the implementation address in a fixed storage slot. This library deploys minimal proxies that
+mimic the behavior of [`ERC1967Proxy`](#ERC1967Proxy) with a bytecode optimized for cheap deployment and usage. The
+deployment emits [`IERC1967.Upgraded`](/contracts/5.x/api/interfaces#IERC1967-Upgraded-address-) from the proxy address, so on-chain tooling and indexers can
+track the new instance from the block it was created in.
+
+The library includes functions to deploy a proxy using either `create` (traditional deployment) or
+`create2` (salted deterministic deployment). It also includes a function to predict the addresses of
+proxies deployed using the deterministic method.
+
+
+Unlike [`ERC1967Proxy`](#ERC1967Proxy), this proxy does not run an initialization call at construction and
+does not check that `implementation` has code. Calls forwarded to a non-contract `implementation`
+succeed silently and return empty data, which an uninitialized clone cannot distinguish from a
+legitimate response. Factories using this library are expected to invoke the initializer on the
+returned address in the same transaction as the deployment.
+
+
+
+
+Deploys and returns the address of a minimal ERC-1967 proxy that delegates to `implementation`.
+
+This function uses the create opcode, which should never revert.
+
+Emits an [`IERC1967.Upgraded`](/contracts/5.x/api/interfaces#IERC1967-Upgraded-address-) event from the deployed proxy.
+
+
+This function does not check if `implementation` has code, and the deployed proxy does not run
+any initialization call at construction.
+
+
+
+
+Same as [clone](#ERC1967Clones-clone-address-), but with a `value` parameter to send native
+currency to the new contract.
+
+Emits an [`IERC1967.Upgraded`](/contracts/5.x/api/interfaces#IERC1967-Upgraded-address-) event from the deployed proxy.
+
+
+This function does not check if `implementation` has code, and the deployed proxy does not run
+any initialization call at construction.
+
+
+
+Using a non-zero value at creation will require the contract using this function (e.g. a factory)
+to always have enough balance for new deployments. Consider exposing this function under a payable method.
+
+
+
+
+Deploys and returns the address of a minimal ERC-1967 proxy that delegates to `implementation`.
+
+This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the
+same `implementation` and `salt` multiple times will revert, since the clones cannot be deployed twice
+at the same address.
+
+Emits an [`IERC1967.Upgraded`](/contracts/5.x/api/interfaces#IERC1967-Upgraded-address-) event from the deployed proxy.
+
+
+This function does not check if `implementation` has code, and the deployed proxy does not run
+any initialization call at construction.
+
+
+
+
+Same as [cloneDeterministic](#ERC1967Clones-cloneDeterministic-address-bytes32-), but with a
+`value` parameter to send native currency to the new contract.
+
+Emits an [`IERC1967.Upgraded`](/contracts/5.x/api/interfaces#IERC1967-Upgraded-address-) event from the deployed proxy.
+
+
+This function does not check if `implementation` has code, and the deployed proxy does not run
+any initialization call at construction.
+
+
+
+Using a non-zero value at creation will require the contract using this function (e.g. a factory)
+to always have enough balance for new deployments. Consider exposing this function under a payable method.
+
+
+
+
+Computes the address of a clone deployed using [`ERC1967Clones.cloneDeterministic`](#ERC1967Clones-cloneDeterministic-address-bytes32-uint256-).
+
+
+
+Computes the address of a clone deployed using [`ERC1967Clones.cloneDeterministic`](#ERC1967Clones-cloneDeterministic-address-bytes32-uint256-).
+
+
+
+
## `ERC1967Proxy`
-
+
@@ -611,7 +808,7 @@ The proxy is left uninitialized.
## `ERC1967Utils`
-
+
@@ -844,7 +1041,7 @@ An upgrade function sees `msg.value > 0` that may be lost.
## `Proxy`
-
+
@@ -953,7 +1150,7 @@ function in the contract matches the call data.
## `BeaconProxy`
-
+
@@ -1062,7 +1259,7 @@ Returns the beacon.
## `IBeacon`
-
+
@@ -1106,7 +1303,7 @@ Must return an address that can be used as a delegate call target.
## `UpgradeableBeacon`
-
+
@@ -1266,7 +1463,7 @@ The `implementation` of the beacon is invalid.
## `ProxyAdmin`
-
+
@@ -1391,7 +1588,7 @@ during an upgrade.
## `ITransparentUpgradeableProxy`
-
+
@@ -1450,7 +1647,7 @@ See [`UUPSUpgradeable.upgradeToAndCall`](#UUPSUpgradeable-upgradeToAndCall-addre
## `TransparentUpgradeableProxy`
-
+
@@ -1619,7 +1816,7 @@ The proxy caller is the current admin, and can't fallback to the proxy target.
## `Initializable`
-
+
@@ -1947,7 +2144,7 @@ The contract is not initializing.
## `UUPSUpgradeable`
-
+
diff --git a/content/contracts/5.x/api/token/ERC1155.mdx b/content/contracts/5.x/api/token/ERC1155.mdx
index 25e8b67f..9e473fdd 100644
--- a/content/contracts/5.x/api/token/ERC1155.mdx
+++ b/content/contracts/5.x/api/token/ERC1155.mdx
@@ -13,6 +13,7 @@ Additionally there are multiple custom extensions, including:
* designation of addresses that can pause token transfers for all users ([`ERC1155Pausable`](#ERC1155Pausable)).
* destruction of own tokens ([`ERC1155Burnable`](#ERC1155Burnable)).
+* crosschain bridging of tokens through ERC-7786 gateways ([`ERC1155Crosschain`](#ERC1155Crosschain)).
This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC-1155 (such as [`_mint`](#ERC1155-_mint-address-uint256-uint256-bytes-)) and expose them as external functions in the way they prefer.
@@ -30,10 +31,12 @@ This core set of contracts is designed to be unopinionated, allowing developers
## Extensions
-[`ERC1155Pausable`](#ERC1155Pausable)
-
[`ERC1155Burnable`](#ERC1155Burnable)
+[`ERC1155Crosschain`](#ERC1155Crosschain)
+
+[`ERC1155Pausable`](#ERC1155Pausable)
+
[`ERC1155Supply`](#ERC1155Supply)
[`ERC1155URIStorage`](#ERC1155URIStorage)
@@ -50,7 +53,7 @@ This core set of contracts is designed to be unopinionated, allowing developers
## `ERC1155`
-
+
@@ -649,7 +652,7 @@ Requirements:
## `IERC1155`
-
+
@@ -917,7 +920,7 @@ returned by [`IERC1155MetadataURI.uri`](#IERC1155MetadataURI-uri-uint256-).
## `IERC1155Receiver`
-
+
@@ -999,7 +1002,7 @@ To accept the transfer(s), this must return
## `ERC1155Burnable`
-
+
@@ -1108,13 +1111,218 @@ own tokens and those that they have been approved to use.
+
+```solidity
+import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Crosschain.sol";
+```
+
+Extension of [`ERC1155`](#ERC1155) that makes it natively cross-chain using the ERC-7786 based [`BridgeMultiToken`](/contracts/5.x/api/crosschain#BridgeMultiToken).
+
+This extension makes the token compatible with:
+* [`ERC1155Crosschain`](#ERC1155Crosschain) instances on other chains,
+* [`ERC1155`](#ERC1155) instances on other chains that are bridged using [`BridgeERC1155`](/contracts/5.x/api/crosschain#BridgeERC1155),
+
+
+
+TransferFrom variant of [`ERC1155Crosschain.crosschainTransferFrom`](#ERC1155Crosschain-crosschainTransferFrom-address-bytes-uint256---uint256---), using ERC1155 allowance from the sender to the caller.
+
+
+
+
+
+
+
+
+
crosschainTransferFrom(address from, bytes to, uint256[] ids, uint256[] values) → bytes32
+
+TransferFrom variant of [`ERC1155Crosschain.crosschainTransferFrom`](#ERC1155Crosschain-crosschainTransferFrom-address-bytes-uint256---uint256---), using ERC1155 allowance from the sender to the caller.
+
+
+
+"Unlocking" tokens is achieved through minting
+
+
+
+
## `ERC1155Pausable`
-
+
@@ -1253,7 +1461,7 @@ Requirements:
## `ERC1155Supply`
-
+
@@ -1433,7 +1641,7 @@ The ERC-1155 acceptance check is not performed in this function. See [`ERC1155._
## `ERC1155URIStorage`
-
+
@@ -1584,7 +1792,7 @@ Sets `baseURI` as the `_baseURI` for all tokens
## `IERC1155MetadataURI`
-
+
@@ -1662,7 +1870,7 @@ clients with the actual token type ID.
## `ERC1155Holder`
-
+
@@ -1748,7 +1956,7 @@ This function call must use less than 30 000 gas.
## `ERC1155Utils`
-
+
@@ -1810,7 +2018,7 @@ Performs a batch acceptance check for the provided `operator` by calling [`IERC1
on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
-Otherwise, the recipient must implement [`IERC1155Receiver.onERC1155Received`](#IERC1155Receiver-onERC1155Received-address-address-uint256-uint256-bytes-) and return the acceptance magic value to accept
+Otherwise, the recipient must implement [`IERC1155Receiver.onERC1155BatchReceived`](#IERC1155Receiver-onERC1155BatchReceived-address-address-uint256---uint256---bytes-) and return the acceptance magic value to accept
the transfer.
diff --git a/content/contracts/5.x/api/token/ERC20.mdx b/content/contracts/5.x/api/token/ERC20.mdx
index 007f0149..1c356d3d 100644
--- a/content/contracts/5.x/api/token/ERC20.mdx
+++ b/content/contracts/5.x/api/token/ERC20.mdx
@@ -18,6 +18,8 @@ There are a few core contracts that implement the behavior specified in the ERC-
Additionally there are multiple custom extensions, including:
* [`ERC20Permit`](#ERC20Permit): gasless approval of tokens (standardized as ERC-2612).
+* [`ERC3009`](#ERC3009): gasless transfer of tokens via signed authorizations (standardized as ERC-3009).
+* [`ERC20TransferAuthorization`](#ERC20TransferAuthorization): variant of [`ERC3009`](#ERC3009) using keyed sequential nonces and supporting ERC-1271 signatures.
* [`ERC20Bridgeable`](#ERC20Bridgeable): compatibility with crosschain bridges through ERC-7802.
* [`ERC20Burnable`](#ERC20Burnable): destruction of own tokens.
* [`ERC20Capped`](#ERC20Capped): enforcement of a cap to the total supply when minting tokens.
@@ -56,6 +58,14 @@ This core set of contracts is designed to be unopinionated, allowing developers
[`ERC20Permit`](#ERC20Permit)
+[`IERC3009`](/contracts/5.x/api/interfaces#IERC3009)
+
+[`IERC3009Cancel`](/contracts/5.x/api/interfaces#IERC3009Cancel)
+
+[`ERC3009`](#ERC3009)
+
+[`ERC20TransferAuthorization`](#ERC20TransferAuthorization)
+
[`ERC20Bridgeable`](#ERC20Bridgeable)
[`ERC20Burnable`](#ERC20Burnable)
@@ -90,7 +100,7 @@ This core set of contracts is designed to be unopinionated, allowing developers
## `ERC20`
-
+
@@ -574,7 +584,7 @@ Does not emit an [`IERC20.Approval`](#IERC20-Approval-address-address-uint256-)
## `IERC20`
-
+
@@ -781,7 +791,7 @@ a call to [`ERC20.approve`](#ERC20-approve-address-uint256-). `value` is the new
## `ERC1363`
-
+
@@ -1075,7 +1085,7 @@ Indicates a failure within the [`ERC20.approve`](#ERC20-approve-address-uint256-
## `ERC20Burnable`
-
+
@@ -1186,7 +1196,7 @@ See [`ERC20._burn`](#ERC20-_burn-address-uint256-) and [`ERC20.allowance`](#ERC2
Requirements:
-- the caller must have allowance for ``accounts``'s tokens of at least
+- the caller must have allowance for `account`'s tokens of at least
`value`.
@@ -1198,7 +1208,7 @@ Requirements:
## `ERC20Capped`
-
+
@@ -1367,7 +1377,7 @@ The supplied cap is not a valid cap.
## `ERC20Crosschain`
-
+
@@ -1554,7 +1564,7 @@ Variant of [`BridgeFungible.crosschainTransfer`](/contracts/5.x/api/crosschain#B
## `ERC20FlashMint`
-
+
@@ -1696,7 +1706,7 @@ loans.
Returns the fee applied when doing flash loans. By default this
-implementation has 0 fees. This function can be overloaded to make
+implementation has 0 fees. This function can be overridden to make
the flash loan mechanism deflationary.
@@ -1716,7 +1726,7 @@ the flash loan mechanism deflationary.
Returns the receiver address of the flash fee. By default this
implementation returns the address(0) which means the fee amount will be burnt.
-This function can be overloaded to change the fee receiver.
+This function can be overridden to change the fee receiver.
@@ -1799,7 +1809,7 @@ The receiver of a flashloan is not a valid [`IERC3156FlashBorrower.onFlashLoan`]
## `ERC20Pausable`
-
+
@@ -1931,7 +1941,7 @@ Requirements:
## `ERC20Permit`
-
+
@@ -2172,13 +2182,275 @@ Mismatched signature.
+
+```solidity
+import "@openzeppelin/contracts/token/ERC20/extensions/ERC20TransferAuthorization.sol";
+```
+
+Variant of `ERC-3009` that uses keyed sequential nonces as defined in [`NoncesKeyed`](/contracts/5.x/api/utils#NoncesKeyed).
+
+
+This extension uses keyed sequential nonces following the
+[ERC-4337 semi-abstracted nonce system](https://eips.ethereum.org/EIPS/eip-4337#semi-abstracted-nonce-support).
+The `bytes32` nonce field is interpreted as a 192-bit key packed with a 64-bit sequence. Nonces with
+different keys are independent and can be submitted in parallel without ordering constraints, while nonces
+sharing the same key must be used sequentially. This is unlike [`ERC20Permit`](#ERC20Permit) which uses a single global
+sequential nonce.
+
+
+
+
+See [`IERC3009.authorizationState`](/contracts/5.x/api/interfaces#IERC3009-authorizationState-address-bytes32-).
+
+
+Returning `false` does not guarantee that the authorization is currently executable.
+With keyed sequential nonces, a nonce may be blocked by a predecessor in the same key's sequence
+that has not yet been consumed.
+
+
+
+
+Same as [`ERC20TransferAuthorization.transferWithAuthorization`](#ERC20TransferAuthorization-transferWithAuthorization-address-address-uint256-uint256-uint256-bytes32-bytes-) but with a bytes signature.
+
+
+
+Same as [`ERC20TransferAuthorization.receiveWithAuthorization`](#ERC20TransferAuthorization-receiveWithAuthorization-address-address-uint256-uint256-uint256-bytes32-bytes-) but with a bytes signature.
+
+
+
+Same as [`ERC20TransferAuthorization.cancelAuthorization`](#ERC20TransferAuthorization-cancelAuthorization-address-bytes32-bytes-) but with a bytes signature.
+
+
+Due to the keyed sequential nonce model, only the next nonce in a given key's sequence
+can be cancelled. It is not possible to directly cancel a future nonce whose predecessors in the
+same key have not yet been consumed or cancelled. To invalidate a future authorization, all
+preceding nonces in the same key must first be consumed or cancelled in order.
+
+
+
+
+Override the internal nonce consumption logic to use the keyed sequential nonces from [`NoncesKeyed`](/contracts/5.x/api/utils#NoncesKeyed).
+
+
+This override does not call `super._consumeNonce`, so any sibling override added by another extension
+is skipped under C3 linearization. Integrators combining this contract with extensions that introduce
+additional side effects through `_consumeNonce` must reintroduce those side effects themselves.
+
+
+
+
+
## `ERC20Votes`
-
+
@@ -2227,7 +2499,7 @@ requires users to delegate to themselves in order to activate checkpoints and ha
- [_transferVotingUnits(from, to, amount)](#Votes-_transferVotingUnits-address-address-uint256-)
- [_moveDelegateVotes(from, to, amount)](#Votes-_moveDelegateVotes-address-address-uint256-)
- [_numCheckpoints(account)](#Votes-_numCheckpoints-address-)
-- [_checkpoints(account, pos)](#Votes-_checkpoints-address-uint32-)
+- [_checkpoints(account, index)](#Votes-_checkpoints-address-uint32-)
@@ -2304,7 +2576,6 @@ requires users to delegate to themselves in order to activate checkpoints and ha
Votes
-- [ERC6372InconsistentClock()](#Votes-ERC6372InconsistentClock--)
- [ERC5805FutureLookup(timepoint, clock)](#Votes-ERC5805FutureLookup-uint256-uint48-)
@@ -2456,7 +2727,7 @@ Total supply cap has been exceeded, introducing a risk of votes overflowing.
## `ERC20Wrapper`
-
+
@@ -2569,6 +2840,14 @@ for recovering value accrued to the wrapper.
+See [`IERC20Metadata`](#IERC20Metadata). Uses [`Math.ternary`](/contracts/5.x/api/utils#Math-ternary-bool-uint256-uint256-) for branchless selection, which evaluates both branches. This is safe
+because the default [`ERC20.decimals`](#ERC20-decimals--) is commonly a constant.
+
+
+If a derived contract overrides `super.decimals()` to read from
+storage, it should also override this function and use a conditional ternary instead.
+
+
@@ -2664,7 +2943,7 @@ The underlying token couldn't be wrapped.
## `ERC4626`
-
+
@@ -3465,7 +3744,7 @@ Attempted to redeem more shares than the max amount for `owner`.
## `IERC20Metadata`
-
+
@@ -3567,7 +3846,7 @@ Returns the decimals places of the token.
## `IERC20Permit`
-
+
@@ -3706,7 +3985,7 @@ Returns the domain separator used in the encoding of the signature for [`ERC20Pe
## `ERC20Bridgeable`
-
+
@@ -3894,7 +4173,7 @@ customizing the list of allowed senders. Consider using [`AccessControl`](/contr
## `ERC20TemporaryApproval`
-
+
@@ -4080,13 +4359,370 @@ is enough to cover the spending.
+
+```solidity
+import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC3009.sol";
+```
+
+Implementation of the ERC-3009 Transfer With Authorization extension allowing
+transfers to be made via signatures, as defined in [ERC-3009](https://eips.ethereum.org/EIPS/eip-3009).
+
+Adds the [`ERC20TransferAuthorization.transferWithAuthorization`](#ERC20TransferAuthorization-transferWithAuthorization-address-address-uint256-uint256-uint256-bytes32-bytes-) and [`ERC20TransferAuthorization.receiveWithAuthorization`](#ERC20TransferAuthorization-receiveWithAuthorization-address-address-uint256-uint256-uint256-bytes32-bytes-) methods, which
+can be used to change an account's ERC-20 balance by presenting a message signed
+by the account. By not relying on [`IERC20.approve`](#IERC20-approve-address-uint256-) and [`IERC20.transferFrom`](#IERC20-transferFrom-address-address-uint256-), the
+token holder account doesn't need to send a transaction, and thus is not required
+to hold native currency (e.g. ETH) at all.
+
+
+To enable both timestamp-based and block-number-based validity windows, `validAfter` and
+`validBefore` use a dual-clock encoding mirroring [`ERC4337Utils`](/contracts/5.x/api/account#ERC4337Utils). Bit 47 ([`ERC4337Utils.BLOCK_RANGE_FLAG`](/contracts/5.x/api/account#ERC4337Utils-BLOCK_RANGE_FLAG-uint48)) acts as a
+clock selector: when *both* `validAfter` and `validBefore` have this bit set, the values are interpreted
+as block numbers; otherwise they are interpreted as Unix timestamps (the default, matching the ERC-3009
+specification). Since the current clock fits in 48 bits, any bit set at position 47 or above (other than
+the active clock-mode flag) makes the value point to an unreachable future. See [`ERC3009._checkValidity`](#ERC3009-_checkValidity-uint256-uint256-).
+
+
+
+
+Returns whether the `nonce` has been used by `authorizer`. A `true` value means the authorization
+has already been consumed (either transferred or canceled) and can no longer be used; a `false` value
+means the nonce is still available.
+
+Nonces are randomly generated 32-byte values unique to the authorizer's address.
+
+
+
+Executes a transfer with a signed authorization.
+
+Requirements:
+
+* `validAfter` must be less than the current block timestamp.
+* `validBefore` must be greater than the current block timestamp.
+* `nonce` must not have been used by the `from` account.
+* the signature must be valid for the authorization.
+
+
+
+Receives a transfer with a signed authorization from the payer.
+
+Includes an additional check to ensure that the payee's address (`to`) matches the caller
+to prevent front-running attacks.
+
+Requirements:
+
+* `to` must be the caller of this function.
+* `validAfter` must be less than the current block timestamp.
+* `validBefore` must be greater than the current block timestamp.
+* `nonce` must not have been used by the `from` account.
+* the signature must be valid for the authorization.
+
+
+
+Cancels an authorization.
+
+Requirements:
+
+* `nonce` must not have been used by the `authorizer` account.
+* the signature must be valid for the cancellation.
+
+
+
+Marks `nonce` as used for `authorizer`. Reverts with [`ERC3009.ERC3009UsedAuthorization`](#ERC3009-ERC3009UsedAuthorization-address-bytes32-) if already consumed.
+
+
+
+Checks the validity of the authorization against the current clock.
+
+Following the ERC-4337-style dual-clock encoding, the clock is interpreted as block number only when
+*both* `validAfter` and `validBefore` carry the [`ERC4337Utils.BLOCK_RANGE_FLAG`](/contracts/5.x/api/account#ERC4337Utils-BLOCK_RANGE_FLAG-uint48); otherwise it falls back to
+timestamp (matching the ERC-3009 specification's default). Mixed-flag inputs therefore fall back to
+the timestamp clock rather than reverting, mirroring [`ERC4337Utils.parseValidationData`](/contracts/5.x/api/account#ERC4337Utils-parseValidationData-uint256-). The flag bit
+is masked off the values only when block-mode is engaged; in timestamp mode the full 256-bit value
+participates in the comparison.
+
+
+Any `validAfter` or `validBefore` with a bit set at position 47 or above (other than the active
+clock-mode flag) is interpreted as an unreachable point in the future (i.e. never valid after or
+always valid before, respectively).
+
+
+
+
+The authorization has already been used or canceled
+
+
+
+
## `ERC1363Utils`
-
+
@@ -4202,7 +4838,7 @@ Indicates a failure with the token `spender`. Used in approvals.
## `SafeERC20`
-
+
@@ -4232,6 +4868,7 @@ which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
- [transferAndCallRelaxed(token, to, value, data)](#SafeERC20-transferAndCallRelaxed-contract-IERC1363-address-uint256-bytes-)
- [transferFromAndCallRelaxed(token, from, to, value, data)](#SafeERC20-transferFromAndCallRelaxed-contract-IERC1363-address-address-uint256-bytes-)
- [approveAndCallRelaxed(token, to, value, data)](#SafeERC20-approveAndCallRelaxed-contract-IERC1363-address-uint256-bytes-)
+- [tryGetDecimals(token)](#SafeERC20-tryGetDecimals-contract-IERC20-)
@@ -4457,6 +5094,23 @@ Reverts if the returned value is other than `true`.
+
+Attempts to fetch the token decimals. A return value of false indicates that the attempt failed in some way.
+
+
+
+
diff --git a/content/contracts/5.x/api/token/ERC6909.mdx b/content/contracts/5.x/api/token/ERC6909.mdx
index cb2ebfa5..f2e1f836 100644
--- a/content/contracts/5.x/api/token/ERC6909.mdx
+++ b/content/contracts/5.x/api/token/ERC6909.mdx
@@ -32,7 +32,7 @@ Implementations are provided for each of the 4 interfaces defined in the ERC.
## `ERC6909`
-
+
@@ -512,7 +512,7 @@ Does not emit an [`IERC6909.Approval`](/contracts/5.x/api/interfaces#IERC6909-Ap
## `ERC6909ContentURI`
-
+
@@ -722,7 +722,7 @@ See [`IERC1155.URI`](/contracts/5.x/api/token/ERC1155#IERC1155-URI-string-uint25
## `ERC6909Metadata`
-
+
@@ -988,7 +988,7 @@ The decimals value for token of type `id` was updated to `newDecimals`.
## `ERC6909TokenSupply`
-
+
diff --git a/content/contracts/5.x/api/token/ERC721.mdx b/content/contracts/5.x/api/token/ERC721.mdx
index 32fbdfff..8d73ab0d 100644
--- a/content/contracts/5.x/api/token/ERC721.mdx
+++ b/content/contracts/5.x/api/token/ERC721.mdx
@@ -24,12 +24,13 @@ OpenZeppelin Contracts provides implementations of all four interfaces:
Additionally there are a few of other extensions:
+* [`ERC721Burnable`](#ERC721Burnable): A way for token holders to burn their own tokens.
* [`ERC721Consecutive`](#ERC721Consecutive): An implementation of [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) for minting batches of tokens during construction, in accordance with ERC-721.
+* [`ERC721Crosschain`](#ERC721Crosschain): Embedded [`BridgeNonFungible`](/contracts/5.x/api/crosschain#BridgeNonFungible) bridge, making the token crosschain through the use of ERC-7786 gateways.
+* [`ERC721Pausable`](#ERC721Pausable): A primitive to pause contract operation.
+* [`ERC721Royalty`](#ERC721Royalty): A way to signal royalty information following ERC-2981.
* [`ERC721URIStorage`](#ERC721URIStorage): A more flexible but more expensive way of storing metadata.
* [`ERC721Votes`](#ERC721Votes): Support for voting and vote delegation.
-* [`ERC721Royalty`](#ERC721Royalty): A way to signal royalty information following ERC-2981.
-* [`ERC721Pausable`](#ERC721Pausable): A primitive to pause contract operation.
-* [`ERC721Burnable`](#ERC721Burnable): A way for token holders to burn their own tokens.
* [`ERC721Wrapper`](#ERC721Wrapper): Wrapper to create an ERC-721 backed by another ERC-721, with deposit and withdraw methods. Useful in conjunction with [`ERC721Votes`](#ERC721Votes).
@@ -52,18 +53,20 @@ This core set of contracts is designed to be unopinionated, allowing developers
## Extensions
-[`ERC721Pausable`](#ERC721Pausable)
-
[`ERC721Burnable`](#ERC721Burnable)
[`ERC721Consecutive`](#ERC721Consecutive)
-[`ERC721URIStorage`](#ERC721URIStorage)
+[`ERC721Crosschain`](#ERC721Crosschain)
-[`ERC721Votes`](#ERC721Votes)
+[`ERC721Pausable`](#ERC721Pausable)
[`ERC721Royalty`](#ERC721Royalty)
+[`ERC721URIStorage`](#ERC721URIStorage)
+
+[`ERC721Votes`](#ERC721Votes)
+
[`ERC721Wrapper`](#ERC721Wrapper)
## Utilities
@@ -78,7 +81,7 @@ This core set of contracts is designed to be unopinionated, allowing developers
## `ERC721`
-
+
@@ -896,7 +899,7 @@ Overrides to ownership logic should be done to [`ERC721._ownerOf`](#ERC721-_owne
## `IERC721`
-
+
@@ -1215,7 +1218,7 @@ Emitted when `owner` enables or disables (`approved`) `operator` to manage all o
## `IERC721Receiver`
-
+
@@ -1265,7 +1268,7 @@ The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.
## `ERC721Burnable`
-
+
@@ -1380,7 +1383,7 @@ Requirements:
## `ERC721Consecutive`
-
+
@@ -1555,7 +1558,7 @@ been minted as part of a batch, and not yet transferred.
Mint a batch of tokens of length `batchSize` for `to`. Returns the token id of the first token minted in the
-batch; if `batchSize` is 0, returns the number of consecutive ids minted so far.
+batch; if `batchSize` is 0, returns the next token id to be minted consecutively.
Requirements:
@@ -1685,13 +1688,211 @@ Batch burn is not supported.
+
+```solidity
+import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Crosschain.sol";
+```
+
+Extension of [`ERC721`](#ERC721) that makes it natively cross-chain using the ERC-7786 based [`BridgeNonFungible`](/contracts/5.x/api/crosschain#BridgeNonFungible).
+
+This extension makes the token compatible with:
+* [`ERC721Crosschain`](#ERC721Crosschain) instances on other chains,
+* [`ERC721`](#ERC721) instances on other chains that are bridged using [`BridgeERC721`](/contracts/5.x/api/crosschain#BridgeERC721),
+
+
+
+Crosschain variant of [`ERC721.transferFrom`](#ERC721-transferFrom-address-address-uint256-), using the allowance system from the underlying ERC-721 token.
+
+
+
+"Unlocking" tokens is achieved through minting
+
+
+
+
## `ERC721Enumerable`
-
+
@@ -1950,7 +2151,7 @@ Batch mint is not allowed.
## `ERC721Pausable`
-
+
@@ -2100,7 +2301,7 @@ Requirements:
## `ERC721Royalty`
-
+
@@ -2238,7 +2439,7 @@ voluntarily pay royalties together with sales, but note that this standard is no
## `ERC721URIStorage`
-
+
@@ -2413,7 +2614,7 @@ Returns the suffix part of the tokenURI for `tokenId`.
## `ERC721Votes`
-
+
@@ -2453,7 +2654,7 @@ the votes in governance decisions, or they can delegate to themselves to be thei
- [_transferVotingUnits(from, to, amount)](#Votes-_transferVotingUnits-address-address-uint256-)
- [_moveDelegateVotes(from, to, amount)](#Votes-_moveDelegateVotes-address-address-uint256-)
- [_numCheckpoints(account)](#Votes-_numCheckpoints-address-)
-- [_checkpoints(account, pos)](#Votes-_checkpoints-address-uint32-)
+- [_checkpoints(account, index)](#Votes-_checkpoints-address-uint32-)
@@ -2544,7 +2745,6 @@ the votes in governance decisions, or they can delegate to themselves to be thei
Votes
-- [ERC6372InconsistentClock()](#Votes-ERC6372InconsistentClock--)
- [ERC5805FutureLookup(timepoint, clock)](#Votes-ERC5805FutureLookup-uint256-uint48-)
@@ -2639,7 +2839,7 @@ See [`ERC721._increaseBalance`](#ERC721-_increaseBalance-address-uint128-). We n
## `ERC721Wrapper`
-
+
@@ -2870,7 +3070,7 @@ The received ERC-721 token couldn't be wrapped.
## `IERC721Enumerable`
-
+
@@ -2984,7 +3184,7 @@ Use along with [`ERC721Enumerable.totalSupply`](#ERC721Enumerable-totalSupply--)
## `IERC721Metadata`
-
+
@@ -3096,7 +3296,7 @@ Returns the Uniform Resource Identifier (URI) for `tokenId` token.
## `ERC721Holder`
-
+
@@ -3146,7 +3346,7 @@ Always returns `IERC721Receiver.onERC721Received.selector`.
## `ERC721Utils`
-
+
diff --git a/content/contracts/5.x/api/token/common.mdx b/content/contracts/5.x/api/token/common.mdx
index 1f1b5644..598e22cd 100644
--- a/content/contracts/5.x/api/token/common.mdx
+++ b/content/contracts/5.x/api/token/common.mdx
@@ -18,7 +18,7 @@ Functionality that is common to multiple token standards.
## `ERC2981`
-
+
diff --git a/content/contracts/5.x/api/utils.mdx b/content/contracts/5.x/api/utils.mdx
index 5989c483..e7d39c29 100644
--- a/content/contracts/5.x/api/utils.mdx
+++ b/content/contracts/5.x/api/utils.mdx
@@ -27,21 +27,26 @@ Miscellaneous contracts and libraries containing utility functions you can use t
* [`Base58`](#Base58): On-chain base58 encoding and decoding.
* [`Base64`](#Base64): On-chain base64 and base64URL encoding according to [RFC-4648](https://datatracker.ietf.org/doc/html/rfc4648).
* [`Blockhash`](#Blockhash): A library for accessing historical block hashes beyond the standard 256 block limit utilizing EIP-2935’s historical blockhash functionality.
+* [`BlockHeader`](#BlockHeader): A library for parsing and verifying RLP-encoded block headers.
* [`Bytes`](#Bytes): Common operations on bytes objects.
* [`CAIP2`](#CAIP2), [`CAIP10`](#CAIP10): Libraries for formatting and parsing CAIP-2 and CAIP-10 identifiers.
* [`Calldata`](#Calldata): Helpers for manipulating calldata.
* [`Comparators`](#Comparators): A library that contains comparator functions to use with the [`Heap`](#Heap) library.
* [`Context`](#Context): A utility for abstracting the sender and calldata in the current execution context.
* [`Create2`](#Create2): Wrapper around the [`CREATE2` EVM opcode](https://blog.openzeppelin.com/getting-the-most-out-of-create2/) for safe use without having to deal with low-level assembly.
+* [`Create3`](#Create3): Library implementing the Create3 mechanism for counterfactually deploying contract at addresses that are only affected by the salt (and not by the bytecodehash like Create2).
+* [`ERC6372Utils`](#ERC6372Utils): Utility library for the ERC-6372 clock standard
* [`InteroperableAddress`](#InteroperableAddress): Library for formatting and parsing ERC-7930 interoperable addresses.
* [`LowLevelCall`](#LowLevelCall): Collection of functions to perform calls with low-level assembly.
* [`Memory`](#Memory): A utility library to manipulate memory.
* [`Multicall`](#Multicall): Abstract contract with a utility to allow batching together multiple calls in a single transaction. Useful for allowing EOAs to perform multiple operations at once.
* [`Packing`](#Packing): A library for packing and unpacking multiple values into bytes32.
* [`Panic`](#Panic): A library to revert with [Solidity panic codes](https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require).
+* [`RateLimiter`](#RateLimiter): A library that provides primitives for limiting the rate at which an action can be performed, using a refilling token bucket or a sliding window counter.
* [`RelayedCall`](#RelayedCall): A library for performing calls that use minimal and predictable relayers to hide the sender.
* [`RLP`](#RLP): Library for encoding and decoding data in Ethereum’s Recursive Length Prefix format.
* [`ShortStrings`](#ShortStrings): Library to encode (and decode) short strings into (or from) a single bytes32 slot for optimizing costs. Short strings are limited to 31 characters.
+* [`SimulateCall`](#SimulateCall): Library for simulating contract calls, enabling safe inspection of call results without affecting on-chain state.
* [`SlotDerivation`](#SlotDerivation): Methods for deriving storage slot from ERC-7201 namespaces as well as from constructions such as mapping and arrays.
* [`StorageSlot`](#StorageSlot): Methods for accessing specific storage slots formatted as common primitive types.
* [`Strings`](#Strings): Common operations for strings formatting.
@@ -116,6 +121,8 @@ Ethereum contracts have no native concept of an interface, so applications must
[`Blockhash`](#Blockhash)
+[`BlockHeader`](#BlockHeader)
+
[`Bytes`](#Bytes)
[`CAIP10`](#CAIP10)
@@ -130,6 +137,10 @@ Ethereum contracts have no native concept of an interface, so applications must
[`Create2`](#Create2)
+[`Create3`](#Create3)
+
+[`ERC6372Utils`](#ERC6372Utils)
+
[`InteroperableAddress`](#InteroperableAddress)
[`LowLevelCall`](#LowLevelCall)
@@ -142,12 +153,16 @@ Ethereum contracts have no native concept of an interface, so applications must
[`Panic`](#Panic)
+[`RateLimiter`](#RateLimiter)
+
[`RelayedCall`](#RelayedCall)
[`RLP`](#RLP)
[`ShortStrings`](#ShortStrings)
+[`SimulateCall`](#SimulateCall)
+
[`SlotDerivation`](#SlotDerivation)
[`StorageSlot`](#StorageSlot)
@@ -164,7 +179,7 @@ Ethereum contracts have no native concept of an interface, so applications must
## `Address`
-
+
@@ -383,7 +398,7 @@ There's no code at `target` (it is not a contract).
## `Arrays`
-
+
@@ -1439,7 +1454,7 @@ this does not clear elements if length is reduced, or initialize elements if len
## `Base58`
-
+
@@ -1535,7 +1550,7 @@ Unrecognized Base58 character on decoding.
## `Base64`
-
+
@@ -1634,1012 +1649,2205 @@ Converts a Base64 `string` to the `bytes` it represents.
```solidity
-import "@openzeppelin/contracts/utils/Blockhash.sol";
+import "@openzeppelin/contracts/utils/BlockHeader.sol";
```
-Library for accessing historical block hashes beyond the standard 256 block limit.
-Uses EIP-2935's history storage contract which maintains a ring buffer of the last
-8191 block hashes in state.
-
-For blocks within the last 256 blocks, it uses the native `BLOCKHASH` opcode.
-For blocks between 257 and 8191 blocks ago, it queries the EIP-2935 history storage.
-For blocks older than 8191 or future blocks, it returns zero, matching the `BLOCKHASH` behavior.
-
-
-After EIP-2935 activation, it takes 8191 blocks to completely fill the history.
-Before that, only block hashes since the fork block will be available.
-
+Library for parsing and verifying RLP-encoded block headers.
-Retrieves the block hash for any historical block within the supported range.
+Verifies that the given block header RLP corresponds to a valid block header for the current chain.
-The function gracefully handles future blocks and blocks beyond the history window
-by returning zero, consistent with the EVM's native `BLOCKHASH` behavior.
+Blocks older than 8191 blocks ago are not available through `Blockhash.blockHash`
-## `Bytes`
+Variant of [`BlockHeader.verifyBlockHeader`](#BlockHeader-verifyBlockHeader-Memory-Slice---bytes32-) that takes a pre-parsed list of fields and a pre-computed
+header hash.
-
-
-
+
+The caller must supply `headerHash == keccak256(rlp)`, where `rlp` is the RLP
+buffer that `fields` was parsed from; this overload only checks that `headerHash` is the
+canonical hash for the block number in `fields`. Use this when the hash was already computed
+to avoid a second `keccak256`.
+
+
+
+Decode the block header RLP into a list of field slices. Use this when reading multiple fields to avoid
+decoding the RLP list more than once. The returned slices reference the input buffer, so it must not be mutated.
-
-Forward search for `s` in `buffer`
-* If `s` is present in the buffer, returns the index of the first instance
-* If `s` is not present in the buffer, returns type(uint256).max
-
-
-replicates the behavior of [Javascript's `Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
-
+Extract the parent hash from the block header RLP.
-Forward search for `s` in `buffer` starting at position `pos`
-* If `s` is present in the buffer (at or after `pos`), returns the index of the next instance
-* If `s` is not present in the buffer (at or after `pos`), returns type(uint256).max
-
-
-replicates the behavior of [Javascript's `Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
-
+Extract the parent hash from pre-parsed header fields.
-Backward search for `s` in `buffer`
-* If `s` is present in the buffer, returns the index of the last instance
-* If `s` is not present in the buffer, returns type(uint256).max
-
-
-replicates the behavior of [Javascript's `Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
-
+Extract the ommers hash from the block header RLP. This is constant to keccak256(rlp([])) since EIP-3675 (Paris)
-Backward search for `s` in `buffer` starting at position `pos`
-* If `s` is present in the buffer (at or before `pos`), returns the index of the previous instance
-* If `s` is not present in the buffer (at or before `pos`), returns type(uint256).max
-
-
-replicates the behavior of [Javascript's `Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
-
+Extract the ommers hash from pre-parsed header fields.
-Copies the content of `buffer`, from `start` (included) to the end of `buffer` into a new bytes object in
-memory.
-
-
-replicates the behavior of [Javascript's `Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
-
+Extract the coinbase (a.k.a. beneficiary or miner) address from the block header RLP.
-Copies the content of `buffer`, from `start` (included) to `end` (excluded) into a new bytes object in
-memory. The `end` argument is truncated to the length of the `buffer`.
-
-
-replicates the behavior of [Javascript's `Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
-
+Extract the coinbase from pre-parsed header fields.
-Moves the content of `buffer`, from `start` (included) to the end of `buffer` to the start of that buffer,
-and shrinks the buffer length accordingly, effectively overriding the content of buffer with buffer[start:].
-
-
-This function modifies the provided buffer in place. If you need to preserve the original buffer, use [`Arrays.slice`](#Arrays-slice-uint256---uint256-uint256-) instead
-
+Extract the state root from the block header RLP.
-Moves the content of `buffer`, from `start` (included) to `end` (excluded) to the start of that buffer,
-and shrinks the buffer length accordingly, effectively overriding the content of buffer with buffer[start:end].
-The `end` argument is truncated to the length of the `buffer`.
-
-
-This function modifies the provided buffer in place. If you need to preserve the original buffer, use [`Arrays.slice`](#Arrays-slice-uint256---uint256-uint256-) instead
-
+Extract the state root from pre-parsed header fields.
-Replaces bytes in `buffer` starting at `pos` with all bytes from `replacement`.
-
-Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, buffer.length]`).
-If `pos >= buffer.length`, no replacement occurs and the buffer is returned unchanged.
-
-
-This function modifies the provided buffer in place.
-
+Extract the transactions root from the block header RLP.
-Replaces bytes in `buffer` starting at `pos` with bytes from `replacement` starting at `offset`.
-Copies at most `length` bytes from `replacement` to `buffer`.
-
-Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, buffer.length]`, `offset` is
-clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,
-buffer.length - pos))`. If `pos >= buffer.length` or `offset >= replacement.length`, no replacement occurs
-and the buffer is returned unchanged.
-
-
-This function modifies the provided buffer in place.
-
+Extract the transactions root from pre-parsed header fields.
-Concatenate an array of bytes into a single bytes object.
-
-For fixed bytes types, we recommend using the solidity built-in `bytes.concat` or (equivalent)
-`abi.encodePacked`.
-
-
-this could be done in assembly with a single loop that expands starting at the FMP, but that would be
-significantly less readable. It might be worth benchmarking the savings of the full-assembly approach.
-
+Extract the receipts root from the block header RLP.
-Split each byte in `input` into two nibbles (4 bits each)
-
-Example: hex"01234567" → hex"0001020304050607"
+Extract the receipts root from pre-parsed header fields.
-Reverses the byte order of a bytes32 value, converting between little-endian and big-endian.
-Inspired by [Reverse Parallel](https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel)
+Extract the logs bloom from pre-parsed header fields.
-Same as [`Bytes.reverseBytes32`](#Bytes-reverseBytes32-bytes32-) but optimized for 128-bit values.
+Extract the difficulty from the block header RLP. This is constant to 0 since EIP-3675 (Paris)
-Same as [`Bytes.reverseBytes32`](#Bytes-reverseBytes32-bytes32-) but optimized for 64-bit values.
+Extract the difficulty from pre-parsed header fields.
-Same as [`Bytes.reverseBytes32`](#Bytes-reverseBytes32-bytes32-) but optimized for 32-bit values.
+Extract the block number from the block header RLP.
-Same as [`Bytes.reverseBytes32`](#Bytes-reverseBytes32-bytes32-) but optimized for 16-bit values.
+Extract the block number from pre-parsed header fields.
-Counts the number of leading zero bits a bytes array. Returns `8 * buffer.length`
-if the buffer is all zeros.
+Extract the gas used from the block header RLP.
-```solidity
-import "@openzeppelin/contracts/utils/CAIP10.sol";
-```
+Extract the gas limit from the block header RLP.
-Helper library to format and parse CAIP-10 identifiers
+
+
-[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) defines account identifiers as:
-account_id: chain_id + ":" + account_address
-chain_id: [-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32} (See [`CAIP2`](#CAIP2))
-account_address: [-.%a-zA-Z0-9]{1,128}
+
-
-According to [CAIP-10's canonicalization section](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md#canonicalization),
-the implementation remains at the developer's discretion. Please note that case variations may introduce ambiguity.
-For example, when building hashes to identify accounts or data associated to them, multiple representations of the
-same account would derive to different hashes. For EVM chains, we recommend using checksummed addresses for the
-"account_address" part. They can be generated onchain using [`Strings.toChecksumHexString`](#Strings-toChecksumHexString-address-).
-
+
-Return the CAIP-10 identifier for a given caip2 chain and account.
-
-
-This function does not verify that the inputs are properly formatted.
-
+Extract the timestamp from pre-parsed header fields.
-Parse a CAIP-10 identifier into its components.
-
-
-This function does not verify that the CAIP-10 input is properly formatted. The `caip2` return can be
-parsed using the [`CAIP2`](#CAIP2) library.
-
+Extract the extra data from the block header RLP.
-
-In some cases, multiple CAIP-2 identifiers may all be valid representation of a single chain.
-For EVM chains, it is recommended to use `eip155:xxx` as the canonical representation (where `xxx` is
-the EIP-155 chain id). Consider the possible ambiguity when processing CAIP-2 identifiers or when using them
-in the context of hashes.
-
+Extract the prevRandao (a.k.a. mixHash before Paris) from the block header RLP.
-
-Return the CAIP-2 identifier for a given namespace and reference.
-
-
-This function does not verify that the inputs are properly formatted.
-
+Extract the nonce from the block header RLP. This is constant to 0 since EIP-3675 (Paris)
-Parse a CAIP-2 identifier into its components.
-
-
-This function does not verify that the CAIP-2 input is properly formatted.
-
+Extract the nonce from pre-parsed header fields.
-
-
-
+Extract the parent beacon block root from the block header RLP. This was introduced in Cancun.
+
-```solidity
-import "@openzeppelin/contracts/utils/Context.sol";
-```
+
-Provides information about the current execution context, including the
-sender of the transaction and its data. While these are generally available
-via msg.sender and msg.data, they should not be accessed in such a direct
-manner, since when dealing with meta-transactions the account sending and
-paying for execution may not be the actual sender (as far as an application
-is concerned).
+
+
+Thrown when the provided block header RLP does not have the expected number of fields.
+Happens if it corresponds to an older version of the EVM that doesn't include the field.
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/Blockhash.sol";
+```
+
+Library for accessing historical block hashes beyond the standard 256 block limit.
+Uses EIP-2935's history storage contract which maintains a ring buffer of the last
+8191 block hashes in state.
+
+For blocks within the last 256 blocks, it uses the native `BLOCKHASH` opcode.
+For blocks between 257 and 8191 blocks ago, it queries the EIP-2935 history storage.
+For blocks older than 8191 or future blocks, it returns zero, matching the `BLOCKHASH` behavior.
+
+
+After EIP-2935 activation, it takes 8191 blocks to completely fill the history.
+Before that, only block hashes since the fork block will be available.
+
+
+
+
+Retrieves the block hash for any historical block within the supported range.
+
+
+The function gracefully handles future blocks and blocks beyond the history window
+by returning zero, consistent with the EVM's native `BLOCKHASH` behavior.
+
+
+
+
+Forward search for `s` in `buffer`
+* If `s` is present in the buffer, returns the index of the first instance
+* If `s` is not present in the buffer, returns type(uint256).max
+
+
+replicates the behavior of [Javascript's `Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
+
+
+
+
+Forward search for `s` in `buffer` starting at position `pos`
+* If `s` is present in the buffer (at or after `pos`), returns the index of the next instance
+* If `s` is not present in the buffer (at or after `pos`), returns type(uint256).max
+
+
+replicates the behavior of [Javascript's `Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
+
+
+
+
+Backward search for `s` in `buffer`
+* If `s` is present in the buffer, returns the index of the last instance
+* If `s` is not present in the buffer, returns type(uint256).max
+
+
+replicates the behavior of [Javascript's `Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
+
+
+
+
+Backward search for `s` in `buffer` starting at position `pos`
+* If `s` is present in the buffer (at or before `pos`), returns the index of the previous instance
+* If `s` is not present in the buffer (at or before `pos`), returns type(uint256).max
+
+
+replicates the behavior of [Javascript's `Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
+
+
+
+
+Copies the content of `buffer`, from `start` (included) to the end of `buffer` into a new bytes object in
+memory.
+
+
+replicates the behavior of [Javascript's `Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
+
+
+
+
+Copies the content of `buffer`, from `start` (included) to `end` (excluded) into a new bytes object in
+memory. The `end` argument is truncated to the length of the `buffer`.
+
+
+replicates the behavior of [Javascript's `Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
+
+
+
+
+Moves the content of `buffer`, from `start` (included) to the end of `buffer` to the start of that buffer,
+and shrinks the buffer length accordingly, effectively overriding the content of buffer with buffer[start:].
+
+
+This function modifies the provided buffer in place. If you need to preserve the original buffer, use [`Arrays.slice`](#Arrays-slice-uint256---uint256-uint256-) instead
+
+
+
+
+Moves the content of `buffer`, from `start` (included) to `end` (excluded) to the start of that buffer,
+and shrinks the buffer length accordingly, effectively overriding the content of buffer with buffer[start:end].
+The `end` argument is truncated to the length of the `buffer`.
+
+
+This function modifies the provided buffer in place. If you need to preserve the original buffer, use [`Arrays.slice`](#Arrays-slice-uint256---uint256-uint256-) instead
+
+
+
+
+Replaces bytes in `buffer` starting at `pos` with all bytes from `replacement`.
+
+Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, buffer.length]`).
+If `pos >= buffer.length`, no replacement occurs and the buffer is returned unchanged.
+
+
+This function modifies the provided buffer in place.
+
+
+
+
+Replaces bytes in `buffer` starting at `pos` with bytes from `replacement` starting at `offset`.
+Copies at most `length` bytes from `replacement` to `buffer`.
+
+Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, buffer.length]`, `offset` is
+clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,
+buffer.length - pos))`. If `pos >= buffer.length` or `offset >= replacement.length`, no replacement occurs
+and the buffer is returned unchanged.
+
+
+This function modifies the provided buffer in place.
+
+
+
+
+Concatenate an array of bytes into a single bytes object.
+
+For fixed bytes types, we recommend using the solidity built-in `bytes.concat` or (equivalent)
+`abi.encodePacked`.
+
+
+this could be done in assembly with a single loop that expands starting at the FMP, but that would be
+significantly less readable. It might be worth benchmarking the savings of the full-assembly approach.
+
+
+
+
+Reverses the byte order of a bytes32 value, converting between little-endian and big-endian.
+Inspired by [Reverse Parallel](https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel)
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/CAIP10.sol";
+```
+
+Helper library to format and parse CAIP-10 identifiers
+
+[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) defines account identifiers as:
+account_id: chain_id + ":" + account_address
+chain_id: [-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32} (See [`CAIP2`](#CAIP2))
+account_address: [-.%a-zA-Z0-9]{1,128}
+
+
+According to [CAIP-10's canonicalization section](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md#canonicalization),
+the implementation remains at the developer's discretion. Please note that case variations may introduce ambiguity.
+For example, when building hashes to identify accounts or data associated to them, multiple representations of the
+same account would derive to different hashes. For EVM chains, we recommend using checksummed addresses for the
+"account_address" part. They can be generated onchain using [`Strings.toChecksumHexString`](#Strings-toChecksumHexString-address-).
+
+
+
+
+Parse a CAIP-10 identifier into its components.
+
+
+This function does not verify that the CAIP-10 input is properly formatted. The `caip2` return can be
+parsed using the [`CAIP2`](#CAIP2) library.
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/CAIP2.sol";
+```
+
+Helper library to format and parse CAIP-2 identifiers
+
+[CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) defines chain identifiers as:
+chain_id: namespace + ":" + reference
+namespace: [-a-z0-9]{3,8}
+reference: [-_a-zA-Z0-9]{1,32}
+
+
+In some cases, multiple CAIP-2 identifiers may all be valid representation of a single chain.
+For EVM chains, it is recommended to use `eip155:xxx` as the canonical representation (where `xxx` is
+the EIP-155 chain id). Consider the possible ambiguity when processing CAIP-2 identifiers or when using them
+in the context of hashes.
+
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/Comparators.sol";
+```
+
+Provides a set of functions to compare values.
+
+_Available since v5.1._
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/Context.sol";
+```
+
+Provides information about the current execution context, including the
+sender of the transaction and its data. While these are generally available
+via msg.sender and msg.data, they should not be accessed in such a direct
+manner, since when dealing with meta-transactions the account sending and
+paying for execution may not be the actual sender (as far as an application
+is concerned).
+
+This contract is only required for intermediate, library-like contracts.
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/Create2.sol";
+```
+
+Helper to make usage of the `CREATE2` EVM opcode easier and safer.
`CREATE2` can be used to compute in advance the address where a smart
contract will be deployed, which allows for interesting new mechanisms known
as 'counterfactual interactions'.
-See the [EIP](https://eips.ethereum.org/EIPS/eip-1014#motivation) for more
-information.
+See the [EIP](https://eips.ethereum.org/EIPS/eip-1014#motivation) for more
+information.
+
+
+
+Deploys a contract using `CREATE2`. The address where the contract
+will be deployed can be known in advance via [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-).
+
+The bytecode for a contract can be obtained from Solidity with
+`type(contractName).creationCode`.
+
+Requirements:
+
+- `bytecode` must not be empty.
+- `salt` must have not been used for `bytecode` already.
+- the factory must have a balance of at least `amount`.
+- if `amount` is non-zero, `bytecode` must have a `payable` constructor.
+
+
+
+Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-). Any change in the
+`bytecodeHash` or `salt` will result in a new destination address.
+
+
+
+Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-) from a contract located at
+`deployer`. If `deployer` is this contract's address, returns the same value as [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-).
+
+
+
+```solidity
+import "@openzeppelin/contracts/utils/Create3.sol";
+```
+
+Helper to deploy contracts using the `CREATE3` approach.
+`CREATE3` combines both `CREATE2` and `CREATE` opcodes to deploy arbitrary bytecode at an address that only depends
+on the provided salt and the address of the contract using this library. At a high level, it behaves like a `CREATE2`
+operation that would not use the bytecodehash to generate the contract address.
+
+CREATE3 can be used to compute in advance the address where a smart contract will be deployed, even if the bytecode
+is subject to change.
+
+
+To get the same deployment address on multiple chains, the deployer contract must live at the same address on
+each chain.
+
+
+See [`Create2`](#Create2) for counterfactual deployments that include the bytecodehash in the computation of the address.
+
+
+
+Deploys a contract using the `CREATE3` mechanism. The address where the contract
+will be deployed can be known in advance via [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-), and only depends on the salt.
+The bytecode that is deployed DOES NOT affect the location at which it is deployed.
+
+The bytecode for a contract can be obtained from Solidity with
+`type(contractName).creationCode`.
+
+Requirements:
+
+- `bytecode` must not be empty.
+- `salt` must not have been used already.
+- the factory must have a balance of at least `amount`.
+- if `amount` is non-zero, `bytecode` must have a `payable` constructor.
+
+
+
+Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-). Any change in the
+`salt` will result in a new destination address.
+
+
+
+Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-) from a contract located at
+`deployer`. If `deployer` is this contract's address, returns the same value as [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-).
+
+
-Deploys a contract using `CREATE2`. The address where the contract
-will be deployed can be known in advance via [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-).
+Block number clock mode. Checks that the current `clock` was not modified.
-The bytecode for a contract can be obtained from Solidity with
-`type(contractName).creationCode`.
+
+
-Requirements:
+
-- `bytecode` must not be empty.
-- `salt` must have not been used for `bytecode` already.
-- the factory must have a balance of at least `amount`.
-- if `amount` is non-zero, `bytecode` must have a `payable` constructor.
+
-Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-). Any change in the
-`bytecodeHash` or `salt` will result in a new destination address.
+Variant of `timestampClockMode-uint48-` that checks against the clock function.
-Returns the address where a contract will be stored if deployed via [`Create2.deploy`](#Create2-deploy-uint256-bytes32-bytes-) from a contract located at
-`deployer`. If `deployer` is this contract's address, returns the same value as [`Create2.computeAddress`](#Create2-computeAddress-bytes32-bytes32-address-).
+Timestamp clock mode. Checks that the current `clock` was not modified.
-There's no code to deploy.
+The clock was incorrectly modified.
@@ -2650,7 +3858,7 @@ There's no code to deploy.
## `Errors`
-
+
@@ -2753,7 +3961,7 @@ A necessary precompile is missing.
## `LowLevelCall`
-
+
@@ -3014,7 +4222,7 @@ Revert with the return data from the last call.
## `Memory`
-
+
@@ -3276,7 +4484,7 @@ Returns true if the memory occupied by the slice is reserved (i.e. before the fr
## `Multicall`
-
+
@@ -3329,7 +4537,7 @@ Receives and executes a batch of function calls on this contract.
## `Nonces`
-
+
@@ -3433,7 +4641,7 @@ The nonce used for an `account` is not the expected current nonce.
## `NoncesKeyed`
-
+
@@ -3513,7 +4721,7 @@ Returns the next unused nonce for an address and key. Result contains the key pr
Consumes the next unused nonce for an address and key.
-Returns the current value without the key prefix. Consumed nonce is increased, so calling this function twice
+Returns the current value with the key prefix (i.e. the packed keyNonce). Consumed nonce is increased, so calling this function twice
with the same arguments will return different (sequential) results.
@@ -3565,7 +4773,7 @@ This version takes the key and the nonce as two different parameters.
## `Packing`
-
+
@@ -6489,7 +7697,202 @@ _Available since v5.1._
replace_28_10(bytes28 self, bytes10 value, uint8 offset) → bytes28 result
+
+```solidity
+import "@openzeppelin/contracts/utils/Panic.sol";
+```
+
+Helper library for emitting standardized panic codes.
+
+```solidity
+contract Example {
+ using Panic for uint256;
+
+ // Use any of the declared internal constants
+ function foo() { Panic.GENERIC.panic(); }
+
+ // Alternatively
+ function foo() { Panic.panic(Panic.GENERIC); }
+}
+```
+
+Follows the list from [libsolutil](https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h).
+
+_Available since v5.1._
+
+
+
Functions
+
+- [panic(code)](#Panic-panic-uint256-)
+
+
+
+
-
extract_32_12(bytes32 self, uint8 offset) → bytes12 result
+
+```solidity
+import "@openzeppelin/contracts/utils/Pausable.sol";
+```
+
+Contract module which allows children to implement an emergency stop
+mechanism that can be triggered by an authorized account.
+
+This module is used through inheritance. It will make available the
+modifiers `whenNotPaused` and `whenPaused`, which can be applied to
+the functions of your contract. Note that they will not be pausable by
+simply including this module, only once the modifiers are put in place.
+
+
```solidity
-import "@openzeppelin/contracts/utils/Panic.sol";
-```
-
-Helper library for emitting standardized panic codes.
-
-```solidity
-contract Example {
- using Panic for uint256;
-
- // Use any of the declared internal constants
- function foo() { Panic.GENERIC.panic(); }
-
- // Alternatively
- function foo() { Panic.panic(Panic.GENERIC); }
-}
+import "@openzeppelin/contracts/utils/RLP.sol";
```
-Follows the list from [libsolutil](https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h).
-
-_Available since v5.1._
-
-
-
-Reverts with a panic code. Recommended to use with
-the internal constants with predefined codes.
+Library for encoding and decoding data in RLP format.
+Recursive Length Prefix (RLP) is the main encoding method used to serialize objects in Ethereum.
+It's used for encoding everything from transactions to blocks to Patricia-Merkle tries.
-
-
+Inspired by
-
+* https://github.com/succinctlabs/optimism-bedrock-contracts/blob/main/rlp/RLPWriter.sol
+* https://github.com/succinctlabs/optimism-bedrock-contracts/blob/main/rlp/RLPReader.sol
-
+## Canonical vs Non-Canonical Encodings
-## `Pausable`
+According to the Ethereum Yellow Paper, a "canonical" RLP encoding is the unique, minimal
+representation of a value. For scalar values (integers), this means:
-
-
-
+* No leading zero bytes (e.g., `0x0123` should be encoded as 2 bytes, not `0x000123` as 3 bytes)
+* Single bytes less than 0x80 must be encoded directly without a prefix wrapper
+* Zero is represented as an empty byte array (prefix `0x80`)
-
+A "non-canonical" encoding represents the same value but doesn't follow these minimality rules.
+For example, encoding the integer 1234 (0x04d2) with a leading zero as `0x830004d2` instead
+of the canonical `0x8204d2`.
-```solidity
-import "@openzeppelin/contracts/utils/Pausable.sol";
-```
+
+This implementation takes a permissive approach to decoding, accepting some non-canonical
+encodings (e.g., scalar values with leading zero bytes) that would be rejected by
+strict implementations like go-ethereum. This design choice prioritizes compatibility
+with diverse RLP encoders in the ecosystem over strict adherence to the Yellow Paper
+specification's canonicalization requirements.
-Contract module which allows children to implement an emergency stop
-mechanism that can be triggered by an authorized account.
+Users should be aware that:
-This module is used through inheritance. It will make available the
-modifiers `whenNotPaused` and `whenPaused`, which can be applied to
-the functions of your contract. Note that they will not be pausable by
-simply including this module, only once the modifiers are put in place.
+* Multiple different RLP encodings may decode to the same value (non-injective)
+* Encoding followed by decoding is guaranteed to work correctly
+* External RLP data from untrusted sources may have non-canonical encodings
+* Improperly wrapped single bytes (< 0x80) are still rejected as invalid
+
-Modifier to make a function callable only when the contract is not paused.
-
-Requirements:
-
-- The contract must not be paused.
+Add a boolean to a given RLP Encoder.
-Modifier to make a function callable only when the contract is paused.
-
-Requirements:
-
-- The contract must be paused.
+Add an address to a given RLP Encoder.
-Emitted when the pause is triggered by `account`.
+Add an (input) Encoder to a (target) Encoder. The input is RLP encoded as a list of bytes, and added to the target Encoder.
-Emitted when the pause is lifted by `account`.
+Encode a boolean as RLP.
+
+Boolean `true` is encoded as 0x01, `false` as 0x80 (equivalent to encoding integers 1 and 0).
+This follows the de facto ecosystem standard where booleans are treated as 0/1 integers.
-The operation failed because the contract is paused.
+Encode an address as an RLP item of fixed size (20 bytes).
+
+The address is encoded with its leading zeros (if it has any). If someone wants to encode the address as a scalar,
+they can cast it to a uint256 and then call the corresponding [`Base58.encode`](#Base58-encode-bytes-) function.
-The operation failed because the contract is not paused.
+Encode a uint256 as an RLP scalar.
+
+Unlike `encode-bytes32-`, this function uses scalar encoding that removes the prefix zeros.
-## `RLP`
+Encode a bytes32 as an RLP item of fixed size (32 bytes).
-
-
-
+Unlike `encode-uint256-`, this function uses array encoding that preserves the prefix zeros.
+
-```solidity
-import "@openzeppelin/contracts/utils/RLP.sol";
-```
+
-Library for encoding and decoding data in RLP format.
-Recursive Length Prefix (RLP) is the main encoding method used to serialize objects in Ethereum.
-It's used for encoding everything from transactions to blocks to Patricia-Merkle tries.
+
-Inspired by
+Encode a bytes buffer as RLP.
-* https://github.com/succinctlabs/optimism-bedrock-contracts/blob/main/rlp/RLPWriter.sol
-* https://github.com/succinctlabs/optimism-bedrock-contracts/blob/main/rlp/RLPReader.sol
+
+
-## Canonical vs Non-Canonical Encodings
+
-According to the Ethereum Yellow Paper, a "canonical" RLP encoding is the unique, minimal
-representation of a value. For scalar values (integers), this means:
+
-* No leading zero bytes (e.g., `0x0123` should be encoded as 2 bytes, not `0x000123` as 3 bytes)
-* Single bytes less than 0x80 must be encoded directly without a prefix wrapper
-* Zero is represented as an empty byte array (prefix `0x80`)
+Encode a string as RLP. Type alias for `encode-bytes-`.
-A "non-canonical" encoding represents the same value but doesn't follow these minimality rules.
-For example, encoding the integer 1234 (0x04d2) with a leading zero as `0x830004d2` instead
-of the canonical `0x8204d2`.
+
+
-
-This implementation takes a permissive approach to decoding, accepting some non-canonical
-encodings (e.g., scalar values with leading zero bytes) that would be rejected by
-strict implementations like go-ethereum. This design choice prioritizes compatibility
-with diverse RLP encoders in the ecosystem over strict adherence to the Yellow Paper
-specification's canonicalization requirements.
+
-Users should be aware that:
+
-* Multiple different RLP encodings may decode to the same value (non-injective)
-* Encoding followed by decoding is guaranteed to work correctly
-* External RLP data from untrusted sources may have non-canonical encodings
-* Improperly wrapped single bytes (< 0x80) are still rejected as invalid
-
+Encode an array of bytes as RLP.
+This function expects an array of already encoded bytes, not raw bytes.
+Users should call [`Base58.encode`](#Base58-encode-bytes-) on each element of the array before calling it.
-
-Create an empty RLP Encoder.
+Decode an RLP encoded bool. See `encode-bool`
+
+
+This function treats any non-zero value as `true`, which is more permissive
+than some implementations (e.g., go-ethereum only accepts `0x00` for false and `0x01`
+for true). For example, `0x02`, `0x03`, etc. will all decode as `true`.
+
-Add a boolean to a given RLP Encoder.
+Decode an RLP encoded address. See `encode-address`
+
+
+This function accepts both single-byte encodings (for values 0-127, including
+precompile addresses like 0x01) and the standard 21-byte encoding with the `0x94` prefix.
+For example, `0x01` decodes to `0x0000000000000000000000000000000000000001`.
+
+Additionally, like [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-), this function accepts non-canonical encodings with
+leading zeros. For instance, both `0x01` and `0x940000000000000000000000000000000000000001`
+decode to the same address.
+
-Add an address to a given RLP Encoder.
+Decode an RLP encoded uint256. See `encode-uint256`
+
+
+This function accepts non-canonical encodings with leading zero bytes for multi-byte values,
+which differs from the Ethereum Yellow Paper specification and some reference
+implementations like go-ethereum. For example, both `0x88ab54a98ceb1f0ad2` and
+`0x8900ab54a98ceb1f0ad2` will decode to the same uint256 value (12345678901234567890).
+
+However, single bytes less than 0x80 must NOT be wrapped with a prefix. For example,
+`0x8100` is invalid (should be `0x00`), but `0x820000` is valid (two zero bytes).
+
+This permissive behavior is intentional for compatibility with various RLP encoders
+in the ecosystem, but users should be aware that multiple RLP encodings may map
+to the same decoded value (non-injective decoding).
+
-Add a uint256 to a given RLP Encoder.
+Decode an RLP encoded bytes32. See `encode-bytes32`
+
+
+Since this function delegates to [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-), it inherits the non-canonical
+encoding acceptance behavior for multi-byte values. Multiple RLP encodings with different
+leading zero bytes may decode to the same bytes32 value, but single bytes < 0x80 must
+not be wrapped with a prefix (e.g., `0x820000` is valid, but `0x8100` is not).
+
-Add a string to a given RLP Encoder.
+Decodes an RLP encoded list in a memory slice into an array of RLP Items.
+
+
+The returned array contains slice references into the original payload, not copied bytes. Any further
+modification of the input buffer may cause the output result to become invalid.
+
-Add an (input) Encoder to a (target) Encoder. The input is RLP encoded as a list of bytes, and added to the target Encoder.
+Decode an RLP encoded address from bytes. See [`RLP.readAddress`](#RLP-readAddress-Memory-Slice-)
-Encode a boolean as RLP.
+Decode an RLP encoded uint256 from bytes. See [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-)
-Boolean `true` is encoded as 0x01, `false` as 0x80 (equivalent to encoding integers 1 and 0).
-This follows the de facto ecosystem standard where booleans are treated as 0/1 integers.
+
-Encode an address as an RLP item of fixed size (20 bytes).
+Decode an RLP encoded bytes from bytes. See [`RLP.readBytes`](#RLP-readBytes-Memory-Slice-)
-The address is encoded with its leading zeros (if it has any). If someone wants to encode the address as a scalar,
-they can cast it to an uint256 and then call the corresponding [`Base58.encode`](#Base58-encode-bytes-) function.
+
-Encode an uint256 as an RLP scalar.
+Decode an RLP encoded list from bytes. See [`RLP.readList`](#RLP-readList-Memory-Slice-)
-Unlike `encode-bytes32-`, this function uses scalar encoding that removes the prefix zeros.
+
+The returned array contains slice references into the original payload, not copied bytes. Any further
+modification of the input buffer may cause the output result to become invalid.
+
-Encode a bytes32 as an RLP item of fixed size (32 bytes).
+The item is not properly formatted and cannot be decoded.
-Unlike `encode-uint256-`, this function uses array encoding that preserves the prefix zeros.
+
+
+```solidity
+import "@openzeppelin/contracts/utils/RateLimiter.sol";
+```
+
+This library provides primitives for limiting the rate at which an action can be performed.
+
+Two complementary strategies are available, each represented by a storage struct that the consumer keeps in its
+own storage:
+
+- [`RateLimiter.RefillingBucket`](#RateLimiter-RefillingBucket): a token bucket that refills linearly over time. The bucket starts full; each consumption
+ draws from it, and it is refilled over time. Suitable when the protected resource regenerates continuously and bursts
+ of size up to the bucket's capacity are allowed. Storage cost is constant regardless of consumption history.
+
+- [`RateLimiter.SlidingWindow`](#RateLimiter-SlidingWindow): a moving-window counter that caps the cumulative consumption over any `window`-second
+ interval. Suitable when a strict cap on usage within a rolling window is required. Each successful consumption
+ appends a checkpoint, making it a more expensive option with a larger storage footprint.
+
+### Limiter vs. entries
+
+Each storage struct is a _limiter_: it pairs a single, shared configuration (the `window`, together with the
+`capacity` of a [`RateLimiter.RefillingBucket`](#RateLimiter-RefillingBucket) or the `limit` of a [`RateLimiter.SlidingWindow`](#RateLimiter-SlidingWindow)) with a mapping of independent _entries_
+keyed by `bytes32`. Every operation takes a `key` and applies only to that entry.
+
+All entries in a limiter share the same configuration, but each entry tracks its own consumption independently:
+consuming from one `key` never affects the availability of another. This lets a single limiter enforce the same
+rate limit separately across many subjects--for example one entry per caller, per token, or per protected
+function--simply by choosing the `key` accordingly. Using a constant `key` (e.g. `bytes32(0)`) reduces the
+limiter to a single global rate limit.
+
+Configuration is changed for the whole limiter at once with [`RateLimiter.updateSettings`](#RateLimiter-updateSettings-struct-RateLimiter-SlidingWindow-uint48-uint208-), whereas [`RateLimiter.state`](#RateLimiter-state-struct-RateLimiter-SlidingWindow-bytes32-), [`RateLimiter.used`](#RateLimiter-used-struct-RateLimiter-SlidingWindow-bytes32-),
+[`RateLimiter.available`](#RateLimiter-available-struct-RateLimiter-SlidingWindow-bytes32-), [`RateLimiter.tryConsume`](#RateLimiter-tryConsume-struct-RateLimiter-SlidingWindow-bytes32-uint256-), [`RateLimiter.consume`](#RateLimiter-consume-struct-RateLimiter-SlidingWindow-bytes32-uint256-) and [`RateLimiter.reset`](#RateLimiter-reset-struct-RateLimiter-SlidingWindow-bytes32-) act on the individual entry identified by `key`.
+
+Example usage (one independent rate limit per caller, all sharing the same capacity and window):
+
+```solidity
+using RateLimiter for RateLimiter.RefillingBucket;
+
+RateLimiter.RefillingBucket private _rateLimiter;
+function withdraw(uint256 amount) external {
+ _rateLimiter.consume(bytes32(uint256(uint160(msg.sender))), amount);
+ // ...
+}
+```
+
+
-Encode a bytes buffer as RLP.
+The per-`key` state of a [`RefillingBucket`](#RateLimiter-RefillingBucket) entry.
+`lastUsed` and `lastTimepoint` record the used quantity and the time it was recorded at the entry's last
+update. The current state is reconstructed lazily from these two fields on read (see `state`), keeping storage
+cost constant at one packed slot per entry regardless of how many times the entry has been consumed.
+
+```solidity
+struct RefillingBucketItem {
+ uint208 lastUsed;
+ uint48 lastTimepoint;
+}
+```
-Encode a string as RLP. Type alias for `encode-bytes-`.
+A token-bucket limiter: shared configuration plus a mapping of independent per-`key` buckets.
+`capacity` and `window` are shared by every entry: each bucket has a maximum `capacity` and refills at a rate
+of `capacity / window` per second, so that an empty bucket fully refills in `window` seconds. `items` holds the
+individual buckets, each tracking its own consumption under its `key` (see [`RefillingBucketItem`](#RateLimiter-RefillingBucketItem)).
+
+```solidity
+struct RefillingBucket {
+ uint208 capacity;
+ uint48 window;
+ mapping(bytes32 => struct RateLimiter.RefillingBucketItem) items;
+}
+```
-Encode an array of bytes as RLP.
-This function expects an array of already encoded bytes, not raw bytes.
-Users should call [`Base58.encode`](#Base58-encode-bytes-) on each element of the array before calling it.
+A moving-window limiter: shared configuration plus a mapping of independent per-`key` counters.
+`limit` and `window` are shared by every entry, and cap the cumulative consumption of each entry within any
+`window`-second interval. `items` holds the individual counters: each entry keeps its own checkpoint history
+(a `Checkpoints.Trace208`) under its `key`, recording the running cumulative total. An entry's current `used`
+quantity is the difference between its cumulative total at `block.timestamp` and at `block.timestamp - window`.
+
+
+The cumulative total of each entry is stored as a `uint208`. Once it reaches `2²⁰⁸ - 1`, further
+consumption of that entry will revert in [`SafeCast`](/contracts/5.x/api/utils#SafeCast). This bound is unreachable for any realistic `limit`, but
+consumers should be aware of it.
+
+
+
+An entry's checkpoint history is not a reliable log of past consumptions--previous entries may be
+overwritten in place. The storage footprint of an entry grows with the number of
+[`tryConsume`](#RateLimiter-tryConsume-struct-RateLimiter-SlidingWindow-bytes32-uint256-) calls on that `key` that succeed with a non-zero
+`quantity`.
+
+
+```solidity
+struct SlidingWindow {
+ uint208 limit;
+ uint48 window;
+ mapping(bytes32 => struct Checkpoints.Trace208) items;
+}
+```
-Encode an encoder (list of bytes) as RLP
+Returns the current `used` and `available` quantities for the `key` bucket, accounting for the time-based
+refill that has accrued since that entry's last update.
+
+
+A `window` of 0 is treated as 1 second in the refill computation: the effective refill rate becomes
+`capacity` per second, and an uninitialized limiter (`capacity = window = 0`) reports as an empty bucket.
+
-Decode an RLP encoded bool. See `encode-bool`
-
-
-This function treats any non-zero value as `true`, which is more permissive
-than some implementations (e.g., go-ethereum only accepts `0x00` for false and `0x01`
-for true). For example, `0x02`, `0x03`, etc. will all decode as `true`.
-
+Returns the currently used quantity. See `state-struct-RateLimiter-RefillingBucket-bytes32`.
-Decode an RLP encoded address. See `encode-address`
-
-
-This function accepts both single-byte encodings (for values 0-127, including
-precompile addresses like 0x01) and the standard 21-byte encoding with the `0x94` prefix.
-For example, `0x01` decodes to `0x0000000000000000000000000000000000000001`.
-
-Additionally, like [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-), this function accepts non-canonical encodings with
-leading zeros. For instance, both `0x01` and `0x940000000000000000000000000000000000000001`
-decode to the same address.
-
+Returns the currently available quantity. See `state-struct-RateLimiter-RefillingBucket-bytes32`.
-Decode an RLP encoded uint256. See `encode-uint256`
-
-
-This function accepts non-canonical encodings with leading zero bytes for multi-byte values,
-which differs from the Ethereum Yellow Paper specification and some reference
-implementations like go-ethereum. For example, both `0x88ab54a98ceb1f0ad2` and
-`0x8900ab54a98ceb1f0ad2` will decode to the same uint256 value (12345678901234567890).
-
-However, single bytes less than 0x80 must NOT be wrapped with a prefix. For example,
-`0x8100` is invalid (should be `0x00`), but `0x820000` is valid (two zero bytes).
+Attempts to consume `quantity` from the `key` bucket. Returns `true` on success, `false` if that entry's
+available quantity is insufficient.
-This permissive behavior is intentional for compatibility with various RLP encoders
-in the ecosystem, but users should be aware that multiple RLP encodings may map
-to the same decoded value (non-injective decoding).
-
+A `quantity` of 0 is always accepted and does not modify storage.
-Decode an RLP encoded bytes32. See `encode-bytes32`
-
-
-Since this function delegates to [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-), it inherits the non-canonical
-encoding acceptance behavior for multi-byte values. Multiple RLP encodings with different
-leading zero bytes may decode to the same bytes32 value, but single bytes < 0x80 must
-not be wrapped with a prefix (e.g., `0x820000` is valid, but `0x8100` is not).
-
+Consumes `quantity` from the `key` bucket. Reverts with [`RateLimiter.RateLimitExceeded`](#RateLimiter-RateLimitExceeded--) if that entry's available
+quantity is insufficient. See `tryConsume-struct-RateLimiter-RefillingBucket-bytes32-uint256`.
-Decodes an RLP encoded string. See `encode-string`
+Updates the shared `capacity` and `window` of the limiter, affecting every entry.
+
+
+The new settings will retroactively affect all the keys. The new replenishing rate (capacity / window) is
+applied from the last update timepoint of each key. Therefore, if the new settings correspond to a faster
+replenishing rate, some quantity may become available immediately. Conversely, if the new settings correspond
+to a slower replenishing rate, some quantity that would otherwise be available immediately may become
+unavailable. This side effect can be mitigated by calling [`RateLimiter.sync`](#RateLimiter-sync-struct-RateLimiter-RefillingBucket-bytes32-) on the relevant keys before updating the
+settings. There is no mechanism to automatically sync all the keys in a single operation.
+
-Decodes an RLP encoded list in a memory slice into an array of RLP Items.
-
-
-The returned array contains slice references into the original payload, not copied bytes. Any further
-modification of the input buffer may cause the output result to become invalid.
-
+Refreshes the `key` bucket by applying the accrued refill since its last update timepoint to `lastUsed`
+and `lastTimepoint`, effectively moving that entry's timepoint forward to now. This can be used to mitigate the
+side effect of `updateSettings-struct-RateLimiter-RefillingBucket-uint48-uint208` when the replenishing rate is
+modified. It must be called per key; there is no mechanism to sync all entries at once.
-Decode an RLP encoded bool from bytes. See [`RLP.readBool`](#RLP-readBool-Memory-Slice-)
+Returns the current `used` and `available` quantities for the `key` counter, computed as that entry's
+cumulative consumption over the last `window` seconds.
+
+
+A `window` of 0 is treated as 1 second in the rolling-window lookup, and an uninitialized limiter
+(`limit = window = 0`) reports as a counter with no available quantity.
+
-Decode an RLP encoded address from bytes. See [`RLP.readAddress`](#RLP-readAddress-Memory-Slice-)
+Returns the quantity currently used by the `key` counter within the sliding window. See
+`state-struct-RateLimiter-SlidingWindow-bytes32`.
-Decode an RLP encoded uint256 from bytes. See [`RLP.readUint256`](#RLP-readUint256-Memory-Slice-)
+Returns the quantity currently available to the `key` counter within the rolling window. See
+`state-struct-RateLimiter-SlidingWindow-bytes32`.
-Decode an RLP encoded bytes32 from bytes. See [`RLP.readBytes32`](#RLP-readBytes32-Memory-Slice-)
+Attempts to record a consumption of `quantity` against the `key` counter. Returns `true` on success,
+`false` if that entry's available quantity within the current window is insufficient.
+
+A `quantity` of 0 is always accepted and does not modify storage.
-Decode an RLP encoded bytes from bytes. See [`RLP.readBytes`](#RLP-readBytes-Memory-Slice-)
+Records a consumption of `quantity` against the `key` counter. Reverts with [`RateLimiter.RateLimitExceeded`](#RateLimiter-RateLimitExceeded--) if that
+entry's available quantity within the current window is insufficient. See
+`tryConsume-struct-RateLimiter-SlidingWindow-bytes32-uint256`.
-Decode an RLP encoded string from bytes. See [`RLP.readString`](#RLP-readString-Memory-Slice-)
+Resets the `key` counter to a fully-available state. Other entries are unaffected.
+
+
+This will reset that entry's entire history, meaning it can also be used to recover from the cumulative
+total approaching the `uint208` ceiling. The underlying storage slots holding past checkpoints are not zeroed
+out. As a consequence, there is no gas refunded, but future
+`consume-struct-RateLimiter-SlidingWindow-bytes32-uint256` and
+`tryConsume-struct-RateLimiter-SlidingWindow-bytes32-uint256` operations are cheaper from reusing "dirty" slots.
+
-Decode an RLP encoded list from bytes. See [`RLP.readList`](#RLP-readList-Memory-Slice-)
+Updates the shared `limit` and `window` of the limiter, affecting every entry.
-The returned array contains slice references into the original payload, not copied bytes. Any further
-modification of the input buffer may cause the output result to become invalid.
+The history of past consumptions is not modified. Increasing `window` retroactively brings older
+consumptions back into the rolling window until they age out under the new duration; decreasing `window`
+conversely causes older consumptions to drop out sooner.
#
@@ -8448,7 +10168,7 @@ Relays a call to the target contract through a dynamically deployed relay contra
-Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-bytes32-) but with a value.
+Same as `relayCall-address-bytes` but with a value.
@@ -8457,7 +10177,7 @@ Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-b
#
@@ -8465,7 +10185,7 @@ Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-b
-Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-bytes32-) but with a salt.
+Same as `relayCall-address-bytes` but with a salt.
@@ -8474,7 +10194,7 @@ Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-b
#
@@ -8482,7 +10202,7 @@ Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-b
-Same as [`RelayedCall.relayCall`](#RelayedCall-relayCall-address-uint256-bytes-bytes32-) but with a salt and a value.
+Same as `relayCall-address-bytes` but with a salt and a value.
@@ -8527,7 +10247,7 @@ Returns the relayer address for a given salt.
## `ShortString`
-
+
@@ -8543,7 +10263,7 @@ import "@openzeppelin/contracts/utils/ShortStrings.sol";
## `ShortStrings`
-
+
@@ -8614,7 +10334,7 @@ contract Named {
Encode a string of at most 31 chars into a `ShortString`.
-This will trigger a `StringTooLong` error is the input string is too long.
+This will trigger a `StringTooLong` error if the input string is too long.
@@ -8740,13 +10460,102 @@ actual characters as the UTF-8 encoding of a single character can span over mult
+
+```solidity
+import "@openzeppelin/contracts/utils/SimulateCall.sol";
+```
+
+Library for simulating external calls and inspecting the result of the call while reverting any state changes
+of events the call may have produced.
+
+This pattern is useful when you need to simulate the result of a call without actually executing it on-chain. Since
+the address of the sender is preserved, this supports simulating calls that perform token swap that use the caller's
+balance, or any operation that is restricted to the caller.
+
+
+
+Returns the simulator address.
+
+The simulator REVERTs on success and RETURNs on failure, preserving the return data in both cases.
+
+* A failed target call returns the return data and succeeds in our context (no state changes).
+* A successful target call causes a revert in our context (undoing all state changes) while still
+capturing the return data.
+
+
+
+
## `SlotDerivation`
-
+
@@ -8985,7 +10794,7 @@ Derive the location of a mapping element from the key.
## `StorageSlot`
-
+
@@ -9197,7 +11006,7 @@ Returns an `BytesSlot` representation of the bytes storage pointer `store`.
## `Strings`
-
+
@@ -9808,7 +11617,7 @@ The string being parsed is not a properly formatted address.
## `TransientSlot`
-
+
@@ -10127,7 +11936,7 @@ Store `value` at location `slot` in transient storage.
## `InteroperableAddress`
-
+
@@ -10249,7 +12058,7 @@ Variant of `formatV1-bytes2-bytes-bytes-` that specifies an EVM address without
-Parse a ERC-7930 interoperable address (version 1) into its different components. Reverts if the input is
+Parse an ERC-7930 interoperable address (version 1) into its different components. Reverts if the input is
not following a version 1 of ERC-7930.
@@ -10324,7 +12133,7 @@ Variant of [`InteroperableAddress.tryParseV1`](#InteroperableAddress-tryParseV1-
-Parse a ERC-7930 interoperable address (version 1) corresponding to an EIP-155 chain. The `chainId` and
+Parse an ERC-7930 interoperable address (version 1) corresponding to an EIP-155 chain. The `chainId` and
`addr` return values will be zero if the input doesn't include a chainReference or an address, respectively.
@@ -10428,7 +12237,7 @@ Variant of [`InteroperableAddress.tryParseEvmV1`](#InteroperableAddress-tryParse
## `ERC165`
-
+
@@ -10484,7 +12293,7 @@ This function call must use less than 30 000 gas.
## `ERC165Checker`
-
+
@@ -10623,7 +12432,7 @@ Interface identification is specified in ERC-165.
## `IERC165`
-
+
@@ -10676,7 +12485,7 @@ This function call must use less than 30 000 gas.
## `Math`
-
+
@@ -11399,7 +13208,7 @@ Counts the number of leading zero bits in a uint256.
## `SafeCast`
-
+
@@ -13153,7 +14962,7 @@ A uint value doesn't fit in an int of `bits` size.
## `SignedMath`
-
+
@@ -13274,7 +15083,7 @@ Returns the absolute unsigned value of a signed value.
## `Accumulators`
-
+
@@ -13425,7 +15234,7 @@ Flatten all the bytes entries in an Accumulator into a single buffer
## `BitMaps`
-
+
@@ -13531,7 +15340,7 @@ Unsets the bit at `index`.
## `Checkpoints`
-
+
@@ -13557,7 +15366,8 @@ checkpoint for the current transaction block using the [`RLP.push`](#RLP-push-st
- [latest(self)](#Checkpoints-latest-struct-Checkpoints-Trace256-)
- [latestCheckpoint(self)](#Checkpoints-latestCheckpoint-struct-Checkpoints-Trace256-)
- [length(self)](#Checkpoints-length-struct-Checkpoints-Trace256-)
-- [at(self, pos)](#Checkpoints-at-struct-Checkpoints-Trace256-uint32-)
+- [at(self, index)](#Checkpoints-at-struct-Checkpoints-Trace256-uint32-)
+- [pos(self, index)](#Checkpoints-pos-struct-Checkpoints-Trace256-uint32-)
- [push(self, key, value)](#Checkpoints-push-struct-Checkpoints-Trace224-uint32-uint224-)
- [lowerLookup(self, key)](#Checkpoints-lowerLookup-struct-Checkpoints-Trace224-uint32-)
- [upperLookup(self, key)](#Checkpoints-upperLookup-struct-Checkpoints-Trace224-uint32-)
@@ -13565,7 +15375,8 @@ checkpoint for the current transaction block using the [`RLP.push`](#RLP-push-st
- [latest(self)](#Checkpoints-latest-struct-Checkpoints-Trace224-)
- [latestCheckpoint(self)](#Checkpoints-latestCheckpoint-struct-Checkpoints-Trace224-)
- [length(self)](#Checkpoints-length-struct-Checkpoints-Trace224-)
-- [at(self, pos)](#Checkpoints-at-struct-Checkpoints-Trace224-uint32-)
+- [at(self, index)](#Checkpoints-at-struct-Checkpoints-Trace224-uint32-)
+- [pos(self, index)](#Checkpoints-pos-struct-Checkpoints-Trace224-uint32-)
- [push(self, key, value)](#Checkpoints-push-struct-Checkpoints-Trace208-uint48-uint208-)
- [lowerLookup(self, key)](#Checkpoints-lowerLookup-struct-Checkpoints-Trace208-uint48-)
- [upperLookup(self, key)](#Checkpoints-upperLookup-struct-Checkpoints-Trace208-uint48-)
@@ -13573,7 +15384,8 @@ checkpoint for the current transaction block using the [`RLP.push`](#RLP-push-st
- [latest(self)](#Checkpoints-latest-struct-Checkpoints-Trace208-)
- [latestCheckpoint(self)](#Checkpoints-latestCheckpoint-struct-Checkpoints-Trace208-)
- [length(self)](#Checkpoints-length-struct-Checkpoints-Trace208-)
-- [at(self, pos)](#Checkpoints-at-struct-Checkpoints-Trace208-uint32-)
+- [at(self, index)](#Checkpoints-at-struct-Checkpoints-Trace208-uint32-)
+- [pos(self, index)](#Checkpoints-pos-struct-Checkpoints-Trace208-uint32-)
- [push(self, key, value)](#Checkpoints-push-struct-Checkpoints-Trace160-uint96-uint160-)
- [lowerLookup(self, key)](#Checkpoints-lowerLookup-struct-Checkpoints-Trace160-uint96-)
- [upperLookup(self, key)](#Checkpoints-upperLookup-struct-Checkpoints-Trace160-uint96-)
@@ -13581,7 +15393,8 @@ checkpoint for the current transaction block using the [`RLP.push`](#RLP-push-st
- [latest(self)](#Checkpoints-latest-struct-Checkpoints-Trace160-)
- [latestCheckpoint(self)](#Checkpoints-latestCheckpoint-struct-Checkpoints-Trace160-)
- [length(self)](#Checkpoints-length-struct-Checkpoints-Trace160-)
-- [at(self, pos)](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-)
+- [at(self, index)](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-)
+- [pos(self, index)](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-)
@@ -13731,7 +15544,7 @@ Returns the number of checkpoints.
#
@@ -13741,6 +15554,30 @@ Returns the number of checkpoints.
Returns checkpoint at given position.
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns checkpoint at given position.
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -13883,7 +15720,7 @@ Returns the number of checkpoints.
#
@@ -13893,6 +15730,30 @@ Returns the number of checkpoints.
Returns checkpoint at given position.
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns checkpoint at given position.
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -14026,25 +15887,49 @@ in the most recent checkpoint.
-Returns the number of checkpoints.
+Returns the number of checkpoints.
+
+
+
+Returns checkpoint at given position.
+
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
Returns checkpoint at given position.
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -14187,7 +16072,7 @@ Returns the number of checkpoints.
#
@@ -14197,6 +16082,30 @@ Returns the number of checkpoints.
Returns checkpoint at given position.
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns checkpoint at given position.
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -14223,7 +16132,7 @@ A value was attempted to be inserted on a past checkpoint.
## `CircularBuffer`
-
+
@@ -14451,7 +16360,7 @@ Error emitted when trying to setup a buffer with a size of 0.
## `DoubleEndedQueue`
-
+
@@ -14488,7 +16397,9 @@ DoubleEndedQueue.Bytes32Deque queue;
- [back(deque)](#DoubleEndedQueue-back-struct-DoubleEndedQueue-Bytes32Deque-)
- [tryBack(deque)](#DoubleEndedQueue-tryBack-struct-DoubleEndedQueue-Bytes32Deque-)
- [at(deque, index)](#DoubleEndedQueue-at-struct-DoubleEndedQueue-Bytes32Deque-uint256-)
+- [pos(deque, index)](#DoubleEndedQueue-pos-struct-DoubleEndedQueue-Bytes32Deque-uint256-)
- [tryAt(deque, index)](#DoubleEndedQueue-tryAt-struct-DoubleEndedQueue-Bytes32Deque-uint256-)
+- [values(deque, start, end)](#DoubleEndedQueue-values-struct-DoubleEndedQueue-Bytes32Deque-uint256-uint256-)
- [clear(deque)](#DoubleEndedQueue-clear-struct-DoubleEndedQueue-Bytes32Deque-)
- [length(deque)](#DoubleEndedQueue-length-struct-DoubleEndedQueue-Bytes32Deque-)
- [empty(deque)](#DoubleEndedQueue-empty-struct-DoubleEndedQueue-Bytes32Deque-)
@@ -14741,6 +16652,33 @@ Return the item at a position in the queue given by `index`, with the first item
Reverts with [`Panic.ARRAY_OUT_OF_BOUNDS`](#Panic-ARRAY_OUT_OF_BOUNDS-uint256) if the index is out of bounds.
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Return the item at a position in the queue given by `index`, with the first item at 0 and last item at
+`length(deque) - 1`.
+
+Reverts with [`Panic.ARRAY_OUT_OF_BOUNDS`](#Panic-ARRAY_OUT_OF_BOUNDS-uint256) if the index is out of bounds.
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -14764,6 +16702,32 @@ Returns `(false, 0x00)` if the index is out of bounds. Never reverts.
+
+Return a slice of the queue in an array, with the first item at `start` (inclusive) and the last item at
+`end` (exclusive). Out-of-bound values for `start` and `end` are clamped to the queue length.
+
+
+This operation will copy a portion of the storage to memory, which can be quite expensive. This is
+designed to mostly be used by view accessors that are queried without any gas fees. Developers should keep in
+mind that this function has an unbounded cost, and using it as part of a state-changing function may render the
+function uncallable if the queue grows to a point where copying to memory consumes too much gas to fit in a
+block.
+
+
+
+
+Returns the key-value pair stored at position `index` in the map. O(1).
+
+Note that there are no guarantees on the ordering of entries inside the
+array, and it may change when more entries are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -15328,6 +17334,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.UintToUintMap map, uint256 index) → uint256 key, uint256 value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -15535,6 +17571,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.UintToAddressMap map, uint256 index) → uint256 key, address value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -15742,6 +17808,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.UintToBytes32Map map, uint256 index) → uint256 key, bytes32 value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -15949,6 +18045,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.AddressToUintMap map, uint256 index) → address key, uint256 value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -16156,6 +18282,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.AddressToAddressMap map, uint256 index) → address key, address value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -16363,6 +18519,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.AddressToBytes32Map map, uint256 index) → address key, bytes32 value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -16550,14 +18736,42 @@ Returns the number of elements in the map. O(1).
-
+
+
+
+
+
at(struct EnumerableMap.Bytes32ToUintMap map, uint256 index) → bytes32 key, uint256 value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
-
at(struct EnumerableMap.Bytes32ToUintMap map, uint256 index) → bytes32 key, uint256 value
+
pos(struct EnumerableMap.Bytes32ToUintMap map, uint256 index) → bytes32 key, uint256 value
@@ -16570,6 +18784,8 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -16777,6 +18993,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.Bytes32ToAddressMap map, uint256 index) → bytes32 key, address value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -16984,6 +19230,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.Bytes4ToAddressMap map, uint256 index) → bytes4 key, address value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -17191,6 +19467,36 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+
+
+
+
+
+
pos(struct EnumerableMap.BytesToBytesMap map, uint256 index) → bytes key, bytes value
+
+Returns the element stored at position `index` in the map. O(1).
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -17541,6 +19853,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -17709,6 +20052,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -17877,6 +20251,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -18045,6 +20450,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -18213,6 +20649,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -18381,6 +20848,37 @@ Requirements:
- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Deprecated. This function's name clashes with a keyword scheduled for inclusion in Solidity. Developers
+should use [`Checkpoints.pos`](#Checkpoints-pos-struct-Checkpoints-Trace160-uint32-) instead.
+
+
+
+
+Returns the value stored at position `index` in the set. O(1).
+
+Note that there are no guarantees on the ordering of values inside the
+array, and it may change when more values are added or removed.
+
+Requirements:
+
+- `index` must be strictly less than [`Memory.length`](#Memory-length-Memory-Slice-).
+
+Replacement of the deprecated [`Checkpoints.at`](#Checkpoints-at-struct-Checkpoints-Trace160-uint32-) function.
+
@@ -18438,7 +20936,7 @@ uncallable if the set grows to a point where copying to memory consumes too much
## `Heap`
-
+
@@ -18683,7 +21181,7 @@ Removes all elements in the heap.
## `MerkleTree`
-
+
@@ -18734,6 +21232,52 @@ _Available since v5.1._
+
+A complete `bytes32` Merkle tree.
+The `sides` and `zero` arrays are set to have a length equal to the depth of the tree during setup.
+Struct members have an underscore prefix indicating that they are "private" and should not be read or written to
+directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and
+lead to unexpected behavior.
+
+
+The `root` and the updates history is not stored within the tree. Consider using a secondary structure to
+store a list of historical roots from the values returned from `setup` and `push` (e.g. a mapping, `BitMaps` or
+`Checkpoints`).
+
+
+
+Updating any of the tree's parameters after the first insertion will result in a corrupted tree.
+
+
+```solidity
+struct Bytes32PushTree {
+ uint256 _nextLeafIndex;
+ bytes32[] _sides;
+ bytes32[] _zeros;
+}
+```
+
+
+
+
@@ -18951,7 +21495,7 @@ Error emitted when the proof used during an update is invalid (could not reprodu
## `Time`
-
+
diff --git a/content/contracts/5.x/api/utils/cryptography.mdx b/content/contracts/5.x/api/utils/cryptography.mdx
index 0f496a59..a02d695b 100644
--- a/content/contracts/5.x/api/utils/cryptography.mdx
+++ b/content/contracts/5.x/api/utils/cryptography.mdx
@@ -61,6 +61,8 @@ A collection of contracts and libraries that implement various signature validat
[`SignerEIP7702`](#SignerEIP7702)
+[`SignerWebAuthn`](#SignerWebAuthn)
+
[`SignerERC7913`](#SignerERC7913)
[`MultiSignerERC7913`](#MultiSignerERC7913)
@@ -81,7 +83,7 @@ A collection of contracts and libraries that implement various signature validat
## `ECDSA`
-
+
@@ -404,7 +406,7 @@ The signature has an S value that is in the upper half order.
## `EIP712`
-
+
@@ -605,7 +607,7 @@ It only reads from storage if necessary (in case the value is too large to fit i
## `Hashes`
-
+
@@ -671,7 +673,7 @@ Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand me
## `MerkleProof`
-
+
@@ -1188,7 +1190,7 @@ The multiproof provided is not valid.
## `MessageHashUtils`
-
+
@@ -1426,7 +1428,7 @@ Builds an EIP-712 domain type hash depending on the `fields` provided, following
## `P256`
-
+
@@ -1556,7 +1558,7 @@ In particular this function checks that x < P and y < P.
## `RSA`
-
+
@@ -1643,7 +1645,7 @@ using a low exponent out of security concerns.
## `SignatureChecker`
-
+
@@ -1818,7 +1820,7 @@ change through time. It could return true at block N and false at block N+1 (or
## `TrieProof`
-
+
@@ -1835,7 +1837,7 @@ The [`TrieProof.traverse`](#TrieProof-traverse-bytes32-bytes-bytes---) and [`Mer
* Transaction against the transactionsRoot of a block.
* Event against receiptsRoot of a block.
* Account details (RLP encoding of [nonce, balance, storageRoot, codeHash]) against the stateRoot of a block.
-* Storage slot (RLP encoding of the value) against the storageRoot of a account.
+* Storage slot (RLP encoding of the value) against the storageRoot of an account.
Proving a storage slot is usually done in 3 steps:
@@ -1875,7 +1877,7 @@ Based on [this implementation from optimism](https://github.com/ethereum-optimis
-Verifies a `proof` against a given `key`, `value`, `and root` hash.
+Verifies a `proof` against a given `key`, `value`, and `root` hash.
@@ -2063,7 +2098,7 @@ cause revert/panic.
## `ERC7739Utils`
-
+
@@ -2250,7 +2285,7 @@ modes.
Following ERC-7739 specifications, a `contentsName` is considered invalid if it's empty or it contains
any of the following bytes , )\x00
-If the `contentsType` is invalid, this returns an empty string. Otherwise, the return string has non-zero
+If the `contentsDescr` is invalid, this returns empty strings. Otherwise, the return strings have non-zero
length.
@@ -2262,7 +2297,7 @@ length.
## `AbstractSigner`
-
+
@@ -2315,7 +2350,7 @@ xref:api:utils/cryptography#P256[P256] or xref:api:utils/cryptography#RSA[RSA]).
## `MultiSignerERC7913`
-
+
@@ -2823,7 +2858,7 @@ The `threshold` is unreachable given the number of `signers`.
## `MultiSignerERC7913Weighted`
-
+
@@ -3163,7 +3198,7 @@ Thrown when the arrays lengths don't match. See [`MultiSignerERC7913Weighted._se
## `SignerECDSA`
-
+
@@ -3283,7 +3318,7 @@ xref:api:utils/cryptography#P256[P256] or xref:api:utils/cryptography#RSA[RSA]).
## `SignerEIP7702`
-
+
@@ -3327,7 +3362,7 @@ Validates the signature using the EOA's address (i.e. `address(this)`).
## `SignerERC7913`
-
+
@@ -3447,7 +3482,7 @@ with [`SignerECDSA.signer`](#SignerECDSA-signer--), `hash` and `signature`.
## `SignerP256`
-
+
@@ -3589,7 +3624,7 @@ xref:api:utils/cryptography#P256[P256] or xref:api:utils/cryptography#RSA[RSA]).
## `SignerRSA`
-
+
@@ -3709,7 +3744,7 @@ encoding as per section 9.2 (step 1) of the RFC.
## `SignerWebAuthn`
-
+
@@ -3793,7 +3828,7 @@ Returns `false` if the signature is not a valid WebAuthn authentication assertio
## `ERC7739`
-
+
@@ -3881,7 +3916,7 @@ A nested EIP-712 type might be presented in 2 different ways:
## `ERC7913P256Verifier`
-
+
@@ -3929,7 +3964,7 @@ SHOULD return 0xffffffff or revert if the key is empty
## `ERC7913RSAVerifier`
-
+
@@ -3977,7 +4012,7 @@ SHOULD return 0xffffffff or revert if the key is empty
## `ERC7913WebAuthnVerifier`
-
+
@@ -4006,6 +4041,7 @@ Wallets that may require default P256 validation may install a P256 verifier sep
+
diff --git a/content/contracts/5.x/eoa-delegation.mdx b/content/contracts/5.x/eoa-delegation.mdx
index 7a3a17bc..55dd8f64 100644
--- a/content/contracts/5.x/eoa-delegation.mdx
+++ b/content/contracts/5.x/eoa-delegation.mdx
@@ -8,7 +8,7 @@ title: "EOA Delegation"
* Sponsoring transactions for other users.
* Implementing privilege de-escalation (e.g., sub-keys with limited permissions)
-This section walks you through the process of delegating an EOA to a contract following [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). This allows you to use your EOA’s private key to sign and execute operations with custom execution logic. Combined with [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) infrastructure, users can achieve gas sponsoring through [paymasters](https://docs.openzeppelin.com/community-contracts/paymasters).
+This section walks you through the process of delegating an EOA to a contract following [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). This allows you to use your EOA’s private key to sign and execute operations with custom execution logic. Combined with [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) infrastructure, users can achieve gas sponsoring through [paymasters](/contracts/5.x/paymasters).
## Delegating execution
@@ -84,7 +84,7 @@ To remove the delegation and restore your EOA to its original state, you can sen
When changing an account’s delegation, ensure the newly delegated code is purposely designed and tested as an upgrade to the old one. To ensure safe migration between delegate contracts, use namespaced storage that avoids accidental collisions following ERC-7201.
-Updating the delegation designator may render your EOA unusable due to potential storage collisions. We recommend following similar practices to those of [writing upgradeable smart contracts](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable).
+Updating the delegation designator may render your EOA unusable due to potential storage collisions. We recommend following similar practices to those of [writing upgradeable smart contracts](/upgrades-plugins/writing-upgradeable).
## Using with ERC-4337
@@ -95,7 +95,7 @@ The ability to set code to execute logic on an EOA allows users to leverage ERC-
Once your EOA is delegated to an ERC-4337 compatible account, you can send user operations through the entry point contract. The user operation includes all the necessary fields for execution, including gas limits, fees, and the actual call data to execute. The entry point will validate the operation and execute it in the context of your delegated account.
-Similar to how [sending a UserOp](/contracts/5.x/accounts#bundle_a_useroperation) is achieved for factory accounts, here’s how you can construct a UserOp for an EOA who’s delegated to an [`Account`](/contracts/5.x/api/account#Account) contract.
+Similar to how [sending a UserOp](/contracts/5.x/accounts#bundle-a-useroperation) is achieved for factory accounts, here’s how you can construct a UserOp for an EOA who’s delegated to an [`Account`](/contracts/5.x/api/account#Account) contract.
```typescript
const userOp = {
diff --git a/content/contracts/5.x/erc1155.mdx b/content/contracts/5.x/erc1155.mdx
index 30e09e73..bbfc0045 100644
--- a/content/contracts/5.x/erc1155.mdx
+++ b/content/contracts/5.x/erc1155.mdx
@@ -2,7 +2,7 @@
title: "ERC-1155"
---
-ERC-1155 is a novel token standard that aims to take the best from previous standards to create a [**fungibility-agnostic**](/contracts/5.x/tokens#different-kinds-of-tokens) and **gas-efficient** [token contract](/contracts/5.x/tokens#but_first_coffee_a_primer_on_token_contracts).
+ERC-1155 is a novel token standard that aims to take the best from previous standards to create a [**fungibility-agnostic**](/contracts/5.x/tokens#different-kinds-of-tokens) and **gas-efficient** [token contract](/contracts/5.x/tokens#but-first-coffee-a-primer-on-token-contracts).
ERC-1155 draws ideas from all of [ERC-20](/contracts/5.x/erc20), [ERC-721](/contracts/5.x/erc721), and [ERC-777](https://eips.ethereum.org/EIPS/eip-777). If you’re unfamiliar with those standards, head to their guides before moving on.
@@ -108,6 +108,6 @@ This is a good thing! It means that the recipient contract has not registered it
In order for our contract to receive ERC-1155 tokens we can inherit from the convenience contract [`ERC1155Holder`](/contracts/5.x/api/token/ERC1155#ERC1155Holder) which handles the registering for us. However, we need to remember to implement functionality to allow tokens to be transferred out of our contract:
-./examples/token/ERC1155/MyERC115HolderContract.sol
+./examples/token/ERC1155/MyERC1155HolderContract.sol
We can also implement more complex scenarios using the [`onERC1155Received`](/contracts/5.x/api/token/ERC1155#IERC1155Receiver-onERC1155Received-address-address-uint256-uint256-bytes-) and [`onERC1155BatchReceived`](/contracts/5.x/api/token/ERC1155#IERC1155Receiver-onERC1155BatchReceived-address-address-uint256---uint256---bytes-) functions.
diff --git a/content/contracts/5.x/erc4626.mdx b/content/contracts/5.x/erc4626.mdx
index d2c76fc0..fab67e57 100644
--- a/content/contracts/5.x/erc4626.mdx
+++ b/content/contracts/5.x/erc4626.mdx
@@ -57,11 +57,11 @@ In math that gives:
* $a_1$ the attacker donation
* $u$ the user deposit
-| |
+| | Assets | Shares | Rate |
| --- | --- | --- | --- |
-| Assets | Shares | Rate | initial |
-| $0$ | $0$ | - | after attacker’s deposit |
-| $a_0$ | $a_0$ | $1$ | after attacker’s donation |
+| initial | $0$ | $0$ | - |
+| after attacker’s deposit | $a_0$ | $a_0$ | $1$ |
+| after attacker’s donation | $a_0+a_1$ | $a_0$ | $\frac{a_0}{a_0+a_1}$ |
This means a deposit of $u$ will give $\frac{u \times a_0}{a_0 + a_1}$ shares.
@@ -97,11 +97,11 @@ Following the previous math definitions, we have:
* $a_1$ the attacker donation
* $u$ the user deposit
-| |
+| | Assets | Shares | Rate |
| --- | --- | --- | --- |
-| Assets | Shares | Rate | initial |
-| $1$ | $10^\delta$ | $10^\delta$ | after attacker’s deposit |
-| $1+a_0$ | $10^\delta \times (1+a_0)$ | $10^\delta$ | after attacker’s donation |
+| initial | $1$ | $10^\delta$ | $10^\delta$ |
+| after attacker’s deposit | $1+a_0$ | $10^\delta \times (1+a_0)$ | $10^\delta$ |
+| after attacker’s donation | $1+a_0+a_1$ | $10^\delta \times (1+a_0)$ | $10^\delta \times \frac{1+a_0}{1+a_0+a_1}$ |
One important thing to note is that the attacker only owns a fraction $\frac{a_0}{1 + a_0}$ of the shares, so when doing the donation, he will only be able to recover that fraction $\frac{a_1 \times a_0}{1 + a_0}$ of the donation. The remaining $\frac{a_1}{1+a_0}$ are captured by the vault.
diff --git a/content/contracts/5.x/extending-contracts.mdx b/content/contracts/5.x/extending-contracts.mdx
index 65cb8f66..7a4cabcf 100644
--- a/content/contracts/5.x/extending-contracts.mdx
+++ b/content/contracts/5.x/extending-contracts.mdx
@@ -1,5 +1,5 @@
---
-title: Extending Contracts
+title: "Extending Contracts"
---
Most of the OpenZeppelin Contracts are expected to be used via [inheritance](https://solidity.readthedocs.io/en/latest/contracts.html#inheritance): you will _inherit_ from them when writing your own contracts.
@@ -63,6 +63,19 @@ The `super.revokeRole` statement at the end will invoke ``AccessControl`’s ori
The same rule is implemented and extended in [`AccessControlDefaultAdminRules`](/contracts/5.x/api/access#AccessControlDefaultAdminRules), an extension that also adds enforced security measures for the `DEFAULT_ADMIN_ROLE`.
+### Token Compatibility Assumptions
+
+Most token standards are written without considering non-standard transfer mechanisms like fees, rebases, or hooks that mutate balances outside of explicit transfers. This is a well-understood community convention: the standards specify a behavior, and integrations across the ecosystem rely on it. Contracts in this library follow the same convention. In particular, they assume that:
+
+* A successful [`transfer`](/contracts/5.x/api/token/ERC20#IERC20-transfer-address-uint256-) or [`transferFrom`](/contracts/5.x/api/token/ERC20#IERC20-transferFrom-address-address-uint256-) of `amount` reduces the sender’s [`balanceOf`](/contracts/5.x/api/token/ERC20#IERC20-balanceOf-address-) and increases the recipient’s [`balanceOf`](/contracts/5.x/api/token/ERC20#IERC20-balanceOf-address-) by exactly `amount`.
+* An account’s [`balanceOf`](/contracts/5.x/api/token/ERC20#IERC20-balanceOf-address-) only changes through explicit transfers, mints, or burns.
+
+Considering many ERCs are not compatible with these mechanisms, the library has taken a policy of not accounting for tokens that break these assumptions, such as fee-on-transfer and rebasing variants, since they could desynchronize a contract’s internal accounting from its on-chain balance. The resulting undercollateralization may cause later withdrawals, redemptions, or releases to revert.
+
+
+When a contract custodies tokens and may accumulate excess balance (positive rebasing, accidental transfers, airdrops), consider exposing an access-controlled recovery function similar to [`ERC20Wrapper._recover`](/contracts/5.x/api/token/ERC20#ERC20Wrapper-_recover-address-) to retrieve the surplus. This only helps when the contract holds more than it owes, not the undercollateralization case above.
+
+
## Security
The maintainers of OpenZeppelin Contracts are mainly concerned with the correctness and security of the code as published in the library, and the combinations of base contracts with the official extensions from the library.
diff --git a/content/contracts/5.x/governance.mdx b/content/contracts/5.x/governance.mdx
index e45ccfa3..7207f05f 100644
--- a/content/contracts/5.x/governance.mdx
+++ b/content/contracts/5.x/governance.mdx
@@ -36,7 +36,7 @@ When using a timelock with your Governor contract, you can use either OpenZeppel
[Tally](https://www.tally.xyz) is a full-fledged application for user owned on-chain governance. It comprises a voting dashboard, proposal creation wizard, real time research and analysis, and educational content.
-For all of these options, the Governor will be compatible with Tally: users will be able to create proposals, see voting periods and delays following [IERC6372](/contracts/5.x/api/interfaces#IERC6372), visualize voting power and advocates, navigate proposals, and cast votes. For proposal creation in particular, projects can also use [Defender Transaction Proposals](https://docs.openzeppelin.com/defender/module/actions#transaction-proposals-reference) as an alternative interface.
+For all of these options, the Governor will be compatible with Tally: users will be able to create proposals, see voting periods and delays following [IERC6372](/contracts/5.x/api/interfaces#IERC6372), visualize voting power and advocates, navigate proposals, and cast votes. For proposal creation in particular, projects can also use [Defender Transaction Proposals](/defender/module/transaction-proposals) as an alternative interface.
In the rest of this guide, we will focus on a fresh deploy of the vanilla OpenZeppelin Governor features without concern for compatibility with GovernorAlpha or Bravo.
@@ -111,17 +111,17 @@ A proposal is a sequence of actions that the Governor contract will perform if i
Let’s say we want to create a proposal to give a team a grant, in the form of ERC-20 tokens from the governance treasury. This proposal will consist of a single action where the target is the ERC-20 token, calldata is the encoded function call `transfer(, )`, and with 0 ETH attached.
-Generally a proposal will be created with the help of an interface such as Tally or [Defender Proposals](https://docs.openzeppelin.com/defender/module/actions#transaction-proposals-reference). Here we will show how to create the proposal using Ethers.js.
+Generally a proposal will be created with the help of an interface such as Tally or [Defender Proposals](/defender/module/transaction-proposals). Here we will show how to create the proposal using Ethers.js.
First we get all the parameters necessary for the proposal action.
```javascript
const tokenAddress = ...;
-const token = await ethers.getContractAt(‘ERC20’, tokenAddress);
+const token = await ethers.getContractAt("ERC20", tokenAddress);
const teamAddress = ...;
const grantAmount = ...;
-const transferCalldata = token.interface.encodeFunctionData(‘transfer’, [teamAddress, grantAmount]);
+const transferCalldata = token.interface.encodeFunctionData("transfer", [teamAddress, grantAmount]);
```
Now we are ready to call the propose function of the Governor. Note that we don’t pass in one array of actions, but instead three arrays corresponding to the list of targets, the list of values, and the list of calldatas. In this case it’s a single action, so it’s simple:
@@ -131,7 +131,7 @@ await governor.propose(
[tokenAddress],
[0],
[transferCalldata],
- “Proposal #1: Give grant to team”,
+ "Proposal #1: Give grant to team",
);
```
@@ -158,7 +158,7 @@ If a timelock was set up, the first step to execution is queueing. You will noti
To queue, we call the queue function:
```javascript
-const descriptionHash = ethers.utils.id(“Proposal #1: Give grant to team”);
+const descriptionHash = ethers.id("Proposal #1: Give grant to team");
await governor.queue(
[tokenAddress],
diff --git a/content/contracts/5.x/index.mdx b/content/contracts/5.x/index.mdx
index 9da54697..026d8f3e 100644
--- a/content/contracts/5.x/index.mdx
+++ b/content/contracts/5.x/index.mdx
@@ -52,7 +52,7 @@ Foundry installs the latest version initially, but subsequent `forge update` com
$ forge install OpenZeppelin/openzeppelin-contracts
```
-Add `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/` in `remappings.txt.`
+Add `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/` in `remappings.txt`.
### Usage
diff --git a/content/contracts/5.x/multisig.mdx b/content/contracts/5.x/multisig.mdx
index ef0a2be1..c9f10674 100644
--- a/content/contracts/5.x/multisig.mdx
+++ b/content/contracts/5.x/multisig.mdx
@@ -8,7 +8,7 @@ Popular implementations like [Safe](https://safe.global/) (formerly Gnosis Safe)
## Beyond Standard Signature Verification
-As discussed in the [accounts section](/contracts/5.x/accounts#signature_validation), the standard approach for smart contracts to verify signatures is [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271), which defines an `isValidSignature(hash, signature)`. However, it is limited in two important ways:
+As discussed in the [accounts section](/contracts/5.x/accounts#signature-validation), the standard approach for smart contracts to verify signatures is [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271), which defines an `isValidSignature(hash, signature)`. However, it is limited in two important ways:
1. It assumes the signer has an EVM address
2. It treats the signer as a single identity
diff --git a/content/contracts/5.x/paymasters.mdx b/content/contracts/5.x/paymasters.mdx
new file mode 100644
index 00000000..2435e7a2
--- /dev/null
+++ b/content/contracts/5.x/paymasters.mdx
@@ -0,0 +1,496 @@
+---
+title: "Paymasters"
+---
+
+In case you want to sponsor user operations for your users, ERC-4337 defines a special type of contract called _paymaster_, whose purpose is to pay the gas fees consumed by the user operation.
+
+In the context of account abstraction, sponsoring user operations allows a third party to pay for transaction gas fees on behalf of users. This can improve user experience by eliminating the need for users to hold native cryptocurrency (like ETH) to pay for transactions.
+
+To enable sponsorship, users sign their user operations including a special field called `paymasterAndData`, resulting from the concatenation of the paymaster address they’re intending to use and the associated calldata that’s going to be passed into [`validatePaymasterUserOp`](/contracts/5.x/api/utils/cryptography#Paymaster-validatePaymasterUserOp). The EntryPoint will use this field to determine whether it is willing to pay for the user operation or not.
+
+## Signed Sponsorship
+
+The [`PaymasterSigner`](/contracts/5.x/api/account#PaymasterSigner) implements signature-based sponsorship via authorization signatures, allowing designated paymaster signers to authorize and sponsor specific user operations without requiring users to hold native ETH.
+
+
+Learn more about [signers](/contracts/5.x/accounts#selecting-a-signer) to explore different approaches to user operation sponsorship via signatures.
+
+
+./examples/account/paymaster/PaymasterECDSASigner.sol
+
+
+[`ERC4337Utils`](/contracts/5.x/api/account#ERC4337Utils) to facilitate the access to paymaster-related fields of the userOp (e.g. `paymasterData`, `paymasterVerificationGasLimit`)
+
+
+To implement signature-based sponsorship, you’ll first need to deploy the paymaster contract. This contract will hold the ETH used to pay for user operations and verify signatures from your authorized signer. After deployment, you must fund the paymaster with ETH to cover gas costs for the operations it will sponsor:
+
+```typescript
+// Fund the paymaster with ETH
+await eoaClient.sendTransaction({
+ to: paymasterECDSASigner.address,
+ value: parseEther("0.01"),
+ data: encodeFunctionData({
+ abi: paymasterECDSASigner.abi,
+ functionName: "deposit",
+ args: [],
+ }),
+});
+```
+
+
+Paymasters require sufficient ETH balance to pay for gas costs. If the paymaster runs out of funds, all operations it’s meant to sponsor will fail. Consider implementing monitoring and automatic refilling of the paymaster’s balance in production environments.
+
+
+When a user initiates an operation that requires sponsorship, your backend service (or other authorized entity) needs to sign the operation using EIP-712. This signature proves to the paymaster that it should cover the gas costs for this specific user operation:
+
+```typescript
+// Set validation window
+const now = Math.floor(Date.now() / 1000);
+const validAfter = now - 60; // Valid from 1 minute ago
+const validUntil = now + 3600; // Valid for 1 hour
+const paymasterVerificationGasLimit = 100_000n;
+const paymasterPostOpGasLimit = 300_000n;
+
+// Sign using EIP-712 typed data
+const paymasterSignature = await signer.signTypedData({
+ domain: {
+ chainId: await signerClient.getChainId(),
+ name: "MyPaymasterECDSASigner",
+ verifyingContract: paymasterECDSASigner.address,
+ version: "1",
+ },
+ types: {
+ UserOperationRequest: [
+ { name: "sender", type: "address" },
+ { name: "nonce", type: "uint256" },
+ { name: "initCode", type: "bytes" },
+ { name: "callData", type: "bytes" },
+ { name: "accountGasLimits", type: "bytes32" },
+ { name: "preVerificationGas", type: "uint256" },
+ { name: "gasFees", type: "bytes32" },
+ { name: "paymasterVerificationGasLimit", type: "uint256" },
+ { name: "paymasterPostOpGasLimit", type: "uint256" },
+ { name: "validAfter", type: "uint48" },
+ { name: "validUntil", type: "uint48" },
+ ],
+ },
+ primaryType: "UserOperationRequest",
+ message: {
+ sender: userOp.sender,
+ nonce: userOp.nonce,
+ initCode: userOp.initCode,
+ callData: userOp.callData,
+ accountGasLimits: userOp.accountGasLimits,
+ preVerificationGas: userOp.preVerificationGas,
+ gasFees: userOp.gasFees,
+ paymasterVerificationGasLimit,
+ paymasterPostOpGasLimit,
+ validAfter,
+ validUntil,
+ },
+});
+```
+
+The time window (`validAfter` and `validUntil`) allows you to limit how long the signature remains valid. Once signed, the paymaster data needs to be formatted and attached to the user operation:
+
+```typescript
+userOp.paymasterAndData = encodePacked(
+ ["address", "uint128", "uint128", "bytes"],
+ [
+ paymasterECDSASigner.address,
+ paymasterVerificationGasLimit,
+ paymasterPostOpGasLimit,
+ encodePacked(
+ ["uint48", "uint48", "bytes"],
+ [validAfter, validUntil, paymasterSignature]
+ ),
+ ]
+);
+```
+
+
+The `paymasterVerificationGasLimit` and `paymasterPostOpGasLimit` values should be adjusted based on your paymaster’s complexity. Higher values increase the gas cost but provide more execution headroom, reducing the risk of out-of-gas errors during validation or post-operation processing.
+
+
+With the paymaster data attached, the user operation can now be signed by the account signer and submitted to the EntryPoint contract:
+
+```typescript
+// Sign the user operation with the account owner
+const signedUserOp = await signUserOp(entrypoint, userOp);
+
+// Submit to the EntryPoint contract
+const userOpReceipt = await eoaClient.writeContract({
+ abi: EntrypointV09Abi,
+ address: entrypoint.address,
+ functionName: "handleOps",
+ args: [[signedUserOp], beneficiary.address],
+});
+```
+
+Behind the scenes, the EntryPoint will call the paymaster’s `validatePaymasterUserOp` function, which verifies the signature and time window. If valid, the paymaster commits to paying for the operation’s gas costs, and the EntryPoint executes the operation.
+
+## ERC20-based Sponsorship
+
+While signature-based sponsorship is useful for many applications, sometimes you want users to pay for their own transactions but using tokens instead of ETH. The [`PaymasterERC20`](/contracts/5.x/api/account#PaymasterERC20) allows users to pay for gas fees using ERC-20 tokens. Developers must implement an [`_fetchDetails`](/contracts/5.x/api/account#PaymasterERC20-_fetchDetails-struct-PackedUserOperation-bytes32-) to get the token price information from an oracle of their preference.
+
+```solidity
+function _fetchDetails(
+ PackedUserOperation calldata userOp,
+ bytes32 userOpHash
+) internal view override returns (uint256 validationData, IERC20 token, uint256 tokenPerNative) {
+ // Implement logic to fetch the token and token price from the userOp
+}
+```
+
+### Using Oracles
+
+#### Chainlink Price Feeds
+
+A popular approach to implement price oracles is to use [Chainlink’s price feeds](https://docs.chain.link/data-feeds/using-data-feeds). By using their [`AggregatorV3Interface`](https://docs.chain.link/data-feeds/api-reference#aggregatorv3interface) developers determine the token-to-ETH exchange rate dynamically for their paymasters. This ensures fair pricing even as market rates fluctuate.
+
+Consider the following contract:
+
+```solidity
+// WARNING: Unaudited code.
+// Consider performing a security review before going to production.
+contract PaymasterUSDCChainlink is PaymasterERC20, Ownable {
+ // Values for sepolia
+ // See https://docs.chain.link/data-feeds/price-feeds/addresses
+ AggregatorV3Interface public constant USDC_USD_ORACLE =
+ AggregatorV3Interface(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E);
+ AggregatorV3Interface public constant ETH_USD_ORACLE =
+ AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
+
+ // See https://sepolia.etherscan.io/token/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
+ IERC20 private constant USDC =
+ IERC20(0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238);
+
+ constructor(address initialOwner) Ownable(initialOwner) {}
+
+ function _authorizeWithdraw() internal virtual override onlyOwner {}
+
+ function liveness() public view virtual returns (uint256) {
+ return 15 minutes; // Tolerate stale data
+ }
+
+ /// @dev Floor: refuse to sponsor when 1 ETH is worth less than 100 USDC.
+ /// 1e8 = 100 (USDC per ETH) * 10**6 (USDC decimals); the 1e18 denom cancels 1e18 wei/ETH.
+ function _minTokensPerNative() internal view virtual override returns (uint256) {
+ return 1e8;
+ }
+
+ function _fetchDetails(
+ PackedUserOperation calldata userOp,
+ bytes32 /* userOpHash */
+ ) internal view virtual override returns (uint256 validationData, IERC20 token, uint256 tokenPerNative) {
+ (uint256 validationData_, uint256 price) = _fetchOracleDetails(userOp);
+ return (
+ validationData_,
+ USDC,
+ price
+ );
+ }
+
+ function _fetchOracleDetails(
+ PackedUserOperation calldata /* userOp */
+ )
+ internal
+ view
+ virtual
+ returns (uint256 validationData, uint256 tokenPerNative)
+ {
+ // ...
+ }
+}
+```
+
+
+The `PaymasterUSDCChainlink` contract uses specific Chainlink price feeds (ETH/USD and USDC/USD) on Sepolia. For production use or other networks, you’ll need to modify the contract to use the appropriate price feed addresses.
+
+
+
+[`_minTokensPerNative`](/contracts/5.x/api/account#PaymasterERC20-_minTokensPerNative--) defaults to `0` in `PaymasterERC20` and should be overridden. It is a lower bound on `tokenPerNative` (same units: token-units per native coin, scaled by [`_tokenPerNativeDenominator`](/contracts/5.x/api/account#PaymasterERC20-_tokenPerNativeDenominator--)); any operation whose `_fetchDetails` returns a `tokenPerNative` strictly below this floor is rejected with `SIG_VALIDATION_FAILED` before pre-charging the user. The example above returns `1e8`, which refuses to sponsor when 1 ETH is worth less than 100 USDC — a conservative sanity check against misconfigured oracles or extreme market conditions. Returning `0` disables the check and re-opens the "free sponsorship" footgun if `_fetchDetails` ever returns a near-zero price.
+
+
+As you can see, a `_fetchOracleDetails` function is specified to fetch the token price that will be used as a reference for calculating the final ERC-20 payment. One can fetch and process price data from Chainlink oracles to determine the exchange rate between ETH and a concrete ERC-20. An example with USDC would be:
+
+1. Fetch the current `ETH/USD` and `USDC/USD` prices from their respective oracles.
+2. `tokenPerNative` is the number of USDC units (smallest denomination) charged per native token. Combining the two feeds: `tokenPerNative = (ETH_USD / USDC_USD) * 10**USDC_decimals`. Note that the oracles may come with their own denominator that has to be considered.
+
+
+On mainnet `tokenPerNative` is expressed per ETH and not per wei. On most EVM chains, this native token includes 10¹⁸ units (wei). This can be customized by overriding [`_tokenPerNativeDenominator`](/contracts/5.x/api/account#PaymasterERC20-_tokenPerNativeDenominator--).
+
+
+Here’s how an implementation of `_fetchOracleDetails` would look like using this approach:
+
+
+Use [`ERC4337Utils.combineValidationData`](/contracts/5.x/api/account#ERC4337Utils-combineValidationData-uint256-uint256-) to merge two `validationData` values.
+
+
+```solidity
+// WARNING: Unaudited code.
+// Consider performing a security review before going to production.
+
+using ERC4337Utils for *;
+
+function _fetchOracleDetails(
+ PackedUserOperation calldata /* userOp */
+)
+ internal
+ view
+ virtual
+ returns (uint256 validationData, uint256 tokenPerNative)
+{
+ (uint256 ETHUSDValidationData, uint256 ETHUSD) = _fetchPrice(ETH_USD_ORACLE);
+ (uint256 USDCUSDValidationData, uint256 USDCUSD) = _fetchPrice(USDC_USD_ORACLE);
+
+ // USDC_units / eth = (ETH/USD) / (USDC/USD) * 10 ** USDC_decimals
+ return (
+ ETHUSDValidationData.combineValidationData(USDCUSDValidationData),
+ ETHUSD
+ * (10 ** USDC.decimals())
+ * (10 ** USDC_USD_ORACLE.decimals())
+ / USDCUSD
+ / (10 ** ETH_USD_ORACLE.decimals())
+ );
+}
+
+function _fetchPrice(
+ AggregatorV3Interface oracle
+) internal view virtual returns (uint256 validationData, uint256 price) {
+ (
+ uint80 roundId,
+ int256 price_,
+ ,
+ uint256 timestamp,
+ uint80 answeredInRound
+ ) = oracle.latestRoundData();
+ if (
+ price_ <= 0 || // No data or negative price
+ answeredInRound < roundId || // Not answered in round
+ timestamp == 0 || // Incomplete round
+ block.timestamp - timestamp > liveness() // Stale data
+ ) {
+ return (ERC4337Utils.SIG_VALIDATION_FAILED, 0);
+ }
+ return (ERC4337Utils.SIG_VALIDATION_SUCCESS, uint256(price_));
+}
+```
+
+
+An important difference with token-based sponsorship is that the user’s smart account must first approve the paymaster to spend their tokens. You might want to incorporate this approval as part of your account initialization process, or check if approval is needed before executing an operation.
+
+
+The PaymasterERC20 contract follows a pre-charge and refund model:
+
+1. During validation, it pre-charges the maximum possible gas cost
+2. After execution, it refunds any unused gas back to the user
+
+This model ensures the paymaster can always cover gas costs, while only charging users for the actual gas used.
+
+```typescript
+const paymasterVerificationGasLimit = 150_000n;
+const paymasterPostOpGasLimit = 300_000n;
+
+userOp.paymasterAndData = encodePacked(
+ ["address", "uint128", "uint128", "bytes"],
+ [
+ paymasterUSDCChainlink.address,
+ paymasterVerificationGasLimit,
+ paymasterPostOpGasLimit,
+ "0x" // No additional data needed
+ ]
+);
+```
+
+For the rest, you can sign the user operation as you would normally do once the `paymasterAndData` field has been set.
+
+```typescript
+// Sign the user operation with the account owner
+const signedUserOp = await signUserOp(entrypoint, userOp);
+
+// Submit to the EntryPoint contract
+const userOpReceipt = await eoaClient.writeContract({
+ abi: EntrypointV09Abi,
+ address: entrypoint.address,
+ functionName: "handleOps",
+ args: [[signedUserOp], beneficiary.address],
+});
+```
+
+
+Oracle-based pricing relies on the accuracy and freshness of price feeds. The `PaymasterUSDCChainlink` includes safety checks for stale data, but you should still monitor for extreme market volatility that could affect your users.
+
+
+### Using a Guarantor
+
+There are multiple valid cases where the user might not have enough tokens to pay for the transaction before it takes place. For example, if the user is claiming an airdrop, they might need their first transaction to be sponsored. For those cases, the [`PaymasterERC20Guarantor`](/contracts/5.x/api/account#PaymasterERC20Guarantor) contract extends the standard PaymasterERC20 to allow a third party (guarantor) to back user operations.
+
+The guarantor pre-funds the maximum possible gas cost upfront, and after execution:
+
+1. If the user repays the guarantor, the guarantor gets their funds back
+2. If the user fails to repay, the guarantor absorbs the cost
+
+
+A common use case is for guarantors to pay for operations of users claiming airdrops:
+
+* The guarantor pays gas fees upfront
+* The user claims their airdrop tokens
+* The user repays the guarantor from the claimed tokens
+* If the user fails to repay, the guarantor absorbs the cost
+
+
+To implement guarantor functionality, your paymaster needs to extend the PaymasterERC20Guarantor class and implement the `_fetchGuarantor` function:
+
+```solidity
+function _fetchGuarantor(
+ PackedUserOperation calldata userOp
+) internal view override returns (address guarantor) {
+ // Implement logic to fetch and validate the guarantor from userOp
+}
+```
+
+Let’s create a guarantor-enabled paymaster by extending our previous example:
+
+```solidity
+// WARNING: Unaudited code.
+// Consider performing a security review before going to production.
+contract PaymasterUSDCGuaranteed is EIP712, PaymasterERC20Guarantor, Ownable {
+
+ // Keep the same oracle code as before...
+
+ bytes32 private constant GUARANTEED_USER_OPERATION_TYPEHASH =
+ keccak256(
+ "GuaranteedUserOperation(address sender,uint256 nonce,bytes initCode,bytes callData,bytes32 accountGasLimits,uint256 preVerificationGas,bytes32 gasFees,bytes paymasterData)"
+ );
+
+ constructor(
+ address initialOwner
+ ) EIP712("PaymasterUSDCGuaranteed", "1") Ownable(initialOwner) {}
+
+ // Other functions from PaymasterUSDCChainlink...
+
+ function _fetchGuarantor(
+ PackedUserOperation calldata userOp
+ ) internal view override returns (address guarantor) {
+ bytes calldata paymasterData = userOp.paymasterData();
+
+ // If no guarantor specified, return early
+ if (paymasterData.length < 20) {
+ return address(0);
+ }
+
+ guarantor = address(bytes20(paymasterData));
+ bytes calldata guarantorSignature = paymasterData[20:];
+
+ // Validate the guarantor's signature
+ bytes32 structHash = _getGuaranteedOperationStructHash(userOp);
+ bytes32 hash = _hashTypedDataV4(structHash);
+
+ return SignatureChecker.isValidSignatureNow(
+ guarantor,
+ hash,
+ guarantorSignature
+ ) ? guarantor : address(0);
+ }
+
+ function _getGuaranteedOperationStructHash(
+ PackedUserOperation calldata userOp
+ ) internal pure returns (bytes32) {
+ return keccak256(
+ abi.encode(
+ GUARANTEED_USER_OPERATION_TYPEHASH,
+ userOp.sender,
+ userOp.nonce,
+ keccak256(userOp.initCode),
+ keccak256(userOp.callData),
+ userOp.accountGasLimits,
+ userOp.preVerificationGas,
+ userOp.gasFees,
+ keccak256(bytes(userOp.paymasterData()[:20])) // Just the guarantor address part
+ )
+ );
+ }
+}
+```
+
+With this implementation, a guarantor would sign a user operation to authorize backing it:
+
+```typescript
+// Sign the user operation with the guarantor
+const guarantorSignature = await guarantor.signTypedData({
+ domain: {
+ chainId: await guarantorClient.getChainId(),
+ name: "PaymasterUSDCGuaranteed",
+ verifyingContract: paymasterUSDC.address,
+ version: "1",
+ },
+ types: {
+ GuaranteedUserOperation: [
+ { name: "sender", type: "address" },
+ { name: "nonce", type: "uint256" },
+ { name: "initCode", type: "bytes" },
+ { name: "callData", type: "bytes" },
+ { name: "accountGasLimits", type: "bytes32" },
+ { name: "preVerificationGas", type: "uint256" },
+ { name: "gasFees", type: "bytes32" },
+ { name: "paymasterData", type: "bytes" }
+ ]
+ },
+ primaryType: "GuaranteedUserOperation",
+ message: {
+ sender: userOp.sender,
+ nonce: userOp.nonce,
+ initCode: userOp.initCode,
+ callData: userOp.callData,
+ accountGasLimits: userOp.accountGasLimits,
+ preVerificationGas: userOp.preVerificationGas,
+ gasFees: userOp.gasFees,
+ paymasterData: guarantorAddress // Just the guarantor address
+ },
+});
+```
+
+Then, we include the guarantor’s address and its signature in the paymaster data:
+
+```typescript
+const paymasterVerificationGasLimit = 150_000n;
+const paymasterPostOpGasLimit = 300_000n;
+
+userOp.paymasterAndData = encodePacked(
+ ["address", "uint128", "uint128", "bytes"],
+ [
+ paymasterUSDC.address,
+ paymasterVerificationGasLimit,
+ paymasterPostOpGasLimit,
+ encodePacked(
+ ["address", "bytes"],
+ [guarantorAddress, guarantorSignature]
+ )
+ ]
+);
+```
+
+When the operation executes:
+
+1. During validation, the paymaster verifies the guarantor’s signature and pre-funds from the guarantor’s account
+2. The user operation executes, potentially giving the user tokens (like in an airdrop claim)
+3. During post-operation, the paymaster first tries to get repayment from the user
+4. If the user can’t pay, the guarantor’s pre-funded amount is used
+5. An event is emitted indicating who ultimately paid for the operation
+
+This approach enables novel use cases where users don’t need tokens to start using a web3 app, and can cover costs after receiving value through their transaction.
+
+## Practical Considerations
+
+When implementing paymasters in production environments, keep these considerations in mind:
+
+1. ***Balance management***: Regularly monitor and replenish your paymaster’s ETH balance to ensure uninterrupted service.
+2. ***Gas limits***: The verification and post-operation gas limits should be set carefully. Too low, and operations might fail; too high, and you waste resources.
+3. ***Security***: For signature-based paymasters, protect your signing key as it controls who gets subsidized operations.
+4. ***Price volatility***: For token-based paymasters, consider restricting which tokens are accepted, and implementing circuit breakers for extreme market conditions.
+5. ***Spending limits***: Consider implementing daily or per-user limits to prevent abuse of your paymaster.
+
+
+For production deployments, it’s often useful to implement a monitoring service that tracks paymaster usage, balances, and other metrics to ensure smooth operation.
+
diff --git a/content/contracts/5.x/upgradeable.mdx b/content/contracts/5.x/upgradeable.mdx
index 6b7376a8..8ec0d8ea 100644
--- a/content/contracts/5.x/upgradeable.mdx
+++ b/content/contracts/5.x/upgradeable.mdx
@@ -35,7 +35,7 @@ Interfaces and libraries are not included in the Upgradeable package, but are in
Constructors are replaced by internal initializer functions following the naming convention `__ContractName_init`. Since these are internal, you must always define your own public initializer function and call the parent initializer of the contract you extend.
```diff
-- constructor() ERC721("MyCollectible", "MCO") public {
+- constructor() ERC721("MyCollectible", "MCO") {
+ function initialize() initializer public {
+ __ERC721_init("MyCollectible", "MCO");
}
diff --git a/content/contracts/5.x/utilities.mdx b/content/contracts/5.x/utilities.mdx
index 9f601399..5bb6a0ca 100644
--- a/content/contracts/5.x/utilities.mdx
+++ b/content/contracts/5.x/utilities.mdx
@@ -230,10 +230,10 @@ contract MyContract {
using SignedMath for int256;
function tryOperations(uint256 a, uint256 b) internal pure {
- (bool succeededAdd, uint256 resultAdd) = x.tryAdd(y);
- (bool succeededSub, uint256 resultSub) = x.trySub(y);
- (bool succeededMul, uint256 resultMul) = x.tryMul(y);
- (bool succeededDiv, uint256 resultDiv) = x.tryDiv(y);
+ (bool succeededAdd, uint256 resultAdd) = a.tryAdd(b);
+ (bool succeededSub, uint256 resultSub) = a.trySub(b);
+ (bool succeededMul, uint256 resultMul) = a.tryMul(b);
+ (bool succeededDiv, uint256 resultDiv) = a.tryDiv(b);
// ...
}
@@ -409,7 +409,7 @@ Users can leverage this standard using the [`SlotDerivation`](/contracts/5.x/api
```solidity
using SlotDerivation for bytes32;
-string private constant _NAMESPACE = "" // eg. example.main
+string private constant _NAMESPACE = ""; // e.g. example.main
function erc7201Pointer() internal view returns (bytes32) {
return _NAMESPACE.erc7201Slot();
diff --git a/docgen/templates-md/contract.hbs b/docgen/templates-md/contract.hbs
index 1e5112b8..f7d921b9 100644
--- a/docgen/templates-md/contract.hbs
+++ b/docgen/templates-md/contract.hbs
@@ -106,6 +106,47 @@ import "@openzeppelin/{{__item_context.file.absolutePath}}";
+
+{{/each}}
+
{{#each modifiers}}
diff --git a/docgen/templates-md/helpers.js b/docgen/templates-md/helpers.js
index 1c679f5f..20208465 100644
--- a/docgen/templates-md/helpers.js
+++ b/docgen/templates-md/helpers.js
@@ -72,6 +72,24 @@ module.exports['typed-params'] = params => {
return params?.map(p => `${p.type}${p.indexed ? ' indexed' : ''}${p.name ? ' ' + p.name : ''}`).join(', ');
};
+// Extract the @dev tag body from a raw StructuredDocumentation node.
+// Solidity strips the leading ` *` per line but keeps a single leading space,
+// so we normalise: trim leading whitespace per line, then take everything
+// after `@dev ` up to the next `@tag` (or end-of-string).
+module.exports['struct-dev'] = function (struct) {
+ const raw = struct?.documentation?.text;
+ if (!raw) return '';
+ const dedented = raw.replace(/^[ \t]+/gm, '');
+ const match = dedented.match(/@dev\s+([\s\S]*?)(?=\n@\w+|$)/);
+ return match ? match[1].trim() : dedented.trim();
+};
+
+// Render a struct member as `` (Solidity declaration form).
+module.exports['struct-member-decl'] = function (member) {
+ const type = member?.typeDescriptions?.typeString || '';
+ return `${type} ${member.name}`;
+};
+
const slug = (module.exports.slug = str => {
if (str === undefined) {
throw new Error('Missing argument');
diff --git a/docgen/templates-md/properties.js b/docgen/templates-md/properties.js
index f2453b63..d792fdfc 100644
--- a/docgen/templates-md/properties.js
+++ b/docgen/templates-md/properties.js
@@ -71,6 +71,11 @@ module.exports.functions = function ({ item }) {
];
};
+module.exports.structs = function ({ item }) {
+ if (!isNodeType('ContractDefinition', item)) return [];
+ return item.nodes.filter((n) => isNodeType('StructDefinition', n));
+};
+
module.exports.returns2 = function ({ item }) {
if (isNodeType('VariableDeclaration', item)) {
return [{ type: item.typeDescriptions.typeString }];
diff --git a/examples/AccessManagerEnumerable.sol b/examples/AccessManagerEnumerable.sol
index 78640b4c..e862e0e6 100644
--- a/examples/AccessManagerEnumerable.sol
+++ b/examples/AccessManagerEnumerable.sol
@@ -40,7 +40,7 @@ abstract contract AccessManagerEnumerable is AccessManager {
* for more information.
*/
function getRoleMember(uint64 roleId, uint256 index) public view virtual returns (address) {
- return _roleMembers[roleId].at(index);
+ return _roleMembers[roleId].pos(index);
}
/**
@@ -84,7 +84,7 @@ abstract contract AccessManagerEnumerable is AccessManager {
* for more information.
*/
function getRoleTargetFunction(uint64 roleId, address target, uint256 index) public view virtual returns (bytes4) {
- return _roleTargetFunctions[roleId][target].at(index);
+ return _roleTargetFunctions[roleId][target].pos(index);
}
/**
diff --git a/examples/account/paymaster/PaymasterECDSASigner.sol b/examples/account/paymaster/PaymasterECDSASigner.sol
index af244cf2..1ecffd75 100644
--- a/examples/account/paymaster/PaymasterECDSASigner.sol
+++ b/examples/account/paymaster/PaymasterECDSASigner.sol
@@ -1,14 +1,31 @@
// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
-import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";
-import {PaymasterSigner, EIP712} from "@openzeppelin/community-contracts/account/paymaster/PaymasterSigner.sol";
+import {PaymasterSigner, EIP712} from "@openzeppelin/contracts/account/paymaster/extensions/PaymasterSigner.sol";
contract PaymasterECDSASigner is PaymasterSigner, SignerECDSA, Ownable {
constructor(address signerAddr) EIP712("MyPaymasterECDSASigner", "1") Ownable(signerAddr) SignerECDSA(signerAddr) {}
- function _authorizeWithdraw() internal virtual override onlyOwner {}
+ function deposit() public payable virtual {
+ _deposit(msg.value);
+ }
+
+ function withdraw(address payable to, uint256 value) public virtual onlyOwner {
+ _withdraw(to, value);
+ }
+
+ function addStake(uint32 unstakeDelaySec) public payable virtual {
+ _addStake(msg.value, unstakeDelaySec);
+ }
+
+ function unlockStake() public virtual onlyOwner {
+ _unlockStake();
+ }
+
+ function withdrawStake(address payable to) public virtual onlyOwner {
+ _withdrawStake(to);
+ }
}
diff --git a/examples/token/ERC1155/MyERC1155HolderContract.sol b/examples/token/ERC1155/MyERC1155HolderContract.sol
new file mode 100644
index 00000000..c7550c40
--- /dev/null
+++ b/examples/token/ERC1155/MyERC1155HolderContract.sol
@@ -0,0 +1,7 @@
+// contracts/MyERC1155HolderContract.sol
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
+
+contract MyERC1155HolderContract is ERC1155Holder {}
diff --git a/scripts/convert-adoc.js b/scripts/convert-adoc.js
index 140c0ef2..b394679a 100755
--- a/scripts/convert-adoc.js
+++ b/scripts/convert-adoc.js
@@ -36,6 +36,21 @@ async function convertAdocFiles(directory, apiRoute = "contracts/5.x/api") {
"./examples/$1",
);
+ // Convert remaining markdown-style fenced blocks to AsciiDoc
+ // `[source,lang]\n----\n...\n----` form BEFORE downdoc runs.
+ // downdoc mangles the contents of triple-backtick blocks inside
+ // .adoc sources (strips `//` comment lines, de-indents nested
+ // braces, drops closing `}`), because it doesn't recognise them
+ // as verbatim. `----` blocks are treated as literal, so this
+ // preprocess step preserves indentation and comments exactly.
+ content = content.replace(
+ /```([a-zA-Z0-9_-]+)?\s*\n([\s\S]*?)\n```/g,
+ (_match, lang, body) => {
+ const source = lang ? `[source,${lang}]\n` : "";
+ return `${source}----\n${body}\n----`;
+ },
+ );
+
// Replace TIP: and NOTE: callouts with tags
content = content.replace(
/^(TIP|NOTE):\s*(.+)$/gm,
@@ -167,7 +182,7 @@ async function convertAdocFiles(directory, apiRoute = "contracts/5.x/api") {
// Fix HTML-style callouts
📌 NOTE
...
// Handle multi-line callouts by using a more permissive pattern
mdContent = mdContent.replace(
- /
[📌🔔ℹ️]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
([\s\S]*?)<\/dd><\/dl>/gu,
+ /
[📌🔔ℹ️💡]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
([\s\S]*?)<\/dd><\/dl>/gu,
"\n$2\n",
);
@@ -178,7 +193,7 @@ async function convertAdocFiles(directory, apiRoute = "contracts/5.x/api") {
// Handle cases where
might be missing or malformed
mdContent = mdContent.replace(
- /
[📌🔔ℹ️]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
([\s\S]*?)(?=\n\n|
|$)/gu,
+ /
[📌🔔ℹ️💡]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
([\s\S]*?)(?=\n\n|
|$)/gu,
"\n$2\n",
);
@@ -199,7 +214,7 @@ async function convertAdocFiles(directory, apiRoute = "contracts/5.x/api") {
// Clean up orphaned HTML tags from malformed callouts
// Handle orphaned
EMOJI TYPE
without closing tags
mdContent = mdContent.replace(
- /
[📌🔔ℹ️]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
\s*\n([\s\S]*?)(?=\n\n|
|$)/gu,
+ /
[📌🔔ℹ️💡]\s*(NOTE|TIP|INFO)<\/strong><\/dt>
\s*\n([\s\S]*?)(?=\n\n|
|$)/gu,
"\n$2\n",
);
diff --git a/skills/docgen-fixup/SKILL.md b/skills/docgen-fixup/SKILL.md
new file mode 100644
index 00000000..d4c5541f
--- /dev/null
+++ b/skills/docgen-fixup/SKILL.md
@@ -0,0 +1,118 @@
+---
+name: docgen-fixup
+description: Review an auto-generated OZ API docs PR (from any of the three `.github/workflows/generate-api-docs-*.yml` receivers — contracts, community-contracts, confidential-contracts) and fix the known regression patterns the docgen pipeline introduces on each run. Trigger when the user says "review PR ", "check the v5.x docs regen", "fix the regressions on the latest bot PR", or "run docgen-fixup". Scans the diff for cross-ref leaks, broken code blocks, dangling struct anchors, mangled admonitions, wrong URL rewrites, missing docs-side props, and other patterns cataloged in `references/patterns.md`, then applies direct MDX patches. Also flags NatSpec / `.adoc` mistakes that should be fixed upstream in the source contracts repo.
+allowed-tools: Read, Write, Edit, Glob, Grep, Bash
+inputs:
+ pr_number:
+ type: text
+ prompt: "Docs PR number to fix (e.g. 206)."
+ required: true
+ contracts_repo_path:
+ type: text
+ prompt: "Absolute path to the source contracts repo. Leave blank to auto-detect from the PR body's source-repo hint (matches a sibling `solidity/`, `openzeppelin-community-contracts/`, `community/`, or `openzeppelin-confidential-contracts/`)."
+ required: false
+ contracts_tag:
+ type: text
+ prompt: "Source tag / branch the PR was generated from (e.g. v5.7.0-rc.0, master). Leave blank to parse from the PR body."
+ required: false
+ mode:
+ type: choice
+ prompt: "Run mode. interactive = show findings, wait for approval per pattern. automatic = apply every fix from `references/patterns.md` and report."
+ options:
+ - interactive
+ - automatic
+ default: interactive
+ required: false
+---
+
+# docgen-fixup
+
+Fix the known regression patterns in an auto-generated API docs PR before it merges. The docs bot runs three receivers — one per source repo — each on a release tag / master commit, and opens a PR against `content//**/*.mdx`:
+
+| Workflow | Source repo | Docs slice | Versioned |
+|-----------------------------------------------------|---------------------------------------------------|--------------------------------|-----------|
+| `.github/workflows/generate-api-docs-contracts.yml` | `OpenZeppelin/openzeppelin-contracts` | `content/contracts/.x/` | yes |
+| `.github/workflows/generate-api-docs-community-contracts.yml` | `OpenZeppelin/openzeppelin-community-contracts` | `content/community-contracts/` | no |
+| `.github/workflows/generate-api-docs-confidential-contracts.yml` | `OpenZeppelin/openzeppelin-confidential-contracts` | `content/confidential-contracts/` | no |
+
+All three run the same transformer (`docgen/templates-md/` + `scripts/convert-adoc.js` + `scripts/process-mdx.js`), so the same regression patterns apply to all three. The transformer is intentionally kept simple — it does not paper over upstream NatSpec / `.adoc` mistakes, and it does not try to be exhaustive about every edge case. Those get caught here.
+
+## When to use
+
+- The docs bot just opened a PR (title starts with `[CI] Update API docs for OpenZeppelin/…`).
+- The user names a PR number and asks for a review / fix pass.
+- Before merging any auto-generated docs update.
+
+Do **not** use this skill for:
+
+- Hand-written guide pages that were not touched by the bot (use a normal edit).
+- Changes to `docgen/templates-md/` or `scripts/convert-adoc.js` — those are transformer changes, not fixup. Keep the transformer minimal; catalog new regression patterns here instead.
+
+## Guiding principle
+
+The docgen transformer stays minimal. It fixes only genuine regex / template bugs — not upstream authoring mistakes. Everything the docgen leaves broken should either be:
+
+1. **Fixed upstream** in the source `.sol` NatSpec or `docs/modules/ROOT/pages/*.adoc`, so the next regen produces correct output — and cataloged in `references/patterns.md` for the next reviewer.
+2. **Patched directly** in the generated MDX for the current PR, so the PR is correct without waiting for a regen.
+
+Both. Upstream fixes drop the pattern from future PRs; direct patches unblock the current one.
+
+Some patterns have **no clean upstream fix** because the value depends on a docs-side decision (e.g. which Wizard `version=` to pin for a given release). Those are `n/a` for upstream and are re-applied on every regen. That is not a bug — it is the boundary between what upstream owns and what the docs repo owns.
+
+## Inputs
+
+| Input | Required | Notes |
+|-----------------------|----------|--------------------------------------------------------------------|
+| `pr_number` | yes | PR to review (auto-generated by the bot) |
+| `contracts_repo_path` | no | absolute path; auto-detected from the PR body if omitted |
+| `contracts_tag` | no | git tag / ref; parsed from the PR body if omitted |
+| `mode` | no | `interactive` (default) or `automatic` |
+
+Never invent an SHA, a path, or a PR number. If auto-detection fails, stop and report which field is missing.
+
+## Workflow
+
+Follow `process.md` end-to-end. It:
+
+1. Validates inputs and resolves the source repo + tag from the PR body.
+2. Fetches the PR diff and lays out per-file patches under `/tmp/pr--diffs/`.
+3. Runs the pattern catalog in `references/patterns.md` against each changed file.
+4. Emits a findings block per pattern (interactive mode waits for approval; automatic mode applies immediately).
+5. Applies direct MDX patches, opens upstream PRs where warranted, and updates the PR branch.
+
+## Pattern catalog
+
+`references/patterns.md` is the source of truth for what this skill knows how to fix. Each entry has:
+
+- **Symptom** — what the reader sees in the generated MDX.
+- **Detection** — the grep / heuristic that finds it.
+- **Root cause** — where in the pipeline (docgen resolver / regex / template / upstream NatSpec / upstream `.adoc`) the pattern comes from.
+- **Upstream fix** — the change to the source `.sol` / `.adoc` so the next regen produces correct output. Skip if there is no clean upstream fix.
+- **MDX patch** — the direct patch to apply on the current PR.
+- **Example** — a concrete case from a prior regen.
+
+When you discover a **new** regression pattern that isn't in the catalog, append it to `references/patterns.md` in the same shape as an existing entry, and note it in the run report. The catalog is a living document — every reviewer contributes.
+
+## Scope of edits
+
+Edit only:
+
+- Files inside the resolved PR's diff — do not touch pages the bot did not modify.
+- Upstream source files under `/contracts/**/*.sol` or `/docs/modules/ROOT/pages/**/*.adoc` when a pattern has an upstream fix — via a **separate branch and PR** on the contracts repo, never in a direct commit to `master`.
+
+Do **not**:
+
+- Modify `docgen/templates-md/` or `scripts/convert-adoc.js`. If a pattern seems to demand a transformer change, stop and surface it to the user — that is a separate design decision, not a fixup.
+- Touch docs slices the current PR is not scoped to. Each of the three docgen workflows targets a single slice (`content/contracts/.x/`, `content/community-contracts/`, or `content/confidential-contracts/`); patch only inside that slice.
+- Rewrite prose beyond what a specific pattern requires.
+
+## End of run
+
+Produce a compact report per `references/report-template.md`:
+
+- Files fixed, per pattern, with line hints.
+- Upstream PRs opened (URL + one-line summary each).
+- Any new patterns added to `references/patterns.md`.
+- Anything skipped (with the reason).
+
+Do not write the report to a file unless the user asks — inline in the final message is enough.
diff --git a/skills/docgen-fixup/process.md b/skills/docgen-fixup/process.md
new file mode 100644
index 00000000..f324f283
--- /dev/null
+++ b/skills/docgen-fixup/process.md
@@ -0,0 +1,172 @@
+# docgen-fixup process
+
+Deterministic workflow. Steps run in order. If a step fails, stop and surface — do not skip ahead.
+
+All paths in this document are relative to the docs repo unless prefixed ``.
+
+---
+
+## Step 0 — Validate inputs
+
+Inputs arrive from the frontmatter `inputs` schema. Validate inline:
+
+- `pr_number`: is a positive integer; PR exists and is open on `OpenZeppelin/docs`.
+- `contracts_repo_path` (if provided): exists and is a git repo.
+- `contracts_tag` (if provided): resolves in the source contracts repo.
+
+Missing / invalid input is a hard error — return an error message naming every failing field. Never invent values.
+
+## Step 1 — Fetch PR metadata
+
+```
+gh pr view --repo OpenZeppelin/docs \
+ --json title,body,headRefName,baseRefName,changedFiles,url,mergeable
+```
+
+Record `headRefName` (branch), `baseRefName` (target — usually `main`), and the body.
+
+## Step 2 — Resolve source repo, docs slice, and tag
+
+Parse the PR body:
+
+- **Repository** line names the source repo (e.g. `OpenZeppelin/openzeppelin-contracts`, `OpenZeppelin/openzeppelin-community-contracts`, `OpenZeppelin/openzeppelin-confidential-contracts`).
+- **Reference** line names the tag / branch (e.g. `v5.7.0-rc.0`, `master`).
+- **Output Directory** line names the docs slice (e.g. `content/contracts/5.x/api`, `content/community-contracts/api`, `content/confidential-contracts/api`).
+
+Fill in `contracts_repo_path` and `contracts_tag` from inputs if provided; otherwise from the body. Then:
+
+- Auto-detect the local checkout. Walk the parent of `` and any known sibling roots. For each candidate directory, run `git -C remote get-url origin 2>/dev/null` and match against the parsed source repo. Common names to try, per source repo:
+
+ | Source repo | Candidate dir names |
+ |--------------------------------------------------------|--------------------------------------------------------|
+ | `OpenZeppelin/openzeppelin-contracts` | `solidity`, `openzeppelin-contracts` |
+ | `OpenZeppelin/openzeppelin-community-contracts` | `community`, `openzeppelin-community-contracts` |
+ | `OpenZeppelin/openzeppelin-confidential-contracts` | `confidential`, `openzeppelin-confidential-contracts` |
+
+ Fall back to a `git remote -v | grep ` sweep across all directories under the workspace root if none of the common names hit. Do not invent a path.
+
+- Fetch the tag: `git -C fetch origin refs/tags/:refs/tags/` for a tag, or `git -C fetch origin ` for a branch (community-contracts and confidential-contracts often generate against `master`).
+- Create a read-only worktree pinned at the ref:
+ ```
+ git -C worktree add /tmp/oz-src-
+ ```
+ Use a slug that includes both the repo short-name and the ref so parallel runs don't collide: `oz-src-contracts-v5.7.0-rc.0`, `oz-src-community-master`, etc. Remove in Step 11.
+
+Note the docs slice from the PR body so pattern-scan globs stay scoped to that slice (`content//**/*.mdx`) and don't false-positive on other slices.
+
+If auto-detection or fetching fails, stop with a clear error naming both the parsed repo and the candidate paths that were tried.
+
+## Step 3 — Check out the PR branch locally
+
+```
+git -C fetch origin pull//head:pr-
+git -C checkout pr-
+```
+
+Record the previous branch so it can be restored at end of run.
+
+## Step 4 — Capture per-file diffs
+
+Stage the diff for pattern scanning:
+
+```
+mkdir -p /tmp/pr--diffs
+for f in $(gh pr diff --repo OpenZeppelin/docs --name-only); do
+ safe=$(echo "$f" | sed 's|/|__|g')
+ git -C diff origin/ pr- -- "$f" > "/tmp/pr--diffs/$safe.diff"
+done
+```
+
+## Step 5 — Run the pattern catalog
+
+For each pattern in `references/patterns.md`, in order:
+
+1. Run its **Detection** command / heuristic against the diff (or the PR branch's MDX, whichever the pattern specifies).
+2. Collect hits — one row per (file, line, matched snippet).
+3. For each hit, verify against upstream source in `/tmp/oz-src-/` before flagging. Skip if the hit is a false positive (the pattern description says how).
+4. If the pattern **has** an upstream fix, note the upstream file + line for the eventual upstream PR.
+
+## Step 6 — Findings gate (interactive mode)
+
+Emit ONE findings block per pattern that has hits. Format:
+
+```
+## Pattern:
+Symptom:
+Root cause:
+
+### Hits
+- : —
+ → MDX patch:
+ → Upstream: : — (or: "no clean upstream fix")
+
+### Approval
+Reply "apply" to patch the MDX + open the upstream PR, "skip" to leave this pattern alone this run, or refine to change the plan.
+```
+
+End the turn after emitting all findings blocks. Wait for the user's response. Accept: `apply`, `apply all`, `skip`, or refinements. Anything else re-emit + wait.
+
+In `automatic` mode, skip this gate — apply every patch immediately.
+
+## Step 7 — Apply MDX patches
+
+For each approved pattern:
+
+1. Read the affected MDX file (must Read before Edit).
+2. Apply the direct patch described in `references/patterns.md`. Use `Edit` with enough surrounding context to make the `old_string` unique.
+3. Verify the patch: re-grep for the pattern's detection signature on the file; the hit should be gone.
+
+Never batch a rewrite. One `Edit` per (file, hit).
+
+## Step 8 — Open upstream PRs
+
+For each approved pattern with an upstream fix:
+
+1. Group hits by target file — one branch per file is fine, one branch per pattern is better.
+2. Create a worktree on the source contracts repo (do not disturb the user's current checkout):
+ ```
+ git -C worktree add /tmp/oz-upstream- origin/master
+ ```
+3. Apply the upstream edits in that worktree.
+4. Commit with a subject in the form `docs: in `.
+5. Push to the user's fork:
+ ```
+ git -C /tmp/oz-upstream- push
+ ```
+ The fork remote is the one whose URL points at the user's GitHub username. Do not push to `origin` on the contracts repo.
+6. Open a PR:
+ ```
+ gh pr create --repo --base master --head : \
+ --title "" --body ""
+ ```
+7. Remove the worktree.
+
+Record the PR URL for the final report.
+
+## Step 9 — Commit and push the MDX patches
+
+```
+git -C add
+git -C commit -m "fixup: apply docgen-fixup patterns to "
+git -C push origin pr-:
+```
+
+Only push if the user's docs remote points at their fork or they have write access to `OpenZeppelin/docs`. Verify with `git remote -v` before pushing. If neither is true, stop and surface — do not force it.
+
+## Step 10 — Catalog new patterns (if any)
+
+If Step 5 surfaced a regression pattern that is NOT in `references/patterns.md`:
+
+1. Draft a new entry in the same shape as an existing one (Symptom / Detection / Root cause / Upstream fix / MDX patch / Example).
+2. Append it to `references/patterns.md`.
+3. Commit under the same message so the catalog grows with each run.
+
+## Step 11 — Restore local state
+
+- Return the docs repo to the branch it was on when the run started.
+- Remove `/tmp/oz-src-/`, `/tmp/oz-upstream-/`, `/tmp/pr--diffs/`.
+- Do not delete the `pr-` local branch — leave it available for follow-up.
+
+## Step 12 — Report
+
+Emit the report per `references/report-template.md`. Inline in the final message — do not write to a file unless the user asks.
diff --git a/skills/docgen-fixup/references/patterns.md b/skills/docgen-fixup/references/patterns.md
new file mode 100644
index 00000000..0bff46a6
--- /dev/null
+++ b/skills/docgen-fixup/references/patterns.md
@@ -0,0 +1,187 @@
+# Regression pattern catalog
+
+Every pattern the `docgen-fixup` skill knows how to detect and fix. Add new entries as new regressions emerge; do not delete entries even when the underlying pipeline bug is fixed — pinned regens against old tags can still hit them.
+
+All patterns apply to any of the three source-repo receivers unless the entry says otherwise: `contracts` (versioned, `content/contracts/.x/`), `community-contracts` (unversioned, `content/community-contracts/`), `confidential-contracts` (unversioned, `content/confidential-contracts/`).
+
+Each entry:
+
+- **Symptom** — what the reader sees in the generated MDX.
+- **Detection** — a grep or scan that finds hits. Scope globs to the docs slice from the PR body — see Step 2 of `process.md`.
+- **Root cause** — where in the pipeline (docgen resolver, regex, template, `downdoc`, upstream NatSpec, upstream `.adoc`, docs-side decision) it comes from.
+- **Upstream fix** — the change to the source `.sol` / `.adoc` so the next regen produces correct output. `n/a` if there is no clean upstream fix (e.g. the value depends on a docs-side decision, or the pattern is a transformer bug fixable only in the docs repo).
+- **MDX patch** — the direct patch to apply on the current PR.
+- **Example** — one concrete case from a prior regen.
+
+---
+
+## 1. Broken Solidity code block in a hand-authored guide
+
+**Symptom**: a fenced ```` ```solidity ```` block inside a guide `.mdx` has mangled indentation on interior lines and/or a missing closing brace. Copy-pasting the block would not compile.
+
+**Detection**:
+```
+git diff origin/ pr- -- 'content/**/*.mdx' \
+ | awk '/```solidity/,/```/' \
+ | grep -nE '^\+' \
+ | grep -E '^\+ {0,4}(super|return|revert|emit)|^\+\}$'
+```
+False-positive check: the same block on `origin/` did NOT have the same shape (the regression is new in this PR).
+
+**Root cause**: `downdoc` mangles the contents of triple-backtick fenced blocks when they live inside a `.adoc` source (it treats them as prose, strips `//` comment lines, de-indents nested `{}`). `scripts/convert-adoc.js` preprocesses these to `[source,lang]\n----\n...\n----` form before running `downdoc` — but if a maintainer bypasses that preprocess (or a new fenced-block variant slips through the regex), the mangle returns.
+
+**Upstream fix**: rewrite the block in the source `.adoc` as `[source,lang]\n----\n...\n----` explicitly, or as `include::api:example$path/to/File.sol[]`. Do not rely on the preprocess to catch new syntaxes.
+
+**MDX patch**: restore indentation and closing braces by copying the corresponding code from the source `.adoc` (or the referenced example `.sol`).
+
+**Example** (PR #206): `content/contracts/5.x/extending-contracts.mdx:52-56` — `super.revokeRole(...)` dedented to 4 spaces, function closing `}` at column 0, function-level closing `}` missing.
+
+---
+
+## 2. NatSpec `{Type}` / `{Contract.method}` leaks as raw anchor fragment
+
+**Symptom**: prose inside an API MDX contains a bare `#Contract-something-Type` fragment sitting in the middle of a sentence (not inside a Markdown link).
+
+**Detection**:
+```
+grep -rnP '(?` anywhere in the file. Clicking navigates to a non-existent fragment.
+
+**Detection**:
+```
+python3 -c '
+import re, glob
+for f in glob.glob("content/**/api/**/*.mdx", recursive=True):
+ t = open(f).read()
+ defs = set(re.findall(r"` — inheritance-related dangles are a separate, broader issue.
+
+**Root cause**: `contract.hbs` emits `` for structs (as of the fix that shipped with PR #206). For **enums** and **user-defined value types** it does not — those are still on the "if a NatSpec ref hits one, the link dangles" path. Slugs for those AST node types are still registered by `getAllLinks`, so `{EnumType}` in NatSpec produces a link to a nonexistent anchor.
+
+**Upstream fix**: rewrite the NatSpec ref to inline code (`` `EnumType` ``) or link to the contract page (`{Contract}`).
+
+**MDX patch**: either emit the missing `` alongside the contract's main anchor, or rewrite the link into inline code. Prefer the anchor when the reader benefits from a jump target.
+
+**Example** (PR #206): `content/contracts/5.x/api/utils.mdx` — `[RateLimiter.RefillingBucket](#RateLimiter-RefillingBucket)` and `[RateLimiter.SlidingWindow](#RateLimiter-SlidingWindow)` in the RateLimiter description. Fixed by rendering full struct sections (see the `contract.hbs` change that shipped with PR #206).
+
+---
+
+## 5. AsciiDoc heading conversion leaves trailing `===`
+
+**Symptom**: an MDX heading like `### Section title ===` — the trailing equals signs from an AsciiDoc symmetric setext form leaked through into the Markdown output.
+
+**Detection**:
+```
+grep -rnE '^#+ .*=+ *$' content/**/*.mdx
+```
+
+**Root cause**: NatSpec author wrote `=== Section title ===` (equals on both sides — legacy AsciiDoc symmetric setext). `docgen/templates-md/helpers.js processCallouts()` converts leading `===` to `###` but does not strip the trailing `===`. The transformer regex is deliberately kept narrow — this is an upstream authoring mistake.
+
+**Upstream fix**: drop the trailing `===` in the source `.sol` NatSpec. Standard form in this codebase is leading-only (`* === Section title`).
+
+**MDX patch**: strip the trailing `===` from the heading.
+
+**Example** (PR #206): `content/contracts/5.x/api/utils.mdx:9286` — `### Limiter vs. entries ===` from `contracts/utils/RateLimiter.sol:23`. Upstream fixed in [OpenZeppelin/openzeppelin-contracts#6612](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/6612).
+
+---
+
+## 6. `[TIP]==== ... ====` block admonition dumped as prose
+
+**Symptom**: content that should be wrapped in a `` component renders as plain paragraph text, often with two or three empty lines where the block delimiters used to be.
+
+**Detection**:
+```
+# Blank runs of 3+ lines in generated MDX are often a signature of stripped admonition delimiters
+grep -rnE '^$' content/**/*.mdx | awk -F: '{print $1":"$2}' | uniq -c | awk '$1 >= 3'
+# Then verify each hit against the source .adoc to see if a [TIP]====/[NOTE]==== block sat there.
+```
+
+**Root cause**: `downdoc` converts AsciiDoc `[TIP]==== ... ====` block admonitions into `