Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0.000005 ETH
Eth Value
$0.02 (@ $3,802.63/ETH)More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 105 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 16391902 | 699 days ago | IN | 0 ETH | 0.00079743 | ||||
Transfer | 16390638 | 699 days ago | IN | 0 ETH | 0.00057315 | ||||
Transfer | 16085472 | 742 days ago | IN | 0 ETH | 0.00076477 | ||||
Transfer | 16085455 | 742 days ago | IN | 0 ETH | 0.00123963 | ||||
Transfer | 16085437 | 742 days ago | IN | 0 ETH | 0.00095573 | ||||
Transfer | 15885587 | 770 days ago | IN | 0 ETH | 0.00092126 | ||||
Transfer | 15885526 | 770 days ago | IN | 0 ETH | 0.0013715 | ||||
Transfer | 15859224 | 773 days ago | IN | 0 ETH | 0.0005249 | ||||
Transfer | 15859217 | 773 days ago | IN | 0 ETH | 0.00067721 | ||||
Transfer | 15859207 | 773 days ago | IN | 0 ETH | 0.00051091 | ||||
Transfer | 15859201 | 773 days ago | IN | 0 ETH | 0.0005843 | ||||
Transfer | 15859194 | 773 days ago | IN | 0 ETH | 0.00053118 | ||||
Transfer | 15859187 | 773 days ago | IN | 0 ETH | 0.00062694 | ||||
Transfer | 15859175 | 773 days ago | IN | 0 ETH | 0.00051216 | ||||
Transfer | 15859168 | 773 days ago | IN | 0 ETH | 0.00065411 | ||||
Transfer | 15859163 | 773 days ago | IN | 0 ETH | 0.00050724 | ||||
Transfer | 15859157 | 773 days ago | IN | 0 ETH | 0.0006577 | ||||
Transfer | 15859152 | 773 days ago | IN | 0 ETH | 0.00052907 | ||||
Transfer | 15859145 | 773 days ago | IN | 0 ETH | 0.00067662 | ||||
Transfer | 15859139 | 773 days ago | IN | 0 ETH | 0.00046164 | ||||
Transfer | 15859131 | 773 days ago | IN | 0 ETH | 0.00067377 | ||||
Transfer | 15859124 | 773 days ago | IN | 0 ETH | 0.00050409 | ||||
Transfer | 15859117 | 773 days ago | IN | 0 ETH | 0.00062026 | ||||
Transfer | 15845131 | 775 days ago | IN | 0 ETH | 0.00062506 | ||||
Transfer | 15845124 | 775 days ago | IN | 0 ETH | 0.0008085 |
Latest 4 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
15635424 | 805 days ago | 0.00005 ETH | ||||
15635406 | 805 days ago | 0.000005 ETH | ||||
15635331 | 805 days ago | 0.00005 ETH | ||||
15635319 | 805 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
EPSRegister
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 // EPS Contracts v2.0.0 pragma solidity 0.8.17; import "./DelegateRegister.sol"; import "./ProxyRegister.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; /** * * @dev The EPS Register contract, implementing the proxy and deligate registers * */ contract EPSRegister is ProxyRegister, DelegateRegister { using SafeERC20 for IERC20; // ====================================================== // VARIABLES // ====================================================== // EPS treasury address: address public treasury; // Count of active ETH addresses for total supply uint256 public activeEthAddresses = 1; // 'Air drop' of EPSAPI to every address uint256 public epsAPIBalance = 10000; error ColdWalletCannotInteractUserHot(); error EthWithdrawFailed(); error UnknownAmount(); /** * @dev Constructor initialises the parameters for the proxy and delegate registers. */ constructor( uint256 proxyRegisterFee_, address treasury_, uint96 delegationRegisterFee_, uint32 delegationFeePercentage_, address weth_, uint256 deletionNominalEth_ ) ProxyRegister(proxyRegisterFee_, deletionNominalEth_) DelegateRegister(delegationRegisterFee_, delegationFeePercentage_, weth_) { setTreasuryAddress(treasury_); } // ====================================================== // VIEW METHODS // ====================================================== /** * @dev beneficiaryOf: Returns the beneficiary of the `tokenId` token. */ function beneficiaryOf( address tokenContract_, uint256 tokenId_, uint256 rightsIndex_ ) external view returns (address beneficiary_) { // 1 Check for an active delegation. We need a concept of a 'senior right', which // we have elected to be airdrop rights, being the right of the holder to receive // free benefits associated with being a beneficiary. If we are looking for a beneficiary // rights index out of bounds default to an airdrop rights query (rights index position 1) if (rightsIndex_ == 0 || rightsIndex_ > 15) { rightsIndex_ = 1; } beneficiary_ = getBeneficiaryByRight( tokenContract_, tokenId_, rightsIndex_ ); if (beneficiary_ == address(0)) { // 2 No delegation. Get the owner: beneficiary_ = IERC721(tokenContract_).ownerOf(tokenId_); // 3 Check if this is a proxied benefit if (coldIsLive(beneficiary_)) { beneficiary_ = coldToHot[beneficiary_]; } } } /** * @dev beneficiaryBalance: Returns the beneficiary balance of ETH. */ function beneficiaryBalance(address queryAddress_) external view returns (uint256 balance_) { // Get any balances held at a nominated cold address if (hotIsLive(queryAddress_)) { // This is a hot address with a current record - include the balance // held natively by this address and the cold: balance_ += queryAddress_.balance; balance_ += hotToRecord[queryAddress_].cold.balance; } else { // Check if this is cold wallet on an active record. If so do not include balance as that is absorbed into the proxy if (!coldIsLive(queryAddress_)) { balance_ += queryAddress_.balance; } } } /** * @dev beneficiaryBalanceOf: Returns the beneficiary balance for an ERC721, ERC20 or ERC777 contract. */ function beneficiaryBalanceOf( address queryAddress_, address tokenContract_, uint256 rightsIndex_ ) external view returns (uint256 balance_) { // 1a If this is a delegation container the balance is always 0, as the balance associated // will be for the benefit of either the original asset owner or the delegate, depending // on the delegation parameters: if (containerToDelegationId[queryAddress_] != 0) { return (0); } // 1b We need a concept of a 'senior right', which we have elected to be airdrop rights, // being the right of the holder to receive free benefits associated with being a beneficiary. // If we are looking for a beneficiary rights index out of bounds default to an airdrop // rights query (rights index position 1) if (rightsIndex_ == 0 || rightsIndex_ > 15) { rightsIndex_ = 1; } // 2 Get delegated balances: balance_ = getBalanceByRight(tokenContract_, queryAddress_, rightsIndex_); // 3 Add any balances held at a nominated cold address if (hotIsLive(queryAddress_)) { // This is a hot address with a current record - add on the balances // held natively by this address and the cold: balance_ += (IERC721(tokenContract_).balanceOf(queryAddress_)); address cold = hotToRecord[queryAddress_].cold; balance_ += IERC721(tokenContract_).balanceOf(cold); } else { // Check if this is cold wallet on an active record. If so do not include balance as that is absorbed into the proxy if (!coldIsLive(queryAddress_)) { balance_ += IERC721(tokenContract_).balanceOf(queryAddress_); } } } /** * @dev beneficiaryBalanceOf1155: Returns the beneficiary balance for an ERC1155. */ function beneficiaryBalanceOf1155( address queryAddress_, address tokenContract_, uint256 id_ ) external view returns (uint256 balance_) { // Add any balances held at a nominated cold address if (hotIsLive(queryAddress_)) { // This is a hot address with a current record - add on the balances // held natively by this address and the cold: balance_ += (IERC1155(tokenContract_).balanceOf(queryAddress_, id_)); address cold = hotToRecord[queryAddress_].cold; balance_ += IERC1155(tokenContract_).balanceOf(cold, id_); } else { // Check if this is cold wallet on an active record. If so do not include balance as that is absorbed into the proxy if (!coldIsLive(queryAddress_)) { balance_ += IERC1155(tokenContract_).balanceOf(queryAddress_, id_); } } } /** * @dev getAddresses: Returns the register address details (cold and delivery address) for a passed hot address */ function getAddresses(address _receivedAddress) public view returns ( address cold, address delivery, bool isProxied ) { if (coldIsLive(_receivedAddress)) revert ColdWalletCannotInteractUserHot(); if (hotIsLive(_receivedAddress)) { return ( hotToRecord[_receivedAddress].cold, hotToRecord[_receivedAddress].delivery, true ); } else { return (_receivedAddress, _receivedAddress, false); } } // ====================================================== // ADMIN FUNCTIONS // ====================================================== /** * @dev setTreasuryAddress: set the treasury address: */ function setTreasuryAddress(address _treasuryAddress) public onlyOwner { treasury = _treasuryAddress; } /** * @dev setActiveEthAddresses: used in the psuedo total supply calc: */ function setNNumberOfEthAddressesAndAirdropAmount( uint256 count_, uint256 air_ ) public onlyOwner { activeEthAddresses = count_; epsAPIBalance = air_; } /** * @dev withdrawETH: withdraw eth to the treasury: */ function withdrawETH(uint256 amount_) external onlyOwner { (bool success, ) = treasury.call{value: amount_}(""); if (!success) revert EthWithdrawFailed(); } /** * @dev withdrawERC20: Allow any ERC20s to be withdrawn Note, this is provided to enable the * withdrawal of any assets sent here in error */ function withdrawERC20(IERC20 token_, uint256 amount_) external onlyOwner { token_.safeTransfer(owner(), amount_); } /** * @dev withdrawERC721: Allow any ERC721s to be withdrawn. Note, all delegated ERC721s are in their * own contract, NOT on this contract. This is provided to enable the withdrawal of * any assets sent here in error using transferFrom not safeTransferFrom. */ function withdrawERC721(IERC721 token_, uint256 tokenId_) external onlyOwner { token_.transferFrom(address(this), owner(), tokenId_); } // ====================================================== // ETH CALL ENTRY POINT // ====================================================== /** * * @dev receive: Wallets need never connect directly to add to EPS register, rather they can * interact through ETH or ERC20 transfers. This 'air gaps' your wallet(s) from * EPS. ETH transfers can be used to pay the fee or delete a record (sent from either * the hot or the cold wallet). * */ receive() external payable { if ( msg.value != proxyRegisterFee && msg.value != deletionNominalEth && containerToDelegationId[msg.sender] == 0 && msg.sender != owner() ) revert UnknownAmount(); if (msg.value == proxyRegisterFee) { _payFee(msg.sender); } else if (msg.value == deletionNominalEth) { // Either hot or cold requesting a deletion: _deleteRecord(msg.sender, 0); } } /** * @dev _payFee: process receipt of payment */ function _payFee(address from_) internal { // 1) If our from address is a hot address and the proxy is pending payment we // can record this as paid and put the record live: if (hotToRecord[from_].status == ProxyStatus.PendingPayment) { _recordLive( from_, hotToRecord[from_].cold, hotToRecord[from_].delivery, hotToRecord[from_].provider ); } else if ( // 2) If our from address is a cold address and the proxy is pending payment we // can record this as paid and put the record live: hotToRecord[coldToHot[from_]].status == ProxyStatus.PendingPayment ) { _recordLive( coldToHot[from_], from_, hotToRecord[coldToHot[from_]].delivery, hotToRecord[coldToHot[from_]].provider ); } else revert NoPaymentPendingForAddress(); } // ====================================================== // ERC20 METHODS (to expose API) // ====================================================== /** * @dev Returns the name of the token. */ function name() public pure returns (string memory) { return "EPS API"; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public pure returns (string memory) { return "EPSAPI"; } function decimals() public pure returns (uint8) { return 0; } function balanceOf(address) public view returns (uint256) { return epsAPIBalance; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return activeEthAddresses * epsAPIBalance; } /** * @dev Doesn't move tokens at all. There was no spoon and there are no tokens. * Rather the quantity being 'sent' denotes the action the user is taking * on the EPS register, and the address they are 'sent' to is the address that is * being referenced by this request. */ function transfer(address to, uint256 amount) public returns (bool) { _tokenAPICall(msg.sender, to, amount); return (true); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: BUSL-1.1 // EPS Contracts v2.0.0 pragma solidity 0.8.17; import "@openzeppelin/contracts/access/Ownable.sol"; import "./IEPSProxyRegister.sol"; /** * * @dev The EPS Proxy Register contract. This contract implements a trustless proof of proxy between * two addresses, allowing the hot address to operate with the same rights as a cold address, and * for new assets to be delivered to a configurable delivery address. * */ contract ProxyRegister is IEPSProxyRegister, Ownable { // ====================================================== // CONSTANTS // ====================================================== // Constants denoting the API access types: uint256 constant HOT_NOMINATE_COLD = 1; uint256 constant COLD_ACCEPT_HOT = 2; uint256 constant CHANGE_DELIVERY = 3; uint256 constant DELETE_RECORD = 4; // ====================================================== // VARIABLES // ====================================================== // Fee to add a live proxy record to the register. This must be sent by the cold or hot wallet // address to the contract AFTER the hot wallet has nominated the cold wallet and the cold // wallet has accepted. If a fee is payable the record will remain in paymentPending status // until it is paid. If no fee is being charged the record is live after the cold wallet has // accepted the nomination. uint256 public proxyRegisterFee; // Cold wallet addresses need never call methods on EPS. All functionality is provided through // an ERC20 interface API, as well as traditional contract methods. To allow a cold wallet to delete // a proxy record without even using the ERC20 API, for example when the owner has lost access to // the hot wallet, we provide a nominal ETH payment, that if received from a cold wallet on a live // proxy will delete that proxy record. uint256 public deletionNominalEth; // ====================================================== // MAPPINGS // ====================================================== // Mapping between the hot wallet and the proxy record, the proxy record holding all the details of // the proxy relationship mapping(address => Record) hotToRecord; // Mapping from a cold address to the associated hot address mapping(address => address) coldToHot; /** * @dev Constructor initialises the register fee and nominal ETH to which can be sent to * the contract to end an existing proxy. */ constructor(uint256 registerFee_, uint256 deletionNominalEth_) { proxyRegisterFee = registerFee_; deletionNominalEth = deletionNominalEth_; } // ====================================================== // VIEW METHODS // ====================================================== /** * @dev isValidAddresses: Check the validity of sent addresses */ function isValidAddresses( address hot_, address cold_, address delivery_ ) public pure { if (cold_ == address(0)) revert ColdIsAddressZero(); if (cold_ == hot_) revert ColdAddressCannotBeTheSameAsHot(); if (delivery_ == address(0)) revert DeliveryIsAddressZero(); } /** * @dev addressIsAvailable: Return if an address isn't, as either hot or cold: * 1) live * 2) pending acceptance (unless we are checking as a cold address, which can be at pendingAcceptance infinite times) * 3) pending payment */ function addressIsAvailable(address queryAddress_, bool checkingHot_) public view returns (bool) { // Check as cold: ProxyStatus currentStatus = hotToRecord[coldToHot[queryAddress_]].status; if ( currentStatus == ProxyStatus.Live || currentStatus == ProxyStatus.PendingPayment || // Cold addresses CAN be pending acceptance as many times as they like, // in fact it is vital that they can be, so we only check this for the hot // address: (checkingHot_ && currentStatus == ProxyStatus.PendingAcceptance) ) { return false; } // Check as hot: currentStatus = hotToRecord[queryAddress_].status; if ( currentStatus == ProxyStatus.Live || currentStatus == ProxyStatus.PendingPayment || // Neither cold or hot can be a hot address, at any status currentStatus == ProxyStatus.PendingAcceptance ) { return false; } return true; } /** * @dev coldIsLive: Return if a cold wallet is live */ function coldIsLive(address cold_) public view returns (bool) { return (hotToRecord[coldToHot[cold_]].status == ProxyStatus.Live); } /** * @dev hotIsLive: Return if a hot wallet is live */ function hotIsLive(address hot_) public view returns (bool) { return (hotToRecord[hot_].status == ProxyStatus.Live); } /** * @dev coldIsActiveOnRegister: Return if a cold wallet is active */ function coldIsActiveOnRegister(address cold_) public view returns (bool) { ProxyStatus currentStatus = hotToRecord[coldToHot[cold_]].status; return (currentStatus == ProxyStatus.Live || currentStatus == ProxyStatus.PendingPayment); } /** * @dev hotIsActiveOnRegister: Return if a hot wallet is active */ function hotIsActiveOnRegister(address hot_) public view returns (bool) { ProxyStatus currentStatus = hotToRecord[hot_].status; return (currentStatus != ProxyStatus.None); } /** * @dev getProxyRecordForHot: Get proxy details for a hot address */ function getProxyRecordForHot(address hot_) public view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ) { Record memory currentItem = hotToRecord[hot_]; return ( currentItem.status, hot_, currentItem.cold, currentItem.delivery, currentItem.provider, currentItem.feePaid ); } /** * @dev getProxyRecordForCold: Get proxy details for a cold address */ function getProxyRecordForCold(address cold_) public view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ) { address currentHot = coldToHot[cold_]; Record memory currentItem = hotToRecord[currentHot]; return ( currentItem.status, currentHot, currentItem.cold, currentItem.delivery, currentItem.provider, currentItem.feePaid ); } /** * @dev Get proxy details for an address, checking cold and hot */ function getProxyRecordForAddress(address queryAddress_) external view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ) { // Check as cold: ProxyStatus currentStatus = hotToRecord[coldToHot[queryAddress_]].status; if ( currentStatus == ProxyStatus.Live || currentStatus == ProxyStatus.PendingPayment || (currentStatus == ProxyStatus.PendingAcceptance) ) { return getProxyRecordForCold(queryAddress_); } // Check as hot: currentStatus = hotToRecord[queryAddress_].status; if ( currentStatus == ProxyStatus.Live || currentStatus == ProxyStatus.PendingPayment || (currentStatus == ProxyStatus.PendingAcceptance) ) { return (getProxyRecordForHot(queryAddress_)); } // Address not found return (ProxyStatus.None, address(0), address(0), address(0), 0, false); } // ====================================================== // LIFECYCLE - NOMINATION // ====================================================== /** * @dev nominate: Hot Nominates cold, direct contract call */ function nominate( address cold_, address delivery_, uint64 provider_ ) external payable { if (msg.value != proxyRegisterFee) revert IncorrectProxyRegisterFee(); _processNomination(msg.sender, cold_, delivery_, msg.value, provider_); } /** * @dev _processNomination: Process the nomination */ // The hot wallet cannot be on any record, live or pending, as either a hot or cold wallet. // The cold wallet cannot be currently live or pending payment, but can be 'pending' on multiple records. It can // only accept one of those pending records (at at time - others can be accepted if it cancels the existing proxy) function _processNomination( address hot_, address cold_, address delivery_, uint256 feePaid_, uint64 provider_ ) internal { isValidAddresses(hot_, cold_, delivery_); if (!addressIsAvailable(hot_, true) || !addressIsAvailable(cold_, false)) revert AlreadyProxied(); // Record the mapping from the hot address to the record. This is pending until accepted by the cold address. hotToRecord[hot_] = Record( provider_, ProxyStatus.PendingAcceptance, feePaid_ == proxyRegisterFee, cold_, delivery_ ); emit NominationMade(hot_, cold_, delivery_, provider_); } /** * @dev acceptNomination: Cold accepts nomination, direct contract call * (though it is anticipated that most will use an ERC20 transfer) */ function acceptNomination(address hot_, uint64 provider_) external payable { _acceptNominationValidation(hot_, msg.sender); if (!hotToRecord[hot_].feePaid && msg.value != proxyRegisterFee) revert ProxyRegisterFeeRequired(); _acceptNomination(hot_, msg.sender, msg.value, provider_); } /** * @dev _acceptNominationValidation: validate passed parameters */ function _acceptNominationValidation(address hot_, address cold_) internal view { // Check that the address passed in matches a pending record for the hot address: if ( hotToRecord[hot_].cold != cold_ || hotToRecord[hot_].status != ProxyStatus.PendingAcceptance ) revert AddressMismatch(); // Check that the cold address isn't live or pending payment anywhere on the register: if (!addressIsAvailable(cold_, false)) revert AlreadyProxied(); } /** * @dev _acceptNomination: Cold wallet accepts nomination */ function _acceptNomination( address hot_, address cold_, uint256 feePaid_, uint64 providerCode_ ) internal { // Record the mapping from the cold to the hot address: coldToHot[cold_] = hot_; emit NominationAccepted( hot_, cold_, hotToRecord[hot_].delivery, providerCode_ ); if (hotToRecord[hot_].feePaid || feePaid_ == proxyRegisterFee) { _recordLive( hot_, cold_, hotToRecord[hot_].delivery, hotToRecord[hot_].provider ); } else { hotToRecord[hot_].status = ProxyStatus.PendingPayment; } } /** * @dev _recordLive: put a proxy record live */ function _recordLive( address hot_, address cold_, address delivery_, uint64 provider_ ) internal { hotToRecord[hot_].feePaid = true; hotToRecord[hot_].status = ProxyStatus.Live; emit ProxyRecordLive(hot_, cold_, delivery_, provider_); } // ====================================================== // LIFECYCLE - CHANGING DELIVERY ADDRESS // ====================================================== /** * @dev updateDeliveryAddress: Change delivery address on an existing proxy record. */ function updateDeliveryAddress(address delivery_, uint256 provider_) external { _updateDeliveryAddress(msg.sender, delivery_, provider_); } /** * @dev _updateDeliveryAddress: unified delivery address update processing */ function _updateDeliveryAddress( address caller_, address delivery_, uint256 provider_ ) internal { if (delivery_ == address(0)) revert DeliveryCannotBeTheZeroAddress(); // Only hot can change delivery address: if (hotIsActiveOnRegister(caller_)) { // Hot is requesting the change of address. // Get the associated hot address and process the address change _processUpdateDeliveryAddress(caller_, delivery_, provider_); // } else if (coldIsActiveOnRegister(caller_)) { // Cold is requesting the change of address. Cold cannot perform this operation: revert OnlyHotAddressCanChangeAddress(); // } else { // Address not found, revert revert NoRecordFoundForAddress(); } } /** * @dev _processUpdateDeliveryAddress: Process the update of the delivery address */ function _processUpdateDeliveryAddress( address hot_, address delivery_, uint256 provider_ ) internal { Record memory priorItem = hotToRecord[hot_]; hotToRecord[hot_].delivery = delivery_; emit DeliveryUpdated( hot_, priorItem.cold, delivery_, priorItem.delivery, provider_ ); } // ====================================================== // LIFECYCLE - DELETING A RECORD // ====================================================== /** * @dev deleteRecord: Delete a proxy record, if found */ function deleteRecord(uint256 provider_) external { _deleteRecord(msg.sender, provider_); } /** * @dev _deleteRecord: unified delete record processing */ function _deleteRecord(address caller_, uint256 provider_) internal { // Hot can delete any entry that exists for it: if (hotIsActiveOnRegister(caller_)) { // Hot is requesting the deletion. // Get the associated cold address and process the deletion. _processDeleteRecord( caller_, hotToRecord[caller_].cold, Participant.Hot, provider_ ); // Cold can only delete a record that it has accepted. This means a record // at either pendingPayment or live } else if (coldIsActiveOnRegister(caller_)) { // Cold is requesting the deletion. // Get the associated hot address and process the deletion _processDeleteRecord( coldToHot[caller_], caller_, Participant.Cold, provider_ ); } else { // Address not found, revert revert NoRecordFoundForAddress(); } } /** * @dev _processDeleteRecord: process record deletion */ function _processDeleteRecord( address hot_, address cold_, Participant initiator_, uint256 provider_ ) internal { // Delete the register entry delete hotToRecord[hot_]; // Delete the cold to hot mapping: delete coldToHot[cold_]; emit RecordDeleted(initiator_, cold_, hot_, provider_); } // ====================================================== // ERC20 CALL ENTRY POINT // ====================================================== /** * @dev tokenAPICall: receive a token API call */ function _tokenAPICall( address from_, address to_, uint256 amount_ ) internal { // The final digit of the amount are the action code, the // rest of the amount is the provider code uint256 actionCode = amount_ % 10; if (actionCode == 0 || actionCode > 4) revert UnrecognisedEPSAPIAmount(); uint64 providerCode = uint64(amount_ / 10); if (actionCode == HOT_NOMINATE_COLD) _processNomination(from_, to_, from_, 0, providerCode); else if (actionCode == COLD_ACCEPT_HOT) { _acceptNominationValidation(to_, from_); _acceptNomination(to_, from_, 0, providerCode); } else if (actionCode == CHANGE_DELIVERY) _updateDeliveryAddress(from_, to_, providerCode); else if (actionCode == DELETE_RECORD) _deleteRecord(from_, providerCode); } // ====================================================== // CONFIGURATION // ====================================================== /** * @dev setRegisterFee: set the fee for accepting a registration: */ function setRegisterFee(uint256 registerFee_) external onlyOwner { proxyRegisterFee = registerFee_; } /** * @dev setDeletionNominalEth: set the nominal ETH transfer that represents an address ending a proxy */ function setDeletionNominalEth(uint256 deleteNominalEth_) external onlyOwner { deletionNominalEth = deleteNominalEth_; } }
// SPDX-License-Identifier: BUSL-1.1 // EPS Contracts v2.0.0 pragma solidity 0.8.17; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/proxy/Clones.sol"; import "./IDelegationContainer.sol"; import "./IEPSDelegateRegister.sol"; /** * * @dev The EPS Delegation Register contract. This contract is part of the EPSRegister, and allows the owner * of an ERC721 to delegate rights to another address (the delegate address). The owner decides what rights * they wish to delegate, how long for, and if they require payment for the delegation. For example, a holder * might decide that they wish to delegate physical event rights to another for three months. They want 0.5 ETH * for this privelidge. They load the delegation here, with the asset being custodied in a delegation container * that the original asset owner owns. Other addresses can accept that delegation proposal by paying the ETH * due. This loads the delegation details to the register, and means that query functions like beneficiaryOf and * beneficiaryBalanceOf return data that reflect this delegation. * */ contract DelegateRegister is IEPSDelegateRegister, Ownable, IERC721Receiver { using Clones for address payable; // ======================================= // CONSTANTS // ======================================= // Total rights, positions 13, 14 and 15 reserved for project specific rights. uint256 constant TOTAL_RIGHTS = 10000100001000010000100001000010000100001000010000100001000010000100001; //15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 // Rights slice length - this is used in run time to slice up rights integers into their component parts. uint256 constant RIGHTS_SLICE_LENGTH = 5; // Default for any percentages, which must be held as a prortion of 100,000, i.e. a // percentage of 5% is held as 5,000. uint256 constant PERCENTAGE_DENOMINATOR = 100000; address immutable weth; // ======================================= // STORAGE // ======================================= // Unique ID for every proposed delegation. uint64 public delegationId; // Unique ID for every collection offer. uint64 public offerId; // Basic fee charged by the protocol for operations that require payment, namely the acceptance of a delegation // or the secondary sale of rights. uint96 public delegationRegisterFee; // Percentage fee applied to proceeds derived from protocol actions. For example, if this is set to 0.5% (500) and // an asset owner has charged 1 ETH for a delegation this will be a charge of 0.005 ETH. Note that this is charged in // addition to the base fee. This is important, as the base fee is all the protocol will take for fee free transactions, // and some revenue is required to maintain the service. uint32 public delegationFeePercentage; // The string descriptions associated with the default rights codes. Only position 1 to 12 will be used, but full length // provided here for future flexiblity string[16] public defaultRightsCodes; // Lock for delegation container address bool public delegationContainerTemplateLocked; // Provide ability to pause new sales (in-ife functionality including asset reclaim cannot be paused) bool public marketplacePaused; struct DelegationRecord { // The unique identifier for every delegation. Note that this is stamped on each delegation container. This doesn't mean // that every delegation Id will make it to the register, as this might be a proposed delegation that is not taken // up by anyone. uint64 delegationId; // 64 // The owner of the asset that is being containerised for delegation. address owner; // 160 // The end time for this delegation. After the end time the owner can remove the asset. uint64 endTime; // 64 // The address of the delegate for this delegation address delegate; // 160 // Delegate rights integer: uint256 delegateRightsInteger; } struct DelegationParameters { // The provider who has originated this delegation. uint64 provider; // 64 // The address proposed as deletage. The owner of an asset can specify a particular address OR they can leave // this as address 0 if they will accept any delegate, subject to payment of the fee (if any) address delegate; // 160 // The duration of the delegation. uint24 duration; // 24 // The fee that the delegate must pay for this delegation to go live. uint96 fee; // 96 // Owner rights integer: uint256 ownerRightsInteger; // Delegate rights integer: uint256 delegateRightsInteger; // URI string URI; // Offer ID, passed if this is accepting an offer, otherwise will be 0: uint64 offerId; } struct Offer { // Slot 1 160 + 24 + 32 + 8 = 224 // The address that is making the offer address offerMaker; // 160 // The delegation duration time in days for this offer. uint24 delegationDuration; //24 // When this offer expires uint32 expiry; // 32 // Boolean to note a collection offer bool collectionOffer; // 8 // Slot 2 160 + 96 = 256 // The collection the offer is for address collection; // Offer amount (in provided ERC) uint96 offerAmount; // Slot 3 = 256 // TokenId, (is ignored for collection offers) uint256 tokenId; // Slot 4 = 256 // Delegate rights integer that they are requesting: uint256 delegateRightsInteger; // ERC20 that they are paying in: address paymentERC20; } // Configurable payment options for offers: struct ERC20PaymentOptions { bool isValid; uint96 registerFee; } // The address of the delegation container template. address payable public delegationContainer; // Map a tokenContract and Id to a delegation record. // bytes32 mapping for this is tokenContract and tokenId mapping(bytes32 => DelegationRecord) public tokenToDelegationRecord; // Map a token contract and query address to a balance struct: // bytes32 mapping for this is tokenContract and address being queried mapping(bytes32 => uint256) public contractToBalanceByRights; // Map a deployed container contract to a delegation record. mapping(address => uint64) public containerToDelegationId; // Map a token contract to a listing of contract specific rights codes: mapping(address => string[16]) public tokenContractToRightsCodes; // Map collection offer ID to offer: mapping(uint64 => Offer) public offerIdToOfferDetails; // Store offer ERC20 payment options, the returned value if the base fee for that ERC20 mapping(address => ERC20PaymentOptions) public validERC20PaymentOption; /** * * @dev Constructor * */ constructor( uint96 delegationRegisterFee_, uint32 delegationFeePercentage_, address weth_ ) { delegationRegisterFee = delegationRegisterFee_; delegationFeePercentage = delegationFeePercentage_; weth = weth_; } // ======================================= // GETTERS // ======================================= /** * * @dev getFeeDetails: Get fee details (register fee and fee percentage). * */ function getFeeDetails() external view returns (uint96 delegationRegisterFee_, uint32 delegationFeePercentage_) { return (delegationRegisterFee, delegationFeePercentage); } /** * * @dev getDelegationIdForContainer: Get delegation ID for a given container. * */ function getDelegationIdForContainer(address container_) external view returns (uint64 delegationId_) { return (containerToDelegationId[container_]); } /** * * @dev getBalanceByRight: Get balance by rights * */ function getBalanceByRight( address tokenContract_, address queryAddress_, uint256 rightsIndex_ ) public view returns (uint256) { // Create the hash for this contract and address combination: bytes32 queryHash = _getParticipantHash(tokenContract_, queryAddress_); return ( _sliceRightsInteger(rightsIndex_, contractToBalanceByRights[queryHash]) ); } /** * * @dev getBeneficiaryByRight: Get beneficiary by rights * */ function getBeneficiaryByRight( address tokenContract_, uint256 tokenId_, uint256 rightsIndex_ ) public view returns (address) { bytes32 keyHash = _getKeyHash(tokenContract_, tokenId_); DelegationRecord memory currentRecord = tokenToDelegationRecord[keyHash]; // Check for delegation if (currentRecord.delegationId != 0) { if ( _sliceRightsInteger( rightsIndex_, currentRecord.delegateRightsInteger ) == 0 ) { // Owner has the rights return (currentRecord.owner); } else { // Delegate has the rights return (currentRecord.delegate); } } // Return 0 if there is nothing stored here. return (address(0)); } // ======================================= // SETTERS // ======================================= /** * @dev addOfferPaymentERC20: add an offer ERC20 payment option */ function addOfferPaymentERC20(address contractForERC20_, uint96 baseFee_) public onlyOwner { validERC20PaymentOption[contractForERC20_].isValid = true; validERC20PaymentOption[contractForERC20_].registerFee = baseFee_; } /** * @dev removeOfferPaymentERC20: remove an offer ERC20 payment option */ function removeOfferPaymentERC20(address contractForERC20_) public onlyOwner { delete validERC20PaymentOption[contractForERC20_]; } /** * @dev setDefaultRightsCodes: set the string description for the 12 defauls rights codes. Note this is for information only - these strings are * not used in the contract for any purpose. */ function setDefaultRightsCodes( uint256 rightsIndex_, string memory rightsDescription_ ) public onlyOwner { defaultRightsCodes[rightsIndex_] = rightsDescription_; } /** * @dev setProjectSpecificRightsCodes: set the string description for the 3 configurable rights codes that can be set per token contract. These * occupy positions 13, 14 and 15 on the rights index. These may be seldom used, but the idea is to give projects three positions in the rights * integer where they can determine their own authorities. */ function setProjectSpecificRightsCodes( address tokenContract_, uint256 rightsIndex_, string memory rightsDescription_ ) public onlyOwner { tokenContractToRightsCodes[tokenContract_][ rightsIndex_ ] = rightsDescription_; } /** * @dev setDelegationRegisterFee: set the base fee for transactions. */ function setDelegationRegisterFee(uint96 delegationRegisterFee_) public onlyOwner { delegationRegisterFee = delegationRegisterFee_; } /** * @dev setDelegationFeePercentage: set the percentage fee taken from transactions that involve payment. */ function setDelegationFeePercentage(uint32 delegationFeePercentage_) public onlyOwner { delegationFeePercentage = delegationFeePercentage_; } /** * @dev lockDelegationContainerTemplate: allow the delegation container template to be locked at a given address. */ function lockDelegationContainerTemplate() public onlyOwner { delegationContainerTemplateLocked = true; } /** * * @dev setDelegationContainer: set the container address. Can only be called once. Not set in the constructor * as the container needs to know the address of the register (which IS set in the constructor) * so we have a chicken and egg situation to resolve. Only allow to be set ONCE. * */ function setDelegationContainer(address payable delegationContainer_) public onlyOwner { if (delegationContainerTemplateLocked) revert TemplateContainerLocked(); delegationContainer = delegationContainer_; } /** * @dev toggleMarketplace: allow the marketplace to be paused / unpaused */ function pauseMarketplace(bool marketPlacePaused) public onlyOwner { marketplacePaused = marketPlacePaused; } // ======================================= // VALIDATION // ======================================= /** * @dev Throws if this is not a valid container, returnds delegation Id if it's valid. */ function isValidContainer(address container_) public view returns (uint64 recordId_) { recordId_ = containerToDelegationId[container_]; if (recordId_ == 0) revert InvalidContainer(); return (recordId_); } /** * @dev Throws if marketplace is not open */ function _isMarketOpen() internal view { if (marketplacePaused) revert MarketPlacePaused(); } // ======================================= // RIGHTS 'BOOKKEEPING' // ======================================= /** * * @dev _increaseRightsInteger: increase the passed rights integer with the passed integer * */ function _increaseRightsInteger( address containerAddress_, address participantAddress_, address tokenContract_, uint256 tokenId_, bytes32 participantHash_, uint256 rightsInteger_ ) internal { contractToBalanceByRights[participantHash_] += rightsInteger_; // An increase of rights is implicitly a transfer from the container that holds the asset: emit TransferRights( containerAddress_, participantAddress_, tokenContract_, tokenId_, rightsInteger_ ); } /** * * @dev _decreaseRightsInteger: decrease the passed rights integer with the passed integer * */ function _decreaseRightsInteger( address containerAddress_, address participantAddress_, address tokenContract_, uint256 tokenId_, bytes32 participantHash_, uint256 rightsInteger_ ) internal { contractToBalanceByRights[participantHash_] -= rightsInteger_; // An decrease of rights is implicitly a transfer to the container that holds the asset: emit TransferRights( participantAddress_, containerAddress_, tokenContract_, tokenId_, rightsInteger_ ); } /** * * @dev _adjustBalancesAtEndOfDelegation: reduce balances when a delegation has ended * */ function _adjustBalancesAtEndOfDelegation( address tokenContract_, address container_, address owner_, address delegate_, uint256 tokenId_, uint64 delegationId_ ) internal returns (bytes32 keyHash_, bytes32 ownerHash_) { (bytes32 keyHash, bytes32 ownerHash, bytes32 delegateHash) = _getAllHashes( tokenContract_, tokenId_, owner_, delegate_ ); _decreaseRightsInteger( container_, owner_, tokenContract_, tokenId_, ownerHash, (TOTAL_RIGHTS - tokenToDelegationRecord[keyHash].delegateRightsInteger) ); _decreaseRightsInteger( container_, delegate_, tokenContract_, tokenId_, delegateHash, tokenToDelegationRecord[keyHash].delegateRightsInteger ); // Emit event to show that this delegation is now _emitComplete(delegationId_); return (keyHash, ownerHash); } // ======================================= // DELEGATION RECORDS MANAGEMENT // ======================================= /** * * @dev _assignDelegationId: Create new delegation Id and assign it. * */ function _assignDelegationId(address container_) internal { delegationId += 1; containerToDelegationId[container_] = delegationId; } /** * * @dev _resetDelegationRecordDetails: reset to default on relist * */ function _resetDelegationRecordDetails(bytes32 keyHash_) internal { _updateDelegationRecordDetails(keyHash_, 0, address(0), 0); } /** * * @dev _updateDelegationRecordDetails: common processing for delegation record updates * */ function _updateDelegationRecordDetails( bytes32 keyHash_, uint64 endTime_, address delegate_, uint256 delegateRightsInteger_ ) internal { tokenToDelegationRecord[keyHash_].endTime = endTime_; tokenToDelegationRecord[keyHash_].delegate = delegate_; tokenToDelegationRecord[keyHash_] .delegateRightsInteger = delegateRightsInteger_; } /** * * @dev _getAllHashes: get the hashes for tracking owner and delegate * */ function _getAllHashes( address tokenContract_, uint256 tokenId_, address owner_, address delegate_ ) internal pure returns ( bytes32 keyHash_, bytes32 ownerHash_, bytes32 delegateHash_ ) { (keyHash_, ownerHash_) = _getKeyAndParticipantHashes( tokenContract_, tokenId_, owner_ ); delegateHash_ = keccak256(abi.encodePacked(tokenContract_, delegate_)); return (keyHash_, ownerHash_, delegateHash_); } /** * * @dev _getKeyAndParticipantHashes: get key and one participant hashes * */ function _getKeyAndParticipantHashes( address tokenContract_, uint256 tokenId_, address participant_ ) internal pure returns (bytes32 keyHash_, bytes32 participantHash_) { keyHash_ = _getKeyHash(tokenContract_, tokenId_); participantHash_ = _getParticipantHash(tokenContract_, participant_); return (keyHash_, participantHash_); } /** * * @dev _getParticipantHash: get one participant hash * */ function _getParticipantHash(address tokenContract_, address participant_) internal pure returns (bytes32 participantHash_) { participantHash_ = keccak256( abi.encodePacked(tokenContract_, participant_) ); return (participantHash_); } /** * * @dev _getKeyHash: get key hash * */ function _getKeyHash(address tokenContract_, uint256 tokenId_) internal pure returns (bytes32 keyHash_) { keyHash_ = keccak256(abi.encodePacked(tokenContract_, tokenId_)); return (keyHash_); } /** * * @dev _sliceRightsInteger: extract a position from the rights integer * */ function _sliceRightsInteger(uint256 position_, uint256 rightsInteger_) internal pure returns (uint256 value) { uint256 exponent = (10**(position_ * RIGHTS_SLICE_LENGTH)); uint256 divisor; if (position_ == 1) { divisor = 1; } else { divisor = (10**((position_ - 1) * RIGHTS_SLICE_LENGTH)); } return ((rightsInteger_ % exponent) / divisor); } /** * * @dev sundryEvent: generic function for delegation register emits * */ function sundryEvent( uint64 provider_, address address1_, address address2_, uint256 int1_, uint256 int2_, uint256 int3_, uint256 int4_ ) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); // Emit a sundry event so we know about it: emit SundryEvent( provider_, recordId, address1_, address2_, int1_, int2_, int3_, int4_ ); } // ======================================= // DELEGATION CREATION // ======================================= /** * * @dev _createDelegationFromOffer: call when an offer is being accepted *_createDelegation */ function _createDelegationFromOffer( DelegationParameters memory delegationData_, uint256 tokenId_, address owner_, bytes32 keyHash_, bytes32 ownerHash_, address tokenContract_, address container_ ) internal { _offerAccepted(delegationData_, tokenId_, owner_, tokenContract_); _createDelegation( owner_, uint64(block.timestamp) + (uint64(delegationData_.duration) * 1 days), delegationData_.delegate, delegationData_.delegateRightsInteger, keyHash_ ); _increaseRightsInteger( container_, owner_, tokenContract_, tokenId_, ownerHash_, (TOTAL_RIGHTS - delegationData_.delegateRightsInteger) ); _increaseRightsInteger( container_, delegationData_.delegate, tokenContract_, tokenId_, _getParticipantHash(tokenContract_, delegationData_.delegate), delegationData_.delegateRightsInteger ); _emitDelegationAccepted( delegationData_, container_, tokenContract_, tokenId_, owner_ ); } /** * * @dev _emitDelegationAccepted * */ function _emitDelegationAccepted( DelegationParameters memory delegationData_, address container_, address tokenContract_, uint256 tokenId_, address owner_ ) internal { emit DelegationAccepted( delegationData_.provider, delegationId, container_, tokenContract_, tokenId_, owner_, delegationData_.delegate, uint64(block.timestamp) + (uint64(delegationData_.duration) * 1 days), delegationData_.delegateRightsInteger, 0, delegationData_.URI ); } /** * * @dev _createDelegation: create the delegation record * */ function _createDelegation( address owner_, uint64 endTime_, address delegate_, uint256 delegateRightsInteger_, bytes32 keyHash_ ) internal { tokenToDelegationRecord[keyHash_] = DelegationRecord( delegationId, owner_, endTime_, delegate_, delegateRightsInteger_ ); } /** * * @dev _offerAccepted: call when an offer is being accepted * */ function _offerAccepted( DelegationParameters memory delegationData_, uint256 tokenId_, address owner_, address collection_ ) internal { // 1) Check this is a valid match. Offer memory offerData = offerIdToOfferDetails[delegationData_.offerId]; if ( (offerData.collection != collection_) || (!offerData.collectionOffer && offerData.tokenId != tokenId_) || (delegationData_.delegate != offerData.offerMaker) || (delegationData_.duration != offerData.delegationDuration) || (delegationData_.fee != offerData.offerAmount) || (delegationData_.delegateRightsInteger != offerData.delegateRightsInteger) || (block.timestamp > offerData.expiry) ) { revert InvalidOffer(); } // 2) Perform payment processing: // If the payment ERC20 is address(0) this means the default, which is weth // (doing this saves a slot on the offer struct) address paymentERC20Address; uint256 registerFee; if (offerData.paymentERC20 == address(0)) { paymentERC20Address = weth; registerFee = delegationRegisterFee; } else { paymentERC20Address = offerData.paymentERC20; if (!validERC20PaymentOption[paymentERC20Address].isValid) revert InvalidERC20(); registerFee = validERC20PaymentOption[paymentERC20Address].registerFee; } // Cancel the offer as it is being actioned delete offerIdToOfferDetails[delegationData_.offerId]; uint256 claimAmount = (delegationData_.fee + registerFee); // Claim payment from the offerer: if (claimAmount > 0) { IERC20(paymentERC20Address).transferFrom( delegationData_.delegate, address(this), claimAmount ); } uint256 epsFee; // The fee taken by the protocol is a percentage of the delegation fee + the register fee. This ensures // that even for free delegations the platform takes a small fee to remain sustainable. if (delegationData_.fee == 0) { epsFee = registerFee; } else { epsFee = ((delegationData_.fee * delegationFeePercentage) / PERCENTAGE_DENOMINATOR) + registerFee; } // Handle delegation Fee remittance if (delegationData_.fee != 0) { IERC20(paymentERC20Address).transfer(owner_, (claimAmount - epsFee)); } emit OfferAccepted( delegationData_.provider, delegationData_.offerId, epsFee, paymentERC20Address ); } /** * * @dev _decodeParameters * */ function _decodeParameters(bytes memory data_) internal pure returns (DelegationParameters memory) { // Decode the delegation parameters from the data_ passed in: ( uint64 paramProvider, address paramDelegate, uint24 paramDuration, uint96 paramFee, uint256 paramOwnerRights, uint256 paramDelegateRights, string memory paramURI, uint64 paramPfferId ) = abi.decode( data_, (uint64, address, uint24, uint96, uint256, uint256, string, uint64) ); return ( DelegationParameters( paramProvider, paramDelegate, paramDuration, paramFee, paramOwnerRights, paramDelegateRights, paramURI, paramPfferId ) ); } /** * * @dev onERC721Received - tokens are containerised for delegation by being sent to this * contract with the correct bytes data. NOTE - DO NOT JUST SEND ERC721s TO THIS * CONTRACT. This MUST be called from an interface that correctly encodes the * bytes parameter data for decode. * */ function onERC721Received( address, address from_, uint256 tokenId_, bytes memory data_ ) external override returns (bytes4) { if (from_ == address(0)) revert DoNoMintToThisAddress(); address tokenContract = msg.sender; // Decode the delegation parameters from the data_ passed in: DelegationParameters memory delegationData = _decodeParameters(data_); // Check that we have been passed valid rights details for the owner and the beneficiary. if ( delegationData.ownerRightsInteger + delegationData.delegateRightsInteger != TOTAL_RIGHTS ) revert InvalidRights(); // Cannot assign the current owner as the delegate: if (delegationData.delegate == from_) revert OwnerCannotBeDelegate(); // Create the container contract: address newDelegationContainer = delegationContainer.clone(); // Assign the container a delegation Id _assignDelegationId(newDelegationContainer); if (delegationData.offerId == 0) { emit DelegationCreated( delegationData.provider, delegationId, newDelegationContainer, from_, delegationData.delegate, delegationData.fee, delegationData.duration, tokenContract, tokenId_, delegationData.delegateRightsInteger, delegationData.URI ); } (bytes32 keyHash, bytes32 ownerHash) = _getKeyAndParticipantHashes( tokenContract, tokenId_, from_ ); // If this was accepting an offer we save a full delegation record now: if (delegationData.offerId != 0) { _isMarketOpen(); _createDelegationFromOffer( delegationData, tokenId_, from_, keyHash, ownerHash, tokenContract, newDelegationContainer ); } else { _createDelegation(from_, 0, address(0), 0, keyHash); _increaseRightsInteger( newDelegationContainer, from_, tokenContract, tokenId_, ownerHash, TOTAL_RIGHTS ); } // Initialise storage data: IDelegationContainer(newDelegationContainer).initialiseDelegationContainer( payable(from_), payable(delegationData.delegate), delegationData.fee, delegationData.duration, msg.sender, tokenId_, delegationData.delegateRightsInteger, delegationData.URI, delegationData.offerId ); // Deliver the ERC721 to the container: IERC721(msg.sender).safeTransferFrom( address(this), newDelegationContainer, tokenId_ ); return this.onERC721Received.selector; } /** * * @dev saveDelegationRecord: Save the complete delegation to the register. * */ function saveDelegationRecord( uint64 provider_, address tokenContract_, uint256 tokenId_, address owner_, address delegate_, uint64 endTime_, uint256 delegateRightsInteger_, string memory containerURI_ ) external payable { _isMarketOpen(); // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 ownerHash, bytes32 delegateHash) = _getAllHashes( tokenContract_, tokenId_, owner_, delegate_ ); _updateDelegationRecordDetails( keyHash, endTime_, delegate_, delegateRightsInteger_ ); // We can just subtract the delegate rights integer as we added in a // TOTAL_RIGHTS for the owner while the delegation was pending: _decreaseRightsInteger( msg.sender, owner_, tokenContract_, tokenId_, ownerHash, delegateRightsInteger_ ); _increaseRightsInteger( msg.sender, delegate_, tokenContract_, tokenId_, delegateHash, delegateRightsInteger_ ); emit DelegationAccepted( provider_, recordId, msg.sender, tokenContract_, tokenId_, owner_, delegate_, endTime_, delegateRightsInteger_, msg.value, containerURI_ ); } /** * * @dev acceptOfferPriorToCommencement: Accept an offer from a container that is pre-commencement * */ function acceptOfferPriorToCommencement( uint64 provider_, address owner_, address delegate_, uint24 duration_, uint96 fee_, uint256 delegateRightsInteger_, uint64 offerId_, address tokenContract_, uint256 tokenId_ ) external { _isMarketOpen(); // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 ownerHash) = _getKeyAndParticipantHashes( tokenContract_, tokenId_, owner_ ); // Remove the temporary full rights for the owner: _decreaseRightsInteger( msg.sender, owner_, tokenContract_, tokenId_, ownerHash, TOTAL_RIGHTS ); // Emit event to show that the previous listing is removed: _emitComplete(recordId); // Move the container to a new delegation Id: _assignDelegationId(msg.sender); _createDelegationFromOffer( DelegationParameters( provider_, delegate_, duration_, fee_, TOTAL_RIGHTS - delegateRightsInteger_, delegateRightsInteger_, "", offerId_ ), tokenId_, owner_, keyHash, ownerHash, tokenContract_, msg.sender ); } // ======================================= // SECONDARY MARKET / TRANSFERS // ======================================= /** * * @dev containerListedForSale: record that a delegation container has been listed for sale. * */ function containerListedForSale(uint64 provider_, uint96 salePrice_) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); // Emit an event so we know about it: emit ContainerListedForSale(provider_, recordId, msg.sender, salePrice_); } /** * * @dev containerDetailsUpdated: record that an asset owner has updated container details. * */ function containerDetailsUpdated( uint64 provider_, address delegate_, uint256 fee_, uint256 duration_, uint256 delegateRightsInteger_ ) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); // Emit an event so we know about it: emit ContainerDetailsUpdated( provider_, recordId, msg.sender, delegate_, fee_, duration_, delegateRightsInteger_ ); } /** * * @dev changeAssetOwner: Change the owner of the container on sale. * */ function changeAssetOwner( uint64 provider_, address newOwner_, address tokenContract_, uint256 tokenId_, uint256 epsFee_ ) external { _isMarketOpen(); // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 newOwnerHash) = _getKeyAndParticipantHashes( tokenContract_, tokenId_, newOwner_ ); // Save the old owner: address oldOwner = tokenToDelegationRecord[keyHash].owner; // Get hash for old owner: bytes32 oldOwnerHash = _getParticipantHash(tokenContract_, oldOwner); // This has been called from a container, and that method is assetOwner only. Procced to // update the register accordingly. // Update owner: tokenToDelegationRecord[keyHash].owner = newOwner_; // Reduce the contract to balance rights of the old owner by the owner rights integer // for this delegation record, and likewise increase it for the new owner: uint256 rightsInteger = TOTAL_RIGHTS - tokenToDelegationRecord[keyHash].delegateRightsInteger; _decreaseRightsInteger( msg.sender, oldOwner, tokenContract_, tokenId_, oldOwnerHash, rightsInteger ); _increaseRightsInteger( msg.sender, newOwner_, tokenContract_, tokenId_, newOwnerHash, rightsInteger ); emit DelegationOwnerChanged(provider_, recordId, newOwner_, epsFee_); } /** * * @dev List the delegation for sale. * */ function delegationListedForSale(uint64 provider_, uint96 salePrice_) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); // Emit an event so we know about it: emit DelegationListedForSale(provider_, recordId, salePrice_); } /** * * @dev changeDelegate: Change the delegate on a delegation. * */ function changeDelegate( uint64 provider_, address newDelegate_, address tokenContract_, uint256 tokenId_, uint256 epsFee_ ) external { _isMarketOpen(); // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 newDelegateHash) = _getKeyAndParticipantHashes( tokenContract_, tokenId_, newDelegate_ ); // Save the old delegate: address oldDelegate = tokenToDelegationRecord[keyHash].delegate; // Get hashes for new and old delegate: bytes32 oldDelegateHash = _getParticipantHash(tokenContract_, oldDelegate); // This has been called from a container, and that method is delegate only. Procced to // update the register accordingly: // Update delegate: tokenToDelegationRecord[keyHash].delegate = newDelegate_; // Reduce the contract to balance rights of the old delegate by the delegate rights integer // for this delegation record, and likewise increase it for the new delegate: uint256 rightsInteger = tokenToDelegationRecord[keyHash] .delegateRightsInteger; _decreaseRightsInteger( msg.sender, oldDelegate, tokenContract_, tokenId_, oldDelegateHash, rightsInteger ); _increaseRightsInteger( msg.sender, newDelegate_, tokenContract_, tokenId_, newDelegateHash, rightsInteger ); emit DelegationDelegateChanged(provider_, recordId, newDelegate_, epsFee_); } // ======================================= // END OF DELEGATION // ======================================= /** * * @dev acceptOfferAfterDelegationCompleted: Perform acceptance processing where the user is * ending a delegation and accepting an offer. * */ function acceptOfferAfterDelegationCompleted( uint64 provider_, address owner_, address oldDelegate_, address newDelegate_, uint24 duration_, uint96 fee_, uint256 delegateRightsInteger_, uint64 offerId_, address tokenContract_, uint256 tokenId_ ) external payable { _isMarketOpen(); // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 ownerHash) = _adjustBalancesAtEndOfDelegation( tokenContract_, msg.sender, owner_, oldDelegate_, tokenId_, recordId ); // Move the container to a new delegation Id: _assignDelegationId(msg.sender); _createDelegationFromOffer( DelegationParameters( provider_, newDelegate_, duration_, fee_, TOTAL_RIGHTS - delegateRightsInteger_, delegateRightsInteger_, "", offerId_ ), tokenId_, owner_, keyHash, ownerHash, tokenContract_, msg.sender ); } /** * * @dev deleteEntry: remove a completed entry from the register. * */ function deleteEntry( address tokenContract_, uint256 tokenId_, address owner_, address delegate_ ) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, ) = _adjustBalancesAtEndOfDelegation( tokenContract_, msg.sender, owner_, delegate_, tokenId_, recordId ); // Delete the register entry and owner and delegate data: delete tokenToDelegationRecord[keyHash]; delete containerToDelegationId[msg.sender]; } /** * * @dev relistEntry: relist an entry for a new delegation * */ function relistEntry( uint64 provider_, address owner_, address oldDelegate_, address newDelegate_, uint96 fee_, uint24 durationInDays_, address tokenContract_, uint256 tokenId_, uint256 delegateRightsInteger_, string memory containerURI_ ) external { // Check this is a valid call from a delegationContainer: uint64 recordId = isValidContainer(msg.sender); (bytes32 keyHash, bytes32 ownerHash) = _adjustBalancesAtEndOfDelegation( tokenContract_, msg.sender, owner_, oldDelegate_, tokenId_, recordId ); // Move the container to a new delegation Id: _assignDelegationId(msg.sender); _resetDelegationRecordDetails(keyHash); _increaseRightsInteger( msg.sender, owner_, tokenContract_, tokenId_, ownerHash, TOTAL_RIGHTS ); emit DelegationCreated( provider_, delegationId, msg.sender, owner_, newDelegate_, fee_, durationInDays_, tokenContract_, tokenId_, delegateRightsInteger_, containerURI_ ); } /** * * @dev _emitComplete: signal that this delegation is complete * */ function _emitComplete(uint64 delegationId_) internal { emit DelegationComplete(delegationId_); } // ======================================= // OFFERS // ======================================= /** * * @dev makeOffer: make an offer. * */ function makeOffer( uint64 provider_, uint24 duration_, uint32 expiry_, bool collectionOffer_, address collection_, uint96 offerAmount_, address offerERC20_, uint256 tokenId_, uint256 delegateRightsRequested_ ) external { // Check that the payment ERC20 is valid if ( offerERC20_ != address(0) && !validERC20PaymentOption[offerERC20_].isValid ) revert InvalidERC20(); // Increment offer id offerId += 1; offerIdToOfferDetails[offerId] = Offer( msg.sender, duration_, expiry_, collectionOffer_, collection_, offerAmount_, tokenId_, delegateRightsRequested_, offerERC20_ ); emit OfferMade( provider_, offerId, collection_, collectionOffer_, tokenId_, duration_, expiry_, offerAmount_, delegateRightsRequested_, msg.sender ); } /** * * @dev cancelOffer: cancel an offer. * */ function cancelOffer(uint64 provider_, uint64 offerId_) external { if (msg.sender != offerIdToOfferDetails[offerId_].offerMaker) revert CallerIsNotOfferMaker(); delete offerIdToOfferDetails[offerId_]; emit OfferDeleted(provider_, offerId_); } /** * * @dev changeOffer: change an offer. * */ function changeOffer( uint64 provider_, uint64 offerId_, uint24 newDuration_, uint32 newExpiry_, uint96 newAmount_, uint256 newRightsInteger_ ) external { if (msg.sender != offerIdToOfferDetails[offerId_].offerMaker) revert CallerIsNotOfferMaker(); if (newDuration_ != 0) offerIdToOfferDetails[offerId_].delegationDuration = newDuration_; if (newExpiry_ != 0) offerIdToOfferDetails[offerId_].expiry = newExpiry_; if (newAmount_ != 0) offerIdToOfferDetails[offerId_].offerAmount = newAmount_; if (newRightsInteger_ != 0) offerIdToOfferDetails[offerId_].delegateRightsInteger = newRightsInteger_; emit OfferChanged( provider_, offerId_, newDuration_, newExpiry_, newAmount_, newRightsInteger_ ); } }
// SPDX-License-Identifier: MIT // EPS Contracts v2.0.0 pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /** * * @dev Implementation of the EPS proxy register interface. * */ interface IEPSProxyRegister { // ====================================================== // ENUMS // ====================================================== // enum for available proxy statuses enum ProxyStatus { None, PendingAcceptance, PendingPayment, Live } // enum for participant enum Participant { Hot, Cold } // ====================================================== // STRUCTS // ====================================================== // Full proxy record struct Record { // Slot 1: 64 + 8 + 8 + 160 = 240 uint64 provider; ProxyStatus status; bool feePaid; address cold; // Slot 2: 160 address delivery; } // ====================================================== // EVENTS // ====================================================== // Emitted when a hot address nominates a cold address: event NominationMade( address indexed hot, address indexed cold, address delivery, uint256 provider ); // Emitted when a cold accepts a nomination from a hot address: event NominationAccepted( address indexed hot, address indexed cold, address delivery, uint64 indexed provider ); // Emitted when a proxy goes live event ProxyRecordLive( address indexed hot, address indexed cold, address delivery, uint64 indexed provider ); // Emitted when the delivery address is updated on a record: event DeliveryUpdated( address indexed hot, address indexed cold, address indexed delivery, address oldDelivery, uint256 provider ); // Emitted when a register record is deleted. initiator 0 = cold, 1 = hot: event RecordDeleted( Participant initiator, address indexed hot, address indexed cold, uint256 provider ); // ====================================================== // ERRORS // ====================================================== error NoPaymentPendingForAddress(); error NoRecordFoundForAddress(); error OnlyHotAddressCanChangeAddress(); error ColdIsAddressZero(); error ColdAddressCannotBeTheSameAsHot(); error DeliveryIsAddressZero(); error IncorrectProxyRegisterFee(); error AlreadyProxied(); error ProxyRegisterFeeRequired(); error AddressMismatch(); error DeliveryCannotBeTheZeroAddress(); error UnrecognisedEPSAPIAmount(); // ====================================================== // VIEW METHODS // ====================================================== /** * @dev Return if a cold wallet is live */ function coldIsLive(address cold_) external view returns (bool); /** * @dev Return if a hot wallet is live */ function hotIsLive(address hot_) external view returns (bool); /** * @dev Get proxy details for a hot address */ function getProxyRecordForHot(address hot_) external view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ); /** * @dev Get proxy details for a cold address */ function getProxyRecordForCold(address cold_) external view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ); /** * @dev Get proxy details for a passed address (could be hot or cold) */ function getProxyRecordForAddress(address queryAddress_) external view returns ( ProxyStatus status, address hot, address cold, address delivery, uint64 provider_, bool feePaid ); // ====================================================== // LIFECYCLE - NOMINATION // ====================================================== /** * @dev nominate: Hot Nominates cold, direct contract call */ function nominate( address cold_, address delivery_, uint64 provider_ ) external payable; /** * @dev acceptNomination: Cold accepts nomination, direct contract call * (though it is anticipated that most will use an ERC20 transfer) */ function acceptNomination(address hot_, uint64 provider_) external payable; // ====================================================== // LIFECYCLE - CHANGING DELIVERY ADDRESS // ====================================================== /** * @dev updateDeliveryAddress: Change delivery address on an existing proxy record. */ function updateDeliveryAddress(address delivery_, uint256 provider_) external; // ====================================================== // LIFECYCLE - DELETING A RECORD // ====================================================== /** * @dev deleteRecord: Delete a proxy record, if found */ function deleteRecord(uint256 provider_) external; // ====================================================== // ADMIN FUNCTIONS // ====================================================== /** * @dev setRegisterFee: set the fee for accepting a registration: */ function setRegisterFee(uint256 registerFee_) external; /** * @dev setDeletionNominalEth: set the nominal ETH transfer that represents an address ending a proxy */ function setDeletionNominalEth(uint256 deleteNominalEth_) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // EPS Contracts v2.0.0 pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /** * * @dev Implementation of the EPS Delegation register interface. * */ interface IEPSDelegateRegister { // ====================================================== // EVENTS // ====================================================== // Emitted when a delegation container is created: event DelegationCreated( uint64 indexed provider, uint64 indexed delegationId, address indexed containerAddress, address owner, address delegate, uint96 fee, uint24 durationInDays, address tokenContract, uint256 tokenId, uint256 delegateRightsInteger, string URI ); // Emitted when the delegation is accepted: event DelegationAccepted( uint64 indexed provider, uint64 indexed delegationId, address container, address tokenContract, uint256 tokenId, address owner, address delegate, uint64 endTime, uint256 delegateRightsInteger, uint256 epsFee, string URI ); // Emitted when a delegation is complete: event DelegationComplete(uint64 indexed delegationId); // Emitted when the delegation owner changes: event DelegationOwnerChanged( uint64 indexed provider, uint64 indexed delegationId, address indexed newOwner, uint256 epsFee ); // Emitted when the delegation delegate changes: event DelegationDelegateChanged( uint64 indexed provider, uint64 indexed delegationId, address indexed newDelegate, uint256 epsFee ); event ContainerListedForSale( uint64 provider, uint64 delegationId, address container, uint96 salePrice ); event DelegationListedForSale( uint64 provider, uint64 delegationId, uint96 salePrice ); event OfferMade( uint64 provider, uint64 offerId, address collection, bool collectionOffer, uint256 tokenId, uint24 duration, uint32 expiry, uint96 offerAmount, uint256 delegateRightsRequested, address offerer ); event OfferAccepted( uint64 provider, uint64 offerId, uint256 epsFee, address epsFeeToken ); event OfferDeleted(uint64 provider, uint64 offerId); event OfferChanged( uint64 provider, uint64 offerId, uint24 duration, uint32 offerExpiry, uint96 offerAmount, uint256 delegateRightsInteger ); event TransferRights( address indexed from, address indexed to, address indexed tokenContract, uint256 tokenId, uint256 rightsInteger ); event ContainerDetailsUpdated( uint64 provider, uint64 delegationId, address container, address delegate, uint256 fee, uint256 duration, uint256 delegateRightsInteger ); event SundryEvent( uint64 provider, uint64 delegationId, address address1, address address2, uint256 integer1, uint256 integer2, uint256 integer3, uint256 integer4 ); // ====================================================== // ERRORS // ====================================================== error TemplateContainerLocked(); error InvalidContainer(); error InvalidERC20(); error DoNoMintToThisAddress(); error InvalidRights(); error OwnerCannotBeDelegate(); error CallerIsNotOfferMaker(); error InvalidOffer(); error MarketPlacePaused(); // ====================================================== // FUNCTIONS // ====================================================== function getFeeDetails() external view returns (uint96 delegationRegisterFee_, uint32 delegationFeePercentage_); function getBeneficiaryByRight( address tokenContract_, uint256 tokenId_, uint256 rightsIndex_ ) external view returns (address); function getBalanceByRight( address tokenContract_, address queryAddress_, uint256 rightsIndex_ ) external view returns (uint256); function saveDelegationRecord( uint64 provider_, address tokenContract_, uint256 tokenId_, address owner_, address delegate_, uint64 endTime_, uint256 delegateRightsInteger_, string memory containerURI_ ) external payable; function changeAssetOwner( uint64 provider_, address newOwner_, address tokenContract_, uint256 tokenId_, uint256 epsFee ) external; function changeDelegate( uint64 provider_, address newDelegate_, address tokenContract_, uint256 tokenId_, uint256 epsFee_ ) external; function deleteEntry( address tokenContract_, uint256 tokenId_, address owner_, address delegate_ ) external; function containerListedForSale(uint64 provider_, uint96 salePrice_) external; function delegationListedForSale(uint64 provider_, uint96 salePrice_) external; function getDelegationIdForContainer(address container_) external view returns (uint64 delegationId_); function relistEntry( uint64 provider_, address owner_, address oldDelegate_, address delegate_, uint96 fee_, uint24 durationInDays_, address tokenContract_, uint256 tokenId_, uint256 delegateRightsInteger_, string memory containerURI_ ) external; function acceptOfferAfterDelegationCompleted( uint64 provider_, address owner_, address oldDelegate_, address newDelegate_, uint24 duration_, uint96 fee_, uint256 delegateRightsInteger_, uint64 offerId_, address tokenContract_, uint256 tokenId_ ) external payable; function containerDetailsUpdated( uint64 provider_, address delegate_, uint256 fee_, uint256 duration_, uint256 delegateRightsInteger_ ) external; function acceptOfferPriorToCommencement( uint64 provider_, address owner_, address delegate_, uint24 duration_, uint96 fee_, uint256 delegateRightsInteger_, uint64 offerId_, address tokenContract_, uint256 tokenId_ ) external; function sundryEvent( uint64 provider_, address address1_, address address2_, uint256 int1_, uint256 int2_, uint256 int3_, uint256 int4_ ) external; }
// SPDX-License-Identifier: MIT // EPSP Contracts v2.0.0 pragma solidity 0.8.17; /** * * @dev The EPS Delegation container contract interface. Lightweight interface with just the functions required * by the register contract. * */ interface IDelegationContainer { event OwnershipTransferred( uint64 provider, address indexed previousOwner, address indexed newOwner ); event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); event EPSRegisterCallError(bytes reason); /** * @dev initialiseDelegationContainer - function to call to set storage correctly on a new clone: */ function initialiseDelegationContainer( address payable owner_, address payable delegate_, uint96 fee_, uint24 durationInDays_, address tokenContract_, uint256 tokenId_, uint256 ownerRightsInteger, string memory containerURI_, uint64 offerId ) external; /** * @dev Delegate accepts delegation */ function acceptDelegation(uint64 provider_) external payable; /** * @dev Get delegation details. */ function getDelegationContainerDetails(uint64 passedDelegationId_) external view returns ( uint64 delegationId_, address assetOwner_, address delegate_, address tokenContract_, uint256 tokenId_, bool terminated_, uint32 startTime_, uint24 durationInDays_, uint96 delegationFee_, uint256 delegateRightsInteger_, uint96 containerSalePrice_, uint96 delegationSalePrice_ ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) instance := create(0, ptr, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) instance := create2(0, ptr, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000) mstore(add(ptr, 0x38), shl(0x60, deployer)) mstore(add(ptr, 0x4c), salt) mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) predicted := keccak256(add(ptr, 0x37), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: 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 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"proxyRegisterFee_","type":"uint256"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"uint96","name":"delegationRegisterFee_","type":"uint96"},{"internalType":"uint32","name":"delegationFeePercentage_","type":"uint32"},{"internalType":"address","name":"weth_","type":"address"},{"internalType":"uint256","name":"deletionNominalEth_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressMismatch","type":"error"},{"inputs":[],"name":"AlreadyProxied","type":"error"},{"inputs":[],"name":"CallerIsNotOfferMaker","type":"error"},{"inputs":[],"name":"ColdAddressCannotBeTheSameAsHot","type":"error"},{"inputs":[],"name":"ColdIsAddressZero","type":"error"},{"inputs":[],"name":"ColdWalletCannotInteractUserHot","type":"error"},{"inputs":[],"name":"DeliveryCannotBeTheZeroAddress","type":"error"},{"inputs":[],"name":"DeliveryIsAddressZero","type":"error"},{"inputs":[],"name":"DoNoMintToThisAddress","type":"error"},{"inputs":[],"name":"EthWithdrawFailed","type":"error"},{"inputs":[],"name":"IncorrectProxyRegisterFee","type":"error"},{"inputs":[],"name":"InvalidContainer","type":"error"},{"inputs":[],"name":"InvalidERC20","type":"error"},{"inputs":[],"name":"InvalidOffer","type":"error"},{"inputs":[],"name":"InvalidRights","type":"error"},{"inputs":[],"name":"MarketPlacePaused","type":"error"},{"inputs":[],"name":"NoPaymentPendingForAddress","type":"error"},{"inputs":[],"name":"NoRecordFoundForAddress","type":"error"},{"inputs":[],"name":"OnlyHotAddressCanChangeAddress","type":"error"},{"inputs":[],"name":"OwnerCannotBeDelegate","type":"error"},{"inputs":[],"name":"ProxyRegisterFeeRequired","type":"error"},{"inputs":[],"name":"TemplateContainerLocked","type":"error"},{"inputs":[],"name":"UnknownAmount","type":"error"},{"inputs":[],"name":"UnrecognisedEPSAPIAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":false,"internalType":"address","name":"container","type":"address"},{"indexed":false,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"}],"name":"ContainerDetailsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":false,"internalType":"address","name":"container","type":"address"},{"indexed":false,"internalType":"uint96","name":"salePrice","type":"uint96"}],"name":"ContainerListedForSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":false,"internalType":"address","name":"container","type":"address"},{"indexed":false,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint64","name":"endTime","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epsFee","type":"uint256"},{"indexed":false,"internalType":"string","name":"URI","type":"string"}],"name":"DelegationAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"delegationId","type":"uint64"}],"name":"DelegationComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":true,"internalType":"address","name":"containerAddress","type":"address"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint96","name":"fee","type":"uint96"},{"indexed":false,"internalType":"uint24","name":"durationInDays","type":"uint24"},{"indexed":false,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"},{"indexed":false,"internalType":"string","name":"URI","type":"string"}],"name":"DelegationCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":true,"internalType":"address","name":"newDelegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"epsFee","type":"uint256"}],"name":"DelegationDelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":false,"internalType":"uint96","name":"salePrice","type":"uint96"}],"name":"DelegationListedForSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"},{"indexed":false,"internalType":"uint256","name":"epsFee","type":"uint256"}],"name":"DelegationOwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hot","type":"address"},{"indexed":true,"internalType":"address","name":"cold","type":"address"},{"indexed":true,"internalType":"address","name":"delivery","type":"address"},{"indexed":false,"internalType":"address","name":"oldDelivery","type":"address"},{"indexed":false,"internalType":"uint256","name":"provider","type":"uint256"}],"name":"DeliveryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hot","type":"address"},{"indexed":true,"internalType":"address","name":"cold","type":"address"},{"indexed":false,"internalType":"address","name":"delivery","type":"address"},{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"}],"name":"NominationAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hot","type":"address"},{"indexed":true,"internalType":"address","name":"cold","type":"address"},{"indexed":false,"internalType":"address","name":"delivery","type":"address"},{"indexed":false,"internalType":"uint256","name":"provider","type":"uint256"}],"name":"NominationMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"offerId","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"epsFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"epsFeeToken","type":"address"}],"name":"OfferAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"offerId","type":"uint64"},{"indexed":false,"internalType":"uint24","name":"duration","type":"uint24"},{"indexed":false,"internalType":"uint32","name":"offerExpiry","type":"uint32"},{"indexed":false,"internalType":"uint96","name":"offerAmount","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"}],"name":"OfferChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"offerId","type":"uint64"}],"name":"OfferDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"offerId","type":"uint64"},{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"bool","name":"collectionOffer","type":"bool"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint24","name":"duration","type":"uint24"},{"indexed":false,"internalType":"uint32","name":"expiry","type":"uint32"},{"indexed":false,"internalType":"uint96","name":"offerAmount","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"delegateRightsRequested","type":"uint256"},{"indexed":false,"internalType":"address","name":"offerer","type":"address"}],"name":"OfferMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hot","type":"address"},{"indexed":true,"internalType":"address","name":"cold","type":"address"},{"indexed":false,"internalType":"address","name":"delivery","type":"address"},{"indexed":true,"internalType":"uint64","name":"provider","type":"uint64"}],"name":"ProxyRecordLive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IEPSProxyRegister.Participant","name":"initiator","type":"uint8"},{"indexed":true,"internalType":"address","name":"hot","type":"address"},{"indexed":true,"internalType":"address","name":"cold","type":"address"},{"indexed":false,"internalType":"uint256","name":"provider","type":"uint256"}],"name":"RecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"provider","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"delegationId","type":"uint64"},{"indexed":false,"internalType":"address","name":"address1","type":"address"},{"indexed":false,"internalType":"address","name":"address2","type":"address"},{"indexed":false,"internalType":"uint256","name":"integer1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"integer2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"integer3","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"integer4","type":"uint256"}],"name":"SundryEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rightsInteger","type":"uint256"}],"name":"TransferRights","type":"event"},{"inputs":[{"internalType":"address","name":"hot_","type":"address"},{"internalType":"uint64","name":"provider_","type":"uint64"}],"name":"acceptNomination","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"oldDelegate_","type":"address"},{"internalType":"address","name":"newDelegate_","type":"address"},{"internalType":"uint24","name":"duration_","type":"uint24"},{"internalType":"uint96","name":"fee_","type":"uint96"},{"internalType":"uint256","name":"delegateRightsInteger_","type":"uint256"},{"internalType":"uint64","name":"offerId_","type":"uint64"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"acceptOfferAfterDelegationCompleted","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"delegate_","type":"address"},{"internalType":"uint24","name":"duration_","type":"uint24"},{"internalType":"uint96","name":"fee_","type":"uint96"},{"internalType":"uint256","name":"delegateRightsInteger_","type":"uint256"},{"internalType":"uint64","name":"offerId_","type":"uint64"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"acceptOfferPriorToCommencement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activeEthAddresses","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractForERC20_","type":"address"},{"internalType":"uint96","name":"baseFee_","type":"uint96"}],"name":"addOfferPaymentERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"queryAddress_","type":"address"},{"internalType":"bool","name":"checkingHot_","type":"bool"}],"name":"addressIsAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queryAddress_","type":"address"}],"name":"beneficiaryBalance","outputs":[{"internalType":"uint256","name":"balance_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queryAddress_","type":"address"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"rightsIndex_","type":"uint256"}],"name":"beneficiaryBalanceOf","outputs":[{"internalType":"uint256","name":"balance_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queryAddress_","type":"address"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"beneficiaryBalanceOf1155","outputs":[{"internalType":"uint256","name":"balance_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"rightsIndex_","type":"uint256"}],"name":"beneficiaryOf","outputs":[{"internalType":"address","name":"beneficiary_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"uint64","name":"offerId_","type":"uint64"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"newOwner_","type":"address"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"epsFee_","type":"uint256"}],"name":"changeAssetOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"newDelegate_","type":"address"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"epsFee_","type":"uint256"}],"name":"changeDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"uint64","name":"offerId_","type":"uint64"},{"internalType":"uint24","name":"newDuration_","type":"uint24"},{"internalType":"uint32","name":"newExpiry_","type":"uint32"},{"internalType":"uint96","name":"newAmount_","type":"uint96"},{"internalType":"uint256","name":"newRightsInteger_","type":"uint256"}],"name":"changeOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cold_","type":"address"}],"name":"coldIsActiveOnRegister","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cold_","type":"address"}],"name":"coldIsLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"delegate_","type":"address"},{"internalType":"uint256","name":"fee_","type":"uint256"},{"internalType":"uint256","name":"duration_","type":"uint256"},{"internalType":"uint256","name":"delegateRightsInteger_","type":"uint256"}],"name":"containerDetailsUpdated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"uint96","name":"salePrice_","type":"uint96"}],"name":"containerListedForSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"containerToDelegationId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"contractToBalanceByRights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"defaultRightsCodes","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationContainer","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationContainerTemplateLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationFeePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"uint96","name":"salePrice_","type":"uint96"}],"name":"delegationListedForSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationRegisterFee","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"delegate_","type":"address"}],"name":"deleteEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"provider_","type":"uint256"}],"name":"deleteRecord","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deletionNominalEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epsAPIBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receivedAddress","type":"address"}],"name":"getAddresses","outputs":[{"internalType":"address","name":"cold","type":"address"},{"internalType":"address","name":"delivery","type":"address"},{"internalType":"bool","name":"isProxied","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"address","name":"queryAddress_","type":"address"},{"internalType":"uint256","name":"rightsIndex_","type":"uint256"}],"name":"getBalanceByRight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"rightsIndex_","type":"uint256"}],"name":"getBeneficiaryByRight","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"container_","type":"address"}],"name":"getDelegationIdForContainer","outputs":[{"internalType":"uint64","name":"delegationId_","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeDetails","outputs":[{"internalType":"uint96","name":"delegationRegisterFee_","type":"uint96"},{"internalType":"uint32","name":"delegationFeePercentage_","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queryAddress_","type":"address"}],"name":"getProxyRecordForAddress","outputs":[{"internalType":"enum IEPSProxyRegister.ProxyStatus","name":"status","type":"uint8"},{"internalType":"address","name":"hot","type":"address"},{"internalType":"address","name":"cold","type":"address"},{"internalType":"address","name":"delivery","type":"address"},{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"bool","name":"feePaid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"cold_","type":"address"}],"name":"getProxyRecordForCold","outputs":[{"internalType":"enum IEPSProxyRegister.ProxyStatus","name":"status","type":"uint8"},{"internalType":"address","name":"hot","type":"address"},{"internalType":"address","name":"cold","type":"address"},{"internalType":"address","name":"delivery","type":"address"},{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"bool","name":"feePaid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"hot_","type":"address"}],"name":"getProxyRecordForHot","outputs":[{"internalType":"enum IEPSProxyRegister.ProxyStatus","name":"status","type":"uint8"},{"internalType":"address","name":"hot","type":"address"},{"internalType":"address","name":"cold","type":"address"},{"internalType":"address","name":"delivery","type":"address"},{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"bool","name":"feePaid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"hot_","type":"address"}],"name":"hotIsActiveOnRegister","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"hot_","type":"address"}],"name":"hotIsLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"hot_","type":"address"},{"internalType":"address","name":"cold_","type":"address"},{"internalType":"address","name":"delivery_","type":"address"}],"name":"isValidAddresses","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"container_","type":"address"}],"name":"isValidContainer","outputs":[{"internalType":"uint64","name":"recordId_","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDelegationContainerTemplate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"uint24","name":"duration_","type":"uint24"},{"internalType":"uint32","name":"expiry_","type":"uint32"},{"internalType":"bool","name":"collectionOffer_","type":"bool"},{"internalType":"address","name":"collection_","type":"address"},{"internalType":"uint96","name":"offerAmount_","type":"uint96"},{"internalType":"address","name":"offerERC20_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"delegateRightsRequested_","type":"uint256"}],"name":"makeOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketplacePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"cold_","type":"address"},{"internalType":"address","name":"delivery_","type":"address"},{"internalType":"uint64","name":"provider_","type":"uint64"}],"name":"nominate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"offerId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"offerIdToOfferDetails","outputs":[{"internalType":"address","name":"offerMaker","type":"address"},{"internalType":"uint24","name":"delegationDuration","type":"uint24"},{"internalType":"uint32","name":"expiry","type":"uint32"},{"internalType":"bool","name":"collectionOffer","type":"bool"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint96","name":"offerAmount","type":"uint96"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"},{"internalType":"address","name":"paymentERC20","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"marketPlacePaused","type":"bool"}],"name":"pauseMarketplace","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyRegisterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"oldDelegate_","type":"address"},{"internalType":"address","name":"newDelegate_","type":"address"},{"internalType":"uint96","name":"fee_","type":"uint96"},{"internalType":"uint24","name":"durationInDays_","type":"uint24"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"delegateRightsInteger_","type":"uint256"},{"internalType":"string","name":"containerURI_","type":"string"}],"name":"relistEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractForERC20_","type":"address"}],"name":"removeOfferPaymentERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"delegate_","type":"address"},{"internalType":"uint64","name":"endTime_","type":"uint64"},{"internalType":"uint256","name":"delegateRightsInteger_","type":"uint256"},{"internalType":"string","name":"containerURI_","type":"string"}],"name":"saveDelegationRecord","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rightsIndex_","type":"uint256"},{"internalType":"string","name":"rightsDescription_","type":"string"}],"name":"setDefaultRightsCodes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"delegationContainer_","type":"address"}],"name":"setDelegationContainer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"delegationFeePercentage_","type":"uint32"}],"name":"setDelegationFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"delegationRegisterFee_","type":"uint96"}],"name":"setDelegationRegisterFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"deleteNominalEth_","type":"uint256"}],"name":"setDeletionNominalEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count_","type":"uint256"},{"internalType":"uint256","name":"air_","type":"uint256"}],"name":"setNNumberOfEthAddressesAndAirdropAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract_","type":"address"},{"internalType":"uint256","name":"rightsIndex_","type":"uint256"},{"internalType":"string","name":"rightsDescription_","type":"string"}],"name":"setProjectSpecificRightsCodes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"registerFee_","type":"uint256"}],"name":"setRegisterFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasuryAddress","type":"address"}],"name":"setTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"provider_","type":"uint64"},{"internalType":"address","name":"address1_","type":"address"},{"internalType":"address","name":"address2_","type":"address"},{"internalType":"uint256","name":"int1_","type":"uint256"},{"internalType":"uint256","name":"int2_","type":"uint256"},{"internalType":"uint256","name":"int3_","type":"uint256"},{"internalType":"uint256","name":"int4_","type":"uint256"}],"name":"sundryEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenContractToRightsCodes","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenToDelegationRecord","outputs":[{"internalType":"uint64","name":"delegationId","type":"uint64"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"uint256","name":"delegateRightsInteger","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delivery_","type":"address"},{"internalType":"uint256","name":"provider_","type":"uint256"}],"name":"updateDeliveryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validERC20PaymentOption","outputs":[{"internalType":"bool","name":"isValid","type":"bool"},{"internalType":"uint96","name":"registerFee","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"token_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"withdrawERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040526001601e55612710601f553480156200001c57600080fd5b5060405162006016380380620060168339810160408190526200003f91620001bb565b83838388846200004f33620000c1565b6001919091556002556005805463ffffffff909316600160e01b026001600160e01b036001600160601b03909516600160801b0285166001600160801b0390941693909317929092179091556001600160a01b0316608052620000b59086906200011116565b50505050505062000243565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200011b6200013d565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146200019c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b565b80516001600160a01b0381168114620001b657600080fd5b919050565b60008060008060008060c08789031215620001d557600080fd5b86519550620001e7602088016200019e565b60408801519095506001600160601b03811681146200020557600080fd5b606088015190945063ffffffff811681146200022057600080fd5b925062000230608088016200019e565b915060a087015190509295509295509295565b608051615db76200025f600039600061453b0152615db76000f3fe60806040526004361061048d5760003560e01c80638da5cb5b11610255578063c1f5c49a11610144578063dd2ebdb4116100c1578063f14210a611610085578063f14210a614611132578063f2fde38b14611152578063f3362fb914611172578063f3e414f814611192578063f8907b60146111b2578063fc2bc7b2146111d257600080fd5b8063dd2ebdb414611081578063e575d025146110a1578063e963134f146110b4578063ec8b9071146110d4578063f023a734146110f357600080fd5b8063cf135b9d11610108578063cf135b9d14610feb578063d1d3e28f1461100b578063d5472c181461102b578063d56bb0571461104b578063db7840cb1461106157600080fd5b8063c1f5c49a14610f5f578063c2f5dc4414610f7f578063c858380814610f95578063c93b228914610fb5578063ce46756914610fcb57600080fd5b8063a2966f5f116101d2578063b2969acf11610196578063b2969acf14610ea0578063b810c63614610ec0578063b9f97d4114610eff578063bd17532414610f2c578063c124eb1f14610f3f57600080fd5b8063a2966f5f14610d39578063a4c1408414610d4c578063a9059cbb14610e40578063ae7044c214610e60578063afb85e6214610e8057600080fd5b806393a1d1aa1161021957806393a1d1aa14610c8a57806395d89b4114610caa578063a0a3660614610cd9578063a1db978214610cf9578063a276c41514610d1957600080fd5b80638da5cb5b14610bce578063906f634314610bec57806390938e9514610c34578063913965c314610c5457806392be2ab814610c6a57600080fd5b806341e3196f1161037c578063657f9233116102f957806370a08231116102bd57806370a0823114610b0b578063715018a614610b2d5780637a3be00d14610b425780637afbd21214610b625780638523837014610b8257806388d6f15114610b9557600080fd5b8063657f923314610a375780636605bfda14610a575780636bcf608814610a775780636e22bad914610a8c5780636f1dcc3b14610aeb57600080fd5b80635205cb5b116103405780635205cb5b1461099757806353556440146109b757806357b14d9e146109d75780635ba58955146109f757806361d027b314610a1757600080fd5b806341e3196f146108f757806342b046901461091757806342de52551461093757806345065089146109575780634835de371461097757600080fd5b80631fc784101161040a578063274971b3116103ce578063274971b31461082b578063313ce5671461084b57806333ac8aa8146108675780633a0236e3146108995780633a30d464146108b957600080fd5b80631fc78410146106e0578063214cf7ad1461070057806321a0bd9e146107a557806321ce9f91146107e4578063265d97ee1461080b57600080fd5b8063150b7a0211610451578063150b7a02146106245780631718e0cf1461065d57806318160ddd1461067d5780631888f727146106a057806318976a24146106c057600080fd5b8063061f98111461052a57806306fdde031461054a5780630956d8a71461058c5780630ec735da146105bc57806314977eb8146105d657600080fd5b366105255760015434141580156104a657506002543414155b80156104c85750336000908152601960205260409020546001600160401b0316155b80156104df57506000546001600160a01b03163314155b156104fd5760405163020ad41b60e11b815260040160405180910390fd5b60015434036105115761050f336111f2565b005b600254340361050f5761050f336000611322565b600080fd5b34801561053657600080fd5b5061050f610545366004614bc1565b6113b3565b34801561055657600080fd5b506040805180820190915260078152664550532041504960c81b60208201525b6040516105839190614c2a565b60405180910390f35b34801561059857600080fd5b506105ac6105a7366004614c5d565b6113bd565b6040519015158152602001610583565b3480156105c857600080fd5b506016546105ac9060ff1681565b3480156105e257600080fd5b5061060c6105f1366004614c5d565b6019602052600090815260409020546001600160401b031681565b6040516001600160401b039091168152602001610583565b34801561063057600080fd5b5061064461063f366004614d25565b6113fc565b6040516001600160e01b03199091168152602001610583565b34801561066957600080fd5b5061050f610678366004614da4565b6116e9565b34801561068957600080fd5b506106926116f4565b604051908152602001610583565b3480156106ac57600080fd5b5061050f6106bb366004614dde565b61170b565b3480156106cc57600080fd5b506106926106db366004614dfb565b61172d565b3480156106ec57600080fd5b5061050f6106fb366004614e51565b611762565b34801561070c57600080fd5b5061076361071b366004614bc1565b6017602052600090815260409020805460018201546002909201546001600160401b03808316936001600160a01b03600160401b948590048116949282169392909104169085565b604080516001600160401b0396871681526001600160a01b0395861660208201529590931692850192909252919091166060830152608082015260a001610583565b3480156107b157600080fd5b506005546107cc90600160801b90046001600160601b031681565b6040516001600160601b039091168152602001610583565b3480156107f057600080fd5b5060055461060c90600160401b90046001600160401b031681565b34801561081757600080fd5b5061050f610826366004614ec1565b611888565b34801561083757600080fd5b506105ac610846366004614ede565b6118c1565b34801561085757600080fd5b5060405160008152602001610583565b34801561087357600080fd5b50610887610882366004614c5d565b6119eb565b60405161058396959493929190614f2d565b3480156108a557600080fd5b506105ac6108b4366004614c5d565b611ade565b3480156108c557600080fd5b506016546108df906201000090046001600160a01b031681565b6040516001600160a01b039091168152602001610583565b34801561090357600080fd5b5061050f610912366004614f81565b611b1a565b34801561092357600080fd5b50610576610932366004614bc1565b611b69565b34801561094357600080fd5b506108df610952366004614faf565b611c09565b34801561096357600080fd5b5061050f610972366004615004565b611cd8565b34801561098357600080fd5b5061050f610992366004614c5d565b611d05565b3480156109a357600080fd5b5061050f6109b236600461507a565b611d5b565b3480156109c357600080fd5b506105ac6109d2366004614c5d565b6120ad565b3480156109e357600080fd5b506106926109f2366004614dfb565b6120f7565b348015610a0357600080fd5b50610692610a12366004614c5d565b6122b1565b348015610a2357600080fd5b50601d546108df906001600160a01b031681565b348015610a4357600080fd5b506105ac610a52366004614c5d565b61232b565b348015610a6357600080fd5b5061050f610a72366004614c5d565b61239a565b348015610a8357600080fd5b5061050f6123c4565b348015610a9857600080fd5b50610acc610aa7366004614c5d565b601c6020526000908152604090205460ff81169061010090046001600160601b031682565b6040805192151583526001600160601b03909116602083015201610583565b348015610af757600080fd5b5061050f610b06366004615122565b6123db565b348015610b1757600080fd5b50610692610b26366004614c5d565b50601f5490565b348015610b3957600080fd5b5061050f612408565b348015610b4e57600080fd5b5061050f610b5d36600461513d565b61241c565b348015610b6e57600080fd5b50610887610b7d366004614c5d565b6125c7565b61050f610b903660046151b4565b61270e565b348015610ba157600080fd5b50600554610bb990600160e01b900463ffffffff1681565b60405163ffffffff9091168152602001610583565b348015610bda57600080fd5b506000546001600160a01b03166108df565b348015610bf857600080fd5b50610c0c610c07366004614c5d565b61273d565b604080516001600160a01b039485168152939092166020840152151590820152606001610583565b348015610c4057600080fd5b5061050f610c4f3660046151ff565b6127be565b348015610c6057600080fd5b50610692601e5481565b348015610c7657600080fd5b5061050f610c85366004614bc1565b61283a565b348015610c9657600080fd5b506108df610ca5366004614faf565b612847565b348015610cb657600080fd5b5060408051808201909152600681526545505341504960d01b6020820152610576565b348015610ce557600080fd5b5061050f610cf4366004615250565b6128fc565b348015610d0557600080fd5b5061050f610d14366004614da4565b61290f565b348015610d2557600080fd5b50610576610d34366004614da4565b61293d565b61050f610d47366004615272565b612969565b348015610d5857600080fd5b50610dd9610d6736600461531f565b601b60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0380851695600160a01b80870462ffffff1696600160b81b810463ffffffff1696600160d81b90910460ff169584821695929091046001600160601b0316939092911689565b604080516001600160a01b039a8b16815262ffffff90991660208a015263ffffffff90971696880196909652931515606087015291861660808601526001600160601b031660a085015260c084015260e08301529190911661010082015261012001610583565b348015610e4c57600080fd5b506105ac610e5b366004614da4565b612a26565b348015610e6c57600080fd5b5061050f610e7b366004614c5d565b612a3c565b348015610e8c57600080fd5b5061050f610e9b366004614e51565b612a71565b348015610eac57600080fd5b5061050f610ebb36600461533c565b612b6e565b348015610ecc57600080fd5b5060055460408051600160801b83046001600160601b03168152600160e01b90920463ffffffff16602083015201610583565b348015610f0b57600080fd5b50610692610f1a366004614bc1565b60186020526000908152604090205481565b61050f610f3a36600461536a565b612c3e565b348015610f4b57600080fd5b5061060c610f5a366004614c5d565b612d19565b348015610f6b57600080fd5b5061050f610f7a366004615428565b612d5c565b348015610f8b57600080fd5b5061069260025481565b348015610fa157600080fd5b5061050f610fb03660046154f8565b612e33565b348015610fc157600080fd5b5061069260015481565b348015610fd757600080fd5b5061050f610fe6366004615516565b612e9d565b348015610ff757600080fd5b5060055461060c906001600160401b031681565b34801561101757600080fd5b5061050f611026366004614bc1565b612f2d565b34801561103757600080fd5b5061050f611046366004615584565b612f3a565b34801561105757600080fd5b50610692601f5481565b34801561106d57600080fd5b5061050f61107c3660046155d7565b612fab565b34801561108d57600080fd5b5061050f61109c3660046154f8565b6130a7565b61050f6110af366004615681565b61310e565b3480156110c057600080fd5b506108876110cf366004614c5d565b613174565b3480156110e057600080fd5b506016546105ac90610100900460ff1681565b3480156110ff57600080fd5b5061060c61110e366004614c5d565b6001600160a01b03166000908152601960205260409020546001600160401b031690565b34801561113e57600080fd5b5061050f61114d366004614bc1565b61324f565b34801561115e57600080fd5b5061050f61116d366004614c5d565b6132cb565b34801561117e57600080fd5b5061050f61118d36600461569f565b613346565b34801561119e57600080fd5b5061050f6111ad366004614da4565b61338b565b3480156111be57600080fd5b506106926111cd366004614dfb565b613420565b3480156111de57600080fd5b5061050f6111ed3660046156f7565b61357e565b60026001600160a01b038216600090815260036020819052604090912054600160401b900460ff169081111561122a5761122a614f17565b03611275576001600160a01b0380821660009081526003602052604090208054600190910154611272928492600160501b8104821692909116906001600160401b03166135fe565b50565b60026001600160a01b03828116600090815260046020908152604080832054909316825260039081905291902054600160401b900460ff16908111156112bd576112bd614f17565b03611309576001600160a01b03818116600090815260046020908152604080832054841680845260039092529091206001810154905461127293859216906001600160401b03166135fe565b604051637115fdd360e01b815260040160405180910390fd5b61132b826113bd565b15611364576001600160a01b03808316600090815260036020526040812054611360928592600160501b909204169084613680565b5050565b61136d8261232b565b1561139a576001600160a01b03808316600090815260046020526040902054611360911683600184613680565b60405163163e0acf60e21b815260040160405180910390fd5b6112723382611322565b6001600160a01b038116600090815260036020526040812054600160401b900460ff16818160038111156113f3576113f3614f17565b14159392505050565b60006001600160a01b0384166114255760405163989992a560e01b815260040160405180910390fd5b33600061143184613716565b9050600080516020615d628339815191528160a001518260800151611456919061574d565b1461147457604051630eb911d560e01b815260040160405180910390fd5b856001600160a01b031681602001516001600160a01b0316036114aa57604051637c72ea1360e01b815260040160405180910390fd5b6016546000906114c8906201000090046001600160a01b03166137e5565b90506114d38161387d565b8160e001516001600160401b031660000361157957806001600160a01b0316600560009054906101000a90046001600160401b03166001600160401b031683600001516001600160401b03167f5a0f2eb6ae0aa35d6df4a692dcea08836a52a923522d010ac5241fce52a2180e8a8660200151876060015188604001518a8e8b60a001518c60c00151604051611570989796959493929190615760565b60405180910390a45b60008061158785898b6138f6565b915091508360e001516001600160401b03166000146115bc576115a8613919565b6115b784898b85858a89613945565b6115e7565b6115cb896000806000866139e9565b6115e7838a878b85600080516020615d62833981519152613a8c565b826001600160a01b0316636638439e8a866020015187606001518860400151338e8b60a001518c60c001518d60e001516040518a63ffffffff1660e01b815260040161163b999897969594939291906157cc565b600060405180830381600087803b15801561165557600080fd5b505af1158015611669573d6000803e3d6000fd5b5050604051632142170760e11b81523060048201526001600160a01b0386166024820152604481018b90523392506342842e0e9150606401600060405180830381600087803b1580156116bb57600080fd5b505af11580156116cf573d6000803e3d6000fd5b50630a85bd0160e11b9d9c50505050505050505050505050565b611360338383613b05565b6000601f54601e54611706919061584a565b905090565b611713613b6f565b601680549115156101000261ff0019909216919091179055565b60008061173a8585613bc9565b600081815260186020526040902054909150611757908490613c0f565b9150505b9392505050565b61176a613919565b600061177533612d19565b90506000806117858686896138f6565b600082815260176020526040812054929450909250600160401b9091046001600160a01b0316906117b68883613bc9565b60008581526017602052604081208054600160401b600160e01b031916600160401b6001600160a01b038e1602178155600201549192509061180690600080516020615d62833981519152615861565b905061181633848b8b8686613c7f565b611824338b8b8b8886613a8c565b896001600160a01b0316866001600160401b03168c6001600160401b03167f5dbf7557a2e3e90ad585a162df084f4b4e0c5b124740bf7821294703d0fe639c8a60405161187391815260200190565b60405180910390a45050505050505050505050565b611890613b6f565b600580546001600160601b03909216600160801b026bffffffffffffffffffffffff60801b19909216919091179055565b6001600160a01b038281166000908152600460209081526040808320549093168252600390819052918120549091600160401b90910460ff169081600381111561190d5761190d614f17565b148061192a5750600281600381111561192857611928614f17565b145b8061194e575082801561194e5750600181600381111561194c5761194c614f17565b145b1561195d5760009150506119e5565b506001600160a01b038316600090815260036020819052604090912054600160401b900460ff169081600381111561199757611997614f17565b14806119b4575060028160038111156119b2576119b2614f17565b145b806119d0575060018160038111156119ce576119ce614f17565b145b156119df5760009150506119e5565b60019150505b92915050565b6001600160a01b038181166000908152600460209081526040808320549093168083526003808352848420855160a0810190965280546001600160401b0381168752949586958695869586958695919486949093840191600160401b90910460ff1690811115611a5d57611a5d614f17565b6003811115611a6e57611a6e614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b039081166040808501919091526001909401541660609283015283015190830151608084015184519490930151919b5094995093975095509350909150505b91939550919395565b6001600160a01b0381166000908152600360208190526040822054600160401b900460ff1681811115611b1357611b13614f17565b1492915050565b611b22613b6f565b6001600160a01b039091166000908152601c6020526040902080546001600160601b03909216610100026cffffffffffffffffffffffffff19909216919091176001179055565b60068160108110611b7957600080fd5b018054909150611b8890615874565b80601f0160208091040260200160405190810160405280929190818152602001828054611bb490615874565b8015611c015780601f10611bd657610100808354040283529160200191611c01565b820191906000526020600020905b815481529060010190602001808311611be457829003601f168201915b505050505081565b6000811580611c185750600f82115b15611c2257600191505b611c2d848484612847565b90506001600160a01b03811661175b576040516331a9108f60e11b8152600481018490526001600160a01b03851690636352211e90602401602060405180830381865afa158015611c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca691906158ae565b9050611cb1816120ad565b1561175b576001600160a01b03908116600090815260046020526040902054169392505050565b611ce0613b6f565b8060068360108110611cf457611cf46158cb565b0190611d009082615927565b505050565b611d0d613b6f565b60165460ff1615611d3157604051632e6129eb60e11b815260040160405180910390fd5b601680546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6001600160a01b03831615801590611d8c57506001600160a01b0383166000908152601c602052604090205460ff16155b15611daa57604051630eca12dd60e31b815260040160405180910390fd5b6001600560088282829054906101000a90046001600160401b0316611dcf91906159e6565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550604051806101200160405280336001600160a01b031681526020018962ffffff1681526020018863ffffffff1681526020018715158152602001866001600160a01b03168152602001856001600160601b03168152602001838152602001828152602001846001600160a01b0316815250601b6000600560089054906101000a90046001600160401b03166001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548162ffffff021916908362ffffff16021790555060408201518160000160176101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601b6101000a81548160ff02191690831515021790555060808201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160010160146101000a8154816001600160601b0302191690836001600160601b0316021790555060c0820151816002015560e082015181600301556101008201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507fcfc9ed74ed2586915eb2ba885b6516120033d928b11ec45eb846af0700dabca489600560089054906101000a90046001600160401b03168789868d8d8b893360405161209a9a999897969594939291906001600160401b039a8b1681529890991660208901526001600160a01b0396871660408901529415156060880152608087019390935262ffffff9190911660a086015263ffffffff1660c08501526001600160601b031660e0840152610100830152919091166101208201526101400190565b60405180910390a1505050505050505050565b600060036001600160a01b03838116600090815260046020908152604080832054909316825260039081905291902054600160401b900460ff1690811115611b1357611b13614f17565b600061210284611ade565b1561222257604051627eeac760e11b81526001600160a01b0385811660048301526024820184905284169062fdd58e90604401602060405180830381865afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121769190615a0d565b612180908261574d565b6001600160a01b0385811660009081526003602052604090819020549051627eeac760e11b8152600160501b909104821660048201819052602482018690529293509085169062fdd58e906044015b602060405180830381865afa1580156121ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122109190615a0d565b61221a908361574d565b91505061175b565b61222b846120ad565b61175b57604051627eeac760e11b81526001600160a01b0385811660048301526024820184905284169062fdd58e906044015b602060405180830381865afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f9190615a0d565b6122a9908261574d565b949350505050565b60006122bc82611ade565b15612305576122d56001600160a01b038316318261574d565b6001600160a01b038084166000908152600360205260409020549192506119e591600160501b900416318261574d565b61230e826120ad565b612326576119e56001600160a01b038316318261574d565b919050565b6001600160a01b038181166000908152600460209081526040808320549093168252600390819052918120549091600160401b90910460ff169081600381111561237757612377614f17565b148061175b5750600281600381111561239257612392614f17565b149392505050565b6123a2613b6f565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b6123cc613b6f565b6016805460ff19166001179055565b6123e3613b6f565b6005805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b612410613b6f565b61241a6000613cec565b565b6001600160401b0385166000908152601b60205260409020546001600160a01b0316331461245d5760405163471e5c3d60e11b815260040160405180910390fd5b62ffffff84161561249b576001600160401b0385166000908152601b60205260409020805462ffffff60a01b1916600160a01b62ffffff8716021790555b63ffffffff8316156124dc576001600160401b0385166000908152601b60205260409020805463ffffffff60b81b1916600160b81b63ffffffff8616021790555b6001600160601b03821615612525576001600160401b0385166000908152601b6020526040902060010180546001600160a01b0316600160a01b6001600160601b038516021790555b801561254a576001600160401b0385166000908152601b602052604090206003018190555b604080516001600160401b0380891682528716602082015262ffffff86169181019190915263ffffffff841660608201526001600160601b038316608082015260a081018290527f283ca86eb787b2e4eed53d42c177266ef3af5e5879ca7e291363d2eed932ee0e9060c0015b60405180910390a1505050505050565b6001600160a01b03818116600090815260046020908152604080832054909316825260039081905291812054909182918291829182918291600160401b900460ff169081600381111561261c5761261c614f17565b14806126395750600281600381111561263757612637614f17565b145b806126555750600181600381111561265357612653614f17565b145b1561267557612663886119eb565b96509650965096509650965050611ad5565b506001600160a01b038716600090815260036020819052604090912054600160401b900460ff16908160038111156126af576126af614f17565b14806126cc575060028160038111156126ca576126ca614f17565b145b806126e8575060018160038111156126e6576126e6614f17565b145b156126f65761266388613174565b50600097889750879650869550859450849350915050565b6001543414612730576040516333b18e6b60e11b815260040160405180910390fd5b611d003384843485613d3c565b600080600061274b846120ad565b156127695760405163125f0c1360e21b815260040160405180910390fd5b61277284611ade565b156127ad575050506001600160a01b0380821660009081526003602052604090208054600191820154600160501b90910483169216906127b7565b5082915081905060005b9193909250565b60006127c933612d19565b604080516001600160401b03808a1682528316602082015233918101919091526001600160a01b03871660608201526080810186905260a0810185905260c081018490529091507f64b5ca6749db1c615652096d273882ff7a1008ac9664f51568b14410b7a4f1a69060e0016125b7565b612842613b6f565b600155565b6000806128548585613f09565b600081815260176020908152604091829020825160a08101845281546001600160401b038082168084526001600160a01b03600160401b93849004811696850196909652600185015491821696840196909652049092166060830152600201546080820152919250156128f0576128cf848260800151613c0f565b6000036128e35760200151915061175b9050565b60600151915061175b9050565b50600095945050505050565b612904613b6f565b601e91909155601f55565b612917613b6f565b61136061292c6000546001600160a01b031690565b6001600160a01b0384169083613f32565b601a602052816000526040600020816010811061295957600080fd5b018054909250611b889150615874565b612971613919565b600061297c33612d19565b9050600080600061298f8b8b8b8b613f84565b9250925092506129a183888a89613fdf565b6129af338a8d8d868b613c7f565b6129bd33898d8d858b613a8c565b836001600160401b03168c6001600160401b03167f874a0ec379dec4a6469317f6b2eb8bcb7381c2e0074e09ba06e85ef2dcb2ce4b338e8e8e8e8e8e348f604051612a1099989796959493929190615a26565b60405180910390a3505050505050505050505050565b6000612a3333848461402d565b50600192915050565b612a44613b6f565b6001600160a01b03166000908152601c6020526040902080546cffffffffffffffffffffffffff19169055565b612a79613919565b6000612a8433612d19565b9050600080612a948686896138f6565b600082815260176020526040812060010154929450909250600160401b9091046001600160a01b031690612ac88883613bc9565b6000858152601760205260409020600181018054600160401b600160e01b031916600160401b6001600160a01b038e160217905560020154909150612b1133848b8b8686613c7f565b612b1f338b8b8b8886613a8c565b896001600160a01b0316866001600160401b03168c6001600160401b03167f140155fa1de4908485153ff90dc3ed5358f6cf7d8c89166509c6a6ae2a850ca28a60405161187391815260200190565b6001600160401b0381166000908152601b60205260409020546001600160a01b03163314612baf5760405163471e5c3d60e11b815260040160405180910390fd5b6001600160401b038181166000818152601b6020908152604080832080546001600160e01b031916815560018101849055600281018490556003810193909355600490920180546001600160a01b0319169055815193861684528301919091527fce37e681b0772d563a915fa6cbf7fde2d8a8889e12015eb50beb269910bcd011910160405180910390a15050565b612c46613919565b6000612c5133612d19565b9050600080612c6485338e8e88886140ee565b91509150612c713361387d565b612d0a6040518061010001604052808f6001600160401b031681526020018c6001600160a01b031681526020018b62ffffff1681526020018a6001600160601b0316815260200189600080516020615d62833981519152612cd29190615861565b8152602001898152602001604051806020016040528060008152508152602001886001600160401b0316815250858e85858a33613945565b50505050505050505050505050565b6001600160a01b0381166000908152601960205260408120546001600160401b03169081900361232657604051630ce1b58d60e21b815260040160405180910390fd5b6000612d6733612d19565b9050600080612d7a87338e8e8a886140ee565b91509150612d873361387d565b612d9082614182565b612dac338d898985600080516020615d62833981519152613a8c565b336001600160a01b0316600560009054906101000a90046001600160401b03166001600160401b03168e6001600160401b03167f5a0f2eb6ae0aa35d6df4a692dcea08836a52a923522d010ac5241fce52a2180e8f8e8e8e8e8e8e8e604051612e1c989796959493929190615760565b60405180910390a450505050505050505050505050565b6000612e3e33612d19565b604080516001600160401b038087168252831660208201526001600160601b038516918101919091529091507f8aadc94565cd0449ff6a891861dce3989ecfbd4c25311ed3926eac0d5d53aba4906060015b60405180910390a1505050565b6000612ea833612d19565b604080516001600160401b038b81168252831660208201526001600160a01b038a811682840152891660608201526080810188905260a0810187905260c0810186905260e0810185905290519192507f09f2adc90b22f76ff47f53431a42a7a5e0bcc5867d0ebaedce6ce5d5d7f5d74791908190036101000190a15050505050505050565b612f35613b6f565b600255565b6000612f4533612d19565b90506000612f578633868689876140ee565b50600090815260176020908152604080832080546001600160e01b03199081168255600182018054909116905560020183905533835260199091529020805467ffffffffffffffff19169055505050505050565b612fb3613919565b6000612fbe33612d19565b9050600080612fce85858d6138f6565b91509150612fee338c878785600080516020615d62833981519152613c7f565b612ff783614190565b6130003361387d565b6130996040518061010001604052808e6001600160401b031681526020018c6001600160a01b031681526020018b62ffffff1681526020018a6001600160601b0316815260200189600080516020615d628339815191526130619190615861565b8152602001898152602001604051806020016040528060008152508152602001886001600160401b0316815250858d85858a33613945565b505050505050505050505050565b60006130b233612d19565b604080516001600160401b0380871682528316602082015233918101919091526001600160601b03841660608201529091507fdf35dff92be2e5e7dae645fb3e7a3d43e9487ecbbfd323bfef15c43ad2de58a590608001612e90565b61311882336141c7565b6001600160a01b038216600090815260036020526040902054600160481b900460ff1615801561314a57506001543414155b1561316857604051632740b97160e11b815260040160405180910390fd5b61136082333484614276565b6001600160a01b0381166000908152600360208181526040808420815160a0810190925280546001600160401b03811683528594859485948594859485949293919291840191600160401b90910460ff16908111156131d5576131d5614f17565b60038111156131e6576131e6614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b039081166040808501919091526001909401541660609283015283015190830151608084015184519490930151919c909a5091985091965090945092505050565b613257613b6f565b601d546040516000916001600160a01b03169083908381818185875af1925050503d80600081146132a4576040519150601f19603f3d011682016040523d82523d6000602084013e6132a9565b606091505b50509050806113605760405163e53e5bcd60e01b815260040160405180910390fd5b6132d3613b6f565b6001600160a01b03811661333d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61127281613cec565b61334e613b6f565b6001600160a01b0383166000908152601a6020526040902081908360108110613379576133796158cb565b01906133859082615927565b50505050565b613393613b6f565b816001600160a01b03166323b872dd306133b56000546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101849052606401600060405180830381600087803b15801561340457600080fd5b505af1158015613418573d6000803e3d6000fd5b505050505050565b6001600160a01b0383166000908152601960205260408120546001600160401b03161561344f5750600061175b565b81158061345c5750600f82115b1561346657600191505b61347183858461172d565b905061347c84611ade565b15613543576040516370a0823160e01b81526001600160a01b0385811660048301528416906370a0823190602401602060405180830381865afa1580156134c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134eb9190615a0d565b6134f5908261574d565b6001600160a01b03858116600090815260036020526040908190205490516370a0823160e01b8152600160501b909104821660048201819052929350908516906370a08231906024016121cf565b61354c846120ad565b61175b576040516370a0823160e01b81526001600160a01b0385811660048301528416906370a082319060240161225e565b6001600160a01b0382166135a55760405163bd78145160e01b815260040160405180910390fd5b826001600160a01b0316826001600160a01b0316036135d7576040516304da706760e51b815260040160405180910390fd5b6001600160a01b038116611d0057604051634ca5048960e01b815260040160405180910390fd5b6001600160a01b03848116600081815260036020908152604091829020805469ffff000000000000000019166901030000000000000000179055905185841681526001600160401b03851693871692917f5717bcaec46242edc8fb07322221c02d6dd3de7a954d5c009ee550cd0cdf768591015b60405180910390a450505050565b6001600160a01b03808516600081815260036020908152604080832080546001600160f01b031916815560010180546001600160a01b03199081169091559488168084526004909252918290208054909416909355519091907fbd302a9bf683315c275f4a7f0092796d97d17fbb2a89bbc8938bd6842c38eb89906137089086908690615a98565b60405180910390a350505050565b604080516101008101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c082015260e0810191909152600080600080600080600080898060200190518101906137769190615ac1565b60408051610100810182526001600160401b03998a1681526001600160a01b03909816602089015262ffffff909616958701959095526001600160601b039093166060860152608085019190915260a084015260c08301529190911660e08201529a9950505050505050505050565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b0381166123265760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b6044820152606401613334565b600580546001919060009061389c9084906001600160401b03166159e6565b82546001600160401b039182166101009390930a9283029282021916919091179091556005546001600160a01b039093166000908152601960205260409020805467ffffffffffffffff1916939091169290921790915550565b6000806139038585613f09565b915061390f8584613bc9565b9050935093915050565b601654610100900460ff161561241a576040516001621dce6960e31b0319815260040160405180910390fd5b6139518787878561439b565b61398785886040015162ffffff166201518061396d9190615bac565b61397790426159e6565b89602001518a60a00151886139e9565b6139b281868489878c60a00151600080516020615d628339815191526139ad9190615861565b613a8c565b60208701516139d390829084896139c98284613bc9565b8c60a00151613a8c565b6139e0878284898961482e565b50505050505050565b6040805160a0810182526005546001600160401b0390811682526001600160a01b039788166020808401918252978216838501908152968916606084019081526080840196875260009586526017909852929093209051815492519084166001600160e01b031993841617600160401b91891682021782559451600182018054975191909416969092169590951795169092029390931790559051600290910155565b60008281526018602052604081208054839290613aaa90849061574d565b909155505060408051848152602081018390526001600160a01b038087169288821692918a16917fa1c0f6bb9ba071b3dfd066f852f622c51d4073a7cc058fd04296ae916b8b0bc691015b60405180910390a4505050505050565b6001600160a01b038216613b2c576040516334b1be0d60e21b815260040160405180910390fd5b613b35836113bd565b15613b4557611d008383836148c7565b613b4e8361232b565b1561139a5760405160016208d37d60e21b0319815260040160405180910390fd5b6000546001600160a01b0316331461241a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401613334565b6040516001600160601b0319606084811b8216602084015283901b1660348201526000906048015b60405160208183030381529060405280519060200120905092915050565b600080613c1d60058561584a565b613c2890600a615cbb565b9050600084600103613c3c57506001613c61565b6005613c49600187615861565b613c53919061584a565b613c5e90600a615cbb565b90505b80613c6c8386615cdd565b613c769190615cf1565b95945050505050565b60008281526018602052604081208054839290613c9d908490615861565b909155505060408051848152602081018390526001600160a01b038087169289821692918916917fa1c0f6bb9ba071b3dfd066f852f622c51d4073a7cc058fd04296ae916b8b0bc69101613af5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b613d4785858561357e565b613d528560016118c1565b1580613d665750613d648460006118c1565b155b15613d84576040516307facddb60e11b815260040160405180910390fd5b6040805160a0810182526001600160401b0383811682526001602080840182815291548714848601526001600160a01b03898116606086015288811660808601528a1660009081526003918290529490942083518154931667ffffffffffffffff1984168117825591519394909392849268ffffffffffffffffff199091161790600160401b908490811115613e1c57613e1c614f17565b0217905550604082810151825460608501517fffff000000000000000000000000000000000000000000ffffffffffffffffff909116600160481b921515929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff1691909117600160501b6001600160a01b0392831602178355608090930151600190920180546001600160a01b03191692841692909217909155805185831681526001600160401b0384166020820152868316928816917f752c94da010e5b94c0278334398a684d4a7bde91f0f38c9dbb1766ad4f586c6991015b60405180910390a35050505050565b6040516001600160601b0319606084901b16602082015260348101829052600090605401613bf1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d009084906149db565b6000806000613f948787876138f6565b6040516001600160601b031960608b811b8216602084015288901b16603482015291945092506048016040516020818303038152906040528051906020012090509450945094915050565b6000938452601760205260409093206001810180546001600160a01b03909316600160401b026001600160e01b03199093166001600160401b03909416939093179190911790915560020155565b600061403a600a83615cdd565b90508015806140495750600481115b1561406757604051631ec9ca4160e21b815260040160405180910390fd5b6000614074600a84615cf1565b9050600182036140915761408c858587600085613d3c565b6140e7565b600282036140b0576140a384866141c7565b61408c8486600084614276565b600382036140cc5761408c8585836001600160401b0316613b05565b600482036140e7576140e785826001600160401b0316611322565b5050505050565b60008060008060006141028b888b8b613f84565b9250925092506141458a8a8d8a86601760008a815260200190815260200160002060020154600080516020615d628339815191526141409190615861565b613c7f565b6141698a898d8a85601760008a815260200190815260200160002060020154613c7f565b61417286614190565b5090999098509650505050505050565b611272816000806000613fdf565b6040516001600160401b038216907ff4a42f4ac762c05af0cbe21a8c16a2a87cd93719bbcfae68dce6a1b7f353a16c90600090a250565b6001600160a01b03828116600090815260036020526040902054600160501b90048116908216141580614230575060016001600160a01b038316600090815260036020819052604090912054600160401b900460ff169081111561422d5761422d614f17565b14155b1561424e57604051634cd87fb560e01b815260040160405180910390fd5b6142598160006118c1565b611360576040516307facddb60e11b815260040160405180910390fd5b6001600160a01b03838116600081815260046020908152604080832080546001600160a01b0319168a87169081179091558084526003835292819020600101549051941684526001600160401b038516937fda23dc0f47967fd81e9b62f5207a955b77295fef190364f10a6c3cf26773c1ab910160405180910390a46001600160a01b038416600090815260036020526040902054600160481b900460ff1680614321575060015482145b15614364576001600160a01b0380851660009081526003602052604090206001810154905461435f92879287929116906001600160401b03166135fe565b613385565b5050506001600160a01b03166000908152600360205260409020805468ff0000000000000000191668020000000000000000179055565b60e0848101516001600160401b03166000908152601b602090815260409182902082516101208101845281546001600160a01b038082168352600160a01b80830462ffffff1695840195909552600160b81b820463ffffffff1695830195909552600160d81b900460ff16151560608201526001820154808516608083018190529390046001600160601b031660a0820152600282015460c0820152600382015494810194909452600401548216610100840152908316141580614470575080606001511580156144705750838160c0015114155b80614495575080600001516001600160a01b031685602001516001600160a01b031614155b806144b25750806020015162ffffff16856040015162ffffff1614155b806144d757508060a001516001600160601b031685606001516001600160601b031614155b806144ea57508060e001518560a0015114155b806144fe5750806040015163ffffffff1642115b1561451c57604051631771cc0160e11b815260040160405180910390fd5b61010081015160009081906001600160a01b03166145705750506005547f000000000000000000000000000000000000000000000000000000000000000090600160801b90046001600160601b03166145db565b6101008301516001600160a01b0381166000908152601c602052604090205490925060ff166145b257604051630eca12dd60e31b815260040160405180910390fd5b506001600160a01b0381166000908152601c602052604090205461010090046001600160601b03165b60e08701516001600160401b03166000908152601b6020526040812080546001600160e01b031916815560018101829055600281018290556003810182905560040180546001600160a01b031916905560608801516146449083906001600160601b031661574d565b905080156146cd5760208801516040516323b872dd60e01b81526001600160a01b03918216600482015230602482015260448101839052908416906323b872dd906064016020604051808303816000875af11580156146a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146cb9190615d05565b505b600088606001516001600160601b03166000036146eb575081614731565b60055460608a01518491620186a09161471191600160e01b900463ffffffff1690615d22565b6001600160601b03166147249190615cf1565b61472e919061574d565b90505b60608901516001600160601b0316156147cf576001600160a01b03841663a9059cbb8861475e8486615861565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156147a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147cd9190615d05565b505b885160e08a0151604080516001600160401b03938416815292909116602083015281018290526001600160a01b03851660608201527f848da897c5a8478af17be9c5fb6ebd38774ff21fc83fdc1a19216edb8dc1eb029060800161209a565b600560009054906101000a90046001600160401b03166001600160401b031685600001516001600160401b03167f874a0ec379dec4a6469317f6b2eb8bcb7381c2e0074e09ba06e85ef2dcb2ce4b868686868b602001518c6040015162ffffff166201518061489d9190615bac565b6148a790426159e6565b60a08e015160c08f0151604051613efa9897969594939291600091615a26565b6001600160a01b0383166000908152600360208181526040808420815160a0810190925280546001600160401b038116835291939092840191600160401b900460ff169081111561491a5761491a614f17565b600381111561492b5761492b614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b03908116604080850191909152600194850154821660609485015289821660008181526003855282902090950180546001600160a01b0319168a84169081179091559386015160808701518251908416815293840189905295965092941692917fa0aa3b38771c7ab4ece55c6009c41d814f4ff862285d0825c24528a87fd124d79101613672565b6000614a30826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614aad9092919063ffffffff16565b805190915015611d005780806020019051810190614a4e9190615d05565b611d005760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401613334565b60606122a98484600085856001600160a01b0385163b614b0f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401613334565b600080866001600160a01b03168587604051614b2b9190615d45565b60006040518083038185875af1925050503d8060008114614b68576040519150601f19603f3d011682016040523d82523d6000602084013e614b6d565b606091505b5091509150614b7d828286614b88565b979650505050505050565b60608315614b9757508161175b565b825115614ba75782518084602001fd5b8160405162461bcd60e51b81526004016133349190614c2a565b600060208284031215614bd357600080fd5b5035919050565b60005b83811015614bf5578181015183820152602001614bdd565b50506000910152565b60008151808452614c16816020860160208601614bda565b601f01601f19169290920160200192915050565b60208152600061175b6020830184614bfe565b6001600160a01b038116811461127257600080fd5b803561232681614c3d565b600060208284031215614c6f57600080fd5b813561175b81614c3d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614cb857614cb8614c7a565b604052919050565b60006001600160401b03821115614cd957614cd9614c7a565b50601f01601f191660200190565b6000614cfa614cf584614cc0565b614c90565b9050828152838383011115614d0e57600080fd5b828260208301376000602084830101529392505050565b60008060008060808587031215614d3b57600080fd5b8435614d4681614c3d565b93506020850135614d5681614c3d565b92506040850135915060608501356001600160401b03811115614d7857600080fd5b8501601f81018713614d8957600080fd5b614d9887823560208401614ce7565b91505092959194509250565b60008060408385031215614db757600080fd5b8235614dc281614c3d565b946020939093013593505050565b801515811461127257600080fd5b600060208284031215614df057600080fd5b813561175b81614dd0565b600080600060608486031215614e1057600080fd5b8335614e1b81614c3d565b92506020840135614e2b81614c3d565b929592945050506040919091013590565b6001600160401b038116811461127257600080fd5b600080600080600060a08688031215614e6957600080fd5b8535614e7481614e3c565b94506020860135614e8481614c3d565b93506040860135614e9481614c3d565b94979396509394606081013594506080013592915050565b6001600160601b038116811461127257600080fd5b600060208284031215614ed357600080fd5b813561175b81614eac565b60008060408385031215614ef157600080fd5b8235614efc81614c3d565b91506020830135614f0c81614dd0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60c0810160048810614f4157614f41614f17565b9681526001600160a01b03958616602082015293851660408501529190931660608301526001600160401b03909216608082015290151560a09091015290565b60008060408385031215614f9457600080fd5b8235614f9f81614c3d565b91506020830135614f0c81614eac565b600080600060608486031215614fc457600080fd5b8335614fcf81614c3d565b95602085013595506040909401359392505050565b600082601f830112614ff557600080fd5b61175b83833560208501614ce7565b6000806040838503121561501757600080fd5b8235915060208301356001600160401b0381111561503457600080fd5b61504085828601614fe4565b9150509250929050565b62ffffff8116811461127257600080fd5b80356123268161504a565b803563ffffffff8116811461232657600080fd5b60008060008060008060008060006101208a8c03121561509957600080fd5b89356150a481614e3c565b985060208a01356150b48161504a565b97506150c260408b01615066565b965060608a01356150d281614dd0565b955060808a01356150e281614c3d565b945060a08a01356150f281614eac565b935060c08a013561510281614c3d565b8093505060e08a013591506101008a013590509295985092959850929598565b60006020828403121561513457600080fd5b61175b82615066565b60008060008060008060c0878903121561515657600080fd5b863561516181614e3c565b9550602087013561517181614e3c565b945060408701356151818161504a565b935061518f60608801615066565b9250608087013561519f81614eac565b8092505060a087013590509295509295509295565b6000806000606084860312156151c957600080fd5b83356151d481614c3d565b925060208401356151e481614c3d565b915060408401356151f481614e3c565b809150509250925092565b600080600080600060a0868803121561521757600080fd5b853561522281614e3c565b9450602086013561523281614c3d565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561526357600080fd5b50508035926020909101359150565b600080600080600080600080610100898b03121561528f57600080fd5b883561529a81614e3c565b975060208901356152aa81614c3d565b96506040890135955060608901356152c181614c3d565b945060808901356152d181614c3d565b935060a08901356152e181614e3c565b925060c0890135915060e08901356001600160401b0381111561530357600080fd5b61530f8b828c01614fe4565b9150509295985092959890939650565b60006020828403121561533157600080fd5b813561175b81614e3c565b6000806040838503121561534f57600080fd5b823561535a81614e3c565b91506020830135614f0c81614e3c565b6000806000806000806000806000806101408b8d03121561538a57600080fd5b8a3561539581614e3c565b995060208b01356153a581614c3d565b985060408b01356153b581614c3d565b975060608b01356153c581614c3d565b965060808b01356153d58161504a565b955060a08b01356153e581614eac565b945060c08b0135935060e08b01356153fc81614e3c565b92506101008b013561540d81614c3d565b809250506101208b013590509295989b9194979a5092959850565b6000806000806000806000806000806101408b8d03121561544857600080fd5b8a3561545381614e3c565b995060208b013561546381614c3d565b985060408b013561547381614c3d565b975060608b013561548381614c3d565b965060808b013561549381614eac565b95506154a160a08c0161505b565b94506154af60c08c01614c52565b935060e08b013592506101008b013591506101208b01356001600160401b038111156154da57600080fd5b6154e68d828e01614fe4565b9150509295989b9194979a5092959850565b6000806040838503121561550b57600080fd5b8235614f9f81614e3c565b600080600080600080600060e0888a03121561553157600080fd5b873561553c81614e3c565b9650602088013561554c81614c3d565b9550604088013561555c81614c3d565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b6000806000806080858703121561559a57600080fd5b84356155a581614c3d565b93506020850135925060408501356155bc81614c3d565b915060608501356155cc81614c3d565b939692955090935050565b60008060008060008060008060006101208a8c0312156155f657600080fd5b893561560181614e3c565b985060208a013561561181614c3d565b975060408a013561562181614c3d565b965060608a01356156318161504a565b955060808a013561564181614eac565b945060a08a0135935060c08a013561565881614e3c565b925060e08a013561566881614c3d565b809250506101008a013590509295985092959850929598565b6000806040838503121561569457600080fd5b823561535a81614c3d565b6000806000606084860312156156b457600080fd5b83356156bf81614c3d565b92506020840135915060408401356001600160401b038111156156e157600080fd5b6156ed86828701614fe4565b9150509250925092565b60008060006060848603121561570c57600080fd5b833561571781614c3d565b9250602084013561572781614c3d565b915060408401356151f481614c3d565b634e487b7160e01b600052601160045260246000fd5b808201808211156119e5576119e5615737565b6001600160a01b03898116825288811660208301526001600160601b038816604083015262ffffff871660608301528516608082015260a0810184905260c0810183905261010060e082018190526000906157bd83820185614bfe565b9b9a5050505050505050505050565b6001600160a01b038a8116825289811660208301526001600160601b038916604083015262ffffff881660608301528616608082015260a0810185905260c0810184905261012060e0820181905260009061582983820186614bfe565b9150506001600160401b0383166101008301529a9950505050505050505050565b80820281158282048414176119e5576119e5615737565b818103818111156119e5576119e5615737565b600181811c9082168061588857607f821691505b6020821081036158a857634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156158c057600080fd5b815161175b81614c3d565b634e487b7160e01b600052603260045260246000fd5b601f821115611d0057600081815260208120601f850160051c810160208610156159085750805b601f850160051c820191505b8181101561341857828155600101615914565b81516001600160401b0381111561594057615940614c7a565b6159548161594e8454615874565b846158e1565b602080601f83116001811461598957600084156159715750858301515b600019600386901b1c1916600185901b178555613418565b600085815260208120601f198616915b828110156159b857888601518255948401946001909101908401615999565b50858210156159d65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160401b03818116838216019080821115615a0657615a06615737565b5092915050565b600060208284031215615a1f57600080fd5b5051919050565b6001600160a01b038a811682528981166020830152604082018990528781166060830152861660808201526001600160401b03851660a082015260c0810184905260e081018390526101206101008201819052600090615a8883820185614bfe565b9c9b505050505050505050505050565b6040810160028410615aac57615aac614f17565b9281526020015290565b805161232681614e3c565b600080600080600080600080610100898b031215615ade57600080fd5b8851615ae981614e3c565b60208a0151909850615afa81614c3d565b60408a0151909750615b0b8161504a565b60608a0151909650615b1c81614eac565b809550506080890151935060a0890151925060c08901516001600160401b03811115615b4757600080fd5b8901601f81018b13615b5857600080fd5b8051615b66614cf582614cc0565b8181528c6020838501011115615b7b57600080fd5b615b8c826020830160208601614bda565b9350615b9d91505060e08a01615ab6565b90509295985092959890939650565b6001600160401b03818116838216028082169190828114615bcf57615bcf615737565b505092915050565b600181815b80851115615c12578160001904821115615bf857615bf8615737565b80851615615c0557918102915b93841c9390800290615bdc565b509250929050565b600082615c29575060016119e5565b81615c36575060006119e5565b8160018114615c4c5760028114615c5657615c72565b60019150506119e5565b60ff841115615c6757615c67615737565b50506001821b6119e5565b5060208310610133831016604e8410600b8410161715615c95575081810a6119e5565b615c9f8383615bd7565b8060001904821115615cb357615cb3615737565b029392505050565b600061175b8383615c1a565b634e487b7160e01b600052601260045260246000fd5b600082615cec57615cec615cc7565b500690565b600082615d0057615d00615cc7565b500490565b600060208284031215615d1757600080fd5b815161175b81614dd0565b6001600160601b03818116838216028082169190828114615bcf57615bcf615737565b60008251615d57818460208701614bda565b919091019291505056fe00000172eca084a2dfd7bef9ff78b9eed31c81789db8f74134d76bc8e5e3eaa1a2646970667358221220f1fb24f530623c085a1848e4eb0747caac6bcda1a16bcf475a7e65a4c50792d864736f6c63430008110033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028b224a23a6c66e4b496fef0e544ccf7bf1f9b96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000002540be400
Deployed Bytecode
0x60806040526004361061048d5760003560e01c80638da5cb5b11610255578063c1f5c49a11610144578063dd2ebdb4116100c1578063f14210a611610085578063f14210a614611132578063f2fde38b14611152578063f3362fb914611172578063f3e414f814611192578063f8907b60146111b2578063fc2bc7b2146111d257600080fd5b8063dd2ebdb414611081578063e575d025146110a1578063e963134f146110b4578063ec8b9071146110d4578063f023a734146110f357600080fd5b8063cf135b9d11610108578063cf135b9d14610feb578063d1d3e28f1461100b578063d5472c181461102b578063d56bb0571461104b578063db7840cb1461106157600080fd5b8063c1f5c49a14610f5f578063c2f5dc4414610f7f578063c858380814610f95578063c93b228914610fb5578063ce46756914610fcb57600080fd5b8063a2966f5f116101d2578063b2969acf11610196578063b2969acf14610ea0578063b810c63614610ec0578063b9f97d4114610eff578063bd17532414610f2c578063c124eb1f14610f3f57600080fd5b8063a2966f5f14610d39578063a4c1408414610d4c578063a9059cbb14610e40578063ae7044c214610e60578063afb85e6214610e8057600080fd5b806393a1d1aa1161021957806393a1d1aa14610c8a57806395d89b4114610caa578063a0a3660614610cd9578063a1db978214610cf9578063a276c41514610d1957600080fd5b80638da5cb5b14610bce578063906f634314610bec57806390938e9514610c34578063913965c314610c5457806392be2ab814610c6a57600080fd5b806341e3196f1161037c578063657f9233116102f957806370a08231116102bd57806370a0823114610b0b578063715018a614610b2d5780637a3be00d14610b425780637afbd21214610b625780638523837014610b8257806388d6f15114610b9557600080fd5b8063657f923314610a375780636605bfda14610a575780636bcf608814610a775780636e22bad914610a8c5780636f1dcc3b14610aeb57600080fd5b80635205cb5b116103405780635205cb5b1461099757806353556440146109b757806357b14d9e146109d75780635ba58955146109f757806361d027b314610a1757600080fd5b806341e3196f146108f757806342b046901461091757806342de52551461093757806345065089146109575780634835de371461097757600080fd5b80631fc784101161040a578063274971b3116103ce578063274971b31461082b578063313ce5671461084b57806333ac8aa8146108675780633a0236e3146108995780633a30d464146108b957600080fd5b80631fc78410146106e0578063214cf7ad1461070057806321a0bd9e146107a557806321ce9f91146107e4578063265d97ee1461080b57600080fd5b8063150b7a0211610451578063150b7a02146106245780631718e0cf1461065d57806318160ddd1461067d5780631888f727146106a057806318976a24146106c057600080fd5b8063061f98111461052a57806306fdde031461054a5780630956d8a71461058c5780630ec735da146105bc57806314977eb8146105d657600080fd5b366105255760015434141580156104a657506002543414155b80156104c85750336000908152601960205260409020546001600160401b0316155b80156104df57506000546001600160a01b03163314155b156104fd5760405163020ad41b60e11b815260040160405180910390fd5b60015434036105115761050f336111f2565b005b600254340361050f5761050f336000611322565b600080fd5b34801561053657600080fd5b5061050f610545366004614bc1565b6113b3565b34801561055657600080fd5b506040805180820190915260078152664550532041504960c81b60208201525b6040516105839190614c2a565b60405180910390f35b34801561059857600080fd5b506105ac6105a7366004614c5d565b6113bd565b6040519015158152602001610583565b3480156105c857600080fd5b506016546105ac9060ff1681565b3480156105e257600080fd5b5061060c6105f1366004614c5d565b6019602052600090815260409020546001600160401b031681565b6040516001600160401b039091168152602001610583565b34801561063057600080fd5b5061064461063f366004614d25565b6113fc565b6040516001600160e01b03199091168152602001610583565b34801561066957600080fd5b5061050f610678366004614da4565b6116e9565b34801561068957600080fd5b506106926116f4565b604051908152602001610583565b3480156106ac57600080fd5b5061050f6106bb366004614dde565b61170b565b3480156106cc57600080fd5b506106926106db366004614dfb565b61172d565b3480156106ec57600080fd5b5061050f6106fb366004614e51565b611762565b34801561070c57600080fd5b5061076361071b366004614bc1565b6017602052600090815260409020805460018201546002909201546001600160401b03808316936001600160a01b03600160401b948590048116949282169392909104169085565b604080516001600160401b0396871681526001600160a01b0395861660208201529590931692850192909252919091166060830152608082015260a001610583565b3480156107b157600080fd5b506005546107cc90600160801b90046001600160601b031681565b6040516001600160601b039091168152602001610583565b3480156107f057600080fd5b5060055461060c90600160401b90046001600160401b031681565b34801561081757600080fd5b5061050f610826366004614ec1565b611888565b34801561083757600080fd5b506105ac610846366004614ede565b6118c1565b34801561085757600080fd5b5060405160008152602001610583565b34801561087357600080fd5b50610887610882366004614c5d565b6119eb565b60405161058396959493929190614f2d565b3480156108a557600080fd5b506105ac6108b4366004614c5d565b611ade565b3480156108c557600080fd5b506016546108df906201000090046001600160a01b031681565b6040516001600160a01b039091168152602001610583565b34801561090357600080fd5b5061050f610912366004614f81565b611b1a565b34801561092357600080fd5b50610576610932366004614bc1565b611b69565b34801561094357600080fd5b506108df610952366004614faf565b611c09565b34801561096357600080fd5b5061050f610972366004615004565b611cd8565b34801561098357600080fd5b5061050f610992366004614c5d565b611d05565b3480156109a357600080fd5b5061050f6109b236600461507a565b611d5b565b3480156109c357600080fd5b506105ac6109d2366004614c5d565b6120ad565b3480156109e357600080fd5b506106926109f2366004614dfb565b6120f7565b348015610a0357600080fd5b50610692610a12366004614c5d565b6122b1565b348015610a2357600080fd5b50601d546108df906001600160a01b031681565b348015610a4357600080fd5b506105ac610a52366004614c5d565b61232b565b348015610a6357600080fd5b5061050f610a72366004614c5d565b61239a565b348015610a8357600080fd5b5061050f6123c4565b348015610a9857600080fd5b50610acc610aa7366004614c5d565b601c6020526000908152604090205460ff81169061010090046001600160601b031682565b6040805192151583526001600160601b03909116602083015201610583565b348015610af757600080fd5b5061050f610b06366004615122565b6123db565b348015610b1757600080fd5b50610692610b26366004614c5d565b50601f5490565b348015610b3957600080fd5b5061050f612408565b348015610b4e57600080fd5b5061050f610b5d36600461513d565b61241c565b348015610b6e57600080fd5b50610887610b7d366004614c5d565b6125c7565b61050f610b903660046151b4565b61270e565b348015610ba157600080fd5b50600554610bb990600160e01b900463ffffffff1681565b60405163ffffffff9091168152602001610583565b348015610bda57600080fd5b506000546001600160a01b03166108df565b348015610bf857600080fd5b50610c0c610c07366004614c5d565b61273d565b604080516001600160a01b039485168152939092166020840152151590820152606001610583565b348015610c4057600080fd5b5061050f610c4f3660046151ff565b6127be565b348015610c6057600080fd5b50610692601e5481565b348015610c7657600080fd5b5061050f610c85366004614bc1565b61283a565b348015610c9657600080fd5b506108df610ca5366004614faf565b612847565b348015610cb657600080fd5b5060408051808201909152600681526545505341504960d01b6020820152610576565b348015610ce557600080fd5b5061050f610cf4366004615250565b6128fc565b348015610d0557600080fd5b5061050f610d14366004614da4565b61290f565b348015610d2557600080fd5b50610576610d34366004614da4565b61293d565b61050f610d47366004615272565b612969565b348015610d5857600080fd5b50610dd9610d6736600461531f565b601b60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0380851695600160a01b80870462ffffff1696600160b81b810463ffffffff1696600160d81b90910460ff169584821695929091046001600160601b0316939092911689565b604080516001600160a01b039a8b16815262ffffff90991660208a015263ffffffff90971696880196909652931515606087015291861660808601526001600160601b031660a085015260c084015260e08301529190911661010082015261012001610583565b348015610e4c57600080fd5b506105ac610e5b366004614da4565b612a26565b348015610e6c57600080fd5b5061050f610e7b366004614c5d565b612a3c565b348015610e8c57600080fd5b5061050f610e9b366004614e51565b612a71565b348015610eac57600080fd5b5061050f610ebb36600461533c565b612b6e565b348015610ecc57600080fd5b5060055460408051600160801b83046001600160601b03168152600160e01b90920463ffffffff16602083015201610583565b348015610f0b57600080fd5b50610692610f1a366004614bc1565b60186020526000908152604090205481565b61050f610f3a36600461536a565b612c3e565b348015610f4b57600080fd5b5061060c610f5a366004614c5d565b612d19565b348015610f6b57600080fd5b5061050f610f7a366004615428565b612d5c565b348015610f8b57600080fd5b5061069260025481565b348015610fa157600080fd5b5061050f610fb03660046154f8565b612e33565b348015610fc157600080fd5b5061069260015481565b348015610fd757600080fd5b5061050f610fe6366004615516565b612e9d565b348015610ff757600080fd5b5060055461060c906001600160401b031681565b34801561101757600080fd5b5061050f611026366004614bc1565b612f2d565b34801561103757600080fd5b5061050f611046366004615584565b612f3a565b34801561105757600080fd5b50610692601f5481565b34801561106d57600080fd5b5061050f61107c3660046155d7565b612fab565b34801561108d57600080fd5b5061050f61109c3660046154f8565b6130a7565b61050f6110af366004615681565b61310e565b3480156110c057600080fd5b506108876110cf366004614c5d565b613174565b3480156110e057600080fd5b506016546105ac90610100900460ff1681565b3480156110ff57600080fd5b5061060c61110e366004614c5d565b6001600160a01b03166000908152601960205260409020546001600160401b031690565b34801561113e57600080fd5b5061050f61114d366004614bc1565b61324f565b34801561115e57600080fd5b5061050f61116d366004614c5d565b6132cb565b34801561117e57600080fd5b5061050f61118d36600461569f565b613346565b34801561119e57600080fd5b5061050f6111ad366004614da4565b61338b565b3480156111be57600080fd5b506106926111cd366004614dfb565b613420565b3480156111de57600080fd5b5061050f6111ed3660046156f7565b61357e565b60026001600160a01b038216600090815260036020819052604090912054600160401b900460ff169081111561122a5761122a614f17565b03611275576001600160a01b0380821660009081526003602052604090208054600190910154611272928492600160501b8104821692909116906001600160401b03166135fe565b50565b60026001600160a01b03828116600090815260046020908152604080832054909316825260039081905291902054600160401b900460ff16908111156112bd576112bd614f17565b03611309576001600160a01b03818116600090815260046020908152604080832054841680845260039092529091206001810154905461127293859216906001600160401b03166135fe565b604051637115fdd360e01b815260040160405180910390fd5b61132b826113bd565b15611364576001600160a01b03808316600090815260036020526040812054611360928592600160501b909204169084613680565b5050565b61136d8261232b565b1561139a576001600160a01b03808316600090815260046020526040902054611360911683600184613680565b60405163163e0acf60e21b815260040160405180910390fd5b6112723382611322565b6001600160a01b038116600090815260036020526040812054600160401b900460ff16818160038111156113f3576113f3614f17565b14159392505050565b60006001600160a01b0384166114255760405163989992a560e01b815260040160405180910390fd5b33600061143184613716565b9050600080516020615d628339815191528160a001518260800151611456919061574d565b1461147457604051630eb911d560e01b815260040160405180910390fd5b856001600160a01b031681602001516001600160a01b0316036114aa57604051637c72ea1360e01b815260040160405180910390fd5b6016546000906114c8906201000090046001600160a01b03166137e5565b90506114d38161387d565b8160e001516001600160401b031660000361157957806001600160a01b0316600560009054906101000a90046001600160401b03166001600160401b031683600001516001600160401b03167f5a0f2eb6ae0aa35d6df4a692dcea08836a52a923522d010ac5241fce52a2180e8a8660200151876060015188604001518a8e8b60a001518c60c00151604051611570989796959493929190615760565b60405180910390a45b60008061158785898b6138f6565b915091508360e001516001600160401b03166000146115bc576115a8613919565b6115b784898b85858a89613945565b6115e7565b6115cb896000806000866139e9565b6115e7838a878b85600080516020615d62833981519152613a8c565b826001600160a01b0316636638439e8a866020015187606001518860400151338e8b60a001518c60c001518d60e001516040518a63ffffffff1660e01b815260040161163b999897969594939291906157cc565b600060405180830381600087803b15801561165557600080fd5b505af1158015611669573d6000803e3d6000fd5b5050604051632142170760e11b81523060048201526001600160a01b0386166024820152604481018b90523392506342842e0e9150606401600060405180830381600087803b1580156116bb57600080fd5b505af11580156116cf573d6000803e3d6000fd5b50630a85bd0160e11b9d9c50505050505050505050505050565b611360338383613b05565b6000601f54601e54611706919061584a565b905090565b611713613b6f565b601680549115156101000261ff0019909216919091179055565b60008061173a8585613bc9565b600081815260186020526040902054909150611757908490613c0f565b9150505b9392505050565b61176a613919565b600061177533612d19565b90506000806117858686896138f6565b600082815260176020526040812054929450909250600160401b9091046001600160a01b0316906117b68883613bc9565b60008581526017602052604081208054600160401b600160e01b031916600160401b6001600160a01b038e1602178155600201549192509061180690600080516020615d62833981519152615861565b905061181633848b8b8686613c7f565b611824338b8b8b8886613a8c565b896001600160a01b0316866001600160401b03168c6001600160401b03167f5dbf7557a2e3e90ad585a162df084f4b4e0c5b124740bf7821294703d0fe639c8a60405161187391815260200190565b60405180910390a45050505050505050505050565b611890613b6f565b600580546001600160601b03909216600160801b026bffffffffffffffffffffffff60801b19909216919091179055565b6001600160a01b038281166000908152600460209081526040808320549093168252600390819052918120549091600160401b90910460ff169081600381111561190d5761190d614f17565b148061192a5750600281600381111561192857611928614f17565b145b8061194e575082801561194e5750600181600381111561194c5761194c614f17565b145b1561195d5760009150506119e5565b506001600160a01b038316600090815260036020819052604090912054600160401b900460ff169081600381111561199757611997614f17565b14806119b4575060028160038111156119b2576119b2614f17565b145b806119d0575060018160038111156119ce576119ce614f17565b145b156119df5760009150506119e5565b60019150505b92915050565b6001600160a01b038181166000908152600460209081526040808320549093168083526003808352848420855160a0810190965280546001600160401b0381168752949586958695869586958695919486949093840191600160401b90910460ff1690811115611a5d57611a5d614f17565b6003811115611a6e57611a6e614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b039081166040808501919091526001909401541660609283015283015190830151608084015184519490930151919b5094995093975095509350909150505b91939550919395565b6001600160a01b0381166000908152600360208190526040822054600160401b900460ff1681811115611b1357611b13614f17565b1492915050565b611b22613b6f565b6001600160a01b039091166000908152601c6020526040902080546001600160601b03909216610100026cffffffffffffffffffffffffff19909216919091176001179055565b60068160108110611b7957600080fd5b018054909150611b8890615874565b80601f0160208091040260200160405190810160405280929190818152602001828054611bb490615874565b8015611c015780601f10611bd657610100808354040283529160200191611c01565b820191906000526020600020905b815481529060010190602001808311611be457829003601f168201915b505050505081565b6000811580611c185750600f82115b15611c2257600191505b611c2d848484612847565b90506001600160a01b03811661175b576040516331a9108f60e11b8152600481018490526001600160a01b03851690636352211e90602401602060405180830381865afa158015611c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca691906158ae565b9050611cb1816120ad565b1561175b576001600160a01b03908116600090815260046020526040902054169392505050565b611ce0613b6f565b8060068360108110611cf457611cf46158cb565b0190611d009082615927565b505050565b611d0d613b6f565b60165460ff1615611d3157604051632e6129eb60e11b815260040160405180910390fd5b601680546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6001600160a01b03831615801590611d8c57506001600160a01b0383166000908152601c602052604090205460ff16155b15611daa57604051630eca12dd60e31b815260040160405180910390fd5b6001600560088282829054906101000a90046001600160401b0316611dcf91906159e6565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550604051806101200160405280336001600160a01b031681526020018962ffffff1681526020018863ffffffff1681526020018715158152602001866001600160a01b03168152602001856001600160601b03168152602001838152602001828152602001846001600160a01b0316815250601b6000600560089054906101000a90046001600160401b03166001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548162ffffff021916908362ffffff16021790555060408201518160000160176101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601b6101000a81548160ff02191690831515021790555060808201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160010160146101000a8154816001600160601b0302191690836001600160601b0316021790555060c0820151816002015560e082015181600301556101008201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507fcfc9ed74ed2586915eb2ba885b6516120033d928b11ec45eb846af0700dabca489600560089054906101000a90046001600160401b03168789868d8d8b893360405161209a9a999897969594939291906001600160401b039a8b1681529890991660208901526001600160a01b0396871660408901529415156060880152608087019390935262ffffff9190911660a086015263ffffffff1660c08501526001600160601b031660e0840152610100830152919091166101208201526101400190565b60405180910390a1505050505050505050565b600060036001600160a01b03838116600090815260046020908152604080832054909316825260039081905291902054600160401b900460ff1690811115611b1357611b13614f17565b600061210284611ade565b1561222257604051627eeac760e11b81526001600160a01b0385811660048301526024820184905284169062fdd58e90604401602060405180830381865afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121769190615a0d565b612180908261574d565b6001600160a01b0385811660009081526003602052604090819020549051627eeac760e11b8152600160501b909104821660048201819052602482018690529293509085169062fdd58e906044015b602060405180830381865afa1580156121ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122109190615a0d565b61221a908361574d565b91505061175b565b61222b846120ad565b61175b57604051627eeac760e11b81526001600160a01b0385811660048301526024820184905284169062fdd58e906044015b602060405180830381865afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f9190615a0d565b6122a9908261574d565b949350505050565b60006122bc82611ade565b15612305576122d56001600160a01b038316318261574d565b6001600160a01b038084166000908152600360205260409020549192506119e591600160501b900416318261574d565b61230e826120ad565b612326576119e56001600160a01b038316318261574d565b919050565b6001600160a01b038181166000908152600460209081526040808320549093168252600390819052918120549091600160401b90910460ff169081600381111561237757612377614f17565b148061175b5750600281600381111561239257612392614f17565b149392505050565b6123a2613b6f565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b6123cc613b6f565b6016805460ff19166001179055565b6123e3613b6f565b6005805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b612410613b6f565b61241a6000613cec565b565b6001600160401b0385166000908152601b60205260409020546001600160a01b0316331461245d5760405163471e5c3d60e11b815260040160405180910390fd5b62ffffff84161561249b576001600160401b0385166000908152601b60205260409020805462ffffff60a01b1916600160a01b62ffffff8716021790555b63ffffffff8316156124dc576001600160401b0385166000908152601b60205260409020805463ffffffff60b81b1916600160b81b63ffffffff8616021790555b6001600160601b03821615612525576001600160401b0385166000908152601b6020526040902060010180546001600160a01b0316600160a01b6001600160601b038516021790555b801561254a576001600160401b0385166000908152601b602052604090206003018190555b604080516001600160401b0380891682528716602082015262ffffff86169181019190915263ffffffff841660608201526001600160601b038316608082015260a081018290527f283ca86eb787b2e4eed53d42c177266ef3af5e5879ca7e291363d2eed932ee0e9060c0015b60405180910390a1505050505050565b6001600160a01b03818116600090815260046020908152604080832054909316825260039081905291812054909182918291829182918291600160401b900460ff169081600381111561261c5761261c614f17565b14806126395750600281600381111561263757612637614f17565b145b806126555750600181600381111561265357612653614f17565b145b1561267557612663886119eb565b96509650965096509650965050611ad5565b506001600160a01b038716600090815260036020819052604090912054600160401b900460ff16908160038111156126af576126af614f17565b14806126cc575060028160038111156126ca576126ca614f17565b145b806126e8575060018160038111156126e6576126e6614f17565b145b156126f65761266388613174565b50600097889750879650869550859450849350915050565b6001543414612730576040516333b18e6b60e11b815260040160405180910390fd5b611d003384843485613d3c565b600080600061274b846120ad565b156127695760405163125f0c1360e21b815260040160405180910390fd5b61277284611ade565b156127ad575050506001600160a01b0380821660009081526003602052604090208054600191820154600160501b90910483169216906127b7565b5082915081905060005b9193909250565b60006127c933612d19565b604080516001600160401b03808a1682528316602082015233918101919091526001600160a01b03871660608201526080810186905260a0810185905260c081018490529091507f64b5ca6749db1c615652096d273882ff7a1008ac9664f51568b14410b7a4f1a69060e0016125b7565b612842613b6f565b600155565b6000806128548585613f09565b600081815260176020908152604091829020825160a08101845281546001600160401b038082168084526001600160a01b03600160401b93849004811696850196909652600185015491821696840196909652049092166060830152600201546080820152919250156128f0576128cf848260800151613c0f565b6000036128e35760200151915061175b9050565b60600151915061175b9050565b50600095945050505050565b612904613b6f565b601e91909155601f55565b612917613b6f565b61136061292c6000546001600160a01b031690565b6001600160a01b0384169083613f32565b601a602052816000526040600020816010811061295957600080fd5b018054909250611b889150615874565b612971613919565b600061297c33612d19565b9050600080600061298f8b8b8b8b613f84565b9250925092506129a183888a89613fdf565b6129af338a8d8d868b613c7f565b6129bd33898d8d858b613a8c565b836001600160401b03168c6001600160401b03167f874a0ec379dec4a6469317f6b2eb8bcb7381c2e0074e09ba06e85ef2dcb2ce4b338e8e8e8e8e8e348f604051612a1099989796959493929190615a26565b60405180910390a3505050505050505050505050565b6000612a3333848461402d565b50600192915050565b612a44613b6f565b6001600160a01b03166000908152601c6020526040902080546cffffffffffffffffffffffffff19169055565b612a79613919565b6000612a8433612d19565b9050600080612a948686896138f6565b600082815260176020526040812060010154929450909250600160401b9091046001600160a01b031690612ac88883613bc9565b6000858152601760205260409020600181018054600160401b600160e01b031916600160401b6001600160a01b038e160217905560020154909150612b1133848b8b8686613c7f565b612b1f338b8b8b8886613a8c565b896001600160a01b0316866001600160401b03168c6001600160401b03167f140155fa1de4908485153ff90dc3ed5358f6cf7d8c89166509c6a6ae2a850ca28a60405161187391815260200190565b6001600160401b0381166000908152601b60205260409020546001600160a01b03163314612baf5760405163471e5c3d60e11b815260040160405180910390fd5b6001600160401b038181166000818152601b6020908152604080832080546001600160e01b031916815560018101849055600281018490556003810193909355600490920180546001600160a01b0319169055815193861684528301919091527fce37e681b0772d563a915fa6cbf7fde2d8a8889e12015eb50beb269910bcd011910160405180910390a15050565b612c46613919565b6000612c5133612d19565b9050600080612c6485338e8e88886140ee565b91509150612c713361387d565b612d0a6040518061010001604052808f6001600160401b031681526020018c6001600160a01b031681526020018b62ffffff1681526020018a6001600160601b0316815260200189600080516020615d62833981519152612cd29190615861565b8152602001898152602001604051806020016040528060008152508152602001886001600160401b0316815250858e85858a33613945565b50505050505050505050505050565b6001600160a01b0381166000908152601960205260408120546001600160401b03169081900361232657604051630ce1b58d60e21b815260040160405180910390fd5b6000612d6733612d19565b9050600080612d7a87338e8e8a886140ee565b91509150612d873361387d565b612d9082614182565b612dac338d898985600080516020615d62833981519152613a8c565b336001600160a01b0316600560009054906101000a90046001600160401b03166001600160401b03168e6001600160401b03167f5a0f2eb6ae0aa35d6df4a692dcea08836a52a923522d010ac5241fce52a2180e8f8e8e8e8e8e8e8e604051612e1c989796959493929190615760565b60405180910390a450505050505050505050505050565b6000612e3e33612d19565b604080516001600160401b038087168252831660208201526001600160601b038516918101919091529091507f8aadc94565cd0449ff6a891861dce3989ecfbd4c25311ed3926eac0d5d53aba4906060015b60405180910390a1505050565b6000612ea833612d19565b604080516001600160401b038b81168252831660208201526001600160a01b038a811682840152891660608201526080810188905260a0810187905260c0810186905260e0810185905290519192507f09f2adc90b22f76ff47f53431a42a7a5e0bcc5867d0ebaedce6ce5d5d7f5d74791908190036101000190a15050505050505050565b612f35613b6f565b600255565b6000612f4533612d19565b90506000612f578633868689876140ee565b50600090815260176020908152604080832080546001600160e01b03199081168255600182018054909116905560020183905533835260199091529020805467ffffffffffffffff19169055505050505050565b612fb3613919565b6000612fbe33612d19565b9050600080612fce85858d6138f6565b91509150612fee338c878785600080516020615d62833981519152613c7f565b612ff783614190565b6130003361387d565b6130996040518061010001604052808e6001600160401b031681526020018c6001600160a01b031681526020018b62ffffff1681526020018a6001600160601b0316815260200189600080516020615d628339815191526130619190615861565b8152602001898152602001604051806020016040528060008152508152602001886001600160401b0316815250858d85858a33613945565b505050505050505050505050565b60006130b233612d19565b604080516001600160401b0380871682528316602082015233918101919091526001600160601b03841660608201529091507fdf35dff92be2e5e7dae645fb3e7a3d43e9487ecbbfd323bfef15c43ad2de58a590608001612e90565b61311882336141c7565b6001600160a01b038216600090815260036020526040902054600160481b900460ff1615801561314a57506001543414155b1561316857604051632740b97160e11b815260040160405180910390fd5b61136082333484614276565b6001600160a01b0381166000908152600360208181526040808420815160a0810190925280546001600160401b03811683528594859485948594859485949293919291840191600160401b90910460ff16908111156131d5576131d5614f17565b60038111156131e6576131e6614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b039081166040808501919091526001909401541660609283015283015190830151608084015184519490930151919c909a5091985091965090945092505050565b613257613b6f565b601d546040516000916001600160a01b03169083908381818185875af1925050503d80600081146132a4576040519150601f19603f3d011682016040523d82523d6000602084013e6132a9565b606091505b50509050806113605760405163e53e5bcd60e01b815260040160405180910390fd5b6132d3613b6f565b6001600160a01b03811661333d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61127281613cec565b61334e613b6f565b6001600160a01b0383166000908152601a6020526040902081908360108110613379576133796158cb565b01906133859082615927565b50505050565b613393613b6f565b816001600160a01b03166323b872dd306133b56000546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101849052606401600060405180830381600087803b15801561340457600080fd5b505af1158015613418573d6000803e3d6000fd5b505050505050565b6001600160a01b0383166000908152601960205260408120546001600160401b03161561344f5750600061175b565b81158061345c5750600f82115b1561346657600191505b61347183858461172d565b905061347c84611ade565b15613543576040516370a0823160e01b81526001600160a01b0385811660048301528416906370a0823190602401602060405180830381865afa1580156134c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134eb9190615a0d565b6134f5908261574d565b6001600160a01b03858116600090815260036020526040908190205490516370a0823160e01b8152600160501b909104821660048201819052929350908516906370a08231906024016121cf565b61354c846120ad565b61175b576040516370a0823160e01b81526001600160a01b0385811660048301528416906370a082319060240161225e565b6001600160a01b0382166135a55760405163bd78145160e01b815260040160405180910390fd5b826001600160a01b0316826001600160a01b0316036135d7576040516304da706760e51b815260040160405180910390fd5b6001600160a01b038116611d0057604051634ca5048960e01b815260040160405180910390fd5b6001600160a01b03848116600081815260036020908152604091829020805469ffff000000000000000019166901030000000000000000179055905185841681526001600160401b03851693871692917f5717bcaec46242edc8fb07322221c02d6dd3de7a954d5c009ee550cd0cdf768591015b60405180910390a450505050565b6001600160a01b03808516600081815260036020908152604080832080546001600160f01b031916815560010180546001600160a01b03199081169091559488168084526004909252918290208054909416909355519091907fbd302a9bf683315c275f4a7f0092796d97d17fbb2a89bbc8938bd6842c38eb89906137089086908690615a98565b60405180910390a350505050565b604080516101008101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c082015260e0810191909152600080600080600080600080898060200190518101906137769190615ac1565b60408051610100810182526001600160401b03998a1681526001600160a01b03909816602089015262ffffff909616958701959095526001600160601b039093166060860152608085019190915260a084015260c08301529190911660e08201529a9950505050505050505050565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b0381166123265760405162461bcd60e51b8152602060048201526016602482015275115490cc4c4d8dce8818dc99585d194819985a5b195960521b6044820152606401613334565b600580546001919060009061389c9084906001600160401b03166159e6565b82546001600160401b039182166101009390930a9283029282021916919091179091556005546001600160a01b039093166000908152601960205260409020805467ffffffffffffffff1916939091169290921790915550565b6000806139038585613f09565b915061390f8584613bc9565b9050935093915050565b601654610100900460ff161561241a576040516001621dce6960e31b0319815260040160405180910390fd5b6139518787878561439b565b61398785886040015162ffffff166201518061396d9190615bac565b61397790426159e6565b89602001518a60a00151886139e9565b6139b281868489878c60a00151600080516020615d628339815191526139ad9190615861565b613a8c565b60208701516139d390829084896139c98284613bc9565b8c60a00151613a8c565b6139e0878284898961482e565b50505050505050565b6040805160a0810182526005546001600160401b0390811682526001600160a01b039788166020808401918252978216838501908152968916606084019081526080840196875260009586526017909852929093209051815492519084166001600160e01b031993841617600160401b91891682021782559451600182018054975191909416969092169590951795169092029390931790559051600290910155565b60008281526018602052604081208054839290613aaa90849061574d565b909155505060408051848152602081018390526001600160a01b038087169288821692918a16917fa1c0f6bb9ba071b3dfd066f852f622c51d4073a7cc058fd04296ae916b8b0bc691015b60405180910390a4505050505050565b6001600160a01b038216613b2c576040516334b1be0d60e21b815260040160405180910390fd5b613b35836113bd565b15613b4557611d008383836148c7565b613b4e8361232b565b1561139a5760405160016208d37d60e21b0319815260040160405180910390fd5b6000546001600160a01b0316331461241a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401613334565b6040516001600160601b0319606084811b8216602084015283901b1660348201526000906048015b60405160208183030381529060405280519060200120905092915050565b600080613c1d60058561584a565b613c2890600a615cbb565b9050600084600103613c3c57506001613c61565b6005613c49600187615861565b613c53919061584a565b613c5e90600a615cbb565b90505b80613c6c8386615cdd565b613c769190615cf1565b95945050505050565b60008281526018602052604081208054839290613c9d908490615861565b909155505060408051848152602081018390526001600160a01b038087169289821692918916917fa1c0f6bb9ba071b3dfd066f852f622c51d4073a7cc058fd04296ae916b8b0bc69101613af5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b613d4785858561357e565b613d528560016118c1565b1580613d665750613d648460006118c1565b155b15613d84576040516307facddb60e11b815260040160405180910390fd5b6040805160a0810182526001600160401b0383811682526001602080840182815291548714848601526001600160a01b03898116606086015288811660808601528a1660009081526003918290529490942083518154931667ffffffffffffffff1984168117825591519394909392849268ffffffffffffffffff199091161790600160401b908490811115613e1c57613e1c614f17565b0217905550604082810151825460608501517fffff000000000000000000000000000000000000000000ffffffffffffffffff909116600160481b921515929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff1691909117600160501b6001600160a01b0392831602178355608090930151600190920180546001600160a01b03191692841692909217909155805185831681526001600160401b0384166020820152868316928816917f752c94da010e5b94c0278334398a684d4a7bde91f0f38c9dbb1766ad4f586c6991015b60405180910390a35050505050565b6040516001600160601b0319606084901b16602082015260348101829052600090605401613bf1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d009084906149db565b6000806000613f948787876138f6565b6040516001600160601b031960608b811b8216602084015288901b16603482015291945092506048016040516020818303038152906040528051906020012090509450945094915050565b6000938452601760205260409093206001810180546001600160a01b03909316600160401b026001600160e01b03199093166001600160401b03909416939093179190911790915560020155565b600061403a600a83615cdd565b90508015806140495750600481115b1561406757604051631ec9ca4160e21b815260040160405180910390fd5b6000614074600a84615cf1565b9050600182036140915761408c858587600085613d3c565b6140e7565b600282036140b0576140a384866141c7565b61408c8486600084614276565b600382036140cc5761408c8585836001600160401b0316613b05565b600482036140e7576140e785826001600160401b0316611322565b5050505050565b60008060008060006141028b888b8b613f84565b9250925092506141458a8a8d8a86601760008a815260200190815260200160002060020154600080516020615d628339815191526141409190615861565b613c7f565b6141698a898d8a85601760008a815260200190815260200160002060020154613c7f565b61417286614190565b5090999098509650505050505050565b611272816000806000613fdf565b6040516001600160401b038216907ff4a42f4ac762c05af0cbe21a8c16a2a87cd93719bbcfae68dce6a1b7f353a16c90600090a250565b6001600160a01b03828116600090815260036020526040902054600160501b90048116908216141580614230575060016001600160a01b038316600090815260036020819052604090912054600160401b900460ff169081111561422d5761422d614f17565b14155b1561424e57604051634cd87fb560e01b815260040160405180910390fd5b6142598160006118c1565b611360576040516307facddb60e11b815260040160405180910390fd5b6001600160a01b03838116600081815260046020908152604080832080546001600160a01b0319168a87169081179091558084526003835292819020600101549051941684526001600160401b038516937fda23dc0f47967fd81e9b62f5207a955b77295fef190364f10a6c3cf26773c1ab910160405180910390a46001600160a01b038416600090815260036020526040902054600160481b900460ff1680614321575060015482145b15614364576001600160a01b0380851660009081526003602052604090206001810154905461435f92879287929116906001600160401b03166135fe565b613385565b5050506001600160a01b03166000908152600360205260409020805468ff0000000000000000191668020000000000000000179055565b60e0848101516001600160401b03166000908152601b602090815260409182902082516101208101845281546001600160a01b038082168352600160a01b80830462ffffff1695840195909552600160b81b820463ffffffff1695830195909552600160d81b900460ff16151560608201526001820154808516608083018190529390046001600160601b031660a0820152600282015460c0820152600382015494810194909452600401548216610100840152908316141580614470575080606001511580156144705750838160c0015114155b80614495575080600001516001600160a01b031685602001516001600160a01b031614155b806144b25750806020015162ffffff16856040015162ffffff1614155b806144d757508060a001516001600160601b031685606001516001600160601b031614155b806144ea57508060e001518560a0015114155b806144fe5750806040015163ffffffff1642115b1561451c57604051631771cc0160e11b815260040160405180910390fd5b61010081015160009081906001600160a01b03166145705750506005547f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290600160801b90046001600160601b03166145db565b6101008301516001600160a01b0381166000908152601c602052604090205490925060ff166145b257604051630eca12dd60e31b815260040160405180910390fd5b506001600160a01b0381166000908152601c602052604090205461010090046001600160601b03165b60e08701516001600160401b03166000908152601b6020526040812080546001600160e01b031916815560018101829055600281018290556003810182905560040180546001600160a01b031916905560608801516146449083906001600160601b031661574d565b905080156146cd5760208801516040516323b872dd60e01b81526001600160a01b03918216600482015230602482015260448101839052908416906323b872dd906064016020604051808303816000875af11580156146a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146cb9190615d05565b505b600088606001516001600160601b03166000036146eb575081614731565b60055460608a01518491620186a09161471191600160e01b900463ffffffff1690615d22565b6001600160601b03166147249190615cf1565b61472e919061574d565b90505b60608901516001600160601b0316156147cf576001600160a01b03841663a9059cbb8861475e8486615861565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156147a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147cd9190615d05565b505b885160e08a0151604080516001600160401b03938416815292909116602083015281018290526001600160a01b03851660608201527f848da897c5a8478af17be9c5fb6ebd38774ff21fc83fdc1a19216edb8dc1eb029060800161209a565b600560009054906101000a90046001600160401b03166001600160401b031685600001516001600160401b03167f874a0ec379dec4a6469317f6b2eb8bcb7381c2e0074e09ba06e85ef2dcb2ce4b868686868b602001518c6040015162ffffff166201518061489d9190615bac565b6148a790426159e6565b60a08e015160c08f0151604051613efa9897969594939291600091615a26565b6001600160a01b0383166000908152600360208181526040808420815160a0810190925280546001600160401b038116835291939092840191600160401b900460ff169081111561491a5761491a614f17565b600381111561492b5761492b614f17565b81528154600160481b810460ff161515602080840191909152600160501b9091046001600160a01b03908116604080850191909152600194850154821660609485015289821660008181526003855282902090950180546001600160a01b0319168a84169081179091559386015160808701518251908416815293840189905295965092941692917fa0aa3b38771c7ab4ece55c6009c41d814f4ff862285d0825c24528a87fd124d79101613672565b6000614a30826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614aad9092919063ffffffff16565b805190915015611d005780806020019051810190614a4e9190615d05565b611d005760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401613334565b60606122a98484600085856001600160a01b0385163b614b0f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401613334565b600080866001600160a01b03168587604051614b2b9190615d45565b60006040518083038185875af1925050503d8060008114614b68576040519150601f19603f3d011682016040523d82523d6000602084013e614b6d565b606091505b5091509150614b7d828286614b88565b979650505050505050565b60608315614b9757508161175b565b825115614ba75782518084602001fd5b8160405162461bcd60e51b81526004016133349190614c2a565b600060208284031215614bd357600080fd5b5035919050565b60005b83811015614bf5578181015183820152602001614bdd565b50506000910152565b60008151808452614c16816020860160208601614bda565b601f01601f19169290920160200192915050565b60208152600061175b6020830184614bfe565b6001600160a01b038116811461127257600080fd5b803561232681614c3d565b600060208284031215614c6f57600080fd5b813561175b81614c3d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614cb857614cb8614c7a565b604052919050565b60006001600160401b03821115614cd957614cd9614c7a565b50601f01601f191660200190565b6000614cfa614cf584614cc0565b614c90565b9050828152838383011115614d0e57600080fd5b828260208301376000602084830101529392505050565b60008060008060808587031215614d3b57600080fd5b8435614d4681614c3d565b93506020850135614d5681614c3d565b92506040850135915060608501356001600160401b03811115614d7857600080fd5b8501601f81018713614d8957600080fd5b614d9887823560208401614ce7565b91505092959194509250565b60008060408385031215614db757600080fd5b8235614dc281614c3d565b946020939093013593505050565b801515811461127257600080fd5b600060208284031215614df057600080fd5b813561175b81614dd0565b600080600060608486031215614e1057600080fd5b8335614e1b81614c3d565b92506020840135614e2b81614c3d565b929592945050506040919091013590565b6001600160401b038116811461127257600080fd5b600080600080600060a08688031215614e6957600080fd5b8535614e7481614e3c565b94506020860135614e8481614c3d565b93506040860135614e9481614c3d565b94979396509394606081013594506080013592915050565b6001600160601b038116811461127257600080fd5b600060208284031215614ed357600080fd5b813561175b81614eac565b60008060408385031215614ef157600080fd5b8235614efc81614c3d565b91506020830135614f0c81614dd0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60c0810160048810614f4157614f41614f17565b9681526001600160a01b03958616602082015293851660408501529190931660608301526001600160401b03909216608082015290151560a09091015290565b60008060408385031215614f9457600080fd5b8235614f9f81614c3d565b91506020830135614f0c81614eac565b600080600060608486031215614fc457600080fd5b8335614fcf81614c3d565b95602085013595506040909401359392505050565b600082601f830112614ff557600080fd5b61175b83833560208501614ce7565b6000806040838503121561501757600080fd5b8235915060208301356001600160401b0381111561503457600080fd5b61504085828601614fe4565b9150509250929050565b62ffffff8116811461127257600080fd5b80356123268161504a565b803563ffffffff8116811461232657600080fd5b60008060008060008060008060006101208a8c03121561509957600080fd5b89356150a481614e3c565b985060208a01356150b48161504a565b97506150c260408b01615066565b965060608a01356150d281614dd0565b955060808a01356150e281614c3d565b945060a08a01356150f281614eac565b935060c08a013561510281614c3d565b8093505060e08a013591506101008a013590509295985092959850929598565b60006020828403121561513457600080fd5b61175b82615066565b60008060008060008060c0878903121561515657600080fd5b863561516181614e3c565b9550602087013561517181614e3c565b945060408701356151818161504a565b935061518f60608801615066565b9250608087013561519f81614eac565b8092505060a087013590509295509295509295565b6000806000606084860312156151c957600080fd5b83356151d481614c3d565b925060208401356151e481614c3d565b915060408401356151f481614e3c565b809150509250925092565b600080600080600060a0868803121561521757600080fd5b853561522281614e3c565b9450602086013561523281614c3d565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561526357600080fd5b50508035926020909101359150565b600080600080600080600080610100898b03121561528f57600080fd5b883561529a81614e3c565b975060208901356152aa81614c3d565b96506040890135955060608901356152c181614c3d565b945060808901356152d181614c3d565b935060a08901356152e181614e3c565b925060c0890135915060e08901356001600160401b0381111561530357600080fd5b61530f8b828c01614fe4565b9150509295985092959890939650565b60006020828403121561533157600080fd5b813561175b81614e3c565b6000806040838503121561534f57600080fd5b823561535a81614e3c565b91506020830135614f0c81614e3c565b6000806000806000806000806000806101408b8d03121561538a57600080fd5b8a3561539581614e3c565b995060208b01356153a581614c3d565b985060408b01356153b581614c3d565b975060608b01356153c581614c3d565b965060808b01356153d58161504a565b955060a08b01356153e581614eac565b945060c08b0135935060e08b01356153fc81614e3c565b92506101008b013561540d81614c3d565b809250506101208b013590509295989b9194979a5092959850565b6000806000806000806000806000806101408b8d03121561544857600080fd5b8a3561545381614e3c565b995060208b013561546381614c3d565b985060408b013561547381614c3d565b975060608b013561548381614c3d565b965060808b013561549381614eac565b95506154a160a08c0161505b565b94506154af60c08c01614c52565b935060e08b013592506101008b013591506101208b01356001600160401b038111156154da57600080fd5b6154e68d828e01614fe4565b9150509295989b9194979a5092959850565b6000806040838503121561550b57600080fd5b8235614f9f81614e3c565b600080600080600080600060e0888a03121561553157600080fd5b873561553c81614e3c565b9650602088013561554c81614c3d565b9550604088013561555c81614c3d565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b6000806000806080858703121561559a57600080fd5b84356155a581614c3d565b93506020850135925060408501356155bc81614c3d565b915060608501356155cc81614c3d565b939692955090935050565b60008060008060008060008060006101208a8c0312156155f657600080fd5b893561560181614e3c565b985060208a013561561181614c3d565b975060408a013561562181614c3d565b965060608a01356156318161504a565b955060808a013561564181614eac565b945060a08a0135935060c08a013561565881614e3c565b925060e08a013561566881614c3d565b809250506101008a013590509295985092959850929598565b6000806040838503121561569457600080fd5b823561535a81614c3d565b6000806000606084860312156156b457600080fd5b83356156bf81614c3d565b92506020840135915060408401356001600160401b038111156156e157600080fd5b6156ed86828701614fe4565b9150509250925092565b60008060006060848603121561570c57600080fd5b833561571781614c3d565b9250602084013561572781614c3d565b915060408401356151f481614c3d565b634e487b7160e01b600052601160045260246000fd5b808201808211156119e5576119e5615737565b6001600160a01b03898116825288811660208301526001600160601b038816604083015262ffffff871660608301528516608082015260a0810184905260c0810183905261010060e082018190526000906157bd83820185614bfe565b9b9a5050505050505050505050565b6001600160a01b038a8116825289811660208301526001600160601b038916604083015262ffffff881660608301528616608082015260a0810185905260c0810184905261012060e0820181905260009061582983820186614bfe565b9150506001600160401b0383166101008301529a9950505050505050505050565b80820281158282048414176119e5576119e5615737565b818103818111156119e5576119e5615737565b600181811c9082168061588857607f821691505b6020821081036158a857634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156158c057600080fd5b815161175b81614c3d565b634e487b7160e01b600052603260045260246000fd5b601f821115611d0057600081815260208120601f850160051c810160208610156159085750805b601f850160051c820191505b8181101561341857828155600101615914565b81516001600160401b0381111561594057615940614c7a565b6159548161594e8454615874565b846158e1565b602080601f83116001811461598957600084156159715750858301515b600019600386901b1c1916600185901b178555613418565b600085815260208120601f198616915b828110156159b857888601518255948401946001909101908401615999565b50858210156159d65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160401b03818116838216019080821115615a0657615a06615737565b5092915050565b600060208284031215615a1f57600080fd5b5051919050565b6001600160a01b038a811682528981166020830152604082018990528781166060830152861660808201526001600160401b03851660a082015260c0810184905260e081018390526101206101008201819052600090615a8883820185614bfe565b9c9b505050505050505050505050565b6040810160028410615aac57615aac614f17565b9281526020015290565b805161232681614e3c565b600080600080600080600080610100898b031215615ade57600080fd5b8851615ae981614e3c565b60208a0151909850615afa81614c3d565b60408a0151909750615b0b8161504a565b60608a0151909650615b1c81614eac565b809550506080890151935060a0890151925060c08901516001600160401b03811115615b4757600080fd5b8901601f81018b13615b5857600080fd5b8051615b66614cf582614cc0565b8181528c6020838501011115615b7b57600080fd5b615b8c826020830160208601614bda565b9350615b9d91505060e08a01615ab6565b90509295985092959890939650565b6001600160401b03818116838216028082169190828114615bcf57615bcf615737565b505092915050565b600181815b80851115615c12578160001904821115615bf857615bf8615737565b80851615615c0557918102915b93841c9390800290615bdc565b509250929050565b600082615c29575060016119e5565b81615c36575060006119e5565b8160018114615c4c5760028114615c5657615c72565b60019150506119e5565b60ff841115615c6757615c67615737565b50506001821b6119e5565b5060208310610133831016604e8410600b8410161715615c95575081810a6119e5565b615c9f8383615bd7565b8060001904821115615cb357615cb3615737565b029392505050565b600061175b8383615c1a565b634e487b7160e01b600052601260045260246000fd5b600082615cec57615cec615cc7565b500690565b600082615d0057615d00615cc7565b500490565b600060208284031215615d1757600080fd5b815161175b81614dd0565b6001600160601b03818116838216028082169190828114615bcf57615bcf615737565b60008251615d57818460208701614bda565b919091019291505056fe00000172eca084a2dfd7bef9ff78b9eed31c81789db8f74134d76bc8e5e3eaa1a2646970667358221220f1fb24f530623c085a1848e4eb0747caac6bcda1a16bcf475a7e65a4c50792d864736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028b224a23a6c66e4b496fef0e544ccf7bf1f9b96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000002540be400
-----Decoded View---------------
Arg [0] : proxyRegisterFee_ (uint256): 0
Arg [1] : treasury_ (address): 0x28b224a23A6C66E4B496feF0E544CCf7Bf1F9b96
Arg [2] : delegationRegisterFee_ (uint96): 0
Arg [3] : delegationFeePercentage_ (uint32): 500
Arg [4] : weth_ (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [5] : deletionNominalEth_ (uint256): 10000000000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000028b224a23a6c66e4b496fef0e544ccf7bf1f9b96
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [4] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [5] : 00000000000000000000000000000000000000000000000000000002540be400
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,803.35 | 0.000005 | $0.019017 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.