Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 134 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Approve | 23526664 | 155 days ago | IN | 0 ETH | 0.00024697 | ||||
| Approve | 23174332 | 204 days ago | IN | 0 ETH | 0.00010697 | ||||
| Approve | 23138815 | 209 days ago | IN | 0 ETH | 0.00015634 | ||||
| Transfer | 17100118 | 1055 days ago | IN | 0 ETH | 0.00129569 | ||||
| Transfer | 16819519 | 1094 days ago | IN | 0 ETH | 0.0046297 | ||||
| Transfer | 16686046 | 1113 days ago | IN | 0 ETH | 0.00170174 | ||||
| Transfer | 16583448 | 1127 days ago | IN | 0 ETH | 0.00107537 | ||||
| Transfer | 16337619 | 1162 days ago | IN | 0 ETH | 0.00111835 | ||||
| Transfer | 16227708 | 1177 days ago | IN | 0 ETH | 0.00158375 | ||||
| Transfer | 15866900 | 1227 days ago | IN | 0 ETH | 0.00032305 | ||||
| Transfer | 15855940 | 1229 days ago | IN | 0 ETH | 0.0004818 | ||||
| Transfer | 15543466 | 1273 days ago | IN | 0 ETH | 0.00035373 | ||||
| Transfer | 15522126 | 1276 days ago | IN | 0 ETH | 0.0006379 | ||||
| Transfer | 15520931 | 1276 days ago | IN | 0 ETH | 0.0006752 | ||||
| Transfer | 15429511 | 1291 days ago | IN | 0 ETH | 0.00063614 | ||||
| Transfer | 15395160 | 1297 days ago | IN | 0 ETH | 0.00025697 | ||||
| Transfer | 15372367 | 1300 days ago | IN | 0 ETH | 0.00076597 | ||||
| Transfer | 15328202 | 1307 days ago | IN | 0 ETH | 0.00069578 | ||||
| Transfer | 15002541 | 1359 days ago | IN | 0 ETH | 0.00226709 | ||||
| Transfer | 14834931 | 1387 days ago | IN | 0 ETH | 0.00071119 | ||||
| Transfer | 14827709 | 1389 days ago | IN | 0 ETH | 0.00115722 | ||||
| Transfer | 14810249 | 1391 days ago | IN | 0 ETH | 0.00072555 | ||||
| Transfer | 14755978 | 1400 days ago | IN | 0 ETH | 0.00589616 | ||||
| Transfer | 14697544 | 1409 days ago | IN | 0 ETH | 0.00158091 | ||||
| Transfer | 14595354 | 1425 days ago | IN | 0 ETH | 0.0007343 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
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
Contract ABI
API[{"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
60c06040523480156200001157600080fd5b5060405162000e9638038062000e96833981810160405260808110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b506040525050506001600160601b0319606085901b1660805260a08390528151620001d6906001906020850190620001f7565b508051620001ec906002906020840190620001f7565b50505050506200029c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200023a57805160ff19168380011785556200026a565b828001600101855582156200026a579182015b828111156200026a5782518255916020019190600101906200024d565b50620002789291506200027c565b5090565b6200029991905b8082111562000278576000815560010162000283565b90565b60805160601c60a051610ba6620002f06000398061040f528061077d528061097d5280610ada5250806103e052806104ea528061067152806107a8528061082152806108ac5280610b095250610ba66000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806370a082311161008c578063a6d49dca11610066578063a6d49dca14610297578063a9059cbb146102cf578063b8f9260b146102fb578063dd62ed3e14610303576100df565b806370a08231146102455780638b7b59d01461026b57806395d89b411461028f576100df565b806323b872dd116100bd57806323b872dd146101bb5780632b991746146101f1578063313ce56714610227576100df565b806306fdde03146100e4578063095ea7b31461016157806318160ddd146101a1575b600080fd5b6100ec610331565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012657818101518382015260200161010e565b50505050905090810190601f1680156101535780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018d6004803603604081101561017757600080fd5b506001600160a01b0381351690602001356103c6565b604080519115158252519081900360200190f35b6101a96103dc565b60408051918252519081900360200190f35b61018d600480360360608110156101d157600080fd5b506001600160a01b03813581169160208101359091169060400135610493565b61018d6004803603606081101561020757600080fd5b506001600160a01b03813581169160208101359091169060400135610624565b61022f610740565b6040805160ff9092168252519081900360200190f35b6101a96004803603602081101561025b57600080fd5b50356001600160a01b0316610745565b61027361081f565b604080516001600160a01b039092168252519081900360200190f35b6100ec610843565b6102cd600480360360608110156102ad57600080fd5b506001600160a01b038135811691602081013590911690604001356108a1565b005b61018d600480360360408110156102e557600080fd5b506001600160a01b03813516906020013561096e565b6101a961097b565b6101a96004803603604081101561031957600080fd5b506001600160a01b038135811691602001351661099f565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b820191906000526020600020905b81548152906001019060200180831161039f57829003601f168201915b5050505050905090565b60006103d33384846109c8565b50600192915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638806792f7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561046257600080fd5b505afa158015610476573d6000803e3d6000fd5b505050506040513d602081101561048c57600080fd5b5051905090565b6000336001600160a01b038516148015906105615750604080517f0d70e29c0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015233602483015291517f000000000000000000000000000000000000000000000000000000000000000090921691630d70e29c91604480820192602092909190829003018186803b15801561053357600080fd5b505afa158015610547573d6000803e3d6000fd5b505050506040513d602081101561055d57600080fd5b5051155b1561060f576001600160a01b038416600090815260208181526040808320338452909152902054600019811461060d57828110156105e6576040805162461bcd60e51b815260206004820152601760248201527f4e4f545f415554484f495a45445f414c4c4f57414e4345000000000000000000604482015290519081900360640190fd5b6001600160a01b038516600090815260208181526040808320338452909152902083820390555b505b61061a848484610a99565b5060019392505050565b6000336001600160a01b03851614806106e45750604080517feaa5125100000000000000000000000000000000000000000000000000000000815233600482015290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163eaa51251916024808301926020929190829003018186803b1580156106b757600080fd5b505afa1580156106cb573d6000803e3d6000fd5b505050506040513d60208110156106e157600080fd5b50515b610735576040805162461bcd60e51b815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61061a8484846109c8565b600090565b604080517efdd58e0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000602483015291516000927f0000000000000000000000000000000000000000000000000000000000000000169162fdd58e916044808301926020929190829003018186803b1580156107ed57600080fd5b505afa158015610801573d6000803e3d6000fd5b505050506040513d602081101561081757600080fd5b505192915050565b7f000000000000000000000000000000000000000000000000000000000000000090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461091e576040805162461bcd60e51b815260206004820152601960248201527f4e4f545f415554484f52495a45445f47524f55505f4f4e4c5900000000000000604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60006103d3338484610a99565b7f000000000000000000000000000000000000000000000000000000000000000090565b6001600160a01b0391821660009081526020818152604080832093909416825291909152205490565b6001600160a01b038316158015906109e857506001600160a01b03821615155b610a39576040805162461bcd60e51b815260206004820152601760248201527f494e56414c49445f46524f4d5f4f525f5350454e444552000000000000000000604482015290519081900360640190fd5b6001600160a01b0380841660008181526020818152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b604080517fa531e0fa0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301527f000000000000000000000000000000000000000000000000000000000000000060448301526064820184905291517f00000000000000000000000000000000000000000000000000000000000000009092169163a531e0fa9160848082019260009290919082900301818387803b158015610b5357600080fd5b505af1158015610b67573d6000803e3d6000fd5b5050505050505056fea2646970667358221220aba4d5d4c7526152be2064d9b1a3bf47d70653024031475ddfd6cbb49c2d587e64736f6c634300060500330000000000000000000000008ff2611da386de427fc96a8073963619c5851ba50000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001453616e64626f782773204d414749432047656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d41474943000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c806370a082311161008c578063a6d49dca11610066578063a6d49dca14610297578063a9059cbb146102cf578063b8f9260b146102fb578063dd62ed3e14610303576100df565b806370a08231146102455780638b7b59d01461026b57806395d89b411461028f576100df565b806323b872dd116100bd57806323b872dd146101bb5780632b991746146101f1578063313ce56714610227576100df565b806306fdde03146100e4578063095ea7b31461016157806318160ddd146101a1575b600080fd5b6100ec610331565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012657818101518382015260200161010e565b50505050905090810190601f1680156101535780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018d6004803603604081101561017757600080fd5b506001600160a01b0381351690602001356103c6565b604080519115158252519081900360200190f35b6101a96103dc565b60408051918252519081900360200190f35b61018d600480360360608110156101d157600080fd5b506001600160a01b03813581169160208101359091169060400135610493565b61018d6004803603606081101561020757600080fd5b506001600160a01b03813581169160208101359091169060400135610624565b61022f610740565b6040805160ff9092168252519081900360200190f35b6101a96004803603602081101561025b57600080fd5b50356001600160a01b0316610745565b61027361081f565b604080516001600160a01b039092168252519081900360200190f35b6100ec610843565b6102cd600480360360608110156102ad57600080fd5b506001600160a01b038135811691602081013590911690604001356108a1565b005b61018d600480360360408110156102e557600080fd5b506001600160a01b03813516906020013561096e565b6101a961097b565b6101a96004803603604081101561031957600080fd5b506001600160a01b038135811691602001351661099f565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b820191906000526020600020905b81548152906001019060200180831161039f57829003601f168201915b5050505050905090565b60006103d33384846109c8565b50600192915050565b60007f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba56001600160a01b0316638806792f7f00000000000000000000000000000000000000000000000000000000000000036040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561046257600080fd5b505afa158015610476573d6000803e3d6000fd5b505050506040513d602081101561048c57600080fd5b5051905090565b6000336001600160a01b038516148015906105615750604080517f0d70e29c0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015233602483015291517f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba590921691630d70e29c91604480820192602092909190829003018186803b15801561053357600080fd5b505afa158015610547573d6000803e3d6000fd5b505050506040513d602081101561055d57600080fd5b5051155b1561060f576001600160a01b038416600090815260208181526040808320338452909152902054600019811461060d57828110156105e6576040805162461bcd60e51b815260206004820152601760248201527f4e4f545f415554484f495a45445f414c4c4f57414e4345000000000000000000604482015290519081900360640190fd5b6001600160a01b038516600090815260208181526040808320338452909152902083820390555b505b61061a848484610a99565b5060019392505050565b6000336001600160a01b03851614806106e45750604080517feaa5125100000000000000000000000000000000000000000000000000000000815233600482015290516001600160a01b037f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba5169163eaa51251916024808301926020929190829003018186803b1580156106b757600080fd5b505afa1580156106cb573d6000803e3d6000fd5b505050506040513d60208110156106e157600080fd5b50515b610735576040805162461bcd60e51b815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61061a8484846109c8565b600090565b604080517efdd58e0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000003602483015291516000927f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba5169162fdd58e916044808301926020929190829003018186803b1580156107ed57600080fd5b505afa158015610801573d6000803e3d6000fd5b505050506040513d602081101561081757600080fd5b505192915050565b7f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba590565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103bc5780601f10610391576101008083540402835291602001916103bc565b336001600160a01b037f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba5161461091e576040805162461bcd60e51b815260206004820152601960248201527f4e4f545f415554484f52495a45445f47524f55505f4f4e4c5900000000000000604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60006103d3338484610a99565b7f000000000000000000000000000000000000000000000000000000000000000390565b6001600160a01b0391821660009081526020818152604080832093909416825291909152205490565b6001600160a01b038316158015906109e857506001600160a01b03821615155b610a39576040805162461bcd60e51b815260206004820152601760248201527f494e56414c49445f46524f4d5f4f525f5350454e444552000000000000000000604482015290519081900360640190fd5b6001600160a01b0380841660008181526020818152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b604080517fa531e0fa0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301527f000000000000000000000000000000000000000000000000000000000000000360448301526064820184905291517f0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba59092169163a531e0fa9160848082019260009290919082900301818387803b158015610b5357600080fd5b505af1158015610b67573d6000803e3d6000fd5b5050505050505056fea2646970667358221220aba4d5d4c7526152be2064d9b1a3bf47d70653024031475ddfd6cbb49c2d587e64736f6c63430006050033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba50000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001453616e64626f782773204d414749432047656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d41474943000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : group (address): 0x8Ff2611dA386de427fC96A8073963619c5851Ba5
Arg [1] : index (uint256): 3
Arg [2] : tokenName (string): Sandbox's MAGIC Gems
Arg [3] : tokenSymbol (string): MAGIC
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000008ff2611da386de427fc96a8073963619c5851ba5
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [5] : 53616e64626f782773204d414749432047656d73000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 4d41474943000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.