Skip to content

Commit

Permalink
Merge branch 'master' into feature/_setApprovalForAll
Browse files Browse the repository at this point in the history
  • Loading branch information
frangio committed Oct 6, 2021
2 parents 50ee070 + e2fa301 commit 8f47039
Show file tree
Hide file tree
Showing 24 changed files with 23,941 additions and 1,890 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,8 +2,20 @@

## Unreleased

* `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
* `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
* `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
* `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2852))
* Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834))

## 4.3.2 (2021-09-14)

* `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular.

## 4.3.1 (2021-08-26)

* `TimelockController`: Add additional isOperationReady check.

## 4.3.0 (2021-08-17)

* `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754))
Expand Down Expand Up @@ -99,6 +111,14 @@ Make sure you're using git or another version control system to be able to recov

Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section.

## 3.4.2

* `TimelockController`: Add additional isOperationReady check.

## 3.4.1 (2021-03-03)

* `ERC721`: made `_approve` an internal function (was private).

## 3.4.0 (2021-02-02)

* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
Expand Down
18 changes: 15 additions & 3 deletions contracts/access/AccessControl.sol
Expand Up @@ -150,7 +150,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
* 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 granted `role`, emits a {RoleRevoked}
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
Expand Down Expand Up @@ -178,6 +178,8 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
Expand All @@ -194,14 +196,24 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}

function _grantRole(bytes32 role, address account) private {
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}

function _revokeRole(bytes32 role, address account) private {
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
Expand Down
12 changes: 8 additions & 4 deletions contracts/access/Ownable.sol
Expand Up @@ -25,7 +25,7 @@ abstract contract Ownable is Context {
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(_msgSender());
_transferOwnership(_msgSender());
}

/**
Expand All @@ -51,7 +51,7 @@ abstract contract Ownable is Context {
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
_transferOwnership(address(0));
}

/**
Expand All @@ -60,10 +60,14 @@ abstract contract Ownable is Context {
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
_transferOwnership(newOwner);
}

function _setOwner(address newOwner) private {
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
Expand Down
7 changes: 7 additions & 0 deletions contracts/governance/Governor.sol
Expand Up @@ -55,6 +55,13 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor {
_name = name_;
}

/**
* @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)
*/
receive() external payable virtual {
require(_executor() == address(this));
}

/**
* @dev See {IERC165-supportsInterface}.
*/
Expand Down
7 changes: 4 additions & 3 deletions contracts/governance/TimelockController.sol
Expand Up @@ -268,7 +268,7 @@ contract TimelockController is AccessControl {
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_beforeCall(predecessor);
_beforeCall(id, predecessor);
_call(id, 0, target, value, data);
_afterCall(id);
}
Expand All @@ -293,7 +293,7 @@ contract TimelockController is AccessControl {
require(targets.length == datas.length, "TimelockController: length mismatch");

bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_beforeCall(predecessor);
_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], datas[i]);
}
Expand All @@ -303,7 +303,8 @@ contract TimelockController is AccessControl {
/**
* @dev Checks before execution of an operation's calls.
*/
function _beforeCall(bytes32 predecessor) private view {
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
require(isOperationReady(id), "TimelockController: operation is not ready");
require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/governance/extensions/GovernorCountingSimple.sol
Expand Up @@ -70,7 +70,7 @@ abstract contract GovernorCountingSimple is Governor {
}

/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes.
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
Expand Down
3 changes: 2 additions & 1 deletion contracts/governance/extensions/GovernorTimelockCompound.sol
Expand Up @@ -177,8 +177,9 @@ abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor {
) internal virtual override {
uint256 eta = proposalEta(proposalId);
require(eta > 0, "GovernorTimelockCompound: proposal not yet queued");
Address.sendValue(payable(_timelock), msg.value);
for (uint256 i = 0; i < targets.length; ++i) {
_timelock.executeTransaction{value: values[i]}(targets[i], values[i], "", calldatas[i], eta);
_timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta);
}
}

Expand Down
2 changes: 0 additions & 2 deletions contracts/mocks/GovernorCompMock.sol
Expand Up @@ -20,8 +20,6 @@ contract GovernorCompMock is Governor, GovernorVotesComp, GovernorCountingSimple
_votingPeriod = votingPeriod_;
}

receive() external payable {}

function votingDelay() public view override returns (uint256) {
return _votingDelay;
}
Expand Down
2 changes: 0 additions & 2 deletions contracts/mocks/GovernorMock.sol
Expand Up @@ -21,8 +21,6 @@ contract GovernorMock is Governor, GovernorVotesQuorumFraction, GovernorCounting
_votingPeriod = votingPeriod_;
}

receive() external payable {}

function votingDelay() public view override returns (uint256) {
return _votingDelay;
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/package.json
@@ -1,7 +1,7 @@
{
"name": "@openzeppelin/contracts",
"description": "Secure Smart Contract library for Solidity",
"version": "4.3.0",
"version": "4.3.2",
"files": [
"**/*.sol",
"/build/contracts/*.json",
Expand Down
15 changes: 15 additions & 0 deletions contracts/proxy/utils/Initializable.sol
Expand Up @@ -13,6 +13,21 @@ pragma solidity ^0.8.0;
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
Expand Down
22 changes: 19 additions & 3 deletions contracts/proxy/utils/UUPSUpgradeable.sol
Expand Up @@ -17,16 +17,32 @@ import "../ERC1967/ERC1967Upgrade.sol";
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is ERC1967Upgrade {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);

/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}

/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual {
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, bytes(""), false);
_upgradeToAndCallSecure(newImplementation, new bytes(0), false);
}

/**
Expand All @@ -37,7 +53,7 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual {
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, data, true);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/security/ReentrancyGuard.sol
Expand Up @@ -43,7 +43,7 @@ abstract contract ReentrancyGuard {
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
Expand Down

0 comments on commit 8f47039

Please sign in to comment.