Feature Tip: Add private address tag to any address under My Name Tag !
ERC-20
Overview
Max Total Supply
14,405 EPIC
Holders
37
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ERC20SubToken
Compiler Version
v0.6.5+commit.f956cc89
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.6.5; import "../contracts_common/src/Libraries/SafeMathWithRequire.sol"; import "../contracts_common/src/BaseWithStorage/SuperOperators.sol"; import "../contracts_common/src/BaseWithStorage/MetaTransactionReceiver.sol"; import "./ERC20Group.sol"; contract ERC20SubToken { // TODO add natspec, currently blocked by solidity compiler issue event Transfer(address indexed from, address indexed to, uint256 value); // TODO add natspec, currently blocked by solidity compiler issue event Approval(address indexed owner, address indexed spender, uint256 value); /// @notice A descriptive name for the tokens /// @return name of the tokens function name() public view returns (string memory) { return _name; } /// @notice An abbreviated name for the tokens /// @return symbol of the tokens function symbol() public view returns (string memory) { return _symbol; } /// @notice the tokenId in ERC20Group /// @return the tokenId in ERC20Group function groupTokenId() external view returns (uint256) { return _index; } /// @notice the ERC20Group address /// @return the address of the group function groupAddress() external view returns (address) { return address(_group); } function totalSupply() external view returns (uint256) { return _group.supplyOf(_index); } function balanceOf(address who) external view returns (uint256) { return _group.balanceOf(who, _index); } function decimals() external pure returns (uint8) { return uint8(0); } function transfer(address to, uint256 amount) external returns (bool success) { _transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) external returns (bool success) { if (msg.sender != from && !_group.isAuthorizedToTransfer(from, msg.sender)) { uint256 allowance = _mAllowed[from][msg.sender]; if (allowance != ~uint256(0)) { // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717) require(allowance >= amount, "NOT_AUTHOIZED_ALLOWANCE"); _mAllowed[from][msg.sender] = allowance - amount; } } _transfer(from, to, amount); return true; } function approve(address spender, uint256 amount) external returns (bool success) { _approveFor(msg.sender, spender, amount); return true; } function approveFor( address from, address spender, uint256 amount ) external returns (bool success) { require(msg.sender == from || _group.isAuthorizedToApprove(msg.sender), "NOT_AUTHORIZED"); _approveFor(from, spender, amount); return true; } function emitTransferEvent( address from, address to, uint256 amount ) external { require(msg.sender == address(_group), "NOT_AUTHORIZED_GROUP_ONLY"); emit Transfer(from, to, amount); } // /////////////////// INTERNAL //////////////////////// function _approveFor( address owner, address spender, uint256 amount ) internal { require(owner != address(0) && spender != address(0), "INVALID_FROM_OR_SPENDER"); _mAllowed[owner][spender] = amount; emit Approval(owner, spender, amount); } function allowance(address owner, address spender) external view returns (uint256 remaining) { return _mAllowed[owner][spender]; } function _transfer( address from, address to, uint256 amount ) internal { _group.singleTransferFrom(from, to, _index, amount); } // ///////////////////// UTILITIES /////////////////////// using SafeMathWithRequire for uint256; // //////////////////// CONSTRUCTOR ///////////////////// constructor( ERC20Group group, uint256 index, string memory tokenName, string memory tokenSymbol ) public { _group = group; _index = index; _name = tokenName; _symbol = tokenSymbol; } // ////////////////////// DATA /////////////////////////// ERC20Group internal immutable _group; uint256 internal immutable _index; mapping(address => mapping(address => uint256)) internal _mAllowed; string internal _name; string internal _symbol; }
pragma solidity 0.6.5; pragma experimental ABIEncoderV2; import "./ERC20SubToken.sol"; import "../contracts_common/src/Libraries/SafeMath.sol"; import "../contracts_common/src/Libraries/AddressUtils.sol"; import "../contracts_common/src/Libraries/ObjectLib32.sol"; import "../contracts_common/src/Libraries/BytesUtil.sol"; import "../contracts_common/src/BaseWithStorage/SuperOperators.sol"; import "../contracts_common/src/BaseWithStorage/MetaTransactionReceiver.sol"; contract ERC20Group is SuperOperators, MetaTransactionReceiver { uint256 internal constant MAX_UINT256 = ~uint256(0); /// @notice emitted when a new Token is added to the group. /// @param subToken the token added, its id will be its index in the array. event SubToken(ERC20SubToken subToken); /// @notice emitted when `owner` is allowing or disallowing `operator` to transfer tokens on its behalf. /// @param owner the address approving. /// @param operator the address being granted (or revoked) permission to transfer. /// @param approved whether the operator is granted transfer right or not. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event Minter(address minter, bool enabled); /// @notice Enable or disable the ability of `minter` to mint tokens /// @param minter address that will be given/removed minter right. /// @param enabled set whether the minter is enabled or disabled. function setMinter(address minter, bool enabled) external { require(msg.sender == _admin, "NOT_AUTHORIZED_ADMIN"); _setMinter(minter, enabled); } /// @notice check whether address `who` is given minter rights. /// @param who The address to query. /// @return whether the address has minter rights. function isMinter(address who) public view returns (bool) { return _minters[who]; } /// @dev mint more tokens of a specific subToken . /// @param to address receiving the tokens. /// @param id subToken id (also the index at which it was added). /// @param amount of token minted. function mint( address to, uint256 id, uint256 amount ) external { require(_minters[msg.sender], "NOT_AUTHORIZED_MINTER"); (uint256 bin, uint256 index) = id.getTokenBinIndex(); mapping(uint256 => uint256) storage toPack = _packedTokenBalance[to]; toPack[bin] = toPack[bin].updateTokenBalance(index, amount, ObjectLib32.Operations.ADD); _packedSupplies[bin] = _packedSupplies[bin].updateTokenBalance(index, amount, ObjectLib32.Operations.ADD); _erc20s[id].emitTransferEvent(address(0), to, amount); } /// @dev mint more tokens of a several subToken . /// @param to address receiving the tokens. /// @param ids subToken ids (also the index at which it was added). /// @param amounts for each token minted. function batchMint( address to, uint256[] calldata ids, uint256[] calldata amounts ) external { require(_minters[msg.sender], "NOT_AUTHORIZED_MINTER"); require(ids.length == amounts.length, "INVALID_INCONSISTENT_LENGTH"); _batchMint(to, ids, amounts); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts ) internal { uint256 lastBin = MAX_UINT256; uint256 bal = 0; uint256 supply = 0; mapping(uint256 => uint256) storage toPack = _packedTokenBalance[to]; for (uint256 i = 0; i < ids.length; i++) { if (amounts[i] != 0) { (uint256 bin, uint256 index) = ids[i].getTokenBinIndex(); if (lastBin == MAX_UINT256) { lastBin = bin; bal = toPack[bin].updateTokenBalance(index, amounts[i], ObjectLib32.Operations.ADD); supply = _packedSupplies[bin].updateTokenBalance(index, amounts[i], ObjectLib32.Operations.ADD); } else { if (bin != lastBin) { toPack[lastBin] = bal; bal = toPack[bin]; _packedSupplies[lastBin] = supply; supply = _packedSupplies[bin]; lastBin = bin; } bal = bal.updateTokenBalance(index, amounts[i], ObjectLib32.Operations.ADD); supply = supply.updateTokenBalance(index, amounts[i], ObjectLib32.Operations.ADD); } _erc20s[ids[i]].emitTransferEvent(address(0), to, amounts[i]); } } if (lastBin != MAX_UINT256) { toPack[lastBin] = bal; _packedSupplies[lastBin] = supply; } } /// @notice return the current total supply of a specific subToken. /// @param id subToken id. /// @return supply current total number of tokens. function supplyOf(uint256 id) external view returns (uint256 supply) { (uint256 bin, uint256 index) = id.getTokenBinIndex(); return _packedSupplies[bin].getValueInBin(index); } /// @notice return the balance of a particular owner for a particular subToken. /// @param owner whose balance it is of. /// @param id subToken id. /// @return balance of the owner function balanceOf(address owner, uint256 id) public view returns (uint256 balance) { (uint256 bin, uint256 index) = id.getTokenBinIndex(); return _packedTokenBalance[owner][bin].getValueInBin(index); } /// @notice return the balances of a list of owners / subTokens. /// @param owners list of addresses to which we want to know the balance. /// @param ids list of subTokens's addresses. /// @return balances list of balances for each request. function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external view returns (uint256[] memory balances) { require(owners.length == ids.length, "INVALID_INCONSISTENT_LENGTH"); balances = new uint256[](ids.length); for (uint256 i = 0; i < ids.length; i++) { balances[i] = balanceOf(owners[i], ids[i]); } } /// @notice transfer a number of subToken from one address to another. /// @param from owner to transfer from. /// @param to destination address that will receive the tokens. /// @param id subToken id. /// @param value amount of tokens to transfer. function singleTransferFrom( address from, address to, uint256 id, uint256 value ) external { require(to != address(0), "INVALID_TO_ZERO_ADDRESS"); ERC20SubToken erc20 = _erc20s[id]; require( from == msg.sender || msg.sender == address(erc20) || _metaTransactionContracts[msg.sender] || _superOperators[msg.sender] || _operatorsForAll[from][msg.sender], "NOT_AUTHORIZED" ); (uint256 bin, uint256 index) = id.getTokenBinIndex(); mapping(uint256 => uint256) storage fromPack = _packedTokenBalance[from]; mapping(uint256 => uint256) storage toPack = _packedTokenBalance[to]; fromPack[bin] = fromPack[bin].updateTokenBalance(index, value, ObjectLib32.Operations.SUB); toPack[bin] = toPack[bin].updateTokenBalance(index, value, ObjectLib32.Operations.ADD); erc20.emitTransferEvent(from, to, value); } /// @notice transfer a number of different subTokens from one address to another. /// @param from owner to transfer from. /// @param to destination address that will receive the tokens. /// @param ids list of subToken ids to transfer. /// @param values list of amount for eacg subTokens to transfer. function batchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata values ) external { require(ids.length == values.length, "INVALID_INCONSISTENT_LENGTH"); require(to != address(0), "INVALID_TO_ZERO_ADDRESS"); require( from == msg.sender || _superOperators[msg.sender] || _operatorsForAll[from][msg.sender] || _metaTransactionContracts[msg.sender], "NOT_AUTHORIZED" ); _batchTransferFrom(from, to, ids, values); } function _batchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory values ) internal { uint256 lastBin = MAX_UINT256; uint256 balFrom; uint256 balTo; mapping(uint256 => uint256) storage fromPack = _packedTokenBalance[from]; mapping(uint256 => uint256) storage toPack = _packedTokenBalance[to]; for (uint256 i = 0; i < ids.length; i++) { if (values[i] != 0) { (uint256 bin, uint256 index) = ids[i].getTokenBinIndex(); if (lastBin == MAX_UINT256) { lastBin = bin; balFrom = ObjectLib32.updateTokenBalance(fromPack[bin], index, values[i], ObjectLib32.Operations.SUB); balTo = ObjectLib32.updateTokenBalance(toPack[bin], index, values[i], ObjectLib32.Operations.ADD); } else { if (bin != lastBin) { fromPack[lastBin] = balFrom; toPack[lastBin] = balTo; balFrom = fromPack[bin]; balTo = toPack[bin]; lastBin = bin; } balFrom = balFrom.updateTokenBalance(index, values[i], ObjectLib32.Operations.SUB); balTo = balTo.updateTokenBalance(index, values[i], ObjectLib32.Operations.ADD); } ERC20SubToken erc20 = _erc20s[ids[i]]; erc20.emitTransferEvent(from, to, values[i]); } } if (lastBin != MAX_UINT256) { fromPack[lastBin] = balFrom; toPack[lastBin] = balTo; } } /// @notice grant or revoke the ability for an address to transfer token on behalf of another address. /// @param sender address granting/revoking the approval. /// @param operator address being granted/revoked ability to transfer. /// @param approved whether the operator is revoked or approved. function setApprovalForAllFor( address sender, address operator, bool approved ) external { require(msg.sender == sender || _metaTransactionContracts[msg.sender] || _superOperators[msg.sender], "NOT_AUTHORIZED"); _setApprovalForAll(sender, operator, approved); } /// @notice grant or revoke the ability for an address to transfer token on your behalf. /// @param operator address being granted/revoked ability to transfer. /// @param approved whether the operator is revoked or approved. function setApprovalForAll(address operator, bool approved) external { _setApprovalForAll(msg.sender, operator, approved); } /// @notice return whether an oeprator has the ability to transfer on behalf of another address. /// @param owner address who would have granted the rights. /// @param operator address being given the ability to transfer. /// @return isOperator whether the operator has approval rigths or not. function isApprovedForAll(address owner, address operator) external view returns (bool isOperator) { return _operatorsForAll[owner][operator] || _superOperators[operator]; } function isAuthorizedToTransfer(address owner, address sender) external view returns (bool) { return _metaTransactionContracts[sender] || _superOperators[sender] || _operatorsForAll[owner][sender]; } function isAuthorizedToApprove(address sender) external view returns (bool) { return _metaTransactionContracts[sender] || _superOperators[sender]; } function batchBurnFrom( address from, uint256[] calldata ids, uint256[] calldata amounts ) external { require(from != address(0), "INVALID_FROM_ZERO_ADDRESS"); require( from == msg.sender || _metaTransactionContracts[msg.sender] || _superOperators[msg.sender] || _operatorsForAll[from][msg.sender], "NOT_AUTHORIZED" ); _batchBurnFrom(from, ids, amounts); } /// @notice burn token for a specific owner and subToken. /// @param from fron which address the token are burned from. /// @param id subToken id. /// @param value amount of tokens to burn. function burnFrom( address from, uint256 id, uint256 value ) external { require( from == msg.sender || _superOperators[msg.sender] || _operatorsForAll[from][msg.sender] || _metaTransactionContracts[msg.sender], "NOT_AUTHORIZED" ); _burn(from, id, value); } /// @notice burn token for a specific subToken. /// @param id subToken id. /// @param value amount of tokens to burn. function burn(uint256 id, uint256 value) external { _burn(msg.sender, id, value); } // ///////////////// INTERNAL ////////////////////////// function _batchBurnFrom( address from, uint256[] memory ids, uint256[] memory amounts ) internal { uint256 balFrom = 0; uint256 supply = 0; uint256 lastBin = MAX_UINT256; mapping(uint256 => uint256) storage fromPack = _packedTokenBalance[from]; for (uint256 i = 0; i < ids.length; i++) { if (amounts[i] != 0) { (uint256 bin, uint256 index) = ids[i].getTokenBinIndex(); if (lastBin == MAX_UINT256) { lastBin = bin; balFrom = fromPack[bin].updateTokenBalance(index, amounts[i], ObjectLib32.Operations.SUB); supply = _packedSupplies[bin].updateTokenBalance(index, amounts[i], ObjectLib32.Operations.SUB); } else { if (bin != lastBin) { fromPack[lastBin] = balFrom; balFrom = fromPack[bin]; _packedSupplies[lastBin] = supply; supply = _packedSupplies[bin]; lastBin = bin; } balFrom = balFrom.updateTokenBalance(index, amounts[i], ObjectLib32.Operations.SUB); supply = supply.updateTokenBalance(index, amounts[i], ObjectLib32.Operations.SUB); } _erc20s[ids[i]].emitTransferEvent(from, address(0), amounts[i]); } } if (lastBin != MAX_UINT256) { fromPack[lastBin] = balFrom; _packedSupplies[lastBin] = supply; } } function _burn( address from, uint256 id, uint256 value ) internal { ERC20SubToken erc20 = _erc20s[id]; (uint256 bin, uint256 index) = id.getTokenBinIndex(); mapping(uint256 => uint256) storage fromPack = _packedTokenBalance[from]; fromPack[bin] = ObjectLib32.updateTokenBalance(fromPack[bin], index, value, ObjectLib32.Operations.SUB); _packedSupplies[bin] = ObjectLib32.updateTokenBalance(_packedSupplies[bin], index, value, ObjectLib32.Operations.SUB); erc20.emitTransferEvent(from, address(0), value); } function _addSubToken(ERC20SubToken subToken) internal returns (uint256 id) { id = _erc20s.length; require(subToken.groupAddress() == address(this), "INVALID_GROUP"); require(subToken.groupTokenId() == id, "INVALID_ID"); _erc20s.push(subToken); emit SubToken(subToken); } function _setApprovalForAll( address sender, address operator, bool approved ) internal { require(!_superOperators[operator], "INVALID_SUPER_OPERATOR"); _operatorsForAll[sender][operator] = approved; emit ApprovalForAll(sender, operator, approved); } function _setMinter(address minter, bool enabled) internal { _minters[minter] = enabled; emit Minter(minter, enabled); } // ///////////////// UTILITIES ///////////////////////// using AddressUtils for address; using ObjectLib32 for ObjectLib32.Operations; using ObjectLib32 for uint256; using SafeMath for uint256; // ////////////////// DATA /////////////////////////////// mapping(uint256 => uint256) internal _packedSupplies; mapping(address => mapping(uint256 => uint256)) internal _packedTokenBalance; mapping(address => mapping(address => bool)) internal _operatorsForAll; ERC20SubToken[] internal _erc20s; mapping(address => bool) internal _minters; // ////////////// CONSTRUCTOR //////////////////////////// struct SubTokenData { string name; string symbol; } constructor( address metaTransactionContract, address admin, address initialMinter ) internal { _admin = admin; _setMetaTransactionProcessor(metaTransactionContract, true); _setMinter(initialMinter, true); } }
pragma solidity ^0.6.0; contract Admin { address internal _admin; /// @dev emitted when the contract administrator is changed. /// @param oldAdmin address of the previous administrator. /// @param newAdmin address of the new administrator. event AdminChanged(address oldAdmin, address newAdmin); /// @dev gives the current administrator of this contract. /// @return the current administrator of this contract. function getAdmin() external view returns (address) { return _admin; } /// @dev change the administrator to be `newAdmin`. /// @param newAdmin address of the new administrator. function changeAdmin(address newAdmin) external { require(msg.sender == _admin, "only admin can change admin"); emit AdminChanged(_admin, newAdmin); _admin = newAdmin; } modifier onlyAdmin() { require(msg.sender == _admin, "only admin allowed"); _; } }
pragma solidity ^0.6.0; import "./Admin.sol"; contract MetaTransactionReceiver is Admin { mapping(address => bool) internal _metaTransactionContracts; /// @dev emiited when a meta transaction processor is enabled/disabled /// @param metaTransactionProcessor address that will be given/removed metaTransactionProcessor rights. /// @param enabled set whether the metaTransactionProcessor is enabled or disabled. event MetaTransactionProcessor(address metaTransactionProcessor, bool enabled); /// @dev Enable or disable the ability of `metaTransactionProcessor` to perform meta-tx (metaTransactionProcessor rights). /// @param metaTransactionProcessor address that will be given/removed metaTransactionProcessor rights. /// @param enabled set whether the metaTransactionProcessor is enabled or disabled. function setMetaTransactionProcessor(address metaTransactionProcessor, bool enabled) public { require(msg.sender == _admin, "only admin can setup metaTransactionProcessors"); _setMetaTransactionProcessor(metaTransactionProcessor, enabled); } function _setMetaTransactionProcessor(address metaTransactionProcessor, bool enabled) internal { _metaTransactionContracts[metaTransactionProcessor] = enabled; emit MetaTransactionProcessor(metaTransactionProcessor, enabled); } /// @dev check whether address `who` is given meta-transaction execution rights. /// @param who The address to query. /// @return whether the address has meta-transaction execution rights. function isMetaTransactionProcessor(address who) external view returns (bool) { return _metaTransactionContracts[who]; } }
pragma solidity ^0.6.0; import "./Admin.sol"; contract SuperOperators is Admin { mapping(address => bool) internal _superOperators; event SuperOperator(address superOperator, bool enabled); /// @notice Enable or disable the ability of `superOperator` to transfer tokens of all (superOperator rights). /// @param superOperator address that will be given/removed superOperator right. /// @param enabled set whether the superOperator is enabled or disabled. function setSuperOperator(address superOperator, bool enabled) external { require(msg.sender == _admin, "only admin is allowed to add super operators"); _superOperators[superOperator] = enabled; emit SuperOperator(superOperator, enabled); } /// @notice check whether address `who` is given superOperator rights. /// @param who The address to query. /// @return whether the address has superOperator rights. function isSuperOperator(address who) public view returns (bool) { return _superOperators[who]; } }
pragma solidity ^0.6.0; library AddressUtils { function toPayable(address _address) internal pure returns (address payable _payable) { return address(uint160(_address)); } function isContract(address addr) internal view returns (bool) { // for accounts without code, i.e. `keccak256('')`: bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; bytes32 codehash; // solium-disable-next-line security/no-inline-assembly assembly { codehash := extcodehash(addr) } return (codehash != 0x0 && codehash != accountHash); } }
pragma solidity ^0.6.0; library BytesUtil { function memcpy( uint256 dest, uint256 src, uint256 len ) internal pure { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint256 mask = 256**(32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } function pointerToBytes(uint256 src, uint256 len) internal pure returns (bytes memory) { bytes memory ret = new bytes(len); uint256 retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, src, len); return ret; } function addressToBytes(address a) internal pure returns (bytes memory b) { assembly { let m := mload(0x40) mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, a)) mstore(0x40, add(m, 52)) b := m } } function uint256ToBytes(uint256 a) internal pure returns (bytes memory b) { assembly { let m := mload(0x40) mstore(add(m, 32), a) mstore(0x40, add(m, 64)) b := m } } function doFirstParamEqualsAddress(bytes memory data, address _address) internal pure returns (bool) { if (data.length < (36 + 32)) { return false; } uint256 value; assembly { value := mload(add(data, 36)) } return value == uint256(_address); } function doParamEqualsUInt256( bytes memory data, uint256 i, uint256 value ) internal pure returns (bool) { if (data.length < (36 + (i + 1) * 32)) { return false; } uint256 offset = 36 + i * 32; uint256 valuePresent; assembly { valuePresent := mload(add(data, offset)) } return valuePresent == value; } function overrideFirst32BytesWithAddress(bytes memory data, address _address) internal pure returns (bytes memory) { uint256 dest; assembly { dest := add(data, 48) } // 48 = 32 (offset) + 4 (func sig) + 12 (address is only 20 bytes) bytes memory addressBytes = addressToBytes(_address); uint256 src; assembly { src := add(addressBytes, 32) } memcpy(dest, src, 20); return data; } function overrideFirstTwo32BytesWithAddressAndInt( bytes memory data, address _address, uint256 _value ) internal pure returns (bytes memory) { uint256 dest; uint256 src; assembly { dest := add(data, 48) } // 48 = 32 (offset) + 4 (func sig) + 12 (address is only 20 bytes) bytes memory bbytes = addressToBytes(_address); assembly { src := add(bbytes, 32) } memcpy(dest, src, 20); assembly { dest := add(data, 68) } // 48 = 32 (offset) + 4 (func sig) + 32 (next slot) bbytes = uint256ToBytes(_value); assembly { src := add(bbytes, 32) } memcpy(dest, src, 32); return data; } }
pragma solidity ^0.6.0; import "./SafeMathWithRequire.sol"; library ObjectLib32 { using SafeMathWithRequire for uint256; enum Operations {ADD, SUB, REPLACE} // Constants regarding bin or chunk sizes for balance packing uint256 constant TYPES_BITS_SIZE = 32; // Max size of each object uint256 constant TYPES_PER_UINT256 = 256 / TYPES_BITS_SIZE; // Number of types per uint256 // // Objects and Tokens Functions // /** * @dev Return the bin number and index within that bin where ID is * @param tokenId Object type * @return bin Bin number * @return index ID's index within that bin */ function getTokenBinIndex(uint256 tokenId) internal pure returns (uint256 bin, uint256 index) { bin = (tokenId * TYPES_BITS_SIZE) / 256; index = tokenId % TYPES_PER_UINT256; return (bin, index); } /** * @dev update the balance of a type provided in binBalances * @param binBalances Uint256 containing the balances of objects * @param index Index of the object in the provided bin * @param amount Value to update the type balance * @param operation Which operation to conduct : * Operations.REPLACE : Replace type balance with amount * Operations.ADD : ADD amount to type balance * Operations.SUB : Substract amount from type balance */ function updateTokenBalance( uint256 binBalances, uint256 index, uint256 amount, Operations operation ) internal pure returns (uint256 newBinBalance) { uint256 objectBalance = 0; if (operation == Operations.ADD) { objectBalance = getValueInBin(binBalances, index); newBinBalance = writeValueInBin(binBalances, index, objectBalance.add(amount)); } else if (operation == Operations.SUB) { objectBalance = getValueInBin(binBalances, index); require(objectBalance >= amount, "can't substract more than there is"); newBinBalance = writeValueInBin(binBalances, index, objectBalance.sub(amount)); } else if (operation == Operations.REPLACE) { newBinBalance = writeValueInBin(binBalances, index, amount); } else { revert("Invalid operation"); // Bad operation } return newBinBalance; } /* * @dev return value in binValue at position index * @param binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param index index at which to retrieve value * @return Value at given index in bin */ function getValueInBin(uint256 binValue, uint256 index) internal pure returns (uint256) { // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 rightShift = 256 - TYPES_BITS_SIZE * (index + 1); return (binValue >> rightShift) & mask; } /** * @dev return the updated binValue after writing amount at index * @param binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param index Index at which to retrieve value * @param amount Value to store at index in bin * @return Value at given index in bin */ function writeValueInBin( uint256 binValue, uint256 index, uint256 amount ) internal pure returns (uint256) { require(amount < 2**TYPES_BITS_SIZE, "Amount to write in bin is too large"); // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 leftShift = 256 - TYPES_BITS_SIZE * (index + 1); return (binValue & ~(mask << leftShift)) | (amount << leftShift); } }
pragma solidity ^0.6.0; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } }
pragma solidity ^0.6.0; /** * @title SafeMath * @dev Math operations with safety checks that revert */ library SafeMathWithRequire { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; require(c / a == b, "overflow"); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "divbyzero"); // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "undeflow"); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; require(c >= a, "overflow"); return c; } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 2000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC20Group","name":"group","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveFor","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitTransferEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"groupAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"groupTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162000e9638038062000e96833981810160405260808110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b506040525050506001600160601b0319606085901b1660805260a08390528151620001d6906001906020850190620001f7565b508051620001ec906002906020840190620001f7565b50505050506200029c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200023a57805160ff19168380011785556200026a565b828001600101855582156200026a579182015b828111156200026a5782518255916020019190600101906200024d565b50620002789291506200027c565b5090565b6200029991905b8082111562000278576000815560010162000283565b90565b60805160601c60a051610ba6620002f06000398061040f528061077d528061097d5280610ada5250806103e052806104ea528061067152806107a8528061082152806108ac5280610b095250610ba66000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806370a082311161008c578063a6d49dca11610066578063a6d49dca14610297578063a9059cbb146102cf578063b8f9260b146102fb578063dd62ed3e14610303576100df565b806370a08231146102455780638b7b59d01461026b57806395d89b411461028f576100df565b806323b872dd116100bd57806323b872dd146101bb5780632b991746146101f1578063313ce56714610227576100df565b806306fdde03146100e4578063095ea7b31461016157806318160ddd146101a1575b600080fd5b6100ec610331565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012657818101518382015260200161010e565b50505050905090810190601f1680156101535780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018d6004803603604081101561017757600080fd5b506001600160a01b0381351690602001356103c6565b604080519115158252519081900360200190f35b6101a96103dc565b60408051918252519081900360200190f35b61018d600480360360608110156101d157600080fd5b506001600160a01b03813581169160208101359091169060400135610493565b61018d6004803603606081101561020757600080fd5b506001600160a01b03813581169160208101359091169060400135610624565b61022f610740565b6040805160ff9092168252519081900360200190f35b6101a96004803603602081101561025b57600080fd5b50356001600160a01b0316610745565b61027361081f565b604080516001600160a01b039092168252519081900360200190f35b6100ec610843565b6102cd600480360360608110156102ad57600080fd5b506001600160a01b038135811691602081013590911690604001356108a1565b005b61018d600480360360408110156102e557600080fd5b506001600160a01b03813516906020013561096e565b6101a961097b565b6101a96004803603604081101561031957600080fd5b506001600160a01b038135811691602001351661099f565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b820191906000526020600020905b81548152906001019060200180831161039f57829003601f168201915b5050505050905090565b60006103d33384846109c8565b50600192915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638806792f7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561046257600080fd5b505afa158015610476573d6000803e3d6000fd5b505050506040513d602081101561048c57600080fd5b5051905090565b6000336001600160a01b038516148015906105615750604080517f0d70e29c0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015233602483015291517f000000000000000000000000000000000000000000000000000000000000000090921691630d70e29c91604480820192602092909190829003018186803b15801561053357600080fd5b505afa158015610547573d6000803e3d6000fd5b505050506040513d602081101561055d57600080fd5b5051155b1561060f576001600160a01b038416600090815260208181526040808320338452909152902054600019811461060d57828110156105e6576040805162461bcd60e51b815260206004820152601760248201527f4e4f545f415554484f495a45445f414c4c4f57414e4345000000000000000000604482015290519081900360640190fd5b6001600160a01b038516600090815260208181526040808320338452909152902083820390555b505b61061a848484610a99565b5060019392505050565b6000336001600160a01b03851614806106e45750604080517feaa5125100000000000000000000000000000000000000000000000000000000815233600482015290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163eaa51251916024808301926020929190829003018186803b1580156106b757600080fd5b505afa1580156106cb573d6000803e3d6000fd5b505050506040513d60208110156106e157600080fd5b50515b610735576040805162461bcd60e51b815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61061a8484846109c8565b600090565b604080517efdd58e0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000602483015291516000927f0000000000000000000000000000000000000000000000000000000000000000169162fdd58e916044808301926020929190829003018186803b1580156107ed57600080fd5b505afa158015610801573d6000803e3d6000fd5b505050506040513d602081101561081757600080fd5b505192915050565b7f000000000000000000000000000000000000000000000000000000000000000090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461091e576040805162461bcd60e51b815260206004820152601960248201527f4e4f545f415554484f52495a45445f47524f55505f4f4e4c5900000000000000604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60006103d3338484610a99565b7f000000000000000000000000000000000000000000000000000000000000000090565b6001600160a01b0391821660009081526020818152604080832093909416825291909152205490565b6001600160a01b038316158015906109e857506001600160a01b03821615155b610a39576040805162461bcd60e51b815260206004820152601760248201527f494e56414c49445f46524f4d5f4f525f5350454e444552000000000000000000604482015290519081900360640190fd5b6001600160a01b0380841660008181526020818152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b604080517fa531e0fa0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301527f000000000000000000000000000000000000000000000000000000000000000060448301526064820184905291517f00000000000000000000000000000000000000000000000000000000000000009092169163a531e0fa9160848082019260009290919082900301818387803b158015610b5357600080fd5b505af1158015610b67573d6000803e3d6000fd5b5050505050505056fea2646970667358221220aba4d5d4c7526152be2064d9b1a3bf47d70653024031475ddfd6cbb49c2d587e64736f6c634300060500330000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001853616e64626f782773204550494320436174616c79737473000000000000000000000000000000000000000000000000000000000000000000000000000000044550494300000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c806370a082311161008c578063a6d49dca11610066578063a6d49dca14610297578063a9059cbb146102cf578063b8f9260b146102fb578063dd62ed3e14610303576100df565b806370a08231146102455780638b7b59d01461026b57806395d89b411461028f576100df565b806323b872dd116100bd57806323b872dd146101bb5780632b991746146101f1578063313ce56714610227576100df565b806306fdde03146100e4578063095ea7b31461016157806318160ddd146101a1575b600080fd5b6100ec610331565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012657818101518382015260200161010e565b50505050905090810190601f1680156101535780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018d6004803603604081101561017757600080fd5b506001600160a01b0381351690602001356103c6565b604080519115158252519081900360200190f35b6101a96103dc565b60408051918252519081900360200190f35b61018d600480360360608110156101d157600080fd5b506001600160a01b03813581169160208101359091169060400135610493565b61018d6004803603606081101561020757600080fd5b506001600160a01b03813581169160208101359091169060400135610624565b61022f610740565b6040805160ff9092168252519081900360200190f35b6101a96004803603602081101561025b57600080fd5b50356001600160a01b0316610745565b61027361081f565b604080516001600160a01b039092168252519081900360200190f35b6100ec610843565b6102cd600480360360608110156102ad57600080fd5b506001600160a01b038135811691602081013590911690604001356108a1565b005b61018d600480360360408110156102e557600080fd5b506001600160a01b03813516906020013561096e565b6101a961097b565b6101a96004803603604081101561031957600080fd5b506001600160a01b038135811691602001351661099f565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b820191906000526020600020905b81548152906001019060200180831161039f57829003601f168201915b5050505050905090565b60006103d33384846109c8565b50600192915050565b60007f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f16001600160a01b0316638806792f7f00000000000000000000000000000000000000000000000000000000000000026040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561046257600080fd5b505afa158015610476573d6000803e3d6000fd5b505050506040513d602081101561048c57600080fd5b5051905090565b6000336001600160a01b038516148015906105615750604080517f0d70e29c0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015233602483015291517f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f190921691630d70e29c91604480820192602092909190829003018186803b15801561053357600080fd5b505afa158015610547573d6000803e3d6000fd5b505050506040513d602081101561055d57600080fd5b5051155b1561060f576001600160a01b038416600090815260208181526040808320338452909152902054600019811461060d57828110156105e6576040805162461bcd60e51b815260206004820152601760248201527f4e4f545f415554484f495a45445f414c4c4f57414e4345000000000000000000604482015290519081900360640190fd5b6001600160a01b038516600090815260208181526040808320338452909152902083820390555b505b61061a848484610a99565b5060019392505050565b6000336001600160a01b03851614806106e45750604080517feaa5125100000000000000000000000000000000000000000000000000000000815233600482015290516001600160a01b037f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f1169163eaa51251916024808301926020929190829003018186803b1580156106b757600080fd5b505afa1580156106cb573d6000803e3d6000fd5b505050506040513d60208110156106e157600080fd5b50515b610735576040805162461bcd60e51b815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61061a8484846109c8565b600090565b604080517efdd58e0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000002602483015291516000927f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f1169162fdd58e916044808301926020929190829003018186803b1580156107ed57600080fd5b505afa158015610801573d6000803e3d6000fd5b505050506040513d602081101561081757600080fd5b505192915050565b7f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f190565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b336001600160a01b037f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f1161461091e576040805162461bcd60e51b815260206004820152601960248201527f4e4f545f415554484f52495a45445f47524f55505f4f4e4c5900000000000000604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60006103d3338484610a99565b7f000000000000000000000000000000000000000000000000000000000000000290565b6001600160a01b0391821660009081526020818152604080832093909416825291909152205490565b6001600160a01b038316158015906109e857506001600160a01b03821615155b610a39576040805162461bcd60e51b815260206004820152601760248201527f494e56414c49445f46524f4d5f4f525f5350454e444552000000000000000000604482015290519081900360640190fd5b6001600160a01b0380841660008181526020818152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b604080517fa531e0fa0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301527f000000000000000000000000000000000000000000000000000000000000000260448301526064820184905291517f0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f19092169163a531e0fa9160848082019260009290919082900301818387803b158015610b5357600080fd5b505af1158015610b67573d6000803e3d6000fd5b5050505050505056fea2646970667358221220aba4d5d4c7526152be2064d9b1a3bf47d70653024031475ddfd6cbb49c2d587e64736f6c63430006050033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001853616e64626f782773204550494320436174616c79737473000000000000000000000000000000000000000000000000000000000000000000000000000000044550494300000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : group (address): 0x2fC246149B4B8d7bcEF6188A10AF1791380227f1
Arg [1] : index (uint256): 2
Arg [2] : tokenName (string): Sandbox's EPIC Catalysts
Arg [3] : tokenSymbol (string): EPIC
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000002fc246149b4b8d7bcef6188a10af1791380227f1
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000018
Arg [5] : 53616e64626f782773204550494320436174616c797374730000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4550494300000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.