Skip to content

Commit

Permalink
Use an explicit registration internally to mark token IDs as existing
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiRo-at committed Apr 14, 2020
1 parent 1a921e7 commit 9af78df
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions contracts/token/ERC1155/ERC1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ contract ERC1155 is ERC165, IERC1155
// Mapping from account to operator approvals
mapping (address => mapping(address => bool)) private _operatorApprovals;

// Mapping token ID to that token being registered as existing
mapping (uint256 => bool) private _tokenExists;

/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
Expand Down Expand Up @@ -53,6 +56,7 @@ contract ERC1155 is ERC165, IERC1155
*/
function balanceOf(address account, uint256 id) public view override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
require(_exists(id), "ERC1155: balance query for nonexistent token");
return _balances[id][account];
}

Expand Down Expand Up @@ -80,6 +84,7 @@ contract ERC1155 is ERC165, IERC1155

for (uint256 i = 0; i < accounts.length; ++i) {
require(accounts[i] != address(0), "ERC1155: some address in batch balance query is zero");
require(_exists(id), "ERC1155: some token in batch balance query does not exist");
batchBalances[i] = _balances[ids[i]][accounts[i]];
}

Expand Down Expand Up @@ -194,14 +199,21 @@ contract ERC1155 is ERC165, IERC1155
}

/**
* @dev Returns whether the specified token exists. This is intentionally marked
* `virtual` as specific implementations may want to override to actually have
* existence be respected while the generic implementation always returns true.
* @dev Register a token ID so other contract functionality knows this token
* actually exists and this ID is valid. Minting will automatically call this.
* @param id uint256 ID of the token to register
*/
function _registerToken(uint256 id) internal virtual {
return _tokenExists[id] = true;
}

/**
* @dev Returns whether the specified token exists. Use {_registerTokenID} to set this flag.
* @param id uint256 ID of the token to query the existence of
* @return bool whether the token exists
*/
function _exists(uint256 id) internal view virtual returns (bool) {
return true;
function _exists(uint256 id) internal view returns (bool) {
return _tokenExists[id];
}

/**
Expand All @@ -214,6 +226,9 @@ contract ERC1155 is ERC165, IERC1155
function _mint(address to, uint256 id, uint256 value, bytes memory data) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");

if (!_exists(id)) {
_registerToken(id);
}
_balances[id][to] = _balances[id][to].add(value);
emit TransferSingle(msg.sender, address(0), to, id, value);

Expand All @@ -232,6 +247,9 @@ contract ERC1155 is ERC165, IERC1155
require(ids.length == values.length, "ERC1155: minted IDs and values must have same lengths");

for(uint i = 0; i < ids.length; i++) {
if (!_exists(id)) {
_registerToken(id);
}
_balances[ids[i]][to] = values[i].add(_balances[ids[i]][to]);
}

Expand Down

0 comments on commit 9af78df

Please sign in to comment.