Overview
ETH Balance
0.1 ETH
Eth Value
$265.62 (@ $2,656.20/ETH)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 17,007 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Finish Fusion | 14309417 | 904 days ago | IN | 0 ETH | 0.01299694 | ||||
Fuse | 14308681 | 904 days ago | IN | 0.005 ETH | 0.01227591 | ||||
Finish Fusion | 12777115 | 1143 days ago | IN | 0 ETH | 0.00672858 | ||||
Finish Fusion | 12777058 | 1143 days ago | IN | 0 ETH | 0.00586761 | ||||
Fuse | 12741665 | 1148 days ago | IN | 0.005 ETH | 0.00132172 | ||||
Fuse | 12741630 | 1148 days ago | IN | 0.005 ETH | 0.00115207 | ||||
Finish Fusion | 11343346 | 1364 days ago | IN | 0 ETH | 0.00339294 | ||||
Fuse | 11343302 | 1364 days ago | IN | 0.005 ETH | 0.00249402 | ||||
Finish Fusion | 11343296 | 1364 days ago | IN | 0 ETH | 0.00338912 | ||||
Fuse | 11343247 | 1364 days ago | IN | 0.005 ETH | 0.00045486 | ||||
Fuse | 11343247 | 1364 days ago | IN | 0.005 ETH | 0.00220582 | ||||
Finish Fusion | 11343214 | 1364 days ago | IN | 0 ETH | 0.00339347 | ||||
Fuse | 11343183 | 1364 days ago | IN | 0.005 ETH | 0.00207974 | ||||
Finish Fusion | 11342890 | 1364 days ago | IN | 0 ETH | 0.00413582 | ||||
Fuse | 11342834 | 1364 days ago | IN | 0.005 ETH | 0.00274809 | ||||
Finish Fusion | 11342827 | 1364 days ago | IN | 0 ETH | 0.00405465 | ||||
Fuse | 11342826 | 1364 days ago | IN | 0.005 ETH | 0.00279218 | ||||
Finish Fusion | 11227563 | 1382 days ago | IN | 0 ETH | 0.00448056 | ||||
Fuse | 11227556 | 1382 days ago | IN | 0.005 ETH | 0.00455566 | ||||
Finish Fusion | 11133735 | 1396 days ago | IN | 0 ETH | 0.00448426 | ||||
Finish Fusion | 11133735 | 1396 days ago | IN | 0 ETH | 0.00448525 | ||||
Finish Fusion | 11133735 | 1396 days ago | IN | 0 ETH | 0.00449543 | ||||
Fuse | 11127093 | 1397 days ago | IN | 0.005 ETH | 0.00216314 | ||||
Fuse | 11127086 | 1397 days ago | IN | 0.005 ETH | 0.00223076 | ||||
Fuse | 11127084 | 1397 days ago | IN | 0.005 ETH | 0.00048789 |
Latest 9 internal transactions
Advanced mode:
Loading...
Loading
Contract Name:
Fusion
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-02-28 */ pragma solidity ^0.4.24; // File: contracts/openzeppelin-solidity/introspection/ERC165.sol /** * @title ERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface ERC165 { /** * @notice Query if a contract implements an interface * @param _interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 _interfaceId) external view returns (bool); } // File: contracts/openzeppelin-solidity/token/ERC721/ERC721Basic.sol /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Basic is ERC165 { 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 balanceOf(address _owner) public view returns (uint256 _balance); function ownerOf(uint256 _tokenId) public view returns (address _owner); function exists(uint256 _tokenId) public view returns (bool _exists); function approve(address _to, uint256 _tokenId) public; function getApproved(uint256 _tokenId) public view returns (address _operator); function setApprovalForAll(address _operator, bool _approved) public; function isApprovedForAll(address _owner, address _operator) public view returns (bool); function transferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) public; } // File: contracts/openzeppelin-solidity/token/ERC721/ERC721.sol /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Enumerable is ERC721Basic { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex( address _owner, uint256 _index ) public view returns (uint256 _tokenId); function tokenByIndex(uint256 _index) public view returns (uint256); } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Metadata is ERC721Basic { function name() external view returns (string _name); function symbol() external view returns (string _symbol); function tokenURI(uint256 _tokenId) public view returns (string); } /** * @title ERC-721 Non-Fungible Token Standard, full implementation interface * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { } // File: contracts/openzeppelin-solidity/token/ERC721/ERC721Receiver.sol /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract ERC721Receiver { /** * @dev Magic value to be returned upon successful reception of an NFT * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` */ bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safetransfer`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the contract address is always the message sender. * @param _operator The address which called `safeTransferFrom` function * @param _from The address which previously owned the token * @param _tokenId The NFT identifier which is being transfered * @param _data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes _data ) public returns(bytes4); } // File: contracts/openzeppelin-solidity/math/SafeMath.sol /** * @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; } } // File: contracts/openzeppelin-solidity/AddressUtils.sol /** * Utility library of inline functions on addresses */ library AddressUtils { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param addr address to check * @return whether the target address is a contract */ function isContract(address addr) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(addr) } return size > 0; } } // File: contracts/openzeppelin-solidity/introspection/SupportsInterfaceWithLookup.sol /** * @title SupportsInterfaceWithLookup * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract SupportsInterfaceWithLookup is ERC165 { bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) internal supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor() public { _registerInterface(InterfaceId_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 _interfaceId) external view returns (bool) { return supportedInterfaces[_interfaceId]; } /** * @dev private method for registering an interface */ function _registerInterface(bytes4 _interfaceId) internal { require(_interfaceId != 0xffffffff); supportedInterfaces[_interfaceId] = true; } } // File: contracts/openzeppelin-solidity/token/ERC721/ERC721BasicToken.sol /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721BasicToken is SupportsInterfaceWithLookup, ERC721Basic { bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; /* * 0x4f558e79 === * bytes4(keccak256('exists(uint256)')) */ using SafeMath for uint256; using AddressUtils for address; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` bytes4 private constant ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) internal tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) internal tokenApprovals; // Mapping from owner to number of owned token mapping (address => uint256) internal ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) internal operatorApprovals; /** * @dev Guarantees msg.sender is owner of the given token * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender */ modifier onlyOwnerOf(uint256 _tokenId) { require(ownerOf(_tokenId) == msg.sender); _; } /** * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator * @param _tokenId uint256 ID of the token to validate */ modifier canTransfer(uint256 _tokenId) { require(isApprovedOrOwner(msg.sender, _tokenId)); _; } constructor() public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(InterfaceId_ERC721); _registerInterface(InterfaceId_ERC721Exists); } /** * @dev Gets the balance of the specified address * @param _owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address _owner) public view returns (uint256) { require(_owner != address(0)); return ownedTokensCount[_owner]; } /** * @dev Gets the owner of the specified token ID * @param _tokenId uint256 ID of the token to query the owner of * @return owner address currently marked as the owner of the given token ID */ function ownerOf(uint256 _tokenId) public view returns (address) { address owner = tokenOwner[_tokenId]; require(owner != address(0)); return owner; } /** * @dev Returns whether the specified token exists * @param _tokenId uint256 ID of the token to query the existence of * @return whether the token exists */ function exists(uint256 _tokenId) public view returns (bool) { address owner = tokenOwner[_tokenId]; return owner != address(0); } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param _to address to be approved for the given token ID * @param _tokenId uint256 ID of the token to be approved */ function approve(address _to, uint256 _tokenId) public { address owner = ownerOf(_tokenId); require(_to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); tokenApprovals[_tokenId] = _to; emit Approval(owner, _to, _tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * @param _tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 _tokenId) public view returns (address) { return tokenApprovals[_tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param _to operator address to set the approval * @param _approved representing the status of the approval to be set */ function setApprovalForAll(address _to, bool _approved) public { require(_to != msg.sender); operatorApprovals[msg.sender][_to] = _approved; emit ApprovalForAll(msg.sender, _to, _approved); } /** * @dev Tells whether an operator is approved by a given owner * @param _owner owner address which you want to query the approval of * @param _operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll( address _owner, address _operator ) public view returns (bool) { return operatorApprovals[_owner][_operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg sender to be the owner, approved, or operator * @param _from current owner of the token * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred */ function transferFrom( address _from, address _to, uint256 _tokenId ) public canTransfer(_tokenId) { require(_from != address(0)); require(_to != address(0)); clearApproval(_from, _tokenId); removeTokenFrom(_from, _tokenId); addTokenTo(_to, _tokenId); emit Transfer(_from, _to, _tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * * Requires the msg sender to be the owner, approved, or operator * @param _from current owner of the token * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) public canTransfer(_tokenId) { // solium-disable-next-line arg-overflow safeTransferFrom(_from, _to, _tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg sender to be the owner, approved, or operator * @param _from current owner of the token * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) public canTransfer(_tokenId) { transferFrom(_from, _to, _tokenId); // solium-disable-next-line arg-overflow require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); } /** * @dev Returns whether the given spender can transfer a given token ID * @param _spender address of the spender to query * @param _tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function isApprovedOrOwner( address _spender, uint256 _tokenId ) internal view returns (bool) { address owner = ownerOf(_tokenId); // Disable solium check because of // https://github.com/duaraghav8/Solium/issues/175 // solium-disable-next-line operator-whitespace return ( _spender == owner || getApproved(_tokenId) == _spender || isApprovedForAll(owner, _spender) ); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param _to The address that will own the minted token * @param _tokenId uint256 ID of the token to be minted by the msg.sender */ function _mint(address _to, uint256 _tokenId) internal { require(_to != address(0)); addTokenTo(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param _tokenId uint256 ID of the token being burned by the msg.sender */ function _burn(address _owner, uint256 _tokenId) internal { clearApproval(_owner, _tokenId); removeTokenFrom(_owner, _tokenId); emit Transfer(_owner, address(0), _tokenId); } /** * @dev Internal function to clear current approval of a given token ID * Reverts if the given address is not indeed the owner of the token * @param _owner owner of the token * @param _tokenId uint256 ID of the token to be transferred */ function clearApproval(address _owner, uint256 _tokenId) internal { require(ownerOf(_tokenId) == _owner); if (tokenApprovals[_tokenId] != address(0)) { tokenApprovals[_tokenId] = address(0); } } /** * @dev Internal function to add a token ID to the list of a given address * @param _to address representing the new owner of the given token ID * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address */ function addTokenTo(address _to, uint256 _tokenId) internal { require(tokenOwner[_tokenId] == address(0)); tokenOwner[_tokenId] = _to; ownedTokensCount[_to] = ownedTokensCount[_to].add(1); } /** * @dev Internal function to remove a token ID from the list of a given address * @param _from address representing the previous owner of the given token ID * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function removeTokenFrom(address _from, uint256 _tokenId) internal { require(ownerOf(_tokenId) == _from); ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); tokenOwner[_tokenId] = address(0); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param _from address representing the previous owner of the given token ID * @param _to target address that will receive the tokens * @param _tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return whether the call correctly returned the expected magic value */ function checkAndCallSafeTransfer( address _from, address _to, uint256 _tokenId, bytes _data ) internal returns (bool) { if (!_to.isContract()) { return true; } bytes4 retval = ERC721Receiver(_to).onERC721Received( msg.sender, _from, _tokenId, _data); return (retval == ERC721_RECEIVED); } } // File: contracts/openzeppelin-solidity/token/ERC721/ERC721Token.sol /** * @title Full ERC721 Token * This implementation includes all the required and some optional functionality of the ERC721 standard * Moreover, it includes approve all functionality using operator terminology * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; /** * 0x780e9d63 === * bytes4(keccak256('totalSupply()')) ^ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ * bytes4(keccak256('tokenByIndex(uint256)')) */ bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; /** * 0x5b5e139f === * bytes4(keccak256('name()')) ^ * bytes4(keccak256('symbol()')) ^ * bytes4(keccak256('tokenURI(uint256)')) */ // Token name string internal name_; // Token symbol string internal symbol_; // Mapping from owner to list of owned token IDs mapping(address => uint256[]) internal ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) internal ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] internal allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) internal allTokensIndex; // Optional mapping for token URIs mapping(uint256 => string) internal tokenURIs; /** * @dev Constructor function */ constructor(string _name, string _symbol) public { name_ = _name; symbol_ = _symbol; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(InterfaceId_ERC721Enumerable); _registerInterface(InterfaceId_ERC721Metadata); } /** * @dev Gets the token name * @return string representing the token name */ function name() external view returns (string) { return name_; } /** * @dev Gets the token symbol * @return string representing the token symbol */ function symbol() external view returns (string) { return symbol_; } /** * @dev Returns an URI for a given token ID * Throws if the token ID does not exist. May return an empty string. * @param _tokenId uint256 ID of the token to query */ function tokenURI(uint256 _tokenId) public view returns (string) { require(exists(_tokenId)); return tokenURIs[_tokenId]; } /** * @dev Gets the token ID at a given index of the tokens list of the requested owner * @param _owner address owning the tokens list to be accessed * @param _index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ function tokenOfOwnerByIndex( address _owner, uint256 _index ) public view returns (uint256) { require(_index < balanceOf(_owner)); return ownedTokens[_owner][_index]; } /** * @dev Gets the total amount of tokens stored by the contract * @return uint256 representing the total amount of tokens */ function totalSupply() public view returns (uint256) { return allTokens.length; } /** * @dev Gets the token ID at a given index of all the tokens in this contract * Reverts if the index is greater or equal to the total number of tokens * @param _index uint256 representing the index to be accessed of the tokens list * @return uint256 token ID at the given index of the tokens list */ function tokenByIndex(uint256 _index) public view returns (uint256) { require(_index < totalSupply()); return allTokens[_index]; } /** * @dev Internal function to set the token URI for a given token * Reverts if the token ID does not exist * @param _tokenId uint256 ID of the token to set its URI * @param _uri string URI to assign */ function _setTokenURI(uint256 _tokenId, string _uri) internal { require(exists(_tokenId)); tokenURIs[_tokenId] = _uri; } /** * @dev Internal function to add a token ID to the list of a given address * @param _to address representing the new owner of the given token ID * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address */ function addTokenTo(address _to, uint256 _tokenId) internal { super.addTokenTo(_to, _tokenId); uint256 length = ownedTokens[_to].length; ownedTokens[_to].push(_tokenId); ownedTokensIndex[_tokenId] = length; } /** * @dev Internal function to remove a token ID from the list of a given address * @param _from address representing the previous owner of the given token ID * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function removeTokenFrom(address _from, uint256 _tokenId) internal { super.removeTokenFrom(_from, _tokenId); uint256 tokenIndex = ownedTokensIndex[_tokenId]; uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); uint256 lastToken = ownedTokens[_from][lastTokenIndex]; ownedTokens[_from][tokenIndex] = lastToken; ownedTokens[_from][lastTokenIndex] = 0; // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping // the lastToken to the first position, and then dropping the element placed in the last position of the list ownedTokens[_from].length--; ownedTokensIndex[_tokenId] = 0; ownedTokensIndex[lastToken] = tokenIndex; } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param _to address the beneficiary that will own the minted token * @param _tokenId uint256 ID of the token to be minted by the msg.sender */ function _mint(address _to, uint256 _tokenId) internal { super._mint(_to, _tokenId); allTokensIndex[_tokenId] = allTokens.length; allTokens.push(_tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param _owner owner of the token to burn * @param _tokenId uint256 ID of the token being burned by the msg.sender */ function _burn(address _owner, uint256 _tokenId) internal { super._burn(_owner, _tokenId); // Clear metadata (if any) if (bytes(tokenURIs[_tokenId]).length != 0) { delete tokenURIs[_tokenId]; } // Reorg all tokens array uint256 tokenIndex = allTokensIndex[_tokenId]; uint256 lastTokenIndex = allTokens.length.sub(1); uint256 lastToken = allTokens[lastTokenIndex]; allTokens[tokenIndex] = lastToken; allTokens[lastTokenIndex] = 0; allTokens.length--; allTokensIndex[_tokenId] = 0; allTokensIndex[lastToken] = tokenIndex; } } // File: contracts/openzeppelin-solidity/ownership/Ownable.sol /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; event OwnershipRenounced(address indexed previousOwner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipRenounced(owner); owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address _newOwner) public onlyOwner { _transferOwnership(_newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function _transferOwnership(address _newOwner) internal { require(_newOwner != address(0)); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: contracts/ERC721TokenWithData.sol // import "./ERC721SlimTokenArray.sol"; // an ERC721 token with additional data storage, contract ERC721TokenWithData is ERC721Token("CryptoAssaultUnit", "CAU"), Ownable { /** * @dev Returns whether the given spender can transfer a given token ID * @param _spender address of the spender to query * @param _tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function isApprovedOrOwner( address _spender, uint256 _tokenId ) internal view returns (bool) { address owner = ownerOf(_tokenId); // Disable solium check because of // https://github.com/duaraghav8/Solium/issues/175 // solium-disable-next-line operator-whitespace return ( _spender == owner || approvedContractAddresses[_spender] || getApproved(_tokenId) == _spender || isApprovedForAll(owner, _spender) ); } mapping (address => bool) internal approvedContractAddresses; bool approvedContractsFinalized = false; /** * @notice Approve a contract address for minting tokens and transferring tokens, when approved by the owner * @param contractAddress The address that will be approved */ function addApprovedContractAddress(address contractAddress) public onlyOwner { require(!approvedContractsFinalized); approvedContractAddresses[contractAddress] = true; } /** * @notice Unapprove a contract address for minting tokens and transferring tokens * @param contractAddress The address that will be unapproved */ function removeApprovedContractAddress(address contractAddress) public onlyOwner { require(!approvedContractsFinalized); approvedContractAddresses[contractAddress] = false; } /** * @notice Finalize the contract so it will be forever impossible to change the approved contracts list */ function finalizeApprovedContracts() public onlyOwner { approvedContractsFinalized = true; } mapping(uint256 => mapping(uint256 => uint256)) data; function getData(uint256 _tokenId, uint256 _index) public view returns (uint256) { return data[_index][_tokenId]; } function getData3(uint256 _tokenId1, uint256 _tokenId2, uint256 _tokenId3, uint256 _index) public view returns (uint256, uint256, uint256) { return ( data[_index][_tokenId1], data[_index][_tokenId2], data[_index][_tokenId3] ); } function getDataAndOwner3(uint256 _tokenId1, uint256 _tokenId2, uint256 _tokenId3, uint256 _index) public view returns (uint256, uint256, uint256, address, address, address) { return ( data[_index][_tokenId1], data[_index][_tokenId2], data[_index][_tokenId3], ownerOf(_tokenId1), ownerOf(_tokenId2), ownerOf(_tokenId3) ); } function _setData(uint256 _tokenId, uint256 _index, uint256 _data) internal { data[_index][_tokenId] = _data; } function setData(uint256 _tokenId, uint256 _index, uint256 _data) public { require(approvedContractAddresses[msg.sender], "not an approved sender"); data[_index][_tokenId] = _data; } /** * @notice Gets the list of tokens owned by a given address * @param _owner address to query the tokens of * @return uint256[] representing the list of tokens owned by the passed address */ function tokensOfWithData(address _owner, uint256 _index) public view returns (uint256[], uint256[]) { uint256[] memory tokensList = ownedTokens[_owner]; uint256[] memory dataList = new uint256[](tokensList.length); for (uint i=0; i<tokensList.length; i++) { dataList[i] = data[_index][tokensList[i]]; } return (tokensList, dataList); } // The tokenId of the next minted token. It auto-increments. uint256 nextTokenId = 1; function getNextTokenId() public view returns (uint256) { return nextTokenId; } /** * @notice Mint token function * @param _to The address that will own the minted token */ function mintAndSetData(address _to, uint256 _data) public returns (uint256) { require(approvedContractAddresses[msg.sender], "not an approved sender"); uint256 tokenId = nextTokenId; nextTokenId++; _mint(_to, tokenId); _setData(tokenId, 0, _data); return tokenId; } function burn(uint256 _tokenId) public { require( approvedContractAddresses[msg.sender] || msg.sender == owner, "burner not approved" ); _burn(ownerOf(_tokenId), _tokenId); } function burn3(uint256 _tokenId1, uint256 _tokenId2, uint256 _tokenId3) public { require( approvedContractAddresses[msg.sender] || msg.sender == owner, "burner not approved" ); _burn(ownerOf(_tokenId1), _tokenId1); _burn(ownerOf(_tokenId2), _tokenId2); _burn(ownerOf(_tokenId3), _tokenId3); } } // File: contracts/strings/Strings.sol library Strings { // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory _bd = bytes(_d); bytes memory _be = bytes(_e); string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); bytes memory babcde = bytes(abcde); uint k = 0; for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; for (i = 0; i < _be.length; i++) babcde[k++] = _be[i]; return string(babcde); } function strConcat(string _a, string _b, string _c, string _d) internal pure returns (string) { return strConcat(_a, _b, _c, _d, ""); } function strConcat(string _a, string _b, string _c) internal pure returns (string) { return strConcat(_a, _b, _c, "", ""); } function strConcat(string _a, string _b) internal pure returns (string) { return strConcat(_a, _b, "", "", ""); } function uint2str(uint i) internal pure returns (string) { if (i == 0) return "0"; uint j = i; uint len; while (j != 0){ len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (i != 0){ bstr[k--] = byte(48 + i % 10); i /= 10; } return string(bstr); } } // File: contracts/Token.sol contract Token is ERC721TokenWithData { string metadataUrlPrefix = "https://metadata.cryptoassault.io/unit/"; /** * @dev Returns an URI for a given token ID * Throws if the token ID does not exist. May return an empty string. * @param _tokenId uint256 ID of the token to query */ function tokenURI(uint256 _tokenId) public view returns (string) { require(exists(_tokenId)); return Strings.strConcat(metadataUrlPrefix, Strings.uint2str(_tokenId)); } function setMetadataUrlPrefix(string _metadataUrlPrefix) public onlyOwner { metadataUrlPrefix = _metadataUrlPrefix; } } // File: contracts/openzeppelin-solidity/lifecycle/Pausable.sol /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyOwner whenNotPaused public { paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyOwner whenPaused public { paused = false; emit Unpause(); } } // File: contracts/Fusion.sol contract Fusion is Pausable { event Fused(uint32 unit1, uint32 unit2, uint32 unit3, uint256 price); event FinishedFusing(uint32 unit1, uint32 unit2, uint32 unit3, uint32 newUnit); Token token; function setTokenContractAddress(address newAddress) onlyOwner public { token = Token(newAddress); } struct WaitingToFuse { address owner; uint32 unit1; uint32 unit2; uint32 unit3; uint48 fusedOnBlockNumber; //TODO: maybe fit into 256 bits } mapping (uint256 => WaitingToFuse) waitingToFuse; // This is a LIFO stack. uint64 waitingToFuseNum = 0; uint64 waitingToFuseFirstIndex = 0; uint64 fuseNonce = 1; uint256 fusePrice = 0.005 ether; function withdrawBalance() onlyOwner public { owner.transfer(address(this).balance); } function setFusePrice(uint256 price) public onlyOwner { fusePrice = price; } function pushFuse(uint32 unit1, uint32 unit2, uint32 unit3) private { waitingToFuse[waitingToFuseFirstIndex + waitingToFuseNum] = WaitingToFuse(msg.sender, unit1, unit2, unit3, uint48(block.number)); waitingToFuseNum = waitingToFuseNum + 1; } function popFuse() private { require(waitingToFuseNum > 0, "trying to popFuse() an empty stack"); waitingToFuseNum = waitingToFuseNum - 1; if (waitingToFuseNum == 0) { waitingToFuseFirstIndex = 0; } else { waitingToFuseFirstIndex++; } } function peekFuse() private view returns (WaitingToFuse) { return waitingToFuse[waitingToFuseFirstIndex]; } function fuse(uint32 unit1, uint32 unit2, uint32 unit3) external payable whenNotPaused { require(msg.value == fusePrice, "Price doesnt match the amount payed"); address owner1; address owner2; address owner3; uint256 data1; uint256 data2; uint256 data3; (data1, data2, data3, owner1, owner2, owner3) = token.getDataAndOwner3(unit1, unit2, unit3, 0); require(msg.sender == owner1, "not the owner"); require(msg.sender == owner2, "not the owner"); require(msg.sender == owner3, "not the owner"); uint256 category1 = ((data1 >> 248) & 0xff) / 6; uint256 category2 = ((data2 >> 248) & 0xff) / 6; uint256 category3 = ((data3 >> 248) & 0xff) / 6; require( category1 == category2 && category1 == category3, "categories don't match" ); uint256 tier1 = (data1 >> 244) & 0x0f; // uint256 tier2 = (data2 >> 244) & 0x0f; // uint256 tier3 = (data3 >> 244) & 0x0f; require( (tier1 == (data2 >> 244) & 0x0f) && (tier1 == (data3 >> 244) & 0x0f), "tiers don't match" ); require (tier1 <= 2, "4 is the maximum tier"); // burn the tokens. // their data will still be used though. token.burn3(unit1, unit2, unit3); pushFuse(unit1, unit2, unit3); emit Fused(unit1, unit2, unit3, fusePrice); } function getProjectedBlockHash(uint256 blockNumber) internal view returns (uint256) { uint256 blockToHash = blockNumber; uint256 blocksAgo = block.number - blockToHash; blockToHash += ((blocksAgo-1) / 256) * 256; return uint256(blockhash(blockToHash)); } function fusionsNeeded() external view returns (uint256) { return waitingToFuseNum; } function getRandomRarity(uint256 data1, uint256 data2, uint256 data3, uint16 rarityRand) internal pure returns (uint256, uint256) { uint256 rarityPattern = 0; rarityPattern += 1 << (((data1 >> 216) & 0x0f) * 4); rarityPattern += 1 << (((data2 >> 216) & 0x0f) * 4); rarityPattern += 1 << (((data3 >> 216) & 0x0f) * 4); int256 rarity; int256 lowestParentRarity; if (rarityPattern == 0x0003) { rarity = 0; lowestParentRarity = 0; } else if (rarityPattern == 0x0030) { rarity = 1; lowestParentRarity = 1; } else if (rarityPattern == 0x0300) { rarity = 2; lowestParentRarity = 2; } else if (rarityPattern == 0x3000) { rarity = 3; lowestParentRarity = 3; } else if (rarityPattern == 0x0111) { rarity = (rarityRand < 21845) ? 0 : ((rarityRand < 43691) ? 1 : 2); lowestParentRarity = 0; } else if (rarityPattern == 0x1110) { rarity = (rarityRand < 21845) ? 1 : ((rarityRand < 43691) ? 2 : 3); lowestParentRarity = 1; } else if (rarityPattern == 0x1011) { rarity = (rarityRand < 10923) ? 0 : ((rarityRand < 36409) ? 1 : ((rarityRand < 54613) ? 2 : 3)); lowestParentRarity = 0; } else if (rarityPattern == 0x1101) { rarity = (rarityRand < 10923) ? 0 : ((rarityRand < 29127) ? 1 : ((rarityRand < 54613) ? 2 : 3)); lowestParentRarity = 0; } else if (rarityPattern == 0x2001) { rarity = (rarityRand < 10923) ? 0 : ((rarityRand < 25486) ? 1 : ((rarityRand < 43691) ? 2 : 3)); lowestParentRarity = 0; } else if (rarityPattern == 0x1002) { rarity = (rarityRand < 21845) ? 0 : ((rarityRand < 40050) ? 1 : ((rarityRand < 54613) ? 2 : 3)); lowestParentRarity = 0; } else if (rarityPattern == 0x2010) { rarity = (rarityRand < 14564) ? 1 : ((rarityRand < 36409) ? 2 : 3); lowestParentRarity = 1; } else if (rarityPattern == 0x0201) { rarity = (rarityRand < 14564) ? 0 : ((rarityRand < 36409) ? 1 : 2); lowestParentRarity = 0; } else if (rarityPattern == 0x0102) { rarity = (rarityRand < 29127) ? 0 : ((rarityRand < 50972) ? 1 : 2); lowestParentRarity = 0; } else if (rarityPattern == 0x1020) { rarity = (rarityRand < 29127) ? 1 : ((rarityRand < 50972) ? 2 : 3); lowestParentRarity = 1; } else if (rarityPattern == 0x0012) { rarity = (rarityRand < 43691) ? 0 : 1; lowestParentRarity = 0; } else if (rarityPattern == 0x0021) { rarity = (rarityRand < 43691) ? 1 : 0; lowestParentRarity = 0; } else if (rarityPattern == 0x0120) { rarity = (rarityRand < 43691) ? 1 : 2; lowestParentRarity = 1; } else if (rarityPattern == 0x0210) { rarity = (rarityRand < 43691) ? 2 : 1; lowestParentRarity = 1; } else if (rarityPattern == 0x1200) { rarity = (rarityRand < 43691) ? 2 : 3; lowestParentRarity = 2; } else if (rarityPattern == 0x2100) { rarity = (rarityRand < 43691) ? 3 : 2; lowestParentRarity = 2; } else { require(false, "invalid rarity pattern");//TODO: remove this rarity = 0; } // Apply the penalty for when the child rarity is higher than the lowest parent rarity: // child is 3 rarities higher: 0.85 // child is 2 rarities higher: 0.89 // child is 1 rarity higher: 0.95 int256 rarityDifference = rarity - lowestParentRarity; uint256 penalty; if (rarityDifference == 3) { penalty = 55705; } else if (rarityDifference == 2) { penalty = 58327; } else if (rarityDifference == 1) { penalty = 62259; } else { penalty = 65536; } return (uint256(rarity), penalty); } function getOldestBirthTimestamp(uint256 data1, uint256 data2, uint256 data3) internal pure returns (uint256) { uint256 oldestBirthTimestamp = ((data1 >> 220) & 0xffffff); uint256 birthTimestamp2 = ((data2 >> 220) & 0xffffff); uint256 birthTimestamp3 = ((data3 >> 220) & 0xffffff); if (birthTimestamp2 < oldestBirthTimestamp) oldestBirthTimestamp = birthTimestamp2; if (birthTimestamp3 < oldestBirthTimestamp) oldestBirthTimestamp = birthTimestamp3; return oldestBirthTimestamp; } function finishFusion() external whenNotPaused { require(waitingToFuseNum > 0, "nothing to fuse"); WaitingToFuse memory w = peekFuse(); // can't fuse on the same block. its block hash would be unknown. require(w.fusedOnBlockNumber < block.number, "Can't fuse on the same block."); uint256 rand = uint256(keccak256(abi.encodePacked(getProjectedBlockHash(w.fusedOnBlockNumber)))); uint256 data1; uint256 data2; uint256 data3; (data1, data2, data3) = token.getData3(w.unit1, w.unit2, w.unit3, 0); uint256 data = 0; data |= ((data1 >> 248) & 0xff) << 248; // type data |= (((data1 >> 244) & 0x0f) + 1) << 244; // tier // uint256 oldestBirthTimestamp = getOldestBirthTimestamp(data1, data2, data3); // Get the oldest birthday // uint256 oldestBirthTimestamp = ((data1 >> 220) & 0xffffff); // if (((data2 >> 220) & 0xffffff) < oldestBirthTimestamp) oldestBirthTimestamp = ((data2 >> 220) & 0xffffff); // if (((data3 >> 220) & 0xffffff) < oldestBirthTimestamp) oldestBirthTimestamp = ((data3 >> 220) & 0xffffff); data |= getOldestBirthTimestamp(data1, data2, data3) << 220; (uint256 rarity, uint256 penalty) = getRandomRarity(data1, data2, data3, uint16(rand)); rand >>= 16; data |= rarity << 216; data |= ((data1 >> 208) & 0xff) << 208; // sku // Apply the penalty for fusing non-matching types: // 1 matching: 0.93 // 0 matching: 0.88 uint256 numMatchingTypes = 0; if ((((data1 >> 248) & 0xff) << 248) == (((data2 >> 248) & 0xff) << 248)) numMatchingTypes++; if ((((data1 >> 248) & 0xff) << 248) == (((data3 >> 248) & 0xff) << 248)) numMatchingTypes++; if (numMatchingTypes == 1) { penalty = (penalty * 60948) / 65536; // *= 0.93 } else if (numMatchingTypes == 0) { penalty = (penalty * 57671) / 65536; // *= 0.88 } // generate child stats for (uint256 i=0; i<18; i++) { data |= ((( ((data1 >> (200-i*8)) & 0xff) + ((data2 >> (200-i*8)) & 0xff) + ((data3 >> (200-i*8)) & 0xff) ) * penalty // the penalty from mismatched types/rarities * (63488 + (rand&0x3ff)) // a random penalty from 97% to 100% ) / 0x300000000) << (200-i*8); rand >>= 10; } // TODO: maybe re-use the unit1 token as the new fused unit, to save gas uint32 newUnit = uint32(token.mintAndSetData(w.owner, data)); popFuse(); emit FinishedFusing(w.unit1, w.unit2, w.unit3, newUnit); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"price","type":"uint256"}],"name":"setFusePrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"unit1","type":"uint32"},{"name":"unit2","type":"uint32"},{"name":"unit3","type":"uint32"}],"name":"fuse","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fusionsNeeded","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"setTokenContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finishFusion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"unit1","type":"uint32"},{"indexed":false,"name":"unit2","type":"uint32"},{"indexed":false,"name":"unit3","type":"uint32"},{"indexed":false,"name":"price","type":"uint256"}],"name":"Fused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"unit1","type":"uint32"},{"indexed":false,"name":"unit2","type":"uint32"},{"indexed":false,"name":"unit3","type":"uint32"},{"indexed":false,"name":"newUnit","type":"uint32"}],"name":"FinishedFusing","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
60806040526000805460038054600160c060020a0319167001000000000000000000000000000000001790556611c37937e08000600455600160a860020a03191633179055611792806100536000396000f3006080604052600436106100a05763ffffffff60e060020a6000350416633f4ba83a81146100a55780635c975abb146100bc5780635faa6b23146100e55780635fd8c710146100fd5780636040e91814610112578063715018a61461012f5780638456cb59146101445780638b289879146101595780638da5cb5b14610180578063b23d4854146101b1578063d26920cf146101d2578063f2fde38b146101e7575b600080fd5b3480156100b157600080fd5b506100ba610208565b005b3480156100c857600080fd5b506100d161027e565b604080519115158252519081900360200190f35b3480156100f157600080fd5b506100ba60043561028e565b34801561010957600080fd5b506100ba6102aa565b6100ba63ffffffff600435811690602435811690604435166102ff565b34801561013b57600080fd5b506100ba610838565b34801561015057600080fd5b506100ba6108a4565b34801561016557600080fd5b5061016e61091f565b60408051918252519081900360200190f35b34801561018c57600080fd5b5061019561092f565b60408051600160a060020a039092168252519081900360200190f35b3480156101bd57600080fd5b506100ba600160a060020a036004351661093e565b3480156101de57600080fd5b506100ba610984565b3480156101f357600080fd5b506100ba600160a060020a0360043516610ea6565b600054600160a060020a0316331461021f57600080fd5b60005460a060020a900460ff16151561023757600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a1565b60005460a060020a900460ff1681565b600054600160a060020a031633146102a557600080fd5b600455565b600054600160a060020a031633146102c157600080fd5b60008054604051600160a060020a0390911691303180156108fc02929091818181858888f193505050501580156102fc573d6000803e3d6000fd5b50565b600080600080600080600080600080600060149054906101000a900460ff1615151561032a57600080fd5b60045434146103a9576040805160e560020a62461bcd02815260206004820152602360248201527f507269636520646f65736e74206d617463682074686520616d6f756e7420706160448201527f7965640000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160009054906101000a9004600160a060020a0316600160a060020a0316632a0deab48e8e8e60006040518563ffffffff1660e060020a028152600401808563ffffffff1681526020018463ffffffff1681526020018363ffffffff16815260200182815260200194505050505060c060405180830381600087803b15801561043257600080fd5b505af1158015610446573d6000803e3d6000fd5b505050506040513d60c081101561045c57600080fd5b508051602082015160408301516060840151608085015160a090950151909e50939c50929a509098509650945033600160a060020a038b16146104e9576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b33600160a060020a038a1614610549576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b33600160a060020a038916146105a9576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b600660ff60f860020a890416049350600660ff60f860020a880416049250600660ff60f860020a87041604915082841480156105e457508184145b151561063a576040805160e560020a62461bcd02815260206004820152601660248201527f63617465676f7269657320646f6e2774206d6174636800000000000000000000604482015290519081900360640190fd5b50600f60f460020a80880482169190870416811480156106625750600f60f460020a86041681145b15156106b8576040805160e560020a62461bcd02815260206004820152601160248201527f746965727320646f6e2774206d61746368000000000000000000000000000000604482015290519081900360640190fd5b6002811115610711576040805160e560020a62461bcd02815260206004820152601560248201527f3420697320746865206d6178696d756d20746965720000000000000000000000604482015290519081900360640190fd5b600160009054906101000a9004600160a060020a0316600160a060020a0316639d248e088e8e8e6040518463ffffffff1660e060020a028152600401808463ffffffff1681526020018363ffffffff1681526020018263ffffffff1681526020019350505050600060405180830381600087803b15801561079157600080fd5b505af11580156107a5573d6000803e3d6000fd5b505050506107b48d8d8d610ec6565b7fe33e955549546adee4b93a8eccb1f9b2b0192b7d7539481fd55cced9657664d78d8d8d600454604051808563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff16815260200182815260200194505050505060405180910390a150505050505050505050505050565b600054600160a060020a0316331461084f57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146108bb57600080fd5b60005460a060020a900460ff16156108d257600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a1565b60035467ffffffffffffffff1690565b600054600160a060020a031681565b600054600160a060020a0316331461095557600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b61098c611738565b600080600080600080600080600080600060149054906101000a900460ff161515156109b757600080fd5b600354600067ffffffffffffffff90911611610a1d576040805160e560020a62461bcd02815260206004820152600f60248201527f6e6f7468696e6720746f20667573650000000000000000000000000000000000604482015290519081900360640190fd5b610a25611045565b9a50438b6080015165ffffffffffff16101515610a8c576040805160e560020a62461bcd02815260206004820152601d60248201527f43616e27742066757365206f6e207468652073616d6520626c6f636b2e000000604482015290519081900360640190fd5b610aa18b6080015165ffffffffffff166110ee565b604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b60208310610aef5780518252601f199092019160209182019101610ad0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600190049950600160009054906101000a9004600160a060020a0316600160a060020a03166397306c278c602001518d604001518e6060015160006040518563ffffffff1660e060020a028152600401808563ffffffff1681526020018463ffffffff1681526020018363ffffffff168152602001828152602001945050505050606060405180830381600087803b158015610bb757600080fd5b505af1158015610bcb573d6000803e3d6000fd5b505050506040513d6060811015610be157600080fd5b5080516020820151604090920151909a50909850965060f860020a808a0460ff160260f460020a808b04600f166001010217955060dc610c228a8a8a611102565b9060020a0286179550610c378989898d611157565b62010000909b049a60ff7a010000000000000000000000000000000000000000000000000000808d048216027b01000000000000000000000000000000000000000000000000000000840299909917989098179791965094506000935060f860020a808b0482168102818b04909216021415610cb4576001909201915b60f860020a808a0460ff9081168202828a04919091169091021415610cda576001909201915b8260011415610cf4576201000061ee148502049350610d08565b821515610d08576201000061e14785020493505b600091505b6012821015610d67576008820260c803640300000000600282900a808c0460ff908116828d04821601918b041601860261f8006103ff8e160102610400909c049b60029290920a9104029590951794600190910190610d0d565b6001548b51604080517f6b3559e1000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152602481018a905290519190921691636b3559e19160448083019260209291908290030181600087803b158015610dd857600080fd5b505af1158015610dec573d6000803e3d6000fd5b505050506040513d6020811015610e0257600080fd5b50519050610e0e6115a4565b7f5f35a68372238cec24e46cdac2c0a92c09ef335507a551c86e345128ee18af0a8b602001518c604001518d6060015184604051808563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15050505050505050505050565b600054600160a060020a03163314610ebd57600080fd5b6102fc816116bb565b6040805160a08101825233815263ffffffff94851660208083019182529486168284019081529386166060830190815265ffffffffffff438116608085019081526003805468010000000000000000810467ffffffffffffffff90811691811691909101811660009081526002909a5296909820945185549451975193518a1660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff948b167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff99909b1660a060020a0277ffffffff000000000000000000000000000000000000000019600160a060020a039390931673ffffffffffffffffffffffffffffffffffffffff199097169690961791909116949094179690961697909717161781559151600192830180549190951665ffffffffffff1990911617909355815480841690910190921667ffffffffffffffff19909216919091179055565b61104d611738565b5060035467ffffffffffffffff6801000000000000000090910416600090815260026020908152604091829020825160a0810184528154600160a060020a038116825263ffffffff60a060020a82048116948301949094527801000000000000000000000000000000000000000000000000810484169482019490945260e060020a90930490911660608301526001015465ffffffffffff16608082015290565b610100600019438390030181900402014090565b600062ffffff7b1000000000000000000000000000000000000000000000000000000080860482169181860481169185041682821015611140578192505b8281101561114c578092505b509095945050505050565b6000807b01000000000000000000000000000000000000000000000000000000808704600f9081166004908102600290810a848a0484168302820a019388049290921602900a018180808060038514156111b8576000935060009250611552565b84603014156111ce576001935060019250611552565b8461030014156111e5576002935060029250611552565b8461300014156111fc576003935060039250611552565b846101111415611240576155558861ffff161061122f5761aaab8861ffff161061122757600261122a565b60015b611232565b60005b60ff16935060009250611552565b846111101415611284576155558861ffff16106112735761aaab8861ffff161061126b57600361126e565b60025b611276565b60015b60ff16935060019250611552565b8461101114156112c457612aab8861ffff161061122f57618e398861ffff16106112275761d5558861ffff16106112bc5760036112bf565b60025b61122a565b8461110114156112fc57612aab8861ffff161061122f576171c78861ffff16106112275761d5558861ffff16106112bc5760036112bf565b84612001141561133457612aab8861ffff161061122f5761638e8861ffff16106112275761aaab8861ffff16106112bc5760036112bf565b84611002141561136c576155558861ffff161061122f57619c728861ffff16106112275761d5558861ffff16106112bc5760036112bf565b846120101415611397576138e48861ffff161061127357618e398861ffff161061126b57600361126e565b8461020114156113c2576138e48861ffff161061122f57618e398861ffff161061122757600261122a565b8461010214156113ed576171c78861ffff161061122f5761c71c8861ffff161061122757600261122a565b846110201415611418576171c78861ffff16106112735761c71c8861ffff161061126b57600361126e565b84601214156114355761aaab8861ffff161061122f576001611232565b846021141561145f5761aaab8861ffff1610611452576000611232565b6001935060009250611552565b84610120141561147d5761aaab8861ffff1610611273576002611276565b8461021014156114a85761aaab8861ffff161061149b576001611276565b6002935060019250611552565b8461120014156114d75761aaab8861ffff16106114c65760036114c9565b60025b60ff16935060029250611552565b8461210014156115025761aaab8861ffff16106114f55760026114c9565b6003935060029250611552565b6040805160e560020a62461bcd02815260206004820152601660248201527f696e76616c696420726172697479207061747465726e00000000000000000000604482015290519081900360640190fd5b82840391508160031415611569575061d999611593565b816002141561157b575061e3d7611593565b816001141561158d575061f333611593565b50620100005b929a92995091975050505050505050565b600354600067ffffffffffffffff90911611611630576040805160e560020a62461bcd02815260206004820152602260248201527f747279696e6720746f20706f7046757365282920616e20656d7074792073746160448201527f636b000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003805467ffffffffffffffff19811667ffffffffffffffff918216600019018216179182905516151561167c57600380546fffffffffffffffff0000000000000000191690556116b9565b60038054600167ffffffffffffffff6801000000000000000080840482169290920116026fffffffffffffffff0000000000000000199091161790555b565b600160a060020a03811615156116d057600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a72305820486c90195f2979389a78a2a404b2db9e435cd5ce41911504211c1a5463a0cd910029
Deployed Bytecode
0x6080604052600436106100a05763ffffffff60e060020a6000350416633f4ba83a81146100a55780635c975abb146100bc5780635faa6b23146100e55780635fd8c710146100fd5780636040e91814610112578063715018a61461012f5780638456cb59146101445780638b289879146101595780638da5cb5b14610180578063b23d4854146101b1578063d26920cf146101d2578063f2fde38b146101e7575b600080fd5b3480156100b157600080fd5b506100ba610208565b005b3480156100c857600080fd5b506100d161027e565b604080519115158252519081900360200190f35b3480156100f157600080fd5b506100ba60043561028e565b34801561010957600080fd5b506100ba6102aa565b6100ba63ffffffff600435811690602435811690604435166102ff565b34801561013b57600080fd5b506100ba610838565b34801561015057600080fd5b506100ba6108a4565b34801561016557600080fd5b5061016e61091f565b60408051918252519081900360200190f35b34801561018c57600080fd5b5061019561092f565b60408051600160a060020a039092168252519081900360200190f35b3480156101bd57600080fd5b506100ba600160a060020a036004351661093e565b3480156101de57600080fd5b506100ba610984565b3480156101f357600080fd5b506100ba600160a060020a0360043516610ea6565b600054600160a060020a0316331461021f57600080fd5b60005460a060020a900460ff16151561023757600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a1565b60005460a060020a900460ff1681565b600054600160a060020a031633146102a557600080fd5b600455565b600054600160a060020a031633146102c157600080fd5b60008054604051600160a060020a0390911691303180156108fc02929091818181858888f193505050501580156102fc573d6000803e3d6000fd5b50565b600080600080600080600080600080600060149054906101000a900460ff1615151561032a57600080fd5b60045434146103a9576040805160e560020a62461bcd02815260206004820152602360248201527f507269636520646f65736e74206d617463682074686520616d6f756e7420706160448201527f7965640000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160009054906101000a9004600160a060020a0316600160a060020a0316632a0deab48e8e8e60006040518563ffffffff1660e060020a028152600401808563ffffffff1681526020018463ffffffff1681526020018363ffffffff16815260200182815260200194505050505060c060405180830381600087803b15801561043257600080fd5b505af1158015610446573d6000803e3d6000fd5b505050506040513d60c081101561045c57600080fd5b508051602082015160408301516060840151608085015160a090950151909e50939c50929a509098509650945033600160a060020a038b16146104e9576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b33600160a060020a038a1614610549576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b33600160a060020a038916146105a9576040805160e560020a62461bcd02815260206004820152600d60248201527f6e6f7420746865206f776e657200000000000000000000000000000000000000604482015290519081900360640190fd5b600660ff60f860020a890416049350600660ff60f860020a880416049250600660ff60f860020a87041604915082841480156105e457508184145b151561063a576040805160e560020a62461bcd02815260206004820152601660248201527f63617465676f7269657320646f6e2774206d6174636800000000000000000000604482015290519081900360640190fd5b50600f60f460020a80880482169190870416811480156106625750600f60f460020a86041681145b15156106b8576040805160e560020a62461bcd02815260206004820152601160248201527f746965727320646f6e2774206d61746368000000000000000000000000000000604482015290519081900360640190fd5b6002811115610711576040805160e560020a62461bcd02815260206004820152601560248201527f3420697320746865206d6178696d756d20746965720000000000000000000000604482015290519081900360640190fd5b600160009054906101000a9004600160a060020a0316600160a060020a0316639d248e088e8e8e6040518463ffffffff1660e060020a028152600401808463ffffffff1681526020018363ffffffff1681526020018263ffffffff1681526020019350505050600060405180830381600087803b15801561079157600080fd5b505af11580156107a5573d6000803e3d6000fd5b505050506107b48d8d8d610ec6565b7fe33e955549546adee4b93a8eccb1f9b2b0192b7d7539481fd55cced9657664d78d8d8d600454604051808563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff16815260200182815260200194505050505060405180910390a150505050505050505050505050565b600054600160a060020a0316331461084f57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146108bb57600080fd5b60005460a060020a900460ff16156108d257600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a1565b60035467ffffffffffffffff1690565b600054600160a060020a031681565b600054600160a060020a0316331461095557600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b61098c611738565b600080600080600080600080600080600060149054906101000a900460ff161515156109b757600080fd5b600354600067ffffffffffffffff90911611610a1d576040805160e560020a62461bcd02815260206004820152600f60248201527f6e6f7468696e6720746f20667573650000000000000000000000000000000000604482015290519081900360640190fd5b610a25611045565b9a50438b6080015165ffffffffffff16101515610a8c576040805160e560020a62461bcd02815260206004820152601d60248201527f43616e27742066757365206f6e207468652073616d6520626c6f636b2e000000604482015290519081900360640190fd5b610aa18b6080015165ffffffffffff166110ee565b604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b60208310610aef5780518252601f199092019160209182019101610ad0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600190049950600160009054906101000a9004600160a060020a0316600160a060020a03166397306c278c602001518d604001518e6060015160006040518563ffffffff1660e060020a028152600401808563ffffffff1681526020018463ffffffff1681526020018363ffffffff168152602001828152602001945050505050606060405180830381600087803b158015610bb757600080fd5b505af1158015610bcb573d6000803e3d6000fd5b505050506040513d6060811015610be157600080fd5b5080516020820151604090920151909a50909850965060f860020a808a0460ff160260f460020a808b04600f166001010217955060dc610c228a8a8a611102565b9060020a0286179550610c378989898d611157565b62010000909b049a60ff7a010000000000000000000000000000000000000000000000000000808d048216027b01000000000000000000000000000000000000000000000000000000840299909917989098179791965094506000935060f860020a808b0482168102818b04909216021415610cb4576001909201915b60f860020a808a0460ff9081168202828a04919091169091021415610cda576001909201915b8260011415610cf4576201000061ee148502049350610d08565b821515610d08576201000061e14785020493505b600091505b6012821015610d67576008820260c803640300000000600282900a808c0460ff908116828d04821601918b041601860261f8006103ff8e160102610400909c049b60029290920a9104029590951794600190910190610d0d565b6001548b51604080517f6b3559e1000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152602481018a905290519190921691636b3559e19160448083019260209291908290030181600087803b158015610dd857600080fd5b505af1158015610dec573d6000803e3d6000fd5b505050506040513d6020811015610e0257600080fd5b50519050610e0e6115a4565b7f5f35a68372238cec24e46cdac2c0a92c09ef335507a551c86e345128ee18af0a8b602001518c604001518d6060015184604051808563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15050505050505050505050565b600054600160a060020a03163314610ebd57600080fd5b6102fc816116bb565b6040805160a08101825233815263ffffffff94851660208083019182529486168284019081529386166060830190815265ffffffffffff438116608085019081526003805468010000000000000000810467ffffffffffffffff90811691811691909101811660009081526002909a5296909820945185549451975193518a1660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff948b167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff99909b1660a060020a0277ffffffff000000000000000000000000000000000000000019600160a060020a039390931673ffffffffffffffffffffffffffffffffffffffff199097169690961791909116949094179690961697909717161781559151600192830180549190951665ffffffffffff1990911617909355815480841690910190921667ffffffffffffffff19909216919091179055565b61104d611738565b5060035467ffffffffffffffff6801000000000000000090910416600090815260026020908152604091829020825160a0810184528154600160a060020a038116825263ffffffff60a060020a82048116948301949094527801000000000000000000000000000000000000000000000000810484169482019490945260e060020a90930490911660608301526001015465ffffffffffff16608082015290565b610100600019438390030181900402014090565b600062ffffff7b1000000000000000000000000000000000000000000000000000000080860482169181860481169185041682821015611140578192505b8281101561114c578092505b509095945050505050565b6000807b01000000000000000000000000000000000000000000000000000000808704600f9081166004908102600290810a848a0484168302820a019388049290921602900a018180808060038514156111b8576000935060009250611552565b84603014156111ce576001935060019250611552565b8461030014156111e5576002935060029250611552565b8461300014156111fc576003935060039250611552565b846101111415611240576155558861ffff161061122f5761aaab8861ffff161061122757600261122a565b60015b611232565b60005b60ff16935060009250611552565b846111101415611284576155558861ffff16106112735761aaab8861ffff161061126b57600361126e565b60025b611276565b60015b60ff16935060019250611552565b8461101114156112c457612aab8861ffff161061122f57618e398861ffff16106112275761d5558861ffff16106112bc5760036112bf565b60025b61122a565b8461110114156112fc57612aab8861ffff161061122f576171c78861ffff16106112275761d5558861ffff16106112bc5760036112bf565b84612001141561133457612aab8861ffff161061122f5761638e8861ffff16106112275761aaab8861ffff16106112bc5760036112bf565b84611002141561136c576155558861ffff161061122f57619c728861ffff16106112275761d5558861ffff16106112bc5760036112bf565b846120101415611397576138e48861ffff161061127357618e398861ffff161061126b57600361126e565b8461020114156113c2576138e48861ffff161061122f57618e398861ffff161061122757600261122a565b8461010214156113ed576171c78861ffff161061122f5761c71c8861ffff161061122757600261122a565b846110201415611418576171c78861ffff16106112735761c71c8861ffff161061126b57600361126e565b84601214156114355761aaab8861ffff161061122f576001611232565b846021141561145f5761aaab8861ffff1610611452576000611232565b6001935060009250611552565b84610120141561147d5761aaab8861ffff1610611273576002611276565b8461021014156114a85761aaab8861ffff161061149b576001611276565b6002935060019250611552565b8461120014156114d75761aaab8861ffff16106114c65760036114c9565b60025b60ff16935060029250611552565b8461210014156115025761aaab8861ffff16106114f55760026114c9565b6003935060029250611552565b6040805160e560020a62461bcd02815260206004820152601660248201527f696e76616c696420726172697479207061747465726e00000000000000000000604482015290519081900360640190fd5b82840391508160031415611569575061d999611593565b816002141561157b575061e3d7611593565b816001141561158d575061f333611593565b50620100005b929a92995091975050505050505050565b600354600067ffffffffffffffff90911611611630576040805160e560020a62461bcd02815260206004820152602260248201527f747279696e6720746f20706f7046757365282920616e20656d7074792073746160448201527f636b000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003805467ffffffffffffffff19811667ffffffffffffffff918216600019018216179182905516151561167c57600380546fffffffffffffffff0000000000000000191690556116b9565b60038054600167ffffffffffffffff6801000000000000000080840482169290920116026fffffffffffffffff0000000000000000199091161790555b565b600160a060020a03811615156116d057600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a72305820486c90195f2979389a78a2a404b2db9e435cd5ce41911504211c1a5463a0cd910029
Swarm Source
bzzr://486c90195f2979389a78a2a404b2db9e435cd5ce41911504211c1a5463a0cd91
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,656.98 | 0.1 | $265.7 |
Loading...
Loading
[ Download: CSV Export ]
[ 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.