Last active
February 28, 2022 09:10
-
-
Save z0r0z/9a1e292390a4441dfe13843c12d38dd8 to your computer and use it in GitHub Desktop.
what ERC-1155 could have been
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: AGPL-3.0-only | |
pragma solidity >=0.8.0; | |
/// @notice Modern and gas efficient MultiToken implementation adhering as closely to ERC20 interface. | |
/// @author Ross, modified from (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) | |
abstract contract MultiToken { | |
/*/////////////////////////////////////////////////////////////// | |
EVENTS | |
//////////////////////////////////////////////////////////////*/ | |
event Transfer(address indexed from, address indexed to, uint256 indexed id, uint256 amount); | |
event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); | |
/*/////////////////////////////////////////////////////////////// | |
METADATA STORAGE/LOGIC | |
//////////////////////////////////////////////////////////////*/ | |
string public name; | |
string public symbol; | |
function tokenURI(uint256 id) public view virtual returns (string memory); | |
/*/////////////////////////////////////////////////////////////// | |
TOKEN STORAGE | |
//////////////////////////////////////////////////////////////*/ | |
mapping(uint256 => uint256) public totalSupplyForId; | |
mapping(address => mapping(uint256 => uint256)) public balanceOf; | |
mapping(address => mapping(address => mapping(uint256 => uint256))) public allowance; | |
/*/////////////////////////////////////////////////////////////// | |
CONSTRUCTOR | |
//////////////////////////////////////////////////////////////*/ | |
constructor(string memory _name, string memory _symbol) { | |
name = _name; | |
symbol = _symbol; | |
} | |
/*/////////////////////////////////////////////////////////////// | |
TOKEN LOGIC | |
//////////////////////////////////////////////////////////////*/ | |
function approve( | |
address spender, | |
uint256 id, | |
uint256 amount | |
) public virtual { | |
allowance[msg.sender][spender][id] = amount; | |
emit Approval(msg.sender, spender, id, amount); | |
} | |
function transfer( | |
address to, | |
uint256 id, | |
uint256 amount | |
) public virtual { | |
balanceOf[msg.sender][id] -= amount; | |
// Cannot overflow because the sum of all user | |
// balances can't exceed the max uint256 value. | |
unchecked { | |
balanceOf[to][id] += amount; | |
} | |
emit Transfer(msg.sender, to, id, amount); | |
} | |
function transferFrom( | |
address from, | |
address to, | |
uint256 id, | |
uint256 amount | |
) public virtual { | |
uint256 allowed = allowance[from][msg.sender][id]; // Saves gas for limited approvals. | |
if (allowed != type(uint256).max) allowance[from][msg.sender][id] = allowed - amount; | |
balanceOf[from][id] -= amount; | |
// Cannot overflow because the sum of all user | |
// balances can't exceed the max uint256 value. | |
unchecked { | |
balanceOf[to][id] += amount; | |
} | |
emit Transfer(from, to, id, amount); | |
} | |
/*/////////////////////////////////////////////////////////////// | |
INTERNAL MINT/BURN LOGIC | |
//////////////////////////////////////////////////////////////*/ | |
function _mint( | |
address to, | |
uint256 id, | |
uint256 amount | |
) internal virtual { | |
totalSupplyForId[id] += amount; | |
// Cannot overflow because the sum of all user | |
// balances can't exceed the max uint256 value. | |
unchecked { | |
balanceOf[to][id] += amount; | |
} | |
emit Transfer(address(0), to, id, amount); | |
} | |
function _burn( | |
address from, | |
uint256 id, | |
uint256 amount | |
) internal virtual { | |
balanceOf[from][id] -= amount; | |
// Cannot underflow because a user's balance | |
// will never be larger than the total supply. | |
unchecked { | |
totalSupplyForId[id] -= amount; | |
} | |
emit Transfer(from, address(0), id, amount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment