Skip to content

Commit

Permalink
Port ERC 1155 branch to Solidity 0.6 (and current master) (#2130)
Browse files Browse the repository at this point in the history
* port ERC1155 to Solidity 0.6

* make ERC1155 constructor more similar to ERC721 one

* also migrate mock contracts to Solidity 0.6

* mark all non-view functions as virtual
  • Loading branch information
KaiRo-at authored Apr 27, 2020
1 parent c3f4ae3 commit 5fd36e7
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 36 deletions.
2 changes: 1 addition & 1 deletion contracts/mocks/ERC1155Mock.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "../token/ERC1155/ERC1155.sol";

Expand Down
4 changes: 3 additions & 1 deletion contracts/mocks/ERC1155ReceiverMock.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "../token/ERC1155/IERC1155Receiver.sol";
import "./ERC165Mock.sol";
Expand Down Expand Up @@ -34,6 +34,7 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock {
bytes calldata data
)
external
override
returns(bytes4)
{
require(!_recReverts, "ERC1155ReceiverMock: reverting on receive");
Expand All @@ -49,6 +50,7 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock {
bytes calldata data
)
external
override
returns(bytes4)
{
require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive");
Expand Down
50 changes: 31 additions & 19 deletions contracts/token/ERC1155/ERC1155.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
Expand All @@ -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);
}

/**
Expand All @@ -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];
}
Expand All @@ -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");
Expand All @@ -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);
Expand All @@ -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];
}

Expand All @@ -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(
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand All @@ -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");

Expand All @@ -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(
Expand All @@ -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");

Expand All @@ -264,6 +274,7 @@ contract ERC1155 is ERC165, IERC1155
bytes memory data
)
internal
virtual
{
if(to.isContract()) {
require(
Expand All @@ -283,6 +294,7 @@ contract ERC1155 is ERC165, IERC1155
bytes memory data
)
internal
virtual
{
if(to.isContract()) {
require(
Expand Down
6 changes: 3 additions & 3 deletions contracts/token/ERC1155/ERC1155Holder.sol
Original file line number Diff line number Diff line change
@@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/token/ERC1155/ERC1155Receiver.sol
Original file line number Diff line number Diff line change
@@ -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 ^
Expand Down
16 changes: 8 additions & 8 deletions contracts/token/ERC1155/IERC1155.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

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);
Expand All @@ -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;
}
4 changes: 2 additions & 2 deletions contracts/token/ERC1155/IERC1155Receiver.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

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
Expand Down

0 comments on commit 5fd36e7

Please sign in to comment.