Contract 0x14Cb2fdab641AF08BdD1EF4edc4Eefa4C751DD83

 
Ad
Crypto.com
Txn Hash Method
Block
From
To
Value
0x9fbc50b1eba94527eb32940c47733855b4bfbb4606fdb353d17756214c950e260x6080604095608712020-02-26 18:48:27436 days 19 hrs ago0xa4c7c9d95cfcb3bbfca0c0af3302406a520d002e IN  Contract Creation0 Ether0.0095763153
[ Download CSV Export 
Latest 4 internal transactions
Parent Txn Hash Block From To Value
0x36b74329dddc8b4a281a569164a8099e2410498e74e215cc4fee6cf602c9613f107347832020-08-26 7:41:48255 days 6 hrs ago 0x14cb2fdab641af08bdd1ef4edc4eefa4c751dd83  Contract Creation0 Ether
0x724e93f73c4daefc94e85b9fafd53effb2acaaa2ced1708ae5802fd2947d519b99219712020-04-22 11:26:04381 days 2 hrs ago 0x14cb2fdab641af08bdd1ef4edc4eefa4c751dd83  Contract Creation0 Ether
0xbbf9fb9884c671595e7bc751e6c0bd1840f28da846ebaabbf785bd9e08fa79f096559262020-03-12 9:27:12422 days 4 hrs ago 0x14cb2fdab641af08bdd1ef4edc4eefa4c751dd83  Contract Creation0 Ether
0x635e23104289ef440f270811db1ae4f3a4680c41d78f130f1cf7603b9ecbe19b96372582020-03-09 12:36:56425 days 1 hr ago 0x14cb2fdab641af08bdd1ef4edc4eefa4c751dd83  Contract Creation0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
XcertDeployProxy

Compiler Version
v0.6.1+commit.e6f7d5a4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-02-27
*/

pragma solidity 0.6.1;
pragma experimental ABIEncoderV2;


interface ERC2477 {
  
  function tokenURIIntegrity(uint256 tokenId) external view returns(bytes memory digest, string memory hashAlgorithm);

  
  function tokenURISchemaIntegrity(uint256 tokenId) external view returns(bytes memory digest, string memory hashAlgorithm);
}

interface Xcert {

  
  function create(
    address _to,
    uint256 _id,
    bytes32 _imprint
  )
    external;

  
  function setUri(
    string calldata _uriPrefix,
    string calldata _uriPostfix
  )
    external;

}

interface XcertBurnable {

  
  function destroy(
    uint256 _tokenId
  )
    external;

}

interface XcertMutable {

  
  function updateTokenURIIntegrityDigest(
    uint256 _tokenId,
    bytes32 _tokenURIIntegrityDigest
  )
    external;

}

interface XcertPausable {

  
  function setPause(
    bool _isPaused
  )
    external;

}

interface XcertRevokable {

  
  function revoke(
    uint256 _tokenId
  )
    external;

}

library SafeMath {

  
  string constant OVERFLOW = "008001";
  string constant SUBTRAHEND_GREATER_THEN_MINUEND = "008002";
  string constant DIVISION_BY_ZERO = "008003";

  
  function mul(
    uint256 _factor1,
    uint256 _factor2
  )
    internal
    pure
    returns (uint256 product)
  {
    
    
    
    if (_factor1 == 0)
    {
      return 0;
    }

    product = _factor1 * _factor2;
    require(product / _factor1 == _factor2, OVERFLOW);
  }

  
  function div(
    uint256 _dividend,
    uint256 _divisor
  )
    internal
    pure
    returns (uint256 quotient)
  {
    
    require(_divisor > 0, DIVISION_BY_ZERO);
    quotient = _dividend / _divisor;
    
  }

  
  function sub(
    uint256 _minuend,
    uint256 _subtrahend
  )
    internal
    pure
    returns (uint256 difference)
  {
    require(_subtrahend <= _minuend, SUBTRAHEND_GREATER_THEN_MINUEND);
    difference = _minuend - _subtrahend;
  }

  
  function add(
    uint256 _addend1,
    uint256 _addend2
  )
    internal
    pure
    returns (uint256 sum)
  {
    sum = _addend1 + _addend2;
    require(sum >= _addend1, OVERFLOW);
  }

  
  function mod(
    uint256 _dividend,
    uint256 _divisor
  )
    internal
    pure
    returns (uint256 remainder)
  {
    require(_divisor != 0, DIVISION_BY_ZERO);
    remainder = _dividend % _divisor;
  }

}

contract Abilitable {
  using SafeMath for uint;

  
  string constant NOT_AUTHORIZED = "017001";
  string constant INVALID_INPUT = "017002";

  
  uint8 constant SUPER_ABILITY = 1;

  
  uint8 constant ALLOW_SUPER_ABILITY = 2;

  
  uint8 constant EMPTY_SLOT_1 = 4;

  
  uint8 constant EMPTY_SLOT_2 = 8;

  
  uint8 constant ALL_DEFAULT_ABILITIES = 15;

  
  mapping(address => uint256) public addressToAbility;

  
  event SetAbilities(
    address indexed _target,
    uint256 indexed _abilities
  );

  
  modifier hasAbilities(
    uint256 _abilities
  )
  {
    require(_abilities > 0, INVALID_INPUT);
    require(
      addressToAbility[msg.sender] & _abilities == _abilities,
      NOT_AUTHORIZED
    );
    _;
  }

  
  constructor()
    public
  {
    addressToAbility[msg.sender] = ALL_DEFAULT_ABILITIES;
  }

  
  function grantAbilities(
    address _target,
    uint256 _abilities
  )
    external
    hasAbilities(SUPER_ABILITY)
  {
    addressToAbility[_target] |= _abilities;
    emit SetAbilities(_target, addressToAbility[_target]);
  }

  
  function revokeAbilities(
    address _target,
    uint256 _abilities
  )
    external
    hasAbilities(SUPER_ABILITY)
  {
    addressToAbility[_target] &= ~_abilities;
    emit SetAbilities(_target, addressToAbility[_target]);
  }

  
  function setAbilities(
    address _target,
    uint256 _abilities
  )
    external
    hasAbilities(SUPER_ABILITY)
  {
    addressToAbility[_target] = _abilities;
    emit SetAbilities(_target, _abilities);
  }

  
  function isAble(
    address _target,
    uint256 _abilities
  )
    external
    view
    returns (bool)
  {
    require(_abilities > 0, INVALID_INPUT);
    return (addressToAbility[_target] & _abilities) == _abilities;
  }

}

interface ERC721 {

  
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 indexed _tokenId
  );

  
  event Approval(
    address indexed _owner,
    address indexed _approved,
    uint256 indexed _tokenId
  );

  
  event ApprovalForAll(
    address indexed _owner,
    address indexed _operator,
    bool _approved
  );

  
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes calldata _data
  )
    external;

  
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external;

  
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external;

  
  function approve(
    address _approved,
    uint256 _tokenId
  )
    external;

  
  function setApprovalForAll(
    address _operator,
    bool _approved
  )
    external;

  
  function balanceOf(
    address _owner
  )
    external
    view
    returns (uint256);

  
  function ownerOf(
    uint256 _tokenId
  )
    external
    view
    returns (address);

  
  function getApproved(
    uint256 _tokenId
  )
    external
    view
    returns (address);

  
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    external
    view
    returns (bool);

}

interface ERC721Metadata {

  
  function name()
    external
    view
    returns (string memory _name);

  
  function symbol()
    external
    view
    returns (string memory _symbol);

  
  function tokenURI(uint256 _tokenId)
    external
    view
    returns (string memory);

}

interface ERC721Enumerable {

  
  function totalSupply()
    external
    view
    returns (uint256);

  
  function tokenByIndex(
    uint256 _index
  )
    external
    view
    returns (uint256);

  
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    external
    view
    returns (uint256);

}

interface ERC721TokenReceiver {

  
  function onERC721Received(
    address _operator,
    address _from,
    uint256 _tokenId,
    bytes calldata _data
  )
    external
    returns(bytes4);

}

interface ERC165 {

  
  function supportsInterface(
    bytes4 _interfaceID
  )
    external
    view
    returns (bool);

}

contract SupportsInterface is
  ERC165
{

  
  mapping(bytes4 => bool) internal supportedInterfaces;

  
  constructor()
    public
  {
    supportedInterfaces[0x01ffc9a7] = true; 
  }

  
  function supportsInterface(
    bytes4 _interfaceID
  )
    external
    override
    view
    returns (bool)
  {
    return supportedInterfaces[_interfaceID];
  }

}

library AddressUtils {

  
  function isDeployedContract(
    address _addr
  )
    internal
    view
    returns (bool addressCheck)
  {
    uint256 size;
    assembly { size := extcodesize(_addr) } 
    addressCheck = size > 0;
  }

}

contract NFTokenMetadataEnumerable is
  ERC721,
  ERC721Metadata,
  ERC721Enumerable,
  SupportsInterface
{
  using SafeMath for uint256;
  using AddressUtils for address;

  
  string constant ZERO_ADDRESS = "006001";
  string constant NOT_VALID_NFT = "006002";
  string constant NOT_OWNER_OR_OPERATOR = "006003";
  string constant NOT_OWNER_APPROWED_OR_OPERATOR = "006004";
  string constant NOT_ABLE_TO_RECEIVE_NFT = "006005";
  string constant NFT_ALREADY_EXISTS = "006006";
  string constant INVALID_INDEX = "006007";

  
  bytes4 constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02;

  
  string internal nftName;

  
  string internal nftSymbol;

  
  string public uriPrefix;

  
  string public uriPostfix;

  
  uint256[] internal tokens;

  
  mapping(uint256 => uint256) internal idToIndex;

  
  mapping(address => uint256[]) internal ownerToIds;

  
  mapping(uint256 => uint256) internal idToOwnerIndex;

  
  mapping (uint256 => address) internal idToOwner;

  
  mapping (uint256 => address) internal idToApproval;

  
  mapping (address => mapping (address => bool)) internal ownerToOperators;

  
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 indexed _tokenId
  );

  
  event Approval(
    address indexed _owner,
    address indexed _approved,
    uint256 indexed _tokenId
  );

  
  event ApprovalForAll(
    address indexed _owner,
    address indexed _operator,
    bool _approved
  );

  
  constructor()
    public
  {
    supportedInterfaces[0x80ac58cd] = true; 
    supportedInterfaces[0x5b5e139f] = true; 
    supportedInterfaces[0x780e9d63] = true; 
  }

  
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes calldata _data
  )
    external
    override
  {
    _safeTransferFrom(_from, _to, _tokenId, _data);
  }

  
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external
    override
  {
    _safeTransferFrom(_from, _to, _tokenId, "");
  }

  
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external
    override
  {
    _transferFrom(_from, _to, _tokenId);
  }

  
  function approve(
    address _approved,
    uint256 _tokenId
  )
    external
    override
  {
    
    address tokenOwner = idToOwner[_tokenId];
    require(
      tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender],
      NOT_OWNER_OR_OPERATOR
    );

    idToApproval[_tokenId] = _approved;
    emit Approval(tokenOwner, _approved, _tokenId);
  }

  
  function setApprovalForAll(
    address _operator,
    bool _approved
  )
    external
    override
  {
    ownerToOperators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  
  function balanceOf(
    address _owner
  )
    external
    override
    view
    returns (uint256)
  {
    require(_owner != address(0), ZERO_ADDRESS);
    return ownerToIds[_owner].length;
  }

  
  function ownerOf(
    uint256 _tokenId
  )
    external
    override
    view
    returns (address _owner)
  {
    _owner = idToOwner[_tokenId];
    require(_owner != address(0), NOT_VALID_NFT);
  }

  
  function getApproved(
    uint256 _tokenId
  )
    external
    override
    view
    returns (address)
  {
    require(idToOwner[_tokenId] != address(0), NOT_VALID_NFT);
    return idToApproval[_tokenId];
  }

  
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    external
    override
    view
    returns (bool)
  {
    return ownerToOperators[_owner][_operator];
  }

  
  function totalSupply()
    external
    override
    view
    returns (uint256)
  {
    return tokens.length;
  }

  
  function tokenByIndex(
    uint256 _index
  )
    external
    override
    view
    returns (uint256)
  {
    require(_index < tokens.length, INVALID_INDEX);
    return tokens[_index];
  }

  
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    external
    override
    view
    returns (uint256)
  {
    require(_index < ownerToIds[_owner].length, INVALID_INDEX);
    return ownerToIds[_owner][_index];
  }

  
  function name()
    external
    override
    view
    returns (string memory _name)
  {
    _name = nftName;
  }

  
  function symbol()
    external
    override
    view
    returns (string memory _symbol)
  {
    _symbol = nftSymbol;
  }

  
  function tokenURI(
    uint256 _tokenId
  )
    external
    override
    view
    returns (string memory)
  {
    require(idToOwner[_tokenId] != address(0), NOT_VALID_NFT);
    string memory uri = "";
    if (bytes(uriPrefix).length > 0)
    {
      uri = string(abi.encodePacked(uriPrefix, _uint2str(_tokenId)));
      if (bytes(uriPostfix).length > 0)
      {
        uri = string(abi.encodePacked(uri, uriPostfix));
      }
    }
    return uri;
  }

  
  function _setUri(
    string memory _prefix,
    string memory _postfix
  )
    internal
  {
    uriPrefix = _prefix;
    uriPostfix = _postfix;
  }

  
  function _create(
    address _to,
    uint256 _tokenId
  )
    internal
  {
    require(_to != address(0), ZERO_ADDRESS);
    require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS);

    
    idToOwner[_tokenId] = _to;

    ownerToIds[_to].push(_tokenId);
    idToOwnerIndex[_tokenId] = ownerToIds[_to].length - 1;

    
    tokens.push(_tokenId);
    idToIndex[_tokenId] = tokens.length - 1;

    emit Transfer(address(0), _to, _tokenId);
  }

  
  function _destroy(
    uint256 _tokenId
  )
    internal
  {
    
    address _owner = idToOwner[_tokenId];
    require(_owner != address(0), NOT_VALID_NFT);

    
    if (idToApproval[_tokenId] != address(0))
    {
      delete idToApproval[_tokenId];
    }

    
    assert(ownerToIds[_owner].length > 0);

    uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
    uint256 lastTokenIndex = ownerToIds[_owner].length - 1;
    uint256 lastToken;
    if (lastTokenIndex != tokenToRemoveIndex)
    {
      lastToken = ownerToIds[_owner][lastTokenIndex];
      ownerToIds[_owner][tokenToRemoveIndex] = lastToken;
      idToOwnerIndex[lastToken] = tokenToRemoveIndex;
    }

    delete idToOwner[_tokenId];
    delete idToOwnerIndex[_tokenId];
    ownerToIds[_owner].pop();

    
    assert(tokens.length > 0);

    uint256 tokenIndex = idToIndex[_tokenId];
    lastTokenIndex = tokens.length - 1;
    lastToken = tokens[lastTokenIndex];

    tokens[tokenIndex] = lastToken;

    tokens.pop();
    
    idToIndex[lastToken] = tokenIndex;
    idToIndex[_tokenId] = 0;

    emit Transfer(_owner, address(0), _tokenId);
  }

  
  function _transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    internal
    virtual
  {
    
    require(_from != address(0), ZERO_ADDRESS);
    require(idToOwner[_tokenId] == _from, NOT_VALID_NFT);
    require(_to != address(0), ZERO_ADDRESS);

    
    require(
      _from == msg.sender
      || idToApproval[_tokenId] == msg.sender
      || ownerToOperators[_from][msg.sender],
      NOT_OWNER_APPROWED_OR_OPERATOR
    );

    
    if (idToApproval[_tokenId] != address(0))
    {
      delete idToApproval[_tokenId];
    }

    
    assert(ownerToIds[_from].length > 0);

    uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
    uint256 lastTokenIndex = ownerToIds[_from].length - 1;

    if (lastTokenIndex != tokenToRemoveIndex)
    {
      uint256 lastToken = ownerToIds[_from][lastTokenIndex];
      ownerToIds[_from][tokenToRemoveIndex] = lastToken;
      idToOwnerIndex[lastToken] = tokenToRemoveIndex;
    }

    ownerToIds[_from].pop();

    
    idToOwner[_tokenId] = _to;
    ownerToIds[_to].push(_tokenId);
    idToOwnerIndex[_tokenId] = ownerToIds[_to].length - 1;

    emit Transfer(_from, _to, _tokenId);
  }

  
  function _safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes memory _data
  )
    internal
    virtual
  {
    if (_to.isDeployedContract())
    {
      require(
        ERC721TokenReceiver(_to)
          .onERC721Received(msg.sender, _from, _tokenId, _data) == MAGIC_ON_ERC721_RECEIVED,
        NOT_ABLE_TO_RECEIVE_NFT
      );
    }

    _transferFrom(_from, _to, _tokenId);
  }

  
  function _uint2str(
    uint256 _i
  )
    internal
    pure
    returns (string memory str)
  {
    if (_i == 0)
    {
      return "0";
    }
    uint256 j = _i;
    uint256 length;
    while (j != 0)
    {
      length++;
      j /= 10;
    }
    bytes memory bstr = new bytes(length);
    uint256 k = length - 1;
    j = _i;
    while (j != 0)
    {
      bstr[k--] = byte(uint8(48 + j % 10));
      j /= 10;
    }
    str = string(bstr);
  }

}

interface ERC20 {

  
  function name()
    external
    view
    returns (string memory _name);

  
  function symbol()
    external
    view
    returns (string memory _symbol);

  
  function decimals()
    external
    view
    returns (uint8 _decimals);

  
  function totalSupply()
    external
    view
    returns (uint256 _totalSupply);

  
  function balanceOf(
    address _owner
  )
    external
    view
    returns (uint256 _balance);

  
  function transfer(
    address _to,
    uint256 _value
  )
    external
    returns (bool _success);

  
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    external
    returns (bool _success);

  
  function approve(
    address _spender,
    uint256 _value
  )
    external
    returns (bool _success);

  
  function allowance(
    address _owner,
    address _spender
  )
    external
    view
    returns (uint256 _remaining);

  
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 _value
  );

  
  event Approval(
    address indexed _owner,
    address indexed _spender,
    uint256 _value
  );

}

contract XcertToken is
  ERC2477,
  Xcert,
  XcertBurnable,
  XcertMutable,
  XcertPausable,
  XcertRevokable,
  NFTokenMetadataEnumerable,
  Abilitable
{

  
  uint8 constant ABILITY_CREATE_ASSET = 16;
  uint8 constant ABILITY_REVOKE_ASSET = 32;
  uint8 constant ABILITY_TOGGLE_TRANSFERS = 64;
  uint8 constant ABILITY_UPDATE_ASSET_URI_INTEGRITY_DIGEST = 128;
  uint16 constant ABILITY_UPDATE_URI = 256;
  
  
  
  
  

  
  bytes4 constant MUTABLE = 0x0d04c3b8;
  bytes4 constant BURNABLE = 0x9d118770;
  bytes4 constant PAUSABLE = 0xbedb86fb;
  bytes4 constant REVOKABLE = 0x20c5429b;

  
  string constant HASH_ALGORITHM = 'sha256';

  
  string constant CAPABILITY_NOT_SUPPORTED = "007001";
  string constant TRANSFERS_DISABLED = "007002";
  string constant NOT_VALID_XCERT = "007003";
  string constant NOT_XCERT_OWNER_OR_OPERATOR = "007004";
  string constant INVALID_SIGNATURE = "007005";
  string constant INVALID_SIGNATURE_KIND = "007006";
  string constant CLAIM_PERFORMED = "007007";
  string constant CLAIM_EXPIRED = "007008";
  string constant CLAIM_CANCELED = "007009";
  string constant NOT_OWNER = "007010";

  
  event IsPaused(bool isPaused);

  
  event TokenURIIntegrityDigestUpdate(
    uint256 indexed _tokenId,
    bytes32 _tokenURIIntegrityDigest
  );

  
  enum SignatureKind
  {
    eth_sign,
    trezor,
    no_prefix
  }

  
  struct SignatureData
  {
    bytes32 r;
    bytes32 s;
    uint8 v;
    SignatureKind kind;
  }

  
  mapping(bytes32 => bool) public claimPerformed;

  
  mapping(bytes32 => bool) public claimCancelled;

  
  bytes32 internal schemaURIIntegrityDigest;

  
  mapping (uint256 => bytes32) internal idToIntegrityDigest;

  
  mapping (address => bool) internal addressToAuthorized;

  
  bool public isPaused;

  
  constructor()
    public
  {
    supportedInterfaces[0x39541724] = true; 
  }

  
  function create(
    address _to,
    uint256 _id,
    bytes32 _tokenURIIntegrityDigest
  )
    external
    override
    hasAbilities(ABILITY_CREATE_ASSET)
  {
    super._create(_to, _id);
    idToIntegrityDigest[_id] = _tokenURIIntegrityDigest;
  }

  
  function setUri(
    string calldata _uriPrefix,
    string calldata _uriPostfix
  )
    external
    override
    hasAbilities(ABILITY_UPDATE_URI)
  {
    super._setUri(_uriPrefix, _uriPostfix);
  }

  
  function revoke(
    uint256 _tokenId
  )
    external
    override
    hasAbilities(ABILITY_REVOKE_ASSET)
  {
    require(supportedInterfaces[REVOKABLE], CAPABILITY_NOT_SUPPORTED);
    super._destroy(_tokenId);
    delete idToIntegrityDigest[_tokenId];
  }

  
  function setPause(
    bool _isPaused
  )
    external
    override
    hasAbilities(ABILITY_TOGGLE_TRANSFERS)
  {
    require(supportedInterfaces[PAUSABLE], CAPABILITY_NOT_SUPPORTED);
    isPaused = _isPaused;
    emit IsPaused(_isPaused);
  }

  
  function updateTokenURIIntegrityDigest(
    uint256 _tokenId,
    bytes32 _tokenURIIntegrityDigest
  )
    external
    override
    hasAbilities(ABILITY_UPDATE_ASSET_URI_INTEGRITY_DIGEST)
  {
    require(supportedInterfaces[MUTABLE], CAPABILITY_NOT_SUPPORTED);
    require(idToOwner[_tokenId] != address(0), NOT_VALID_XCERT);
    idToIntegrityDigest[_tokenId] = _tokenURIIntegrityDigest;
    emit TokenURIIntegrityDigestUpdate(_tokenId, _tokenURIIntegrityDigest);
  }

  
  function destroy(
    uint256 _tokenId
  )
    external
    override
  {
    require(supportedInterfaces[BURNABLE], CAPABILITY_NOT_SUPPORTED);
    address tokenOwner = idToOwner[_tokenId];
    super._destroy(_tokenId);
    require(
      tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender],
      NOT_XCERT_OWNER_OR_OPERATOR
    );
    delete idToIntegrityDigest[_tokenId];
  }

  
  function setApprovalForAllWithSignature(
    address _owner,
    address _operator,
    bool _approved,
    address _feeToken,
    uint256 _feeValue,
    address _feeRecipient,
    uint256 _seed,
    uint256 _expiration,
    SignatureData calldata _signature
  )
    external
  {
    bytes32 claim = generateClaim(
      _owner,
      _operator,
      _approved,
      _feeToken,
      _feeValue,
      _feeRecipient,
      _seed,
      _expiration
    );
    require(!claimCancelled[claim], CLAIM_CANCELED);
    require(
      isValidSignature(
        _owner,
        claim,
        _signature
      ),
      INVALID_SIGNATURE
    );
    require(!claimPerformed[claim], CLAIM_PERFORMED);
    require(_expiration >= now, CLAIM_EXPIRED);
    claimPerformed[claim] = true;
    ownerToOperators[_owner][_operator] = _approved;
    if (_feeRecipient == address(0)) {
      _feeRecipient = msg.sender;
    }
    ERC20(_feeToken).transferFrom(_owner, _feeRecipient, _feeValue);
    emit ApprovalForAll(_owner, _operator, _approved);
  }

  
  function cancelSetApprovalForAllWithSignature(
    address _owner,
    address _operator,
    bool _approved,
    address _feeToken,
    uint256 _feeValue,
    address _feeRecipient,
    uint256 _seed,
    uint256 _expiration
  )
    external
  {
    require(msg.sender == _owner, NOT_OWNER);
    bytes32 claim = generateClaim(
      _owner,
      _operator,
      _approved,
      _feeToken,
      _feeValue,
      _feeRecipient,
      _seed,
      _expiration
    );
    require(!claimPerformed[claim], CLAIM_PERFORMED);
    claimCancelled[claim] = true;
  }

  
  function generateClaim(
    address _owner,
    address _operator,
    bool _approved,
    address _feeToken,
    uint256 _feeValue,
    address _feeRecipient,
    uint256 _seed,
    uint256 _expiration
  )
    public
    view
    returns(bytes32)
  {
    return keccak256(
      abi.encodePacked(
        address(this),
        _owner,
        _operator,
        _approved,
        _feeToken,
        _feeValue,
        _feeRecipient,
        _seed,
        _expiration
      )
    );
  }

  
  function isValidSignature(
    address _signer,
    bytes32 _claim,
    SignatureData memory _signature
  )
    public
    pure
    returns (bool)
  {
    if (_signature.kind == SignatureKind.eth_sign)
    {
      return _signer == ecrecover(
        keccak256(
          abi.encodePacked(
            "\x19Ethereum Signed Message:\n32",
            _claim
          )
        ),
        _signature.v,
        _signature.r,
        _signature.s
      );
    } else if (_signature.kind == SignatureKind.trezor)
    {
      return _signer == ecrecover(
        keccak256(
          abi.encodePacked(
            "\x19Ethereum Signed Message:\n\x20",
            _claim
          )
        ),
        _signature.v,
        _signature.r,
        _signature.s
      );
    } else if (_signature.kind == SignatureKind.no_prefix)
    {
      return _signer == ecrecover(
        _claim,
        _signature.v,
        _signature.r,
        _signature.s
      );
    }

    revert(INVALID_SIGNATURE_KIND);
  }

  
  function tokenURISchemaIntegrity(
    uint256 tokenId
  )
    external
    override
    view
    returns(bytes memory digest, string memory hashAlgorithm)
  {
    require(idToOwner[tokenId] != address(0), NOT_VALID_XCERT);
    digest = abi.encodePacked(schemaURIIntegrityDigest);
    hashAlgorithm = HASH_ALGORITHM;
  }

  
  function tokenURIIntegrity(
    uint256 tokenId
  )
    external
    override
    view
    returns(bytes memory digest, string memory hashAlgorithm)
  {
    require(idToOwner[tokenId] != address(0), NOT_VALID_XCERT);
    digest = abi.encodePacked(idToIntegrityDigest[tokenId]);
    hashAlgorithm = HASH_ALGORITHM;
  }

  
  function _transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    internal
    override
  {
    
    require(!isPaused, TRANSFERS_DISABLED);
    super._transferFrom(_from, _to, _tokenId);
  }
}

contract XcertCustom is XcertToken {

  
  uint8 constant ABILITY_NONE = 0;
  uint16 constant ABILITY_ALL = 2047; 

  
  constructor(
    string memory _name,
    string memory _symbol,
    string memory _uriPrefix,
    string memory _uriPostfix,
    bytes32 _schemaURIIntegrityDigest,
    bytes4[] memory _capabilities,
    address[6] memory _addresses
  )
    public
  {
    nftName = _name;
    nftSymbol = _symbol;
    uriPrefix = _uriPrefix;
    uriPostfix = _uriPostfix;
    schemaURIIntegrityDigest = _schemaURIIntegrityDigest;
    for(uint256 i = 0; i < _capabilities.length; i++)
    {
      supportedInterfaces[_capabilities[i]] = true;
    }
    addressToAbility[_addresses[1]] = ABILITY_CREATE_ASSET; 
    
    addressToAbility[_addresses[2]] = ABILITY_UPDATE_ASSET_URI_INTEGRITY_DIGEST; 
    
    addressToAbility[_addresses[3]] = SUPER_ABILITY; 
    
    addressToAbility[msg.sender] = ABILITY_NONE;
    addressToAbility[_addresses[0]] = ABILITY_ALL; 
    ownerToOperators[_addresses[0]][_addresses[4]] = true; 
    
    ownerToOperators[_addresses[0]][_addresses[5]] = true; 
  }

}

contract XcertDeployProxy {
  
  function deploy(
    string memory _name,
    string memory _symbol,
    string memory _uriPrefix,
    string memory _uriPostfix,
    bytes32 _schemaURIIntegrityDigest,
    bytes4[] memory _capabilities,
    address[6] memory _addresses
  )
    public
    returns (address xcert)
  {
    xcert = address(
      new XcertCustom(
        _name, _symbol, _uriPrefix, _uriPostfix, _schemaURIIntegrityDigest, _capabilities, _addresses
      )
    );
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_uriPrefix","type":"string"},{"internalType":"string","name":"_uriPostfix","type":"string"},{"internalType":"bytes32","name":"_schemaURIIntegrityDigest","type":"bytes32"},{"internalType":"bytes4[]","name":"_capabilities","type":"bytes4[]"},{"internalType":"address[6]","name":"_addresses","type":"address[6]"}],"name":"deploy","outputs":[{"internalType":"address","name":"xcert","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506138cd806100206000396000f3fe60806040523480156200001157600080fd5b50600436106200002e5760003560e01c806301181d851462000033575b600080fd5b6200004a6200004436600462000245565b62000062565b604051620000599190620003d3565b60405180910390f35b6000878787878787876040516200007990620000b5565b6200008b9796959493929190620003e7565b604051809103906000f080158015620000a8573d6000803e3d6000fd5b5098975050505050505050565b6133b680620004e283390190565b600082601f830112620000d4578081fd5b620000e060c0620004b0565b905080828460c085011115620000f557600080fd5b60005b6006811015620001305781356001600160a01b03811681146200011a57600080fd5b83526020928301929190910190600101620000f8565b50505092915050565b600082601f8301126200014a578081fd5b813567ffffffffffffffff81111562000161578182fd5b602080820262000173828201620004b0565b838152935081840185830182870184018810156200019057600080fd5b600092505b84831015620001cc5780356001600160e01b031981168114620001b757600080fd5b82526001929092019190830190830162000195565b505050505092915050565b600082601f830112620001e8578081fd5b813567ffffffffffffffff811115620001ff578182fd5b62000214601f8201601f1916602001620004b0565b91508082528360208285010111156200022c57600080fd5b8060208401602084013760009082016020015292915050565b6000806000806000806000610180888a03121562000261578283fd5b873567ffffffffffffffff8082111562000279578485fd5b620002878b838c01620001d7565b985060208a01359150808211156200029d578485fd5b620002ab8b838c01620001d7565b975060408a0135915080821115620002c1578485fd5b620002cf8b838c01620001d7565b965060608a0135915080821115620002e5578485fd5b620002f38b838c01620001d7565b955060808a0135945060a08a013591508082111562000310578384fd5b506200031f8a828b0162000139565b925050620003318960c08a01620000c3565b905092959891949750929550565b6001600160e01b031916815260200190565b8060005b60068110156200037f5781516001600160a01b031684526020938401939091019060010162000355565b50505050565b60008151808452815b81811015620003ac576020818501810151868301820152016200038e565b81811115620003be5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6000610180808352620003fd8184018b62000385565b838103602085015262000411818b62000385565b915050828103604084015262000428818962000385565b83810360608501526200043c818962000385565b91505085608084015282810360a08401528085516200045c8184620004d8565b9150602087019250835b818110156200048e576200047c8385516200033f565b60209490940193925060010162000466565b50508092505050620004a460c083018462000351565b98975050505050505050565b60405181810167ffffffffffffffff81118282101715620004d057600080fd5b604052919050565b9081526020019056fe60806040523480156200001157600080fd5b50604051620033b6380380620033b68339810160408190526200003491620004de565b7f67be87c3ff9960ca1e9cfac5cab2ff4747269cf9ed20c9b7306235ac35a491c58054600160ff1991821681179092557ff7815fccbf112960a73756e185887fedcb9fc64ca0a16cc5923b7960ed78080080548216831790557f9562381dfbc2d8b8b66e765249f330164b73e329e5f01670660643571d1974df80548216831790557f77b7bbe0e49b76487c9476b5db3354cf5270619d0037ccb899c2a4c4a75b43188054821683179055336000908152600c602090815260408220600f9055630e5505c960e21b82529081527f51898dc9a6d4a1a28139a8ad74f01a2d4091d77ed3e22b500e2e4f337ecb7ab18054909216831790915588516200013d92918a01906200029b565b508551620001539060029060208901906200029b565b508451620001699060039060208801906200029b565b5083516200017f9060049060208701906200029b565b50600f83905560005b8251811015620001e0576001600080858481518110620001a457fe5b6020908102919091018101516001600160e01b0319168252810191909152604001600020805460ff191691151591909117905560010162000188565b506020818101516001600160a01b039081166000908152600c835260408082206010905580850151831682528082206080908190556060860151841683528183206001908190553384528284208490558651851684528284206107ff9055865185168452600b8087528385209288015186168552918652828420805460ff19908116831790915587518616855291865282842060a09097015190941683529490935291909120805490921617905550620005fe945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002de57805160ff19168380011785556200030e565b828001600101855582156200030e579182015b828111156200030e578251825591602001919060010190620002f1565b506200031c92915062000320565b5090565b6200033d91905b808211156200031c576000815560010162000327565b90565b600082601f83011262000351578081fd5b6200035d60c0620005d7565b905080828460c0850111156200037257600080fd5b60005b6006811015620003ad5781516001600160a01b03811681146200039757600080fd5b8352602092830192919091019060010162000375565b50505092915050565b600082601f830112620003c7578081fd5b81516001600160401b03811115620003dd578182fd5b6020808202620003ef828201620005d7565b838152935081840185830182870184018810156200040c57600080fd5b600092505b84831015620004485780516001600160e01b0319811681146200043357600080fd5b82526001929092019190830190830162000411565b505050505092915050565b600082601f83011262000464578081fd5b81516001600160401b038111156200047a578182fd5b602062000490601f8301601f19168201620005d7565b92508183528481838601011115620004a757600080fd5b60005b82811015620004c7578481018201518482018301528101620004aa565b82811115620003ad57506000918301015292915050565b6000806000806000806000610180888a031215620004fa578283fd5b87516001600160401b038082111562000511578485fd5b6200051f8b838c0162000453565b985060208a015191508082111562000535578485fd5b620005438b838c0162000453565b975060408a015191508082111562000559578485fd5b620005678b838c0162000453565b965060608a01519150808211156200057d578485fd5b6200058b8b838c0162000453565b955060808a0151945060a08a0151915080821115620005a8578384fd5b50620005b78a828b01620003b6565b925050620005c98960c08a0162000340565b905092959891949750929550565b6040518181016001600160401b0381118282101715620005f657600080fd5b604052919050565b612da8806200060e6000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c806370a0823111610130578063b187bd26116100b8578063c87b56dd1161007c578063c87b56dd146104b5578063caae188e146104c8578063ce4e3273146104db578063e985e9c5146104ee578063f394b6df1461050157610232565b8063b187bd261461046c578063b88d4fde14610474578063ba00a33014610487578063bedb86fb1461049a578063c298bba5146104ad57610232565b806395d89b41116100ff57806395d89b41146104185780639d11877014610420578063a0fd419514610433578063a22cb46514610446578063b0e329e41461045957610232565b806370a08231146103cc5780637f9b45b0146103df57806389b73ec0146103f25780638fa76d8d1461040557610232565b806323b872dd116101be5780634984668011610182578063498466801461036a5780634f6ccce71461038b578063590318291461039e57806362b99ad4146103b15780636352211e146103b957610232565b806323b872dd1461030b57806323bf33961461031e5780632f745c591461033157806342842e0e1461034457806345a32c861461035757610232565b80630ab319e8116102055780630ab319e8146102aa5780630d04c3b8146102bd57806315ec3b8b146102d057806318160ddd146102e357806320c5429b146102f857610232565b806301ffc9a71461023757806306fdde0314610260578063081812fc14610275578063095ea7b314610295575b600080fd5b61024a61024536600461299f565b610514565b6040516102579190612ca9565b60405180910390f35b610268610537565b6040516102579190612cf7565b610288610283366004612987565b6105cc565b6040516102579190612c34565b6102a86102a33660046128f2565b610648565b005b6102a86102b83660046128f2565b61072b565b6102a86102cb366004612a5b565b6107e7565b6102a86102de3660046128f2565b610970565b6102eb610a26565b6040516102579190612b7d565b6102a8610306366004612987565b610a2d565b6102a86103193660046127ce565b610b26565b61024a61032c366004612987565b610b36565b6102eb61033f3660046128f2565b610b4b565b6102a86103523660046127ce565b610bdd565b6102eb610365366004612655565b610bf8565b61037d610378366004612987565b610c0a565b604051610257929190612cd2565b6102eb610399366004612987565b610cb5565b61024a6103ac366004612987565b610d17565b610268610d2c565b6102886103c7366004612987565b610dba565b6102eb6103da366004612655565b610e18565b6102a86103ed36600461272b565b610e7c565b6102a86104003660046129d7565b6110f4565b61024a6104133660046128b4565b6111dd565b61026861133f565b6102a861042e366004612987565b61139d565b6102eb6104413660046126a4565b6114bc565b6102a861045436600461287d565b611503565b6102a861046736600461291c565b611572565b61024a6115fe565b6102a861048236600461280e565b611607565b61024a6104953660046128f2565b611649565b6102a86104a836600461294f565b6116ae565b6102686117d6565b6102686104c3366004612987565b611831565b61037d6104d6366004612987565b61192b565b6102a86104e93660046126a4565b61199a565b61024a6104fc366004612670565b611a6c565b6102a861050f3660046128f2565b611a9a565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156105c25780601f10610597576101008083540402835291602001916105c2565b820191906000526020600020905b8154815290600101906020018083116105a557829003601f168201915b5050505050905090565b6000818152600960209081526040808320548151808301909252600682526518181b18181960d11b92820192909252906001600160a01b031661062b5760405162461bcd60e51b81526004016106229190612cf7565b60405180910390fd5b50506000908152600a60205260409020546001600160a01b031690565b6000818152600960205260409020546001600160a01b03163381148061069157506001600160a01b0381166000908152600b6020908152604080832033845290915290205460ff165b6040518060400160405280600681526020016530303630303360d01b815250906106ce5760405162461bcd60e51b81526004016106229190612cf7565b506000828152600a602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b9183019190915260019190821682146107985760405162461bcd60e51b81526004016106229190612cf7565b506001600160a01b0383166000818152600c6020526040808220805486179081905590519092917fd1d59d2d212a435434e7a4a4676427610dfe2b6268b01e541d280d65bf3d6b9091a3505050565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b9183019190915260809190821682146108545760405162461bcd60e51b81526004016106229190612cf7565b506301a0987760e31b600090815260209081527f0d380c36f2a8666f3c5d1c38067efee2829e27fe2865b075864df1ea37b429f65460408051808201909152600681526530303730303160d01b9281019290925260ff166108c85760405162461bcd60e51b81526004016106229190612cf7565b50600083815260096020908152604091829020548251808401909352600683526530303730303360d01b918301919091526001600160a01b031661091f5760405162461bcd60e51b81526004016106229190612cf7565b50600083815260106020526040908190208390555183907fda81dc3bdaf65b621535dbd08fc4032c7e22d5ccab12c8aa2ad010611471d62790610963908590612b7d565b60405180910390a2505050565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b9183019190915260019190821682146109dd5760405162461bcd60e51b81526004016106229190612cf7565b506001600160a01b0383166000818152600c6020526040808220859055518492917fd1d59d2d212a435434e7a4a4676427610dfe2b6268b01e541d280d65bf3d6b9091a3505050565b6005545b90565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b8383015290919082168214610a965760405162461bcd60e51b81526004016106229190612cf7565b506320c5429b60e01b600090815260209081527fa475e1e33e639aa8527a4f5c4f611c4588486a1a8e7684839ad95dc8b4e841a45460408051808201909152600681526530303730303160d01b9281019290925260ff16610b0a5760405162461bcd60e51b81526004016106229190612cf7565b50610b1482611b57565b50600090815260106020526040812055565b610b31838383611df1565b505050565b600d6020526000908152604090205460ff1681565b6001600160a01b0382166000908152600760209081526040808320548151808301909252600682526530303630303760d01b92820192909252908310610ba45760405162461bcd60e51b81526004016106229190612cf7565b506001600160a01b0383166000908152600760205260409020805483908110610bc957fe5b906000526020600020015490505b92915050565b610b3183838360405180602001604052806000815250611e3f565b600c6020526000908152604090205481565b600081815260096020908152604091829020548251808401909352600683526530303730303360d01b9183019190915260609182916001600160a01b0316610c655760405162461bcd60e51b81526004016106229190612cf7565b50600083815260106020908152604091829020549151610c86929101612b7d565b60408051601f19818403018152828201909152600682526539b430991a9b60d11b602083015294909350915050565b60055460408051808201909152600681526530303630303760d01b60208201526000918310610cf75760405162461bcd60e51b81526004016106229190612cf7565b5060058281548110610d0557fe5b90600052602060002001549050919050565b600e6020526000908152604090205460ff1681565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610db25780601f10610d8757610100808354040283529160200191610db2565b820191906000526020600020905b815481529060010190602001808311610d9557829003601f168201915b505050505081565b600081815260096020908152604091829020548251808401909352600683526518181b18181960d11b918301919091526001600160a01b03169081610e125760405162461bcd60e51b81526004016106229190612cf7565b50919050565b60408051808201909152600681526530303630303160d01b60208201526000906001600160a01b038316610e5f5760405162461bcd60e51b81526004016106229190612cf7565b50506001600160a01b031660009081526007602052604090205490565b6000610e8e8a8a8a8a8a8a8a8a6114bc565b6000818152600e6020908152604091829020548251808401909352600683526530303730303960d01b918301919091529192509060ff1615610ee35760405162461bcd60e51b81526004016106229190612cf7565b50610ef88a8261041336869003860186612a40565b6040518060400160405280600681526020016530303730303560d01b81525090610f355760405162461bcd60e51b81526004016106229190612cf7565b506000818152600d6020908152604091829020548251808401909352600683526530303730303760d01b9183019190915260ff1615610f875760405162461bcd60e51b81526004016106229190612cf7565b50604080518082019091526006815265060606e6060760d31b602082015242841015610fc65760405162461bcd60e51b81526004016106229190612cf7565b506000818152600d602090815260408083208054600160ff19918216179091556001600160a01b038e81168552600b84528285208e82168652909352922080549092168a151517909155851661101a573394505b6040516323b872dd60e01b81526001600160a01b038816906323b872dd9061104a908d9089908b90600401612c85565b602060405180830381600087803b15801561106457600080fd5b505af1158015611078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061109c919081019061296b565b50886001600160a01b03168a6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318a6040516110e09190612ca9565b60405180910390a350505050505050505050565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b918301919091526101009190821682146111625760405162461bcd60e51b81526004016106229190612cf7565b506111d685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f89018190048102820181019092528781529250879150869081908401838280828437600092019190915250611f3792505050565b5050505050565b600080826060015160028111156111f057fe5b1415611292576001836040516020016112099190612bd2565b604051602081830303815290604052805190602001208360400151846000015185602001516040516000815260200160405260405161124b9493929190612cb4565b6020604051602081039080840390855afa15801561126d573d6000803e3d6000fd5b505050602060405103516001600160a01b0316846001600160a01b0316149050611338565b6001826060015160028111156112a457fe5b14156112bd576001836040516020016112099190612c03565b6002826060015160028111156112cf57fe5b1415611304576001838360400151846000015185602001516040516000815260200160405260405161124b9493929190612cb4565b604080518082018252600681526518181b98181b60d11b6020820152905162461bcd60e51b81526106229190600401612cf7565b9392505050565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156105c25780601f10610597576101008083540402835291602001916105c2565b6309d1187760e41b600090815260209081527fce9a4990a518db4a5651f73127cf155573e9e5e84e0b58e7d17581df388a54e15460408051808201909152600681526530303730303160d01b9281019290925260ff166114105760405162461bcd60e51b81526004016106229190612cf7565b506000818152600960205260409020546001600160a01b031661143282611b57565b6001600160a01b03811633148061146c57506001600160a01b0381166000908152600b6020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0dcc0c0d60d21b815250906114a95760405162461bcd60e51b81526004016106229190612cf7565b5050600090815260106020526040812055565b60003089898989898989896040516020016114df99989796959493929190612b17565b60405160208183030381529060405280519060200120905098975050505050505050565b336000818152600b602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611566908590612ca9565b60405180910390a35050565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b9183019190915260109190821682146115df5760405162461bcd60e51b81526004016106229190612cf7565b506115ea8484611f5e565b506000918252601060205260409091205550565b60125460ff1681565b6111d685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e3f92505050565b60008082116040518060400160405280600681526020016518189b98181960d11b8152509061168b5760405162461bcd60e51b81526004016106229190612cf7565b50506001600160a01b03919091166000908152600c602052604090205481161490565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c835283902054835180850185529182526530313730303160d01b9282019290925290821682146117175760405162461bcd60e51b81526004016106229190612cf7565b5063bedb86fb60e01b600090815260209081527f7ce77c7e88ab598a61cf35ed6b2db755d687a852164358790f2ba8d2b1dc952d5460408051808201909152600681526530303730303160d01b9281019290925260ff1661178b5760405162461bcd60e51b81526004016106229190612cf7565b506012805460ff19168315151790556040517fff4a5dbbab6b1963d10f5edd139f33a7987ecb3c4f65969be77ddba28d946594906117ca908490612ca9565b60405180910390a15050565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610db25780601f10610d8757610100808354040283529160200191610db2565b600081815260096020908152604091829020548251808401909352600683526518181b18181960d11b91830191909152606091906001600160a01b031661188b5760405162461bcd60e51b81526004016106229190612cf7565b506040805160208101909152600081526003546002600019610100600184161502019091160415610bd75760036118c1846120c7565b6040516020016118d2929190612bad565b60408051601f198184030181529190526004549091506002600019610100600184161502019091160415610bd757806004604051602001611914929190612b86565b604051602081830303815290604052905092915050565b600081815260096020908152604091829020548251808401909352600683526530303730303360d01b9183019190915260609182916001600160a01b03166119865760405162461bcd60e51b81526004016106229190612cf7565b50600f54604051602001610c869190612b7d565b60408051808201909152600681526503030373031360d41b6020820152336001600160a01b038a16146119e05760405162461bcd60e51b81526004016106229190612cf7565b5060006119f389898989898989896114bc565b6000818152600d6020908152604091829020548251808401909352600683526530303730303760d01b918301919091529192509060ff1615611a485760405162461bcd60e51b81526004016106229190612cf7565b506000908152600e60205260409020805460ff191660011790555050505050505050565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205460ff1690565b60408051808201825260068082526518189b98181960d11b602092830152336000908152600c83528390205483518085019094529083526530313730303160d01b918301919091526001919082168214611b075760405162461bcd60e51b81526004016106229190612cf7565b506001600160a01b0383166000818152600c602052604080822080548619169081905590519092917fd1d59d2d212a435434e7a4a4676427610dfe2b6268b01e541d280d65bf3d6b9091a3505050565b600081815260096020908152604091829020548251808401909352600683526518181b18181960d11b918301919091526001600160a01b03169081611baf5760405162461bcd60e51b81526004016106229190612cf7565b506000828152600a60205260409020546001600160a01b031615611bea576000828152600a6020526040902080546001600160a01b03191690555b6001600160a01b038116600090815260076020526040902054611c0957fe5b6000828152600860209081526040808320546001600160a01b03851684526007909252822054909160001990910190818314611cc2576001600160a01b0384166000908152600760205260409020805483908110611c6357fe5b906000526020600020015490508060076000866001600160a01b03166001600160a01b031681526020019081526020016000208481548110611ca157fe5b60009182526020808320909101929092558281526008909152604090208390555b600085815260096020908152604080832080546001600160a01b0319169055600882528083208390556001600160a01b038716835260079091529020805480611d0757fe5b60019003818190600052602060002001600090559055600060058054905011611d2c57fe5b600085815260066020526040902054600580546000198101945084908110611d5057fe5b906000526020600020015491508160058281548110611d6b57fe5b6000918252602090912001556005805480611d8257fe5b600082815260208082208301600019908101839055909201909255838252600690526040808220839055878252808220829055518791906001600160a01b038816907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050505050565b60125460408051808201909152600681526518181b98181960d11b60208201529060ff1615611e335760405162461bcd60e51b81526004016106229190612cf7565b50610b3183838361218b565b611e51836001600160a01b03166124db565b15611f2657604051630a85bd0160e11b808252906001600160a01b0385169063150b7a0290611e8a903390899088908890600401612c48565b602060405180830381600087803b158015611ea457600080fd5b505af1158015611eb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611edc91908101906129bb565b6001600160e01b031916146040518060400160405280600681526020016530303630303560d01b81525090611f245760405162461bcd60e51b81526004016106229190612cf7565b505b611f31848484611df1565b50505050565b8151611f4a9060039060208501906124e1565b508051610b319060049060208401906124e1565b60408051808201909152600681526530303630303160d01b60208201526001600160a01b038316611fa25760405162461bcd60e51b81526004016106229190612cf7565b50600081815260096020908152604091829020548251808401909352600683526518181b18181b60d11b918301919091526001600160a01b031615611ffa5760405162461bcd60e51b81526004016106229190612cf7565b50600081815260096020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558084526007835281842080546001818101835582875285872090910187905590548686526008855283862060001991820190556005805492830181557f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0909201879055905460069094528285209301909255518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060816120ec57506040805180820190915260018152600360fc1b6020820152610532565b8160005b811561210457600101600a820491506120f0565b6060816040519080825280601f01601f191660200182016040528015612131576020820181803883390190505b50859350905060001982015b831561218257600a840660300160f81b8282806001900393508151811061216057fe5b60200101906001600160f81b031916908160001a905350600a8404935061213d565b50949350505050565b60408051808201909152600681526530303630303160d01b60208201526001600160a01b0384166121cf5760405162461bcd60e51b81526004016106229190612cf7565b50600081815260096020908152604091829020548251808401909352600683526518181b18181960d11b918301919091526001600160a01b0385811691161461222b5760405162461bcd60e51b81526004016106229190612cf7565b5060408051808201909152600681526530303630303160d01b60208201526001600160a01b0383166122705760405162461bcd60e51b81526004016106229190612cf7565b506001600160a01b03831633148061229e57506000818152600a60205260409020546001600160a01b031633145b806122cc57506001600160a01b0383166000908152600b6020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0d8c0c0d60d21b815250906123095760405162461bcd60e51b81526004016106229190612cf7565b506000818152600a60205260409020546001600160a01b031615612344576000818152600a6020526040902080546001600160a01b03191690555b6001600160a01b03831660009081526007602052604090205461236357fe5b6000818152600860209081526040808320546001600160a01b038716845260079092529091205460001901808214612417576001600160a01b03851660009081526007602052604081208054839081106123b957fe5b906000526020600020015490508060076000886001600160a01b03166001600160a01b0316815260200190815260200160002084815481106123f757fe5b600091825260208083209091019290925591825260089052604090208290555b6001600160a01b038516600090815260076020526040902080548061243857fe5b60008281526020808220600019908401810183905592830190935585815260098352604080822080546001600160a01b0319166001600160a01b038a8116918217909255808452600786528284208054600181018255818652878620018a9055548985526008909652828420959094019094555186938916917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a45050505050565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061252257805160ff191683800117855561254f565b8280016001018555821561254f579182015b8281111561254f578251825591602001919060010190612534565b5061255b92915061255f565b5090565b610a2a91905b8082111561255b5760008155600101612565565b80356001600160a01b0381168114610bd757600080fd5b60008083601f8401126125a1578182fd5b50813567ffffffffffffffff8111156125b8578182fd5b6020830191508360208285010111156125d057600080fd5b9250929050565b6000608082840312156125e8578081fd5b6040516080810181811067ffffffffffffffff82111715612607578283fd5b80604052508091508235815260208301356020820152604083013560ff8116811461263157600080fd5b604082015260608301356003811061264857600080fd5b6060919091015292915050565b600060208284031215612666578081fd5b6113388383612579565b60008060408385031215612682578081fd5b61268c8484612579565b915061269b8460208501612579565b90509250929050565b600080600080600080600080610100898b0312156126c0578384fd5b6126ca8a8a612579565b97506126d98a60208b01612579565b965060408901356126e981612d4e565b95506126f88a60608b01612579565b94506080890135935061270e8a60a08b01612579565b925060c0890135915060e089013590509295985092959890939650565b6000806000806000806000806000898b0361018081121561274a578182fd5b6127548c8c612579565b99506127638c60208d01612579565b985060408b013561277381612d4e565b97506127828c60608d01612579565b965060808b013595506127988c60a08d01612579565b945060c08b0135935060e08b01359250608060ff19820112156127b9578182fd5b506101008a0190509295985092959850929598565b6000806000606084860312156127e2578283fd5b83356127ed81612d36565b925060208401356127fd81612d36565b929592945050506040919091013590565b600080600080600060808688031215612825578081fd5b61282f8787612579565b945061283e8760208801612579565b935060408601359250606086013567ffffffffffffffff811115612860578182fd5b61286c88828901612590565b969995985093965092949392505050565b6000806040838503121561288f578081fd5b6128998484612579565b915060208301356128a981612d4e565b809150509250929050565b600080600060c084860312156128c8578081fd5b83356128d381612d36565b9250602084013591506128e985604086016125d7565b90509250925092565b60008060408385031215612904578182fd5b61290e8484612579565b946020939093013593505050565b600080600060608486031215612930578081fd5b61293a8585612579565b95602085013595506040909401359392505050565b600060208284031215612960578081fd5b813561133881612d4e565b60006020828403121561297c578081fd5b815161133881612d4e565b600060208284031215612998578081fd5b5035919050565b6000602082840312156129b0578081fd5b813561133881612d5c565b6000602082840312156129cc578081fd5b815161133881612d5c565b600080600080604085870312156129ec578182fd5b843567ffffffffffffffff80821115612a03578384fd5b612a0f88838901612590565b90965094506020870135915080821115612a27578384fd5b50612a3487828801612590565b95989497509550505050565b600060808284031215612a51578081fd5b61133883836125d7565b60008060408385031215612a6d578182fd5b50508035926020909101359150565b60008151808452612a94816020860160208601612d0a565b601f01601f19169290920160200192915050565b600081546001811660008114612ac55760018114612adc57612b0f565b60ff198216855260028204607f1685019250612b0f565b6002820484600052602060002060005b82811015612b0857815488820152600190910190602001612aec565b5050850192505b505092915050565b6bffffffffffffffffffffffff1960609a8b1b81168252988a1b8916601482015296891b8816602888015294151560f81b603c87015292871b8616603d860152605185019190915290941b9092166071820152608581019290925260a582015260c50190565b90815260200190565b60008351612b98818460208801612d0a565b612ba481840185612aa8565b95945050505050565b6000612bb98285612aa8565b8351612bc9818360208801612d0a565b01949350505050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b7f19457468657265756d205369676e6564204d6573736167653a0a2000000000008152601b810191909152603b0190565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612c7b90830184612a7c565b9695505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b901515815260200190565b93845260ff9290921660208401526040830152606082015260800190565b600060408252612ce56040830185612a7c565b8281036020840152612ba48185612a7c565b6000602082526113386020830184612a7c565b60005b83811015612d25578181015183820152602001612d0d565b83811115611f315750506000910152565b6001600160a01b0381168114612d4b57600080fd5b50565b8015158114612d4b57600080fd5b6001600160e01b031981168114612d4b57600080fdfea26469706673582212204574c5994c4e770a143ad25f63b9804d1c5a684f6a61f19a40daaca0540a227164736f6c63430006010033a2646970667358221220b3fdccd7bc05662526714ac50b5ac7fb059f41c9177ef2cee66c141b0c3f87a964736f6c63430006010033

Deployed ByteCode Sourcemap

26885:503:0:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26885:503:0;;;;;;;;;;;;;;;;;;;26920:465;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;27195:13;27270:5;27277:7;27286:10;27298:11;27311:25;27338:13;27353:10;27244:128;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;27220:159:0;26920:465;-1:-1:-1;;;;;;;;26920:465:0:o;26885:503::-;;;;;;;;:::o;161:616:-1:-;;276:3;269:4;261:6;257:17;253:27;243:2;;-1:-1;;284:12;243:2;337:78;8607:17;337:78;;;328:87;;421:16;480:17;538:3;8607:17;513:3;509:27;506:36;503:2;;;555:1;;545:12;503:2;580:1;565:206;318:4;587:1;584:13;565:206;;;72:20;;-1:-1;;;;;11057:54;;11718:35;;11708:2;;580:1;;11757:12;11708:2;658:50;;8619:4;722:14;;;;750;;;;;612:1;605:9;565:206;;;569:14;;;236:541;;;;;802:704;;918:3;911:4;903:6;899:17;895:27;885:2;;-1:-1;;926:12;885:2;973:6;960:20;8804:18;8796:6;8793:30;8790:2;;;-1:-1;;8826:12;8790:2;8871:4;;8863:6;8859:17;995:79;8871:4;8859:17;8924:15;995:79;;;1102:21;;;986:88;-1:-1;1159:14;;;1134:17;;;1239:27;;;;;1236:36;-1:-1;1233:2;;;1285:1;;1275:12;1233:2;1310:1;1301:10;;1295:205;1320:6;1317:1;1314:13;1295:205;;;1717:20;;-1:-1;;;;;;10905:78;;11965:34;;11955:2;;1310:1;;12003:12;11955:2;1388:49;;1342:1;1335:9;;;;;1451:14;;;;1479;;1295:205;;;1299:14;;;;;878:628;;;;;1787:442;;1889:3;1882:4;1874:6;1870:17;1866:27;1856:2;;-1:-1;;1897:12;1856:2;1944:6;1931:20;9100:18;9092:6;9089:30;9086:2;;;-1:-1;;9122:12;9086:2;1966:65;9195:9;9176:17;;-1:-1;;9172:33;9263:4;9253:15;1966:65;;;1957:74;;2051:6;2044:5;2037:21;2155:3;9263:4;2146:6;2079;2137:16;;2134:25;2131:2;;;2172:1;;2162:12;2131:2;11205:6;9263:4;2079:6;2075:17;9263:4;2113:5;2109:16;11182:30;11261:1;11243:16;;;9263:4;11243:16;11236:27;2113:5;1849:380;-1:-1;;1849:380;2237:1599;;;;;;;;2530:3;2518:9;2509:7;2505:23;2501:33;2498:2;;;-1:-1;;2537:12;2498:2;2595:17;2582:31;2633:18;;2625:6;2622:30;2619:2;;;-1:-1;;2655:12;2619:2;2685:63;2740:7;2731:6;2720:9;2716:22;2685:63;;;2675:73;;2813:2;2802:9;2798:18;2785:32;2771:46;;2633:18;2829:6;2826:30;2823:2;;;-1:-1;;2859:12;2823:2;2889:63;2944:7;2935:6;2924:9;2920:22;2889:63;;;2879:73;;3017:2;3006:9;3002:18;2989:32;2975:46;;2633:18;3033:6;3030:30;3027:2;;;-1:-1;;3063:12;3027:2;3093:63;3148:7;3139:6;3128:9;3124:22;3093:63;;;3083:73;;3221:2;3210:9;3206:18;3193:32;3179:46;;2633:18;3237:6;3234:30;3231:2;;;-1:-1;;3267:12;3231:2;3297:63;3352:7;3343:6;3332:9;3328:22;3297:63;;;3287:73;;3397:3;3441:9;3437:22;1581:20;3406:63;;3534:3;3523:9;3519:19;3506:33;3492:47;;2633:18;3551:6;3548:30;3545:2;;;-1:-1;;3581:12;3545:2;;3611:77;3680:7;3671:6;3660:9;3656:22;3611:77;;;3601:87;;;3744:76;3812:7;3725:3;3792:9;3788:22;3744:76;;;3734:86;;2492:1344;;;;;;;;;;;4026:169;-1:-1;;;;;;10905:78;6032:36;;4184:4;4175:14;;4104:91;4466:660;4829:21;4871:1;4856:258;9640:4;4878:1;4875:13;4856:258;;;4942:13;;-1:-1;;;;;11057:54;4264:37;;4006:4;3997:14;;;;10020;;;;11068:42;4896:9;4856:258;;;4860:14;;4578:548;;;6080:347;;6225:5;9763:12;10439:6;10434:3;10427:19;-1:-1;11350:101;11364:6;11361:1;11358:13;11350:101;;;10476:4;11431:11;;;;;11425:18;11412:11;;;;;11405:39;11379:10;11350:101;;;11466:6;11463:1;11460:13;11457:2;;;-1:-1;10476:4;11522:6;10471:3;11513:16;;11506:27;11457:2;-1:-1;9195:9;11622:14;-1:-1;;11618:28;6383:39;;;;10476:4;6383:39;;6172:255;-1:-1;;6172:255;6434:213;-1:-1;;;;;11057:54;;;;4264:37;;6552:2;6537:18;;6523:124;6654:1471;;7114:3;;7136:17;7129:47;7190:78;7114:3;7103:9;7099:19;7254:6;7190:78;;;7316:9;7310:4;7306:20;7301:2;7290:9;7286:18;7279:48;7341:78;7414:4;7405:6;7341:78;;;7333:86;;;7467:9;7461:4;7457:20;7452:2;7441:9;7437:18;7430:48;7492:78;7565:4;7556:6;7492:78;;;7618:9;7612:4;7608:20;7603:2;7592:9;7588:18;7581:48;7643:78;7716:4;7707:6;7643:78;;;7635:86;;;5954:5;7800:3;7789:9;7785:19;5924:37;7854:9;7848:4;7844:20;7838:3;7827:9;7823:19;7816:49;7879:106;5353:5;9763:12;5372:85;5450:6;5445:3;5372:85;;;5365:92;;7301:2;5527:5;9503:14;5539:21;;-1:-1;5566:257;5591:6;5588:1;5585:13;5566:257;;;5679:61;5736:3;5658:6;5652:13;5679:61;;;7301:2;10020:14;;;;;5672:68;-1:-1;5613:1;5606:9;5566:257;;;5570:14;;7871:114;;;;;7996:119;8110:3;8099:9;8095:19;8086:6;7996:119;;;7085:1040;;;;;;;;;;;8132:256;8194:2;8188:9;8220:17;;;8295:18;8280:34;;8316:22;;;8277:62;8274:2;;;8352:1;;8342:12;8274:2;8194;8361:22;8172:216;;-1:-1;8172:216;10310:177;10427:19;;;10476:4;10467:14;;10420:67

Swarm Source

ipfs://b3fdccd7bc05662526714ac50b5ac7fb059f41c9177ef2cee66c141b0c3f87a9
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.