diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fdad388f..c34b77146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 4.3.3 + + * `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. diff --git a/contracts/mocks/ERC1155SupplyMock.sol b/contracts/mocks/ERC1155SupplyMock.sol index 96b436ae5..44b208007 100644 --- a/contracts/mocks/ERC1155SupplyMock.sol +++ b/contracts/mocks/ERC1155SupplyMock.sol @@ -8,37 +8,14 @@ import "../token/ERC1155/extensions/ERC1155Supply.sol"; contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply { constructor(string memory uri) ERC1155Mock(uri) {} - function _mint( - address account, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual override(ERC1155, ERC1155Supply) { - super._mint(account, id, amount, data); - } - - function _mintBatch( + function _beforeTokenTransfer( + address operator, + address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override(ERC1155, ERC1155Supply) { - super._mintBatch(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); + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); } } diff --git a/contracts/token/ERC1155/extensions/ERC1155Supply.sol b/contracts/token/ERC1155/extensions/ERC1155Supply.sol index 2f6838815..26a766193 100644 --- a/contracts/token/ERC1155/extensions/ERC1155Supply.sol +++ b/contracts/token/ERC1155/extensions/ERC1155Supply.sol @@ -30,56 +30,28 @@ abstract contract ERC1155Supply is ERC1155 { } /** - * @dev See {ERC1155-_mint}. + * @dev See {ERC1155-_beforeTokenTransfer}. */ - function _mint( - address account, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual override { - super._mint(account, id, amount, data); - _totalSupply[id] += amount; - } - - /** - * @dev See {ERC1155-_mintBatch}. - */ - function _mintBatch( + function _beforeTokenTransfer( + address operator, + address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override { - super._mintBatch(to, ids, amounts, data); - for (uint256 i = 0; i < ids.length; ++i) { - _totalSupply[ids[i]] += amounts[i]; - } - } + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - /** - * @dev See {ERC1155-_burn}. - */ - function _burn( - address account, - uint256 id, - uint256 amount - ) internal virtual override { - super._burn(account, id, amount); - _totalSupply[id] -= amount; - } + if (from == address(0)) { + for (uint256 i = 0; i < ids.length; ++i) { + _totalSupply[ids[i]] += amounts[i]; + } + } - /** - * @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]; + if (to == address(0)) { + for (uint256 i = 0; i < ids.length; ++i) { + _totalSupply[ids[i]] -= amounts[i]; + } } } }