Basic ERC1155 Implementation. Derived from reference implementation, with bug fixes.
This commit is contained in:
161
contracts/erc1155/contracts/src/ERC1155.sol
Normal file
161
contracts/erc1155/contracts/src/ERC1155.sol
Normal file
@@ -0,0 +1,161 @@
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
import "./lib/SafeMath.sol";
|
||||
import "./lib/Address.sol";
|
||||
import "./interfaces/IERC1155.sol";
|
||||
import "./interfaces/IERC1155Receiver.sol";
|
||||
|
||||
|
||||
// A sample implementation of core ERC1155 function.
|
||||
contract ERC1155 is
|
||||
IERC1155,
|
||||
SafeMath
|
||||
{
|
||||
using Address for address;
|
||||
|
||||
bytes4 constant public ERC1155_RECEIVED = 0xf23a6e61;
|
||||
bytes4 constant public ERC1155_BATCH_RECEIVED = 0xbc197c81;
|
||||
|
||||
// id => (owner => balance)
|
||||
mapping (uint256 => mapping(address => uint256)) internal balances;
|
||||
|
||||
// owner => (operator => approved)
|
||||
mapping (address => mapping(address => bool)) internal operatorApproval;
|
||||
|
||||
// Use a split bit implementation.
|
||||
// Store the type in the upper 128 bits..
|
||||
uint256 constant TYPE_MASK = uint256(uint128(~0)) << 128;
|
||||
|
||||
// ..and the non-fungible index in the lower 128
|
||||
uint256 constant NF_INDEX_MASK = uint128(~0);
|
||||
|
||||
// The top bit is a flag to tell if this is a NFI.
|
||||
uint256 constant TYPE_NF_BIT = 1 << 255;
|
||||
|
||||
mapping (uint256 => address) nfOwners;
|
||||
|
||||
// Only to make code clearer. Should not be functions
|
||||
function isNonFungible(uint256 _id) public pure returns(bool) {
|
||||
return _id & TYPE_NF_BIT == TYPE_NF_BIT;
|
||||
}
|
||||
function isFungible(uint256 _id) public pure returns(bool) {
|
||||
return _id & TYPE_NF_BIT == 0;
|
||||
}
|
||||
function getNonFungibleIndex(uint256 _id) public pure returns(uint256) {
|
||||
return _id & NF_INDEX_MASK;
|
||||
}
|
||||
function getNonFungibleBaseType(uint256 _id) public pure returns(uint256) {
|
||||
return _id & TYPE_MASK;
|
||||
}
|
||||
function isNonFungibleBaseType(uint256 _id) public pure returns(bool) {
|
||||
// A base type has the NF bit but does not have an index.
|
||||
return (_id & TYPE_NF_BIT == TYPE_NF_BIT) && (_id & NF_INDEX_MASK == 0);
|
||||
}
|
||||
function isNonFungibleItem(uint256 _id) public pure returns(bool) {
|
||||
// A base type has the NF bit but does has an index.
|
||||
return (_id & TYPE_NF_BIT == TYPE_NF_BIT) && (_id & NF_INDEX_MASK != 0);
|
||||
}
|
||||
function ownerOf(uint256 _id) public view returns (address) {
|
||||
return nfOwners[_id];
|
||||
}
|
||||
|
||||
// overide
|
||||
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external {
|
||||
|
||||
require(_to != address(0x0), "cannot send to zero address");
|
||||
require(_from == msg.sender || operatorApproval[_from][msg.sender] == true, "Need operator approval for 3rd party transfers.");
|
||||
|
||||
if (isNonFungible(_id)) {
|
||||
require(nfOwners[_id] == _from);
|
||||
nfOwners[_id] = _to;
|
||||
// You could keep balance of NF type in base type id like so:
|
||||
// uint256 baseType = getNonFungibleBaseType(_id);
|
||||
// balances[baseType][_from] = balances[baseType][_from].safeSub(_value);
|
||||
// balances[baseType][_to] = balances[baseType][_to].safeAdd(_value);
|
||||
} else {
|
||||
balances[_id][_from] = safeSub(balances[_id][_from], _value);
|
||||
balances[_id][_to] = safeAdd(balances[_id][_to], _value);
|
||||
}
|
||||
|
||||
emit TransferSingle(msg.sender, _from, _to, _id, _value);
|
||||
|
||||
if (_to.isContract()) {
|
||||
require(IERC1155Receiver(_to).onERC1155Received(msg.sender, _from, _id, _value, _data) == ERC1155_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
// overide
|
||||
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external {
|
||||
|
||||
require(_to != address(0x0), "cannot send to zero address");
|
||||
require(_ids.length == _values.length, "Array length must match");
|
||||
|
||||
// Only supporting a global operator approval allows us to do only 1 check and not to touch storage to handle allowances.
|
||||
require(_from == msg.sender || operatorApproval[_from][msg.sender] == true, "Need operator approval for 3rd party transfers.");
|
||||
|
||||
for (uint256 i = 0; i < _ids.length; ++i) {
|
||||
// Cache value to local variable to reduce read costs.
|
||||
uint256 id = _ids[i];
|
||||
uint256 value = _values[i];
|
||||
|
||||
if (isNonFungible(id)) {
|
||||
require(nfOwners[id] == _from);
|
||||
nfOwners[id] = _to;
|
||||
} else {
|
||||
balances[id][_from] = safeSub(balances[id][_from], value);
|
||||
balances[id][_to] = safeAdd(value, balances[id][_to]);
|
||||
}
|
||||
}
|
||||
|
||||
emit TransferBatch(msg.sender, _from, _to, _ids, _values);
|
||||
|
||||
if (_to.isContract()) {
|
||||
require(IERC1155Receiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _values, _data) == ERC1155_BATCH_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
function balanceOf(address _owner, uint256 _id) external view returns (uint256) {
|
||||
if (isNonFungibleItem(_id))
|
||||
return nfOwners[_id] == _owner ? 1 : 0;
|
||||
return balances[_id][_owner];
|
||||
}
|
||||
|
||||
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory) {
|
||||
|
||||
require(_owners.length == _ids.length);
|
||||
|
||||
uint256[] memory balances_ = new uint256[](_owners.length);
|
||||
|
||||
for (uint256 i = 0; i < _owners.length; ++i) {
|
||||
uint256 id = _ids[i];
|
||||
if (isNonFungibleItem(id)) {
|
||||
balances_[i] = nfOwners[id] == _owners[i] ? 1 : 0;
|
||||
} else {
|
||||
balances_[i] = balances[id][_owners[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return balances_;
|
||||
}
|
||||
|
||||
/**
|
||||
@notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
|
||||
@dev MUST emit the ApprovalForAll event on success.
|
||||
@param _operator address to safeAdd to the set of authorized operators
|
||||
@param _approved True if the operator is approved, false to revoke approval
|
||||
*/
|
||||
function setApprovalForAll(address _operator, bool _approved) external {
|
||||
operatorApproval[msg.sender][_operator] = _approved;
|
||||
emit ApprovalForAll(msg.sender, _operator, _approved);
|
||||
}
|
||||
|
||||
/**
|
||||
@notice Queries the approval status of an operator for a given owner.
|
||||
@param _owner The owner of the Tokens
|
||||
@param _operator address of authorized operator
|
||||
@return True if the operator is approved, false if not
|
||||
*/
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
|
||||
return operatorApproval[_owner][_operator];
|
||||
}
|
||||
}
|
98
contracts/erc1155/contracts/src/ERC1155Mintable.sol
Normal file
98
contracts/erc1155/contracts/src/ERC1155Mintable.sol
Normal file
@@ -0,0 +1,98 @@
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
import "./lib/SafeMath.sol";
|
||||
import "./ERC1155.sol";
|
||||
|
||||
/**
|
||||
@dev Mintable form of ERC1155
|
||||
Shows how easy it is to mint new items
|
||||
*/
|
||||
contract ERC1155Mintable is
|
||||
ERC1155
|
||||
{
|
||||
|
||||
uint256 nonce;
|
||||
mapping (uint256 => address) public creators;
|
||||
mapping (uint256 => uint256) public maxIndex;
|
||||
|
||||
modifier creatorOnly(uint256 _id) {
|
||||
require(creators[_id] == msg.sender);
|
||||
_;
|
||||
}
|
||||
|
||||
// This function only creates the type.
|
||||
function create(
|
||||
string calldata _uri,
|
||||
bool _isNF
|
||||
)
|
||||
external
|
||||
returns (uint256 _type)
|
||||
{
|
||||
// Store the type in the upper 128 bits
|
||||
_type = (++nonce << 128);
|
||||
|
||||
// Set a flag if this is an NFI.
|
||||
if (_isNF)
|
||||
_type = _type | TYPE_NF_BIT;
|
||||
|
||||
// This will allow restricted access to creators.
|
||||
creators[_type] = msg.sender;
|
||||
|
||||
// emit a Transfer event with Create semantic to help with discovery.
|
||||
emit TransferSingle(msg.sender, address(0x0), address(0x0), _type, 0);
|
||||
|
||||
if (bytes(_uri).length > 0)
|
||||
emit URI(_uri, _type);
|
||||
}
|
||||
|
||||
function mintNonFungible(uint256 _type, address[] calldata _to) external creatorOnly(_type) {
|
||||
|
||||
// No need to check this is a nf type rather than an id since
|
||||
// creatorOnly() will only let a type pass through.
|
||||
require(isNonFungible(_type));
|
||||
|
||||
// Index are 1-based.
|
||||
uint256 index = maxIndex[_type] + 1;
|
||||
|
||||
for (uint256 i = 0; i < _to.length; ++i) {
|
||||
address dst = _to[i];
|
||||
uint256 id = _type | index + i;
|
||||
|
||||
nfOwners[id] = dst;
|
||||
|
||||
// You could use base-type id to store NF type balances if you wish.
|
||||
// balances[_type][dst] = quantity.safeAdd(balances[_type][dst]);
|
||||
|
||||
emit TransferSingle(msg.sender, address(0x0), dst, id, 1);
|
||||
|
||||
if (dst.isContract()) {
|
||||
require(IERC1155Receiver(dst).onERC1155Received(msg.sender, msg.sender, id, 1, '') == ERC1155_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
maxIndex[_type] = safeAdd(_to.length, maxIndex[_type]);
|
||||
}
|
||||
|
||||
function mintFungible(uint256 _id, address[] calldata _to, uint256[] calldata _quantities) external creatorOnly(_id) {
|
||||
|
||||
require(isFungible(_id));
|
||||
|
||||
for (uint256 i = 0; i < _to.length; ++i) {
|
||||
|
||||
address to = _to[i];
|
||||
uint256 quantity = _quantities[i];
|
||||
|
||||
// Grant the items to the caller
|
||||
balances[_id][to] = safeAdd(quantity, balances[_id][to]);
|
||||
|
||||
// Emit the Transfer/Mint event.
|
||||
// the 0x0 source address implies a mint
|
||||
// It will also provide the circulating supply info.
|
||||
emit TransferSingle(msg.sender, address(0x0), to, _id, quantity);
|
||||
|
||||
if (to.isContract()) {
|
||||
require(IERC1155Receiver(to).onERC1155Received(msg.sender, msg.sender, _id, quantity, '') == ERC1155_RECEIVED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
124
contracts/erc1155/contracts/src/interfaces/IERC1155.sol
Normal file
124
contracts/erc1155/contracts/src/interfaces/IERC1155.sol
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
|
||||
/**
|
||||
@title ERC-1155 Multi Token Standard
|
||||
@dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md
|
||||
Note: The ERC-165 identifier for this interface is 0xd9b67a26.
|
||||
*/
|
||||
interface IERC1155 {
|
||||
/**
|
||||
@dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero value transfers as well as minting or burning.
|
||||
Operator will always be msg.sender.
|
||||
Either event from address `0x0` signifies a minting operation.
|
||||
An event to address `0x0` signifies a burning or melting operation.
|
||||
The total value transferred from address 0x0 minus the total value transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
|
||||
To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`.
|
||||
*/
|
||||
event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value);
|
||||
|
||||
/**
|
||||
@dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero value transfers as well as minting or burning.
|
||||
Operator will always be msg.sender.
|
||||
Either event from address `0x0` signifies a minting operation.
|
||||
An event to address `0x0` signifies a burning or melting operation.
|
||||
The total value transferred from address 0x0 minus the total value transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
|
||||
To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`.
|
||||
*/
|
||||
event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values);
|
||||
|
||||
/**
|
||||
@dev MUST emit when an approval is updated.
|
||||
*/
|
||||
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
|
||||
|
||||
/**
|
||||
@dev MUST emit when the URI is updated for a token ID.
|
||||
URIs are defined in RFC 3986.
|
||||
The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema".
|
||||
*/
|
||||
event URI(string _value, uint256 indexed _id);
|
||||
|
||||
/**
|
||||
@notice Transfers value amount of an _id from the _from address to the _to address specified.
|
||||
@dev MUST emit TransferSingle event on success.
|
||||
Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
|
||||
MUST throw if `_to` is the zero address.
|
||||
MUST throw if balance of sender for token `_id` is lower than the `_value` sent.
|
||||
MUST throw on any other error.
|
||||
When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return value is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
|
||||
@param _from Source address
|
||||
@param _to Target address
|
||||
@param _id ID of the token type
|
||||
@param _value Transfer amount
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;
|
||||
|
||||
/**
|
||||
@notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
|
||||
@dev MUST emit TransferBatch event on success.
|
||||
Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
|
||||
MUST throw if `_to` is the zero address.
|
||||
MUST throw if length of `_ids` is not the same as length of `_values`.
|
||||
MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent.
|
||||
MUST throw on any other error.
|
||||
When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
|
||||
@param _from Source addresses
|
||||
@param _to Target addresses
|
||||
@param _ids IDs of each token type
|
||||
@param _values Transfer amounts per token type
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;
|
||||
|
||||
/**
|
||||
@notice Get the balance of an account's Tokens.
|
||||
@param _owner The address of the token holder
|
||||
@param _id ID of the Token
|
||||
@return The _owner's balance of the Token type requested
|
||||
*/
|
||||
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
|
||||
|
||||
/**
|
||||
@notice Get the balance of multiple account/token pairs
|
||||
@param _owners The addresses of the token holders
|
||||
@param _ids ID of the Tokens
|
||||
@return The _owner's balance of the Token types requested
|
||||
*/
|
||||
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);
|
||||
|
||||
/**
|
||||
@notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
|
||||
@dev MUST emit the ApprovalForAll event on success.
|
||||
@param _operator Address to add to the set of authorized operators
|
||||
@param _approved True if the operator is approved, false to revoke approval
|
||||
*/
|
||||
function setApprovalForAll(address _operator, bool _approved) external;
|
||||
|
||||
/**
|
||||
@notice Queries the approval status of an operator for a given owner.
|
||||
@param _owner The owner of the Tokens
|
||||
@param _operator Address of authorized operator
|
||||
@return True if the operator is approved, false if not
|
||||
*/
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
|
||||
interface IERC1155Receiver {
|
||||
|
||||
/**
|
||||
@notice Handle the receipt of a single ERC1155 token type
|
||||
@dev The smart contract calls this function on the recipient
|
||||
after a `safeTransferFrom`. This function MAY throw to revert and reject the
|
||||
transfer. Return of other than the magic value MUST result in the
|
||||
transaction being reverted
|
||||
Note: the contract address is always the message sender
|
||||
@param _operator The address which called `safeTransferFrom` function
|
||||
@param _from The address which previously owned the token
|
||||
@param _id An array containing the ids of the token being transferred
|
||||
@param _value An array containing the amount of tokens being transferred
|
||||
@param _data Additional data with no specified format
|
||||
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
|
||||
*/
|
||||
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4);
|
||||
|
||||
/**
|
||||
@notice Handle the receipt of multiple ERC1155 token types
|
||||
@dev The smart contract calls this function on the recipient
|
||||
after a `safeTransferFrom`. This function MAY throw to revert and reject the
|
||||
transfer. Return of other than the magic value MUST result in the
|
||||
transaction being reverted
|
||||
Note: the contract address is always the message sender
|
||||
@param _operator The address which called `safeTransferFrom` function
|
||||
@param _from The address which previously owned the token
|
||||
@param _ids An array containing ids of each token being transferred
|
||||
@param _values An array containing amounts of each token being transferred
|
||||
@param _data Additional data with no specified format
|
||||
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
|
||||
*/
|
||||
function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external returns(bytes4);
|
||||
}
|
75
contracts/erc1155/contracts/test/DummyERC1155Receiver.sol
Normal file
75
contracts/erc1155/contracts/test/DummyERC1155Receiver.sol
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
import "../src/interfaces/IERC1155Receiver.sol";
|
||||
|
||||
contract DummyERC1155Receiver is
|
||||
IERC1155Receiver
|
||||
{
|
||||
|
||||
bytes4 constant public ERC1155_RECEIVED = 0xf23a6e61;
|
||||
bytes4 constant public ERC1155_BATCH_RECEIVED = 0xbc197c81;
|
||||
|
||||
constructor () public {}
|
||||
|
||||
event TokenReceived(
|
||||
address operator,
|
||||
address from,
|
||||
uint256 tokenId,
|
||||
uint256 tokenValue,
|
||||
bytes data
|
||||
);
|
||||
|
||||
event BatchTokenReceived(
|
||||
address operator,
|
||||
address from,
|
||||
uint256[] tokenIds,
|
||||
uint256[] tokenValues,
|
||||
bytes data
|
||||
);
|
||||
|
||||
function onERC1155Received(
|
||||
address _operator,
|
||||
address _from,
|
||||
uint256 _id,
|
||||
uint256 _value,
|
||||
bytes calldata _data
|
||||
)
|
||||
external
|
||||
returns (bytes4)
|
||||
{
|
||||
emit TokenReceived(_operator, _from, _id, _value, _data);
|
||||
return ERC1155_RECEIVED;
|
||||
}
|
||||
|
||||
function onERC1155BatchReceived(
|
||||
address _operator,
|
||||
address _from,
|
||||
uint256[] calldata _ids,
|
||||
uint256[] calldata _values,
|
||||
bytes calldata _data
|
||||
)
|
||||
external
|
||||
returns (bytes4)
|
||||
{
|
||||
emit BatchTokenReceived(_operator, _from, _ids, _values, _data);
|
||||
return ERC1155_BATCH_RECEIVED;
|
||||
}
|
||||
}
|
40
contracts/erc1155/contracts/test/DummyERC1155Token.sol
Normal file
40
contracts/erc1155/contracts/test/DummyERC1155Token.sol
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
import "../src/ERC1155Mintable.sol";
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract DummyERC1155Token is
|
||||
ERC1155Mintable
|
||||
{
|
||||
|
||||
string public name;
|
||||
string public symbol;
|
||||
|
||||
constructor (
|
||||
string memory _name,
|
||||
string memory _symbol
|
||||
)
|
||||
public
|
||||
{
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
}
|
||||
}
|
68
contracts/erc1155/contracts/test/InvalidERC1155Receiver.sol
Normal file
68
contracts/erc1155/contracts/test/InvalidERC1155Receiver.sol
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.3;
|
||||
|
||||
|
||||
contract InvalidERC1155Receiver //is
|
||||
//IERC1155Receiver
|
||||
{
|
||||
/*
|
||||
// Actual function signature is `onERC1155Received(address,address,uint256,bytes)`
|
||||
bytes4 constant internal INVALID_ERC1155_RECEIVED = bytes4(keccak256("onERC1155Received(address,uint256,bytes)"));
|
||||
|
||||
event TokenReceived(
|
||||
address operator,
|
||||
address from,
|
||||
uint256 tokenId,
|
||||
bytes data
|
||||
);
|
||||
|
||||
/// @notice Handle the receipt of an NFT
|
||||
/// @dev The ERC1155 smart contract calls this function on the recipient
|
||||
/// after a `transfer`. This function MAY throw to revert and reject the
|
||||
/// transfer. Return of other than the magic value MUST result in the
|
||||
/// transaction being reverted.
|
||||
/// Note: the contract address is always the message sender.
|
||||
/// @param _operator The address which called `safeTransferFrom` function
|
||||
/// @param _from The address which previously owned the token
|
||||
/// @param _tokenId The NFT identifier which is being transferred
|
||||
/// @param _data Additional data with no specified format
|
||||
/// @return `bytes4(keccak256("onERC1155Received(address,address,uint256,bytes)"))`
|
||||
/// unless throwing
|
||||
function onERC1155Received(
|
||||
address _operator,
|
||||
address _from,
|
||||
uint256 _tokenId,
|
||||
bytes _data
|
||||
)
|
||||
external
|
||||
returns (bytes4)
|
||||
{
|
||||
emit TokenReceived(
|
||||
_operator,
|
||||
_from,
|
||||
_tokenId,
|
||||
_data
|
||||
);
|
||||
return INVALID_ERC1155_RECEIVED;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user