Update docs

This commit is contained in:
github-actions
2025-04-22 16:39:54 +00:00
parent 0dda004024
commit da7fd0d3e5
230 changed files with 11375 additions and 1714 deletions

View File

@ -5,6 +5,8 @@ set -euo pipefail
export COVERAGE=true
export FOUNDRY_FUZZ_RUNS=10
. scripts/set-max-old-space-size.sh
# Hardhat coverage
hardhat coverage
@ -12,7 +14,11 @@ if [ "${CI:-"false"}" == "true" ]; then
# Foundry coverage
forge coverage --report lcov --ir-minimum
# Remove zero hits
sed -i '/,0/d' lcov.info
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' '/,0/d' lcov.info
else
sed -i '/,0/d' lcov.info
fi
fi
# Reports are then uploaded to Codecov automatically by workflow, and merged.

View File

@ -31,7 +31,7 @@ for (const artifact of artifacts) {
}
/// graphlib.alg.findCycles will not find minimal cycles.
/// We are only interested int cycles of lengths 2 (needs proof)
/// We are only interested in cycles of lengths 2 (needs proof)
graph.nodes().forEach((x, i, nodes) =>
nodes
.slice(i + 1)

View File

@ -31,7 +31,7 @@ for (const artifact of artifacts) {
const minVersion = semver.minVersion(pragma[source]);
// loop over all imports in source
for (const { absolutePath } of findAll('ImportDirective', solcOutput.sources[source].ast)) {
// So files that only import without declaring anything cause issues, because they don't shop in in "pragma"
// So files that only import without declaring anything cause issues, because they don't shop in "pragma"
if (!pragma[absolutePath]) continue;
// Check that the minVersion for source satisfies the requirements of the imported files
if (!semver.satisfies(minVersion, pragma[absolutePath])) {

View File

@ -0,0 +1,50 @@
#!/usr/bin/env node
// This script snapshots the bytecode and ABI for the `hardhat/common-contracts.js` script.
// - Bytecode is fetched directly from the blockchain by querying the provided client endpoint. If no endpoint is
// provided, ethers default provider is used instead.
// - ABI is fetched from etherscan's API using the provided etherscan API key. If no API key is provided, ABI will not
// be fetched and saved.
//
// The produced artifacts are stored in the `output` folder ('test/bin' by default). For each contract, two files are
// produced:
// - `<name>.bytecode` containing the contract bytecode (in binary encoding)
// - `<name>.abi` containing the ABI (in utf-8 encoding)
const fs = require('fs');
const path = require('path');
const { ethers } = require('ethers');
const { request } = require('undici');
const { hideBin } = require('yargs/helpers');
const { argv } = require('yargs/yargs')(hideBin(process.argv))
.env('')
.options({
output: { type: 'string', default: 'test/bin/' },
client: { type: 'string' },
etherscan: { type: 'string' },
});
// List of contract names and addresses to fetch
const config = {
EntryPoint070: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
SenderCreator070: '0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C',
EntryPoint080: '0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108',
SenderCreator080: '0x449ED7C3e6Fee6a97311d4b55475DF59C44AdD33',
};
Promise.all(
Object.entries(config).flatMap(([name, addr]) =>
Promise.all([
argv.etherscan &&
request(`https://api.etherscan.io/api?module=contract&action=getabi&address=${addr}&apikey=${argv.etherscan}`)
.then(({ body }) => body.json())
.then(({ result: abi }) => fs.writeFile(path.join(argv.output, `${name}.abi`), abi, 'utf-8', () => {})),
ethers
.getDefaultProvider(argv.client)
.getCode(addr)
.then(bytecode =>
fs.writeFile(path.join(argv.output, `${name}.bytecode`), ethers.getBytes(bytecode), 'binary', () => {}),
),
]),
),
);

View File

@ -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.
*/

View File

@ -119,7 +119,7 @@ function latestCheckpoint(${opts.historyTypeName} storage self) internal view re
}
/**
* @dev Returns the number of checkpoint.
* @dev Returns the number of checkpoints.
*/
function length(${opts.historyTypeName} storage self) internal view returns (uint256) {
return self.${opts.checkpointFieldName}.length;

View File

@ -14,7 +14,7 @@ import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol
const template = opts => `\
using Checkpoints for Checkpoints.${opts.historyTypeName};
// Maximum gap between keys used during the fuzzing tests: the \`_prepareKeys\` function with make sure that
// Maximum gap between keys used during the fuzzing tests: the \`_prepareKeys\` function will make sure that
// key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range.
uint8 internal constant _KEY_MAX_GAP = 64;
@ -36,7 +36,7 @@ function _prepareKeys(${opts.keyTypeName}[] memory keys, ${opts.keyTypeName} max
}
}
function _assertLatestCheckpoint(bool exist, ${opts.keyTypeName} key, ${opts.valueTypeName} value) internal {
function _assertLatestCheckpoint(bool exist, ${opts.keyTypeName} key, ${opts.valueTypeName} value) internal view {
(bool _exist, ${opts.keyTypeName} _key, ${opts.valueTypeName} _value) = _ckpts.latestCheckpoint();
assertEq(_exist, exist);
assertEq(_key, key);

View File

@ -17,6 +17,7 @@ import {EnumerableSet} from "./EnumerableSet.sol";
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
* - Map can be cleared (all entries removed) in O(n).
*
* \`\`\`solidity
* contract Example {
@ -91,6 +92,20 @@ function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (
return map._keys.remove(key);
}
/**
* @dev Removes all the entries from a map. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(Bytes32ToBytes32Map storage map) internal {
uint256 len = length(map);
for (uint256 i = 0; i < len; ++i) {
delete map._values[map._keys.at(i)];
}
map._keys.clear();
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
@ -188,6 +203,16 @@ function remove(${name} storage map, ${keyType} key) internal returns (bool) {
return remove(map._inner, ${toBytes32(keyType, 'key')});
}
/**
* @dev Removes all the entries from a map. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(${name} storage map) internal {
clear(map._inner);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/

View File

@ -5,6 +5,8 @@ const { TYPES } = require('./EnumerableSet.opts');
const header = `\
pragma solidity ^0.8.20;
import {Arrays} from "../Arrays.sol";
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
@ -15,6 +17,7 @@ pragma solidity ^0.8.20;
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
* - Set can be cleared (all elements removed) in O(n).
*
* \`\`\`solidity
* contract Example {
@ -117,6 +120,20 @@ function _remove(Set storage set, bytes32 value) private returns (bool) {
}
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function _clear(Set storage set) private {
uint256 len = _length(set);
for (uint256 i = 0; i < len; ++i) {
delete set._positions[set._values[i]];
}
Arrays.unsafeSetLength(set._values, 0);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
@ -185,6 +202,16 @@ function remove(${name} storage set, ${type} value) internal returns (bool) {
return _remove(set._inner, ${toBytes32(type, 'value')});
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(${name} storage set) internal {
_clear(set._inner);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/

View File

@ -20,7 +20,7 @@ pragma solidity ^0.8.20;
* using SlotDerivation for bytes32;
*
* // Declare a namespace
* string private constant _NAMESPACE = "<namespace>" // eg. OpenZeppelin.Slot
* string private constant _NAMESPACE = "<namespace>"; // eg. OpenZeppelin.Slot
*
* function setValueInNamespace(uint256 key, address newValue) internal {
* _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;

View File

@ -45,7 +45,7 @@ function _assertDeriveArray(uint256 length, uint256 offset) public {
const mapping = ({ type, name }) => `\
mapping(${type} => bytes) private _${type}Mapping;
function testSymbolicDeriveMapping${name}(${type} key) public {
function testSymbolicDeriveMapping${name}(${type} key) public view {
bytes32 baseSlot;
assembly {
baseSlot := _${type}Mapping.slot
@ -76,15 +76,15 @@ function testSymbolicDeriveMapping${name}Dirty(bytes32 dirtyKey) public {
const boundedMapping = ({ type, name }) => `\
mapping(${type} => bytes) private _${type}Mapping;
function testDeriveMapping${name}(${type} memory key) public {
function testDeriveMapping${name}(${type} memory key) public view {
_assertDeriveMapping${name}(key);
}
function symbolicDeriveMapping${name}() public {
function symbolicDeriveMapping${name}() public view {
_assertDeriveMapping${name}(svm.create${name}(256, "DeriveMapping${name}Input"));
}
function _assertDeriveMapping${name}(${type} memory key) internal {
function _assertDeriveMapping${name}(${type} memory key) internal view {
bytes32 baseSlot;
assembly {
baseSlot := _${type}Mapping.slot

View File

@ -34,7 +34,7 @@ pragma solidity ^0.8.24;
const udvt = ({ type, name }) => `\
/**
* @dev UDVT that represent a slot holding a ${type}.
* @dev UDVT that represents a slot holding ${type == 'address' ? 'an' : 'a'} ${type}.
*/
type ${name}Slot is bytes32;

View File

@ -18,7 +18,7 @@ examples_source_dir="contracts/mocks/docs"
examples_target_dir="docs/modules/api/examples"
for f in "$examples_source_dir"/**/*.sol; do
name="${f/#"$examples_source_dir/"/}"
name="${f/#"$examples_source_dir"/}"
mkdir -p "$examples_target_dir/$(dirname "$name")"
sed -Ee '/^import/s|"(\.\./)+|"@openzeppelin/contracts/|' "$f" > "$examples_target_dir/$name"
done

View File

@ -1,5 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
if git status &>/dev/null; then git config core.hooksPath .githooks; fi

View File

@ -27,7 +27,7 @@ const formatted = changelog
.replace(RELEASE_LINE_REGEX, (_, pr, entry) => (pr ? `- ${entry} (${pr})` : `- ${entry}`))
// Add date to new version
.replace(VERSION_TITLE_REGEX, `\n## $1 (${new Date().toISOString().split('T')[0]})`)
// Conditionally allow vX.Y.Z.rc-.W sections only in prerelease
// Conditionally allow vX.Y.Z-rc.W sections only in prerelease
.replace(/^## \d\.\d\.\d-rc\S+[^]+?(?=^#)/gm, section => (isPrerelease ? section : ''));
fs.writeFileSync('CHANGELOG.md', formatted);

View File

@ -0,0 +1,10 @@
#!/usr/bin/env sh
# This script sets the node `--max-old-space-size` to 8192 if it is not set already.
# All existing `NODE_OPTIONS` are retained as is.
export NODE_OPTIONS="${NODE_OPTIONS:-}"
if [ "${NODE_OPTIONS##*--max-old-space-size*}" = "$NODE_OPTIONS" ]; then
export NODE_OPTIONS="${NODE_OPTIONS} --max-old-space-size=8192"
fi

View File

@ -1,5 +1,8 @@
{
"name": "solhint-plugin-openzeppelin",
"version": "0.0.0",
"private": true
"private": true,
"dependencies": {
"minimatch": "^3.1.2"
}
}

View File

@ -59,7 +59,7 @@ index ff596b0c3..000000000
-<!-- Make sure that you have reviewed the OpenZeppelin Contracts Contributor Guidelines. -->
-<!-- https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CONTRIBUTING.md -->
diff --git a/README.md b/README.md
index fa7b4e31e..4799b6376 100644
index 60d0a430a..0e4f91a6d 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,9 @@
@ -110,7 +110,7 @@ index fa7b4e31e..4799b6376 100644
}
```
diff --git a/contracts/package.json b/contracts/package.json
index 845e8c403..8dc181b91 100644
index 3682eadeb..4f870d094 100644
--- a/contracts/package.json
+++ b/contracts/package.json
@@ -1,5 +1,5 @@
@ -118,7 +118,7 @@ index 845e8c403..8dc181b91 100644
- "name": "@openzeppelin/contracts",
+ "name": "@openzeppelin/contracts-upgradeable",
"description": "Secure Smart Contract library for Solidity",
"version": "5.0.2",
"version": "5.2.0",
"files": [
@@ -13,7 +13,7 @@
},
@ -140,7 +140,7 @@ index 845e8c403..8dc181b91 100644
+ }
}
diff --git a/contracts/utils/cryptography/EIP712.sol b/contracts/utils/cryptography/EIP712.sol
index 77c4c8990..602467f40 100644
index bcb67c87a..7195c3bbd 100644
--- a/contracts/utils/cryptography/EIP712.sol
+++ b/contracts/utils/cryptography/EIP712.sol
@@ -4,7 +4,6 @@
@ -151,7 +151,7 @@ index 77c4c8990..602467f40 100644
import {IERC5267} from "../../interfaces/IERC5267.sol";
/**
@@ -28,28 +27,18 @@ import {IERC5267} from "../../interfaces/IERC5267.sol";
@@ -28,30 +27,18 @@ import {IERC5267} from "../../interfaces/IERC5267.sol";
* NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
* separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
* separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
@ -177,14 +177,16 @@ index 77c4c8990..602467f40 100644
- ShortString private immutable _name;
- ShortString private immutable _version;
- // slither-disable-next-line constable-states
- string private _nameFallback;
- // slither-disable-next-line constable-states
- string private _versionFallback;
+ string private _name;
+ string private _version;
/**
* @dev Initializes the domain separator and parameter caches.
@@ -64,29 +53,23 @@ abstract contract EIP712 is IERC5267 {
@@ -66,29 +53,23 @@ abstract contract EIP712 is IERC5267 {
* contract upgrade].
*/
constructor(string memory name, string memory version) {
@ -222,7 +224,7 @@ index 77c4c8990..602467f40 100644
}
/**
@@ -125,6 +108,10 @@ abstract contract EIP712 is IERC5267 {
@@ -127,6 +108,10 @@ abstract contract EIP712 is IERC5267 {
uint256[] memory extensions
)
{
@ -233,7 +235,7 @@ index 77c4c8990..602467f40 100644
return (
hex"0f", // 01111
_EIP712Name(),
@@ -139,22 +126,62 @@ abstract contract EIP712 is IERC5267 {
@@ -141,22 +126,62 @@ abstract contract EIP712 is IERC5267 {
/**
* @dev The name parameter for the EIP712 domain.
*
@ -307,10 +309,10 @@ index 77c4c8990..602467f40 100644
}
}
diff --git a/package.json b/package.json
index c4b358e10..96ab2559c 100644
index f9e7d9205..c35020d51 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
@@ -34,7 +34,7 @@
},
"repository": {
"type": "git",