diff --git a/contracts/mocks/ERC1155Mock.sol b/contracts/mocks/ERC1155Mock.sol index e7b3c549a04..cc154212992 100644 --- a/contracts/mocks/ERC1155Mock.sol +++ b/contracts/mocks/ERC1155Mock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "../token/ERC1155/ERC1155.sol"; diff --git a/contracts/mocks/ERC1155ReceiverMock.sol b/contracts/mocks/ERC1155ReceiverMock.sol index ffbf9a5532d..86bfa167db3 100644 --- a/contracts/mocks/ERC1155ReceiverMock.sol +++ b/contracts/mocks/ERC1155ReceiverMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "../token/ERC1155/IERC1155Receiver.sol"; import "./ERC165Mock.sol"; @@ -34,6 +34,7 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock { bytes calldata data ) external + override returns(bytes4) { require(!_recReverts, "ERC1155ReceiverMock: reverting on receive"); @@ -49,6 +50,7 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock { bytes calldata data ) external + override returns(bytes4) { require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive"); diff --git a/contracts/token/ERC1155/ERC1155.sol b/contracts/token/ERC1155/ERC1155.sol index 1e6163f57cc..aa0d4aaed5e 100644 --- a/contracts/token/ERC1155/ERC1155.sol +++ b/contracts/token/ERC1155/ERC1155.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "./IERC1155.sol"; import "./IERC1155Receiver.sol"; @@ -24,17 +24,22 @@ contract ERC1155 is ERC165, IERC1155 // Mapping from account to operator approvals mapping (address => mapping(address => bool)) private _operatorApprovals; - constructor() - public - { - _registerInterface( - ERC1155(0).safeTransferFrom.selector ^ - ERC1155(0).safeBatchTransferFrom.selector ^ - ERC1155(0).balanceOf.selector ^ - ERC1155(0).balanceOfBatch.selector ^ - ERC1155(0).setApprovalForAll.selector ^ - ERC1155(0).isApprovedForAll.selector - ); + /* + * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e + * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4 + * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 + * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 + * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a + * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6 + * + * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^ + * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26 + */ + bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26; + + constructor() public { + // register the supported interfaces to conform to ERC1155 via ERC165 + _registerInterface(_INTERFACE_ID_ERC1155); } /** @@ -46,7 +51,7 @@ contract ERC1155 is ERC165, IERC1155 @param id ID of the token @return The account's balance of the token type requested */ - function balanceOf(address account, uint256 id) public view returns (uint256) { + function balanceOf(address account, uint256 id) public view override returns (uint256) { require(account != address(0), "ERC1155: balance query for the zero address"); return _balances[id][account]; } @@ -66,6 +71,7 @@ contract ERC1155 is ERC165, IERC1155 ) public view + override returns (uint256[] memory) { require(accounts.length == ids.length, "ERC1155: accounts and IDs must have same lengths"); @@ -91,7 +97,7 @@ contract ERC1155 is ERC165, IERC1155 * @param operator address to set the approval * @param approved representing the status of the approval to be set */ - function setApprovalForAll(address operator, bool approved) external { + function setApprovalForAll(address operator, bool approved) external override virtual { require(msg.sender != operator, "ERC1155: cannot set approval status for self"); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); @@ -103,7 +109,7 @@ contract ERC1155 is ERC165, IERC1155 @param operator Address of authorized operator @return True if the operator is approved, false if not */ - function isApprovedForAll(address account, address operator) public view returns (bool) { + function isApprovedForAll(address account, address operator) public view override returns (bool) { return _operatorApprovals[account][operator]; } @@ -125,6 +131,8 @@ contract ERC1155 is ERC165, IERC1155 bytes calldata data ) external + override + virtual { require(to != address(0), "ERC1155: target address must be non-zero"); require( @@ -159,6 +167,8 @@ contract ERC1155 is ERC165, IERC1155 bytes calldata data ) external + override + virtual { require(ids.length == values.length, "ERC1155: IDs and values must have same lengths"); require(to != address(0), "ERC1155: target address must be non-zero"); @@ -190,7 +200,7 @@ contract ERC1155 is ERC165, IERC1155 * @param value Amount of the token to be minted * @param data Data forwarded to `onERC1155Received` if `to` is a contract receiver */ - function _mint(address to, uint256 id, uint256 value, bytes memory data) internal { + function _mint(address to, uint256 id, uint256 value, bytes memory data) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); _balances[id][to] = _balances[id][to].add(value); @@ -206,7 +216,7 @@ contract ERC1155 is ERC165, IERC1155 * @param values Amounts of the tokens to be minted * @param data Data forwarded to `onERC1155Received` if `to` is a contract receiver */ - function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal { + function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal virtual { require(to != address(0), "ERC1155: batch mint to the zero address"); require(ids.length == values.length, "ERC1155: minted IDs and values must have same lengths"); @@ -225,7 +235,7 @@ contract ERC1155 is ERC165, IERC1155 * @param id ID of the token to be burnt * @param value Amount of the token to be burnt */ - function _burn(address account, uint256 id, uint256 value) internal { + function _burn(address account, uint256 id, uint256 value) internal virtual { require(account != address(0), "ERC1155: attempting to burn tokens on zero account"); _balances[id][account] = _balances[id][account].sub( @@ -241,7 +251,7 @@ contract ERC1155 is ERC165, IERC1155 * @param ids IDs of the tokens to be burnt * @param values Amounts of the tokens to be burnt */ - function _burnBatch(address account, uint256[] memory ids, uint256[] memory values) internal { + function _burnBatch(address account, uint256[] memory ids, uint256[] memory values) internal virtual { require(account != address(0), "ERC1155: attempting to burn batch of tokens on zero account"); require(ids.length == values.length, "ERC1155: burnt IDs and values must have same lengths"); @@ -264,6 +274,7 @@ contract ERC1155 is ERC165, IERC1155 bytes memory data ) internal + virtual { if(to.isContract()) { require( @@ -283,6 +294,7 @@ contract ERC1155 is ERC165, IERC1155 bytes memory data ) internal + virtual { if(to.isContract()) { require( diff --git a/contracts/token/ERC1155/ERC1155Holder.sol b/contracts/token/ERC1155/ERC1155Holder.sol index 465f8b60791..affd20b2f50 100644 --- a/contracts/token/ERC1155/ERC1155Holder.sol +++ b/contracts/token/ERC1155/ERC1155Holder.sol @@ -1,16 +1,16 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "./ERC1155Receiver.sol"; contract ERC1155Holder is ERC1155Receiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) external returns (bytes4) + function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override virtual returns (bytes4) { return this.onERC1155Received.selector; } - function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external returns (bytes4) + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override virtual returns (bytes4) { return this.onERC1155BatchReceived.selector; } diff --git a/contracts/token/ERC1155/ERC1155Receiver.sol b/contracts/token/ERC1155/ERC1155Receiver.sol index 87c4dcca0b1..7e903fa1c6c 100644 --- a/contracts/token/ERC1155/ERC1155Receiver.sol +++ b/contracts/token/ERC1155/ERC1155Receiver.sol @@ -1,9 +1,9 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "./IERC1155Receiver.sol"; import "../../introspection/ERC165.sol"; -contract ERC1155Receiver is ERC165, IERC1155Receiver { +abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { constructor() public { _registerInterface( ERC1155Receiver(0).onERC1155Received.selector ^ diff --git a/contracts/token/ERC1155/IERC1155.sol b/contracts/token/ERC1155/IERC1155.sol index 87bb10d9bb9..ad36cb5104e 100644 --- a/contracts/token/ERC1155/IERC1155.sol +++ b/contracts/token/ERC1155/IERC1155.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "../../introspection/IERC165.sol"; @@ -6,7 +6,7 @@ import "../../introspection/IERC165.sol"; @title ERC-1155 Multi Token Standard basic interface @dev See https://eips.ethereum.org/EIPS/eip-1155 */ -contract IERC1155 is IERC165 { +abstract contract IERC1155 is IERC165 { event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); @@ -15,15 +15,15 @@ contract IERC1155 is IERC165 { event URI(string value, uint256 indexed id); - function balanceOf(address account, uint256 id) public view returns (uint256); + function balanceOf(address account, uint256 id) public view virtual returns (uint256); - function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view returns (uint256[] memory); + function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual returns (uint256[] memory); - function setApprovalForAll(address operator, bool approved) external; + function setApprovalForAll(address operator, bool approved) external virtual; - function isApprovedForAll(address account, address operator) external view returns (bool); + function isApprovedForAll(address account, address operator) external view virtual returns (bool); - function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external; + function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external virtual; - function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external; + function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external virtual; } diff --git a/contracts/token/ERC1155/IERC1155Receiver.sol b/contracts/token/ERC1155/IERC1155Receiver.sol index 90f710972a2..02b053b38ed 100644 --- a/contracts/token/ERC1155/IERC1155Receiver.sol +++ b/contracts/token/ERC1155/IERC1155Receiver.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.6.0; import "../../introspection/IERC165.sol"; @@ -6,7 +6,7 @@ import "../../introspection/IERC165.sol"; @title ERC-1155 Multi Token Receiver Interface @dev See https://eips.ethereum.org/EIPS/eip-1155 */ -contract IERC1155Receiver is IERC165 { +interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is