├── MemeLtD.sol ├── GenesisPool.sol ├── SvenEberwein.sol └── MemeLtDPool.sol /MemeLtD.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2020-08-26 3 | */ 4 | 5 | pragma solidity >=0.5.0; 6 | 7 | 8 | /* 9 | * @dev Provides information about the current execution context, including the 10 | * sender of the transaction and its data. While these are generally available 11 | * via msg.sender and msg.data, they should not be accessed in such a direct 12 | * manner, since when dealing with GSN meta-transactions the account sending and 13 | * paying for execution may not be the actual sender (as far as an application 14 | * is concerned). 15 | * 16 | * This contract is only required for intermediate, library-like contracts. 17 | */ 18 | contract Context { 19 | // Empty internal constructor, to prevent people from mistakenly deploying 20 | // an instance of this contract, which should be used via inheritance. 21 | constructor () internal { } 22 | // solhint-disable-previous-line no-empty-blocks 23 | 24 | function _msgSender() internal view returns (address payable) { 25 | return msg.sender; 26 | } 27 | 28 | function _msgData() internal view returns (bytes memory) { 29 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 30 | return msg.data; 31 | } 32 | } 33 | 34 | /** 35 | * @dev Contract module which provides a basic access control mechanism, where 36 | * there is an account (an owner) that can be granted exclusive access to 37 | * specific functions. 38 | * 39 | * This module is used through inheritance. It will make available the modifier 40 | * `onlyOwner`, which can be applied to your functions to restrict their use to 41 | * the owner. 42 | */ 43 | contract Ownable is Context { 44 | address private _owner; 45 | 46 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 47 | 48 | /** 49 | * @dev Initializes the contract setting the deployer as the initial owner. 50 | */ 51 | constructor () internal { 52 | address msgSender = _msgSender(); 53 | _owner = msgSender; 54 | emit OwnershipTransferred(address(0), msgSender); 55 | } 56 | 57 | /** 58 | * @dev Returns the address of the current owner. 59 | */ 60 | function owner() public view returns (address) { 61 | return _owner; 62 | } 63 | 64 | /** 65 | * @dev Throws if called by any account other than the owner. 66 | */ 67 | modifier onlyOwner() { 68 | require(isOwner(), "Ownable: caller is not the owner"); 69 | _; 70 | } 71 | 72 | /** 73 | * @dev Returns true if the caller is the current owner. 74 | */ 75 | function isOwner() public view returns (bool) { 76 | return _msgSender() == _owner; 77 | } 78 | 79 | /** 80 | * @dev Leaves the contract without owner. It will not be possible to call 81 | * `onlyOwner` functions anymore. Can only be called by the current owner. 82 | * 83 | * NOTE: Renouncing ownership will leave the contract without an owner, 84 | * thereby removing any functionality that is only available to the owner. 85 | */ 86 | function renounceOwnership() public onlyOwner { 87 | emit OwnershipTransferred(_owner, address(0)); 88 | _owner = address(0); 89 | } 90 | 91 | /** 92 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 93 | * Can only be called by the current owner. 94 | */ 95 | function transferOwnership(address newOwner) public onlyOwner { 96 | _transferOwnership(newOwner); 97 | } 98 | 99 | /** 100 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 101 | */ 102 | function _transferOwnership(address newOwner) internal { 103 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 104 | emit OwnershipTransferred(_owner, newOwner); 105 | _owner = newOwner; 106 | } 107 | } 108 | 109 | /** 110 | * @title Roles 111 | * @dev Library for managing addresses assigned to a Role. 112 | */ 113 | library Roles { 114 | struct Role { 115 | mapping (address => bool) bearer; 116 | } 117 | 118 | /** 119 | * @dev Give an account access to this role. 120 | */ 121 | function add(Role storage role, address account) internal { 122 | require(!has(role, account), "Roles: account already has role"); 123 | role.bearer[account] = true; 124 | } 125 | 126 | /** 127 | * @dev Remove an account's access to this role. 128 | */ 129 | function remove(Role storage role, address account) internal { 130 | require(has(role, account), "Roles: account does not have role"); 131 | role.bearer[account] = false; 132 | } 133 | 134 | /** 135 | * @dev Check if an account has this role. 136 | * @return bool 137 | */ 138 | function has(Role storage role, address account) internal view returns (bool) { 139 | require(account != address(0), "Roles: account is the zero address"); 140 | return role.bearer[account]; 141 | } 142 | } 143 | 144 | contract MinterRole is Context { 145 | using Roles for Roles.Role; 146 | 147 | event MinterAdded(address indexed account); 148 | event MinterRemoved(address indexed account); 149 | 150 | Roles.Role private _minters; 151 | 152 | constructor () internal { 153 | _addMinter(_msgSender()); 154 | } 155 | 156 | modifier onlyMinter() { 157 | require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role"); 158 | _; 159 | } 160 | 161 | function isMinter(address account) public view returns (bool) { 162 | return _minters.has(account); 163 | } 164 | 165 | function addMinter(address account) public onlyMinter { 166 | _addMinter(account); 167 | } 168 | 169 | function renounceMinter() public { 170 | _removeMinter(_msgSender()); 171 | } 172 | 173 | function _addMinter(address account) internal { 174 | _minters.add(account); 175 | emit MinterAdded(account); 176 | } 177 | 178 | function _removeMinter(address account) internal { 179 | _minters.remove(account); 180 | emit MinterRemoved(account); 181 | } 182 | } 183 | 184 | /** 185 | * @title WhitelistAdminRole 186 | * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. 187 | */ 188 | contract WhitelistAdminRole is Context { 189 | using Roles for Roles.Role; 190 | 191 | event WhitelistAdminAdded(address indexed account); 192 | event WhitelistAdminRemoved(address indexed account); 193 | 194 | Roles.Role private _whitelistAdmins; 195 | 196 | constructor () internal { 197 | _addWhitelistAdmin(_msgSender()); 198 | } 199 | 200 | modifier onlyWhitelistAdmin() { 201 | require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); 202 | _; 203 | } 204 | 205 | function isWhitelistAdmin(address account) public view returns (bool) { 206 | return _whitelistAdmins.has(account); 207 | } 208 | 209 | function addWhitelistAdmin(address account) public onlyWhitelistAdmin { 210 | _addWhitelistAdmin(account); 211 | } 212 | 213 | function renounceWhitelistAdmin() public { 214 | _removeWhitelistAdmin(_msgSender()); 215 | } 216 | 217 | function _addWhitelistAdmin(address account) internal { 218 | _whitelistAdmins.add(account); 219 | emit WhitelistAdminAdded(account); 220 | } 221 | 222 | function _removeWhitelistAdmin(address account) internal { 223 | _whitelistAdmins.remove(account); 224 | emit WhitelistAdminRemoved(account); 225 | } 226 | } 227 | 228 | /** 229 | * @title ERC165 230 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md 231 | */ 232 | interface IERC165 { 233 | 234 | /** 235 | * @notice Query if a contract implements an interface 236 | * @dev Interface identification is specified in ERC-165. This function 237 | * uses less than 30,000 gas 238 | * @param _interfaceId The interface identifier, as specified in ERC-165 239 | */ 240 | function supportsInterface(bytes4 _interfaceId) 241 | external 242 | view 243 | returns (bool); 244 | } 245 | 246 | /** 247 | * @title SafeMath 248 | * @dev Unsigned math operations with safety checks that revert on error 249 | */ 250 | library SafeMath { 251 | 252 | /** 253 | * @dev Multiplies two unsigned integers, reverts on overflow. 254 | */ 255 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 256 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 257 | // benefit is lost if 'b' is also tested. 258 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 259 | if (a == 0) { 260 | return 0; 261 | } 262 | 263 | uint256 c = a * b; 264 | require(c / a == b, "SafeMath#mul: OVERFLOW"); 265 | 266 | return c; 267 | } 268 | 269 | /** 270 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 271 | */ 272 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 273 | // Solidity only automatically asserts when dividing by 0 274 | require(b > 0, "SafeMath#div: DIVISION_BY_ZERO"); 275 | uint256 c = a / b; 276 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 277 | 278 | return c; 279 | } 280 | 281 | /** 282 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 283 | */ 284 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 285 | require(b <= a, "SafeMath#sub: UNDERFLOW"); 286 | uint256 c = a - b; 287 | 288 | return c; 289 | } 290 | 291 | /** 292 | * @dev Adds two unsigned integers, reverts on overflow. 293 | */ 294 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 295 | uint256 c = a + b; 296 | require(c >= a, "SafeMath#add: OVERFLOW"); 297 | 298 | return c; 299 | } 300 | 301 | /** 302 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 303 | * reverts when dividing by zero. 304 | */ 305 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 306 | require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO"); 307 | return a % b; 308 | } 309 | 310 | } 311 | 312 | /** 313 | * @dev ERC-1155 interface for accepting safe transfers. 314 | */ 315 | interface IERC1155TokenReceiver { 316 | 317 | /** 318 | * @notice Handle the receipt of a single ERC1155 token type 319 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated 320 | * This function MAY throw to revert and reject the transfer 321 | * Return of other amount than the magic value MUST result in the transaction being reverted 322 | * Note: The token contract address is always the message sender 323 | * @param _operator The address which called the `safeTransferFrom` function 324 | * @param _from The address which previously owned the token 325 | * @param _id The id of the token being transferred 326 | * @param _amount The amount of tokens being transferred 327 | * @param _data Additional data with no specified format 328 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 329 | */ 330 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4); 331 | 332 | /** 333 | * @notice Handle the receipt of multiple ERC1155 token types 334 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated 335 | * This function MAY throw to revert and reject the transfer 336 | * Return of other amount than the magic value WILL result in the transaction being reverted 337 | * Note: The token contract address is always the message sender 338 | * @param _operator The address which called the `safeBatchTransferFrom` function 339 | * @param _from The address which previously owned the token 340 | * @param _ids An array containing ids of each token being transferred 341 | * @param _amounts An array containing amounts of each token being transferred 342 | * @param _data Additional data with no specified format 343 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 344 | */ 345 | function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4); 346 | 347 | /** 348 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types. 349 | * @param interfaceID The ERC-165 interface ID that is queried for support.s 350 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface. 351 | * This function MUST NOT consume more than 5,000 gas. 352 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported. 353 | */ 354 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 355 | 356 | } 357 | 358 | interface IERC1155 { 359 | // Events 360 | 361 | /** 362 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 363 | * Operator MUST be msg.sender 364 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 365 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 366 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 367 | * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 368 | */ 369 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 370 | 371 | /** 372 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 373 | * Operator MUST be msg.sender 374 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 375 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 376 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 377 | * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 378 | */ 379 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 380 | 381 | /** 382 | * @dev MUST emit when an approval is updated 383 | */ 384 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 385 | 386 | /** 387 | * @dev MUST emit when the URI is updated for a token ID 388 | * URIs are defined in RFC 3986 389 | * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema" 390 | */ 391 | event URI(string _amount, uint256 indexed _id); 392 | 393 | /** 394 | * @notice Transfers amount of an _id from the _from address to the _to address specified 395 | * @dev MUST emit TransferSingle event on success 396 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 397 | * MUST throw if `_to` is the zero address 398 | * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent 399 | * MUST throw on any other error 400 | * 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 amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 401 | * @param _from Source address 402 | * @param _to Target address 403 | * @param _id ID of the token type 404 | * @param _amount Transfered amount 405 | * @param _data Additional data with no specified format, sent in call to `_to` 406 | */ 407 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external; 408 | 409 | /** 410 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 411 | * @dev MUST emit TransferBatch event on success 412 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 413 | * MUST throw if `_to` is the zero address 414 | * MUST throw if length of `_ids` is not the same as length of `_amounts` 415 | * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent 416 | * MUST throw on any other error 417 | * 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 amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 418 | * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc) 419 | * @param _from Source addresses 420 | * @param _to Target addresses 421 | * @param _ids IDs of each token type 422 | * @param _amounts Transfer amounts per token type 423 | * @param _data Additional data with no specified format, sent in call to `_to` 424 | */ 425 | function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external; 426 | 427 | /** 428 | * @notice Get the balance of an account's Tokens 429 | * @param _owner The address of the token holder 430 | * @param _id ID of the Token 431 | * @return The _owner's balance of the Token type requested 432 | */ 433 | function balanceOf(address _owner, uint256 _id) external view returns (uint256); 434 | 435 | /** 436 | * @notice Get the balance of multiple account/token pairs 437 | * @param _owners The addresses of the token holders 438 | * @param _ids ID of the Tokens 439 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 440 | */ 441 | function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); 442 | 443 | /** 444 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 445 | * @dev MUST emit the ApprovalForAll event on success 446 | * @param _operator Address to add to the set of authorized operators 447 | * @param _approved True if the operator is approved, false to revoke approval 448 | */ 449 | function setApprovalForAll(address _operator, bool _approved) external; 450 | 451 | /** 452 | * @notice Queries the approval status of an operator for a given owner 453 | * @param _owner The owner of the Tokens 454 | * @param _operator Address of authorized operator 455 | * @return True if the operator is approved, false if not 456 | */ 457 | function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator); 458 | 459 | } 460 | 461 | /** 462 | * Copyright 2018 ZeroEx Intl. 463 | * Licensed under the Apache License, Version 2.0 (the "License"); 464 | * you may not use this file except in compliance with the License. 465 | * You may obtain a copy of the License at 466 | * http://www.apache.org/licenses/LICENSE-2.0 467 | * Unless required by applicable law or agreed to in writing, software 468 | * distributed under the License is distributed on an "AS IS" BASIS, 469 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 470 | * See the License for the specific language governing permissions and 471 | * limitations under the License. 472 | */ 473 | /** 474 | * Utility library of inline functions on addresses 475 | */ 476 | library Address { 477 | 478 | /** 479 | * Returns whether the target address is a contract 480 | * @dev This function will return false if invoked during the constructor of a contract, 481 | * as the code is not actually created until after the constructor finishes. 482 | * @param account address of the account to check 483 | * @return whether the target address is a contract 484 | */ 485 | function isContract(address account) internal view returns (bool) { 486 | bytes32 codehash; 487 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 488 | 489 | // XXX Currently there is no better way to check if there is a contract in an address 490 | // than to check the size of the code at that address. 491 | // See https://ethereum.stackexchange.com/a/14016/36603 492 | // for more details about how this works. 493 | // TODO Check this again before the Serenity release, because all addresses will be 494 | // contracts then. 495 | assembly { codehash := extcodehash(account) } 496 | return (codehash != 0x0 && codehash != accountHash); 497 | } 498 | 499 | } 500 | 501 | /** 502 | * @dev Implementation of Multi-Token Standard contract 503 | */ 504 | contract ERC1155 is IERC165 { 505 | using SafeMath for uint256; 506 | using Address for address; 507 | 508 | 509 | /***********************************| 510 | | Variables and Events | 511 | |__________________________________*/ 512 | 513 | // onReceive function signatures 514 | bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61; 515 | bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; 516 | 517 | // Objects balances 518 | mapping (address => mapping(uint256 => uint256)) internal balances; 519 | 520 | // Operator Functions 521 | mapping (address => mapping(address => bool)) internal operators; 522 | 523 | // Events 524 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 525 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 526 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 527 | event URI(string _uri, uint256 indexed _id); 528 | 529 | 530 | /***********************************| 531 | | Public Transfer Functions | 532 | |__________________________________*/ 533 | 534 | /** 535 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 536 | * @param _from Source address 537 | * @param _to Target address 538 | * @param _id ID of the token type 539 | * @param _amount Transfered amount 540 | * @param _data Additional data with no specified format, sent in call to `_to` 541 | */ 542 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 543 | public 544 | { 545 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR"); 546 | require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT"); 547 | // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations 548 | 549 | _safeTransferFrom(_from, _to, _id, _amount); 550 | _callonERC1155Received(_from, _to, _id, _amount, _data); 551 | } 552 | 553 | /** 554 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 555 | * @param _from Source addresses 556 | * @param _to Target addresses 557 | * @param _ids IDs of each token type 558 | * @param _amounts Transfer amounts per token type 559 | * @param _data Additional data with no specified format, sent in call to `_to` 560 | */ 561 | function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 562 | public 563 | { 564 | // Requirements 565 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR"); 566 | require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT"); 567 | 568 | _safeBatchTransferFrom(_from, _to, _ids, _amounts); 569 | _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data); 570 | } 571 | 572 | 573 | /***********************************| 574 | | Internal Transfer Functions | 575 | |__________________________________*/ 576 | 577 | /** 578 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 579 | * @param _from Source address 580 | * @param _to Target address 581 | * @param _id ID of the token type 582 | * @param _amount Transfered amount 583 | */ 584 | function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) 585 | internal 586 | { 587 | // Update balances 588 | balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount 589 | balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount 590 | 591 | // Emit event 592 | emit TransferSingle(msg.sender, _from, _to, _id, _amount); 593 | } 594 | 595 | /** 596 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...) 597 | */ 598 | function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 599 | internal 600 | { 601 | // Check if recipient is contract 602 | if (_to.isContract()) { 603 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data); 604 | require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE"); 605 | } 606 | } 607 | 608 | /** 609 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 610 | * @param _from Source addresses 611 | * @param _to Target addresses 612 | * @param _ids IDs of each token type 613 | * @param _amounts Transfer amounts per token type 614 | */ 615 | function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts) 616 | internal 617 | { 618 | require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH"); 619 | 620 | // Number of transfer to execute 621 | uint256 nTransfer = _ids.length; 622 | 623 | // Executing all transfers 624 | for (uint256 i = 0; i < nTransfer; i++) { 625 | // Update storage balance of previous bin 626 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 627 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 628 | } 629 | 630 | // Emit event 631 | emit TransferBatch(msg.sender, _from, _to, _ids, _amounts); 632 | } 633 | 634 | /** 635 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...) 636 | */ 637 | function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 638 | internal 639 | { 640 | // Pass data if recipient is contract 641 | if (_to.isContract()) { 642 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data); 643 | require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE"); 644 | } 645 | } 646 | 647 | 648 | /***********************************| 649 | | Operator Functions | 650 | |__________________________________*/ 651 | 652 | /** 653 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 654 | * @param _operator Address to add to the set of authorized operators 655 | * @param _approved True if the operator is approved, false to revoke approval 656 | */ 657 | function setApprovalForAll(address _operator, bool _approved) 658 | external 659 | { 660 | // Update operator status 661 | operators[msg.sender][_operator] = _approved; 662 | emit ApprovalForAll(msg.sender, _operator, _approved); 663 | } 664 | 665 | /** 666 | * @notice Queries the approval status of an operator for a given owner 667 | * @param _owner The owner of the Tokens 668 | * @param _operator Address of authorized operator 669 | * @return True if the operator is approved, false if not 670 | */ 671 | function isApprovedForAll(address _owner, address _operator) 672 | public view returns (bool isOperator) 673 | { 674 | return operators[_owner][_operator]; 675 | } 676 | 677 | 678 | /***********************************| 679 | | Balance Functions | 680 | |__________________________________*/ 681 | 682 | /** 683 | * @notice Get the balance of an account's Tokens 684 | * @param _owner The address of the token holder 685 | * @param _id ID of the Token 686 | * @return The _owner's balance of the Token type requested 687 | */ 688 | function balanceOf(address _owner, uint256 _id) 689 | public view returns (uint256) 690 | { 691 | return balances[_owner][_id]; 692 | } 693 | 694 | /** 695 | * @notice Get the balance of multiple account/token pairs 696 | * @param _owners The addresses of the token holders 697 | * @param _ids ID of the Tokens 698 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 699 | */ 700 | function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) 701 | public view returns (uint256[] memory) 702 | { 703 | require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH"); 704 | 705 | // Variables 706 | uint256[] memory batchBalances = new uint256[](_owners.length); 707 | 708 | // Iterate over each owner and token ID 709 | for (uint256 i = 0; i < _owners.length; i++) { 710 | batchBalances[i] = balances[_owners[i]][_ids[i]]; 711 | } 712 | 713 | return batchBalances; 714 | } 715 | 716 | 717 | /***********************************| 718 | | ERC165 Functions | 719 | |__________________________________*/ 720 | 721 | /** 722 | * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)")); 723 | */ 724 | bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; 725 | 726 | /** 727 | * INTERFACE_SIGNATURE_ERC1155 = 728 | * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^ 729 | * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^ 730 | * bytes4(keccak256("balanceOf(address,uint256)")) ^ 731 | * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^ 732 | * bytes4(keccak256("setApprovalForAll(address,bool)")) ^ 733 | * bytes4(keccak256("isApprovedForAll(address,address)")); 734 | */ 735 | bytes4 constant private INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; 736 | 737 | /** 738 | * @notice Query if a contract implements an interface 739 | * @param _interfaceID The interface identifier, as specified in ERC-165 740 | * @return `true` if the contract implements `_interfaceID` and 741 | */ 742 | function supportsInterface(bytes4 _interfaceID) external view returns (bool) { 743 | if (_interfaceID == INTERFACE_SIGNATURE_ERC165 || 744 | _interfaceID == INTERFACE_SIGNATURE_ERC1155) { 745 | return true; 746 | } 747 | return false; 748 | } 749 | 750 | } 751 | 752 | /** 753 | * @notice Contract that handles metadata related methods. 754 | * @dev Methods assume a deterministic generation of URI based on token IDs. 755 | * Methods also assume that URI uses hex representation of token IDs. 756 | */ 757 | contract ERC1155Metadata { 758 | 759 | // URI's default URI prefix 760 | string internal baseMetadataURI; 761 | event URI(string _uri, uint256 indexed _id); 762 | 763 | 764 | /***********************************| 765 | | Metadata Public Function s | 766 | |__________________________________*/ 767 | 768 | /** 769 | * @notice A distinct Uniform Resource Identifier (URI) for a given token. 770 | * @dev URIs are defined in RFC 3986. 771 | * URIs are assumed to be deterministically generated based on token ID 772 | * Token IDs are assumed to be represented in their hex format in URIs 773 | * @return URI string 774 | */ 775 | function uri(uint256 _id) public view returns (string memory) { 776 | return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json")); 777 | } 778 | 779 | 780 | /***********************************| 781 | | Metadata Internal Functions | 782 | |__________________________________*/ 783 | 784 | /** 785 | * @notice Will emit default URI log event for corresponding token _id 786 | * @param _tokenIDs Array of IDs of tokens to log default URI 787 | */ 788 | function _logURIs(uint256[] memory _tokenIDs) internal { 789 | string memory baseURL = baseMetadataURI; 790 | string memory tokenURI; 791 | 792 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 793 | tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json")); 794 | emit URI(tokenURI, _tokenIDs[i]); 795 | } 796 | } 797 | 798 | /** 799 | * @notice Will emit a specific URI log event for corresponding token 800 | * @param _tokenIDs IDs of the token corresponding to the _uris logged 801 | * @param _URIs The URIs of the specified _tokenIDs 802 | */ 803 | function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal { 804 | require(_tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH"); 805 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 806 | emit URI(_URIs[i], _tokenIDs[i]); 807 | } 808 | } 809 | 810 | /** 811 | * @notice Will update the base URL of token's URI 812 | * @param _newBaseMetadataURI New base URL of token's URI 813 | */ 814 | function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal { 815 | baseMetadataURI = _newBaseMetadataURI; 816 | } 817 | 818 | 819 | /***********************************| 820 | | Utility Internal Functions | 821 | |__________________________________*/ 822 | 823 | /** 824 | * @notice Convert uint256 to string 825 | * @param _i Unsigned integer to convert to string 826 | */ 827 | function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 828 | if (_i == 0) { 829 | return "0"; 830 | } 831 | 832 | uint256 j = _i; 833 | uint256 ii = _i; 834 | uint256 len; 835 | 836 | // Get number of bytes 837 | while (j != 0) { 838 | len++; 839 | j /= 10; 840 | } 841 | 842 | bytes memory bstr = new bytes(len); 843 | uint256 k = len - 1; 844 | 845 | // Get each individual ASCII 846 | while (ii != 0) { 847 | bstr[k--] = byte(uint8(48 + ii % 10)); 848 | ii /= 10; 849 | } 850 | 851 | // Convert to string 852 | return string(bstr); 853 | } 854 | 855 | } 856 | 857 | /** 858 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume 859 | * a parent contract to be executed as they are `internal` functions 860 | */ 861 | contract ERC1155MintBurn is ERC1155 { 862 | 863 | 864 | /****************************************| 865 | | Minting Functions | 866 | |_______________________________________*/ 867 | 868 | /** 869 | * @notice Mint _amount of tokens of a given id 870 | * @param _to The address to mint tokens to 871 | * @param _id Token id to mint 872 | * @param _amount The amount to be minted 873 | * @param _data Data to pass if receiver is contract 874 | */ 875 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data) 876 | internal 877 | { 878 | // Add _amount 879 | balances[_to][_id] = balances[_to][_id].add(_amount); 880 | 881 | // Emit event 882 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount); 883 | 884 | // Calling onReceive method if recipient is contract 885 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data); 886 | } 887 | 888 | /** 889 | * @notice Mint tokens for each ids in _ids 890 | * @param _to The address to mint tokens to 891 | * @param _ids Array of ids to mint 892 | * @param _amounts Array of amount of tokens to mint per id 893 | * @param _data Data to pass if receiver is contract 894 | */ 895 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 896 | internal 897 | { 898 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH"); 899 | 900 | // Number of mints to execute 901 | uint256 nMint = _ids.length; 902 | 903 | // Executing all minting 904 | for (uint256 i = 0; i < nMint; i++) { 905 | // Update storage balance 906 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 907 | } 908 | 909 | // Emit batch mint event 910 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts); 911 | 912 | // Calling onReceive method if recipient is contract 913 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data); 914 | } 915 | 916 | 917 | /****************************************| 918 | | Burning Functions | 919 | |_______________________________________*/ 920 | 921 | /** 922 | * @notice Burn _amount of tokens of a given token id 923 | * @param _from The address to burn tokens from 924 | * @param _id Token id to burn 925 | * @param _amount The amount to be burned 926 | */ 927 | function _burn(address _from, uint256 _id, uint256 _amount) 928 | internal 929 | { 930 | //Substract _amount 931 | balances[_from][_id] = balances[_from][_id].sub(_amount); 932 | 933 | // Emit event 934 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount); 935 | } 936 | 937 | /** 938 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair 939 | * @param _from The address to burn tokens from 940 | * @param _ids Array of token ids to burn 941 | * @param _amounts Array of the amount to be burned 942 | */ 943 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts) 944 | internal 945 | { 946 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH"); 947 | 948 | // Number of mints to execute 949 | uint256 nBurn = _ids.length; 950 | 951 | // Executing all minting 952 | for (uint256 i = 0; i < nBurn; i++) { 953 | // Update storage balance 954 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 955 | } 956 | 957 | // Emit batch mint event 958 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts); 959 | } 960 | 961 | } 962 | 963 | library Strings { 964 | // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol 965 | function strConcat( 966 | string memory _a, 967 | string memory _b, 968 | string memory _c, 969 | string memory _d, 970 | string memory _e 971 | ) internal pure returns (string memory) { 972 | bytes memory _ba = bytes(_a); 973 | bytes memory _bb = bytes(_b); 974 | bytes memory _bc = bytes(_c); 975 | bytes memory _bd = bytes(_d); 976 | bytes memory _be = bytes(_e); 977 | string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); 978 | bytes memory babcde = bytes(abcde); 979 | uint256 k = 0; 980 | for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; 981 | for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; 982 | for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; 983 | for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; 984 | for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i]; 985 | return string(babcde); 986 | } 987 | 988 | function strConcat( 989 | string memory _a, 990 | string memory _b, 991 | string memory _c, 992 | string memory _d 993 | ) internal pure returns (string memory) { 994 | return strConcat(_a, _b, _c, _d, ""); 995 | } 996 | 997 | function strConcat( 998 | string memory _a, 999 | string memory _b, 1000 | string memory _c 1001 | ) internal pure returns (string memory) { 1002 | return strConcat(_a, _b, _c, "", ""); 1003 | } 1004 | 1005 | function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { 1006 | return strConcat(_a, _b, "", "", ""); 1007 | } 1008 | 1009 | function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 1010 | if (_i == 0) { 1011 | return "0"; 1012 | } 1013 | uint256 j = _i; 1014 | uint256 len; 1015 | while (j != 0) { 1016 | len++; 1017 | j /= 10; 1018 | } 1019 | bytes memory bstr = new bytes(len); 1020 | uint256 k = len - 1; 1021 | while (_i != 0) { 1022 | bstr[k--] = bytes1(uint8(48 + (_i % 10))); 1023 | _i /= 10; 1024 | } 1025 | return string(bstr); 1026 | } 1027 | } 1028 | 1029 | contract OwnableDelegateProxy {} 1030 | 1031 | contract ProxyRegistry { 1032 | mapping(address => OwnableDelegateProxy) public proxies; 1033 | } 1034 | 1035 | /** 1036 | * @title ERC1155Tradable 1037 | * ERC1155Tradable - ERC1155 contract that whitelists an operator address, 1038 | * has create and mint functionality, and supports useful standards from OpenZeppelin, 1039 | like _exists(), name(), symbol(), and totalSupply() 1040 | */ 1041 | contract ERC1155Tradable is ERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable, MinterRole, WhitelistAdminRole { 1042 | using Strings for string; 1043 | 1044 | address proxyRegistryAddress; 1045 | uint256 private _currentTokenID = 0; 1046 | mapping(uint256 => address) public creators; 1047 | mapping(uint256 => uint256) public tokenSupply; 1048 | mapping(uint256 => uint256) public tokenMaxSupply; 1049 | // Contract name 1050 | string public name; 1051 | // Contract symbol 1052 | string public symbol; 1053 | 1054 | constructor( 1055 | string memory _name, 1056 | string memory _symbol, 1057 | address _proxyRegistryAddress 1058 | ) public { 1059 | name = _name; 1060 | symbol = _symbol; 1061 | proxyRegistryAddress = _proxyRegistryAddress; 1062 | } 1063 | 1064 | function removeWhitelistAdmin(address account) public onlyOwner { 1065 | _removeWhitelistAdmin(account); 1066 | } 1067 | 1068 | function removeMinter(address account) public onlyOwner { 1069 | _removeMinter(account); 1070 | } 1071 | 1072 | function uri(uint256 _id) public view returns (string memory) { 1073 | require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN"); 1074 | return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id)); 1075 | } 1076 | 1077 | /** 1078 | * @dev Returns the total quantity for a token ID 1079 | * @param _id uint256 ID of the token to query 1080 | * @return amount of token in existence 1081 | */ 1082 | function totalSupply(uint256 _id) public view returns (uint256) { 1083 | return tokenSupply[_id]; 1084 | } 1085 | 1086 | /** 1087 | * @dev Returns the max quantity for a token ID 1088 | * @param _id uint256 ID of the token to query 1089 | * @return amount of token in existence 1090 | */ 1091 | function maxSupply(uint256 _id) public view returns (uint256) { 1092 | return tokenMaxSupply[_id]; 1093 | } 1094 | 1095 | /** 1096 | * @dev Will update the base URL of token's URI 1097 | * @param _newBaseMetadataURI New base URL of token's URI 1098 | */ 1099 | function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyWhitelistAdmin { 1100 | _setBaseMetadataURI(_newBaseMetadataURI); 1101 | } 1102 | 1103 | /** 1104 | * @dev Creates a new token type and assigns _initialSupply to an address 1105 | * @param _maxSupply max supply allowed 1106 | * @param _initialSupply Optional amount to supply the first owner 1107 | * @param _uri Optional URI for this token type 1108 | * @param _data Optional data to pass if receiver is contract 1109 | * @return The newly created token ID 1110 | */ 1111 | function create( 1112 | uint256 _maxSupply, 1113 | uint256 _initialSupply, 1114 | string calldata _uri, 1115 | bytes calldata _data 1116 | ) external onlyWhitelistAdmin returns (uint256 tokenId) { 1117 | require(_initialSupply <= _maxSupply, "Initial supply cannot be more than max supply"); 1118 | uint256 _id = _getNextTokenID(); 1119 | _incrementTokenTypeId(); 1120 | creators[_id] = msg.sender; 1121 | 1122 | if (bytes(_uri).length > 0) { 1123 | emit URI(_uri, _id); 1124 | } 1125 | 1126 | if (_initialSupply != 0) _mint(msg.sender, _id, _initialSupply, _data); 1127 | tokenSupply[_id] = _initialSupply; 1128 | tokenMaxSupply[_id] = _maxSupply; 1129 | return _id; 1130 | } 1131 | 1132 | /** 1133 | * @dev Mints some amount of tokens to an address 1134 | * @param _to Address of the future owner of the token 1135 | * @param _id Token ID to mint 1136 | * @param _quantity Amount of tokens to mint 1137 | * @param _data Data to pass if receiver is contract 1138 | */ 1139 | function mint( 1140 | address _to, 1141 | uint256 _id, 1142 | uint256 _quantity, 1143 | bytes memory _data 1144 | ) public onlyMinter { 1145 | uint256 tokenId = _id; 1146 | require(tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached"); 1147 | _mint(_to, _id, _quantity, _data); 1148 | tokenSupply[_id] = tokenSupply[_id].add(_quantity); 1149 | } 1150 | 1151 | /** 1152 | * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings. 1153 | */ 1154 | function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { 1155 | // Whitelist OpenSea proxy contract for easy trading. 1156 | ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); 1157 | if (address(proxyRegistry.proxies(_owner)) == _operator) { 1158 | return true; 1159 | } 1160 | 1161 | return ERC1155.isApprovedForAll(_owner, _operator); 1162 | } 1163 | 1164 | /** 1165 | * @dev Returns whether the specified token exists by checking to see if it has a creator 1166 | * @param _id uint256 ID of the token to query the existence of 1167 | * @return bool whether the token exists 1168 | */ 1169 | function _exists(uint256 _id) internal view returns (bool) { 1170 | return creators[_id] != address(0); 1171 | } 1172 | 1173 | /** 1174 | * @dev calculates the next token ID based on value of _currentTokenID 1175 | * @return uint256 for the next token ID 1176 | */ 1177 | function _getNextTokenID() private view returns (uint256) { 1178 | return _currentTokenID.add(1); 1179 | } 1180 | 1181 | /** 1182 | * @dev increments the value of _currentTokenID 1183 | */ 1184 | function _incrementTokenTypeId() private { 1185 | _currentTokenID++; 1186 | } 1187 | } 1188 | 1189 | /** 1190 | * @title MemeLtd 1191 | * MemeLtd - Collect limited edition NFTs from Meme Ltd 1192 | */ 1193 | contract MemeLtd is ERC1155Tradable { 1194 | constructor(address _proxyRegistryAddress) public ERC1155Tradable("Meme Ltd.", "MEMES", _proxyRegistryAddress) { 1195 | _setBaseMetadataURI("https://api.dontbuymeme.com/memes/"); 1196 | } 1197 | 1198 | function contractURI() public view returns (string memory) { 1199 | return "https://api.dontbuymeme.com/contract/memes-erc1155"; 1200 | } 1201 | } 1202 | -------------------------------------------------------------------------------- /GenesisPool.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2020-08-26 3 | */ 4 | 5 | pragma solidity ^0.5.0; 6 | 7 | 8 | /** 9 | * @dev Standard math utilities missing in the Solidity language. 10 | */ 11 | library Math { 12 | /** 13 | * @dev Returns the largest of two numbers. 14 | */ 15 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 16 | return a >= b ? a : b; 17 | } 18 | 19 | /** 20 | * @dev Returns the smallest of two numbers. 21 | */ 22 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 23 | return a < b ? a : b; 24 | } 25 | 26 | /** 27 | * @dev Returns the average of two numbers. The result is rounded towards 28 | * zero. 29 | */ 30 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 31 | // (a + b) / 2 can overflow, so we distribute 32 | return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); 33 | } 34 | } 35 | 36 | /* 37 | * @dev Provides information about the current execution context, including the 38 | * sender of the transaction and its data. While these are generally available 39 | * via msg.sender and msg.data, they should not be accessed in such a direct 40 | * manner, since when dealing with GSN meta-transactions the account sending and 41 | * paying for execution may not be the actual sender (as far as an application 42 | * is concerned). 43 | * 44 | * This contract is only required for intermediate, library-like contracts. 45 | */ 46 | contract Context { 47 | // Empty internal constructor, to prevent people from mistakenly deploying 48 | // an instance of this contract, which should be used via inheritance. 49 | constructor () internal { } 50 | // solhint-disable-previous-line no-empty-blocks 51 | 52 | function _msgSender() internal view returns (address payable) { 53 | return msg.sender; 54 | } 55 | 56 | function _msgData() internal view returns (bytes memory) { 57 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 58 | return msg.data; 59 | } 60 | } 61 | 62 | /** 63 | * @dev Contract module which provides a basic access control mechanism, where 64 | * there is an account (an owner) that can be granted exclusive access to 65 | * specific functions. 66 | * 67 | * This module is used through inheritance. It will make available the modifier 68 | * `onlyOwner`, which can be applied to your functions to restrict their use to 69 | * the owner. 70 | */ 71 | contract Ownable is Context { 72 | address private _owner; 73 | 74 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 75 | 76 | /** 77 | * @dev Initializes the contract setting the deployer as the initial owner. 78 | */ 79 | constructor () internal { 80 | address msgSender = _msgSender(); 81 | _owner = msgSender; 82 | emit OwnershipTransferred(address(0), msgSender); 83 | } 84 | 85 | /** 86 | * @dev Returns the address of the current owner. 87 | */ 88 | function owner() public view returns (address) { 89 | return _owner; 90 | } 91 | 92 | /** 93 | * @dev Throws if called by any account other than the owner. 94 | */ 95 | modifier onlyOwner() { 96 | require(isOwner(), "Ownable: caller is not the owner"); 97 | _; 98 | } 99 | 100 | /** 101 | * @dev Returns true if the caller is the current owner. 102 | */ 103 | function isOwner() public view returns (bool) { 104 | return _msgSender() == _owner; 105 | } 106 | 107 | /** 108 | * @dev Leaves the contract without owner. It will not be possible to call 109 | * `onlyOwner` functions anymore. Can only be called by the current owner. 110 | * 111 | * NOTE: Renouncing ownership will leave the contract without an owner, 112 | * thereby removing any functionality that is only available to the owner. 113 | */ 114 | function renounceOwnership() public onlyOwner { 115 | emit OwnershipTransferred(_owner, address(0)); 116 | _owner = address(0); 117 | } 118 | 119 | /** 120 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 121 | * Can only be called by the current owner. 122 | */ 123 | function transferOwnership(address newOwner) public onlyOwner { 124 | _transferOwnership(newOwner); 125 | } 126 | 127 | /** 128 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 129 | */ 130 | function _transferOwnership(address newOwner) internal { 131 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 132 | emit OwnershipTransferred(_owner, newOwner); 133 | _owner = newOwner; 134 | } 135 | } 136 | 137 | /** 138 | * @dev Interface of the ERC20 standard as defined in the EIP. Does not include 139 | * the optional functions; to access them see {ERC20Detailed}. 140 | */ 141 | interface IERC20 { 142 | /** 143 | * @dev Returns the amount of tokens in existence. 144 | */ 145 | function totalSupply() external view returns (uint256); 146 | 147 | /** 148 | * @dev Returns the amount of tokens owned by `account`. 149 | */ 150 | function balanceOf(address account) external view returns (uint256); 151 | 152 | /** 153 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 154 | * 155 | * Returns a boolean value indicating whether the operation succeeded. 156 | * 157 | * Emits a {Transfer} event. 158 | */ 159 | function transfer(address recipient, uint256 amount) external returns (bool); 160 | 161 | /** 162 | * @dev Returns the remaining number of tokens that `spender` will be 163 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 164 | * zero by default. 165 | * 166 | * This value changes when {approve} or {transferFrom} are called. 167 | */ 168 | function allowance(address owner, address spender) external view returns (uint256); 169 | 170 | /** 171 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 172 | * 173 | * Returns a boolean value indicating whether the operation succeeded. 174 | * 175 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 176 | * that someone may use both the old and the new allowance by unfortunate 177 | * transaction ordering. One possible solution to mitigate this race 178 | * condition is to first reduce the spender's allowance to 0 and set the 179 | * desired value afterwards: 180 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 181 | * 182 | * Emits an {Approval} event. 183 | */ 184 | function approve(address spender, uint256 amount) external returns (bool); 185 | 186 | /** 187 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 188 | * allowance mechanism. `amount` is then deducted from the caller's 189 | * allowance. 190 | * 191 | * Returns a boolean value indicating whether the operation succeeded. 192 | * 193 | * Emits a {Transfer} event. 194 | */ 195 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 196 | 197 | /** 198 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 199 | * another (`to`). 200 | * 201 | * Note that `value` may be zero. 202 | */ 203 | event Transfer(address indexed from, address indexed to, uint256 value); 204 | 205 | /** 206 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 207 | * a call to {approve}. `value` is the new allowance. 208 | */ 209 | event Approval(address indexed owner, address indexed spender, uint256 value); 210 | } 211 | 212 | /** 213 | * @title Roles 214 | * @dev Library for managing addresses assigned to a Role. 215 | */ 216 | library Roles { 217 | struct Role { 218 | mapping (address => bool) bearer; 219 | } 220 | 221 | /** 222 | * @dev Give an account access to this role. 223 | */ 224 | function add(Role storage role, address account) internal { 225 | require(!has(role, account), "Roles: account already has role"); 226 | role.bearer[account] = true; 227 | } 228 | 229 | /** 230 | * @dev Remove an account's access to this role. 231 | */ 232 | function remove(Role storage role, address account) internal { 233 | require(has(role, account), "Roles: account does not have role"); 234 | role.bearer[account] = false; 235 | } 236 | 237 | /** 238 | * @dev Check if an account has this role. 239 | * @return bool 240 | */ 241 | function has(Role storage role, address account) internal view returns (bool) { 242 | require(account != address(0), "Roles: account is the zero address"); 243 | return role.bearer[account]; 244 | } 245 | } 246 | 247 | contract MinterRole is Context { 248 | using Roles for Roles.Role; 249 | 250 | event MinterAdded(address indexed account); 251 | event MinterRemoved(address indexed account); 252 | 253 | Roles.Role private _minters; 254 | 255 | constructor () internal { 256 | _addMinter(_msgSender()); 257 | } 258 | 259 | modifier onlyMinter() { 260 | require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role"); 261 | _; 262 | } 263 | 264 | function isMinter(address account) public view returns (bool) { 265 | return _minters.has(account); 266 | } 267 | 268 | function addMinter(address account) public onlyMinter { 269 | _addMinter(account); 270 | } 271 | 272 | function renounceMinter() public { 273 | _removeMinter(_msgSender()); 274 | } 275 | 276 | function _addMinter(address account) internal { 277 | _minters.add(account); 278 | emit MinterAdded(account); 279 | } 280 | 281 | function _removeMinter(address account) internal { 282 | _minters.remove(account); 283 | emit MinterRemoved(account); 284 | } 285 | } 286 | 287 | /** 288 | * @title WhitelistAdminRole 289 | * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. 290 | */ 291 | contract WhitelistAdminRole is Context { 292 | using Roles for Roles.Role; 293 | 294 | event WhitelistAdminAdded(address indexed account); 295 | event WhitelistAdminRemoved(address indexed account); 296 | 297 | Roles.Role private _whitelistAdmins; 298 | 299 | constructor () internal { 300 | _addWhitelistAdmin(_msgSender()); 301 | } 302 | 303 | modifier onlyWhitelistAdmin() { 304 | require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); 305 | _; 306 | } 307 | 308 | function isWhitelistAdmin(address account) public view returns (bool) { 309 | return _whitelistAdmins.has(account); 310 | } 311 | 312 | function addWhitelistAdmin(address account) public onlyWhitelistAdmin { 313 | _addWhitelistAdmin(account); 314 | } 315 | 316 | function renounceWhitelistAdmin() public { 317 | _removeWhitelistAdmin(_msgSender()); 318 | } 319 | 320 | function _addWhitelistAdmin(address account) internal { 321 | _whitelistAdmins.add(account); 322 | emit WhitelistAdminAdded(account); 323 | } 324 | 325 | function _removeWhitelistAdmin(address account) internal { 326 | _whitelistAdmins.remove(account); 327 | emit WhitelistAdminRemoved(account); 328 | } 329 | } 330 | 331 | /** 332 | * @title ERC165 333 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md 334 | */ 335 | interface IERC165 { 336 | 337 | /** 338 | * @notice Query if a contract implements an interface 339 | * @dev Interface identification is specified in ERC-165. This function 340 | * uses less than 30,000 gas 341 | * @param _interfaceId The interface identifier, as specified in ERC-165 342 | */ 343 | function supportsInterface(bytes4 _interfaceId) 344 | external 345 | view 346 | returns (bool); 347 | } 348 | 349 | /** 350 | * @title SafeMath 351 | * @dev Unsigned math operations with safety checks that revert on error 352 | */ 353 | library SafeMath { 354 | 355 | /** 356 | * @dev Multiplies two unsigned integers, reverts on overflow. 357 | */ 358 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 359 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 360 | // benefit is lost if 'b' is also tested. 361 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 362 | if (a == 0) { 363 | return 0; 364 | } 365 | 366 | uint256 c = a * b; 367 | require(c / a == b, "SafeMath#mul: OVERFLOW"); 368 | 369 | return c; 370 | } 371 | 372 | /** 373 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 374 | */ 375 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 376 | // Solidity only automatically asserts when dividing by 0 377 | require(b > 0, "SafeMath#div: DIVISION_BY_ZERO"); 378 | uint256 c = a / b; 379 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 380 | 381 | return c; 382 | } 383 | 384 | /** 385 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 386 | */ 387 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 388 | require(b <= a, "SafeMath#sub: UNDERFLOW"); 389 | uint256 c = a - b; 390 | 391 | return c; 392 | } 393 | 394 | /** 395 | * @dev Adds two unsigned integers, reverts on overflow. 396 | */ 397 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 398 | uint256 c = a + b; 399 | require(c >= a, "SafeMath#add: OVERFLOW"); 400 | 401 | return c; 402 | } 403 | 404 | /** 405 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 406 | * reverts when dividing by zero. 407 | */ 408 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 409 | require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO"); 410 | return a % b; 411 | } 412 | 413 | } 414 | 415 | /** 416 | * @dev ERC-1155 interface for accepting safe transfers. 417 | */ 418 | interface IERC1155TokenReceiver { 419 | 420 | /** 421 | * @notice Handle the receipt of a single ERC1155 token type 422 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated 423 | * This function MAY throw to revert and reject the transfer 424 | * Return of other amount than the magic value MUST result in the transaction being reverted 425 | * Note: The token contract address is always the message sender 426 | * @param _operator The address which called the `safeTransferFrom` function 427 | * @param _from The address which previously owned the token 428 | * @param _id The id of the token being transferred 429 | * @param _amount The amount of tokens being transferred 430 | * @param _data Additional data with no specified format 431 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 432 | */ 433 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4); 434 | 435 | /** 436 | * @notice Handle the receipt of multiple ERC1155 token types 437 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated 438 | * This function MAY throw to revert and reject the transfer 439 | * Return of other amount than the magic value WILL result in the transaction being reverted 440 | * Note: The token contract address is always the message sender 441 | * @param _operator The address which called the `safeBatchTransferFrom` function 442 | * @param _from The address which previously owned the token 443 | * @param _ids An array containing ids of each token being transferred 444 | * @param _amounts An array containing amounts of each token being transferred 445 | * @param _data Additional data with no specified format 446 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 447 | */ 448 | function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4); 449 | 450 | /** 451 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types. 452 | * @param interfaceID The ERC-165 interface ID that is queried for support.s 453 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface. 454 | * This function MUST NOT consume more than 5,000 gas. 455 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported. 456 | */ 457 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 458 | 459 | } 460 | 461 | interface IERC1155 { 462 | // Events 463 | 464 | /** 465 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 466 | * Operator MUST be msg.sender 467 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 468 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 469 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 470 | * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 471 | */ 472 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 473 | 474 | /** 475 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 476 | * Operator MUST be msg.sender 477 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 478 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 479 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 480 | * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 481 | */ 482 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 483 | 484 | /** 485 | * @dev MUST emit when an approval is updated 486 | */ 487 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 488 | 489 | /** 490 | * @dev MUST emit when the URI is updated for a token ID 491 | * URIs are defined in RFC 3986 492 | * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema" 493 | */ 494 | event URI(string _amount, uint256 indexed _id); 495 | 496 | /** 497 | * @notice Transfers amount of an _id from the _from address to the _to address specified 498 | * @dev MUST emit TransferSingle event on success 499 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 500 | * MUST throw if `_to` is the zero address 501 | * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent 502 | * MUST throw on any other error 503 | * 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 amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 504 | * @param _from Source address 505 | * @param _to Target address 506 | * @param _id ID of the token type 507 | * @param _amount Transfered amount 508 | * @param _data Additional data with no specified format, sent in call to `_to` 509 | */ 510 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external; 511 | 512 | /** 513 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 514 | * @dev MUST emit TransferBatch event on success 515 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 516 | * MUST throw if `_to` is the zero address 517 | * MUST throw if length of `_ids` is not the same as length of `_amounts` 518 | * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent 519 | * MUST throw on any other error 520 | * 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 amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 521 | * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc) 522 | * @param _from Source addresses 523 | * @param _to Target addresses 524 | * @param _ids IDs of each token type 525 | * @param _amounts Transfer amounts per token type 526 | * @param _data Additional data with no specified format, sent in call to `_to` 527 | */ 528 | function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external; 529 | 530 | /** 531 | * @notice Get the balance of an account's Tokens 532 | * @param _owner The address of the token holder 533 | * @param _id ID of the Token 534 | * @return The _owner's balance of the Token type requested 535 | */ 536 | function balanceOf(address _owner, uint256 _id) external view returns (uint256); 537 | 538 | /** 539 | * @notice Get the balance of multiple account/token pairs 540 | * @param _owners The addresses of the token holders 541 | * @param _ids ID of the Tokens 542 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 543 | */ 544 | function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); 545 | 546 | /** 547 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 548 | * @dev MUST emit the ApprovalForAll event on success 549 | * @param _operator Address to add to the set of authorized operators 550 | * @param _approved True if the operator is approved, false to revoke approval 551 | */ 552 | function setApprovalForAll(address _operator, bool _approved) external; 553 | 554 | /** 555 | * @notice Queries the approval status of an operator for a given owner 556 | * @param _owner The owner of the Tokens 557 | * @param _operator Address of authorized operator 558 | * @return True if the operator is approved, false if not 559 | */ 560 | function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator); 561 | 562 | } 563 | 564 | /** 565 | * Copyright 2018 ZeroEx Intl. 566 | * Licensed under the Apache License, Version 2.0 (the "License"); 567 | * you may not use this file except in compliance with the License. 568 | * You may obtain a copy of the License at 569 | * http://www.apache.org/licenses/LICENSE-2.0 570 | * Unless required by applicable law or agreed to in writing, software 571 | * distributed under the License is distributed on an "AS IS" BASIS, 572 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 573 | * See the License for the specific language governing permissions and 574 | * limitations under the License. 575 | */ 576 | /** 577 | * Utility library of inline functions on addresses 578 | */ 579 | library Address { 580 | 581 | /** 582 | * Returns whether the target address is a contract 583 | * @dev This function will return false if invoked during the constructor of a contract, 584 | * as the code is not actually created until after the constructor finishes. 585 | * @param account address of the account to check 586 | * @return whether the target address is a contract 587 | */ 588 | function isContract(address account) internal view returns (bool) { 589 | bytes32 codehash; 590 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 591 | 592 | // XXX Currently there is no better way to check if there is a contract in an address 593 | // than to check the size of the code at that address. 594 | // See https://ethereum.stackexchange.com/a/14016/36603 595 | // for more details about how this works. 596 | // TODO Check this again before the Serenity release, because all addresses will be 597 | // contracts then. 598 | assembly { codehash := extcodehash(account) } 599 | return (codehash != 0x0 && codehash != accountHash); 600 | } 601 | 602 | } 603 | 604 | /** 605 | * @dev Implementation of Multi-Token Standard contract 606 | */ 607 | contract ERC1155 is IERC165 { 608 | using SafeMath for uint256; 609 | using Address for address; 610 | 611 | 612 | /***********************************| 613 | | Variables and Events | 614 | |__________________________________*/ 615 | 616 | // onReceive function signatures 617 | bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61; 618 | bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; 619 | 620 | // Objects balances 621 | mapping (address => mapping(uint256 => uint256)) internal balances; 622 | 623 | // Operator Functions 624 | mapping (address => mapping(address => bool)) internal operators; 625 | 626 | // Events 627 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 628 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 629 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 630 | event URI(string _uri, uint256 indexed _id); 631 | 632 | 633 | /***********************************| 634 | | Public Transfer Functions | 635 | |__________________________________*/ 636 | 637 | /** 638 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 639 | * @param _from Source address 640 | * @param _to Target address 641 | * @param _id ID of the token type 642 | * @param _amount Transfered amount 643 | * @param _data Additional data with no specified format, sent in call to `_to` 644 | */ 645 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 646 | public 647 | { 648 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR"); 649 | require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT"); 650 | // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations 651 | 652 | _safeTransferFrom(_from, _to, _id, _amount); 653 | _callonERC1155Received(_from, _to, _id, _amount, _data); 654 | } 655 | 656 | /** 657 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 658 | * @param _from Source addresses 659 | * @param _to Target addresses 660 | * @param _ids IDs of each token type 661 | * @param _amounts Transfer amounts per token type 662 | * @param _data Additional data with no specified format, sent in call to `_to` 663 | */ 664 | function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 665 | public 666 | { 667 | // Requirements 668 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR"); 669 | require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT"); 670 | 671 | _safeBatchTransferFrom(_from, _to, _ids, _amounts); 672 | _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data); 673 | } 674 | 675 | 676 | /***********************************| 677 | | Internal Transfer Functions | 678 | |__________________________________*/ 679 | 680 | /** 681 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 682 | * @param _from Source address 683 | * @param _to Target address 684 | * @param _id ID of the token type 685 | * @param _amount Transfered amount 686 | */ 687 | function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) 688 | internal 689 | { 690 | // Update balances 691 | balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount 692 | balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount 693 | 694 | // Emit event 695 | emit TransferSingle(msg.sender, _from, _to, _id, _amount); 696 | } 697 | 698 | /** 699 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...) 700 | */ 701 | function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 702 | internal 703 | { 704 | // Check if recipient is contract 705 | if (_to.isContract()) { 706 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data); 707 | require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE"); 708 | } 709 | } 710 | 711 | /** 712 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 713 | * @param _from Source addresses 714 | * @param _to Target addresses 715 | * @param _ids IDs of each token type 716 | * @param _amounts Transfer amounts per token type 717 | */ 718 | function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts) 719 | internal 720 | { 721 | require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH"); 722 | 723 | // Number of transfer to execute 724 | uint256 nTransfer = _ids.length; 725 | 726 | // Executing all transfers 727 | for (uint256 i = 0; i < nTransfer; i++) { 728 | // Update storage balance of previous bin 729 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 730 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 731 | } 732 | 733 | // Emit event 734 | emit TransferBatch(msg.sender, _from, _to, _ids, _amounts); 735 | } 736 | 737 | /** 738 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...) 739 | */ 740 | function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 741 | internal 742 | { 743 | // Pass data if recipient is contract 744 | if (_to.isContract()) { 745 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data); 746 | require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE"); 747 | } 748 | } 749 | 750 | 751 | /***********************************| 752 | | Operator Functions | 753 | |__________________________________*/ 754 | 755 | /** 756 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 757 | * @param _operator Address to add to the set of authorized operators 758 | * @param _approved True if the operator is approved, false to revoke approval 759 | */ 760 | function setApprovalForAll(address _operator, bool _approved) 761 | external 762 | { 763 | // Update operator status 764 | operators[msg.sender][_operator] = _approved; 765 | emit ApprovalForAll(msg.sender, _operator, _approved); 766 | } 767 | 768 | /** 769 | * @notice Queries the approval status of an operator for a given owner 770 | * @param _owner The owner of the Tokens 771 | * @param _operator Address of authorized operator 772 | * @return True if the operator is approved, false if not 773 | */ 774 | function isApprovedForAll(address _owner, address _operator) 775 | public view returns (bool isOperator) 776 | { 777 | return operators[_owner][_operator]; 778 | } 779 | 780 | 781 | /***********************************| 782 | | Balance Functions | 783 | |__________________________________*/ 784 | 785 | /** 786 | * @notice Get the balance of an account's Tokens 787 | * @param _owner The address of the token holder 788 | * @param _id ID of the Token 789 | * @return The _owner's balance of the Token type requested 790 | */ 791 | function balanceOf(address _owner, uint256 _id) 792 | public view returns (uint256) 793 | { 794 | return balances[_owner][_id]; 795 | } 796 | 797 | /** 798 | * @notice Get the balance of multiple account/token pairs 799 | * @param _owners The addresses of the token holders 800 | * @param _ids ID of the Tokens 801 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 802 | */ 803 | function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) 804 | public view returns (uint256[] memory) 805 | { 806 | require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH"); 807 | 808 | // Variables 809 | uint256[] memory batchBalances = new uint256[](_owners.length); 810 | 811 | // Iterate over each owner and token ID 812 | for (uint256 i = 0; i < _owners.length; i++) { 813 | batchBalances[i] = balances[_owners[i]][_ids[i]]; 814 | } 815 | 816 | return batchBalances; 817 | } 818 | 819 | 820 | /***********************************| 821 | | ERC165 Functions | 822 | |__________________________________*/ 823 | 824 | /** 825 | * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)")); 826 | */ 827 | bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; 828 | 829 | /** 830 | * INTERFACE_SIGNATURE_ERC1155 = 831 | * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^ 832 | * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^ 833 | * bytes4(keccak256("balanceOf(address,uint256)")) ^ 834 | * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^ 835 | * bytes4(keccak256("setApprovalForAll(address,bool)")) ^ 836 | * bytes4(keccak256("isApprovedForAll(address,address)")); 837 | */ 838 | bytes4 constant private INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; 839 | 840 | /** 841 | * @notice Query if a contract implements an interface 842 | * @param _interfaceID The interface identifier, as specified in ERC-165 843 | * @return `true` if the contract implements `_interfaceID` and 844 | */ 845 | function supportsInterface(bytes4 _interfaceID) external view returns (bool) { 846 | if (_interfaceID == INTERFACE_SIGNATURE_ERC165 || 847 | _interfaceID == INTERFACE_SIGNATURE_ERC1155) { 848 | return true; 849 | } 850 | return false; 851 | } 852 | 853 | } 854 | 855 | /** 856 | * @notice Contract that handles metadata related methods. 857 | * @dev Methods assume a deterministic generation of URI based on token IDs. 858 | * Methods also assume that URI uses hex representation of token IDs. 859 | */ 860 | contract ERC1155Metadata { 861 | 862 | // URI's default URI prefix 863 | string internal baseMetadataURI; 864 | event URI(string _uri, uint256 indexed _id); 865 | 866 | 867 | /***********************************| 868 | | Metadata Public Function s | 869 | |__________________________________*/ 870 | 871 | /** 872 | * @notice A distinct Uniform Resource Identifier (URI) for a given token. 873 | * @dev URIs are defined in RFC 3986. 874 | * URIs are assumed to be deterministically generated based on token ID 875 | * Token IDs are assumed to be represented in their hex format in URIs 876 | * @return URI string 877 | */ 878 | function uri(uint256 _id) public view returns (string memory) { 879 | return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json")); 880 | } 881 | 882 | 883 | /***********************************| 884 | | Metadata Internal Functions | 885 | |__________________________________*/ 886 | 887 | /** 888 | * @notice Will emit default URI log event for corresponding token _id 889 | * @param _tokenIDs Array of IDs of tokens to log default URI 890 | */ 891 | function _logURIs(uint256[] memory _tokenIDs) internal { 892 | string memory baseURL = baseMetadataURI; 893 | string memory tokenURI; 894 | 895 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 896 | tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json")); 897 | emit URI(tokenURI, _tokenIDs[i]); 898 | } 899 | } 900 | 901 | /** 902 | * @notice Will emit a specific URI log event for corresponding token 903 | * @param _tokenIDs IDs of the token corresponding to the _uris logged 904 | * @param _URIs The URIs of the specified _tokenIDs 905 | */ 906 | function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal { 907 | require(_tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH"); 908 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 909 | emit URI(_URIs[i], _tokenIDs[i]); 910 | } 911 | } 912 | 913 | /** 914 | * @notice Will update the base URL of token's URI 915 | * @param _newBaseMetadataURI New base URL of token's URI 916 | */ 917 | function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal { 918 | baseMetadataURI = _newBaseMetadataURI; 919 | } 920 | 921 | 922 | /***********************************| 923 | | Utility Internal Functions | 924 | |__________________________________*/ 925 | 926 | /** 927 | * @notice Convert uint256 to string 928 | * @param _i Unsigned integer to convert to string 929 | */ 930 | function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 931 | if (_i == 0) { 932 | return "0"; 933 | } 934 | 935 | uint256 j = _i; 936 | uint256 ii = _i; 937 | uint256 len; 938 | 939 | // Get number of bytes 940 | while (j != 0) { 941 | len++; 942 | j /= 10; 943 | } 944 | 945 | bytes memory bstr = new bytes(len); 946 | uint256 k = len - 1; 947 | 948 | // Get each individual ASCII 949 | while (ii != 0) { 950 | bstr[k--] = byte(uint8(48 + ii % 10)); 951 | ii /= 10; 952 | } 953 | 954 | // Convert to string 955 | return string(bstr); 956 | } 957 | 958 | } 959 | 960 | /** 961 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume 962 | * a parent contract to be executed as they are `internal` functions 963 | */ 964 | contract ERC1155MintBurn is ERC1155 { 965 | 966 | 967 | /****************************************| 968 | | Minting Functions | 969 | |_______________________________________*/ 970 | 971 | /** 972 | * @notice Mint _amount of tokens of a given id 973 | * @param _to The address to mint tokens to 974 | * @param _id Token id to mint 975 | * @param _amount The amount to be minted 976 | * @param _data Data to pass if receiver is contract 977 | */ 978 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data) 979 | internal 980 | { 981 | // Add _amount 982 | balances[_to][_id] = balances[_to][_id].add(_amount); 983 | 984 | // Emit event 985 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount); 986 | 987 | // Calling onReceive method if recipient is contract 988 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data); 989 | } 990 | 991 | /** 992 | * @notice Mint tokens for each ids in _ids 993 | * @param _to The address to mint tokens to 994 | * @param _ids Array of ids to mint 995 | * @param _amounts Array of amount of tokens to mint per id 996 | * @param _data Data to pass if receiver is contract 997 | */ 998 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 999 | internal 1000 | { 1001 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH"); 1002 | 1003 | // Number of mints to execute 1004 | uint256 nMint = _ids.length; 1005 | 1006 | // Executing all minting 1007 | for (uint256 i = 0; i < nMint; i++) { 1008 | // Update storage balance 1009 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 1010 | } 1011 | 1012 | // Emit batch mint event 1013 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts); 1014 | 1015 | // Calling onReceive method if recipient is contract 1016 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data); 1017 | } 1018 | 1019 | 1020 | /****************************************| 1021 | | Burning Functions | 1022 | |_______________________________________*/ 1023 | 1024 | /** 1025 | * @notice Burn _amount of tokens of a given token id 1026 | * @param _from The address to burn tokens from 1027 | * @param _id Token id to burn 1028 | * @param _amount The amount to be burned 1029 | */ 1030 | function _burn(address _from, uint256 _id, uint256 _amount) 1031 | internal 1032 | { 1033 | //Substract _amount 1034 | balances[_from][_id] = balances[_from][_id].sub(_amount); 1035 | 1036 | // Emit event 1037 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount); 1038 | } 1039 | 1040 | /** 1041 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair 1042 | * @param _from The address to burn tokens from 1043 | * @param _ids Array of token ids to burn 1044 | * @param _amounts Array of the amount to be burned 1045 | */ 1046 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts) 1047 | internal 1048 | { 1049 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH"); 1050 | 1051 | // Number of mints to execute 1052 | uint256 nBurn = _ids.length; 1053 | 1054 | // Executing all minting 1055 | for (uint256 i = 0; i < nBurn; i++) { 1056 | // Update storage balance 1057 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 1058 | } 1059 | 1060 | // Emit batch mint event 1061 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts); 1062 | } 1063 | 1064 | } 1065 | 1066 | library Strings { 1067 | // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol 1068 | function strConcat( 1069 | string memory _a, 1070 | string memory _b, 1071 | string memory _c, 1072 | string memory _d, 1073 | string memory _e 1074 | ) internal pure returns (string memory) { 1075 | bytes memory _ba = bytes(_a); 1076 | bytes memory _bb = bytes(_b); 1077 | bytes memory _bc = bytes(_c); 1078 | bytes memory _bd = bytes(_d); 1079 | bytes memory _be = bytes(_e); 1080 | string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); 1081 | bytes memory babcde = bytes(abcde); 1082 | uint256 k = 0; 1083 | for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; 1084 | for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; 1085 | for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; 1086 | for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; 1087 | for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i]; 1088 | return string(babcde); 1089 | } 1090 | 1091 | function strConcat( 1092 | string memory _a, 1093 | string memory _b, 1094 | string memory _c, 1095 | string memory _d 1096 | ) internal pure returns (string memory) { 1097 | return strConcat(_a, _b, _c, _d, ""); 1098 | } 1099 | 1100 | function strConcat( 1101 | string memory _a, 1102 | string memory _b, 1103 | string memory _c 1104 | ) internal pure returns (string memory) { 1105 | return strConcat(_a, _b, _c, "", ""); 1106 | } 1107 | 1108 | function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { 1109 | return strConcat(_a, _b, "", "", ""); 1110 | } 1111 | 1112 | function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 1113 | if (_i == 0) { 1114 | return "0"; 1115 | } 1116 | uint256 j = _i; 1117 | uint256 len; 1118 | while (j != 0) { 1119 | len++; 1120 | j /= 10; 1121 | } 1122 | bytes memory bstr = new bytes(len); 1123 | uint256 k = len - 1; 1124 | while (_i != 0) { 1125 | bstr[k--] = bytes1(uint8(48 + (_i % 10))); 1126 | _i /= 10; 1127 | } 1128 | return string(bstr); 1129 | } 1130 | } 1131 | 1132 | contract OwnableDelegateProxy {} 1133 | 1134 | contract ProxyRegistry { 1135 | mapping(address => OwnableDelegateProxy) public proxies; 1136 | } 1137 | 1138 | /** 1139 | * @title ERC1155Tradable 1140 | * ERC1155Tradable - ERC1155 contract that whitelists an operator address, 1141 | * has create and mint functionality, and supports useful standards from OpenZeppelin, 1142 | like _exists(), name(), symbol(), and totalSupply() 1143 | */ 1144 | contract ERC1155Tradable is ERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable, MinterRole, WhitelistAdminRole { 1145 | using Strings for string; 1146 | 1147 | address proxyRegistryAddress; 1148 | uint256 private _currentTokenID = 0; 1149 | mapping(uint256 => address) public creators; 1150 | mapping(uint256 => uint256) public tokenSupply; 1151 | mapping(uint256 => uint256) public tokenMaxSupply; 1152 | // Contract name 1153 | string public name; 1154 | // Contract symbol 1155 | string public symbol; 1156 | 1157 | constructor( 1158 | string memory _name, 1159 | string memory _symbol, 1160 | address _proxyRegistryAddress 1161 | ) public { 1162 | name = _name; 1163 | symbol = _symbol; 1164 | proxyRegistryAddress = _proxyRegistryAddress; 1165 | } 1166 | 1167 | function removeWhitelistAdmin(address account) public onlyOwner { 1168 | _removeWhitelistAdmin(account); 1169 | } 1170 | 1171 | function removeMinter(address account) public onlyOwner { 1172 | _removeMinter(account); 1173 | } 1174 | 1175 | function uri(uint256 _id) public view returns (string memory) { 1176 | require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN"); 1177 | return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id)); 1178 | } 1179 | 1180 | /** 1181 | * @dev Returns the total quantity for a token ID 1182 | * @param _id uint256 ID of the token to query 1183 | * @return amount of token in existence 1184 | */ 1185 | function totalSupply(uint256 _id) public view returns (uint256) { 1186 | return tokenSupply[_id]; 1187 | } 1188 | 1189 | /** 1190 | * @dev Returns the max quantity for a token ID 1191 | * @param _id uint256 ID of the token to query 1192 | * @return amount of token in existence 1193 | */ 1194 | function maxSupply(uint256 _id) public view returns (uint256) { 1195 | return tokenMaxSupply[_id]; 1196 | } 1197 | 1198 | /** 1199 | * @dev Will update the base URL of token's URI 1200 | * @param _newBaseMetadataURI New base URL of token's URI 1201 | */ 1202 | function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyWhitelistAdmin { 1203 | _setBaseMetadataURI(_newBaseMetadataURI); 1204 | } 1205 | 1206 | /** 1207 | * @dev Creates a new token type and assigns _initialSupply to an address 1208 | * @param _maxSupply max supply allowed 1209 | * @param _initialSupply Optional amount to supply the first owner 1210 | * @param _uri Optional URI for this token type 1211 | * @param _data Optional data to pass if receiver is contract 1212 | * @return The newly created token ID 1213 | */ 1214 | function create( 1215 | uint256 _maxSupply, 1216 | uint256 _initialSupply, 1217 | string calldata _uri, 1218 | bytes calldata _data 1219 | ) external onlyWhitelistAdmin returns (uint256 tokenId) { 1220 | require(_initialSupply <= _maxSupply, "Initial supply cannot be more than max supply"); 1221 | uint256 _id = _getNextTokenID(); 1222 | _incrementTokenTypeId(); 1223 | creators[_id] = msg.sender; 1224 | 1225 | if (bytes(_uri).length > 0) { 1226 | emit URI(_uri, _id); 1227 | } 1228 | 1229 | if (_initialSupply != 0) _mint(msg.sender, _id, _initialSupply, _data); 1230 | tokenSupply[_id] = _initialSupply; 1231 | tokenMaxSupply[_id] = _maxSupply; 1232 | return _id; 1233 | } 1234 | 1235 | /** 1236 | * @dev Mints some amount of tokens to an address 1237 | * @param _to Address of the future owner of the token 1238 | * @param _id Token ID to mint 1239 | * @param _quantity Amount of tokens to mint 1240 | * @param _data Data to pass if receiver is contract 1241 | */ 1242 | function mint( 1243 | address _to, 1244 | uint256 _id, 1245 | uint256 _quantity, 1246 | bytes memory _data 1247 | ) public onlyMinter { 1248 | uint256 tokenId = _id; 1249 | require(tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached"); 1250 | _mint(_to, _id, _quantity, _data); 1251 | tokenSupply[_id] = tokenSupply[_id].add(_quantity); 1252 | } 1253 | 1254 | /** 1255 | * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings. 1256 | */ 1257 | function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { 1258 | // Whitelist OpenSea proxy contract for easy trading. 1259 | ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); 1260 | if (address(proxyRegistry.proxies(_owner)) == _operator) { 1261 | return true; 1262 | } 1263 | 1264 | return ERC1155.isApprovedForAll(_owner, _operator); 1265 | } 1266 | 1267 | /** 1268 | * @dev Returns whether the specified token exists by checking to see if it has a creator 1269 | * @param _id uint256 ID of the token to query the existence of 1270 | * @return bool whether the token exists 1271 | */ 1272 | function _exists(uint256 _id) internal view returns (bool) { 1273 | return creators[_id] != address(0); 1274 | } 1275 | 1276 | /** 1277 | * @dev calculates the next token ID based on value of _currentTokenID 1278 | * @return uint256 for the next token ID 1279 | */ 1280 | function _getNextTokenID() private view returns (uint256) { 1281 | return _currentTokenID.add(1); 1282 | } 1283 | 1284 | /** 1285 | * @dev increments the value of _currentTokenID 1286 | */ 1287 | function _incrementTokenTypeId() private { 1288 | _currentTokenID++; 1289 | } 1290 | } 1291 | 1292 | contract MemeTokenWrapper { 1293 | using SafeMath for uint256; 1294 | IERC20 public meme; 1295 | 1296 | constructor(IERC20 _memeAddress) public { 1297 | meme = IERC20(_memeAddress); 1298 | } 1299 | 1300 | uint256 private _totalSupply; 1301 | mapping(address => uint256) private _balances; 1302 | 1303 | function totalSupply() public view returns (uint256) { 1304 | return _totalSupply; 1305 | } 1306 | 1307 | function balanceOf(address account) public view returns (uint256) { 1308 | return _balances[account]; 1309 | } 1310 | 1311 | function stake(uint256 amount) public { 1312 | _totalSupply = _totalSupply.add(amount); 1313 | _balances[msg.sender] = _balances[msg.sender].add(amount); 1314 | meme.transferFrom(msg.sender, address(this), amount); 1315 | } 1316 | 1317 | function withdraw(uint256 amount) public { 1318 | _totalSupply = _totalSupply.sub(amount); 1319 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 1320 | meme.transfer(msg.sender, amount); 1321 | } 1322 | } 1323 | 1324 | contract GenesisPool is MemeTokenWrapper, Ownable { 1325 | ERC1155Tradable public memes; 1326 | 1327 | mapping(address => uint256) public lastUpdateTime; 1328 | mapping(address => uint256) public points; 1329 | mapping(uint256 => uint256) public cards; 1330 | 1331 | event CardAdded(uint256 card, uint256 points); 1332 | event Staked(address indexed user, uint256 amount); 1333 | event Withdrawn(address indexed user, uint256 amount); 1334 | event Redeemed(address indexed user, uint256 amount); 1335 | 1336 | modifier updateReward(address account) { 1337 | if (account != address(0)) { 1338 | points[account] = earned(account); 1339 | lastUpdateTime[account] = block.timestamp; 1340 | } 1341 | _; 1342 | } 1343 | 1344 | constructor(ERC1155Tradable _memesAddress, IERC20 _memeAddress) public MemeTokenWrapper(_memeAddress) { 1345 | memes = _memesAddress; 1346 | } 1347 | 1348 | function addCard(uint256 cardId, uint256 amount) public onlyOwner { 1349 | cards[cardId] = amount; 1350 | emit CardAdded(cardId, amount); 1351 | } 1352 | 1353 | function earned(address account) public view returns (uint256) { 1354 | uint256 blockTime = block.timestamp; 1355 | return 1356 | points[account].add( 1357 | blockTime.sub(lastUpdateTime[account]).mul(1e18).div(86400).mul(balanceOf(account).div(1e8)) 1358 | ); 1359 | } 1360 | 1361 | // stake visibility is public as overriding MemeTokenWrapper's stake() function 1362 | function stake(uint256 amount) public updateReward(msg.sender) { 1363 | require(amount.add(balanceOf(msg.sender)) <= 500000000, "Cannot stake more than 5 meme"); 1364 | 1365 | super.stake(amount); 1366 | emit Staked(msg.sender, amount); 1367 | } 1368 | 1369 | function withdraw(uint256 amount) public updateReward(msg.sender) { 1370 | require(amount > 0, "Cannot withdraw 0"); 1371 | 1372 | super.withdraw(amount); 1373 | emit Withdrawn(msg.sender, amount); 1374 | } 1375 | 1376 | function exit() external { 1377 | withdraw(balanceOf(msg.sender)); 1378 | } 1379 | 1380 | function redeem(uint256 card) public updateReward(msg.sender) { 1381 | require(cards[card] != 0, "Card not found"); 1382 | require(points[msg.sender] >= cards[card], "Not enough points to redeem for card"); 1383 | require(memes.totalSupply(card) < memes.maxSupply(card), "Max cards minted"); 1384 | 1385 | points[msg.sender] = points[msg.sender].sub(cards[card]); 1386 | memes.mint(msg.sender, card, 1, ""); 1387 | emit Redeemed(msg.sender, cards[card]); 1388 | } 1389 | } 1390 | -------------------------------------------------------------------------------- /SvenEberwein.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2020-09-18 3 | */ 4 | 5 | pragma solidity ^0.5.0; 6 | 7 | 8 | /** 9 | * @dev Standard math utilities missing in the Solidity language. 10 | */ 11 | library Math { 12 | /** 13 | * @dev Returns the largest of two numbers. 14 | */ 15 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 16 | return a >= b ? a : b; 17 | } 18 | 19 | /** 20 | * @dev Returns the smallest of two numbers. 21 | */ 22 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 23 | return a < b ? a : b; 24 | } 25 | 26 | /** 27 | * @dev Returns the average of two numbers. The result is rounded towards 28 | * zero. 29 | */ 30 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 31 | // (a + b) / 2 can overflow, so we distribute 32 | return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); 33 | } 34 | } 35 | 36 | /* 37 | * @dev Provides information about the current execution context, including the 38 | * sender of the transaction and its data. While these are generally available 39 | * via msg.sender and msg.data, they should not be accessed in such a direct 40 | * manner, since when dealing with GSN meta-transactions the account sending and 41 | * paying for execution may not be the actual sender (as far as an application 42 | * is concerned). 43 | * 44 | * This contract is only required for intermediate, library-like contracts. 45 | */ 46 | contract Context { 47 | // Empty internal constructor, to prevent people from mistakenly deploying 48 | // an instance of this contract, which should be used via inheritance. 49 | constructor () internal { } 50 | // solhint-disable-previous-line no-empty-blocks 51 | 52 | function _msgSender() internal view returns (address payable) { 53 | return msg.sender; 54 | } 55 | 56 | function _msgData() internal view returns (bytes memory) { 57 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 58 | return msg.data; 59 | } 60 | } 61 | 62 | /** 63 | * @dev Contract module which provides a basic access control mechanism, where 64 | * there is an account (an owner) that can be granted exclusive access to 65 | * specific functions. 66 | * 67 | * This module is used through inheritance. It will make available the modifier 68 | * `onlyOwner`, which can be applied to your functions to restrict their use to 69 | * the owner. 70 | */ 71 | contract Ownable is Context { 72 | address private _owner; 73 | 74 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 75 | 76 | /** 77 | * @dev Initializes the contract setting the deployer as the initial owner. 78 | */ 79 | constructor () internal { 80 | address msgSender = _msgSender(); 81 | _owner = msgSender; 82 | emit OwnershipTransferred(address(0), msgSender); 83 | } 84 | 85 | /** 86 | * @dev Returns the address of the current owner. 87 | */ 88 | function owner() public view returns (address) { 89 | return _owner; 90 | } 91 | 92 | /** 93 | * @dev Throws if called by any account other than the owner. 94 | */ 95 | modifier onlyOwner() { 96 | require(isOwner(), "Ownable: caller is not the owner"); 97 | _; 98 | } 99 | 100 | /** 101 | * @dev Returns true if the caller is the current owner. 102 | */ 103 | function isOwner() public view returns (bool) { 104 | return _msgSender() == _owner; 105 | } 106 | 107 | /** 108 | * @dev Leaves the contract without owner. It will not be possible to call 109 | * `onlyOwner` functions anymore. Can only be called by the current owner. 110 | * 111 | * NOTE: Renouncing ownership will leave the contract without an owner, 112 | * thereby removing any functionality that is only available to the owner. 113 | */ 114 | function renounceOwnership() public onlyOwner { 115 | emit OwnershipTransferred(_owner, address(0)); 116 | _owner = address(0); 117 | } 118 | 119 | /** 120 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 121 | * Can only be called by the current owner. 122 | */ 123 | function transferOwnership(address newOwner) public onlyOwner { 124 | _transferOwnership(newOwner); 125 | } 126 | 127 | /** 128 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 129 | */ 130 | function _transferOwnership(address newOwner) internal { 131 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 132 | emit OwnershipTransferred(_owner, newOwner); 133 | _owner = newOwner; 134 | } 135 | } 136 | 137 | /** 138 | * @dev Interface of the ERC20 standard as defined in the EIP. Does not include 139 | * the optional functions; to access them see {ERC20Detailed}. 140 | */ 141 | interface IERC20 { 142 | /** 143 | * @dev Returns the amount of tokens in existence. 144 | */ 145 | function totalSupply() external view returns (uint256); 146 | 147 | /** 148 | * @dev Returns the amount of tokens owned by `account`. 149 | */ 150 | function balanceOf(address account) external view returns (uint256); 151 | 152 | /** 153 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 154 | * 155 | * Returns a boolean value indicating whether the operation succeeded. 156 | * 157 | * Emits a {Transfer} event. 158 | */ 159 | function transfer(address recipient, uint256 amount) external returns (bool); 160 | 161 | /** 162 | * @dev Returns the remaining number of tokens that `spender` will be 163 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 164 | * zero by default. 165 | * 166 | * This value changes when {approve} or {transferFrom} are called. 167 | */ 168 | function allowance(address owner, address spender) external view returns (uint256); 169 | 170 | /** 171 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 172 | * 173 | * Returns a boolean value indicating whether the operation succeeded. 174 | * 175 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 176 | * that someone may use both the old and the new allowance by unfortunate 177 | * transaction ordering. One possible solution to mitigate this race 178 | * condition is to first reduce the spender's allowance to 0 and set the 179 | * desired value afterwards: 180 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 181 | * 182 | * Emits an {Approval} event. 183 | */ 184 | function approve(address spender, uint256 amount) external returns (bool); 185 | 186 | /** 187 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 188 | * allowance mechanism. `amount` is then deducted from the caller's 189 | * allowance. 190 | * 191 | * Returns a boolean value indicating whether the operation succeeded. 192 | * 193 | * Emits a {Transfer} event. 194 | */ 195 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 196 | 197 | /** 198 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 199 | * another (`to`). 200 | * 201 | * Note that `value` may be zero. 202 | */ 203 | event Transfer(address indexed from, address indexed to, uint256 value); 204 | 205 | /** 206 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 207 | * a call to {approve}. `value` is the new allowance. 208 | */ 209 | event Approval(address indexed owner, address indexed spender, uint256 value); 210 | } 211 | 212 | /** 213 | * @title Roles 214 | * @dev Library for managing addresses assigned to a Role. 215 | */ 216 | library Roles { 217 | struct Role { 218 | mapping (address => bool) bearer; 219 | } 220 | 221 | /** 222 | * @dev Give an account access to this role. 223 | */ 224 | function add(Role storage role, address account) internal { 225 | require(!has(role, account), "Roles: account already has role"); 226 | role.bearer[account] = true; 227 | } 228 | 229 | /** 230 | * @dev Remove an account's access to this role. 231 | */ 232 | function remove(Role storage role, address account) internal { 233 | require(has(role, account), "Roles: account does not have role"); 234 | role.bearer[account] = false; 235 | } 236 | 237 | /** 238 | * @dev Check if an account has this role. 239 | * @return bool 240 | */ 241 | function has(Role storage role, address account) internal view returns (bool) { 242 | require(account != address(0), "Roles: account is the zero address"); 243 | return role.bearer[account]; 244 | } 245 | } 246 | 247 | contract MinterRole is Context { 248 | using Roles for Roles.Role; 249 | 250 | event MinterAdded(address indexed account); 251 | event MinterRemoved(address indexed account); 252 | 253 | Roles.Role private _minters; 254 | 255 | constructor () internal { 256 | _addMinter(_msgSender()); 257 | } 258 | 259 | modifier onlyMinter() { 260 | require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role"); 261 | _; 262 | } 263 | 264 | function isMinter(address account) public view returns (bool) { 265 | return _minters.has(account); 266 | } 267 | 268 | function addMinter(address account) public onlyMinter { 269 | _addMinter(account); 270 | } 271 | 272 | function renounceMinter() public { 273 | _removeMinter(_msgSender()); 274 | } 275 | 276 | function _addMinter(address account) internal { 277 | _minters.add(account); 278 | emit MinterAdded(account); 279 | } 280 | 281 | function _removeMinter(address account) internal { 282 | _minters.remove(account); 283 | emit MinterRemoved(account); 284 | } 285 | } 286 | 287 | /** 288 | * @title WhitelistAdminRole 289 | * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. 290 | */ 291 | contract WhitelistAdminRole is Context { 292 | using Roles for Roles.Role; 293 | 294 | event WhitelistAdminAdded(address indexed account); 295 | event WhitelistAdminRemoved(address indexed account); 296 | 297 | Roles.Role private _whitelistAdmins; 298 | 299 | constructor () internal { 300 | _addWhitelistAdmin(_msgSender()); 301 | } 302 | 303 | modifier onlyWhitelistAdmin() { 304 | require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); 305 | _; 306 | } 307 | 308 | function isWhitelistAdmin(address account) public view returns (bool) { 309 | return _whitelistAdmins.has(account); 310 | } 311 | 312 | function addWhitelistAdmin(address account) public onlyWhitelistAdmin { 313 | _addWhitelistAdmin(account); 314 | } 315 | 316 | function renounceWhitelistAdmin() public { 317 | _removeWhitelistAdmin(_msgSender()); 318 | } 319 | 320 | function _addWhitelistAdmin(address account) internal { 321 | _whitelistAdmins.add(account); 322 | emit WhitelistAdminAdded(account); 323 | } 324 | 325 | function _removeWhitelistAdmin(address account) internal { 326 | _whitelistAdmins.remove(account); 327 | emit WhitelistAdminRemoved(account); 328 | } 329 | } 330 | 331 | /** 332 | * @title ERC165 333 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md 334 | */ 335 | interface IERC165 { 336 | 337 | /** 338 | * @notice Query if a contract implements an interface 339 | * @dev Interface identification is specified in ERC-165. This function 340 | * uses less than 30,000 gas 341 | * @param _interfaceId The interface identifier, as specified in ERC-165 342 | */ 343 | function supportsInterface(bytes4 _interfaceId) 344 | external 345 | view 346 | returns (bool); 347 | } 348 | 349 | /** 350 | * @title SafeMath 351 | * @dev Unsigned math operations with safety checks that revert on error 352 | */ 353 | library SafeMath { 354 | 355 | /** 356 | * @dev Multiplies two unsigned integers, reverts on overflow. 357 | */ 358 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 359 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 360 | // benefit is lost if 'b' is also tested. 361 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 362 | if (a == 0) { 363 | return 0; 364 | } 365 | 366 | uint256 c = a * b; 367 | require(c / a == b, "SafeMath#mul: OVERFLOW"); 368 | 369 | return c; 370 | } 371 | 372 | /** 373 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 374 | */ 375 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 376 | // Solidity only automatically asserts when dividing by 0 377 | require(b > 0, "SafeMath#div: DIVISION_BY_ZERO"); 378 | uint256 c = a / b; 379 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 380 | 381 | return c; 382 | } 383 | 384 | /** 385 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 386 | */ 387 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 388 | require(b <= a, "SafeMath#sub: UNDERFLOW"); 389 | uint256 c = a - b; 390 | 391 | return c; 392 | } 393 | 394 | /** 395 | * @dev Adds two unsigned integers, reverts on overflow. 396 | */ 397 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 398 | uint256 c = a + b; 399 | require(c >= a, "SafeMath#add: OVERFLOW"); 400 | 401 | return c; 402 | } 403 | 404 | /** 405 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 406 | * reverts when dividing by zero. 407 | */ 408 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 409 | require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO"); 410 | return a % b; 411 | } 412 | 413 | } 414 | 415 | /** 416 | * @dev ERC-1155 interface for accepting safe transfers. 417 | */ 418 | interface IERC1155TokenReceiver { 419 | 420 | /** 421 | * @notice Handle the receipt of a single ERC1155 token type 422 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated 423 | * This function MAY throw to revert and reject the transfer 424 | * Return of other amount than the magic value MUST result in the transaction being reverted 425 | * Note: The token contract address is always the message sender 426 | * @param _operator The address which called the `safeTransferFrom` function 427 | * @param _from The address which previously owned the token 428 | * @param _id The id of the token being transferred 429 | * @param _amount The amount of tokens being transferred 430 | * @param _data Additional data with no specified format 431 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 432 | */ 433 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4); 434 | 435 | /** 436 | * @notice Handle the receipt of multiple ERC1155 token types 437 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated 438 | * This function MAY throw to revert and reject the transfer 439 | * Return of other amount than the magic value WILL result in the transaction being reverted 440 | * Note: The token contract address is always the message sender 441 | * @param _operator The address which called the `safeBatchTransferFrom` function 442 | * @param _from The address which previously owned the token 443 | * @param _ids An array containing ids of each token being transferred 444 | * @param _amounts An array containing amounts of each token being transferred 445 | * @param _data Additional data with no specified format 446 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 447 | */ 448 | function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4); 449 | 450 | /** 451 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types. 452 | * @param interfaceID The ERC-165 interface ID that is queried for support.s 453 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface. 454 | * This function MUST NOT consume more than 5,000 gas. 455 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported. 456 | */ 457 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 458 | 459 | } 460 | 461 | interface IERC1155 { 462 | // Events 463 | 464 | /** 465 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 466 | * Operator MUST be msg.sender 467 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 468 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 469 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 470 | * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 471 | */ 472 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 473 | 474 | /** 475 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 476 | * Operator MUST be msg.sender 477 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 478 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 479 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 480 | * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 481 | */ 482 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 483 | 484 | /** 485 | * @dev MUST emit when an approval is updated 486 | */ 487 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 488 | 489 | /** 490 | * @dev MUST emit when the URI is updated for a token ID 491 | * URIs are defined in RFC 3986 492 | * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema" 493 | */ 494 | event URI(string _amount, uint256 indexed _id); 495 | 496 | /** 497 | * @notice Transfers amount of an _id from the _from address to the _to address specified 498 | * @dev MUST emit TransferSingle event on success 499 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 500 | * MUST throw if `_to` is the zero address 501 | * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent 502 | * MUST throw on any other error 503 | * 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 amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 504 | * @param _from Source address 505 | * @param _to Target address 506 | * @param _id ID of the token type 507 | * @param _amount Transfered amount 508 | * @param _data Additional data with no specified format, sent in call to `_to` 509 | */ 510 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external; 511 | 512 | /** 513 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 514 | * @dev MUST emit TransferBatch event on success 515 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 516 | * MUST throw if `_to` is the zero address 517 | * MUST throw if length of `_ids` is not the same as length of `_amounts` 518 | * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent 519 | * MUST throw on any other error 520 | * 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 amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 521 | * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc) 522 | * @param _from Source addresses 523 | * @param _to Target addresses 524 | * @param _ids IDs of each token type 525 | * @param _amounts Transfer amounts per token type 526 | * @param _data Additional data with no specified format, sent in call to `_to` 527 | */ 528 | function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external; 529 | 530 | /** 531 | * @notice Get the balance of an account's Tokens 532 | * @param _owner The address of the token holder 533 | * @param _id ID of the Token 534 | * @return The _owner's balance of the Token type requested 535 | */ 536 | function balanceOf(address _owner, uint256 _id) external view returns (uint256); 537 | 538 | /** 539 | * @notice Get the balance of multiple account/token pairs 540 | * @param _owners The addresses of the token holders 541 | * @param _ids ID of the Tokens 542 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 543 | */ 544 | function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); 545 | 546 | /** 547 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 548 | * @dev MUST emit the ApprovalForAll event on success 549 | * @param _operator Address to add to the set of authorized operators 550 | * @param _approved True if the operator is approved, false to revoke approval 551 | */ 552 | function setApprovalForAll(address _operator, bool _approved) external; 553 | 554 | /** 555 | * @notice Queries the approval status of an operator for a given owner 556 | * @param _owner The owner of the Tokens 557 | * @param _operator Address of authorized operator 558 | * @return True if the operator is approved, false if not 559 | */ 560 | function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator); 561 | 562 | } 563 | 564 | /** 565 | * Copyright 2018 ZeroEx Intl. 566 | * Licensed under the Apache License, Version 2.0 (the "License"); 567 | * you may not use this file except in compliance with the License. 568 | * You may obtain a copy of the License at 569 | * http://www.apache.org/licenses/LICENSE-2.0 570 | * Unless required by applicable law or agreed to in writing, software 571 | * distributed under the License is distributed on an "AS IS" BASIS, 572 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 573 | * See the License for the specific language governing permissions and 574 | * limitations under the License. 575 | */ 576 | /** 577 | * Utility library of inline functions on addresses 578 | */ 579 | library Address { 580 | 581 | /** 582 | * Returns whether the target address is a contract 583 | * @dev This function will return false if invoked during the constructor of a contract, 584 | * as the code is not actually created until after the constructor finishes. 585 | * @param account address of the account to check 586 | * @return whether the target address is a contract 587 | */ 588 | function isContract(address account) internal view returns (bool) { 589 | bytes32 codehash; 590 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 591 | 592 | // XXX Currently there is no better way to check if there is a contract in an address 593 | // than to check the size of the code at that address. 594 | // See https://ethereum.stackexchange.com/a/14016/36603 595 | // for more details about how this works. 596 | // TODO Check this again before the Serenity release, because all addresses will be 597 | // contracts then. 598 | assembly { codehash := extcodehash(account) } 599 | return (codehash != 0x0 && codehash != accountHash); 600 | } 601 | 602 | } 603 | 604 | /** 605 | * @dev Implementation of Multi-Token Standard contract 606 | */ 607 | contract ERC1155 is IERC165 { 608 | using SafeMath for uint256; 609 | using Address for address; 610 | 611 | 612 | /***********************************| 613 | | Variables and Events | 614 | |__________________________________*/ 615 | 616 | // onReceive function signatures 617 | bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61; 618 | bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; 619 | 620 | // Objects balances 621 | mapping (address => mapping(uint256 => uint256)) internal balances; 622 | 623 | // Operator Functions 624 | mapping (address => mapping(address => bool)) internal operators; 625 | 626 | // Events 627 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 628 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 629 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 630 | event URI(string _uri, uint256 indexed _id); 631 | 632 | 633 | /***********************************| 634 | | Public Transfer Functions | 635 | |__________________________________*/ 636 | 637 | /** 638 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 639 | * @param _from Source address 640 | * @param _to Target address 641 | * @param _id ID of the token type 642 | * @param _amount Transfered amount 643 | * @param _data Additional data with no specified format, sent in call to `_to` 644 | */ 645 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 646 | public 647 | { 648 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR"); 649 | require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT"); 650 | // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations 651 | 652 | _safeTransferFrom(_from, _to, _id, _amount); 653 | _callonERC1155Received(_from, _to, _id, _amount, _data); 654 | } 655 | 656 | /** 657 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 658 | * @param _from Source addresses 659 | * @param _to Target addresses 660 | * @param _ids IDs of each token type 661 | * @param _amounts Transfer amounts per token type 662 | * @param _data Additional data with no specified format, sent in call to `_to` 663 | */ 664 | function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 665 | public 666 | { 667 | // Requirements 668 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR"); 669 | require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT"); 670 | 671 | _safeBatchTransferFrom(_from, _to, _ids, _amounts); 672 | _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data); 673 | } 674 | 675 | 676 | /***********************************| 677 | | Internal Transfer Functions | 678 | |__________________________________*/ 679 | 680 | /** 681 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 682 | * @param _from Source address 683 | * @param _to Target address 684 | * @param _id ID of the token type 685 | * @param _amount Transfered amount 686 | */ 687 | function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) 688 | internal 689 | { 690 | // Update balances 691 | balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount 692 | balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount 693 | 694 | // Emit event 695 | emit TransferSingle(msg.sender, _from, _to, _id, _amount); 696 | } 697 | 698 | /** 699 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...) 700 | */ 701 | function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 702 | internal 703 | { 704 | // Check if recipient is contract 705 | if (_to.isContract()) { 706 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data); 707 | require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE"); 708 | } 709 | } 710 | 711 | /** 712 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 713 | * @param _from Source addresses 714 | * @param _to Target addresses 715 | * @param _ids IDs of each token type 716 | * @param _amounts Transfer amounts per token type 717 | */ 718 | function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts) 719 | internal 720 | { 721 | require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH"); 722 | 723 | // Number of transfer to execute 724 | uint256 nTransfer = _ids.length; 725 | 726 | // Executing all transfers 727 | for (uint256 i = 0; i < nTransfer; i++) { 728 | // Update storage balance of previous bin 729 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 730 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 731 | } 732 | 733 | // Emit event 734 | emit TransferBatch(msg.sender, _from, _to, _ids, _amounts); 735 | } 736 | 737 | /** 738 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...) 739 | */ 740 | function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 741 | internal 742 | { 743 | // Pass data if recipient is contract 744 | if (_to.isContract()) { 745 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data); 746 | require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE"); 747 | } 748 | } 749 | 750 | 751 | /***********************************| 752 | | Operator Functions | 753 | |__________________________________*/ 754 | 755 | /** 756 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 757 | * @param _operator Address to add to the set of authorized operators 758 | * @param _approved True if the operator is approved, false to revoke approval 759 | */ 760 | function setApprovalForAll(address _operator, bool _approved) 761 | external 762 | { 763 | // Update operator status 764 | operators[msg.sender][_operator] = _approved; 765 | emit ApprovalForAll(msg.sender, _operator, _approved); 766 | } 767 | 768 | /** 769 | * @notice Queries the approval status of an operator for a given owner 770 | * @param _owner The owner of the Tokens 771 | * @param _operator Address of authorized operator 772 | * @return True if the operator is approved, false if not 773 | */ 774 | function isApprovedForAll(address _owner, address _operator) 775 | public view returns (bool isOperator) 776 | { 777 | return operators[_owner][_operator]; 778 | } 779 | 780 | 781 | /***********************************| 782 | | Balance Functions | 783 | |__________________________________*/ 784 | 785 | /** 786 | * @notice Get the balance of an account's Tokens 787 | * @param _owner The address of the token holder 788 | * @param _id ID of the Token 789 | * @return The _owner's balance of the Token type requested 790 | */ 791 | function balanceOf(address _owner, uint256 _id) 792 | public view returns (uint256) 793 | { 794 | return balances[_owner][_id]; 795 | } 796 | 797 | /** 798 | * @notice Get the balance of multiple account/token pairs 799 | * @param _owners The addresses of the token holders 800 | * @param _ids ID of the Tokens 801 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 802 | */ 803 | function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) 804 | public view returns (uint256[] memory) 805 | { 806 | require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH"); 807 | 808 | // Variables 809 | uint256[] memory batchBalances = new uint256[](_owners.length); 810 | 811 | // Iterate over each owner and token ID 812 | for (uint256 i = 0; i < _owners.length; i++) { 813 | batchBalances[i] = balances[_owners[i]][_ids[i]]; 814 | } 815 | 816 | return batchBalances; 817 | } 818 | 819 | 820 | /***********************************| 821 | | ERC165 Functions | 822 | |__________________________________*/ 823 | 824 | /** 825 | * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)")); 826 | */ 827 | bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; 828 | 829 | /** 830 | * INTERFACE_SIGNATURE_ERC1155 = 831 | * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^ 832 | * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^ 833 | * bytes4(keccak256("balanceOf(address,uint256)")) ^ 834 | * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^ 835 | * bytes4(keccak256("setApprovalForAll(address,bool)")) ^ 836 | * bytes4(keccak256("isApprovedForAll(address,address)")); 837 | */ 838 | bytes4 constant private INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; 839 | 840 | /** 841 | * @notice Query if a contract implements an interface 842 | * @param _interfaceID The interface identifier, as specified in ERC-165 843 | * @return `true` if the contract implements `_interfaceID` and 844 | */ 845 | function supportsInterface(bytes4 _interfaceID) external view returns (bool) { 846 | if (_interfaceID == INTERFACE_SIGNATURE_ERC165 || 847 | _interfaceID == INTERFACE_SIGNATURE_ERC1155) { 848 | return true; 849 | } 850 | return false; 851 | } 852 | 853 | } 854 | 855 | /** 856 | * @notice Contract that handles metadata related methods. 857 | * @dev Methods assume a deterministic generation of URI based on token IDs. 858 | * Methods also assume that URI uses hex representation of token IDs. 859 | */ 860 | contract ERC1155Metadata { 861 | 862 | // URI's default URI prefix 863 | string internal baseMetadataURI; 864 | event URI(string _uri, uint256 indexed _id); 865 | 866 | 867 | /***********************************| 868 | | Metadata Public Function s | 869 | |__________________________________*/ 870 | 871 | /** 872 | * @notice A distinct Uniform Resource Identifier (URI) for a given token. 873 | * @dev URIs are defined in RFC 3986. 874 | * URIs are assumed to be deterministically generated based on token ID 875 | * Token IDs are assumed to be represented in their hex format in URIs 876 | * @return URI string 877 | */ 878 | function uri(uint256 _id) public view returns (string memory) { 879 | return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json")); 880 | } 881 | 882 | 883 | /***********************************| 884 | | Metadata Internal Functions | 885 | |__________________________________*/ 886 | 887 | /** 888 | * @notice Will emit default URI log event for corresponding token _id 889 | * @param _tokenIDs Array of IDs of tokens to log default URI 890 | */ 891 | function _logURIs(uint256[] memory _tokenIDs) internal { 892 | string memory baseURL = baseMetadataURI; 893 | string memory tokenURI; 894 | 895 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 896 | tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json")); 897 | emit URI(tokenURI, _tokenIDs[i]); 898 | } 899 | } 900 | 901 | /** 902 | * @notice Will emit a specific URI log event for corresponding token 903 | * @param _tokenIDs IDs of the token corresponding to the _uris logged 904 | * @param _URIs The URIs of the specified _tokenIDs 905 | */ 906 | function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal { 907 | require(_tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH"); 908 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 909 | emit URI(_URIs[i], _tokenIDs[i]); 910 | } 911 | } 912 | 913 | /** 914 | * @notice Will update the base URL of token's URI 915 | * @param _newBaseMetadataURI New base URL of token's URI 916 | */ 917 | function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal { 918 | baseMetadataURI = _newBaseMetadataURI; 919 | } 920 | 921 | 922 | /***********************************| 923 | | Utility Internal Functions | 924 | |__________________________________*/ 925 | 926 | /** 927 | * @notice Convert uint256 to string 928 | * @param _i Unsigned integer to convert to string 929 | */ 930 | function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 931 | if (_i == 0) { 932 | return "0"; 933 | } 934 | 935 | uint256 j = _i; 936 | uint256 ii = _i; 937 | uint256 len; 938 | 939 | // Get number of bytes 940 | while (j != 0) { 941 | len++; 942 | j /= 10; 943 | } 944 | 945 | bytes memory bstr = new bytes(len); 946 | uint256 k = len - 1; 947 | 948 | // Get each individual ASCII 949 | while (ii != 0) { 950 | bstr[k--] = byte(uint8(48 + ii % 10)); 951 | ii /= 10; 952 | } 953 | 954 | // Convert to string 955 | return string(bstr); 956 | } 957 | 958 | } 959 | 960 | /** 961 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume 962 | * a parent contract to be executed as they are `internal` functions 963 | */ 964 | contract ERC1155MintBurn is ERC1155 { 965 | 966 | 967 | /****************************************| 968 | | Minting Functions | 969 | |_______________________________________*/ 970 | 971 | /** 972 | * @notice Mint _amount of tokens of a given id 973 | * @param _to The address to mint tokens to 974 | * @param _id Token id to mint 975 | * @param _amount The amount to be minted 976 | * @param _data Data to pass if receiver is contract 977 | */ 978 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data) 979 | internal 980 | { 981 | // Add _amount 982 | balances[_to][_id] = balances[_to][_id].add(_amount); 983 | 984 | // Emit event 985 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount); 986 | 987 | // Calling onReceive method if recipient is contract 988 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data); 989 | } 990 | 991 | /** 992 | * @notice Mint tokens for each ids in _ids 993 | * @param _to The address to mint tokens to 994 | * @param _ids Array of ids to mint 995 | * @param _amounts Array of amount of tokens to mint per id 996 | * @param _data Data to pass if receiver is contract 997 | */ 998 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 999 | internal 1000 | { 1001 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH"); 1002 | 1003 | // Number of mints to execute 1004 | uint256 nMint = _ids.length; 1005 | 1006 | // Executing all minting 1007 | for (uint256 i = 0; i < nMint; i++) { 1008 | // Update storage balance 1009 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 1010 | } 1011 | 1012 | // Emit batch mint event 1013 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts); 1014 | 1015 | // Calling onReceive method if recipient is contract 1016 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data); 1017 | } 1018 | 1019 | 1020 | /****************************************| 1021 | | Burning Functions | 1022 | |_______________________________________*/ 1023 | 1024 | /** 1025 | * @notice Burn _amount of tokens of a given token id 1026 | * @param _from The address to burn tokens from 1027 | * @param _id Token id to burn 1028 | * @param _amount The amount to be burned 1029 | */ 1030 | function _burn(address _from, uint256 _id, uint256 _amount) 1031 | internal 1032 | { 1033 | //Substract _amount 1034 | balances[_from][_id] = balances[_from][_id].sub(_amount); 1035 | 1036 | // Emit event 1037 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount); 1038 | } 1039 | 1040 | /** 1041 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair 1042 | * @param _from The address to burn tokens from 1043 | * @param _ids Array of token ids to burn 1044 | * @param _amounts Array of the amount to be burned 1045 | */ 1046 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts) 1047 | internal 1048 | { 1049 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH"); 1050 | 1051 | // Number of mints to execute 1052 | uint256 nBurn = _ids.length; 1053 | 1054 | // Executing all minting 1055 | for (uint256 i = 0; i < nBurn; i++) { 1056 | // Update storage balance 1057 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 1058 | } 1059 | 1060 | // Emit batch mint event 1061 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts); 1062 | } 1063 | 1064 | } 1065 | 1066 | library Strings { 1067 | // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol 1068 | function strConcat( 1069 | string memory _a, 1070 | string memory _b, 1071 | string memory _c, 1072 | string memory _d, 1073 | string memory _e 1074 | ) internal pure returns (string memory) { 1075 | bytes memory _ba = bytes(_a); 1076 | bytes memory _bb = bytes(_b); 1077 | bytes memory _bc = bytes(_c); 1078 | bytes memory _bd = bytes(_d); 1079 | bytes memory _be = bytes(_e); 1080 | string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); 1081 | bytes memory babcde = bytes(abcde); 1082 | uint256 k = 0; 1083 | for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; 1084 | for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; 1085 | for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; 1086 | for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; 1087 | for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i]; 1088 | return string(babcde); 1089 | } 1090 | 1091 | function strConcat( 1092 | string memory _a, 1093 | string memory _b, 1094 | string memory _c, 1095 | string memory _d 1096 | ) internal pure returns (string memory) { 1097 | return strConcat(_a, _b, _c, _d, ""); 1098 | } 1099 | 1100 | function strConcat( 1101 | string memory _a, 1102 | string memory _b, 1103 | string memory _c 1104 | ) internal pure returns (string memory) { 1105 | return strConcat(_a, _b, _c, "", ""); 1106 | } 1107 | 1108 | function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { 1109 | return strConcat(_a, _b, "", "", ""); 1110 | } 1111 | 1112 | function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 1113 | if (_i == 0) { 1114 | return "0"; 1115 | } 1116 | uint256 j = _i; 1117 | uint256 len; 1118 | while (j != 0) { 1119 | len++; 1120 | j /= 10; 1121 | } 1122 | bytes memory bstr = new bytes(len); 1123 | uint256 k = len - 1; 1124 | while (_i != 0) { 1125 | bstr[k--] = bytes1(uint8(48 + (_i % 10))); 1126 | _i /= 10; 1127 | } 1128 | return string(bstr); 1129 | } 1130 | } 1131 | 1132 | contract OwnableDelegateProxy {} 1133 | 1134 | contract ProxyRegistry { 1135 | mapping(address => OwnableDelegateProxy) public proxies; 1136 | } 1137 | 1138 | /** 1139 | * @title ERC1155Tradable 1140 | * ERC1155Tradable - ERC1155 contract that whitelists an operator address, 1141 | * has create and mint functionality, and supports useful standards from OpenZeppelin, 1142 | like _exists(), name(), symbol(), and totalSupply() 1143 | */ 1144 | contract ERC1155Tradable is ERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable, MinterRole, WhitelistAdminRole { 1145 | using Strings for string; 1146 | 1147 | address proxyRegistryAddress; 1148 | uint256 private _currentTokenID = 0; 1149 | mapping(uint256 => address) public creators; 1150 | mapping(uint256 => uint256) public tokenSupply; 1151 | mapping(uint256 => uint256) public tokenMaxSupply; 1152 | // Contract name 1153 | string public name; 1154 | // Contract symbol 1155 | string public symbol; 1156 | 1157 | constructor( 1158 | string memory _name, 1159 | string memory _symbol, 1160 | address _proxyRegistryAddress 1161 | ) public { 1162 | name = _name; 1163 | symbol = _symbol; 1164 | proxyRegistryAddress = _proxyRegistryAddress; 1165 | } 1166 | 1167 | function removeWhitelistAdmin(address account) public onlyOwner { 1168 | _removeWhitelistAdmin(account); 1169 | } 1170 | 1171 | function removeMinter(address account) public onlyOwner { 1172 | _removeMinter(account); 1173 | } 1174 | 1175 | function uri(uint256 _id) public view returns (string memory) { 1176 | require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN"); 1177 | return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id)); 1178 | } 1179 | 1180 | /** 1181 | * @dev Returns the total quantity for a token ID 1182 | * @param _id uint256 ID of the token to query 1183 | * @return amount of token in existence 1184 | */ 1185 | function totalSupply(uint256 _id) public view returns (uint256) { 1186 | return tokenSupply[_id]; 1187 | } 1188 | 1189 | /** 1190 | * @dev Returns the max quantity for a token ID 1191 | * @param _id uint256 ID of the token to query 1192 | * @return amount of token in existence 1193 | */ 1194 | function maxSupply(uint256 _id) public view returns (uint256) { 1195 | return tokenMaxSupply[_id]; 1196 | } 1197 | 1198 | /** 1199 | * @dev Will update the base URL of token's URI 1200 | * @param _newBaseMetadataURI New base URL of token's URI 1201 | */ 1202 | function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyWhitelistAdmin { 1203 | _setBaseMetadataURI(_newBaseMetadataURI); 1204 | } 1205 | 1206 | /** 1207 | * @dev Creates a new token type and assigns _initialSupply to an address 1208 | * @param _maxSupply max supply allowed 1209 | * @param _initialSupply Optional amount to supply the first owner 1210 | * @param _uri Optional URI for this token type 1211 | * @param _data Optional data to pass if receiver is contract 1212 | * @return The newly created token ID 1213 | */ 1214 | function create( 1215 | uint256 _maxSupply, 1216 | uint256 _initialSupply, 1217 | string calldata _uri, 1218 | bytes calldata _data 1219 | ) external onlyWhitelistAdmin returns (uint256 tokenId) { 1220 | require(_initialSupply <= _maxSupply, "Initial supply cannot be more than max supply"); 1221 | uint256 _id = _getNextTokenID(); 1222 | _incrementTokenTypeId(); 1223 | creators[_id] = msg.sender; 1224 | 1225 | if (bytes(_uri).length > 0) { 1226 | emit URI(_uri, _id); 1227 | } 1228 | 1229 | if (_initialSupply != 0) _mint(msg.sender, _id, _initialSupply, _data); 1230 | tokenSupply[_id] = _initialSupply; 1231 | tokenMaxSupply[_id] = _maxSupply; 1232 | return _id; 1233 | } 1234 | 1235 | /** 1236 | * @dev Mints some amount of tokens to an address 1237 | * @param _to Address of the future owner of the token 1238 | * @param _id Token ID to mint 1239 | * @param _quantity Amount of tokens to mint 1240 | * @param _data Data to pass if receiver is contract 1241 | */ 1242 | function mint( 1243 | address _to, 1244 | uint256 _id, 1245 | uint256 _quantity, 1246 | bytes memory _data 1247 | ) public onlyMinter { 1248 | uint256 tokenId = _id; 1249 | require(tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached"); 1250 | _mint(_to, _id, _quantity, _data); 1251 | tokenSupply[_id] = tokenSupply[_id].add(_quantity); 1252 | } 1253 | 1254 | /** 1255 | * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings. 1256 | */ 1257 | function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { 1258 | // Whitelist OpenSea proxy contract for easy trading. 1259 | ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); 1260 | if (address(proxyRegistry.proxies(_owner)) == _operator) { 1261 | return true; 1262 | } 1263 | 1264 | return ERC1155.isApprovedForAll(_owner, _operator); 1265 | } 1266 | 1267 | /** 1268 | * @dev Returns whether the specified token exists by checking to see if it has a creator 1269 | * @param _id uint256 ID of the token to query the existence of 1270 | * @return bool whether the token exists 1271 | */ 1272 | function _exists(uint256 _id) internal view returns (bool) { 1273 | return creators[_id] != address(0); 1274 | } 1275 | 1276 | /** 1277 | * @dev calculates the next token ID based on value of _currentTokenID 1278 | * @return uint256 for the next token ID 1279 | */ 1280 | function _getNextTokenID() private view returns (uint256) { 1281 | return _currentTokenID.add(1); 1282 | } 1283 | 1284 | /** 1285 | * @dev increments the value of _currentTokenID 1286 | */ 1287 | function _incrementTokenTypeId() private { 1288 | _currentTokenID++; 1289 | } 1290 | } 1291 | 1292 | contract MemeTokenWrapper { 1293 | using SafeMath for uint256; 1294 | IERC20 public meme; 1295 | 1296 | constructor(IERC20 _memeAddress) public { 1297 | meme = IERC20(_memeAddress); 1298 | } 1299 | 1300 | uint256 private _totalSupply; 1301 | mapping(address => uint256) private _balances; 1302 | 1303 | function totalSupply() public view returns (uint256) { 1304 | return _totalSupply; 1305 | } 1306 | 1307 | function balanceOf(address account) public view returns (uint256) { 1308 | return _balances[account]; 1309 | } 1310 | 1311 | function stake(uint256 amount) public { 1312 | _totalSupply = _totalSupply.add(amount); 1313 | _balances[msg.sender] = _balances[msg.sender].add(amount); 1314 | meme.transferFrom(msg.sender, address(this), amount); 1315 | } 1316 | 1317 | function withdraw(uint256 amount) public { 1318 | _totalSupply = _totalSupply.sub(amount); 1319 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 1320 | meme.transfer(msg.sender, amount); 1321 | } 1322 | } 1323 | 1324 | contract SvenEberwein is MemeTokenWrapper, Ownable { 1325 | ERC1155Tradable public memes; 1326 | 1327 | uint256 public periodStart = 1600459200; 1328 | mapping(address => uint256) public lastUpdateTime; 1329 | mapping(address => uint256) public points; 1330 | mapping(uint256 => uint256) public cards; 1331 | 1332 | event CardAdded(uint256 card, uint256 points); 1333 | event Staked(address indexed user, uint256 amount); 1334 | event Withdrawn(address indexed user, uint256 amount); 1335 | event Redeemed(address indexed user, uint256 amount); 1336 | 1337 | modifier updateReward(address account) { 1338 | if (account != address(0)) { 1339 | points[account] = earned(account); 1340 | lastUpdateTime[account] = block.timestamp; 1341 | } 1342 | _; 1343 | } 1344 | 1345 | constructor(ERC1155Tradable _memesAddress, IERC20 _memeAddress) public MemeTokenWrapper(_memeAddress) { 1346 | memes = _memesAddress; 1347 | } 1348 | 1349 | function addCard(uint256 cardId, uint256 amount) public onlyOwner { 1350 | cards[cardId] = amount; 1351 | emit CardAdded(cardId, amount); 1352 | } 1353 | 1354 | function earned(address account) public view returns (uint256) { 1355 | uint256 blockTime = block.timestamp; 1356 | return 1357 | points[account].add( 1358 | blockTime.sub(lastUpdateTime[account]).mul(1e18).div(86400).mul(balanceOf(account).div(1e8)) 1359 | ); 1360 | } 1361 | 1362 | // stake visibility is public as overriding MemeTokenWrapper's stake() function 1363 | function stake(uint256 amount) public updateReward(msg.sender) { 1364 | require(block.timestamp >= periodStart, "Pool not open"); 1365 | require(amount.add(balanceOf(msg.sender)) <= 500000000, "Stake between 1-5 meme"); 1366 | 1367 | super.stake(amount); 1368 | emit Staked(msg.sender, amount); 1369 | } 1370 | 1371 | function withdraw(uint256 amount) public updateReward(msg.sender) { 1372 | require(amount > 0, "Cannot withdraw 0"); 1373 | 1374 | super.withdraw(amount); 1375 | emit Withdrawn(msg.sender, amount); 1376 | } 1377 | 1378 | function exit() external { 1379 | withdraw(balanceOf(msg.sender)); 1380 | } 1381 | 1382 | function redeem(uint256 card) public updateReward(msg.sender) { 1383 | require(cards[card] != 0, "Card not found"); 1384 | require(points[msg.sender] >= cards[card], "Not enough points to redeem for card"); 1385 | require(memes.totalSupply(card) < memes.maxSupply(card), "Max cards minted"); 1386 | 1387 | points[msg.sender] = points[msg.sender].sub(cards[card]); 1388 | memes.mint(msg.sender, card, 1, ""); 1389 | emit Redeemed(msg.sender, cards[card]); 1390 | } 1391 | } 1392 | -------------------------------------------------------------------------------- /MemeLtDPool.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2020-09-24 3 | */ 4 | 5 | pragma solidity ^0.5.0; 6 | 7 | 8 | /** 9 | * @dev Standard math utilities missing in the Solidity language. 10 | */ 11 | library Math { 12 | /** 13 | * @dev Returns the largest of two numbers. 14 | */ 15 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 16 | return a >= b ? a : b; 17 | } 18 | 19 | /** 20 | * @dev Returns the smallest of two numbers. 21 | */ 22 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 23 | return a < b ? a : b; 24 | } 25 | 26 | /** 27 | * @dev Returns the average of two numbers. The result is rounded towards 28 | * zero. 29 | */ 30 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 31 | // (a + b) / 2 can overflow, so we distribute 32 | return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); 33 | } 34 | } 35 | 36 | /* 37 | * @dev Provides information about the current execution context, including the 38 | * sender of the transaction and its data. While these are generally available 39 | * via msg.sender and msg.data, they should not be accessed in such a direct 40 | * manner, since when dealing with GSN meta-transactions the account sending and 41 | * paying for execution may not be the actual sender (as far as an application 42 | * is concerned). 43 | * 44 | * This contract is only required for intermediate, library-like contracts. 45 | */ 46 | contract Context { 47 | // Empty internal constructor, to prevent people from mistakenly deploying 48 | // an instance of this contract, which should be used via inheritance. 49 | constructor () internal { } 50 | // solhint-disable-previous-line no-empty-blocks 51 | 52 | function _msgSender() internal view returns (address payable) { 53 | return msg.sender; 54 | } 55 | 56 | function _msgData() internal view returns (bytes memory) { 57 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 58 | return msg.data; 59 | } 60 | } 61 | 62 | /** 63 | * @dev Contract module which provides a basic access control mechanism, where 64 | * there is an account (an owner) that can be granted exclusive access to 65 | * specific functions. 66 | * 67 | * This module is used through inheritance. It will make available the modifier 68 | * `onlyOwner`, which can be applied to your functions to restrict their use to 69 | * the owner. 70 | */ 71 | contract Ownable is Context { 72 | address private _owner; 73 | 74 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 75 | 76 | /** 77 | * @dev Initializes the contract setting the deployer as the initial owner. 78 | */ 79 | constructor () internal { 80 | address msgSender = _msgSender(); 81 | _owner = msgSender; 82 | emit OwnershipTransferred(address(0), msgSender); 83 | } 84 | 85 | /** 86 | * @dev Returns the address of the current owner. 87 | */ 88 | function owner() public view returns (address) { 89 | return _owner; 90 | } 91 | 92 | /** 93 | * @dev Throws if called by any account other than the owner. 94 | */ 95 | modifier onlyOwner() { 96 | require(isOwner(), "Ownable: caller is not the owner"); 97 | _; 98 | } 99 | 100 | /** 101 | * @dev Returns true if the caller is the current owner. 102 | */ 103 | function isOwner() public view returns (bool) { 104 | return _msgSender() == _owner; 105 | } 106 | 107 | /** 108 | * @dev Leaves the contract without owner. It will not be possible to call 109 | * `onlyOwner` functions anymore. Can only be called by the current owner. 110 | * 111 | * NOTE: Renouncing ownership will leave the contract without an owner, 112 | * thereby removing any functionality that is only available to the owner. 113 | */ 114 | function renounceOwnership() public onlyOwner { 115 | emit OwnershipTransferred(_owner, address(0)); 116 | _owner = address(0); 117 | } 118 | 119 | /** 120 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 121 | * Can only be called by the current owner. 122 | */ 123 | function transferOwnership(address newOwner) public onlyOwner { 124 | _transferOwnership(newOwner); 125 | } 126 | 127 | /** 128 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 129 | */ 130 | function _transferOwnership(address newOwner) internal { 131 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 132 | emit OwnershipTransferred(_owner, newOwner); 133 | _owner = newOwner; 134 | } 135 | } 136 | 137 | /** 138 | * @dev Interface of the ERC20 standard as defined in the EIP. Does not include 139 | * the optional functions; to access them see {ERC20Detailed}. 140 | */ 141 | interface IERC20 { 142 | /** 143 | * @dev Returns the amount of tokens in existence. 144 | */ 145 | function totalSupply() external view returns (uint256); 146 | 147 | /** 148 | * @dev Returns the amount of tokens owned by `account`. 149 | */ 150 | function balanceOf(address account) external view returns (uint256); 151 | 152 | /** 153 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 154 | * 155 | * Returns a boolean value indicating whether the operation succeeded. 156 | * 157 | * Emits a {Transfer} event. 158 | */ 159 | function transfer(address recipient, uint256 amount) external returns (bool); 160 | 161 | /** 162 | * @dev Returns the remaining number of tokens that `spender` will be 163 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 164 | * zero by default. 165 | * 166 | * This value changes when {approve} or {transferFrom} are called. 167 | */ 168 | function allowance(address owner, address spender) external view returns (uint256); 169 | 170 | /** 171 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 172 | * 173 | * Returns a boolean value indicating whether the operation succeeded. 174 | * 175 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 176 | * that someone may use both the old and the new allowance by unfortunate 177 | * transaction ordering. One possible solution to mitigate this race 178 | * condition is to first reduce the spender's allowance to 0 and set the 179 | * desired value afterwards: 180 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 181 | * 182 | * Emits an {Approval} event. 183 | */ 184 | function approve(address spender, uint256 amount) external returns (bool); 185 | 186 | /** 187 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 188 | * allowance mechanism. `amount` is then deducted from the caller's 189 | * allowance. 190 | * 191 | * Returns a boolean value indicating whether the operation succeeded. 192 | * 193 | * Emits a {Transfer} event. 194 | */ 195 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 196 | 197 | /** 198 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 199 | * another (`to`). 200 | * 201 | * Note that `value` may be zero. 202 | */ 203 | event Transfer(address indexed from, address indexed to, uint256 value); 204 | 205 | /** 206 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 207 | * a call to {approve}. `value` is the new allowance. 208 | */ 209 | event Approval(address indexed owner, address indexed spender, uint256 value); 210 | } 211 | 212 | /** 213 | * @title Roles 214 | * @dev Library for managing addresses assigned to a Role. 215 | */ 216 | library Roles { 217 | struct Role { 218 | mapping (address => bool) bearer; 219 | } 220 | 221 | /** 222 | * @dev Give an account access to this role. 223 | */ 224 | function add(Role storage role, address account) internal { 225 | require(!has(role, account), "Roles: account already has role"); 226 | role.bearer[account] = true; 227 | } 228 | 229 | /** 230 | * @dev Remove an account's access to this role. 231 | */ 232 | function remove(Role storage role, address account) internal { 233 | require(has(role, account), "Roles: account does not have role"); 234 | role.bearer[account] = false; 235 | } 236 | 237 | /** 238 | * @dev Check if an account has this role. 239 | * @return bool 240 | */ 241 | function has(Role storage role, address account) internal view returns (bool) { 242 | require(account != address(0), "Roles: account is the zero address"); 243 | return role.bearer[account]; 244 | } 245 | } 246 | 247 | contract PauserRole is Context { 248 | using Roles for Roles.Role; 249 | 250 | event PauserAdded(address indexed account); 251 | event PauserRemoved(address indexed account); 252 | 253 | Roles.Role private _pausers; 254 | 255 | constructor () internal { 256 | _addPauser(_msgSender()); 257 | } 258 | 259 | modifier onlyPauser() { 260 | require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role"); 261 | _; 262 | } 263 | 264 | function isPauser(address account) public view returns (bool) { 265 | return _pausers.has(account); 266 | } 267 | 268 | function addPauser(address account) public onlyPauser { 269 | _addPauser(account); 270 | } 271 | 272 | function renouncePauser() public { 273 | _removePauser(_msgSender()); 274 | } 275 | 276 | function _addPauser(address account) internal { 277 | _pausers.add(account); 278 | emit PauserAdded(account); 279 | } 280 | 281 | function _removePauser(address account) internal { 282 | _pausers.remove(account); 283 | emit PauserRemoved(account); 284 | } 285 | } 286 | 287 | /** 288 | * @dev Contract module which allows children to implement an emergency stop 289 | * mechanism that can be triggered by an authorized account. 290 | * 291 | * This module is used through inheritance. It will make available the 292 | * modifiers `whenNotPaused` and `whenPaused`, which can be applied to 293 | * the functions of your contract. Note that they will not be pausable by 294 | * simply including this module, only once the modifiers are put in place. 295 | */ 296 | contract Pausable is Context, PauserRole { 297 | /** 298 | * @dev Emitted when the pause is triggered by a pauser (`account`). 299 | */ 300 | event Paused(address account); 301 | 302 | /** 303 | * @dev Emitted when the pause is lifted by a pauser (`account`). 304 | */ 305 | event Unpaused(address account); 306 | 307 | bool private _paused; 308 | 309 | /** 310 | * @dev Initializes the contract in unpaused state. Assigns the Pauser role 311 | * to the deployer. 312 | */ 313 | constructor () internal { 314 | _paused = false; 315 | } 316 | 317 | /** 318 | * @dev Returns true if the contract is paused, and false otherwise. 319 | */ 320 | function paused() public view returns (bool) { 321 | return _paused; 322 | } 323 | 324 | /** 325 | * @dev Modifier to make a function callable only when the contract is not paused. 326 | */ 327 | modifier whenNotPaused() { 328 | require(!_paused, "Pausable: paused"); 329 | _; 330 | } 331 | 332 | /** 333 | * @dev Modifier to make a function callable only when the contract is paused. 334 | */ 335 | modifier whenPaused() { 336 | require(_paused, "Pausable: not paused"); 337 | _; 338 | } 339 | 340 | /** 341 | * @dev Called by a pauser to pause, triggers stopped state. 342 | */ 343 | function pause() public onlyPauser whenNotPaused { 344 | _paused = true; 345 | emit Paused(_msgSender()); 346 | } 347 | 348 | /** 349 | * @dev Called by a pauser to unpause, returns to normal state. 350 | */ 351 | function unpause() public onlyPauser whenPaused { 352 | _paused = false; 353 | emit Unpaused(_msgSender()); 354 | } 355 | } 356 | 357 | contract MinterRole is Context { 358 | using Roles for Roles.Role; 359 | 360 | event MinterAdded(address indexed account); 361 | event MinterRemoved(address indexed account); 362 | 363 | Roles.Role private _minters; 364 | 365 | constructor () internal { 366 | _addMinter(_msgSender()); 367 | } 368 | 369 | modifier onlyMinter() { 370 | require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role"); 371 | _; 372 | } 373 | 374 | function isMinter(address account) public view returns (bool) { 375 | return _minters.has(account); 376 | } 377 | 378 | function addMinter(address account) public onlyMinter { 379 | _addMinter(account); 380 | } 381 | 382 | function renounceMinter() public { 383 | _removeMinter(_msgSender()); 384 | } 385 | 386 | function _addMinter(address account) internal { 387 | _minters.add(account); 388 | emit MinterAdded(account); 389 | } 390 | 391 | function _removeMinter(address account) internal { 392 | _minters.remove(account); 393 | emit MinterRemoved(account); 394 | } 395 | } 396 | 397 | /** 398 | * @title WhitelistAdminRole 399 | * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. 400 | */ 401 | contract WhitelistAdminRole is Context { 402 | using Roles for Roles.Role; 403 | 404 | event WhitelistAdminAdded(address indexed account); 405 | event WhitelistAdminRemoved(address indexed account); 406 | 407 | Roles.Role private _whitelistAdmins; 408 | 409 | constructor () internal { 410 | _addWhitelistAdmin(_msgSender()); 411 | } 412 | 413 | modifier onlyWhitelistAdmin() { 414 | require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); 415 | _; 416 | } 417 | 418 | function isWhitelistAdmin(address account) public view returns (bool) { 419 | return _whitelistAdmins.has(account); 420 | } 421 | 422 | function addWhitelistAdmin(address account) public onlyWhitelistAdmin { 423 | _addWhitelistAdmin(account); 424 | } 425 | 426 | function renounceWhitelistAdmin() public { 427 | _removeWhitelistAdmin(_msgSender()); 428 | } 429 | 430 | function _addWhitelistAdmin(address account) internal { 431 | _whitelistAdmins.add(account); 432 | emit WhitelistAdminAdded(account); 433 | } 434 | 435 | function _removeWhitelistAdmin(address account) internal { 436 | _whitelistAdmins.remove(account); 437 | emit WhitelistAdminRemoved(account); 438 | } 439 | } 440 | 441 | /** 442 | * @title ERC165 443 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md 444 | */ 445 | interface IERC165 { 446 | 447 | /** 448 | * @notice Query if a contract implements an interface 449 | * @dev Interface identification is specified in ERC-165. This function 450 | * uses less than 30,000 gas 451 | * @param _interfaceId The interface identifier, as specified in ERC-165 452 | */ 453 | function supportsInterface(bytes4 _interfaceId) 454 | external 455 | view 456 | returns (bool); 457 | } 458 | 459 | /** 460 | * @title SafeMath 461 | * @dev Unsigned math operations with safety checks that revert on error 462 | */ 463 | library SafeMath { 464 | 465 | /** 466 | * @dev Multiplies two unsigned integers, reverts on overflow. 467 | */ 468 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 469 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 470 | // benefit is lost if 'b' is also tested. 471 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 472 | if (a == 0) { 473 | return 0; 474 | } 475 | 476 | uint256 c = a * b; 477 | require(c / a == b, "SafeMath#mul: OVERFLOW"); 478 | 479 | return c; 480 | } 481 | 482 | /** 483 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 484 | */ 485 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 486 | // Solidity only automatically asserts when dividing by 0 487 | require(b > 0, "SafeMath#div: DIVISION_BY_ZERO"); 488 | uint256 c = a / b; 489 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 490 | 491 | return c; 492 | } 493 | 494 | /** 495 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 496 | */ 497 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 498 | require(b <= a, "SafeMath#sub: UNDERFLOW"); 499 | uint256 c = a - b; 500 | 501 | return c; 502 | } 503 | 504 | /** 505 | * @dev Adds two unsigned integers, reverts on overflow. 506 | */ 507 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 508 | uint256 c = a + b; 509 | require(c >= a, "SafeMath#add: OVERFLOW"); 510 | 511 | return c; 512 | } 513 | 514 | /** 515 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 516 | * reverts when dividing by zero. 517 | */ 518 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 519 | require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO"); 520 | return a % b; 521 | } 522 | 523 | } 524 | 525 | /** 526 | * @dev ERC-1155 interface for accepting safe transfers. 527 | */ 528 | interface IERC1155TokenReceiver { 529 | 530 | /** 531 | * @notice Handle the receipt of a single ERC1155 token type 532 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated 533 | * This function MAY throw to revert and reject the transfer 534 | * Return of other amount than the magic value MUST result in the transaction being reverted 535 | * Note: The token contract address is always the message sender 536 | * @param _operator The address which called the `safeTransferFrom` function 537 | * @param _from The address which previously owned the token 538 | * @param _id The id of the token being transferred 539 | * @param _amount The amount of tokens being transferred 540 | * @param _data Additional data with no specified format 541 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 542 | */ 543 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4); 544 | 545 | /** 546 | * @notice Handle the receipt of multiple ERC1155 token types 547 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated 548 | * This function MAY throw to revert and reject the transfer 549 | * Return of other amount than the magic value WILL result in the transaction being reverted 550 | * Note: The token contract address is always the message sender 551 | * @param _operator The address which called the `safeBatchTransferFrom` function 552 | * @param _from The address which previously owned the token 553 | * @param _ids An array containing ids of each token being transferred 554 | * @param _amounts An array containing amounts of each token being transferred 555 | * @param _data Additional data with no specified format 556 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 557 | */ 558 | function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4); 559 | 560 | /** 561 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types. 562 | * @param interfaceID The ERC-165 interface ID that is queried for support.s 563 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface. 564 | * This function MUST NOT consume more than 5,000 gas. 565 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported. 566 | */ 567 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 568 | 569 | } 570 | 571 | interface IERC1155 { 572 | // Events 573 | 574 | /** 575 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 576 | * Operator MUST be msg.sender 577 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 578 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 579 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 580 | * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 581 | */ 582 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 583 | 584 | /** 585 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning 586 | * Operator MUST be msg.sender 587 | * When minting/creating tokens, the `_from` field MUST be set to `0x0` 588 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0` 589 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID 590 | * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 591 | */ 592 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 593 | 594 | /** 595 | * @dev MUST emit when an approval is updated 596 | */ 597 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 598 | 599 | /** 600 | * @dev MUST emit when the URI is updated for a token ID 601 | * URIs are defined in RFC 3986 602 | * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema" 603 | */ 604 | event URI(string _amount, uint256 indexed _id); 605 | 606 | /** 607 | * @notice Transfers amount of an _id from the _from address to the _to address specified 608 | * @dev MUST emit TransferSingle event on success 609 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 610 | * MUST throw if `_to` is the zero address 611 | * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent 612 | * MUST throw on any other error 613 | * 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 amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 614 | * @param _from Source address 615 | * @param _to Target address 616 | * @param _id ID of the token type 617 | * @param _amount Transfered amount 618 | * @param _data Additional data with no specified format, sent in call to `_to` 619 | */ 620 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external; 621 | 622 | /** 623 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 624 | * @dev MUST emit TransferBatch event on success 625 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) 626 | * MUST throw if `_to` is the zero address 627 | * MUST throw if length of `_ids` is not the same as length of `_amounts` 628 | * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent 629 | * MUST throw on any other error 630 | * 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 amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 631 | * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc) 632 | * @param _from Source addresses 633 | * @param _to Target addresses 634 | * @param _ids IDs of each token type 635 | * @param _amounts Transfer amounts per token type 636 | * @param _data Additional data with no specified format, sent in call to `_to` 637 | */ 638 | function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external; 639 | 640 | /** 641 | * @notice Get the balance of an account's Tokens 642 | * @param _owner The address of the token holder 643 | * @param _id ID of the Token 644 | * @return The _owner's balance of the Token type requested 645 | */ 646 | function balanceOf(address _owner, uint256 _id) external view returns (uint256); 647 | 648 | /** 649 | * @notice Get the balance of multiple account/token pairs 650 | * @param _owners The addresses of the token holders 651 | * @param _ids ID of the Tokens 652 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 653 | */ 654 | function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); 655 | 656 | /** 657 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 658 | * @dev MUST emit the ApprovalForAll event on success 659 | * @param _operator Address to add to the set of authorized operators 660 | * @param _approved True if the operator is approved, false to revoke approval 661 | */ 662 | function setApprovalForAll(address _operator, bool _approved) external; 663 | 664 | /** 665 | * @notice Queries the approval status of an operator for a given owner 666 | * @param _owner The owner of the Tokens 667 | * @param _operator Address of authorized operator 668 | * @return True if the operator is approved, false if not 669 | */ 670 | function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator); 671 | 672 | } 673 | 674 | /** 675 | * Copyright 2018 ZeroEx Intl. 676 | * Licensed under the Apache License, Version 2.0 (the "License"); 677 | * you may not use this file except in compliance with the License. 678 | * You may obtain a copy of the License at 679 | * http://www.apache.org/licenses/LICENSE-2.0 680 | * Unless required by applicable law or agreed to in writing, software 681 | * distributed under the License is distributed on an "AS IS" BASIS, 682 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 683 | * See the License for the specific language governing permissions and 684 | * limitations under the License. 685 | */ 686 | /** 687 | * Utility library of inline functions on addresses 688 | */ 689 | library Address { 690 | 691 | /** 692 | * Returns whether the target address is a contract 693 | * @dev This function will return false if invoked during the constructor of a contract, 694 | * as the code is not actually created until after the constructor finishes. 695 | * @param account address of the account to check 696 | * @return whether the target address is a contract 697 | */ 698 | function isContract(address account) internal view returns (bool) { 699 | bytes32 codehash; 700 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 701 | 702 | // XXX Currently there is no better way to check if there is a contract in an address 703 | // than to check the size of the code at that address. 704 | // See https://ethereum.stackexchange.com/a/14016/36603 705 | // for more details about how this works. 706 | // TODO Check this again before the Serenity release, because all addresses will be 707 | // contracts then. 708 | assembly { codehash := extcodehash(account) } 709 | return (codehash != 0x0 && codehash != accountHash); 710 | } 711 | 712 | } 713 | 714 | /** 715 | * @dev Implementation of Multi-Token Standard contract 716 | */ 717 | contract ERC1155 is IERC165 { 718 | using SafeMath for uint256; 719 | using Address for address; 720 | 721 | 722 | /***********************************| 723 | | Variables and Events | 724 | |__________________________________*/ 725 | 726 | // onReceive function signatures 727 | bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61; 728 | bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; 729 | 730 | // Objects balances 731 | mapping (address => mapping(uint256 => uint256)) internal balances; 732 | 733 | // Operator Functions 734 | mapping (address => mapping(address => bool)) internal operators; 735 | 736 | // Events 737 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount); 738 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts); 739 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); 740 | event URI(string _uri, uint256 indexed _id); 741 | 742 | 743 | /***********************************| 744 | | Public Transfer Functions | 745 | |__________________________________*/ 746 | 747 | /** 748 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 749 | * @param _from Source address 750 | * @param _to Target address 751 | * @param _id ID of the token type 752 | * @param _amount Transfered amount 753 | * @param _data Additional data with no specified format, sent in call to `_to` 754 | */ 755 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 756 | public 757 | { 758 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR"); 759 | require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT"); 760 | // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations 761 | 762 | _safeTransferFrom(_from, _to, _id, _amount); 763 | _callonERC1155Received(_from, _to, _id, _amount, _data); 764 | } 765 | 766 | /** 767 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 768 | * @param _from Source addresses 769 | * @param _to Target addresses 770 | * @param _ids IDs of each token type 771 | * @param _amounts Transfer amounts per token type 772 | * @param _data Additional data with no specified format, sent in call to `_to` 773 | */ 774 | function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 775 | public 776 | { 777 | // Requirements 778 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR"); 779 | require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT"); 780 | 781 | _safeBatchTransferFrom(_from, _to, _ids, _amounts); 782 | _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data); 783 | } 784 | 785 | 786 | /***********************************| 787 | | Internal Transfer Functions | 788 | |__________________________________*/ 789 | 790 | /** 791 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified 792 | * @param _from Source address 793 | * @param _to Target address 794 | * @param _id ID of the token type 795 | * @param _amount Transfered amount 796 | */ 797 | function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) 798 | internal 799 | { 800 | // Update balances 801 | balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount 802 | balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount 803 | 804 | // Emit event 805 | emit TransferSingle(msg.sender, _from, _to, _id, _amount); 806 | } 807 | 808 | /** 809 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...) 810 | */ 811 | function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data) 812 | internal 813 | { 814 | // Check if recipient is contract 815 | if (_to.isContract()) { 816 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data); 817 | require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE"); 818 | } 819 | } 820 | 821 | /** 822 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) 823 | * @param _from Source addresses 824 | * @param _to Target addresses 825 | * @param _ids IDs of each token type 826 | * @param _amounts Transfer amounts per token type 827 | */ 828 | function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts) 829 | internal 830 | { 831 | require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH"); 832 | 833 | // Number of transfer to execute 834 | uint256 nTransfer = _ids.length; 835 | 836 | // Executing all transfers 837 | for (uint256 i = 0; i < nTransfer; i++) { 838 | // Update storage balance of previous bin 839 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 840 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 841 | } 842 | 843 | // Emit event 844 | emit TransferBatch(msg.sender, _from, _to, _ids, _amounts); 845 | } 846 | 847 | /** 848 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...) 849 | */ 850 | function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 851 | internal 852 | { 853 | // Pass data if recipient is contract 854 | if (_to.isContract()) { 855 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data); 856 | require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE"); 857 | } 858 | } 859 | 860 | 861 | /***********************************| 862 | | Operator Functions | 863 | |__________________________________*/ 864 | 865 | /** 866 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens 867 | * @param _operator Address to add to the set of authorized operators 868 | * @param _approved True if the operator is approved, false to revoke approval 869 | */ 870 | function setApprovalForAll(address _operator, bool _approved) 871 | external 872 | { 873 | // Update operator status 874 | operators[msg.sender][_operator] = _approved; 875 | emit ApprovalForAll(msg.sender, _operator, _approved); 876 | } 877 | 878 | /** 879 | * @notice Queries the approval status of an operator for a given owner 880 | * @param _owner The owner of the Tokens 881 | * @param _operator Address of authorized operator 882 | * @return True if the operator is approved, false if not 883 | */ 884 | function isApprovedForAll(address _owner, address _operator) 885 | public view returns (bool isOperator) 886 | { 887 | return operators[_owner][_operator]; 888 | } 889 | 890 | 891 | /***********************************| 892 | | Balance Functions | 893 | |__________________________________*/ 894 | 895 | /** 896 | * @notice Get the balance of an account's Tokens 897 | * @param _owner The address of the token holder 898 | * @param _id ID of the Token 899 | * @return The _owner's balance of the Token type requested 900 | */ 901 | function balanceOf(address _owner, uint256 _id) 902 | public view returns (uint256) 903 | { 904 | return balances[_owner][_id]; 905 | } 906 | 907 | /** 908 | * @notice Get the balance of multiple account/token pairs 909 | * @param _owners The addresses of the token holders 910 | * @param _ids ID of the Tokens 911 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) 912 | */ 913 | function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) 914 | public view returns (uint256[] memory) 915 | { 916 | require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH"); 917 | 918 | // Variables 919 | uint256[] memory batchBalances = new uint256[](_owners.length); 920 | 921 | // Iterate over each owner and token ID 922 | for (uint256 i = 0; i < _owners.length; i++) { 923 | batchBalances[i] = balances[_owners[i]][_ids[i]]; 924 | } 925 | 926 | return batchBalances; 927 | } 928 | 929 | 930 | /***********************************| 931 | | ERC165 Functions | 932 | |__________________________________*/ 933 | 934 | /** 935 | * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)")); 936 | */ 937 | bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; 938 | 939 | /** 940 | * INTERFACE_SIGNATURE_ERC1155 = 941 | * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^ 942 | * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^ 943 | * bytes4(keccak256("balanceOf(address,uint256)")) ^ 944 | * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^ 945 | * bytes4(keccak256("setApprovalForAll(address,bool)")) ^ 946 | * bytes4(keccak256("isApprovedForAll(address,address)")); 947 | */ 948 | bytes4 constant private INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; 949 | 950 | /** 951 | * @notice Query if a contract implements an interface 952 | * @param _interfaceID The interface identifier, as specified in ERC-165 953 | * @return `true` if the contract implements `_interfaceID` and 954 | */ 955 | function supportsInterface(bytes4 _interfaceID) external view returns (bool) { 956 | if (_interfaceID == INTERFACE_SIGNATURE_ERC165 || 957 | _interfaceID == INTERFACE_SIGNATURE_ERC1155) { 958 | return true; 959 | } 960 | return false; 961 | } 962 | 963 | } 964 | 965 | /** 966 | * @notice Contract that handles metadata related methods. 967 | * @dev Methods assume a deterministic generation of URI based on token IDs. 968 | * Methods also assume that URI uses hex representation of token IDs. 969 | */ 970 | contract ERC1155Metadata { 971 | 972 | // URI's default URI prefix 973 | string internal baseMetadataURI; 974 | event URI(string _uri, uint256 indexed _id); 975 | 976 | 977 | /***********************************| 978 | | Metadata Public Function s | 979 | |__________________________________*/ 980 | 981 | /** 982 | * @notice A distinct Uniform Resource Identifier (URI) for a given token. 983 | * @dev URIs are defined in RFC 3986. 984 | * URIs are assumed to be deterministically generated based on token ID 985 | * Token IDs are assumed to be represented in their hex format in URIs 986 | * @return URI string 987 | */ 988 | function uri(uint256 _id) public view returns (string memory) { 989 | return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json")); 990 | } 991 | 992 | 993 | /***********************************| 994 | | Metadata Internal Functions | 995 | |__________________________________*/ 996 | 997 | /** 998 | * @notice Will emit default URI log event for corresponding token _id 999 | * @param _tokenIDs Array of IDs of tokens to log default URI 1000 | */ 1001 | function _logURIs(uint256[] memory _tokenIDs) internal { 1002 | string memory baseURL = baseMetadataURI; 1003 | string memory tokenURI; 1004 | 1005 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 1006 | tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json")); 1007 | emit URI(tokenURI, _tokenIDs[i]); 1008 | } 1009 | } 1010 | 1011 | /** 1012 | * @notice Will emit a specific URI log event for corresponding token 1013 | * @param _tokenIDs IDs of the token corresponding to the _uris logged 1014 | * @param _URIs The URIs of the specified _tokenIDs 1015 | */ 1016 | function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal { 1017 | require(_tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH"); 1018 | for (uint256 i = 0; i < _tokenIDs.length; i++) { 1019 | emit URI(_URIs[i], _tokenIDs[i]); 1020 | } 1021 | } 1022 | 1023 | /** 1024 | * @notice Will update the base URL of token's URI 1025 | * @param _newBaseMetadataURI New base URL of token's URI 1026 | */ 1027 | function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal { 1028 | baseMetadataURI = _newBaseMetadataURI; 1029 | } 1030 | 1031 | 1032 | /***********************************| 1033 | | Utility Internal Functions | 1034 | |__________________________________*/ 1035 | 1036 | /** 1037 | * @notice Convert uint256 to string 1038 | * @param _i Unsigned integer to convert to string 1039 | */ 1040 | function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 1041 | if (_i == 0) { 1042 | return "0"; 1043 | } 1044 | 1045 | uint256 j = _i; 1046 | uint256 ii = _i; 1047 | uint256 len; 1048 | 1049 | // Get number of bytes 1050 | while (j != 0) { 1051 | len++; 1052 | j /= 10; 1053 | } 1054 | 1055 | bytes memory bstr = new bytes(len); 1056 | uint256 k = len - 1; 1057 | 1058 | // Get each individual ASCII 1059 | while (ii != 0) { 1060 | bstr[k--] = byte(uint8(48 + ii % 10)); 1061 | ii /= 10; 1062 | } 1063 | 1064 | // Convert to string 1065 | return string(bstr); 1066 | } 1067 | 1068 | } 1069 | 1070 | /** 1071 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume 1072 | * a parent contract to be executed as they are `internal` functions 1073 | */ 1074 | contract ERC1155MintBurn is ERC1155 { 1075 | 1076 | 1077 | /****************************************| 1078 | | Minting Functions | 1079 | |_______________________________________*/ 1080 | 1081 | /** 1082 | * @notice Mint _amount of tokens of a given id 1083 | * @param _to The address to mint tokens to 1084 | * @param _id Token id to mint 1085 | * @param _amount The amount to be minted 1086 | * @param _data Data to pass if receiver is contract 1087 | */ 1088 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data) 1089 | internal 1090 | { 1091 | // Add _amount 1092 | balances[_to][_id] = balances[_to][_id].add(_amount); 1093 | 1094 | // Emit event 1095 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount); 1096 | 1097 | // Calling onReceive method if recipient is contract 1098 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data); 1099 | } 1100 | 1101 | /** 1102 | * @notice Mint tokens for each ids in _ids 1103 | * @param _to The address to mint tokens to 1104 | * @param _ids Array of ids to mint 1105 | * @param _amounts Array of amount of tokens to mint per id 1106 | * @param _data Data to pass if receiver is contract 1107 | */ 1108 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data) 1109 | internal 1110 | { 1111 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH"); 1112 | 1113 | // Number of mints to execute 1114 | uint256 nMint = _ids.length; 1115 | 1116 | // Executing all minting 1117 | for (uint256 i = 0; i < nMint; i++) { 1118 | // Update storage balance 1119 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); 1120 | } 1121 | 1122 | // Emit batch mint event 1123 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts); 1124 | 1125 | // Calling onReceive method if recipient is contract 1126 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data); 1127 | } 1128 | 1129 | 1130 | /****************************************| 1131 | | Burning Functions | 1132 | |_______________________________________*/ 1133 | 1134 | /** 1135 | * @notice Burn _amount of tokens of a given token id 1136 | * @param _from The address to burn tokens from 1137 | * @param _id Token id to burn 1138 | * @param _amount The amount to be burned 1139 | */ 1140 | function _burn(address _from, uint256 _id, uint256 _amount) 1141 | internal 1142 | { 1143 | //Substract _amount 1144 | balances[_from][_id] = balances[_from][_id].sub(_amount); 1145 | 1146 | // Emit event 1147 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount); 1148 | } 1149 | 1150 | /** 1151 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair 1152 | * @param _from The address to burn tokens from 1153 | * @param _ids Array of token ids to burn 1154 | * @param _amounts Array of the amount to be burned 1155 | */ 1156 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts) 1157 | internal 1158 | { 1159 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH"); 1160 | 1161 | // Number of mints to execute 1162 | uint256 nBurn = _ids.length; 1163 | 1164 | // Executing all minting 1165 | for (uint256 i = 0; i < nBurn; i++) { 1166 | // Update storage balance 1167 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]); 1168 | } 1169 | 1170 | // Emit batch mint event 1171 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts); 1172 | } 1173 | 1174 | } 1175 | 1176 | library Strings { 1177 | // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol 1178 | function strConcat( 1179 | string memory _a, 1180 | string memory _b, 1181 | string memory _c, 1182 | string memory _d, 1183 | string memory _e 1184 | ) internal pure returns (string memory) { 1185 | bytes memory _ba = bytes(_a); 1186 | bytes memory _bb = bytes(_b); 1187 | bytes memory _bc = bytes(_c); 1188 | bytes memory _bd = bytes(_d); 1189 | bytes memory _be = bytes(_e); 1190 | string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); 1191 | bytes memory babcde = bytes(abcde); 1192 | uint256 k = 0; 1193 | for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; 1194 | for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; 1195 | for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; 1196 | for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; 1197 | for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i]; 1198 | return string(babcde); 1199 | } 1200 | 1201 | function strConcat( 1202 | string memory _a, 1203 | string memory _b, 1204 | string memory _c, 1205 | string memory _d 1206 | ) internal pure returns (string memory) { 1207 | return strConcat(_a, _b, _c, _d, ""); 1208 | } 1209 | 1210 | function strConcat( 1211 | string memory _a, 1212 | string memory _b, 1213 | string memory _c 1214 | ) internal pure returns (string memory) { 1215 | return strConcat(_a, _b, _c, "", ""); 1216 | } 1217 | 1218 | function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { 1219 | return strConcat(_a, _b, "", "", ""); 1220 | } 1221 | 1222 | function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { 1223 | if (_i == 0) { 1224 | return "0"; 1225 | } 1226 | uint256 j = _i; 1227 | uint256 len; 1228 | while (j != 0) { 1229 | len++; 1230 | j /= 10; 1231 | } 1232 | bytes memory bstr = new bytes(len); 1233 | uint256 k = len - 1; 1234 | while (_i != 0) { 1235 | bstr[k--] = bytes1(uint8(48 + (_i % 10))); 1236 | _i /= 10; 1237 | } 1238 | return string(bstr); 1239 | } 1240 | } 1241 | 1242 | contract OwnableDelegateProxy {} 1243 | 1244 | contract ProxyRegistry { 1245 | mapping(address => OwnableDelegateProxy) public proxies; 1246 | } 1247 | 1248 | /** 1249 | * @title ERC1155Tradable 1250 | * ERC1155Tradable - ERC1155 contract that whitelists an operator address, 1251 | * has create and mint functionality, and supports useful standards from OpenZeppelin, 1252 | like _exists(), name(), symbol(), and totalSupply() 1253 | */ 1254 | contract ERC1155Tradable is ERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable, MinterRole, WhitelistAdminRole { 1255 | using Strings for string; 1256 | 1257 | address proxyRegistryAddress; 1258 | uint256 private _currentTokenID = 0; 1259 | mapping(uint256 => address) public creators; 1260 | mapping(uint256 => uint256) public tokenSupply; 1261 | mapping(uint256 => uint256) public tokenMaxSupply; 1262 | // Contract name 1263 | string public name; 1264 | // Contract symbol 1265 | string public symbol; 1266 | 1267 | constructor( 1268 | string memory _name, 1269 | string memory _symbol, 1270 | address _proxyRegistryAddress 1271 | ) public { 1272 | name = _name; 1273 | symbol = _symbol; 1274 | proxyRegistryAddress = _proxyRegistryAddress; 1275 | } 1276 | 1277 | function removeWhitelistAdmin(address account) public onlyOwner { 1278 | _removeWhitelistAdmin(account); 1279 | } 1280 | 1281 | function removeMinter(address account) public onlyOwner { 1282 | _removeMinter(account); 1283 | } 1284 | 1285 | function uri(uint256 _id) public view returns (string memory) { 1286 | require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN"); 1287 | return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id)); 1288 | } 1289 | 1290 | /** 1291 | * @dev Returns the total quantity for a token ID 1292 | * @param _id uint256 ID of the token to query 1293 | * @return amount of token in existence 1294 | */ 1295 | function totalSupply(uint256 _id) public view returns (uint256) { 1296 | return tokenSupply[_id]; 1297 | } 1298 | 1299 | /** 1300 | * @dev Returns the max quantity for a token ID 1301 | * @param _id uint256 ID of the token to query 1302 | * @return amount of token in existence 1303 | */ 1304 | function maxSupply(uint256 _id) public view returns (uint256) { 1305 | return tokenMaxSupply[_id]; 1306 | } 1307 | 1308 | /** 1309 | * @dev Will update the base URL of token's URI 1310 | * @param _newBaseMetadataURI New base URL of token's URI 1311 | */ 1312 | function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyWhitelistAdmin { 1313 | _setBaseMetadataURI(_newBaseMetadataURI); 1314 | } 1315 | 1316 | /** 1317 | * @dev Creates a new token type and assigns _initialSupply to an address 1318 | * @param _maxSupply max supply allowed 1319 | * @param _initialSupply Optional amount to supply the first owner 1320 | * @param _uri Optional URI for this token type 1321 | * @param _data Optional data to pass if receiver is contract 1322 | * @return The newly created token ID 1323 | */ 1324 | function create( 1325 | uint256 _maxSupply, 1326 | uint256 _initialSupply, 1327 | string calldata _uri, 1328 | bytes calldata _data 1329 | ) external onlyWhitelistAdmin returns (uint256 tokenId) { 1330 | require(_initialSupply <= _maxSupply, "Initial supply cannot be more than max supply"); 1331 | uint256 _id = _getNextTokenID(); 1332 | _incrementTokenTypeId(); 1333 | creators[_id] = msg.sender; 1334 | 1335 | if (bytes(_uri).length > 0) { 1336 | emit URI(_uri, _id); 1337 | } 1338 | 1339 | if (_initialSupply != 0) _mint(msg.sender, _id, _initialSupply, _data); 1340 | tokenSupply[_id] = _initialSupply; 1341 | tokenMaxSupply[_id] = _maxSupply; 1342 | return _id; 1343 | } 1344 | 1345 | /** 1346 | * @dev Mints some amount of tokens to an address 1347 | * @param _to Address of the future owner of the token 1348 | * @param _id Token ID to mint 1349 | * @param _quantity Amount of tokens to mint 1350 | * @param _data Data to pass if receiver is contract 1351 | */ 1352 | function mint( 1353 | address _to, 1354 | uint256 _id, 1355 | uint256 _quantity, 1356 | bytes memory _data 1357 | ) public onlyMinter { 1358 | uint256 tokenId = _id; 1359 | require(tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached"); 1360 | _mint(_to, _id, _quantity, _data); 1361 | tokenSupply[_id] = tokenSupply[_id].add(_quantity); 1362 | } 1363 | 1364 | /** 1365 | * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings. 1366 | */ 1367 | function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { 1368 | // Whitelist OpenSea proxy contract for easy trading. 1369 | ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); 1370 | if (address(proxyRegistry.proxies(_owner)) == _operator) { 1371 | return true; 1372 | } 1373 | 1374 | return ERC1155.isApprovedForAll(_owner, _operator); 1375 | } 1376 | 1377 | /** 1378 | * @dev Returns whether the specified token exists by checking to see if it has a creator 1379 | * @param _id uint256 ID of the token to query the existence of 1380 | * @return bool whether the token exists 1381 | */ 1382 | function _exists(uint256 _id) internal view returns (bool) { 1383 | return creators[_id] != address(0); 1384 | } 1385 | 1386 | /** 1387 | * @dev calculates the next token ID based on value of _currentTokenID 1388 | * @return uint256 for the next token ID 1389 | */ 1390 | function _getNextTokenID() private view returns (uint256) { 1391 | return _currentTokenID.add(1); 1392 | } 1393 | 1394 | /** 1395 | * @dev increments the value of _currentTokenID 1396 | */ 1397 | function _incrementTokenTypeId() private { 1398 | _currentTokenID++; 1399 | } 1400 | } 1401 | 1402 | contract MemeTokenWrapper { 1403 | using SafeMath for uint256; 1404 | IERC20 public meme; 1405 | 1406 | constructor(IERC20 _memeAddress) public { 1407 | meme = IERC20(_memeAddress); 1408 | } 1409 | 1410 | uint256 private _totalSupply; 1411 | mapping(address => uint256) private _balances; 1412 | 1413 | function totalSupply() public view returns (uint256) { 1414 | return _totalSupply; 1415 | } 1416 | 1417 | function balanceOf(address account) public view returns (uint256) { 1418 | return _balances[account]; 1419 | } 1420 | 1421 | function stake(uint256 amount) public { 1422 | _totalSupply = _totalSupply.add(amount); 1423 | _balances[msg.sender] = _balances[msg.sender].add(amount); 1424 | meme.transferFrom(msg.sender, address(this), amount); 1425 | } 1426 | 1427 | function withdraw(uint256 amount) public { 1428 | _totalSupply = _totalSupply.sub(amount); 1429 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 1430 | meme.transfer(msg.sender, amount); 1431 | } 1432 | } 1433 | 1434 | contract MEMELtdPool is MemeTokenWrapper, Ownable, Pausable { 1435 | using SafeMath for uint256; 1436 | ERC1155Tradable public memeLtd; 1437 | 1438 | struct Card { 1439 | uint256 points; 1440 | uint256 releaseTime; 1441 | } 1442 | 1443 | uint256 public periodStart; 1444 | uint256 public maxStake; 1445 | uint256 public rewardRate = 11574074074000; // 1 point per day per staked MEME 1446 | mapping(address => uint256) public lastUpdateTime; 1447 | mapping(address => uint256) public points; 1448 | mapping(uint256 => Card) public cards; 1449 | 1450 | event CardAdded(uint256 card, uint256 points, uint256 releaseTime); 1451 | event Staked(address indexed user, uint256 amount); 1452 | event Withdrawn(address indexed user, uint256 amount); 1453 | event Redeemed(address indexed user, uint256 amount); 1454 | 1455 | modifier updateReward(address account) { 1456 | if (account != address(0)) { 1457 | points[account] = earned(account); 1458 | lastUpdateTime[account] = block.timestamp; 1459 | } 1460 | _; 1461 | } 1462 | 1463 | constructor( 1464 | uint256 _periodStart, 1465 | uint256 _maxStake, 1466 | ERC1155Tradable _memeLtdAddress, 1467 | IERC20 _memeAddress 1468 | ) public MemeTokenWrapper(_memeAddress) { 1469 | maxStake = _maxStake; 1470 | periodStart = _periodStart; 1471 | memeLtd = _memeLtdAddress; 1472 | } 1473 | 1474 | function addCard( 1475 | uint256 _id, 1476 | uint256 _points, 1477 | uint256 _releaseTime 1478 | ) public onlyOwner { 1479 | Card storage c = cards[_id]; 1480 | c.points = _points; 1481 | c.releaseTime = _releaseTime; 1482 | emit CardAdded(_id, _points, _releaseTime); 1483 | } 1484 | 1485 | function earned(address account) public view returns (uint256) { 1486 | uint256 blockTime = block.timestamp; 1487 | return 1488 | balanceOf(account).mul(blockTime.sub(lastUpdateTime[account]).mul(rewardRate)).div(1e8).add( 1489 | points[account] 1490 | ); 1491 | } 1492 | 1493 | // stake visibility is public as overriding MemeTokenWrapper's stake() function 1494 | function stake(uint256 amount) public updateReward(msg.sender) whenNotPaused() { 1495 | require(block.timestamp >= periodStart, "Pool not open"); 1496 | require(amount.add(balanceOf(msg.sender)) <= maxStake, "Deposit 5 MEME or less, no whales"); 1497 | 1498 | super.stake(amount); 1499 | emit Staked(msg.sender, amount); 1500 | } 1501 | 1502 | function withdraw(uint256 amount) public updateReward(msg.sender) { 1503 | require(amount > 0, "Cannot withdraw 0"); 1504 | 1505 | super.withdraw(amount); 1506 | emit Withdrawn(msg.sender, amount); 1507 | } 1508 | 1509 | function exit() external { 1510 | withdraw(balanceOf(msg.sender)); 1511 | } 1512 | 1513 | function redeem(uint256 id) public updateReward(msg.sender) { 1514 | require(cards[id].points != 0, "Card not found"); 1515 | require(block.timestamp >= cards[id].releaseTime, "Card not released"); 1516 | require(points[msg.sender] >= cards[id].points, "Redemption exceeds point balance"); 1517 | 1518 | points[msg.sender] = points[msg.sender].sub(cards[id].points); 1519 | memeLtd.mint(msg.sender, id, 1, ""); 1520 | emit Redeemed(msg.sender, cards[id].points); 1521 | } 1522 | } 1523 | --------------------------------------------------------------------------------