Skip to content

Commit

Permalink
Merge branch 'master' into modular-exponentiation-precompile-wrapper-O…
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx committed Jan 25, 2024
2 parents 1583160 + b5a7f97 commit 19ead8e
Show file tree
Hide file tree
Showing 155 changed files with 8,946 additions and 13,300 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-cooks-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': patch
---

`Checkpoints`: Optimized checkpoint access by removing redundant memory usage.
5 changes: 5 additions & 0 deletions .changeset/cool-mangos-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`Math`: add an `invMod` function to get the modular multiplicative inverse of a number in Z/nZ.
5 changes: 5 additions & 0 deletions .changeset/friendly-nails-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`ERC1363`: Add implementation of the token payable standard allowing execution of contract code after transfers and approvals.
5 changes: 5 additions & 0 deletions .changeset/nice-paws-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`SafeERC20`: Add "relaxed" function for interacting with ERC-1363 functions in a way that is compatible with EOAs.
5 changes: 5 additions & 0 deletions .changeset/twenty-feet-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`Base64`: Add `encodeURL` following section 5 of RFC4648 for URL encoding
5 changes: 5 additions & 0 deletions .changeset/violet-moons-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`AccessControlEnumerable`: Add a `getRoleMembers` method to return all accounts that have `role`.
5 changes: 5 additions & 0 deletions .changeset/yellow-deers-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`EnumerableMap`: add `UintToBytes32Map`, `AddressToAddressMap`, `AddressToBytes32Map` and `Bytes32ToAddressMap`.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ about: Report a bug in OpenZeppelin Contracts

**💻 Environment**

<!-- Tell us what version of OpenZeppelin Contracts you're using, and how you're using it: Truffle, Remix, etc. -->
<!-- Tell us what version of OpenZeppelin Contracts you're using, and how you're using it: Hardhat, Remix, etc. -->

**📝 Details**

Expand Down
6 changes: 3 additions & 3 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Setup
runs:
using: composite
steps:
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 16.x
- uses: actions/cache@v3
node-version: 20.x
- uses: actions/cache@v4
id: cache
with:
path: '**/node_modules'
Expand Down
22 changes: 14 additions & 8 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ jobs:
runs-on: ubuntu-latest
env:
FORCE_COLOR: 1
# Needed for "eth-gas-reporter" to produce a "gasReporterOutput.json" as documented in
# https://github.com/cgewecke/eth-gas-reporter/blob/v0.2.27/docs/gasReporterOutput.md
CI: true
GAS: true
steps:
- uses: actions/checkout@v4
- name: Set up environment
uses: ./.github/actions/setup
- name: Compile contracts # TODO: Remove after migrating tests to ethers
run: npm run compile
- name: Run tests and generate gas report
run: npm run test
- name: Check linearisation of the inheritance graph
Expand All @@ -44,7 +45,6 @@ jobs:
run: npm run test:generation
- name: Compare gas costs
uses: ./.github/actions/gas-compare
if: github.base_ref == 'master'
with:
token: ${{ github.token }}

Expand All @@ -64,15 +64,12 @@ jobs:
cp -rnT contracts lib/openzeppelin-contracts/contracts
- name: Transpile to upgradeable
run: bash scripts/upgradeable/transpile.sh
- name: Compile contracts # TODO: Remove after migrating tests to ethers
run: npm run compile
- name: Run tests
run: npm run test
- name: Check linearisation of the inheritance graph
run: npm run test:inheritance
- name: Check storage layout
uses: ./.github/actions/storage-layout
if: github.base_ref == 'master'
continue-on-error: ${{ contains(github.event.pull_request.labels.*.name, 'breaking change') }}
with:
token: ${{ github.token }}
Expand All @@ -94,14 +91,23 @@ jobs:
- uses: actions/checkout@v4
- name: Set up environment
uses: ./.github/actions/setup
- name: Compile contracts # TODO: Remove after migrating tests to ethers
run: npm run compile
- name: Run coverage
run: npm run coverage
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}

harnesses:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up environment
uses: ./.github/actions/setup
- name: Compile harnesses
run: |
make -C certora apply
npm run compile:harnesses
slither:
runs-on: ubuntu-latest
steps:
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/release-cycle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
env:
PRERELEASE: ${{ needs.state.outputs.is_prerelease }}
- name: Upload tarball artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ github.ref_name }}
path: ${{ steps.pack.outputs.tarball }}
Expand All @@ -170,9 +170,7 @@ jobs:
- uses: actions/checkout@v4
- name: Download tarball artifact
id: artifact
# Replace with actions/upload-artifact@v3 when
# https://github.com/actions/download-artifact/pull/194 gets released
uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b
uses: actions/download-artifact@v4
with:
name: ${{ github.ref_name }}
- name: Check integrity
Expand Down
6 changes: 0 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,9 @@ npm-debug.log
# local env variables
.env

# truffle build directory
build/

# macOS
.DS_Store

# truffle
.node-xmlhttprequest-*

# IntelliJ IDE
.idea

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

### Installation

#### Hardhat, Truffle (npm)
#### Hardhat (npm)

```
$ npm install @openzeppelin/contracts
Expand Down
4 changes: 2 additions & 2 deletions certora/harnesses/EnumerableMapHarness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract EnumerableMapHarness {
return _map.get(key);
}

function _indexOf(bytes32 key) public view returns (uint256) {
return _map._keys._inner._indexes[key];
function _positionOf(bytes32 key) public view returns (uint256) {
return _map._keys._inner._positions[key];
}
}
4 changes: 2 additions & 2 deletions certora/harnesses/EnumerableSetHarness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract EnumerableSetHarness {
return _set.at(index);
}

function _indexOf(bytes32 value) public view returns (uint256) {
return _set._inner._indexes[value];
function _positionOf(bytes32 value) public view returns (uint256) {
return _set._inner._positions[value];
}
}
20 changes: 10 additions & 10 deletions certora/specs/EnumerableMap.spec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ methods {
function get(bytes32) external returns (bytes32) envfree;

// FV
function _indexOf(bytes32) external returns (uint256) envfree;
function _positionOf(bytes32) external returns (uint256) envfree;
}

/*
Expand Down Expand Up @@ -69,13 +69,13 @@ invariant atUniqueness(uint256 index1, uint256 index2)
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
Invariant: index <> value relationship is consistent
│ │
Note that the two consistencyXxx invariants, put together, prove that at_ and _indexOf are inverse of one another.
This proves that we have a bijection between indices (the enumerability part) and keys (the entries that are set
and removed from the EnumerableMap).
Note that the two consistencyXxx invariants, put together, prove that at_ and _positionOf are inverse of one
another. This proves that we have a bijection between indices (the enumerability part) and keys (the entries that
are set and removed from the EnumerableMap). │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
invariant consistencyIndex(uint256 index)
index < length() => to_mathint(_indexOf(key_at(index))) == index + 1
index < length() => to_mathint(_positionOf(key_at(index))) == index + 1
{
preserved remove(bytes32 key) {
requireInvariant consistencyIndex(require_uint256(length() - 1));
Expand All @@ -84,16 +84,16 @@ invariant consistencyIndex(uint256 index)

invariant consistencyKey(bytes32 key)
contains(key) => (
_indexOf(key) > 0 &&
_indexOf(key) <= length() &&
key_at(require_uint256(_indexOf(key) - 1)) == key
_positionOf(key) > 0 &&
_positionOf(key) <= length() &&
key_at(require_uint256(_positionOf(key) - 1)) == key
)
{
preserved remove(bytes32 otherKey) {
requireInvariant consistencyKey(otherKey);
requireInvariant atUniqueness(
require_uint256(_indexOf(key) - 1),
require_uint256(_indexOf(otherKey) - 1)
require_uint256(_positionOf(key) - 1),
require_uint256(_positionOf(otherKey) - 1)
);
}
}
Expand Down
20 changes: 10 additions & 10 deletions certora/specs/EnumerableSet.spec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ methods {
function at_(uint256) external returns (bytes32) envfree;

// FV
function _indexOf(bytes32) external returns (uint256) envfree;
function _positionOf(bytes32) external returns (uint256) envfree;
}

/*
Expand Down Expand Up @@ -52,13 +52,13 @@ invariant atUniqueness(uint256 index1, uint256 index2)
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
Invariant: index <> key relationship is consistent
│ │
Note that the two consistencyXxx invariants, put together, prove that at_ and _indexOf are inverse of one another.
This proves that we have a bijection between indices (the enumerability part) and keys (the entries that are added
and removed from the EnumerableSet).
Note that the two consistencyXxx invariants, put together, prove that at_ and _positionOf are inverse of one
another. This proves that we have a bijection between indices (the enumerability part) and keys (the entries that
are added and removed from the EnumerableSet). │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
invariant consistencyIndex(uint256 index)
index < length() => _indexOf(at_(index)) == require_uint256(index + 1)
index < length() => _positionOf(at_(index)) == require_uint256(index + 1)
{
preserved remove(bytes32 key) {
requireInvariant consistencyIndex(require_uint256(length() - 1));
Expand All @@ -67,16 +67,16 @@ invariant consistencyIndex(uint256 index)

invariant consistencyKey(bytes32 key)
contains(key) => (
_indexOf(key) > 0 &&
_indexOf(key) <= length() &&
at_(require_uint256(_indexOf(key) - 1)) == key
_positionOf(key) > 0 &&
_positionOf(key) <= length() &&
at_(require_uint256(_positionOf(key) - 1)) == key
)
{
preserved remove(bytes32 otherKey) {
requireInvariant consistencyKey(otherKey);
requireInvariant atUniqueness(
require_uint256(_indexOf(key) - 1),
require_uint256(_indexOf(otherKey) - 1)
require_uint256(_positionOf(key) - 1),
require_uint256(_positionOf(otherKey) - 1)
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion contracts/access/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/

This directory provides ways to restrict who can access the functions of a contract or when they can do it.

- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
- {AccessManager} is a full-fledged access control solution for smart contract systems. Allows creating and assigning multiple hierarchical roles with execution delays for each account across various contracts.
- {AccessManaged} delegates its access control to an authority that dictates the permissions of the managed contract. It's compatible with an AccessManager as an authority.
- {AccessControl} provides a per-contract role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts within the same instance.
- {Ownable} is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it.
== Core
Expand Down
12 changes: 12 additions & 0 deletions contracts/access/extensions/AccessControlEnumerable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon
return _roleMembers[role].length();
}

/**
* @dev Return all accounts that have `role`
*
* WARNING: This operation will copy the entire 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 set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {
return _roleMembers[role].values();
}

/**
* @dev Overload {AccessControl-_grantRole} to track enumerable memberships
*/
Expand Down
13 changes: 10 additions & 3 deletions contracts/access/manager/IAccessManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,16 @@ interface IAccessManager {
* [2] Pending execution delay for the account.
* [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.
*/
function getAccess(uint64 roleId, address account) external view returns (uint48, uint32, uint32, uint48);
function getAccess(
uint64 roleId,
address account
) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);

/**
* @dev Check if a given account currently has the permission level corresponding to a given role. Note that this
* permission might be associated with an execution delay. {getAccess} can provide more details.
*/
function hasRole(uint64 roleId, address account) external view returns (bool, uint32);
function hasRole(uint64 roleId, address account) external view returns (bool isMember, uint32 executionDelay);

/**
* @dev Give a label to a role, for improved role discoverability by UIs.
Expand Down Expand Up @@ -340,7 +343,11 @@ interface IAccessManager {
* this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target
* contract if it is using standard Solidity ABI encoding.
*/
function schedule(address target, bytes calldata data, uint48 when) external returns (bytes32, uint32);
function schedule(
address target,
bytes calldata data,
uint48 when
) external returns (bytes32 operationId, uint32 nonce);

/**
* @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the
Expand Down
4 changes: 4 additions & 0 deletions contracts/governance/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Counting modules determine valid voting options.

Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed.

* {GovernorTimelockAccess}: Connects with an instance of an {AccessManager}. This allows restrictions (and delays) enforced by the manager to be considered by the Governor and integrated into the AccessManager's "schedule + execute" workflow.

* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself.

* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract.
Expand Down Expand Up @@ -66,6 +68,8 @@ NOTE: Functions of the `Governor` contract do not include access control. If you

=== Extensions

{{GovernorTimelockAccess}}

{{GovernorTimelockControl}}

{{GovernorTimelockCompound}}
Expand Down
3 changes: 3 additions & 0 deletions contracts/governance/extensions/GovernorTimelockAccess.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {Time} from "../../utils/types/Time.sol";
* mitigate this attack vector, the governor is able to ignore the restrictions claimed by the `AccessManager` using
* {setAccessManagerIgnored}. While permanent denial of service is mitigated, temporary DoS may still be technically
* possible. All of the governor's own functions (e.g., {setBaseDelaySeconds}) ignore the `AccessManager` by default.
*
* NOTE: `AccessManager` does not support scheduling more than one operation with the same target and calldata at
* the same time. See {AccessManager-schedule} for a workaround.
*/
abstract contract GovernorTimelockAccess is Governor {
// An execution plan is produced at the moment a proposal is created, in order to fix at that point the exact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {SafeCast} from "../../utils/math/SafeCast.sol";
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
* inaccessible from a proposal, unless executed via {Governor-relay}.
*/
abstract contract GovernorTimelockCompound is Governor {
ICompoundTimelock private _timelock;
Expand Down
Loading

0 comments on commit 19ead8e

Please sign in to comment.