Merge branch 'master' into feature/merkle-tree-update

pull/5453/head
Hadrien Croubois 2 weeks ago committed by GitHub
commit 374c54fb18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/green-drinks-report.md
  2. 3
      .github/actions/gas-compare/action.yml
  3. 3
      .github/actions/storage-layout/action.yml
  4. 1
      .gitignore
  5. 10
      CHANGELOG.md
  6. 2
      README.md
  7. 2
      RELEASING.md
  8. 2
      SECURITY.md
  9. 2
      audits/2017-03.md
  10. 4
      certora/README.md
  11. 4
      certora/specs/AccessControlDefaultAdminRules.spec
  12. 6
      certora/specs/ERC20FlashMint.spec
  13. 2
      contracts/finance/VestingWallet.sol
  14. 2
      contracts/governance/Governor.sol
  15. 4
      contracts/governance/README.adoc
  16. 4
      contracts/governance/extensions/GovernorCountingFractional.sol
  17. 34
      contracts/governance/extensions/GovernorCountingOverridable.sol
  18. 2
      contracts/governance/extensions/GovernorStorage.sol
  19. 2
      contracts/governance/extensions/GovernorTimelockAccess.sol
  20. 2
      contracts/interfaces/IERC1271.sol
  21. 1
      contracts/proxy/utils/UUPSUpgradeable.sol
  22. 4
      contracts/token/ERC1155/IERC1155.sol
  23. 4
      contracts/token/ERC1155/utils/ERC1155Utils.sol
  24. 2
      contracts/token/ERC20/extensions/ERC4626.sol
  25. 2
      contracts/token/ERC721/README.adoc
  26. 2
      contracts/token/ERC721/extensions/ERC721Consecutive.sol
  27. 2
      contracts/token/ERC721/extensions/ERC721URIStorage.sol
  28. 2
      contracts/token/ERC721/utils/ERC721Utils.sol
  29. 2
      contracts/token/common/ERC2981.sol
  30. 6
      contracts/utils/Arrays.sol
  31. 4
      contracts/utils/Multicall.sol
  32. 7
      contracts/utils/Pausable.sol
  33. 4
      contracts/utils/ShortStrings.sol
  34. 18
      contracts/utils/Strings.sol
  35. 2
      contracts/utils/cryptography/EIP712.sol
  36. 11
      docs/modules/ROOT/pages/crowdsales.adoc
  37. 19
      docs/modules/ROOT/pages/drafts.adoc
  38. 2
      docs/modules/ROOT/pages/erc20-supply.adoc
  39. 4
      docs/modules/ROOT/pages/governance.adoc
  40. 4
      docs/templates/contract.hbs
  41. 16
      docs/templates/properties.js
  42. 2
      scripts/generate/templates/Arrays.js
  43. 2
      test/governance/extensions/GovernorCountingOverridable.test.js
  44. 6
      test/metatx/ERC2771Forwarder.t.sol
  45. 26
      test/token/ERC721/ERC721.behavior.js

@ -0,0 +1,5 @@
---
"openzeppelin-solidity": minor
---
`Pausable`: Stop explicitly setting `paused` to `false` during construction.

@ -44,7 +44,8 @@ runs:
shell: bash
- name: Save report
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: gasreport
overwrite: true
path: ${{ inputs.out_report }}

@ -50,7 +50,8 @@ runs:
shell: bash
- name: Save artifacts
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: layout
overwrite: true
path: ${{ inputs.out_layout }}

1
.gitignore vendored

@ -37,6 +37,7 @@ npm-debug.log
# docs artifacts
docs/modules/api
build/site
# only used to package @openzeppelin/contracts
contracts/build/

@ -1,5 +1,13 @@
# Changelog
### Breaking Changes
- Replace `GovernorCountingOverridable.VoteReceipt` struct parameter member names `hasOverriden` and `overridenWeight` for `hasOverridden` and `overriddenWeight` respectively.
#### Custom error changes
- Replace `GovernorAlreadyOverridenVote` with `GovernorAlreadyOverriddenVote`.
## 5.2.0 (2025-01-08)
### Breaking Changes
@ -48,7 +56,7 @@ This version comes with changes to the custom error identifiers. Contracts previ
### Breaking changes
- `ERC1967Utils`: Removed duplicate declaration of the `Upgraded`, `AdminChanged` and `BeaconUpgraded` events. These events are still available through the `IERC1967` interface located under the `contracts/interfaces/` directory. Minimum pragma version is now 0.8.21.
- `Governor`, `GovernorCountingSimple`: The `_countVote` virtual function now returns an `uint256` with the total votes casted. This change allows for more flexibility for partial and fractional voting. Upgrading users may get a compilation error that can be fixed by adding a return statement to the `_countVote` function.
- `Governor`, `GovernorCountingSimple`: The `_countVote` virtual function now returns an `uint256` with the total votes cast. This change allows for more flexibility for partial and fractional voting. Upgrading users may get a compilation error that can be fixed by adding a return statement to the `_countVote` function.
#### Custom error changes

@ -70,7 +70,7 @@ The guides in the [documentation site](https://docs.openzeppelin.com/contracts)
* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales).
* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools including non-overflowing math, signature verification, and trustless paying systems.
The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com).
The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts' development in the [community forum](https://forum.openzeppelin.com).
Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/), which cover several common use cases and good practices. The following articles provide great background reading, though please note that some of the referenced tools have changed, as the tooling in the ecosystem continues to rapidly evolve.

@ -4,7 +4,7 @@ OpenZeppelin Contracts uses a fully automated release process that takes care of
## Changesets
[Changesets](https://github.com/changesets/changesets/) is used as part of our release process for `CHANGELOG.md` management. Each change that is relevant for the codebase is expected to include a changeset.
[Changesets](https://github.com/changesets/changesets/) are used as part of our release process for `CHANGELOG.md` management. Each change that is relevant for the codebase is expected to include a changeset.
## Branching model

@ -40,4 +40,4 @@ Note as well that the Solidity language itself only guarantees security updates
## Legal
Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an on-going duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project.
Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an ongoing duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project.

@ -20,7 +20,7 @@ The git commit hash we evaluated is:
# Disclaimer
The audit makes no statements or warrantees about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bugfree status. The audit documentation is for discussion purposes only.
The audit makes no statements or warrantees about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bug free status. The audit documentation is for discussion purposes only.
# Executive Summary

@ -2,14 +2,14 @@
These instructions detail the process for running Certora Verification Tool on OpenZeppelin Contracts.
Documentation for CVT and the specification language are available [here](https://certora.atlassian.net/wiki/spaces/CPD/overview).
Documentation for CVT and the specification language is available [here](https://certora.atlassian.net/wiki/spaces/CPD/overview).
## Prerequisites
Follow the [Certora installation guide](https://docs.certora.com/en/latest/docs/user-guide/getting-started/install.html) in order to get the Certora Prover Package and the `solc` executable folder in your path.
> **Note**
> An API Key is required for local testing. Although the prover will run on a Github Actions' CI environment on selected Pull Requests.
> An API Key is required for local testing. Although the prover will run on a GitHub Actions' CI environment on selected Pull Requests.
## Running the verification

@ -176,7 +176,7 @@ rule renounceRoleEffect(env e, bytes32 role) {
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Rule: defaultAdmin is only affected by accepting an admin transfer or renoucing
│ Rule: defaultAdmin is only affected by accepting an admin transfer or renouncing │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
rule noDefaultAdminChange(env e, method f, calldataarg args) {
@ -188,7 +188,7 @@ rule noDefaultAdminChange(env e, method f, calldataarg args) {
f.selector == sig:acceptDefaultAdminTransfer().selector ||
f.selector == sig:renounceRole(bytes32,address).selector
),
"default admin is only affected by accepting an admin transfer or renoucing";
"default admin is only affected by accepting an admin transfer or renouncing";
}
/*

@ -18,7 +18,7 @@ methods {
*/
ghost mapping(address => mathint) trackedMintAmount;
ghost mapping(address => mathint) trackedBurnAmount;
ghost mapping(address => mapping(address => mathint)) trackedTransferedAmount;
ghost mapping(address => mapping(address => mathint)) trackedTransferredAmount;
function specUpdate(address from, address to, uint256 amount) {
if (from == 0 && to == 0) { assert(false); } // defensive
@ -28,7 +28,7 @@ function specUpdate(address from, address to, uint256 amount) {
} else if (to == 0) {
trackedBurnAmount[from] = amount;
} else {
trackedTransferedAmount[from][to] = amount;
trackedTransferredAmount[from][to] = amount;
}
}
@ -51,5 +51,5 @@ rule checkMintAndBurn(env e) {
assert trackedMintAmount[receiver] == to_mathint(amount);
assert trackedBurnAmount[receiver] == amount + to_mathint(recipient == 0 ? fees : 0);
assert (fees > 0 && recipient != 0) => trackedTransferedAmount[receiver][recipient] == to_mathint(fees);
assert (fees > 0 && recipient != 0) => trackedTransferredAmount[receiver][recipient] == to_mathint(fees);
}

@ -16,7 +16,7 @@ import {Ownable} from "../access/Ownable.sol";
* Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly)
* be immediately releasable.
*
* By setting the duration to 0, one can configure this contract to behave like an asset timelock that hold tokens for
* By setting the duration to 0, one can configure this contract to behave like an asset timelock that holds tokens for
* a beneficiary until a specified time.
*
* NOTE: Since the wallet is {Ownable}, and ownership can be transferred, it is possible to sell unvested tokens.

@ -455,7 +455,7 @@ abstract contract Governor is Context, ERC165, EIP712, Nonces, IGovernor, IERC72
* performed (for example adding a vault/timelock).
*
* NOTE: Calling this function directly will NOT check the current state of the proposal, set the executed flag to
* true or emit the `ProposalExecuted` event. Executing a proposal should be done using {execute} or {_execute}.
* true or emit the `ProposalExecuted` event. Executing a proposal should be done using {execute}.
*/
function _executeOperations(
uint256 /* proposalId */,

@ -68,7 +68,7 @@ NOTE: Functions of the `Governor` contract do not include access control. If you
{{GovernorCountingFractional}}
{{GovernorCountingOverride}}
{{GovernorCountingOverridable}}
{{GovernorVotes}}
@ -103,7 +103,7 @@ In a governance system, the {TimelockController} contract is in charge of introd
[[timelock-terminology]]
==== Terminology
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution. If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation status:*
** *Unset:* An operation that is not part of the timelock mechanism.
** *Waiting:* An operation that has been scheduled, before the timer expires.

@ -125,9 +125,9 @@ abstract contract GovernorCountingFractional is Governor {
*
* `abi.encodePacked(uint128(againstVotes), uint128(forVotes), uint128(abstainVotes))`
*
* NOTE: Consider that fractional voting restricts the number of casted vote (in each category) to 128 bits.
* NOTE: Consider that fractional voting restricts the number of casted votes (in each category) to 128 bits.
* Depending on how many decimals the underlying token has, a single voter may require to split their vote into
* multiple vote operations. For precision higher than ~30 decimals, large token holders may require an
* multiple vote operations. For precision higher than ~30 decimals, large token holders may require a
* potentially large number of calls to cast all their votes. The voter has the possibility to cast all the
* remaining votes in a single operation using the traditional "bravo" vote.
*/

@ -27,8 +27,8 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
struct VoteReceipt {
uint8 casted; // 0 if vote was not casted. Otherwise: support + 1
bool hasOverriden;
uint208 overridenWeight;
bool hasOverridden;
uint208 overriddenWeight;
}
struct ProposalVote {
@ -42,7 +42,7 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
/// @dev A delegated vote on `proposalId` was overridden by `weight`
event OverrideVoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
error GovernorAlreadyOverridenVote(address account);
error GovernorAlreadyOverriddenVote(address account);
mapping(uint256 proposalId => ProposalVote) private _proposalVotes;
@ -70,7 +70,7 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
* @dev Check if an `account` has overridden their delegate for a proposal.
*/
function hasVotedOverride(uint256 proposalId, address account) public view virtual returns (bool) {
return _proposalVotes[proposalId].voteReceipt[account].hasOverriden;
return _proposalVotes[proposalId].voteReceipt[account].hasOverridden;
}
/**
@ -122,7 +122,7 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
revert GovernorAlreadyCastVote(account);
}
totalWeight -= proposalVote.voteReceipt[account].overridenWeight;
totalWeight -= proposalVote.voteReceipt[account].overriddenWeight;
proposalVote.votes[support] += totalWeight;
proposalVote.voteReceipt[account].casted = support + 1;
@ -141,26 +141,26 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
revert GovernorInvalidVoteType();
}
if (proposalVote.voteReceipt[account].hasOverriden) {
revert GovernorAlreadyOverridenVote(account);
if (proposalVote.voteReceipt[account].hasOverridden) {
revert GovernorAlreadyOverriddenVote(account);
}
uint256 snapshot = proposalSnapshot(proposalId);
uint256 overridenWeight = VotesExtended(address(token())).getPastBalanceOf(account, snapshot);
uint256 overriddenWeight = VotesExtended(address(token())).getPastBalanceOf(account, snapshot);
address delegate = VotesExtended(address(token())).getPastDelegate(account, snapshot);
uint8 delegateCasted = proposalVote.voteReceipt[delegate].casted;
proposalVote.voteReceipt[account].hasOverriden = true;
proposalVote.votes[support] += overridenWeight;
proposalVote.voteReceipt[account].hasOverridden = true;
proposalVote.votes[support] += overriddenWeight;
if (delegateCasted == 0) {
proposalVote.voteReceipt[delegate].overridenWeight += SafeCast.toUint208(overridenWeight);
proposalVote.voteReceipt[delegate].overriddenWeight += SafeCast.toUint208(overriddenWeight);
} else {
uint8 delegateSupport = delegateCasted - 1;
proposalVote.votes[delegateSupport] -= overridenWeight;
emit VoteReduced(delegate, proposalId, delegateSupport, overridenWeight);
proposalVote.votes[delegateSupport] -= overriddenWeight;
emit VoteReduced(delegate, proposalId, delegateSupport, overriddenWeight);
}
return overridenWeight;
return overriddenWeight;
}
/// @dev Variant of {Governor-_castVote} that deals with vote overrides. Returns the overridden weight.
@ -172,13 +172,13 @@ abstract contract GovernorCountingOverridable is GovernorVotes {
) internal virtual returns (uint256) {
_validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Active));
uint256 overridenWeight = _countOverride(proposalId, account, support);
uint256 overriddenWeight = _countOverride(proposalId, account, support);
emit OverrideVoteCast(account, proposalId, support, overridenWeight, reason);
emit OverrideVoteCast(account, proposalId, support, overriddenWeight, reason);
_tallyUpdated(proposalId);
return overridenWeight;
return overriddenWeight;
}
/// @dev Public function for casting an override vote. Returns the overridden weight.

@ -50,7 +50,7 @@ abstract contract GovernorStorage is Governor {
}
/**
* @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument.
* @dev Version of {IGovernor-queue} with only `proposalId` as an argument.
*/
function queue(uint256 proposalId) public virtual {
// here, using storage is more efficient than memory

@ -277,7 +277,7 @@ abstract contract GovernorTimelockAccess is Governor {
}
/**
* @dev See {IGovernor-_cancel}
* @dev See {Governor-_cancel}
*/
function _cancel(
address[] memory targets,

@ -11,7 +11,7 @@ interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
* @param signature Signature byte array associated with `hash`
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}

@ -91,7 +91,6 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable {
/**
* @dev Reverts if the execution is not performed via delegatecall or the execution
* context is not of a proxy with an ERC-1967 compliant implementation pointing to self.
* See {_onlyProxy}.
*/
function _checkProxy() internal view virtual {
if (

@ -81,7 +81,7 @@ interface IERC1155 is IERC165 {
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {onERC1155Received} on the receiver.
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155Received} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
@ -101,7 +101,7 @@ interface IERC1155 is IERC165 {
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155BatchReceived} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*

@ -15,7 +15,7 @@ import {IERC1155Errors} from "../../../interfaces/draft-IERC6093.sol";
*/
library ERC1155Utils {
/**
* @dev Performs an acceptance check for the provided `operator` by calling {IERC1155-onERC1155Received}
* @dev Performs an acceptance check for the provided `operator` by calling {IERC1155Receiver-onERC1155Received}
* 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).
@ -50,7 +50,7 @@ library ERC1155Utils {
}
/**
* @dev Performs a batch acceptance check for the provided `operator` by calling {IERC1155-onERC1155BatchReceived}
* @dev Performs a batch acceptance check for the provided `operator` by calling {IERC1155Receiver-onERC1155BatchReceived}
* 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).

@ -34,7 +34,7 @@ import {Math} from "../../../utils/math/Math.sol";
* offset (0) makes it non-profitable even if an attacker is able to capture value from multiple user deposits, as a result
* of the value being captured by the virtual shares (out of the attacker's donation) matching the attacker's expected gains.
* With a larger offset, the attack becomes orders of magnitude more expensive than it is profitable. More details about the
* underlying math can be found xref:erc4626.adoc#inflation-attack[here].
* underlying math can be found xref:ROOT:erc4626.adoc#inflation-attack[here].
*
* The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued
* to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets

@ -3,7 +3,7 @@
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721
This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC-721 Non-Fungible Token Standard].
This set of interfaces, contracts, and utilities is all related to the https://eips.ethereum.org/EIPS/eip-721[ERC-721 Non-Fungible Token Standard].
TIP: For a walk through on how to create an ERC-721 token read our xref:ROOT:erc721.adoc[ERC-721 guide].

@ -159,7 +159,7 @@ abstract contract ERC721Consecutive is IERC2309, ERC721 {
}
/**
* @dev Used to offset the first token id in {_nextConsecutiveId}
* @dev Used to offset the first token id in `_nextConsecutiveId`
*/
function _firstConsecutiveId() internal view virtual returns (uint96) {
return 0;

@ -52,7 +52,7 @@ abstract contract ERC721URIStorage is IERC4906, ERC721 {
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Emits {MetadataUpdate}.
* Emits {IERC4906-MetadataUpdate}.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
_tokenURIs[tokenId] = _tokenURI;

@ -15,7 +15,7 @@ import {IERC721Errors} from "../../../interfaces/draft-IERC6093.sol";
*/
library ERC721Utils {
/**
* @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received}
* @dev Performs an acceptance check for the provided `operator` by calling {IERC721Receiver-onERC721Received}
* 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).

@ -39,7 +39,7 @@ abstract contract ERC2981 is IERC2981, ERC165 {
error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);
/**
* @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
* @dev The royalty set for a specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
*/
error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);

@ -448,7 +448,7 @@ library Arrays {
}
/**
* @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
@ -459,7 +459,7 @@ library Arrays {
}
/**
* @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
@ -470,7 +470,7 @@ library Arrays {
}
/**
* @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden.
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/

@ -13,10 +13,10 @@ import {Context} from "./Context.sol";
* careful about sending transactions invoking {multicall}. For example, a relay address that filters function
* selectors won't filter calls nested within a {multicall} operation.
*
* NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}).
* NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {Context-_msgSender}).
* If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data`
* to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of
* {_msgSender} are not propagated to subcalls.
* {Context-_msgSender} are not propagated to subcalls.
*/
abstract contract Multicall is Context {
/**

@ -37,13 +37,6 @@ abstract contract Pausable is Context {
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*

@ -95,7 +95,7 @@ library ShortStrings {
}
/**
* @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
* @dev Decode a string that was encoded to `ShortString` or written to storage using {toShortStringWithFallback}.
*/
function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
@ -107,7 +107,7 @@ library ShortStrings {
/**
* @dev Return the length of a string that was encoded to `ShortString` or written to storage using
* {setWithFallback}.
* {toShortStringWithFallback}.
*
* WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
* actual characters as the UTF-8 encoding of a single character can span over multiple bytes.

@ -139,7 +139,7 @@ library Strings {
}
/**
* @dev Variant of {parseUint} that parses a substring of `input` located between position `begin` (included) and
* @dev Variant of {parseUint-string} that parses a substring of `input` located between position `begin` (included) and
* `end` (excluded).
*
* Requirements:
@ -177,7 +177,7 @@ library Strings {
}
/**
* @dev Implementation of {tryParseUint} that does not check bounds. Caller should make sure that
* @dev Implementation of {tryParseUint-string-uint256-uint256} that does not check bounds. Caller should make sure that
* `begin <= end <= input.length`. Other inputs would result in undefined behavior.
*/
function _tryParseUintUncheckedBounds(
@ -250,7 +250,7 @@ library Strings {
}
/**
* @dev Implementation of {tryParseInt} that does not check bounds. Caller should make sure that
* @dev Implementation of {tryParseInt-string-uint256-uint256} that does not check bounds. Caller should make sure that
* `begin <= end <= input.length`. Other inputs would result in undefined behavior.
*/
function _tryParseIntUncheckedBounds(
@ -287,7 +287,7 @@ library Strings {
}
/**
* @dev Variant of {parseHexUint} that parses a substring of `input` located between position `begin` (included) and
* @dev Variant of {parseHexUint-string} that parses a substring of `input` located between position `begin` (included) and
* `end` (excluded).
*
* Requirements:
@ -325,7 +325,7 @@ library Strings {
}
/**
* @dev Implementation of {tryParseHexUint} that does not check bounds. Caller should make sure that
* @dev Implementation of {tryParseHexUint-string-uint256-uint256} that does not check bounds. Caller should make sure that
* `begin <= end <= input.length`. Other inputs would result in undefined behavior.
*/
function _tryParseHexUintUncheckedBounds(
@ -346,7 +346,7 @@ library Strings {
result *= 16;
unchecked {
// Multiplying by 16 is equivalent to a shift of 4 bits (with additional overflow check).
// This guaratees that adding a value < 16 will not cause an overflow, hence the unchecked.
// This guarantees that adding a value < 16 will not cause an overflow, hence the unchecked.
result += chr;
}
}
@ -364,7 +364,7 @@ library Strings {
}
/**
* @dev Variant of {parseAddress} that parses a substring of `input` located between position `begin` (included) and
* @dev Variant of {parseAddress-string} that parses a substring of `input` located between position `begin` (included) and
* `end` (excluded).
*
* Requirements:
@ -378,7 +378,7 @@ library Strings {
/**
* @dev Variant of {parseAddress-string} that returns false if the parsing fails because the input is not a properly
* formatted address. See {parseAddress} requirements.
* formatted address. See {parseAddress-string} requirements.
*/
function tryParseAddress(string memory input) internal pure returns (bool success, address value) {
return tryParseAddress(input, 0, bytes(input).length);
@ -386,7 +386,7 @@ library Strings {
/**
* @dev Variant of {parseAddress-string-uint256-uint256} that returns false if the parsing fails because input is not a properly
* formatted address. See {parseAddress} requirements.
* formatted address. See {parseAddress-string-uint256-uint256} requirements.
*/
function tryParseAddress(
string memory input,

@ -109,7 +109,7 @@ abstract contract EIP712 is IERC5267 {
}
/**
* @dev See {IERC-5267}.
* @inheritdoc IERC5267
*/
function eip712Domain()
public

@ -1,11 +0,0 @@
= Crowdsales
All crowdsale-related contracts were removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release] due to both a decline in their usage and the complexity associated with migrating them to Solidity v0.6.
They are however still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
```console
$ npm install @openzeppelin/contracts@v2.5
```
Refer to the https://docs.openzeppelin.com/contracts/2.x/crowdsales[v2.x documentation] when working with them.

@ -1,19 +0,0 @@
= Drafts
All draft contracts were either moved into a different directory or removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release].
* `ERC20Migrator`: removed.
* xref:api:token/ERC20.adoc#ERC20Snapshot[`ERC20Snapshot`]: moved to `token/ERC20`.
* `ERC20Detailed` and `ERC1046`: removed.
* `TokenVesting`: removed. Pending a replacement that is being discussed in https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1214[`#1214`].
* xref:api:utils.adoc#Counters[`Counters`]: moved to xref:api:utils.adoc[`utils`].
* xref:api:utils.adoc#Strings[`Strings`]: moved to xref:api:utils.adoc[`utils`].
* xref:api:utils.adoc#SignedSafeMath[`SignedSafeMath`]: moved to xref:api:utils.adoc[`utils`].
Removed contracts are still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
```console
$ npm install @openzeppelin/contracts@v2.5
```
Refer to the xref:2.x@contracts:api:drafts.adoc[v2.x documentation] when working with them.

@ -68,4 +68,4 @@ include::api:example$ERC20WithAutoMinerReward.sol[]
[[wrapping-up]]
== Wrapping Up
We've seen how to implement a ERC-20 supply mechanism: internally through `_mint`. Hopefully this has helped you understand how to use OpenZeppelin Contracts and some of the design principles behind it, and you can apply them to your own smart contracts.
We've seen how to implement an ERC-20 supply mechanism: internally through `_mint`. Hopefully this has helped you understand how to use OpenZeppelin Contracts and some of the design principles behind it, and you can apply them to your own smart contracts.

@ -20,7 +20,7 @@ The ERC-20 extension to keep track of votes and vote delegation is one such case
=== Governor & GovernorStorage
An OpenZeppelin Governor contract is not interface-compatible with Compound's GovernorAlpha or Bravo. Even though events are fully compatible, proposal lifecycle functions (creation, execution, etc.) have different signatures that are meant to optimize storage use. Other functions from GovernorAlpha and Bravo are likewise not available. It’s possible to opt in some Bravo-like behavior by inheriting from the GovernorStorage module. This module provides proposal enumerability and alternate versions of the `queue`, `execute` and `cancel` function that only take the proposal id. This module reduces the calldata needed by some operations in exchange for an increased the storage footprint. This might be a good trade-off for some L2 chains. It also provides primitives for indexer-free frontends.
An OpenZeppelin Governor contract is not interface-compatible with Compound's GovernorAlpha or Bravo. Even though events are fully compatible, proposal lifecycle functions (creation, execution, etc.) have different signatures that are meant to optimize storage use. Other functions from GovernorAlpha and Bravo are likewise not available. It’s possible to opt in some Bravo-like behavior by inheriting from the GovernorStorage module. This module provides proposal enumerability and alternate versions of the `queue`, `execute` and `cancel` function that only take the proposal id. This module reduces the calldata needed by some operations in exchange for an increased storage footprint. This might be a good trade-off for some L2 chains. It also provides primitives for indexer-free frontends.
Note that even with the use of this module, one important difference with Compound's GovernorBravo is the way that `proposalId`s are calculated. Governor uses the hash of the proposal parameters with the purpose of keeping its data off-chain by event indexing, while the original Bravo implementation uses sequential `proposalId`s.
@ -52,7 +52,7 @@ If your project already has a live token that does not include ERC20Votes and is
include::api:example$governance/MyTokenWrapped.sol[]
```
NOTE: The only other source of voting power available in OpenZeppelin Contracts currently is xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]. ERC-721 tokens that don't provide this functionality can be wrapped into a voting tokens using a combination of xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`] and xref:api:token/ERC721Wrapper.adoc#ERC721Wrapper[`ERC721Wrapper`].
NOTE: The only other source of voting power available in OpenZeppelin Contracts currently is xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]. ERC-721 tokens that don't provide this functionality can be wrapped into a voting tokens using a combination of xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`] and xref:api:token/ERC721.adoc#ERC721Wrapper[`ERC721Wrapper`].
NOTE: The internal clock used by the token to store voting balances will dictate the operating mode of the Governor contract attached to it. By default, block numbers are used. Since v4.9, developers can override the xref:api:interfaces.adoc#IERC6372[IERC6372] clock to use timestamps instead of block numbers.

@ -2,6 +2,10 @@
:{{name}}: pass:normal[xref:#{{anchor}}[`++{{name}}++`]]
{{/each}}
{{#each functions}}
:{{fullname}}: pass:normal[xref:#{{anchor}}[`++{{name}}++`]]
{{/each}}
[.contract]
[[{{anchor}}]]
=== `++{{name}}++` link:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v{{oz-version}}/{{__item_context.file.absolutePath}}[{github-icon},role=heading-link]

@ -17,6 +17,22 @@ module.exports.anchor = function anchor({ item, contract }) {
return res;
};
module.exports.fullname = function fullname({ item }) {
let res = '';
res += item.name;
if ('parameters' in item) {
const signature = item.parameters.parameters.map(v => v.typeName.typeDescriptions.typeString).join(',');
res += slug('(' + signature + ')');
}
if (isNodeType('VariableDeclaration', item)) {
res += '-' + slug(item.typeName.typeDescriptions.typeString);
}
if (res.charAt(res.length - 1) === '-') {
return res.slice(0, -1);
}
return res;
};
module.exports.inheritance = function ({ item, build }) {
if (!isNodeType('ContractDefinition', item)) {
throw new Error('used inherited-items on non-contract');

@ -346,7 +346,7 @@ function unsafeMemoryAccess(${type}[] memory arr, uint256 pos) internal pure ret
const unsafeSetLength = type => `\
/**
* @dev Helper to set the length of an dynamic array. Directly writing to \`.length\` is forbidden.
* @dev Helper to set the length of a dynamic array. Directly writing to \`.length\` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/

@ -264,7 +264,7 @@ describe('GovernorCountingOverridable', function () {
.to.emit(this.mock, 'OverrideVoteCast')
.withArgs(this.voter1, this.helper.id, VoteType.Against, ethers.parseEther('10'), '');
await expect(this.mock.connect(this.voter1).castOverrideVote(this.helper.id, VoteType.Abstain, ''))
.to.be.revertedWithCustomError(this.mock, 'GovernorAlreadyOverridenVote')
.to.be.revertedWithCustomError(this.mock, 'GovernorAlreadyOverriddenVote')
.withArgs(this.voter1.address);
});

@ -171,7 +171,7 @@ contract ERC2771ForwarderTest is Test {
uint256 refundExpected = 0;
uint256 nonce = _erc2771Forwarder.nonces(_signer);
// create an sign array or requests (that may fail)
// create an array of signed requests (that may fail)
ERC2771Forwarder.ForwardRequestData[] memory requests = new ERC2771Forwarder.ForwardRequestData[](batchSize);
for (uint256 i = 0; i < batchSize; ++i) {
bool failure = (seed >> i) & 0x1 == 0x1;
@ -229,7 +229,7 @@ contract ERC2771ForwarderTest is Test {
TamperType tamper = _asTamper(_tamper);
uint256 nonce = _erc2771Forwarder.nonces(_signer);
// create an sign array or requests
// create an array of signed requests
ERC2771Forwarder.ForwardRequestData[] memory requests = new ERC2771Forwarder.ForwardRequestData[](3);
for (uint256 i = 0; i < requests.length; ++i) {
requests[i] = _forgeRequestData({
@ -252,7 +252,7 @@ contract ERC2771ForwarderTest is Test {
TamperType tamper = _asTamper(_tamper);
uint256 nonce = _erc2771Forwarder.nonces(_signer);
// create an sign array or requests
// create an array of signed requests
ERC2771Forwarder.ForwardRequestData[] memory requests = new ERC2771Forwarder.ForwardRequestData[](3);
for (uint256 i = 0; i < requests.length; ++i) {
requests[i] = _forgeRequestData({

@ -10,7 +10,6 @@ const firstTokenId = 5042n;
const secondTokenId = 79217n;
const nonExistentTokenId = 13n;
const fourthTokenId = 4n;
const baseURI = 'https://api.example.com/v1/';
const RECEIVER_MAGIC_VALUE = '0x150b7a02';
@ -936,31 +935,6 @@ function shouldBehaveLikeERC721Metadata(name, symbol) {
.to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken')
.withArgs(nonExistentTokenId);
});
describe('base URI', function () {
beforeEach(function () {
if (!this.token.interface.hasFunction('setBaseURI')) {
this.skip();
}
});
it('base URI can be set', async function () {
await this.token.setBaseURI(baseURI);
expect(await this.token.baseURI()).to.equal(baseURI);
});
it('base URI is added as a prefix to the token URI', async function () {
await this.token.setBaseURI(baseURI);
expect(await this.token.tokenURI(firstTokenId)).to.equal(baseURI + firstTokenId.toString());
});
it('token URI can be changed by changing the base URI', async function () {
await this.token.setBaseURI(baseURI);
const newBaseURI = 'https://api.example.com/v2/';
await this.token.setBaseURI(newBaseURI);
expect(await this.token.tokenURI(firstTokenId)).to.equal(newBaseURI + firstTokenId.toString());
});
});
});
});
}

Loading…
Cancel
Save