Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 5 from a total of 5 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MoneyStampsERC721
Compiler Version
v0.5.14+commit.1f1aaa4
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2020-02-04
*/
// MoneyStampsERC721.sol -- Interest-bearing NFTs with lexStamps based on the DAI Savings Token
// - Adapted from ChargedParticlesERC721.sol - https://github.com/robsecord/ChargedParticlesEth
//
// MIT License
// Copyright (c) 2020 Open, ESQ LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
pragma solidity ^0.5.13;
// ERROR CODES:
// 100: ADDRESS, OWNER, OPERATOR
// 101 Invalid Address
// 102 Sender is not owner
// 103 Sender is not operator
// 200: MATH
// 201 Underflow
// 202 Overflow
// 203 Multiplication overflow
// 204 Division by zero
// 300: ERC721
// 301 Invalid Recipient
// 302 Invalid on-received message
// 303 Invalid tokenId
// 304 Invalid owner/operator
// 305 Token ID already exists
// 400: ChargedParticles
// 401 Invalid Method
// 402 Unregistered Type
// 403 Particle has no Charge
// 404 Insufficient DAI Balance
// 405 Transfer Failed
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @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 `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool);
/**
* @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);
}
/**
* @title Chai.money interface
* @dev see https://github.com/dapphub/chai
*/
contract IChai {
function transfer(address dst, uint wad) external returns (bool);
// like transferFrom but dai-denominated
function move(address src, address dst, uint wad) external returns (bool);
function transferFrom(address src, address dst, uint wad) public returns (bool);
function approve(address usr, uint wad) external returns (bool);
function balanceOf(address usr) external returns (uint);
// Approve by signature
function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;
function dai(address usr) external returns (uint wad);
function dai(uint chai) external returns (uint wad);
// wad is denominated in dai
function join(address dst, uint wad) external;
// wad is denominated in (1/chi) * dai
function exit(address src, uint wad) public;
// wad is denominated in dai
function draw(address src, uint wad) external returns (uint chai);
}
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
/**
* @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
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* _Available since v2.4.0._
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
/**
* @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].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
* overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
* directly accessed.
*/
library Counters {
using SafeMath for uint256;
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
// The {SafeMath} overflow check can be skipped here, see the comment at the top
counter._value += 1;
}
function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1);
}
}
/*
* @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 GSN 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.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
/**
* @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);
}
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
/**
* @dev Required interface of an ERC721 compliant contract.
*/
contract IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of NFTs in `owner`'s account.
*/
function balanceOf(address owner) public view returns (uint256 balance);
/**
* @dev Returns the owner of the NFT specified by `tokenId`.
*/
function ownerOf(uint256 tokenId) public view returns (address owner);
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
*
*
* Requirements:
* - `from`, `to` cannot be zero.
* - `tokenId` must be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this
* NFT by either {approve} or {setApprovalForAll}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public;
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
* Requirements:
* - If the caller is not `from`, it must be approved to move this NFT by
* either {approve} or {setApprovalForAll}.
*/
function transferFrom(address from, address to, uint256 tokenId) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address operator);
function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
contract IERC721Receiver {
/**
* @notice Handle the receipt of an NFT
* @dev The ERC721 smart contract calls this function on the recipient
* after a {IERC721-safeTransferFrom}. This function MUST return the function selector,
* otherwise the caller will revert the transaction. The selector to be
* returned can be obtained as `this.onERC721Received.selector`. This
* function MAY throw to revert and reject the transfer.
* Note: the ERC721 contract address is always the message sender.
* @param operator The address which called `safeTransferFrom` function
* @param from The address which previously owned the token
* @param tokenId The NFT identifier which is being transferred
* @param data Additional data with no specified format
* @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
*/
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4);
}
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721 is Context, ERC165, IERC721 {
using SafeMath for uint256;
using Address for address;
using Counters for Counters.Counter;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from token ID to owner
mapping (uint256 => address) private _tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => Counters.Counter) private _ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
constructor () public {
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
}
/**
* @dev Gets the balance of the specified address.
* @param owner address to query the balance of
* @return uint256 representing the amount owned by the passed address
*/
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _ownedTokensCount[owner].current();
}
/**
* @dev Gets the owner of the specified token ID.
* @param tokenId uint256 ID of the token to query the owner of
* @return address currently marked as the owner of the given token ID
*/
function ownerOf(uint256 tokenId) public view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev Approves another address to transfer the given token ID
* The zero address indicates there is no approved address.
* There can only be one approved address per token at a given time.
* Can only be called by the token owner or an approved operator.
* @param to address to be approved for the given token ID
* @param tokenId uint256 ID of the token to be approved
*/
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Gets the approved address for a token ID, or zero if no address set
* Reverts if the token ID does not exist.
* @param tokenId uint256 ID of the token to query the approval of
* @return address currently approved for the given token ID
*/
function getApproved(uint256 tokenId) public view returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev Sets or unsets the approval of a given operator
* An operator is allowed to transfer all tokens of the sender on their behalf.
* @param to operator address to set the approval
* @param approved representing the status of the approval to be set
*/
function setApprovalForAll(address to, bool approved) public {
require(to != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][to] = approved;
emit ApprovalForAll(_msgSender(), to, approved);
}
/**
* @dev Tells whether an operator is approved by a given owner.
* @param owner owner address which you want to query the approval of
* @param operator operator address which you want to query the approval of
* @return bool whether the given operator is approved by the given owner
*/
function isApprovedForAll(address owner, address operator) public view returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev Transfers the ownership of a given token ID to another address.
* Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
* Requires the msg.sender to be the owner, approved, or operator.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function transferFrom(address from, address to, uint256 tokenId) public {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transferFrom(from, to, tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg.sender to be the owner, approved, or operator
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the _msgSender() to be the owner, approved, or operator
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes data to send along with a safe transfer check
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransferFrom(from, to, tokenId, _data);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg.sender to be the owner, approved, or operator
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes data to send along with a safe transfer check
*/
function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
_transferFrom(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether the specified token exists.
* @param tokenId uint256 ID of the token to query the existence of
* @return bool whether the token exists
*/
function _exists(uint256 tokenId) internal view returns (bool) {
address owner = _tokenOwner[tokenId];
return owner != address(0);
}
/**
* @dev Returns whether the given spender can transfer a given token ID.
* @param spender address of the spender to query
* @param tokenId uint256 ID of the token to be transferred
* @return bool whether the msg.sender is approved for the given token ID,
* is an operator of the owner, or is the owner of the token
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Internal function to safely mint a new token.
* Reverts if the given token ID already exists.
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @param to The address that will own the minted token
* @param tokenId uint256 ID of the token to be minted
*/
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
/**
* @dev Internal function to safely mint a new token.
* Reverts if the given token ID already exists.
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @param to The address that will own the minted token
* @param tokenId uint256 ID of the token to be minted
* @param _data bytes data to send along with a safe transfer check
*/
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Internal function to mint a new token.
* Reverts if the given token ID already exists.
* @param to The address that will own the minted token
* @param tokenId uint256 ID of the token to be minted
*/
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* Deprecated, use {_burn} instead.
* @param owner owner of the token to burn
* @param tokenId uint256 ID of the token being burned
*/
function _burn(address owner, uint256 tokenId) internal {
require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] = address(0);
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* @param tokenId uint256 ID of the token being burned
*/
function _burn(uint256 tokenId) internal {
_burn(ownerOf(tokenId), tokenId);
}
/**
* @dev Internal function to transfer ownership of a given token ID to another address.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function _transferFrom(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* This is an internal detail of the `ERC721` contract and its use is deprecated.
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
internal returns (bool)
{
if (!to.isContract()) {
return true;
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = to.call(abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
));
if (!success) {
if (returndata.length > 0) {
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert("ERC721: transfer to non ERC721Receiver implementer");
}
} else {
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
}
/**
* @dev Private function to clear current approval of a given token ID.
* @param tokenId uint256 ID of the token to be transferred
*/
function _clearApproval(uint256 tokenId) private {
if (_tokenApprovals[tokenId] != address(0)) {
_tokenApprovals[tokenId] = address(0);
}
}
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721Enumerable is IERC721 {
function totalSupply() public view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);
function tokenByIndex(uint256 index) public view returns (uint256);
}
/**
* @title ERC-721 Non-Fungible Token with optional enumeration extension logic
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => uint256[]) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
/**
* @dev Constructor function.
*/
constructor () public {
// register the supported interface to conform to ERC721Enumerable via ERC165
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner.
* @param owner address owning the tokens list to be accessed
* @param index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev Gets the total amount of tokens stored by the contract.
* @return uint256 representing the total amount of tokens
*/
function totalSupply() public view returns (uint256) {
return _allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens.
* @param index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/
function tokenByIndex(uint256 index) public view returns (uint256) {
require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev Internal function to transfer ownership of a given token ID to another address.
* As opposed to transferFrom, this imposes no restrictions on msg.sender.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function _transferFrom(address from, address to, uint256 tokenId) internal {
super._transferFrom(from, to, tokenId);
_removeTokenFromOwnerEnumeration(from, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
}
/**
* @dev Internal function to mint a new token.
* Reverts if the given token ID already exists.
* @param to address the beneficiary that will own the minted token
* @param tokenId uint256 ID of the token to be minted
*/
function _mint(address to, uint256 tokenId) internal {
super._mint(to, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
_addTokenToAllTokensEnumeration(tokenId);
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* Deprecated, use {ERC721-_burn} instead.
* @param owner owner of the token to burn
* @param tokenId uint256 ID of the token being burned
*/
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
_removeTokenFromOwnerEnumeration(owner, tokenId);
// Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
_ownedTokensIndex[tokenId] = 0;
_removeTokenFromAllTokensEnumeration(tokenId);
}
/**
* @dev Gets the list of token IDs of the requested owner.
* @param owner address owning the tokens
* @return uint256[] List of token IDs owned by the requested address
*/
function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
return _ownedTokens[owner];
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
_ownedTokensIndex[tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
_ownedTokens[from].length--;
// Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
// lastTokenId, or just over the end of the array if the token was the last one).
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length.sub(1);
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
_allTokens.length--;
_allTokensIndex[tokenId] = 0;
}
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
// Token name
string private _name;
// Token symbol
string private _symbol;
// Base URI
string private _baseURI;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/**
* @dev Constructor function
*/
constructor (string memory name, string memory symbol) public {
_name = name;
_symbol = symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
}
/**
* @dev Gets the token name.
* @return string representing the token name
*/
function name() external view returns (string memory) {
return _name;
}
/**
* @dev Gets the token symbol.
* @return string representing the token symbol
*/
function symbol() external view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the URI for a given token ID. May return an empty string.
*
* If the token's URI is non-empty and a base URI was set (via
* {_setBaseURI}), it will be added to the token ID's URI as a prefix.
*
* Reverts if the token ID does not exist.
*/
function tokenURI(uint256 tokenId) external view returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
// Even if there is a base URI, it is only appended to non-empty token-specific URIs
if (bytes(_tokenURI).length == 0) {
return "";
} else {
// abi.encodePacked is being used to concatenate strings
return string(abi.encodePacked(_baseURI, _tokenURI));
}
}
/**
* @dev Internal function to set the token URI for a given token.
*
* Reverts if the token ID does not exist.
*
* TIP: if all token IDs share a prefix (e.g. if your URIs look like
* `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
* it and save gas.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI}.
*
* _Available since v2.5.0._
*/
function _setBaseURI(string memory baseURI) internal {
_baseURI = baseURI;
}
/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a preffix in {tokenURI} to each token's URI, when
* they are non-empty.
*
* _Available since v2.5.0._
*/
function baseURI() external view returns (string memory) {
return _baseURI;
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* Deprecated, use _burn(uint256) instead.
* @param owner owner of the token to burn
* @param tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
/**
* @notice Money Stamps Contract - Interest-Bearing NFTs with lexical stamps
* <presented by OpenESQ || lexDAO>
*/
contract MoneyStampsERC721 is ERC721Metadata, ERC721Enumerable {
using SafeMath for uint256;
/***********************************|
| Variables and Events |
|__________________________________*/
IERC20 internal dai;
IChai internal chai;
mapping(uint256 => uint256) internal chaiBalanceByTokenId; // Amount of Chai minted from Dai deposited
uint256 internal totalMintedTokens;
uint256 internal mintFee;
uint256 internal collectedFees;
uint256 internal requiredFunding; // Amount of Dai to deposit when minting
address private owner; // To be assigned to a DAO
bytes16 public version = "v0.0.1";
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/***********************************|
| Modifiers |
|__________________________________*/
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner, "E102");
_;
}
/***********************************|
| Initialization |
|__________________________________*/
constructor() ERC721Metadata("$TAMP", "$TAMP") public {
// requiredFunding = 1e18;
// mintFee = 50; // 0.5% of Chai from deposited Dai
owner = msg.sender;
emit OwnershipTransferred(address(0), owner);
}
/***********************************|
| Public Read |
|__________________________________*/
/**
* @notice Gets the address of the contract owner.
* @return The address of the owner
*/
function getContractOwner() public view returns (address) {
return owner;
}
/***********************************|
| Stamp Glue |
|__________________________________*/
/**
* @notice Gets the Amount of Base DAI held in the Token (amount token was minted with)
* @return The Amount of DAI held in the Token
*/
function baseStampWeight() public view returns (uint256) {
return requiredFunding;
}
/**
* @notice Gets the amount of interest the Token has generated (its accumulated stamp-loot)
* @param _tokenId The ID of the Token
* @return The amount of interest the Token has generated
*/
function currentStampLoot(uint256 _tokenId) public returns (uint256) {
require(_exists(_tokenId), "E402");
uint256 currentLoot = chai.dai(chaiBalanceByTokenId[_tokenId]);
if (requiredFunding >= currentLoot) { return 0; }
return currentLoot.sub(requiredFunding);
}
/**
* @notice Allows the owner of the Token to collect the interest generated from the token
* without removing the underlying DAI that is held in the token
* @param _tokenId The ID of the Token
* @return The amount of interest released from the token
*/
function peelStamp(uint256 _tokenId) public returns (uint256) {
require(_isApprovedOrOwner(msg.sender, _tokenId), "E103");
uint256 _currentLootInDai = currentStampLoot(_tokenId);
require(_currentLootInDai > 0, "E403");
uint256 _paidChai = _payoutStampedDai(msg.sender, _currentLootInDai);
chaiBalanceByTokenId[_tokenId] = chaiBalanceByTokenId[_tokenId].sub(_paidChai);
return _currentLootInDai;
}
/***********************************|
| Public Mint |
|__________________________________*/
/**
* @notice Mints multiple new Stamps
* @param _to The owner address to assign the new tokens to
* @param _amount The amount of tokens to mint
* @param _stamp Custom lexical stamp used to establish authenticity
* @return The IDs of the newly minted tokens
*/
function mintStamps(address _to, uint256 _amount, string memory _stamp) public returns (uint256[] memory) {
address _self = address(this);
uint256 i;
uint256 _tokenId;
uint256 _totalDai;
uint256[] memory _tokenIds = new uint256[](_amount);
for (i = 0; i < _amount; ++i) {
_totalDai = requiredFunding.add(_totalDai);
_tokenId = (totalMintedTokens.add(i+1));
_tokenIds[i] = _tokenId;
_mint(_to, _tokenId);
_setTokenURI(_tokenId, _stamp);
}
totalMintedTokens = totalMintedTokens.add(_amount);
if (_totalDai > 0) {
// Transfer DAI from User to Contract
_collectRequiredDai(msg.sender, _totalDai);
uint256 _balance = chai.balanceOf(_self);
for (i = 0; i < _amount; ++i) {
_tokenId = _tokenIds[i];
// Tokenize Interest
chai.join(_self, requiredFunding);
// Track Chai in each Token
chaiBalanceByTokenId[_tokenId] = _totalChaiForToken(chai.balanceOf(_self).sub(_balance));
_balance = chai.balanceOf(_self);
}
}
return _tokenIds;
}
/***********************************|
| Public Burn |
|__________________________________*/
/**
* @notice Destroys a Stamp and releases the underlying DAI + Interest (Weight + Loot)
* @param _tokenId The ID of the token to burn
*/
function burnStamp(uint256 _tokenId) public {
// Burn Token
_burn(msg.sender, _tokenId);
// Payout Dai + Interest
uint256 _tokenChai = chaiBalanceByTokenId[_tokenId];
chaiBalanceByTokenId[_tokenId] = 0;
_payoutFundedDai(msg.sender, _tokenChai);
}
/**
* @notice Destroys multiple Stamps and releases the underlying DAI + Interest (Weight + Loot)
* @param _tokenIds The IDs of the tokens to burn
*/
function burnStamps(uint256[] memory _tokenIds) public {
uint256 _tokenId;
uint256 _totalChai;
for (uint256 i = 0; i < _tokenIds.length; ++i) {
_tokenId = _tokenIds[i];
// Burn Token
_burn(msg.sender, _tokenId);
// Payout Dai + Interest
_totalChai = chaiBalanceByTokenId[_tokenId].add(_totalChai);
chaiBalanceByTokenId[_tokenId] = 0;
}
_payoutFundedDai(msg.sender, _totalChai);
}
/***********************************|
| Only Owner |
|__________________________________*/
/**
* @dev Setup the DAI/CHAI contracts and configure the $TAMP contract
*/
function setup(address _daiAddress, address _chaiAddress, uint256 _mintFee, uint256 _requiredFunding) public onlyOwner {
// Set DAI as Funding Token
dai = IERC20(_daiAddress);
chai = IChai(_chaiAddress);
// Setup Chai to Tokenize DAI Interest
dai.approve(_chaiAddress, uint(-1));
mintFee = _mintFee;
requiredFunding = _requiredFunding;
}
/**
* @dev Allows contract owner to withdraw any fees earned
*/
function withdrawFees() public onlyOwner {
uint256 _balance = address(this).balance;
if (_balance > 0) {
msg.sender.transfer(_balance);
}
if (collectedFees > 0) {
_payoutFundedDai(msg.sender, collectedFees);
collectedFees = 0;
}
}
/**
* @notice Transfers the ownership of the contract to new address
* @param _newOwner Address of the new owner
*/
function transferOwnership(address _newOwner) public onlyOwner {
require(_newOwner != address(0), "E101");
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
/***********************************|
| Private Functions |
|__________________________________*/
/**
* @dev Collects the Required DAI from the users wallet during Minting
* @param _from The owner address to collect the DAI from
* @param _requiredDai The amount of DAI to collect from the user
*/
function _collectRequiredDai(address _from, uint256 _requiredDai) internal {
// Transfer DAI from User to Contract
uint256 _userDaiBalance = dai.balanceOf(_from);
require(_requiredDai <= _userDaiBalance, "E404");
require(dai.transferFrom(_from, address(this), _requiredDai), "E405");
}
/**
* @dev Pays out a specified amount of CHAI
* @param _to The owner address to pay out to
* @param _totalChai The total amount of CHAI to pay out
*/
function _payoutFundedDai(address _to, uint256 _totalChai) internal {
address _self = address(this);
// Exit Chai and collect Dai + Interest
chai.exit(_self, _totalChai);
// Transfer Dai + Interest
uint256 _receivedDai = dai.balanceOf(_self);
require(dai.transferFrom(_self, _to, _receivedDai), "E405");
}
/**
* @dev Pays out a specified amount of DAI
* @param _to The owner address to pay out to
* @param _totalDai The total amount of DAI to pay out
*/
function _payoutStampedDai(address _to, uint256 _totalDai) internal returns (uint256) {
address _self = address(this);
// Collect Interest
uint256 _chai = chai.draw(_self, _totalDai);
// Transfer Interest
uint256 _receivedDai = dai.balanceOf(_self);
require(dai.transferFrom(_self, _to, _receivedDai), "E405");
return _chai;
}
/**
* @dev Calculates the amount of DAI held within a token during minting
* Note: Accounts for any contract fees
* @param _tokenChai The total amount of DAI used to fund the token
* @return The actual amount of DAI to fund the token - fees
*/
function _totalChaiForToken(uint256 _tokenChai) internal returns (uint256) {
if (mintFee == 0) { return _tokenChai; }
uint256 _mintFee = _tokenChai.mul(mintFee).div(1e4);
collectedFees = collectedFees.add(_mintFee);
return _tokenChai.sub(_mintFee);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseStampWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"burnStamp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"burnStamps","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"currentStampLoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getContractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_stamp","type":"string"}],"name":"mintStamps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"peelStamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_daiAddress","type":"address"},{"internalType":"address","name":"_chaiAddress","type":"address"},{"internalType":"uint256","name":"_mintFee","type":"uint256"},{"internalType":"uint256","name":"_requiredFunding","type":"uint256"}],"name":"setup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040527f76302e302e310000000000000000000000000000000000000000000000000000601560006101000a8154816fffffffffffffffffffffffffffffffff021916908360801c02179055503480156200005b57600080fd5b506040518060400160405280600581526020017f2454414d500000000000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f2454414d50000000000000000000000000000000000000000000000000000000815250620000e06301ffc9a760e01b6200022060201b60201c565b620000f86380ac58cd60e01b6200022060201b60201c565b81600590805190602001906200011092919062000329565b5080600690805190602001906200012992919062000329565b5062000142635b5e139f60e01b6200022060201b60201c565b50506200015c63780e9d6360e01b6200022060201b60201c565b33601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3620003d8565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415620002bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200036c57805160ff19168380011785556200039d565b828001600101855582156200039d579182015b828111156200039c5782518255916020019190600101906200037f565b5b509050620003ac9190620003b0565b5090565b620003d591905b80821115620003d1576000816000905550600101620003b7565b5090565b90565b614b2580620003e86000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80634f6ccce7116100f957806395d89b4111610097578063c87b56dd11610071578063c87b56dd14610b46578063e985e9c514610bed578063eeea94fc14610c69578063f2fde38b14610d21576101c4565b806395d89b411461096e578063a22cb465146109f1578063b88d4fde14610a41576101c4565b80636c0360eb116100d35780636c0360eb1461072b57806370a08231146107ae5780637bd1e8061461080657806392c2003a14610834576101c4565b80634f6ccce71461063757806354fd4d50146106795780636352211e146106bd576101c4565b806327e7cd881161016657806332fff0b61161014057806332fff0b61461055757806342842e0e14610575578063442890d5146105e3578063476343ee1461062d576101c4565b806327e7cd88146104715780632e4bfda6146104b35780632f745c59146104f5576101c4565b8063095ea7b3116101a2578063095ea7b31461031f57806316ecc6861461036d57806318160ddd146103e557806323b872dd14610403576101c4565b806301ffc9a7146101c957806306fdde031461022e578063081812fc146102b1575b600080fd5b610214600480360360208110156101df57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d65565b604051808215151515815260200191505060405180910390f35b610236610dcc565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561027657808201518184015260208101905061025b565b50505050905090810190601f1680156102a35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102dd600480360360208110156102c757600080fd5b8101908080359060200190929190505050610e6e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61036b6004803603604081101561033557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f09565b005b6103e36004803603608081101561038357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506110f0565b005b6103ed61134e565b6040518082815260200191505060405180910390f35b61046f6004803603606081101561041957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061135b565b005b61049d6004803603602081101561048757600080fd5b81019080803590602001909291905050506113d1565b6040518082815260200191505060405180910390f35b6104df600480360360208110156104c957600080fd5b8101908080359060200190929190505050611527565b6040518082815260200191505060405180910390f35b6105416004803603604081101561050b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061169c565b6040518082815260200191505060405180910390f35b61055f61175b565b6040518082815260200191505060405180910390f35b6105e16004803603606081101561058b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611765565b005b6105eb611785565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106356117af565b005b6106636004803603602081101561064d57600080fd5b81019080803590602001909291905050506118eb565b6040518082815260200191505060405180910390f35b61068161196b565b60405180826fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6106e9600480360360208110156106d357600080fd5b810190808035906020019092919050505061197e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610733611a46565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610773578082015181840152602081019050610758565b50505050905090810190601f1680156107a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107f0600480360360208110156107c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ae8565b6040518082815260200191505060405180910390f35b6108326004803603602081101561081c57600080fd5b8101908080359060200190929190505050611bbd565b005b6109176004803603606081101561084a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561089157600080fd5b8201836020820111156108a357600080fd5b803590602001918460018302840111640100000000831117156108c557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611c06565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561095a57808201518184015260208101905061093f565b505050509050019250505060405180910390f35b6109766120b7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156109b657808201518184015260208101905061099b565b50505050905090810190601f1680156109e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a3f60048036036040811015610a0757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612159565b005b610b4460048036036080811015610a5757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610abe57600080fd5b820183602082011115610ad057600080fd5b80359060200191846001830284011164010000000083111715610af257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612311565b005b610b7260048036036020811015610b5c57600080fd5b8101908080359060200190929190505050612389565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610bb2578082015181840152602081019050610b97565b50505050905090810190601f168015610bdf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610c4f60048036036040811015610c0357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061258b565b604051808215151515815260200191505060405180910390f35b610d1f60048036036020811015610c7f57600080fd5b8101908080359060200190640100000000811115610c9c57600080fd5b820183602082011115610cae57600080fd5b80359060200191846020830284011164010000000083111715610cd057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929050505061261f565b005b610d6360048036036020811015610d3757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126ad565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e645780601f10610e3957610100808354040283529160200191610e64565b820191906000526020600020905b815481529060010190602001808311610e4757829003601f168201915b5050505050905090565b6000610e79826128d3565b610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061499e602c913960400191505060405180910390fd5b6002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610f148261197e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614a4e6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610fba612945565b73ffffffffffffffffffffffffffffffffffffffff161480610fe95750610fe881610fe3612945565b61258b565b5b61103e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806148f26038913960400191505060405180910390fd5b826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b83600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d602081101561132857600080fd5b810190808051906020019092919050505050816011819055508060138190555050505050565b6000600b80549050905090565b61136c611366612945565b8261294d565b6113c1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614a6f6031913960400191505060405180910390fd5b6113cc838383612a41565b505050565b60006113dd338361294d565b61144f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130330000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600061145a83611527565b9050600081116114d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430330000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006114de3383612a65565b905061150681600f600087815260200190815260200160002054612dc790919063ffffffff16565b600f6000868152602001908152602001600020819055508192505050919050565b6000611532826128d3565b6115a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631043b2cb600f6000868152602001908152602001600020546040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561162e57600080fd5b505af1158015611642573d6000803e3d6000fd5b505050506040513d602081101561165857600080fd5b81019080805190602001909291905050509050806013541061167e576000915050611697565b61169360135482612dc790919063ffffffff16565b9150505b919050565b60006116a783611ae8565b82106116fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614845602b913960400191505060405180910390fd5b600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061174857fe5b9060005260206000200154905092915050565b6000601354905090565b61178083838360405180602001604052806000815250612311565b505050565b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611872576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600047905060008111156118c8573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156118c6573d6000803e3d6000fd5b505b600060125411156118e8576118df33601254612e11565b60006012819055505b50565b60006118f561134e565b821061194c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614aa0602c913960400191505060405180910390fd5b600b828154811061195957fe5b90600052602060002001549050919050565b601560009054906101000a900460801b81565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806149546029913960400191505060405180910390fd5b80915050919050565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ade5780601f10611ab357610100808354040283529160200191611ade565b820191906000526020600020905b815481529060010190602001808311611ac157829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061492a602a913960400191505060405180910390fd5b611bb6600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613145565b9050919050565b611bc73382613153565b6000600f60008381526020019081526020016000205490506000600f600084815260200190815260200160002081905550611c023382612e11565b5050565b606060003090506000806000606087604051908082528060200260200182016040528015611c435781602001602082028038833980820191505090505b509050600093505b87841015611cbc57611c688260135461318d90919063ffffffff16565b9150611c826001850160105461318d90919063ffffffff16565b925082818581518110611c9157fe5b602002602001018181525050611ca78984613215565b611cb18388613236565b836001019350611c4b565b611cd18860105461318d90919063ffffffff16565b60108190555060008211156120a857611cea33836132c0565b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d6020811015611db757600080fd5b81019080805190602001909291905050509050600094505b888510156120a657818581518110611de357fe5b60200260200101519350600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b4da69f876013546040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611e9857600080fd5b505af1158015611eac573d6000803e3d6000fd5b50505050611fa6611fa182600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318a6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611f5857600080fd5b505af1158015611f6c573d6000803e3d6000fd5b505050506040513d6020811015611f8257600080fd5b8101908080519060200190929190505050612dc790919063ffffffff16565b6135a3565b600f600086815260200190815260200160002081905550600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561205e57600080fd5b505af1158015612072573d6000803e3d6000fd5b505050506040513d602081101561208857600080fd5b81019080805190602001909291905050509050846001019450611dcf565b505b80955050505050509392505050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561214f5780601f106121245761010080835404028352916020019161214f565b820191906000526020600020905b81548152906001019060200180831161213257829003601f168201915b5050505050905090565b612161612945565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612202576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b806004600061220f612945565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166122bc612945565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b61232261231c612945565b8361294d565b612377576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614a6f6031913960400191505060405180910390fd5b6123838484848461361b565b50505050565b6060612394826128d3565b6123e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614a1f602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124925780601f1061246757610100808354040283529160200191612492565b820191906000526020600020905b81548152906001019060200180831161247557829003601f168201915b505050505090506000815114156124bb5760405180602001604052806000815250915050612586565b600781604051602001808380546001816001161561010002031660029004801561251c5780601f106124fa57610100808354040283529182019161251c565b820191906000526020600020905b815481529060010190602001808311612508575b505082805190602001908083835b6020831061254d578051825260208201915060208101905060208303925061252a565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529150505b919050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008060008090505b835181101561269d5783818151811061263d57fe5b602002602001015192506126513384613153565b61267782600f60008681526020019081526020016000205461318d90919063ffffffff16565b91506000600f600085815260200190815260200160002081905550806001019050612628565b506126a83382612e11565b505050565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612770576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612813576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b600033905090565b6000612958826128d3565b6129ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806148c6602c913960400191505060405180910390fd5b60006129b88361197e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612a2757508373ffffffffffffffffffffffffffffffffffffffff16612a0f84610e6e565b73ffffffffffffffffffffffffffffffffffffffff16145b80612a385750612a37818561258b565b5b91505092915050565b612a4c83838361368d565b612a5683826138e8565b612a608282613a86565b505050565b6000803090506000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634a03707c83866040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612b1657600080fd5b505af1158015612b2a573d6000803e3d6000fd5b505050506040513d6020811015612b4057600080fd5b810190808051906020019092919050505090506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612bf457600080fd5b505afa158015612c08573d6000803e3d6000fd5b505050506040513d6020811015612c1e57600080fd5b81019080805190602001909291905050509050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8488846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612d0e57600080fd5b505af1158015612d22573d6000803e3d6000fd5b505050506040513d6020811015612d3857600080fd5b8101908080519060200190929190505050612dbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81935050505092915050565b6000612e0983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b4d565b905092915050565b6000309050600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef693bed82846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612f7857600080fd5b505afa158015612f8c573d6000803e3d6000fd5b505050506040513d6020811015612fa257600080fd5b81019080805190602001909291905050509050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8386846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561309257600080fd5b505af11580156130a6573d6000803e3d6000fd5b505050506040513d60208110156130bc57600080fd5b810190808051906020019092919050505061313f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50505050565b600081600001549050919050565b61315d8282613c0d565b61316782826138e8565b6000600a60008381526020019081526020016000208190555061318981613c6a565b5050565b60008082840190508381101561320b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b61321f8282613d24565b6132298282613a86565b61323281613f3c565b5050565b61323f826128d3565b613294576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806149ca602c913960400191505060405180910390fd5b806008600084815260200190815260200160002090805190602001906132bb92919061472b565b505050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561336157600080fd5b505afa158015613375573d6000803e3d6000fd5b505050506040513d602081101561338b57600080fd5b8101908080519060200190929190505050905080821115613414576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430340000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8430856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156134f157600080fd5b505af1158015613505573d6000803e3d6000fd5b505050506040513d602081101561351b57600080fd5b810190808051906020019092919050505061359e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050565b60008060115414156135b757819050613616565b60006135e26127106135d460115486613f8890919063ffffffff16565b61400e90919063ffffffff16565b90506135f98160125461318d90919063ffffffff16565b6012819055506136128184612dc790919063ffffffff16565b9150505b919050565b613626848484612a41565b61363284848484614058565b613687576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806148706032913960400191505060405180910390fd5b50505050565b8273ffffffffffffffffffffffffffffffffffffffff166136ad8261197e565b73ffffffffffffffffffffffffffffffffffffffff1614613719576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806149f66029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561379f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806148a26024913960400191505060405180910390fd5b6137a881614394565b6137ef600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614452565b613836600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614475565b816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006139406001600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612dc790919063ffffffff16565b90506000600a6000848152602001908152602001600020549050818114613a2d576000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083815481106139ad57fe5b9060005260206000200154905080600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110613a0557fe5b906000526020600020018190555081600a600083815260200190815260200160002081905550505b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480919060019003613a7f91906147ab565b5050505050565b600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050600a600083815260200190815260200160002081905550600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055505050565b6000838311158290613bfa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613bbf578082015181840152602081019050613ba4565b50505050905090810190601f168015613bec5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b613c17828261448b565b60006008600083815260200190815260200160002080546001816001161561010002031660029004905014613c6657600860008281526020019081526020016000206000613c6591906147d7565b5b5050565b6000613c856001600b80549050612dc790919063ffffffff16565b90506000600c60008481526020019081526020016000205490506000600b8381548110613cae57fe5b9060005260206000200154905080600b8381548110613cc957fe5b906000526020600020018190555081600c600083815260200190815260200160002081905550600b805480919060019003613d0491906147ab565b506000600c60008681526020019081526020016000208190555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613dc7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b613dd0816128d3565b15613e43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613edc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614475565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600b80549050600c600083815260200190815260200160002081905550600b81908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080831415613f9b5760009050614008565b6000828402905082848281613fac57fe5b0414614003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061497d6021913960400191505060405180910390fd5b809150505b92915050565b600061405083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061461a565b905092915050565b60006140798473ffffffffffffffffffffffffffffffffffffffff166146e0565b614086576001905061438c565b600060608573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1663150b7a02905060e01b6140ca612945565b898888604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561417a57808201518184015260208101905061415f565b50505050905090810190601f1680156141a75780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061423f578051825260208201915060208101905060208303925061421c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146142a1576040519150601f19603f3d011682016040523d82523d6000602084013e6142a6565b606091505b509150915081614314576000815111156142c35780518082602001fd5b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806148706032913960400191505060405180910390fd5b600081806020019051602081101561432b57600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161493505050505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461444f5760006002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b61446a60018260000154612dc790919063ffffffff16565b816000018190555050565b6001816000016000828254019250508190555050565b8173ffffffffffffffffffffffffffffffffffffffff166144ab8261197e565b73ffffffffffffffffffffffffffffffffffffffff1614614517576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614acc6025913960400191505060405180910390fd5b61452081614394565b614567600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614452565b60006001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080831182906146c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561468b578082015181840152602081019050614670565b50505050905090810190601f1680156146b85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816146d257fe5b049050809150509392505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561472257506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061476c57805160ff191683800117855561479a565b8280016001018555821561479a579182015b8281111561479957825182559160200191906001019061477e565b5b5090506147a7919061481f565b5090565b8154818355818111156147d2578183600052602060002091820191016147d1919061481f565b5b505050565b50805460018160011615610100020316600290046000825580601f106147fd575061481c565b601f01602090049060005260206000209081019061481b919061481f565b5b50565b61484191905b8082111561483d576000816000905550600101614825565b5090565b9056fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776ea265627a7a723158202bb1a217cad7940f37ad65b67a9cc545e157d16f2e2c3d5d958f181554b8eee464736f6c634300050e0032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80634f6ccce7116100f957806395d89b4111610097578063c87b56dd11610071578063c87b56dd14610b46578063e985e9c514610bed578063eeea94fc14610c69578063f2fde38b14610d21576101c4565b806395d89b411461096e578063a22cb465146109f1578063b88d4fde14610a41576101c4565b80636c0360eb116100d35780636c0360eb1461072b57806370a08231146107ae5780637bd1e8061461080657806392c2003a14610834576101c4565b80634f6ccce71461063757806354fd4d50146106795780636352211e146106bd576101c4565b806327e7cd881161016657806332fff0b61161014057806332fff0b61461055757806342842e0e14610575578063442890d5146105e3578063476343ee1461062d576101c4565b806327e7cd88146104715780632e4bfda6146104b35780632f745c59146104f5576101c4565b8063095ea7b3116101a2578063095ea7b31461031f57806316ecc6861461036d57806318160ddd146103e557806323b872dd14610403576101c4565b806301ffc9a7146101c957806306fdde031461022e578063081812fc146102b1575b600080fd5b610214600480360360208110156101df57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d65565b604051808215151515815260200191505060405180910390f35b610236610dcc565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561027657808201518184015260208101905061025b565b50505050905090810190601f1680156102a35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102dd600480360360208110156102c757600080fd5b8101908080359060200190929190505050610e6e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61036b6004803603604081101561033557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f09565b005b6103e36004803603608081101561038357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506110f0565b005b6103ed61134e565b6040518082815260200191505060405180910390f35b61046f6004803603606081101561041957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061135b565b005b61049d6004803603602081101561048757600080fd5b81019080803590602001909291905050506113d1565b6040518082815260200191505060405180910390f35b6104df600480360360208110156104c957600080fd5b8101908080359060200190929190505050611527565b6040518082815260200191505060405180910390f35b6105416004803603604081101561050b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061169c565b6040518082815260200191505060405180910390f35b61055f61175b565b6040518082815260200191505060405180910390f35b6105e16004803603606081101561058b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611765565b005b6105eb611785565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106356117af565b005b6106636004803603602081101561064d57600080fd5b81019080803590602001909291905050506118eb565b6040518082815260200191505060405180910390f35b61068161196b565b60405180826fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6106e9600480360360208110156106d357600080fd5b810190808035906020019092919050505061197e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610733611a46565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610773578082015181840152602081019050610758565b50505050905090810190601f1680156107a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107f0600480360360208110156107c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ae8565b6040518082815260200191505060405180910390f35b6108326004803603602081101561081c57600080fd5b8101908080359060200190929190505050611bbd565b005b6109176004803603606081101561084a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561089157600080fd5b8201836020820111156108a357600080fd5b803590602001918460018302840111640100000000831117156108c557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611c06565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561095a57808201518184015260208101905061093f565b505050509050019250505060405180910390f35b6109766120b7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156109b657808201518184015260208101905061099b565b50505050905090810190601f1680156109e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a3f60048036036040811015610a0757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612159565b005b610b4460048036036080811015610a5757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610abe57600080fd5b820183602082011115610ad057600080fd5b80359060200191846001830284011164010000000083111715610af257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612311565b005b610b7260048036036020811015610b5c57600080fd5b8101908080359060200190929190505050612389565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610bb2578082015181840152602081019050610b97565b50505050905090810190601f168015610bdf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610c4f60048036036040811015610c0357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061258b565b604051808215151515815260200191505060405180910390f35b610d1f60048036036020811015610c7f57600080fd5b8101908080359060200190640100000000811115610c9c57600080fd5b820183602082011115610cae57600080fd5b80359060200191846020830284011164010000000083111715610cd057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929050505061261f565b005b610d6360048036036020811015610d3757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126ad565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e645780601f10610e3957610100808354040283529160200191610e64565b820191906000526020600020905b815481529060010190602001808311610e4757829003601f168201915b5050505050905090565b6000610e79826128d3565b610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061499e602c913960400191505060405180910390fd5b6002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610f148261197e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614a4e6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610fba612945565b73ffffffffffffffffffffffffffffffffffffffff161480610fe95750610fe881610fe3612945565b61258b565b5b61103e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806148f26038913960400191505060405180910390fd5b826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b83600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d602081101561132857600080fd5b810190808051906020019092919050505050816011819055508060138190555050505050565b6000600b80549050905090565b61136c611366612945565b8261294d565b6113c1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614a6f6031913960400191505060405180910390fd5b6113cc838383612a41565b505050565b60006113dd338361294d565b61144f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130330000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600061145a83611527565b9050600081116114d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430330000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006114de3383612a65565b905061150681600f600087815260200190815260200160002054612dc790919063ffffffff16565b600f6000868152602001908152602001600020819055508192505050919050565b6000611532826128d3565b6115a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631043b2cb600f6000868152602001908152602001600020546040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561162e57600080fd5b505af1158015611642573d6000803e3d6000fd5b505050506040513d602081101561165857600080fd5b81019080805190602001909291905050509050806013541061167e576000915050611697565b61169360135482612dc790919063ffffffff16565b9150505b919050565b60006116a783611ae8565b82106116fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614845602b913960400191505060405180910390fd5b600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061174857fe5b9060005260206000200154905092915050565b6000601354905090565b61178083838360405180602001604052806000815250612311565b505050565b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611872576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600047905060008111156118c8573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156118c6573d6000803e3d6000fd5b505b600060125411156118e8576118df33601254612e11565b60006012819055505b50565b60006118f561134e565b821061194c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614aa0602c913960400191505060405180910390fd5b600b828154811061195957fe5b90600052602060002001549050919050565b601560009054906101000a900460801b81565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806149546029913960400191505060405180910390fd5b80915050919050565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ade5780601f10611ab357610100808354040283529160200191611ade565b820191906000526020600020905b815481529060010190602001808311611ac157829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061492a602a913960400191505060405180910390fd5b611bb6600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613145565b9050919050565b611bc73382613153565b6000600f60008381526020019081526020016000205490506000600f600084815260200190815260200160002081905550611c023382612e11565b5050565b606060003090506000806000606087604051908082528060200260200182016040528015611c435781602001602082028038833980820191505090505b509050600093505b87841015611cbc57611c688260135461318d90919063ffffffff16565b9150611c826001850160105461318d90919063ffffffff16565b925082818581518110611c9157fe5b602002602001018181525050611ca78984613215565b611cb18388613236565b836001019350611c4b565b611cd18860105461318d90919063ffffffff16565b60108190555060008211156120a857611cea33836132c0565b6000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d6020811015611db757600080fd5b81019080805190602001909291905050509050600094505b888510156120a657818581518110611de357fe5b60200260200101519350600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b4da69f876013546040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611e9857600080fd5b505af1158015611eac573d6000803e3d6000fd5b50505050611fa6611fa182600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318a6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611f5857600080fd5b505af1158015611f6c573d6000803e3d6000fd5b505050506040513d6020811015611f8257600080fd5b8101908080519060200190929190505050612dc790919063ffffffff16565b6135a3565b600f600086815260200190815260200160002081905550600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561205e57600080fd5b505af1158015612072573d6000803e3d6000fd5b505050506040513d602081101561208857600080fd5b81019080805190602001909291905050509050846001019450611dcf565b505b80955050505050509392505050565b606060068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561214f5780601f106121245761010080835404028352916020019161214f565b820191906000526020600020905b81548152906001019060200180831161213257829003601f168201915b5050505050905090565b612161612945565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612202576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b806004600061220f612945565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166122bc612945565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b61232261231c612945565b8361294d565b612377576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614a6f6031913960400191505060405180910390fd5b6123838484848461361b565b50505050565b6060612394826128d3565b6123e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614a1f602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124925780601f1061246757610100808354040283529160200191612492565b820191906000526020600020905b81548152906001019060200180831161247557829003601f168201915b505050505090506000815114156124bb5760405180602001604052806000815250915050612586565b600781604051602001808380546001816001161561010002031660029004801561251c5780601f106124fa57610100808354040283529182019161251c565b820191906000526020600020905b815481529060010190602001808311612508575b505082805190602001908083835b6020831061254d578051825260208201915060208101905060208303925061252a565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529150505b919050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008060008090505b835181101561269d5783818151811061263d57fe5b602002602001015192506126513384613153565b61267782600f60008681526020019081526020016000205461318d90919063ffffffff16565b91506000600f600085815260200190815260200160002081905550806001019050612628565b506126a83382612e11565b505050565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612770576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130320000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612813576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453130310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b600033905090565b6000612958826128d3565b6129ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806148c6602c913960400191505060405180910390fd5b60006129b88361197e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612a2757508373ffffffffffffffffffffffffffffffffffffffff16612a0f84610e6e565b73ffffffffffffffffffffffffffffffffffffffff16145b80612a385750612a37818561258b565b5b91505092915050565b612a4c83838361368d565b612a5683826138e8565b612a608282613a86565b505050565b6000803090506000600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634a03707c83866040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612b1657600080fd5b505af1158015612b2a573d6000803e3d6000fd5b505050506040513d6020811015612b4057600080fd5b810190808051906020019092919050505090506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612bf457600080fd5b505afa158015612c08573d6000803e3d6000fd5b505050506040513d6020811015612c1e57600080fd5b81019080805190602001909291905050509050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8488846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612d0e57600080fd5b505af1158015612d22573d6000803e3d6000fd5b505050506040513d6020811015612d3857600080fd5b8101908080519060200190929190505050612dbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81935050505092915050565b6000612e0983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b4d565b905092915050565b6000309050600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef693bed82846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612f7857600080fd5b505afa158015612f8c573d6000803e3d6000fd5b505050506040513d6020811015612fa257600080fd5b81019080805190602001909291905050509050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8386846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561309257600080fd5b505af11580156130a6573d6000803e3d6000fd5b505050506040513d60208110156130bc57600080fd5b810190808051906020019092919050505061313f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50505050565b600081600001549050919050565b61315d8282613c0d565b61316782826138e8565b6000600a60008381526020019081526020016000208190555061318981613c6a565b5050565b60008082840190508381101561320b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b61321f8282613d24565b6132298282613a86565b61323281613f3c565b5050565b61323f826128d3565b613294576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806149ca602c913960400191505060405180910390fd5b806008600084815260200190815260200160002090805190602001906132bb92919061472b565b505050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561336157600080fd5b505afa158015613375573d6000803e3d6000fd5b505050506040513d602081101561338b57600080fd5b8101908080519060200190929190505050905080821115613414576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430340000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8430856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156134f157600080fd5b505af1158015613505573d6000803e3d6000fd5b505050506040513d602081101561351b57600080fd5b810190808051906020019092919050505061359e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f453430350000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050565b60008060115414156135b757819050613616565b60006135e26127106135d460115486613f8890919063ffffffff16565b61400e90919063ffffffff16565b90506135f98160125461318d90919063ffffffff16565b6012819055506136128184612dc790919063ffffffff16565b9150505b919050565b613626848484612a41565b61363284848484614058565b613687576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806148706032913960400191505060405180910390fd5b50505050565b8273ffffffffffffffffffffffffffffffffffffffff166136ad8261197e565b73ffffffffffffffffffffffffffffffffffffffff1614613719576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806149f66029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561379f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806148a26024913960400191505060405180910390fd5b6137a881614394565b6137ef600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614452565b613836600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614475565b816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006139406001600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612dc790919063ffffffff16565b90506000600a6000848152602001908152602001600020549050818114613a2d576000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083815481106139ad57fe5b9060005260206000200154905080600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110613a0557fe5b906000526020600020018190555081600a600083815260200190815260200160002081905550505b600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480919060019003613a7f91906147ab565b5050505050565b600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050600a600083815260200190815260200160002081905550600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055505050565b6000838311158290613bfa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613bbf578082015181840152602081019050613ba4565b50505050905090810190601f168015613bec5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b613c17828261448b565b60006008600083815260200190815260200160002080546001816001161561010002031660029004905014613c6657600860008281526020019081526020016000206000613c6591906147d7565b5b5050565b6000613c856001600b80549050612dc790919063ffffffff16565b90506000600c60008481526020019081526020016000205490506000600b8381548110613cae57fe5b9060005260206000200154905080600b8381548110613cc957fe5b906000526020600020018190555081600c600083815260200190815260200160002081905550600b805480919060019003613d0491906147ab565b506000600c60008681526020019081526020016000208190555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613dc7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b613dd0816128d3565b15613e43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613edc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614475565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600b80549050600c600083815260200190815260200160002081905550600b81908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080831415613f9b5760009050614008565b6000828402905082848281613fac57fe5b0414614003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061497d6021913960400191505060405180910390fd5b809150505b92915050565b600061405083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061461a565b905092915050565b60006140798473ffffffffffffffffffffffffffffffffffffffff166146e0565b614086576001905061438c565b600060608573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1663150b7a02905060e01b6140ca612945565b898888604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561417a57808201518184015260208101905061415f565b50505050905090810190601f1680156141a75780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061423f578051825260208201915060208101905060208303925061421c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146142a1576040519150601f19603f3d011682016040523d82523d6000602084013e6142a6565b606091505b509150915081614314576000815111156142c35780518082602001fd5b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806148706032913960400191505060405180910390fd5b600081806020019051602081101561432b57600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161493505050505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461444f5760006002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b61446a60018260000154612dc790919063ffffffff16565b816000018190555050565b6001816000016000828254019250508190555050565b8173ffffffffffffffffffffffffffffffffffffffff166144ab8261197e565b73ffffffffffffffffffffffffffffffffffffffff1614614517576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614acc6025913960400191505060405180910390fd5b61452081614394565b614567600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614452565b60006001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080831182906146c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561468b578082015181840152602081019050614670565b50505050905090810190601f1680156146b85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816146d257fe5b049050809150509392505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561472257506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061476c57805160ff191683800117855561479a565b8280016001018555821561479a579182015b8281111561479957825182559160200191906001019061477e565b5b5090506147a7919061481f565b5090565b8154818355818111156147d2578183600052602060002091820191016147d1919061481f565b5b505050565b50805460018160011615610100020316600290046000825580601f106147fd575061481c565b601f01602090049060005260206000209081019061481b919061481f565b5b50565b61484191905b8082111561483d576000816000905550600101614825565b5090565b9056fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776ea265627a7a723158202bb1a217cad7940f37ad65b67a9cc545e157d16f2e2c3d5d958f181554b8eee464736f6c634300050e0032
Deployed Bytecode Sourcemap
49537:10415:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49537:10415:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18016:129;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;18016:129:0;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;46734:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;46734:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25554:195;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;25554:195:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;24881:401;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;24881:401:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;56326:409;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;56326:409:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;38970:90;;;:::i;:::-;;;;;;;;;;;;;;;;;;;27141:280;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27141:280:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;52600:461;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;52600:461:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;51990:306;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;51990:306:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;38603:223;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;38603:223:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;51656:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;28047:128;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28047:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;51265:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;56824:319;;;:::i;:::-;;39385:190;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;39385:190:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;50185:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;24261:216;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;24261:216:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;48813:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;48813:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23851:202;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;23851:202:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;55091:307;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;55091:307:0;;;;;;;;;;;;;;;;;:::i;:::-;;53516:1269;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;53516:1269:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;53516:1269:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;53516:1269:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;53516:1269:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;53516:1269:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;53516:1269:0;;;;;;;;;;;;;;;;;46913:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;46913:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26029:242;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;26029:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28873:263;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;28873:263:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;28873:263:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;28873:263:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;28873:263:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;28873:263:0;;;;;;;;;;;;;;;:::i;:::-;;47282:527;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;47282:527:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;47282:527:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26580:141;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;26580:141:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;55583:511;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;55583:511:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;55583:511:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;55583:511:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;55583:511:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;55583:511:0;;;;;;;;;;;;;;;:::i;:::-;;57290:204;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;57290:204:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;18016:129;18086:4;18107:20;:33;18128:11;18107:33;;;;;;;;;;;;;;;;;;;;;;;;;;;18100:40;;18016:129;;;:::o;46734:79::-;46773:13;46803:5;46796:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46734:79;:::o;25554:195::-;25613:7;25638:16;25646:7;25638;:16::i;:::-;25630:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25720:15;:24;25736:7;25720:24;;;;;;;;;;;;;;;;;;;;;25713:31;;25554:195;;;:::o;24881:401::-;24942:13;24958:16;24966:7;24958;:16::i;:::-;24942:32;;24996:5;24990:11;;:2;:11;;;;24982:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:5;25057:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;25082:37;25099:5;25106:12;:10;:12::i;:::-;25082:16;:37::i;:::-;25057:62;25049:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25234:2;25207:15;:24;25223:7;25207:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;25269:7;25265:2;25249:28;;25258:5;25249:28;;;;;;;;;;;;24881:401;;;:::o;56326:409::-;50589:5;;;;;;;;;;;50575:19;;:10;:19;;;50567:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56506:11;56493:3;;:25;;;;;;;;;;;;;;;;;;56542:12;56529:4;;:26;;;;;;;;;;;;;;;;;;56616:3;;;;;;;;;;;:11;;;56628:12;56647:2;56616:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56616:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56616:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;56616:35:0;;;;;;;;;;;;;;;;;56674:8;56664:7;:18;;;;56711:16;56693:15;:34;;;;56326:409;;;;:::o;38970:90::-;39014:7;39038:10;:17;;;;39031:24;;38970:90;:::o;27141:280::-;27279:41;27298:12;:10;:12::i;:::-;27312:7;27279:18;:41::i;:::-;27271:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27384:32;27398:4;27404:2;27408:7;27384:13;:32::i;:::-;27141:280;;;:::o;52600:461::-;52653:7;52681:40;52700:10;52712:8;52681:18;:40::i;:::-;52673:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52743:25;52771:26;52788:8;52771:16;:26::i;:::-;52743:54;;52836:1;52816:17;:21;52808:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52859:17;52879:48;52897:10;52909:17;52879;:48::i;:::-;52859:68;;52971:45;53006:9;52971:20;:30;52992:8;52971:30;;;;;;;;;;;;:34;;:45;;;;:::i;:::-;52938:20;:30;52959:8;52938:30;;;;;;;;;;;:78;;;;53036:17;53029:24;;;;52600:461;;;:::o;51990:306::-;52050:7;52078:17;52086:8;52078:7;:17::i;:::-;52070:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52117:19;52139:4;;;;;;;;;;;:8;;;52148:20;:30;52169:8;52148:30;;;;;;;;;;;;52139:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52139:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52139:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;52139:40:0;;;;;;;;;;;;;;;;52117:62;;52213:11;52194:15;;:30;52190:49;;52235:1;52228:8;;;;;52190:49;52256:32;52272:15;;52256:11;:15;;:32;;;;:::i;:::-;52249:39;;;51990:306;;;;:::o;38603:223::-;38683:7;38716:16;38726:5;38716:9;:16::i;:::-;38708:5;:24;38700:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38795:12;:19;38808:5;38795:19;;;;;;;;;;;;;;;38815:5;38795:26;;;;;;;;;;;;;;;;38788:33;;38603:223;;;;:::o;51656:98::-;51704:7;51731:15;;51724:22;;51656:98;:::o;28047:128::-;28131:39;28148:4;28154:2;28158:7;28131:39;;;;;;;;;;;;:16;:39::i;:::-;28047:128;;;:::o;51265:89::-;51314:7;51341:5;;;;;;;;;;;51334:12;;51265:89;:::o;56824:319::-;50589:5;;;;;;;;;;;50575:19;;:10;:19;;;50567:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56876:16;56895:21;56876:40;;56942:1;56931:8;:12;56927:74;;;56960:10;:19;;:29;56980:8;56960:29;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56960:29:0;56927:74;57031:1;57015:13;;:17;57011:125;;;57049:43;57066:10;57078:13;;57049:16;:43::i;:::-;57123:1;57107:13;:17;;;;57011:125;50614:1;56824:319::o;39385:190::-;39443:7;39476:13;:11;:13::i;:::-;39468:5;:21;39460:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39553:10;39564:5;39553:17;;;;;;;;;;;;;;;;39546:24;;39385:190;;;:::o;50185:33::-;;;;;;;;;;;;;:::o;24261:216::-;24316:7;24333:13;24349:11;:20;24361:7;24349:20;;;;;;;;;;;;;;;;;;;;;24333:36;;24402:1;24385:19;;:5;:19;;;;24377:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24467:5;24460:12;;;24261:216;;;:::o;48813:85::-;48855:13;48885:8;48878:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48813:85;:::o;23851:202::-;23906:7;23948:1;23931:19;;:5;:19;;;;23923:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24014:34;:17;:24;24032:5;24014:24;;;;;;;;;;;;;;;:32;:34::i;:::-;24007:41;;23851:202;;;:::o;55091:307::-;55169:27;55175:10;55187:8;55169:5;:27::i;:::-;55243:18;55264:20;:30;55285:8;55264:30;;;;;;;;;;;;55243:51;;55338:1;55305:20;:30;55326:8;55305:30;;;;;;;;;;;:34;;;;55350:40;55367:10;55379;55350:16;:40::i;:::-;55091:307;;:::o;53516:1269::-;53604:16;53633:13;53657:4;53633:29;;53673:9;53693:16;53720:17;53748:26;53791:7;53777:22;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;148:4;140:6;136:17;126:27;;0:157;53777:22:0;;;;53748:51;;53821:1;53817:5;;53812:270;53828:7;53824:1;:11;53812:270;;;53869:30;53889:9;53869:15;;:19;;:30;;;;:::i;:::-;53857:42;;53928:26;53952:1;53950;:3;53928:17;;:21;;:26;;;;:::i;:::-;53916:39;;53985:8;53970:9;53980:1;53970:12;;;;;;;;;;;;;:23;;;;;54008:20;54014:3;54019:8;54008:5;:20::i;:::-;54040:30;54053:8;54063:6;54040:12;:30::i;:::-;53837:3;;;;;53812:270;;;54112:30;54134:7;54112:17;;:21;;:30;;;;:::i;:::-;54092:17;:50;;;;54171:1;54159:9;:13;54155:596;;;54240:42;54260:10;54272:9;54240:19;:42::i;:::-;54299:16;54318:4;;;;;;;;;;;:14;;;54333:5;54318:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54318:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54318:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;54318:21:0;;;;;;;;;;;;;;;;54299:40;;54363:1;54359:5;;54354:386;54370:7;54366:1;:11;54354:386;;;54414:9;54424:1;54414:12;;;;;;;;;;;;;;54403:23;;54485:4;;;;;;;;;;;:9;;;54495:5;54502:15;;54485:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54485:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54485:33:0;;;;54618:55;54637:35;54663:8;54637:4;;;;;;;;;;;:14;;;54652:5;54637:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54637:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54637:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;54637:21:0;;;;;;;;;;;;;;;;:25;;:35;;;;:::i;:::-;54618:18;:55::i;:::-;54585:20;:30;54606:8;54585:30;;;;;;;;;;;:88;;;;54703:4;;;;;;;;;;;:14;;;54718:5;54703:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54703:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54703:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;54703:21:0;;;;;;;;;;;;;;;;54692:32;;54379:3;;;;;54354:386;;;54155:596;;54768:9;54761:16;;;;;;;53516:1269;;;;;:::o;46913:83::-;46954:13;46984:7;46977:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46913:83;:::o;26029:242::-;26112:12;:10;:12::i;:::-;26106:18;;:2;:18;;;;26098:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26203:8;26164:18;:32;26183:12;:10;:12::i;:::-;26164:32;;;;;;;;;;;;;;;:36;26197:2;26164:36;;;;;;;;;;;;;;;;:47;;;;;;;;;;;;;;;;;;26253:2;26224:42;;26239:12;:10;:12::i;:::-;26224:42;;;26257:8;26224:42;;;;;;;;;;;;;;;;;;;;;;26029:242;;:::o;28873:263::-;28985:41;29004:12;:10;:12::i;:::-;29018:7;28985:18;:41::i;:::-;28977:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29088:43;29106:4;29112:2;29116:7;29125:5;29088:17;:43::i;:::-;28873:263;;;;:::o;47282:527::-;47340:13;47371:16;47379:7;47371;:16::i;:::-;47363:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47449:23;47475:10;:19;47486:7;47475:19;;;;;;;;;;;47449:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47626:1;47605:9;47599:23;:28;47595:210;;;47641:9;;;;;;;;;;;;;;;;;47595:210;47775:8;47785:9;47758:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;47758:37:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;47758:37:0;;;47744:52;;;47282:527;;;;:::o;26580:141::-;26660:4;26681:18;:25;26700:5;26681:25;;;;;;;;;;;;;;;:35;26707:8;26681:35;;;;;;;;;;;;;;;;;;;;;;;;;26674:42;;26580:141;;;;:::o;55583:511::-;55649:16;55676:18;55710:9;55722:1;55710:13;;55705:331;55729:9;:16;55725:1;:20;55705:331;;;55778:9;55788:1;55778:12;;;;;;;;;;;;;;55767:23;;55834:27;55840:10;55852:8;55834:5;:27::i;:::-;55929:46;55964:10;55929:20;:30;55950:8;55929:30;;;;;;;;;;;;:34;;:46;;;;:::i;:::-;55916:59;;56023:1;55990:20;:30;56011:8;55990:30;;;;;;;;;;;:34;;;;55747:3;;;;;55705:331;;;;56046:40;56063:10;56075;56046:16;:40::i;:::-;55583:511;;;:::o;57290:204::-;50589:5;;;;;;;;;;;50575:19;;:10;:19;;;50567:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57393:1;57372:23;;:9;:23;;;;57364:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57448:9;57420:38;;57441:5;;;;;;;;;;;57420:38;;;;;;;;;;;;57477:9;57469:5;;:17;;;;;;;;;;;;;;;;;;57290:204;:::o;30263:146::-;30320:4;30334:13;30350:11;:20;30362:7;30350:20;;;;;;;;;;;;;;;;;;;;;30334:36;;30402:1;30385:19;;:5;:19;;;;30378:26;;;30263:146;;;:::o;16137:92::-;16182:15;16214:10;16207:17;;16137:92;:::o;30755:321::-;30840:4;30862:16;30870:7;30862;:16::i;:::-;30854:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30935:13;30951:16;30959:7;30951;:16::i;:::-;30935:32;;30994:5;30983:16;;:7;:16;;;:51;;;;31027:7;31003:31;;:20;31015:7;31003:11;:20::i;:::-;:31;;;30983:51;:87;;;;31038:32;31055:5;31062:7;31038:16;:32::i;:::-;30983:87;30975:96;;;30755:321;;;;:::o;39935:233::-;40018:38;40038:4;40044:2;40048:7;40018:19;:38::i;:::-;40066:47;40099:4;40105:7;40066:32;:47::i;:::-;40123:40;40151:2;40155:7;40123:27;:40::i;:::-;39935:233;;;:::o;58964:398::-;59041:7;59061:13;59085:4;59061:29;;59132:13;59148:4;;;;;;;;;;;:9;;;59158:5;59165:9;59148:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59148:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59148:27:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59148:27:0;;;;;;;;;;;;;;;;59132:43;;59218:20;59241:3;;;;;;;;;;;:13;;;59255:5;59241:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59241:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59241:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59241:20:0;;;;;;;;;;;;;;;;59218:43;;59280:3;;;;;;;;;;;:16;;;59297:5;59304:3;59309:12;59280:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59280:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59280:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59280:42:0;;;;;;;;;;;;;;;;59272:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59349:5;59342:12;;;;;58964:398;;;;:::o;7316:130::-;7374:7;7398:43;7402:1;7405;7398:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;7391:50;;7316:130;;;;:::o;58397:368::-;58476:13;58500:4;58476:29;;58567:4;;;;;;;;;;;:9;;;58577:5;58584:10;58567:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58567:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58567:28:0;;;;58644:20;58667:3;;;;;;;;;;;:13;;;58681:5;58667:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58667:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58667:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58667:20:0;;;;;;;;;;;;;;;;58644:43;;58706:3;;;;;;;;;;;:16;;;58723:5;58730:3;58735:12;58706:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58706:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58706:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58706:42:0;;;;;;;;;;;;;;;;58698:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58397:368;;;;:::o;14972:108::-;15037:7;15061;:14;;;15054:21;;14972:108;;;:::o;40862:354::-;40926:27;40938:5;40945:7;40926:11;:27::i;:::-;40963:48;40996:5;41003:7;40963:32;:48::i;:::-;41155:1;41126:17;:26;41144:7;41126:26;;;;;;;;;;;:30;;;;41166:45;41203:7;41166:36;:45::i;:::-;40862:354;;:::o;6902:169::-;6960:7;6977:9;6993:1;6989;:5;6977:17;;7015:1;7010;:6;;7002:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7065:1;7058:8;;;6902:169;;;;:::o;40412:190::-;40473:24;40485:2;40489:7;40473:11;:24::i;:::-;40507:40;40535:2;40539:7;40507:27;:40::i;:::-;40557;40589:7;40557:31;:40::i;:::-;40412:190;;:::o;48114:198::-;48203:16;48211:7;48203;:16::i;:::-;48195:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48298:9;48276:10;:19;48287:7;48276:19;;;;;;;;;;;:31;;;;;;;;;;;;:::i;:::-;;48114:198;;:::o;57870:326::-;58003:23;58029:3;;;;;;;;;;;:13;;;58043:5;58029:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58029:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58029:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58029:20:0;;;;;;;;;;;;;;;;58003:46;;58084:15;58068:12;:31;;58060:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58127:3;;;;;;;;;;;:16;;;58144:5;58159:4;58166:12;58127:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58127:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58127:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58127:52:0;;;;;;;;;;;;;;;;58119:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57870:326;;;:::o;59658:291::-;59724:7;59759:1;59748:7;;:12;59744:40;;;59771:10;59764:17;;;;59744:40;59794:16;59813:32;59841:3;59813:23;59828:7;;59813:10;:14;;:23;;;;:::i;:::-;:27;;:32;;;;:::i;:::-;59794:51;;59872:27;59890:8;59872:13;;:17;;:27;;;;:::i;:::-;59856:13;:43;;;;59917:24;59932:8;59917:10;:14;;:24;;;;:::i;:::-;59910:31;;;59658:291;;;;:::o;29816:263::-;29923:32;29937:4;29943:2;29947:7;29923:13;:32::i;:::-;29971:48;29994:4;30000:2;30004:7;30013:5;29971:22;:48::i;:::-;29963:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29816:263;;;;:::o;34226:435::-;34337:4;34317:24;;:16;34325:7;34317;:16::i;:::-;:24;;;34309:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34417:1;34403:16;;:2;:16;;;;34395:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34470:23;34485:7;34470:14;:23::i;:::-;34503:35;:17;:23;34521:4;34503:23;;;;;;;;;;;;;;;:33;:35::i;:::-;34546:33;:17;:21;34564:2;34546:21;;;;;;;;;;;;;;;:31;:33::i;:::-;34612:2;34589:11;:20;34601:7;34589:20;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;34648:7;34644:2;34629:27;;34638:4;34629:27;;;;;;;;;;;;34226:435;;;:::o;42931:1103::-;43188:22;43213:32;43243:1;43213:12;:18;43226:4;43213:18;;;;;;;;;;;;;;;:25;;;;:29;;:32;;;;:::i;:::-;43188:57;;43253:18;43274:17;:26;43292:7;43274:26;;;;;;;;;;;;43253:47;;43415:14;43401:10;:28;43397:316;;43443:19;43465:12;:18;43478:4;43465:18;;;;;;;;;;;;;;;43484:14;43465:34;;;;;;;;;;;;;;;;43443:56;;43546:11;43513:12;:18;43526:4;43513:18;;;;;;;;;;;;;;;43532:10;43513:30;;;;;;;;;;;;;;;:44;;;;43660:10;43627:17;:30;43645:11;43627:30;;;;;;;;;;;:43;;;;43397:316;;43796:12;:18;43809:4;43796:18;;;;;;;;;;;;;;;:27;;;;;;;;;;;;:::i;:::-;;42931:1103;;;;:::o;41813:177::-;41924:12;:16;41937:2;41924:16;;;;;;;;;;;;;;;:23;;;;41895:17;:26;41913:7;41895:26;;;;;;;;;;;:52;;;;41955:12;:16;41968:2;41955:16;;;;;;;;;;;;;;;41977:7;41955:30;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;41955:30:0;;;;;;;;;;;;;;;;;;;;;;41813:177;;:::o;7747:180::-;7833:7;7863:1;7858;:6;;7866:12;7850:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;7850:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7887:9;7903:1;7899;:5;7887:17;;7921:1;7914:8;;;7747:180;;;;;:::o;49176:229::-;49240:27;49252:5;49259:7;49240:11;:27::i;:::-;49351:1;49320:10;:19;49331:7;49320:19;;;;;;;;;;;49314:33;;;;;;;;;;;;;;;;:38;49310:91;;49373:10;:19;49384:7;49373:19;;;;;;;;;;;;49366:26;;;;:::i;:::-;49310:91;49176:229;;:::o;44311:1040::-;44555:22;44580:24;44602:1;44580:10;:17;;;;:21;;:24;;;;:::i;:::-;44555:49;;44612:18;44633:15;:24;44649:7;44633:24;;;;;;;;;;;;44612:45;;44972:19;44994:10;45005:14;44994:26;;;;;;;;;;;;;;;;44972:48;;45055:11;45030:10;45041;45030:22;;;;;;;;;;;;;;;:36;;;;45163:10;45132:15;:28;45148:11;45132:28;;;;;;;;;;;:41;;;;45291:10;:19;;;;;;;;;;;;:::i;:::-;;45345:1;45318:15;:24;45334:7;45318:24;;;;;;;;;;;:28;;;;44311:1040;;;;:::o;32723:317::-;32806:1;32792:16;;:2;:16;;;;32784:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32862:16;32870:7;32862;:16::i;:::-;32861:17;32853:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32944:2;32921:11;:20;32933:7;32921:20;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;32954:33;:17;:21;32972:2;32954:21;;;;;;;;;;;;;;;:31;:33::i;:::-;33027:7;33023:2;33002:33;;33019:1;33002:33;;;;;;;;;;;;32723:317;;:::o;42176:155::-;42277:10;:17;;;;42250:15;:24;42266:7;42250:24;;;;;;;;;;;:44;;;;42302:10;42318:7;42302:24;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;42302:24:0;;;;;;;;;;;;;;;;;;;;;;42176:155;:::o;8148:441::-;8206:7;8444:1;8439;:6;8435:41;;;8466:1;8459:8;;;;8435:41;8485:9;8501:1;8497;:5;8485:17;;8527:1;8522;8518;:5;;;;;;:10;8510:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8583:1;8576:8;;;8148:441;;;;;:::o;9021:126::-;9079:7;9103:39;9107:1;9110;9103:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;9096:46;;9021:126;;;;:::o;35277:995::-;35396:4;35417:15;:2;:13;;;:15::i;:::-;35412:54;;35453:4;35446:11;;;;35412:54;35531:12;35545:23;35572:2;:7;;35630:2;35614:36;;;:45;;;;35671:12;:10;:12::i;:::-;35695:4;35711:7;35730:5;35580:163;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;35580:163:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;35580:163:0;;;;;;;38:4:-1;29:7;25:18;67:10;61:17;96:58;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;35580:163:0;35572:172;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;35572:172:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;35530:214:0;;;;35757:7;35752:516;;35802:1;35782:10;:17;:21;35778:360;;;35941:10;35935:17;35999:15;35986:10;35982:2;35978:19;35971:44;35892:139;36065:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35752:516;36164:13;36191:10;36180:32;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;36180:32:0;;;;;;;;;;;;;;;;36164:48;;22184:10;36242:16;;36232:26;;;:6;:26;;;;36224:35;;;;;35277:995;;;;;;;:::o;36425:163::-;36522:1;36486:38;;:15;:24;36502:7;36486:24;;;;;;;;;;;;;;;;;;;;;:38;;;36482:102;;36573:1;36538:15;:24;36554:7;36538:24;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;36482:102;36425:163;:::o;15262:104::-;15340:21;15359:1;15340:7;:14;;;:18;;:21;;;;:::i;:::-;15323:7;:14;;:38;;;;15262:104;:::o;15085:172::-;15251:1;15233:7;:14;;;:19;;;;;;;;;;;15085:172;:::o;33293:315::-;33385:5;33365:25;;:16;33373:7;33365;:16::i;:::-;:25;;;33357:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33442:23;33457:7;33442:14;:23::i;:::-;33475:36;:17;:24;33493:5;33475:24;;;;;;;;;;;;;;;:34;:36::i;:::-;33550:1;33519:11;:20;33531:7;33519:20;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;33595:7;33591:1;33567:36;;33576:5;33567:36;;;;;;;;;;;;33293:315;;:::o;9635:327::-;9721:7;9814:1;9810;:5;9817:12;9802:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;9802:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9838:9;9854:1;9850;:5;;;;;;9838:17;;9956:1;9949:8;;;9635:327;;;;;:::o;11775:592::-;11835:4;12085:16;12109:19;12131:66;12109:88;;;;12294:7;12282:20;12270:32;;12331:11;12319:8;:23;;:42;;;;;12358:3;12346:15;;:8;:15;;12319:42;12311:51;;;;11775:592;;;:::o;49537:10415::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
bzzr://2bb1a217cad7940f37ad65b67a9cc545e157d16f2e2c3d5d958f181554b8eee4
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.