Compare commits

...

6 Commits

Author SHA1 Message Date
8d7a871609 4.3.3 2021-11-11 13:04:38 -03:00
c9acfb3c23 Fix ERC1155 supply tracking (#2956)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
(cherry picked from commit 4088540aef)
2021-11-08 19:22:25 -03:00
0c4de6721d 4.3.2 2021-09-14 18:06:39 -03:00
024cc50df4 Restrict upgrade to proxy context in UUPSUpgradeable
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
(cherry picked from commit 6241995ad3)
2021-09-14 18:06:00 -03:00
6edb6dd1ca 4.3.1 2021-08-26 17:59:03 -03:00
0ec7f4c25d Add additional isOperationReady check in TimelockController
(cherry picked from commit cec4f2ef57)
2021-08-24 16:23:37 -03:00
8 changed files with 57 additions and 79 deletions

View File

@ -1,5 +1,17 @@
# Changelog # Changelog
## 4.3.3 (2021-11-11)
* `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls.
## 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) ## 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)) * `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))

View File

@ -268,7 +268,7 @@ contract TimelockController is AccessControl {
bytes32 salt bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt); bytes32 id = hashOperation(target, value, data, predecessor, salt);
_beforeCall(predecessor); _beforeCall(id, predecessor);
_call(id, 0, target, value, data); _call(id, 0, target, value, data);
_afterCall(id); _afterCall(id);
} }
@ -293,7 +293,7 @@ contract TimelockController is AccessControl {
require(targets.length == datas.length, "TimelockController: length mismatch"); require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt); bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_beforeCall(predecessor); _beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) { for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], datas[i]); _call(id, i, targets[i], values[i], datas[i]);
} }
@ -303,7 +303,8 @@ contract TimelockController is AccessControl {
/** /**
* @dev Checks before execution of an operation's calls. * @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"); require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
} }

View File

@ -8,37 +8,14 @@ import "../token/ERC1155/extensions/ERC1155Supply.sol";
contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply { contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply {
constructor(string memory uri) ERC1155Mock(uri) {} constructor(string memory uri) ERC1155Mock(uri) {}
function _mint( function _beforeTokenTransfer(
address account, address operator,
uint256 id, address from,
uint256 amount,
bytes memory data
) internal virtual override(ERC1155, ERC1155Supply) {
super._mint(account, id, amount, data);
}
function _mintBatch(
address to, address to,
uint256[] memory ids, uint256[] memory ids,
uint256[] memory amounts, uint256[] memory amounts,
bytes memory data bytes memory data
) internal virtual override(ERC1155, ERC1155Supply) { ) internal virtual override(ERC1155, ERC1155Supply) {
super._mintBatch(to, ids, amounts, data); super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
function _burn(
address account,
uint256 id,
uint256 amount
) internal virtual override(ERC1155, ERC1155Supply) {
super._burn(account, id, amount);
}
function _burnBatch(
address account,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual override(ERC1155, ERC1155Supply) {
super._burnBatch(account, ids, amounts);
} }
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@openzeppelin/contracts", "name": "@openzeppelin/contracts",
"description": "Secure Smart Contract library for Solidity", "description": "Secure Smart Contract library for Solidity",
"version": "4.3.0", "version": "4.3.3",
"files": [ "files": [
"**/*.sol", "**/*.sol",
"/build/contracts/*.json", "/build/contracts/*.json",

View File

@ -17,6 +17,22 @@ import "../ERC1967/ERC1967Upgrade.sol";
* _Available since v4.1._ * _Available since v4.1._
*/ */
abstract contract UUPSUpgradeable is ERC1967Upgrade { 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`. * @dev Upgrade the implementation of the proxy to `newImplementation`.
* *
@ -24,9 +40,9 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
* *
* Emits an {Upgraded} event. * Emits an {Upgraded} event.
*/ */
function upgradeTo(address newImplementation) external virtual { function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation); _authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, bytes(""), false); _upgradeToAndCallSecure(newImplementation, new bytes(0), false);
} }
/** /**
@ -37,7 +53,7 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
* *
* Emits an {Upgraded} event. * 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); _authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, data, true); _upgradeToAndCallSecure(newImplementation, data, true);
} }

View File

@ -30,56 +30,28 @@ abstract contract ERC1155Supply is ERC1155 {
} }
/** /**
* @dev See {ERC1155-_mint}. * @dev See {ERC1155-_beforeTokenTransfer}.
*/ */
function _mint( function _beforeTokenTransfer(
address account, address operator,
uint256 id, address from,
uint256 amount,
bytes memory data
) internal virtual override {
super._mint(account, id, amount, data);
_totalSupply[id] += amount;
}
/**
* @dev See {ERC1155-_mintBatch}.
*/
function _mintBatch(
address to, address to,
uint256[] memory ids, uint256[] memory ids,
uint256[] memory amounts, uint256[] memory amounts,
bytes memory data bytes memory data
) internal virtual override { ) internal virtual override {
super._mintBatch(to, ids, amounts, data); super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i]; if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
} }
}
/** if (to == address(0)) {
* @dev See {ERC1155-_burn}. for (uint256 i = 0; i < ids.length; ++i) {
*/ _totalSupply[ids[i]] -= amounts[i];
function _burn( }
address account,
uint256 id,
uint256 amount
) internal virtual override {
super._burn(account, id, amount);
_totalSupply[id] -= amount;
}
/**
* @dev See {ERC1155-_burnBatch}.
*/
function _burnBatch(
address account,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual override {
super._burnBatch(account, ids, amounts);
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] -= amounts[i];
} }
} }
} }

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "openzeppelin-solidity", "name": "openzeppelin-solidity",
"version": "4.3.0", "version": "4.3.3",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "openzeppelin-solidity", "name": "openzeppelin-solidity",
"version": "4.3.0-rc.0", "version": "4.3.3",
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js"

View File

@ -1,7 +1,7 @@
{ {
"name": "openzeppelin-solidity", "name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity", "description": "Secure Smart Contract library for Solidity",
"version": "4.3.0", "version": "4.3.3",
"files": [ "files": [
"/contracts/**/*.sol", "/contracts/**/*.sol",
"/build/contracts/*.json", "/build/contracts/*.json",