Overview
TokenID
302
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
RadiCards
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-01-29 */ pragma solidity ^0.4.24; // File: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/access/rbac/Roles.sol /** * @title Roles * @author Francisco Giordano (@frangio) * @dev Library for managing addresses assigned to a Role. * See RBAC.sol for example usage. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev give an address access to this role */ function add(Role storage _role, address _addr) internal { _role.bearer[_addr] = true; } /** * @dev remove an address' access to this role */ function remove(Role storage _role, address _addr) internal { _role.bearer[_addr] = false; } /** * @dev check if an address has this role * // reverts */ function check(Role storage _role, address _addr) internal view { require(has(_role, _addr)); } /** * @dev check if an address has this role * @return bool */ function has(Role storage _role, address _addr) internal view returns (bool) { return _role.bearer[_addr]; } } // File: openzeppelin-solidity/contracts/access/rbac/RBAC.sol /** * @title RBAC (Role-Based Access Control) * @author Matt Condon (@Shrugs) * @dev Stores and provides setters and getters for roles and addresses. * Supports unlimited numbers of roles and addresses. * See //contracts/mocks/RBACMock.sol for an example of usage. * This RBAC method uses strings to key roles. It may be beneficial * for you to write your own implementation of this interface using Enums or similar. */ contract RBAC { using Roles for Roles.Role; mapping (string => Roles.Role) private roles; event RoleAdded(address indexed operator, string role); event RoleRemoved(address indexed operator, string role); /** * @dev reverts if addr does not have role * @param _operator address * @param _role the name of the role * // reverts */ function checkRole(address _operator, string _role) public view { roles[_role].check(_operator); } /** * @dev determine if addr has role * @param _operator address * @param _role the name of the role * @return bool */ function hasRole(address _operator, string _role) public view returns (bool) { return roles[_role].has(_operator); } /** * @dev add a role to an address * @param _operator address * @param _role the name of the role */ function addRole(address _operator, string _role) internal { roles[_role].add(_operator); emit RoleAdded(_operator, _role); } /** * @dev remove a role from an address * @param _operator address * @param _role the name of the role */ function removeRole(address _operator, string _role) internal { roles[_role].remove(_operator); emit RoleRemoved(_operator, _role); } /** * @dev modifier to scope access to a single role (uses msg.sender as addr) * @param _role the name of the role * // reverts */ modifier onlyRole(string _role) { checkRole(msg.sender, _role); _; } /** * @dev modifier to scope access to a set of roles (uses msg.sender as addr) * @param _roles the names of the roles to scope access to * // reverts * * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this * see: https://github.com/ethereum/solidity/issues/2467 */ // modifier onlyRoles(string[] _roles) { // bool hasAnyRole = false; // for (uint8 i = 0; i < _roles.length; i++) { // if (hasRole(msg.sender, _roles[i])) { // hasAnyRole = true; // break; // } // } // require(hasAnyRole); // _; // } } // File: openzeppelin-solidity/contracts/access/Whitelist.sol /** * @title Whitelist * @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions. * This simplifies the implementation of "user permissions". */ contract Whitelist is Ownable, RBAC { string public constant ROLE_WHITELISTED = "whitelist"; /** * @dev Throws if operator is not whitelisted. * @param _operator address */ modifier onlyIfWhitelisted(address _operator) { checkRole(_operator, ROLE_WHITELISTED); _; } /** * @dev add an address to the whitelist * @param _operator address * @return true if the address was added to the whitelist, false if the address was already in the whitelist */ function addAddressToWhitelist(address _operator) public onlyOwner { addRole(_operator, ROLE_WHITELISTED); } /** * @dev getter to determine if address is in whitelist */ function whitelist(address _operator) public view returns (bool) { return hasRole(_operator, ROLE_WHITELISTED); } /** * @dev add addresses to the whitelist * @param _operators addresses * @return true if at least one address was added to the whitelist, * false if all addresses were already in the whitelist */ function addAddressesToWhitelist(address[] _operators) public onlyOwner { for (uint256 i = 0; i < _operators.length; i++) { addAddressToWhitelist(_operators[i]); } } /** * @dev remove an address from the whitelist * @param _operator address * @return true if the address was removed from the whitelist, * false if the address wasn't in the whitelist in the first place */ function removeAddressFromWhitelist(address _operator) public onlyOwner { removeRole(_operator, ROLE_WHITELISTED); } /** * @dev remove addresses from the whitelist * @param _operators addresses * @return true if at least one address was removed from the whitelist, * false if all addresses weren't in the whitelist in the first place */ function removeAddressesFromWhitelist(address[] _operators) public onlyOwner { for (uint256 i = 0; i < _operators.length; i++) { removeAddressFromWhitelist(_operators[i]); } } } // File: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/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 { bytes4 internal 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 internal constant InterfaceId_ERC721Exists = 0x4f558e79; /* * 0x4f558e79 === * bytes4(keccak256('exists(uint256)')) */ bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63; /** * 0x780e9d63 === * bytes4(keccak256('totalSupply()')) ^ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ * bytes4(keccak256('tokenByIndex(uint256)')) */ bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f; /** * 0x5b5e139f === * bytes4(keccak256('name()')) ^ * bytes4(keccak256('symbol()')) ^ * bytes4(keccak256('tokenURI(uint256)')) */ 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: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/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 transferred * @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: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/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: openzeppelin-solidity/contracts/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 { 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; 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 { require(isApprovedOrOwner(msg.sender, _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 { // 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 { 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: openzeppelin-solidity/contracts/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 { // 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); // To prevent a gap in the array, we store the last token in the index of the token to delete, and // then delete the last slot. uint256 tokenIndex = ownedTokensIndex[_tokenId]; uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); uint256 lastToken = ownedTokens[_from][lastTokenIndex]; ownedTokens[_from][tokenIndex] = lastToken; // This also deletes the contents at the last position of the array ownedTokens[_from].length--; // 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 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: openzeppelin-solidity/contracts/token/ERC721/ERC721Holder.sol contract ERC721Holder is ERC721Receiver { function onERC721Received( address, address, uint256, bytes ) public returns(bytes4) { return ERC721_RECEIVED; } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * See https://github.com/ethereum/EIPs/issues/179 */ contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address _who) public view returns (uint256); function transfer(address _to, uint256 _value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } // File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol /** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */ contract BasicToken is ERC20Basic { using SafeMath for uint256; mapping(address => uint256) internal balances; uint256 internal totalSupply_; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return totalSupply_; } /** * @dev Transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public returns (bool) { require(_value <= balances[msg.sender]); require(_to != address(0)); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address _owner, address _spender) public view returns (uint256); function transferFrom(address _from, address _to, uint256 _value) public returns (bool); function approve(address _spender, uint256 _value) public returns (bool); event Approval( address indexed owner, address indexed spender, uint256 value ); } // File: openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/issues/20 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is ERC20, BasicToken { mapping (address => mapping (address => uint256)) internal allowed; /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom( address _from, address _to, uint256 _value ) public returns (bool) { require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); require(_to != address(0)); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Transfer(_from, _to, _value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance( address _owner, address _spender ) public view returns (uint256) { return allowed[_owner][_spender]; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _addedValue The amount of tokens to increase the allowance by. */ function increaseApproval( address _spender, uint256 _addedValue ) public returns (bool) { allowed[msg.sender][_spender] = ( allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseApproval( address _spender, uint256 _subtractedValue ) public returns (bool) { uint256 oldValue = allowed[msg.sender][_spender]; if (_subtractedValue >= oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } } // File: contracts/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) internal pure returns (string) { return strConcat(_a, _b, "", "", ""); } } // File: contracts/Medianizer.sol // This is the original medianizer implementation used by MakerDAO. we use this // contract to fetch the latest ether price by calling the read() function. // public deployed instances of this contract can be found here: //1) kovan: https://kovan.etherscan.io/address/0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc#code //2) mainnet: https://etherscan.io/address/0x729D19f657BD0614b4985Cf1D82531c67569197B#readContract /// return median value of feeds // Copyright (C) 2017 DappHub, LLC // Licensed under the Apache License, Version 2.0 (the "License"). // You may not use this file except in compliance with the License. // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied). pragma solidity ^0.4.8; contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) constant returns (bool); } contract DSAuthEvents { event LogSetAuthority (address indexed authority); event LogSetOwner (address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; function DSAuth() { owner = msg.sender; LogSetOwner(msg.sender); } function setOwner(address owner_) auth { owner = owner_; LogSetOwner(owner); } function setAuthority(DSAuthority authority_) auth { authority = authority_; LogSetAuthority(authority); } modifier auth { assert(isAuthorized(msg.sender, msg.sig)); _; } modifier authorized(bytes4 sig) { assert(isAuthorized(msg.sender, sig)); _; } function isAuthorized(address src, bytes4 sig) internal returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, this, sig); } } function assert(bool x) internal { if (!x) throw; } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } contract DSMath { /* standard uint256 functions */ function add(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x + y) >= x); } function sub(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x - y) <= x); } function mul(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x * y) >= x); } function div(uint256 x, uint256 y) constant internal returns (uint256 z) { z = x / y; } function min(uint256 x, uint256 y) constant internal returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) constant internal returns (uint256 z) { return x >= y ? x : y; } /* uint128 functions (h is for half) */ function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x + y) >= x); } function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x - y) <= x); } function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x * y) >= x); } function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = x / y; } function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) { return x <= y ? x : y; } function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) { return x >= y ? x : y; } /* int256 functions */ function imin(int256 x, int256 y) constant internal returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) constant internal returns (int256 z) { return x >= y ? x : y; } /* WAD math */ uint128 constant WAD = 10 ** 18; function wadd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function wsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + WAD / 2) / WAD); } function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * WAD + y / 2) / y); } function wmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function wmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } /* RAY math */ uint128 constant RAY = 10 ** 27; function radd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function rsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + RAY / 2) / RAY); } function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * RAY + y / 2) / y); } function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) { // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } function rmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function rmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } function cast(uint256 x) constant internal returns (uint128 z) { assert((z = uint128(x)) == x); } } contract DSThing is DSAuth, DSNote, DSMath { } contract DSValue is DSThing { bool has; bytes32 val; function peek() constant returns (bytes32, bool) { return (val,has); } function read() constant returns (bytes32) { var (wut, has) = peek(); assert(has); return wut; } function poke(bytes32 wut) note auth { val = wut; has = true; } function void() note auth { // unset the value has = false; } } contract Medianizer is DSValue { mapping (bytes12 => address) public values; mapping (address => bytes12) public indexes; bytes12 public next = 0x1; uint96 public min = 0x1; function set(address wat) auth { bytes12 nextId = bytes12(uint96(next) + 1); assert(nextId != 0x0); set(next, wat); next = nextId; } function set(bytes12 pos, address wat) note auth { if (pos == 0x0) throw; if (wat != 0 && indexes[wat] != 0) throw; indexes[values[pos]] = 0; // Making sure to remove a possible existing address in that position if (wat != 0) { indexes[wat] = pos; } values[pos] = wat; } function setMin(uint96 min_) note auth { if (min_ == 0x0) throw; min = min_; } function setNext(bytes12 next_) note auth { if (next_ == 0x0) throw; next = next_; } function unset(bytes12 pos) { set(pos, 0); } function unset(address wat) { set(indexes[wat], 0); } function poke() { poke(0); } function poke(bytes32) note { (val, has) = compute(); } function compute() constant returns (bytes32, bool) { bytes32[] memory wuts = new bytes32[](uint96(next) - 1); uint96 ctr = 0; for (uint96 i = 1; i < uint96(next); i++) { if (values[bytes12(i)] != 0) { var (wut, wuz) = DSValue(values[bytes12(i)]).peek(); if (wuz) { if (ctr == 0 || wut >= wuts[ctr - 1]) { wuts[ctr] = wut; } else { uint96 j = 0; while (wut >= wuts[j]) { j++; } for (uint96 k = ctr; k > j; k--) { wuts[k] = wuts[k - 1]; } wuts[j] = wut; } ctr++; } } } if (ctr < min) return (val, false); bytes32 value; if (ctr % 2 == 0) { uint128 val1 = uint128(wuts[(ctr / 2) - 1]); uint128 val2 = uint128(wuts[ctr / 2]); value = bytes32(wdiv(hadd(val1, val2), 2 ether)); } else { value = wuts[(ctr - 1) / 2]; } return (value, true); } } // File: contracts/RadiCards.sol /** * @title Radi.Cards * This is the main Radi Cards NFT (ERC721) contract. It allows for the minting of * cards(NFTs) that can be sent to either a known EOA or to a claimable link. * ETH or DAI can be sent along with the card and the sender can choose a ratio * between a participating benefactor and the recipient, with no restriction. * Predefined cards can be added, with the artwork stored on IPFS. * The card message is stored within the smart contract. Cards can have a defined max * quantity that can be minted and a minimum purchase price. The claimable link sender * generates a public/private key pair that is used to take the NFT out of escrow (held within * this contract). The private key can then be sent to the recipient by email, * telergram, wechat ect. and is embedded within a URL to a claim page. When the user * opens the claim URL the private key is used to redeem the NFT and any associated gift (ETH/DAI). * @author blockrocket.tech (smart contracts) * @author cryptodecks.co * @author knownorigin.io * @author pheme.app * @author d1labs.com * @author mbdoesthings.com * @author chrismaree.io (smart contracts v2 update) */ contract RadiCards is ERC721Token, ERC721Holder, Whitelist { using SafeMath for uint256; // dai support StandardToken daiContract; Medianizer medianizerContract; string public tokenBaseURI = "https://ipfs.infura.io/ipfs/"; uint256 public tokenIdPointer = 0; struct Benefactor { address ethAddress; string name; string website; string logo; } struct CardDesign { string tokenURI; bool active; uint minted; uint maxQnty; //set to zero for unlimited //minimum price per card set in Atto (SI prefix for 1x10-18 dai) uint256 minPrice; //set to zero to default to the minimumContribution } // claimable link support enum Statuses { Empty, Deposited, Claimed, Cancelled } uint256 public EPHEMERAL_ADDRESS_FEE = 0.01 ether; mapping(address => uint256) public ephemeralWalletCards; // ephemeral wallet => tokenId struct RadiCard { address gifter; string message; bool daiDonation; uint256 giftAmount; uint256 donationAmount; Statuses status; uint256 cardIndex; uint256 benefactorIndex; } mapping(uint256 => Benefactor) public benefactors; uint256[] internal benefactorsIndex; mapping(uint256 => CardDesign) public cards; uint256[] internal cardsIndex; mapping(uint256 => RadiCard) public tokenIdToRadiCardIndex; //total gifted/donated in ETH uint256 public totalGiftedInWei; uint256 public totalDonatedInWei; //total gifted/donated in DAI uint256 public totalGiftedInAtto; //SI prefix for 1x10-18 dai is Atto. uint256 public totalDonatedInAtto; event CardGifted( address indexed _to, uint256 indexed _benefactorIndex, uint256 indexed _cardIndex, address _from, uint256 _tokenId, bool daiDonation, uint256 giftAmount, uint256 donationAmount, Statuses status ); event LogClaimGift( address indexed ephemeralAddress, address indexed sender, uint tokenId, address receiver, uint giftAmount, bool daiDonation ); event LogCancelGift( address indexed ephemeralAddress, address indexed sender, uint tokenId ); event BenefactorAdded( uint256 indexed _benefactorIndex ); event CardAdded( uint256 indexed _cardIndex ); constructor () public ERC721Token("RadiCards", "RADI") { addAddressToWhitelist(msg.sender); } function gift(address _to, uint256 _benefactorIndex, uint256 _cardIndex, string _message, uint256 _donationAmount, uint256 _giftAmount, bool _claimableLink) payable public returns (bool) { require(_to != address(0), "Must be a valid address"); if(_donationAmount > 0){ require(benefactors[_benefactorIndex].ethAddress != address(0), "Must specify existing benefactor"); } require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card"); require(cards[_cardIndex].active, "Must be an active card"); Statuses _giftStatus; address _sentToAddress; if(_claimableLink){ require(_donationAmount + _giftAmount + EPHEMERAL_ADDRESS_FEE == msg.value, "Can only request to donate and gift the amount of ether sent + Ephemeral fee"); _giftStatus = Statuses.Deposited; _sentToAddress = this; ephemeralWalletCards[_to] = tokenIdPointer; _to.transfer(EPHEMERAL_ADDRESS_FEE); } else { require(_donationAmount + _giftAmount == msg.value,"Can only request to donate and gift the amount of ether sent"); _giftStatus = Statuses.Claimed; _sentToAddress = _to; } if (cards[_cardIndex].maxQnty > 0){ //the max quantity is set to zero to indicate no limit. Only need to check that can mint if limited require(cards[_cardIndex].minted < cards[_cardIndex].maxQnty, "Can't exceed maximum quantity of card type"); } if(cards[_cardIndex].minPrice > 0){ //if the card has a minimum price check that enough has been sent // Convert the current value of the eth send to a USD value of atto (1 usd = 10^18 atto). // require(getEthUsdValue(msg.value) >= (cards[_cardIndex].minPrice), "Must send at least the minimum amount"); require (getMinCardPriceInWei(_cardIndex) <= msg.value,"Must send at least the minimum amount to buy card"); } tokenIdToRadiCardIndex[tokenIdPointer] = RadiCard({ gifter: msg.sender, message: _message, daiDonation: false, giftAmount: _giftAmount, donationAmount: _donationAmount, status: _giftStatus, cardIndex: _cardIndex, benefactorIndex: _benefactorIndex }); // Card is minted to the _sentToAddress. This is either this radicards contract(if claimableLink==true) // and the creator chose to use the escrow for a claimable link or to the recipient EOA directly uint256 _tokenId = _mint(_sentToAddress, cards[_cardIndex].tokenURI); cards[_cardIndex].minted++; // transfer the ETH to the benefactor if(_donationAmount > 0){ benefactors[_benefactorIndex].ethAddress.transfer(_donationAmount); totalDonatedInWei = totalDonatedInWei.add(_donationAmount); } // transfer gift to recipient. if(_giftAmount > 0){ totalGiftedInWei = totalGiftedInWei.add(_giftAmount); // note that we only do the transfer if the link is not claimable as if it is the eth sits in escrow within this contract if(!_claimableLink){ _sentToAddress.transfer(_giftAmount); } } emit CardGifted(_sentToAddress, _benefactorIndex, _cardIndex, msg.sender, _tokenId, false, _giftAmount, _donationAmount, _giftStatus); return true; } function giftInDai(address _to, uint256 _benefactorIndex, uint256 _cardIndex, string _message, uint256 _donationAmount, uint256 _giftAmount, bool _claimableLink) public payable returns (bool) { require(_to != address(0), "Must be a valid address"); if (_donationAmount > 0){ require(benefactors[_benefactorIndex].ethAddress != address(0), "Must specify existing benefactor"); } require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card"); require(cards[_cardIndex].active, "Must be an active card"); require((_donationAmount + _giftAmount) <= daiContract.allowance(msg.sender, this), "Must have provided high enough alowance to Radicard contract"); require((_donationAmount + _giftAmount) <= daiContract.balanceOf(msg.sender), "Must have enough token balance of dai to pay for donation and gift amount"); if (cards[_cardIndex].maxQnty > 0){ //the max quantity is set to zero to indicate no limit. Only need to check that can mint if limited require(cards[_cardIndex].minted < cards[_cardIndex].maxQnty, "Can't exceed maximum quantity of card type"); } if(cards[_cardIndex].minPrice > 0){ //if the card has a minimum price check that enough has been sent require((_donationAmount + _giftAmount) >= cards[_cardIndex].minPrice, "The total dai sent with the transaction is less than the min price of the token"); } //parameters that change based on the if the card is setup as with a claimable link Statuses _giftStatus; address _sentToAddress; if(_claimableLink){ require(msg.value == EPHEMERAL_ADDRESS_FEE, "A claimable link was generated but not enough ephemeral ether was sent!"); _giftStatus = Statuses.Deposited; _sentToAddress = this; // need to store the address of the ephemeral account and the card that it owns for claimable link functionality ephemeralWalletCards[_to] = tokenIdPointer; _to.transfer(EPHEMERAL_ADDRESS_FEE); } else { _giftStatus = Statuses.Claimed; _sentToAddress = _to; } tokenIdToRadiCardIndex[tokenIdPointer] = RadiCard({ gifter: msg.sender, message: _message, daiDonation: true, giftAmount: _giftAmount, donationAmount: _donationAmount, status: _giftStatus, cardIndex: _cardIndex, benefactorIndex: _benefactorIndex }); // Card is minted to the _sentToAddress. This is either this radicards contract(if claimableLink==true) // and the creator chose to use the escrow for a claimable link or to the recipient EOA directly uint256 _tokenId = _mint(_sentToAddress, cards[_cardIndex].tokenURI); cards[_cardIndex].minted++; // transfer the DAI to the benefactor if(_donationAmount > 0){ address _benefactorAddress = benefactors[_benefactorIndex].ethAddress; require(daiContract.transferFrom(msg.sender, _benefactorAddress, _donationAmount),"Sending to benefactor failed"); totalDonatedInAtto = totalDonatedInAtto.add(_donationAmount); } // transfer gift to recipient. note that this pattern is slightly different from the eth case as irrespective of // if it is a claimable link or not we preform the transaction. if it is indeed a claimable link the dai is sent // to the contract and held in escrow if(_giftAmount > 0){ require(daiContract.transferFrom(msg.sender, _sentToAddress, _giftAmount),"Sending to recipient failed"); totalGiftedInAtto = totalGiftedInAtto.add(_giftAmount); } emit CardGifted(_sentToAddress, _benefactorIndex, _cardIndex, msg.sender, _tokenId, true, _giftAmount, _donationAmount, _giftStatus); return true; } function _mint(address to, string tokenURI) internal returns (uint256 _tokenId) { uint256 tokenId = tokenIdPointer; super._mint(to, tokenId); _setTokenURI(tokenId, tokenURI); tokenIdPointer = tokenIdPointer.add(1); return tokenId; } function cancelGift(address _ephemeralAddress) public returns (bool) { uint256 tokenId = ephemeralWalletCards[_ephemeralAddress]; require(tokenId != 0, "Can only call this function on an address that was used as an ephemeral"); RadiCard storage card = tokenIdToRadiCardIndex[tokenId]; // is deposited and wasn't claimed or cancelled before require(card.status == Statuses.Deposited, "can only cancel gifts that are unclaimed (deposited)"); // only gifter can cancel transfer; require(msg.sender == card.gifter, "only the gifter of the card can cancel a gift"); // update status to cancelled card.status = Statuses.Cancelled; // transfer optional ether or dai back to creators address if (card.giftAmount > 0) { if(card.daiDonation){ require(daiContract.transfer(msg.sender, card.giftAmount),"Sending to recipient after cancel gift failed"); } else{ msg.sender.transfer(card.giftAmount); } } // send nft to buyer. for this we use a custom transfer function to take the nft out of escrow and // send it back to the buyer. transferFromEscrow(msg.sender, tokenId); // log cancel event emit LogCancelGift(_ephemeralAddress, msg.sender, tokenId); return true; } function claimGift(address _receiver) public returns (bool success) { // only holder of ephemeral private key can claim gift address _ephemeralAddress = msg.sender; uint256 tokenId = ephemeralWalletCards[_ephemeralAddress]; require(tokenId != 0, "The calling address does not have an ephemeral card associated with it"); RadiCard storage card = tokenIdToRadiCardIndex[tokenId]; // is deposited and wasn't claimed or cancelled before require(card.status == Statuses.Deposited, "Can only claim a gift that is unclaimed"); // update gift status to claimed card.status = Statuses.Claimed; // send nft to receiver transferFromEscrow(_receiver, tokenId); // transfer optional ether & dai to receiver's address if (card.giftAmount > 0) { if(card.daiDonation){ require(daiContract.transfer(_receiver, card.giftAmount),"Sending to recipient after cancel gift failed"); } else{ _receiver.transfer(card.giftAmount); } } // log claim event emit LogClaimGift( _ephemeralAddress, card.gifter, tokenId, _receiver, card.giftAmount, card.daiDonation ); return true; } function burn(uint256 _tokenId) public pure { revert("Radi.Cards are censorship resistant!"); } function tokenURI(uint256 _tokenId) public view returns (string) { require(exists(_tokenId), "token does not exist"); return Strings.strConcat(tokenBaseURI, tokenURIs[_tokenId]); } function tokenDetails(uint256 _tokenId) public view returns ( address _gifter, string _message, bool _daiDonation, uint256 _giftAmount, uint256 _donationAmount, Statuses status, uint256 _cardIndex, uint256 _benefactorIndex ) { require(exists(_tokenId), "token does not exist"); RadiCard memory _radiCard = tokenIdToRadiCardIndex[_tokenId]; return ( _radiCard.gifter, _radiCard.message, _radiCard.daiDonation, _radiCard.giftAmount, _radiCard.donationAmount, _radiCard.status, _radiCard.cardIndex, _radiCard.benefactorIndex ); } function tokenBenefactor(uint256 _tokenId) public view returns ( address _ethAddress, string _name, string _website, string _logo ) { require(exists(_tokenId),"Card must exist"); RadiCard memory _radiCard = tokenIdToRadiCardIndex[_tokenId]; Benefactor memory _benefactor = benefactors[_radiCard.benefactorIndex]; return ( _benefactor.ethAddress, _benefactor.name, _benefactor.website, _benefactor.logo ); } function tokensOf(address _owner) public view returns (uint256[] _tokenIds) { return ownedTokens[_owner]; } function benefactorsKeys() public view returns (uint256[] _keys) { return benefactorsIndex; } function cardsKeys() public view returns (uint256[] _keys) { return cardsIndex; } function addBenefactor(uint256 _benefactorIndex, address _ethAddress, string _name, string _website, string _logo) public onlyIfWhitelisted(msg.sender) returns (bool) { require(address(_ethAddress) != address(0), "Invalid address"); require(bytes(_name).length != 0, "Invalid name"); require(bytes(_website).length != 0, "Invalid name"); require(bytes(_logo).length != 0, "Invalid name"); benefactors[_benefactorIndex] = Benefactor( _ethAddress, _name, _website, _logo ); benefactorsIndex.push(_benefactorIndex); emit BenefactorAdded(_benefactorIndex); return true; } function addCard(uint256 _cardIndex, string _tokenURI, bool _active, uint256 _maxQnty, uint256 _minPrice) public onlyIfWhitelisted(msg.sender) returns (bool) { require(bytes(_tokenURI).length != 0, "Invalid token URI"); cards[_cardIndex] = CardDesign( _tokenURI, _active, 0, _maxQnty, _minPrice ); cardsIndex.push(_cardIndex); emit CardAdded(_cardIndex); return true; } function setTokenBaseURI(string _newBaseURI) external onlyIfWhitelisted(msg.sender) { require(bytes(_newBaseURI).length != 0, "Base URI invalid"); tokenBaseURI = _newBaseURI; } function setActive(uint256 _cardIndex, bool _active) external onlyIfWhitelisted(msg.sender) { require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card"); cards[_cardIndex].active = _active; } function setMaxQuantity(uint256 _cardIndex, uint256 _maxQnty) external onlyIfWhitelisted(msg.sender) { require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card"); require(cards[_cardIndex].minted <= _maxQnty, "Can't set the max quantity less than the current total minted"); cards[_cardIndex].maxQnty = _maxQnty; } function setMinPrice(uint256 _cardIndex, uint256 _minPrice) external onlyIfWhitelisted(msg.sender) { require(bytes(cards[_cardIndex].tokenURI).length != 0, "Must specify existing card"); cards[_cardIndex].minPrice = _minPrice; } function setDaiContractAddress(address _daiERC20ContractAddress) external onlyIfWhitelisted(msg.sender){ require(_daiERC20ContractAddress != address(0), "Must be a valid address"); daiContract = StandardToken(_daiERC20ContractAddress); } // sets the medianizer contract for the makerdao implementation used as a price oracle function setMedianizerContractAddress(address _MedianizerContractAddress) external onlyIfWhitelisted(msg.sender){ require(_MedianizerContractAddress != address(0), "Must be a valid address"); medianizerContract = Medianizer(_MedianizerContractAddress); } // returns the current ether price in usd. 18 decimal point precision used function getEtherPrice() public view returns(uint256){ return uint256(medianizerContract.read()); } // returns the value of ether in atto (1 usd of ether = 10^18 atto) function getEthUsdValue(uint256 _ether) public view returns(uint256){ return ((_ether*getEtherPrice())/(1 ether)); } // returns the minimum required in wei for a particular card given the card min price in dai function getMinCardPriceInWei(uint256 _cardIndex) public view returns(uint256){ return ((cards[_cardIndex].minPrice * 1 ether)/getEtherPrice()); } // transfer tokens held by this contract in escrow to the recipient. Used when either claiming or cancelling gifts function transferFromEscrow(address _recipient,uint256 _tokenId) internal{ require(super.ownerOf(_tokenId) == address(this),"The card must be owned by the contract for it to be in escrow"); super.clearApproval(this, _tokenId); super.removeTokenFrom(this, _tokenId); super.addTokenTo(_recipient, _tokenId); emit Transfer(this, _recipient, _tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"benefactorsKeys","outputs":[{"name":"_keys","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_daiERC20ContractAddress","type":"address"}],"name":"setDaiContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"}],"name":"claimGift","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenIdToRadiCardIndex","outputs":[{"name":"gifter","type":"address"},{"name":"message","type":"string"},{"name":"daiDonation","type":"bool"},{"name":"giftAmount","type":"uint256"},{"name":"donationAmount","type":"uint256"},{"name":"status","type":"uint8"},{"name":"cardIndex","type":"uint256"},{"name":"benefactorIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"},{"name":"_role","type":"string"}],"name":"checkRole","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"benefactors","outputs":[{"name":"ethAddress","type":"address"},{"name":"name","type":"string"},{"name":"website","type":"string"},{"name":"logo","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROLE_WHITELISTED","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenBenefactor","outputs":[{"name":"_ethAddress","type":"address"},{"name":"_name","type":"string"},{"name":"_website","type":"string"},{"name":"_logo","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"},{"name":"_role","type":"string"}],"name":"hasRole","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operators","type":"address[]"}],"name":"removeAddressesFromWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_ephemeralAddress","type":"address"}],"name":"cancelGift","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"}],"name":"removeAddressFromWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_benefactorIndex","type":"uint256"},{"name":"_ethAddress","type":"address"},{"name":"_name","type":"string"},{"name":"_website","type":"string"},{"name":"_logo","type":"string"}],"name":"addBenefactor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenIdPointer","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_tokenURI","type":"string"},{"name":"_active","type":"bool"},{"name":"_maxQnty","type":"uint256"},{"name":"_minPrice","type":"uint256"}],"name":"addCard","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalGiftedInAtto","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"EPHEMERAL_ADDRESS_FEE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ether","type":"uint256"}],"name":"getEthUsdValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_minPrice","type":"uint256"}],"name":"setMinPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenBaseURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOf","outputs":[{"name":"_tokenIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_maxQnty","type":"uint256"}],"name":"setMaxQuantity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardIndex","type":"uint256"}],"name":"getMinCardPriceInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"}],"name":"addAddressToWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"ephemeralWalletCards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_MedianizerContractAddress","type":"address"}],"name":"setMedianizerContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"cards","outputs":[{"name":"tokenURI","type":"string"},{"name":"active","type":"bool"},{"name":"minted","type":"uint256"},{"name":"maxQnty","type":"uint256"},{"name":"minPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newBaseURI","type":"string"}],"name":"setTokenBaseURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalDonatedInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_operator","type":"address"}],"name":"whitelist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_benefactorIndex","type":"uint256"},{"name":"_cardIndex","type":"uint256"},{"name":"_message","type":"string"},{"name":"_donationAmount","type":"uint256"},{"name":"_giftAmount","type":"uint256"},{"name":"_claimableLink","type":"bool"}],"name":"giftInDai","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_benefactorIndex","type":"uint256"},{"name":"_cardIndex","type":"uint256"},{"name":"_message","type":"string"},{"name":"_donationAmount","type":"uint256"},{"name":"_giftAmount","type":"uint256"},{"name":"_claimableLink","type":"bool"}],"name":"gift","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEtherPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operators","type":"address[]"}],"name":"addAddressesToWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardIndex","type":"uint256"},{"name":"_active","type":"bool"}],"name":"setActive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalDonatedInAtto","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cardsKeys","outputs":[{"name":"_keys","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalGiftedInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenDetails","outputs":[{"name":"_gifter","type":"address"},{"name":"_message","type":"string"},{"name":"_daiDonation","type":"bool"},{"name":"_giftAmount","type":"uint256"},{"name":"_donationAmount","type":"uint256"},{"name":"status","type":"uint8"},{"name":"_cardIndex","type":"uint256"},{"name":"_benefactorIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_benefactorIndex","type":"uint256"},{"indexed":true,"name":"_cardIndex","type":"uint256"},{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"daiDonation","type":"bool"},{"indexed":false,"name":"giftAmount","type":"uint256"},{"indexed":false,"name":"donationAmount","type":"uint256"},{"indexed":false,"name":"status","type":"uint8"}],"name":"CardGifted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ephemeralAddress","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"receiver","type":"address"},{"indexed":false,"name":"giftAmount","type":"uint256"},{"indexed":false,"name":"daiDonation","type":"bool"}],"name":"LogClaimGift","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ephemeralAddress","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"LogCancelGift","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_benefactorIndex","type":"uint256"}],"name":"BenefactorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_cardIndex","type":"uint256"}],"name":"CardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"role","type":"string"}],"name":"RoleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"role","type":"string"}],"name":"RoleRemoved","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"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]
Contract Creation Code
60c0604052601c60808190527f68747470733a2f2f697066732e696e667572612e696f2f697066732f0000000060a09081526200004091601091906200044c565b506000601155662386f26fc100006012553480156200005e57600080fd5b50604080518082018252600981527f52616469436172647300000000000000000000000000000000000000000000006020808301919091528251808401909352600483527f52414449000000000000000000000000000000000000000000000000000000009083015290620000fc7f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001307f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001647f4f558e790000000000000000000000000000000000000000000000000000000064010000000062000229810204565b8151620001799060059060208501906200044c565b5080516200018f9060069060208401906200044c565b50620001c47f780e9d630000000000000000000000000000000000000000000000000000000064010000000062000229810204565b620001f87f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000229810204565b5050600c8054600160a060020a03191633908117909155620002239064010000000062000296810204565b620004f1565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200025957600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b600c54600160a060020a03163314620002ae57600080fd5b620002fe816040805190810160405280600981526020017f77686974656c697374000000000000000000000000000000000000000000000081525062000301640100000000026401000000009004565b50565b6200037d82600d836040518082805190602001908083835b602083106200033a5780518252601f19909201916020918201910162000319565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220929150506401000000006200042781026200527d1704565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b700489826040518080602001828103825283818151815260200191508051906020019080838360005b83811015620003e8578181015183820152602001620003ce565b50505050905090810190601f168015620004165780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200048f57805160ff1916838001178555620004bf565b82800160010185558215620004bf579182015b82811115620004bf578251825591602001919060010190620004a2565b50620004cd929150620004d1565b5090565b620004ee91905b80821115620004cd5760008155600101620004d8565b90565b61584a80620005016000396000f3006080604052600436106102df5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a781146102e457806303cfe12d1461032f578063040e0d311461039457806304f3c40e146103b757806306fdde03146103d85780630701fd6b14610462578063081812fc14610547578063095ea7b31461057b5780630988ca8c1461059f578063128ee16114610606578063150b7a021461077b57806318160ddd1461081c57806318b919e91461084357806319fa8f50146108585780631db1b4fd1461086d578063217fe6c61461088557806323b872dd146108ec57806324953eaa14610916578063254e6f261461096b578063286dd3f51461098c5780632f745c59146109ad57806337073a87146109d15780633b3a1a7a14610ab65780633bac8f9014610acb5780633eeb8d1714610b3657806342842e0e14610b4b57806342966c6814610b755780634b745f9014610b8d5780634d02fef714610ba25780634d7bb88114610bba5780634e99b80014610bd55780634f558e7914610bea5780634f6ccce714610c025780635a3f267214610c1a5780636352211e14610c3b57806370a0823114610c53578063715018a614610c74578063757000f714610c89578063757f015514610ca45780637b9417c814610cbc57806388f0e36414610cdd57806389ae3b1f14610cfe5780638da5cb5b14610d1f5780638dc1076814610d345780638ef79e9114610de457806395d89b4114610e045780639b10acdc14610e195780639b19251a14610e2e578063a10b79bc14610e4f578063a22cb46514610ebd578063b88d4fde14610ee3578063c28ae87614610f52578063c87b56dd14610fc0578063ca7c4dba14610fd8578063e2ec6ec314610fed578063e60a955d14611042578063e7ac2a521461105f578063e985e9c514611074578063f2fde38b1461109b578063f7ad51ce146110bc578063f9256de1146110d1578063fc314e31146110e6575b600080fd5b3480156102f057600080fd5b5061031b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19600435166110fe565b604080519115158252519081900360200190f35b34801561033b57600080fd5b50610344611132565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610380578181015183820152602001610368565b505050509050019250505060405180910390f35b3480156103a057600080fd5b506103b5600160a060020a036004351661118b565b005b3480156103c357600080fd5b5061031b600160a060020a0360043516611249565b3480156103e457600080fd5b506103ed6115a3565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046e57600080fd5b5061047a600435611630565b6040518089600160a060020a0316600160a060020a0316815260200180602001881515151581526020018781526020018681526020018560038111156104bc57fe5b60ff168152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b838110156105055781810151838201526020016104ed565b50505050905090810190601f1680156105325780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b34801561055357600080fd5b5061055f60043561170f565b60408051600160a060020a039092168252519081900360200190f35b34801561058757600080fd5b506103b5600160a060020a036004351660243561172a565b3480156105ab57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526103b5958335600160a060020a03169536956044949193909101919081908401838280828437509497506117e09650505050505050565b34801561061257600080fd5b5061061e60043561184e565b6040518085600160a060020a0316600160a060020a03168152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561067b578181015183820152602001610663565b50505050905090810190601f1680156106a85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156106db5781810151838201526020016106c3565b50505050905090810190601f1680156107085780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561073b578181015183820152602001610723565b50505050905090810190601f1680156107685780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34801561078757600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526107ea94600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750611a249650505050505050565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199092168252519081900360200190f35b34801561082857600080fd5b50610831611a4d565b60408051918252519081900360200190f35b34801561084f57600080fd5b506103ed611a53565b34801561086457600080fd5b506107ea611a78565b34801561087957600080fd5b5061061e600435611a9c565b34801561089157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e419650505050505050565b3480156108f857600080fd5b506103b5600160a060020a0360043581169060243516604435611eb4565b34801561092257600080fd5b50604080516020600480358082013583810280860185019096528085526103b595369593946024949385019291829185019084908082843750949750611f579650505050505050565b34801561097757600080fd5b5061031b600160a060020a0360043516611fa6565b34801561099857600080fd5b506103b5600160a060020a0360043516612358565b3480156109b957600080fd5b50610831600160a060020a036004351660243561239f565b3480156109dd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261031b9482359460248035600160a060020a03169536959460649492019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506123ec9650505050505050565b348015610ac257600080fd5b5061083161269d565b348015610ad757600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b9583359536956044949193909101919081908401838280828437509497505050508235151593505050602081013590604001356126a3565b348015610b4257600080fd5b50610831612822565b348015610b5757600080fd5b506103b5600160a060020a0360043581169060243516604435612828565b348015610b8157600080fd5b506103b5600435612849565b348015610b9957600080fd5b506108316128be565b348015610bae57600080fd5b506108316004356128c4565b348015610bc657600080fd5b506103b56004356024356128e9565b348015610be157600080fd5b506103ed6129a5565b348015610bf657600080fd5b5061031b600435612a33565b348015610c0e57600080fd5b50610831600435612a50565b348015610c2657600080fd5b50610344600160a060020a0360043516612a85565b348015610c4757600080fd5b5061055f600435612af1565b348015610c5f57600080fd5b50610831600160a060020a0360043516612b1b565b348015610c8057600080fd5b506103b5612b4e565b348015610c9557600080fd5b506103b5600435602435612bbc565b348015610cb057600080fd5b50610831600435612d07565b348015610cc857600080fd5b506103b5600160a060020a0360043516612d36565b348015610ce957600080fd5b50610831600160a060020a0360043516612d7a565b348015610d0a57600080fd5b506103b5600160a060020a0360043516612d8c565b348015610d2b57600080fd5b5061055f612e4a565b348015610d4057600080fd5b50610d4c600435612e59565b604051808060200186151515158152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b83811015610da5578181015183820152602001610d8d565b50505050905090810190601f168015610dd25780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610df057600080fd5b506103b56004803560248101910135612f17565b348015610e1057600080fd5b506103ed612fae565b348015610e2557600080fd5b5061083161300f565b348015610e3a57600080fd5b5061031b600160a060020a0360043516613015565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a0381351694602480359560443595369560849493019181908401838280828437509497505084359550505060208301359260400135151591506130449050565b348015610ec957600080fd5b506103b5600160a060020a03600435166024351515613b8d565b348015610eef57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526103b594600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750613c119650505050505050565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a038135169460248035956044359536956084949301918190840183828082843750949750508435955050506020830135926040013515159150613c339050565b348015610fcc57600080fd5b506103ed6004356143ca565b348015610fe457600080fd5b50610831614559565b348015610ff957600080fd5b50604080516020600480358082013583810280860185019096528085526103b5953695939460249493850192918291850190849080828437509497506145e99650505050505050565b34801561104e57600080fd5b506103b56004356024351515614638565b34801561106b57600080fd5b50610831614702565b34801561108057600080fd5b5061031b600160a060020a0360043581169060243516614708565b3480156110a757600080fd5b506103b5600160a060020a0360043516614736565b3480156110c857600080fd5b50610344614756565b3480156110dd57600080fd5b506108316147ac565b3480156110f257600080fd5b5061047a6004356147b2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b6060601580548060200260200160405190810160405280929190818152602001828054801561118057602002820191906000526020600020905b81548152602001906001019080831161116c575b505050505090505b90565b336111b9816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515611219576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b3360008181526013602052604081205490919082811515611300576040805160e560020a62461bcd02815260206004820152604660248201527f5468652063616c6c696e67206164647265737320646f6573206e6f742068617660448201527f6520616e20657068656d6572616c2063617264206173736f636961746564207760648201527f6974682069740000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561132457fe5b1461139f576040805160e560020a62461bcd02815260206004820152602760248201527f43616e206f6e6c7920636c61696d20612067696674207468617420697320756e60448201527f636c61696d656400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660021790556113b8858361498c565b60008160030154111561152f57600281015460ff16156114f457600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561144757600080fd5b505af115801561145b573d6000803e3d6000fd5b505050506040513d602081101561147157600080fd5b505115156114ef576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b61152f565b6003810154604051600160a060020a0387169180156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b80546003820154600283015460408051868152600160a060020a038a811660208301528183019490945260ff909216151560608301525192821692918616917f8944759db4d9e17454f6653113d7eb5bbd79f48e6ee8daef92bfce7bc5d5b1569181900360800190a3506001949350505050565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b820191906000526020600020905b81548152906001019060200180831161161257509395945050505050565b6018602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156116da5780601f106116af576101008083540402835291602001916116da565b820191906000526020600020905b8154815290600101906020018083116116bd57829003601f168201915b5050505060028301546003840154600485015460058601546006870154600790970154959660ff948516969395509193169188565b600090815260026020526040902054600160a060020a031690565b600061173582612af1565b9050600160a060020a03838116908216141561175057600080fd5b33600160a060020a038216148061176c575061176c8133614708565b151561177757600080fd5b600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61184a82600d836040518082805190602001908083835b602083106118165780518252601f1990920191602091820191016117f7565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a74565b5050565b6014602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156118f85780601f106118cd576101008083540402835291602001916118f8565b820191906000526020600020905b8154815290600101906020018083116118db57829003601f168201915b50505060028085018054604080516020601f600019610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561198a5780601f1061195f5761010080835404028352916020019161198a565b820191906000526020600020905b81548152906001019060200180831161196d57829003601f168201915b5050505060038301805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152949594935090830182828015611a1a5780601f106119ef57610100808354040283529160200191611a1a565b820191906000526020600020905b8154815290600101906020018083116119fd57829003601f168201915b5050505050905084565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60095490565b60408051808201909152600981526000805160206157ff833981519152602082015281565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60006060806060611aab615660565b611ab36156a6565b611abc87612a33565b1515611b12576040805160e560020a62461bcd02815260206004820152600f60248201527f43617264206d7573742065786973740000000000000000000000000000000000604482015290519081900360640190fd5b600087815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f8101869004860283018601909652858252919492938581019391929190830182828015611bc65780601f10611b9b57610100808354040283529160200191611bc6565b820191906000526020600020905b815481529060010190602001808311611ba957829003601f168201915b5050509183525050600282015460ff90811615156020830152600380840154604084015260048401546060840152600584015460809093019290911690811115611c0c57fe5b6003811115611c1757fe5b8152600682015460208083019190915260079092015460409182015260e083015160009081526014835281902081516080810183528154600160a060020a03168152600180830180548551600261010094831615949094026000190190911692909204601f8101879004870283018701909552848252959750909491938581019391929190830182828015611ced5780601f10611cc257610100808354040283529160200191611ced565b820191906000526020600020905b815481529060010190602001808311611cd057829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611d7f5780601f10611d5457610100808354040283529160200191611d7f565b820191906000526020600020905b815481529060010190602001808311611d6257829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611e135780601f10611de857610100808354040283529160200191611e13565b820191906000526020600020905b815481529060010190602001808311611df657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000611ead83600d846040518082805190602001908083835b60208310611e795780518252601f199092019160209182019101611e5a565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a89565b9392505050565b611ebe3382614aa8565b1515611ec957600080fd5b600160a060020a0383161515611ede57600080fd5b600160a060020a0382161515611ef357600080fd5b611efd8382614b07565b611f078382614b76565b611f118282614c7d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600c54600090600160a060020a03163314611f7157600080fd5b5060005b815181101561184a57611f9e8282815181101515611f8f57fe5b90602001906020020151612358565b600101611f75565b600160a060020a03811660009081526013602052604081205481811515612063576040805160e560020a62461bcd02815260206004820152604760248201527f43616e206f6e6c792063616c6c20746869732066756e6374696f6e206f6e206160448201527f6e2061646472657373207468617420776173207573656420617320616e20657060648201527f68656d6572616c00000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561208757fe5b14612102576040805160e560020a62461bcd02815260206004820152603460248201527f63616e206f6e6c792063616e63656c206769667473207468617420617265207560448201527f6e636c61696d656420286465706f736974656429000000000000000000000000606482015290519081900360840190fd5b8054600160a060020a03163314612189576040805160e560020a62461bcd02815260206004820152602d60248201527f6f6e6c792074686520676966746572206f662074686520636172642063616e2060448201527f63616e63656c2061206769667400000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660039081179091558101546000101561230457600281015460ff16156122d257600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481019290925251600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d602081101561224f57600080fd5b505115156122cd576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b612304565b6003810154604051339180156108fc02916000818181858888f19350505050158015612302573d6000803e3d6000fd5b505b61230e338361498c565b6040805183815290513391600160a060020a038716917f93be937d7f02e2964b3a79b3a26d9a782f74bf10449a0c34c03cf59c6dab85339181900360200190a35060019392505050565b600c54600160a060020a0316331461236f57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614cc6565b50565b60006123aa83612b1b565b82106123b557600080fd5b600160a060020a03831660009081526007602052604090208054839081106123d957fe5b9060005260206000200154905092915050565b60003361241c816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a038616151561247c576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b845115156124d4576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b8351151561252c576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b82511515612584576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b60408051608081018252600160a060020a03888116825260208083018981528385018990526060840188905260008c815260148352949094208351815473ffffffffffffffffffffffffffffffffffffffff1916931692909217825592518051929391926125f892600185019201906156d8565b50604082015180516126149160028401916020909101906156d8565b50606082015180516126309160038401916020909101906156d8565b50506015805460018101825560009182527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475018990556040518992507f5f4aa3ef0a4bf82c0f10f704eb578f57422b27f40709f8a4aca4694b6bda8ab39190a25060019695505050505050565b60115481565b6000336126d3816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b8551151561272b576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420746f6b656e20555249000000000000000000000000000000604482015290519081900360640190fd5b6040805160a081018252878152861515602080830191909152600082840181905260608301889052608083018790528a81526016825292909220815180519293919261277a92849201906156d8565b5060208201516001828101805460ff19169215159290921790915560408084015160028401556060840151600384015560809093015160049092019190915560178054918201815560009081527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15909101899055905188917fee4df2a71cd5144f989eafc284d855a4cc517ca03f21c5270ed8e2e9dcc3d29c91a25060019695505050505050565b601b5481565b6128448383836020604051908101604052806000815250613c11565b505050565b6040805160e560020a62461bcd028152602060048201526024808201527f526164692e4361726473206172652063656e736f72736869702072657369737460448201527f616e742100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60125481565b6000670de0b6b3a76400006128d7614559565b83028115156128e257fe5b0492915050565b33612917816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b60008381526016602052604090205460026000196101006001841615020190911604151561298f576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b5060009182526016602052604090912060040155565b6010805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612a2b5780601f10612a0057610100808354040283529160200191612a2b565b820191906000526020600020905b815481529060010190602001808311612a0e57829003601f168201915b505050505081565b600090815260016020526040902054600160a060020a0316151590565b6000612a5a611a4d565b8210612a6557600080fd5b6009805483908110612a7357fe5b90600052602060002001549050919050565b600160a060020a038116600090815260076020908152604091829020805483518184028101840190945280845260609392830182828015612ae557602002820191906000526020600020905b815481526020019060010190808311612ad1575b50505050509050919050565b600081815260016020526040812054600160a060020a0316801515612b1557600080fd5b92915050565b6000600160a060020a0382161515612b3257600080fd5b50600160a060020a031660009081526003602052604090205490565b600c54600160a060020a03163314612b6557600080fd5b600c54604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600c805473ffffffffffffffffffffffffffffffffffffffff19169055565b33612bea816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600083815260166020526040902054600260001961010060018416150201909116041515612c62576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b600083815260166020526040902060020154821015612cf1576040805160e560020a62461bcd02815260206004820152603d60248201527f43616e27742073657420746865206d6178207175616e74697479206c6573732060448201527f7468616e207468652063757272656e7420746f74616c206d696e746564000000606482015290519081900360840190fd5b5060009182526016602052604090912060030155565b6000612d11614559565b600083815260166020526040902060040154670de0b6b3a7640000028115156128e257fe5b600c54600160a060020a03163314612d4d57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614dd7565b60136020526000908152604090205481565b33612dba816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515612e1a576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600f805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600c54600160a060020a031681565b60166020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015612ef05780601f10612ec557610100808354040283529160200191612ef0565b820191906000526020600020905b815481529060010190602001808311612ed357829003601f168201915b50505050600183015460028401546003850154600490950154939460ff9092169390925085565b33612f45816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b811515612f9c576040805160e560020a62461bcd02815260206004820152601060248201527f426173652055524920696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b612fa860108484615756565b50505050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b601a5481565b6000612b15826040805190810160405280600981526020016000805160206157ff833981519152815250611e41565b600080808080600160a060020a038c1615156130aa576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b60008811156131215760008b815260146020526040902054600160a060020a03161515613121576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b60008a815260166020526040902054600260001961010060018416150201909116041515613199576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008a81526016602052604090206001015460ff161515613204576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b600e54604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051600160a060020a039092169163dd62ed3e916044808201926020929091908290030181600087803b15801561327057600080fd5b505af1158015613284573d6000803e3d6000fd5b505050506040513d602081101561329a57600080fd5b5051888801111561331b576040805160e560020a62461bcd02815260206004820152603c60248201527f4d75737420686176652070726f7669646564206869676820656e6f756768206160448201527f6c6f77616e636520746f20526164696361726420636f6e747261637400000000606482015290519081900360840190fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b15801561338157600080fd5b505af1158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b50518888011115613452576040805160e560020a62461bcd02815260206004820152604960248201527f4d757374206861766520656e6f75676820746f6b656e2062616c616e6365206f60448201527f662064616920746f2070617920666f7220646f6e6174696f6e20616e6420676960648201527f667420616d6f756e740000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b60008a81526016602052604081206003015411156134fe5760008a81526016602052604090206003810154600290910154106134fe576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008a81526016602052604081206004015411156135cd5760008a81526016602052604090206004015488880110156135cd576040805160e560020a62461bcd02815260206004820152604f60248201527f54686520746f74616c206461692073656e74207769746820746865207472616e60448201527f73616374696f6e206973206c657373207468616e20746865206d696e2070726960648201527f6365206f662074686520746f6b656e0000000000000000000000000000000000608482015290519081900360a40190fd5b85156136d2576012543414613678576040805160e560020a62461bcd02815260206004820152604760248201527f4120636c61696d61626c65206c696e6b207761732067656e657261746564206260448201527f7574206e6f7420656e6f75676820657068656d6572616c20657468657220776160648201527f732073656e742100000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038d1660008181526013602052604080822093909355601254925160019750309650919280156108fc02929091818181858888f193505050501580156136cc573d6000803e3d6000fd5b506136da565b600293508b92505b6101006040519081016040528033600160a060020a031681526020018a815260200160011515815260200188815260200189815260200185600381111561371d57fe5b815260208082018d905260409182018e9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192613782926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156137d257fe5b021790555060c0820151600682015560e09091015160079091015560008a8152601660209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526138909387939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b820191906000526020600020905b81548152906001019060200180831161386957829003601f168201915b5050505050614ea9565b60008b8152601660205260408120600201805460010190559092508811156139d4575060008a815260146020908152604080832054600e5482517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0392831660248201819052604482018e90529351939591909216936323b872dd93606480850194929391928390030190829087803b15801561393b57600080fd5b505af115801561394f573d6000803e3d6000fd5b505050506040513d602081101561396557600080fd5b505115156139bd576040805160e560020a62461bcd02815260206004820152601c60248201527f53656e64696e6720746f2062656e65666163746f72206661696c656400000000604482015290519081900360640190fd5b601c546139d0908963ffffffff614ee116565b601c555b6000871115613aeb57600e54604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018b9052915191909216916323b872dd9160648083019260209291908290030181600087803b158015613a5257600080fd5b505af1158015613a66573d6000803e3d6000fd5b505050506040513d6020811015613a7c57600080fd5b50511515613ad4576040805160e560020a62461bcd02815260206004820152601b60248201527f53656e64696e6720746f20726563697069656e74206661696c65640000000000604482015290519081900360640190fd5b601b54613ae7908863ffffffff614ee116565b601b555b898b84600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338660018d8f8c6040518087600160a060020a0316600160a060020a0316815260200186815260200185151515158152602001848152602001838152602001826003811115613b6357fe5b60ff168152602001965050505050505060405180910390a45060019b9a5050505050505050505050565b600160a060020a038216331415613ba357600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b613c1c848484611eb4565b613c2884848484614eee565b1515612fa857600080fd5b6000808080600160a060020a038b161515613c98576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b6000871115613d0f5760008a815260146020526040902054600160a060020a03161515613d0f576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b600089815260166020526040902054600260001961010060018416150201909116041515613d87576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008981526016602052604090206001015460ff161515613df2576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b8415613efb57601254878701013414613ea1576040805160e560020a62461bcd02815260206004820152604c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e74202b204560648201527f7068656d6572616c206665650000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038c1660008181526013602052604080822093909355601254925160019650309550919280156108fc02929091818181858888f19350505050158015613ef5573d6000803e3d6000fd5b50613f82565b8686013414613f7a576040805160e560020a62461bcd02815260206004820152603c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e7400000000606482015290519081900360840190fd5b600292508a91505b600089815260166020526040812060030154111561402e57600089815260166020526040902060038101546002909101541061402e576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008981526016602052604081206004015411156140cc57346140508a612d07565b11156140cc576040805160e560020a62461bcd02815260206004820152603160248201527f4d7573742073656e64206174206c6561737420746865206d696e696d756d206160448201527f6d6f756e7420746f206275792063617264000000000000000000000000000000606482015290519081900360840190fd5b6101006040519081016040528033600160a060020a0316815260200189815260200160001515815260200187815260200188815260200184600381111561410f57fe5b815260208082018c905260409182018d9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192614174926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156141c457fe5b021790555060c0820151600682015560e0909101516007909101556000898152601660209081526040918290208054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815261424d9386939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b60008a8152601660205260408120600201805460010190559091508711156142cb5760008a815260146020526040808220549051600160a060020a039091169189156108fc02918a91818181858888f193505050501580156142b3573d6000803e3d6000fd5b50601a546142c7908863ffffffff614ee116565b601a555b6000861115614329576019546142e7908763ffffffff614ee116565b60195584151561432957604051600160a060020a0383169087156108fc029088906000818181858888f19350505050158015614327573d6000803e3d6000fd5b505b888a83600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338560008c8e8b6040518087600160a060020a0316600160a060020a03168152602001868152602001851515151581526020018481526020018381526020018260038111156143a157fe5b60ff168152602001965050505050505060405180910390a45060019a9950505050505050505050565b60606143d582612a33565b151561442b576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60108054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152612b1593909290918301828280156144b85780601f1061448d576101008083540402835291602001916144b8565b820191906000526020600020905b81548152906001019060200180831161449b57829003601f168201915b5050506000868152600b60209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381529450925083018282801561454f5780601f106145245761010080835404028352916020019161454f565b820191906000526020600020905b81548152906001019060200180831161453257829003601f168201915b5050505050615070565b600f54604080517f57de26a40000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916357de26a491600480830192602092919082900301818787803b1580156145b857600080fd5b505af11580156145cc573d6000803e3d6000fd5b505050506040513d60208110156145e257600080fd5b5051905090565b600c54600090600160a060020a0316331461460357600080fd5b5060005b815181101561184a57614630828281518110151561462157fe5b90602001906020020151612d36565b600101614607565b33614666816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b6000838152601660205260409020546002600019610100600184161502019091160415156146de576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b50600091825260166020526040909120600101805460ff1916911515919091179055565b601c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c54600160a060020a0316331461474d57600080fd5b61239c816150a5565b60606017805480602002602001604051908101604052809291908181526020018280548015611180576020028201919060005260206000209081548152602001906001019080831161116c575050505050905090565b60195481565b600060606000806000806000806147c7615660565b6147d08a612a33565b1515614826576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60008a815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f81018690048602830186019096528582529194929385810193919291908301828280156148da5780601f106148af576101008083540402835291602001916148da565b820191906000526020600020905b8154815290600101906020018083116148bd57829003601f168201915b5050509183525050600282015460ff9081161515602083015260038084015460408401526004840154606084015260058401546080909301929091169081111561492057fe5b600381111561492b57fe5b8152602001600682015481526020016007820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518696509850985098509850985098509850985050919395975091939597565b3061499682612af1565b600160a060020a031614614a1a576040805160e560020a62461bcd02815260206004820152603d60248201527f5468652063617264206d757374206265206f776e65642062792074686520636f60448201527f6e747261637420666f7220697420746f20626520696e20657363726f77000000606482015290519081900360840190fd5b614a243082614b07565b614a2e3082614b76565b614a388282614c7d565b6040518190600160a060020a0384169030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a45050565b614a7e8282614a89565b151561184a57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b600080614ab483612af1565b905080600160a060020a031684600160a060020a03161480614aef575083600160a060020a0316614ae48461170f565b600160a060020a0316145b80614aff5750614aff8185614708565b949350505050565b81600160a060020a0316614b1a82612af1565b600160a060020a031614614b2d57600080fd5b600081815260026020526040902054600160a060020a03161561184a576000908152600260205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b6000806000614b858585615123565b600084815260086020908152604080832054600160a060020a0389168452600790925290912054909350614bc090600163ffffffff6151b916565b600160a060020a038616600090815260076020526040902080549193509083908110614be857fe5b90600052602060002001549050806007600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614c2857fe5b6000918252602080832090910192909255600160a060020a0387168152600790915260409020805490614c5f9060001983016157c4565b50600093845260086020526040808520859055908452909220555050565b6000614c8983836151cb565b50600160a060020a039091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b614d3082600d836040518082805190602001908083835b60208310614cfc5780518252601f199092019160209182019101614cdd565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061525b565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b83811015614d99578181015183820152602001614d81565b50505050905090810190601f168015614dc65780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b614e4182600d836040518082805190602001908083835b60208310614e0d5780518252601f199092019160209182019101614dee565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061527d565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b7004898260405180806020018281038252838181518152602001915080519060200190808383600083811015614d99578181015183820152602001614d81565b601154600090614eb984826152a2565b614ec381846152f1565b601154614ed790600163ffffffff614ee116565b6011559392505050565b81810182811015612b1557fe5b600080614f0385600160a060020a0316615324565b1515614f125760019150615067565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614fa5578181015183820152602001614f8d565b50505050905090810190601f168015614fd25780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050506040513d602081101561501e57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b604080516020818101835260008083528351808301855281815284519283019094528152606092611ead92869286929061532c565b600160a060020a03811615156150ba57600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81600160a060020a031661513682612af1565b600160a060020a03161461514957600080fd5b600160a060020a03821660009081526003602052604090205461517390600163ffffffff6151b916565b600160a060020a03909216600090815260036020908152604080832094909455918152600190915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000828211156151c557fe5b50900390565b600081815260016020526040902054600160a060020a0316156151ed57600080fd5b6000818152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038816908117909155845260039091529091205461523b91614ee1565b600160a060020a0390921660009081526003602052604090209190915550565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6152ac8282615605565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b6152fa82612a33565b151561530557600080fd5b6000828152600b602090815260409091208251612844928401906156d8565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f191660200182016040528015615385578160200160208202803883390190505b50935083925060009150600090505b885181101561540a5788818151811015156153ab57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156153d257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615394565b5060005b875181101561548457878181518110151561542557fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561544c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161540e565b5060005b86518110156154fe57868181518110151561549f57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156154c657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615488565b5060005b855181101561557857858181518110151561551957fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561554057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615502565b5060005b84518110156155f257848181518110151561559357fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156155ba57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161557c565b50909d9c50505050505050505050505050565b600160a060020a038216151561561a57600080fd5b6156248282614c7d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60408051610100810182526000808252606060208301819052928201819052918101829052608081018290529060a0820190815260200160008152602001600081525090565b6080604051908101604052806000600160a060020a031681526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061571957805160ff1916838001178555615746565b82800160010185558215615746579182015b8281111561574657825182559160200191906001019061572b565b506157529291506157e4565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106157975782800160ff19823516178555615746565b82800160010185558215615746579182015b828111156157465782358255916020019190600101906157a9565b815481835581811115612844576000838152602090206128449181019083015b61118891905b8082111561575257600081556001016157ea560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a72305820610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e390029
Deployed Bytecode
0x6080604052600436106102df5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a781146102e457806303cfe12d1461032f578063040e0d311461039457806304f3c40e146103b757806306fdde03146103d85780630701fd6b14610462578063081812fc14610547578063095ea7b31461057b5780630988ca8c1461059f578063128ee16114610606578063150b7a021461077b57806318160ddd1461081c57806318b919e91461084357806319fa8f50146108585780631db1b4fd1461086d578063217fe6c61461088557806323b872dd146108ec57806324953eaa14610916578063254e6f261461096b578063286dd3f51461098c5780632f745c59146109ad57806337073a87146109d15780633b3a1a7a14610ab65780633bac8f9014610acb5780633eeb8d1714610b3657806342842e0e14610b4b57806342966c6814610b755780634b745f9014610b8d5780634d02fef714610ba25780634d7bb88114610bba5780634e99b80014610bd55780634f558e7914610bea5780634f6ccce714610c025780635a3f267214610c1a5780636352211e14610c3b57806370a0823114610c53578063715018a614610c74578063757000f714610c89578063757f015514610ca45780637b9417c814610cbc57806388f0e36414610cdd57806389ae3b1f14610cfe5780638da5cb5b14610d1f5780638dc1076814610d345780638ef79e9114610de457806395d89b4114610e045780639b10acdc14610e195780639b19251a14610e2e578063a10b79bc14610e4f578063a22cb46514610ebd578063b88d4fde14610ee3578063c28ae87614610f52578063c87b56dd14610fc0578063ca7c4dba14610fd8578063e2ec6ec314610fed578063e60a955d14611042578063e7ac2a521461105f578063e985e9c514611074578063f2fde38b1461109b578063f7ad51ce146110bc578063f9256de1146110d1578063fc314e31146110e6575b600080fd5b3480156102f057600080fd5b5061031b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19600435166110fe565b604080519115158252519081900360200190f35b34801561033b57600080fd5b50610344611132565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610380578181015183820152602001610368565b505050509050019250505060405180910390f35b3480156103a057600080fd5b506103b5600160a060020a036004351661118b565b005b3480156103c357600080fd5b5061031b600160a060020a0360043516611249565b3480156103e457600080fd5b506103ed6115a3565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046e57600080fd5b5061047a600435611630565b6040518089600160a060020a0316600160a060020a0316815260200180602001881515151581526020018781526020018681526020018560038111156104bc57fe5b60ff168152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b838110156105055781810151838201526020016104ed565b50505050905090810190601f1680156105325780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b34801561055357600080fd5b5061055f60043561170f565b60408051600160a060020a039092168252519081900360200190f35b34801561058757600080fd5b506103b5600160a060020a036004351660243561172a565b3480156105ab57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526103b5958335600160a060020a03169536956044949193909101919081908401838280828437509497506117e09650505050505050565b34801561061257600080fd5b5061061e60043561184e565b6040518085600160a060020a0316600160a060020a03168152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561067b578181015183820152602001610663565b50505050905090810190601f1680156106a85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156106db5781810151838201526020016106c3565b50505050905090810190601f1680156107085780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561073b578181015183820152602001610723565b50505050905090810190601f1680156107685780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34801561078757600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526107ea94600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750611a249650505050505050565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199092168252519081900360200190f35b34801561082857600080fd5b50610831611a4d565b60408051918252519081900360200190f35b34801561084f57600080fd5b506103ed611a53565b34801561086457600080fd5b506107ea611a78565b34801561087957600080fd5b5061061e600435611a9c565b34801561089157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e419650505050505050565b3480156108f857600080fd5b506103b5600160a060020a0360043581169060243516604435611eb4565b34801561092257600080fd5b50604080516020600480358082013583810280860185019096528085526103b595369593946024949385019291829185019084908082843750949750611f579650505050505050565b34801561097757600080fd5b5061031b600160a060020a0360043516611fa6565b34801561099857600080fd5b506103b5600160a060020a0360043516612358565b3480156109b957600080fd5b50610831600160a060020a036004351660243561239f565b3480156109dd57600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261031b9482359460248035600160a060020a03169536959460649492019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506123ec9650505050505050565b348015610ac257600080fd5b5061083161269d565b348015610ad757600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261031b9583359536956044949193909101919081908401838280828437509497505050508235151593505050602081013590604001356126a3565b348015610b4257600080fd5b50610831612822565b348015610b5757600080fd5b506103b5600160a060020a0360043581169060243516604435612828565b348015610b8157600080fd5b506103b5600435612849565b348015610b9957600080fd5b506108316128be565b348015610bae57600080fd5b506108316004356128c4565b348015610bc657600080fd5b506103b56004356024356128e9565b348015610be157600080fd5b506103ed6129a5565b348015610bf657600080fd5b5061031b600435612a33565b348015610c0e57600080fd5b50610831600435612a50565b348015610c2657600080fd5b50610344600160a060020a0360043516612a85565b348015610c4757600080fd5b5061055f600435612af1565b348015610c5f57600080fd5b50610831600160a060020a0360043516612b1b565b348015610c8057600080fd5b506103b5612b4e565b348015610c9557600080fd5b506103b5600435602435612bbc565b348015610cb057600080fd5b50610831600435612d07565b348015610cc857600080fd5b506103b5600160a060020a0360043516612d36565b348015610ce957600080fd5b50610831600160a060020a0360043516612d7a565b348015610d0a57600080fd5b506103b5600160a060020a0360043516612d8c565b348015610d2b57600080fd5b5061055f612e4a565b348015610d4057600080fd5b50610d4c600435612e59565b604051808060200186151515158152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b83811015610da5578181015183820152602001610d8d565b50505050905090810190601f168015610dd25780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b348015610df057600080fd5b506103b56004803560248101910135612f17565b348015610e1057600080fd5b506103ed612fae565b348015610e2557600080fd5b5061083161300f565b348015610e3a57600080fd5b5061031b600160a060020a0360043516613015565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a0381351694602480359560443595369560849493019181908401838280828437509497505084359550505060208301359260400135151591506130449050565b348015610ec957600080fd5b506103b5600160a060020a03600435166024351515613b8d565b348015610eef57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526103b594600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750613c119650505050505050565b604080516020601f60643560048181013592830184900484028501840190955281845261031b94600160a060020a038135169460248035956044359536956084949301918190840183828082843750949750508435955050506020830135926040013515159150613c339050565b348015610fcc57600080fd5b506103ed6004356143ca565b348015610fe457600080fd5b50610831614559565b348015610ff957600080fd5b50604080516020600480358082013583810280860185019096528085526103b5953695939460249493850192918291850190849080828437509497506145e99650505050505050565b34801561104e57600080fd5b506103b56004356024351515614638565b34801561106b57600080fd5b50610831614702565b34801561108057600080fd5b5061031b600160a060020a0360043581169060243516614708565b3480156110a757600080fd5b506103b5600160a060020a0360043516614736565b3480156110c857600080fd5b50610344614756565b3480156110dd57600080fd5b506108316147ac565b3480156110f257600080fd5b5061047a6004356147b2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b6060601580548060200260200160405190810160405280929190818152602001828054801561118057602002820191906000526020600020905b81548152602001906001019080831161116c575b505050505090505b90565b336111b9816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515611219576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600e805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b3360008181526013602052604081205490919082811515611300576040805160e560020a62461bcd02815260206004820152604660248201527f5468652063616c6c696e67206164647265737320646f6573206e6f742068617660448201527f6520616e20657068656d6572616c2063617264206173736f636961746564207760648201527f6974682069740000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561132457fe5b1461139f576040805160e560020a62461bcd02815260206004820152602760248201527f43616e206f6e6c7920636c61696d20612067696674207468617420697320756e60448201527f636c61696d656400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660021790556113b8858361498c565b60008160030154111561152f57600281015460ff16156114f457600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561144757600080fd5b505af115801561145b573d6000803e3d6000fd5b505050506040513d602081101561147157600080fd5b505115156114ef576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b61152f565b6003810154604051600160a060020a0387169180156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b80546003820154600283015460408051868152600160a060020a038a811660208301528183019490945260ff909216151560608301525192821692918616917f8944759db4d9e17454f6653113d7eb5bbd79f48e6ee8daef92bfce7bc5d5b1569181900360800190a3506001949350505050565b60058054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b820191906000526020600020905b81548152906001019060200180831161161257509395945050505050565b6018602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156116da5780601f106116af576101008083540402835291602001916116da565b820191906000526020600020905b8154815290600101906020018083116116bd57829003601f168201915b5050505060028301546003840154600485015460058601546006870154600790970154959660ff948516969395509193169188565b600090815260026020526040902054600160a060020a031690565b600061173582612af1565b9050600160a060020a03838116908216141561175057600080fd5b33600160a060020a038216148061176c575061176c8133614708565b151561177757600080fd5b600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61184a82600d836040518082805190602001908083835b602083106118165780518252601f1990920191602091820191016117f7565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a74565b5050565b6014602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a039092169492939092908301828280156118f85780601f106118cd576101008083540402835291602001916118f8565b820191906000526020600020905b8154815290600101906020018083116118db57829003601f168201915b50505060028085018054604080516020601f600019610100600187161502019094169590950492830185900485028101850190915281815295969594509092509083018282801561198a5780601f1061195f5761010080835404028352916020019161198a565b820191906000526020600020905b81548152906001019060200180831161196d57829003601f168201915b5050505060038301805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152949594935090830182828015611a1a5780601f106119ef57610100808354040283529160200191611a1a565b820191906000526020600020905b8154815290600101906020018083116119fd57829003601f168201915b5050505050905084565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60095490565b60408051808201909152600981526000805160206157ff833981519152602082015281565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60006060806060611aab615660565b611ab36156a6565b611abc87612a33565b1515611b12576040805160e560020a62461bcd02815260206004820152600f60248201527f43617264206d7573742065786973740000000000000000000000000000000000604482015290519081900360640190fd5b600087815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f8101869004860283018601909652858252919492938581019391929190830182828015611bc65780601f10611b9b57610100808354040283529160200191611bc6565b820191906000526020600020905b815481529060010190602001808311611ba957829003601f168201915b5050509183525050600282015460ff90811615156020830152600380840154604084015260048401546060840152600584015460809093019290911690811115611c0c57fe5b6003811115611c1757fe5b8152600682015460208083019190915260079092015460409182015260e083015160009081526014835281902081516080810183528154600160a060020a03168152600180830180548551600261010094831615949094026000190190911692909204601f8101879004870283018701909552848252959750909491938581019391929190830182828015611ced5780601f10611cc257610100808354040283529160200191611ced565b820191906000526020600020905b815481529060010190602001808311611cd057829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611d7f5780601f10611d5457610100808354040283529160200191611d7f565b820191906000526020600020905b815481529060010190602001808311611d6257829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611e135780601f10611de857610100808354040283529160200191611e13565b820191906000526020600020905b815481529060010190602001808311611df657829003601f168201915b505050919092525050815160208301516040840151606090940151919b909a50929850965090945050505050565b6000611ead83600d846040518082805190602001908083835b60208310611e795780518252601f199092019160209182019101611e5a565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050614a89565b9392505050565b611ebe3382614aa8565b1515611ec957600080fd5b600160a060020a0383161515611ede57600080fd5b600160a060020a0382161515611ef357600080fd5b611efd8382614b07565b611f078382614b76565b611f118282614c7d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600c54600090600160a060020a03163314611f7157600080fd5b5060005b815181101561184a57611f9e8282815181101515611f8f57fe5b90602001906020020151612358565b600101611f75565b600160a060020a03811660009081526013602052604081205481811515612063576040805160e560020a62461bcd02815260206004820152604760248201527f43616e206f6e6c792063616c6c20746869732066756e6374696f6e206f6e206160448201527f6e2061646472657373207468617420776173207573656420617320616e20657060648201527f68656d6572616c00000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060008181526018602052604090206001600582015460ff16600381111561208757fe5b14612102576040805160e560020a62461bcd02815260206004820152603460248201527f63616e206f6e6c792063616e63656c206769667473207468617420617265207560448201527f6e636c61696d656420286465706f736974656429000000000000000000000000606482015290519081900360840190fd5b8054600160a060020a03163314612189576040805160e560020a62461bcd02815260206004820152602d60248201527f6f6e6c792074686520676966746572206f662074686520636172642063616e2060448201527f63616e63656c2061206769667400000000000000000000000000000000000000606482015290519081900360840190fd5b60058101805460ff191660039081179091558101546000101561230457600281015460ff16156122d257600e546003820154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481019290925251600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d602081101561224f57600080fd5b505115156122cd576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e64696e6720746f20726563697069656e742061667465722063616e636560448201527f6c2067696674206661696c656400000000000000000000000000000000000000606482015290519081900360840190fd5b612304565b6003810154604051339180156108fc02916000818181858888f19350505050158015612302573d6000803e3d6000fd5b505b61230e338361498c565b6040805183815290513391600160a060020a038716917f93be937d7f02e2964b3a79b3a26d9a782f74bf10449a0c34c03cf59c6dab85339181900360200190a35060019392505050565b600c54600160a060020a0316331461236f57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614cc6565b50565b60006123aa83612b1b565b82106123b557600080fd5b600160a060020a03831660009081526007602052604090208054839081106123d957fe5b9060005260206000200154905092915050565b60003361241c816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a038616151561247c576040805160e560020a62461bcd02815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b845115156124d4576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b8351151561252c576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b82511515612584576040805160e560020a62461bcd02815260206004820152600c60248201527f496e76616c6964206e616d650000000000000000000000000000000000000000604482015290519081900360640190fd5b60408051608081018252600160a060020a03888116825260208083018981528385018990526060840188905260008c815260148352949094208351815473ffffffffffffffffffffffffffffffffffffffff1916931692909217825592518051929391926125f892600185019201906156d8565b50604082015180516126149160028401916020909101906156d8565b50606082015180516126309160038401916020909101906156d8565b50506015805460018101825560009182527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475018990556040518992507f5f4aa3ef0a4bf82c0f10f704eb578f57422b27f40709f8a4aca4694b6bda8ab39190a25060019695505050505050565b60115481565b6000336126d3816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b8551151561272b576040805160e560020a62461bcd02815260206004820152601160248201527f496e76616c696420746f6b656e20555249000000000000000000000000000000604482015290519081900360640190fd5b6040805160a081018252878152861515602080830191909152600082840181905260608301889052608083018790528a81526016825292909220815180519293919261277a92849201906156d8565b5060208201516001828101805460ff19169215159290921790915560408084015160028401556060840151600384015560809093015160049092019190915560178054918201815560009081527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15909101899055905188917fee4df2a71cd5144f989eafc284d855a4cc517ca03f21c5270ed8e2e9dcc3d29c91a25060019695505050505050565b601b5481565b6128448383836020604051908101604052806000815250613c11565b505050565b6040805160e560020a62461bcd028152602060048201526024808201527f526164692e4361726473206172652063656e736f72736869702072657369737460448201527f616e742100000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60125481565b6000670de0b6b3a76400006128d7614559565b83028115156128e257fe5b0492915050565b33612917816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b60008381526016602052604090205460026000196101006001841615020190911604151561298f576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b5060009182526016602052604090912060040155565b6010805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612a2b5780601f10612a0057610100808354040283529160200191612a2b565b820191906000526020600020905b815481529060010190602001808311612a0e57829003601f168201915b505050505081565b600090815260016020526040902054600160a060020a0316151590565b6000612a5a611a4d565b8210612a6557600080fd5b6009805483908110612a7357fe5b90600052602060002001549050919050565b600160a060020a038116600090815260076020908152604091829020805483518184028101840190945280845260609392830182828015612ae557602002820191906000526020600020905b815481526020019060010190808311612ad1575b50505050509050919050565b600081815260016020526040812054600160a060020a0316801515612b1557600080fd5b92915050565b6000600160a060020a0382161515612b3257600080fd5b50600160a060020a031660009081526003602052604090205490565b600c54600160a060020a03163314612b6557600080fd5b600c54604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600c805473ffffffffffffffffffffffffffffffffffffffff19169055565b33612bea816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600083815260166020526040902054600260001961010060018416150201909116041515612c62576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b600083815260166020526040902060020154821015612cf1576040805160e560020a62461bcd02815260206004820152603d60248201527f43616e27742073657420746865206d6178207175616e74697479206c6573732060448201527f7468616e207468652063757272656e7420746f74616c206d696e746564000000606482015290519081900360840190fd5b5060009182526016602052604090912060030155565b6000612d11614559565b600083815260166020526040902060040154670de0b6b3a7640000028115156128e257fe5b600c54600160a060020a03163314612d4d57600080fd5b61239c816040805190810160405280600981526020016000805160206157ff833981519152815250614dd7565b60136020526000908152604090205481565b33612dba816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b600160a060020a0382161515612e1a576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b50600f805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600c54600160a060020a031681565b60166020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015612ef05780601f10612ec557610100808354040283529160200191612ef0565b820191906000526020600020905b815481529060010190602001808311612ed357829003601f168201915b50505050600183015460028401546003850154600490950154939460ff9092169390925085565b33612f45816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b811515612f9c576040805160e560020a62461bcd02815260206004820152601060248201527f426173652055524920696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b612fa860108484615756565b50505050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156111805780601f1061160457610100808354040283529160200191611180565b601a5481565b6000612b15826040805190810160405280600981526020016000805160206157ff833981519152815250611e41565b600080808080600160a060020a038c1615156130aa576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b60008811156131215760008b815260146020526040902054600160a060020a03161515613121576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b60008a815260166020526040902054600260001961010060018416150201909116041515613199576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008a81526016602052604090206001015460ff161515613204576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b600e54604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051600160a060020a039092169163dd62ed3e916044808201926020929091908290030181600087803b15801561327057600080fd5b505af1158015613284573d6000803e3d6000fd5b505050506040513d602081101561329a57600080fd5b5051888801111561331b576040805160e560020a62461bcd02815260206004820152603c60248201527f4d75737420686176652070726f7669646564206869676820656e6f756768206160448201527f6c6f77616e636520746f20526164696361726420636f6e747261637400000000606482015290519081900360840190fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b15801561338157600080fd5b505af1158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b50518888011115613452576040805160e560020a62461bcd02815260206004820152604960248201527f4d757374206861766520656e6f75676820746f6b656e2062616c616e6365206f60448201527f662064616920746f2070617920666f7220646f6e6174696f6e20616e6420676960648201527f667420616d6f756e740000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b60008a81526016602052604081206003015411156134fe5760008a81526016602052604090206003810154600290910154106134fe576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008a81526016602052604081206004015411156135cd5760008a81526016602052604090206004015488880110156135cd576040805160e560020a62461bcd02815260206004820152604f60248201527f54686520746f74616c206461692073656e74207769746820746865207472616e60448201527f73616374696f6e206973206c657373207468616e20746865206d696e2070726960648201527f6365206f662074686520746f6b656e0000000000000000000000000000000000608482015290519081900360a40190fd5b85156136d2576012543414613678576040805160e560020a62461bcd02815260206004820152604760248201527f4120636c61696d61626c65206c696e6b207761732067656e657261746564206260448201527f7574206e6f7420656e6f75676820657068656d6572616c20657468657220776160648201527f732073656e742100000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038d1660008181526013602052604080822093909355601254925160019750309650919280156108fc02929091818181858888f193505050501580156136cc573d6000803e3d6000fd5b506136da565b600293508b92505b6101006040519081016040528033600160a060020a031681526020018a815260200160011515815260200188815260200189815260200185600381111561371d57fe5b815260208082018d905260409182018e9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192613782926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156137d257fe5b021790555060c0820151600682015560e09091015160079091015560008a8152601660209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526138909387939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b820191906000526020600020905b81548152906001019060200180831161386957829003601f168201915b5050505050614ea9565b60008b8152601660205260408120600201805460010190559092508811156139d4575060008a815260146020908152604080832054600e5482517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0392831660248201819052604482018e90529351939591909216936323b872dd93606480850194929391928390030190829087803b15801561393b57600080fd5b505af115801561394f573d6000803e3d6000fd5b505050506040513d602081101561396557600080fd5b505115156139bd576040805160e560020a62461bcd02815260206004820152601c60248201527f53656e64696e6720746f2062656e65666163746f72206661696c656400000000604482015290519081900360640190fd5b601c546139d0908963ffffffff614ee116565b601c555b6000871115613aeb57600e54604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018b9052915191909216916323b872dd9160648083019260209291908290030181600087803b158015613a5257600080fd5b505af1158015613a66573d6000803e3d6000fd5b505050506040513d6020811015613a7c57600080fd5b50511515613ad4576040805160e560020a62461bcd02815260206004820152601b60248201527f53656e64696e6720746f20726563697069656e74206661696c65640000000000604482015290519081900360640190fd5b601b54613ae7908863ffffffff614ee116565b601b555b898b84600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338660018d8f8c6040518087600160a060020a0316600160a060020a0316815260200186815260200185151515158152602001848152602001838152602001826003811115613b6357fe5b60ff168152602001965050505050505060405180910390a45060019b9a5050505050505050505050565b600160a060020a038216331415613ba357600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b613c1c848484611eb4565b613c2884848484614eee565b1515612fa857600080fd5b6000808080600160a060020a038b161515613c98576040805160e560020a62461bcd02815260206004820152601760248201527f4d75737420626520612076616c69642061646472657373000000000000000000604482015290519081900360640190fd5b6000871115613d0f5760008a815260146020526040902054600160a060020a03161515613d0f576040805160e560020a62461bcd02815260206004820181905260248201527f4d7573742073706563696679206578697374696e672062656e65666163746f72604482015290519081900360640190fd5b600089815260166020526040902054600260001961010060018416150201909116041515613d87576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b60008981526016602052604090206001015460ff161515613df2576040805160e560020a62461bcd02815260206004820152601660248201527f4d75737420626520616e20616374697665206361726400000000000000000000604482015290519081900360640190fd5b8415613efb57601254878701013414613ea1576040805160e560020a62461bcd02815260206004820152604c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e74202b204560648201527f7068656d6572616c206665650000000000000000000000000000000000000000608482015290519081900360a40190fd5b601154600160a060020a038c1660008181526013602052604080822093909355601254925160019650309550919280156108fc02929091818181858888f19350505050158015613ef5573d6000803e3d6000fd5b50613f82565b8686013414613f7a576040805160e560020a62461bcd02815260206004820152603c60248201527f43616e206f6e6c79207265717565737420746f20646f6e61746520616e64206760448201527f6966742074686520616d6f756e74206f662065746865722073656e7400000000606482015290519081900360840190fd5b600292508a91505b600089815260166020526040812060030154111561402e57600089815260166020526040902060038101546002909101541061402e576040805160e560020a62461bcd02815260206004820152602a60248201527f43616e277420657863656564206d6178696d756d207175616e74697479206f6660448201527f2063617264207479706500000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008981526016602052604081206004015411156140cc57346140508a612d07565b11156140cc576040805160e560020a62461bcd02815260206004820152603160248201527f4d7573742073656e64206174206c6561737420746865206d696e696d756d206160448201527f6d6f756e7420746f206275792063617264000000000000000000000000000000606482015290519081900360840190fd5b6101006040519081016040528033600160a060020a0316815260200189815260200160001515815260200187815260200188815260200184600381111561410f57fe5b815260208082018c905260409182018d9052601154600090815260188252919091208251815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039091161781558282015180519192614174926001850192909101906156d8565b50604082015160028201805491151560ff1992831617905560608301516003808401919091556080840151600484015560a08401516005840180549193909291169060019084908111156141c457fe5b021790555060c0820151600682015560e0909101516007909101556000898152601660209081526040918290208054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815261424d9386939192918301828280156138865780601f1061385b57610100808354040283529160200191613886565b60008a8152601660205260408120600201805460010190559091508711156142cb5760008a815260146020526040808220549051600160a060020a039091169189156108fc02918a91818181858888f193505050501580156142b3573d6000803e3d6000fd5b50601a546142c7908863ffffffff614ee116565b601a555b6000861115614329576019546142e7908763ffffffff614ee116565b60195584151561432957604051600160a060020a0383169087156108fc029088906000818181858888f19350505050158015614327573d6000803e3d6000fd5b505b888a83600160a060020a03167f98e9f98d17ffe453cd16d8de5219cf6b004221a3e5d8d7390ae9409e1d6945ae338560008c8e8b6040518087600160a060020a0316600160a060020a03168152602001868152602001851515151581526020018481526020018381526020018260038111156143a157fe5b60ff168152602001965050505050505060405180910390a45060019a9950505050505050505050565b60606143d582612a33565b151561442b576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60108054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152612b1593909290918301828280156144b85780601f1061448d576101008083540402835291602001916144b8565b820191906000526020600020905b81548152906001019060200180831161449b57829003601f168201915b5050506000868152600b60209081526040918290208054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381529450925083018282801561454f5780601f106145245761010080835404028352916020019161454f565b820191906000526020600020905b81548152906001019060200180831161453257829003601f168201915b5050505050615070565b600f54604080517f57de26a40000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916357de26a491600480830192602092919082900301818787803b1580156145b857600080fd5b505af11580156145cc573d6000803e3d6000fd5b505050506040513d60208110156145e257600080fd5b5051905090565b600c54600090600160a060020a0316331461460357600080fd5b5060005b815181101561184a57614630828281518110151561462157fe5b90602001906020020151612d36565b600101614607565b33614666816040805190810160405280600981526020016000805160206157ff8339815191528152506117e0565b6000838152601660205260409020546002600019610100600184161502019091160415156146de576040805160e560020a62461bcd02815260206004820152601a60248201527f4d7573742073706563696679206578697374696e672063617264000000000000604482015290519081900360640190fd5b50600091825260166020526040909120600101805460ff1916911515919091179055565b601c5481565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c54600160a060020a0316331461474d57600080fd5b61239c816150a5565b60606017805480602002602001604051908101604052809291908181526020018280548015611180576020028201919060005260206000209081548152602001906001019080831161116c575050505050905090565b60195481565b600060606000806000806000806147c7615660565b6147d08a612a33565b1515614826576040805160e560020a62461bcd02815260206004820152601460248201527f746f6b656e20646f6573206e6f74206578697374000000000000000000000000604482015290519081900360640190fd5b60008a815260186020908152604091829020825161010080820185528254600160a060020a03168252600180840180548751600293821615909402600019011691909104601f81018690048602830186019096528582529194929385810193919291908301828280156148da5780601f106148af576101008083540402835291602001916148da565b820191906000526020600020905b8154815290600101906020018083116148bd57829003601f168201915b5050509183525050600282015460ff9081161515602083015260038084015460408401526004840154606084015260058401546080909301929091169081111561492057fe5b600381111561492b57fe5b8152602001600682015481526020016007820154815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e001518696509850985098509850985098509850985050919395975091939597565b3061499682612af1565b600160a060020a031614614a1a576040805160e560020a62461bcd02815260206004820152603d60248201527f5468652063617264206d757374206265206f776e65642062792074686520636f60448201527f6e747261637420666f7220697420746f20626520696e20657363726f77000000606482015290519081900360840190fd5b614a243082614b07565b614a2e3082614b76565b614a388282614c7d565b6040518190600160a060020a0384169030907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a45050565b614a7e8282614a89565b151561184a57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b600080614ab483612af1565b905080600160a060020a031684600160a060020a03161480614aef575083600160a060020a0316614ae48461170f565b600160a060020a0316145b80614aff5750614aff8185614708565b949350505050565b81600160a060020a0316614b1a82612af1565b600160a060020a031614614b2d57600080fd5b600081815260026020526040902054600160a060020a03161561184a576000908152600260205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b6000806000614b858585615123565b600084815260086020908152604080832054600160a060020a0389168452600790925290912054909350614bc090600163ffffffff6151b916565b600160a060020a038616600090815260076020526040902080549193509083908110614be857fe5b90600052602060002001549050806007600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515614c2857fe5b6000918252602080832090910192909255600160a060020a0387168152600790915260409020805490614c5f9060001983016157c4565b50600093845260086020526040808520859055908452909220555050565b6000614c8983836151cb565b50600160a060020a039091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b614d3082600d836040518082805190602001908083835b60208310614cfc5780518252601f199092019160209182019101614cdd565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061525b565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b83811015614d99578181015183820152602001614d81565b50505050905090810190601f168015614dc65780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b614e4182600d836040518082805190602001908083835b60208310614e0d5780518252601f199092019160209182019101614dee565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061527d565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b7004898260405180806020018281038252838181518152602001915080519060200190808383600083811015614d99578181015183820152602001614d81565b601154600090614eb984826152a2565b614ec381846152f1565b601154614ed790600163ffffffff614ee116565b6011559392505050565b81810182811015612b1557fe5b600080614f0385600160a060020a0316615324565b1515614f125760019150615067565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614fa5578181015183820152602001614f8d565b50505050905090810190601f168015614fd25780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050506040513d602081101561501e57600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b604080516020818101835260008083528351808301855281815284519283019094528152606092611ead92869286929061532c565b600160a060020a03811615156150ba57600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81600160a060020a031661513682612af1565b600160a060020a03161461514957600080fd5b600160a060020a03821660009081526003602052604090205461517390600163ffffffff6151b916565b600160a060020a03909216600090815260036020908152604080832094909455918152600190915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000828211156151c557fe5b50900390565b600081815260016020526040902054600160a060020a0316156151ed57600080fd5b6000818152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038816908117909155845260039091529091205461523b91614ee1565b600160a060020a0390921660009081526003602052604090209190915550565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6152ac8282615605565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b6152fa82612a33565b151561530557600080fd5b6000828152600b602090815260409091208251612844928401906156d8565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f191660200182016040528015615385578160200160208202803883390190505b50935083925060009150600090505b885181101561540a5788818151811015156153ab57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156153d257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615394565b5060005b875181101561548457878181518110151561542557fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561544c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161540e565b5060005b86518110156154fe57868181518110151561549f57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156154c657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615488565b5060005b855181101561557857858181518110151561551957fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561554057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101615502565b5060005b84518110156155f257848181518110151561559357fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156155ba57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161557c565b50909d9c50505050505050505050505050565b600160a060020a038216151561561a57600080fd5b6156248282614c7d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60408051610100810182526000808252606060208301819052928201819052918101829052608081018290529060a0820190815260200160008152602001600081525090565b6080604051908101604052806000600160a060020a031681526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061571957805160ff1916838001178555615746565b82800160010185558215615746579182015b8281111561574657825182559160200191906001019061572b565b506157529291506157e4565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106157975782800160ff19823516178555615746565b82800160010185558215615746579182015b828111156157465782358255916020019190600101906157a9565b815481835581811115612844576000838152602090206128449181019083015b61118891905b8082111561575257600081556001016157ea560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a72305820610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e390029
Swarm Source
bzzr://610674e4730bd95e2e009edaf423f7b091682747f0dade37b988385719774e39
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.