- Contract name:
- IDOMaster
- Optimization enabled
- true
- Compiler version
- v0.8.7+commit.e28d00a7
- Optimization runs
- 200
- Verified at
- 2022-12-02T04:25:02.099618Z
Contract source code
// Sources flattened with hardhat v2.9.3 https://hardhat.org
// File @openzeppelin/contracts/utils/math/[email protected]
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// 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 (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @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) {
return a + b;
}
/**
* @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 a - b;
}
/**
* @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) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting 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 a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting 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.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* 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,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File @openzeppelin/contracts/token/ERC20/[email protected]
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
/**
* @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);
}
// File @openzeppelin/contracts/utils/[email protected]
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File @openzeppelin/contracts/token/ERC20/utils/[email protected]
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File @openzeppelin/contracts/utils/[email protected]
// OpenZeppelin Contracts v4.4.1 (utils/Create2.sol)
pragma solidity ^0.8.0;
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(
uint256 amount,
bytes32 salt,
bytes memory bytecode
) internal returns (address) {
address addr;
require(address(this).balance >= amount, "Create2: insufficient balance");
require(bytecode.length != 0, "Create2: bytecode length is zero");
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Create2: Failed on deploy");
return addr;
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(
bytes32 salt,
bytes32 bytecodeHash,
address deployer
) internal pure returns (address) {
bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash));
return address(uint160(uint256(_data)));
}
}
// File @openzeppelin/contracts/security/[email protected]
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File contracts/VestingWallet.sol
pragma solidity 0.8.7;
/**
* @title VestingWallet
* @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens
* can be given to this contract, which will release the token to the beneficiary following a given vesting schedule.
* The vesting schedule is customizable through the {vestedAmount} function.
*
* Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning.
* Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly)
* be immediately releasable.
*/
contract VestingWallet {
event EtherReleased(uint256 amount);
event ERC20Released(address indexed token, uint256 amount);
address private _beneficiary;
uint64 private _start;
uint64 private _duration;
/**
* @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet.
*/
function VestingWallet_initialize(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) internal {
require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address");
_beneficiary = beneficiaryAddress;
_start = startTimestamp;
_duration = durationSeconds;
}
/**
* @dev Getter for the beneficiary address.
*/
function beneficiary() public view virtual returns (address) {
return _beneficiary;
}
/**
* @dev Getter for the start timestamp.
*/
function start() public view virtual returns (uint256) {
return _start;
}
/**
* @dev Getter for the vesting duration.
*/
function duration() public view virtual returns (uint256) {
return _duration;
}
/**
* @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(address(this).balance, timestamp);
}
/**
* @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(IERC20(token).balanceOf(address(this)), timestamp);
}
/**
* @dev Virtual implementation of the vesting formula. This returns the amout vested, as a function of time, for
* an asset given its total historical allocation.
*/
function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) {
if (timestamp >= start() + duration()) {
return totalAllocation;
}else{
return 0;
}
}
}
// File contracts/MultiSigWallet.sol
pragma solidity 0.8.7;
contract MultiSigWallet {
/*
* Events
*/
event Confirmation(address indexed sender, uint indexed transactionId);
event Revocation(address indexed sender, uint indexed transactionId);
event Submission(uint indexed transactionId);
event Execution(uint indexed transactionId);
event ExecutionFailure(uint indexed transactionId);
event Deposit(address indexed sender, uint value);
event OwnerAddition(address indexed owner);
event OwnerRemoval(address indexed owner);
event RequirementChange(uint required);
/*
* Constants
*/
uint constant public MAX_OWNER_COUNT = 50;
/*
* Storage
*/
mapping (uint => Transaction) public transactions;
mapping (uint => mapping (address => bool)) public confirmations;
mapping (address => bool) public isOwner;
address[] public owners;
uint public required;
uint public transactionCount;
struct Transaction {
address destination;
uint value;
bytes data;
bool executed;
}
/*
* Modifiers
*/
modifier onlyWallet() {
require(msg.sender == address(this));
_;
}
modifier ownerDoesNotExist(address owner) {
require(!isOwner[owner]);
_;
}
modifier ownerExists(address owner) {
require(isOwner[owner]);
_;
}
modifier transactionExists(uint transactionId) {
require(transactions[transactionId].destination != address(0));
_;
}
modifier confirmed(uint transactionId, address owner) {
require(confirmations[transactionId][owner]);
_;
}
modifier notConfirmed(uint transactionId, address owner) {
require(!confirmations[transactionId][owner]);
_;
}
modifier notExecuted(uint transactionId) {
require(!transactions[transactionId].executed);
_;
}
modifier notNull(address _address) {
require(_address != address(0));
_;
}
modifier validRequirement(uint ownerCount, uint _required) {
require(ownerCount <= MAX_OWNER_COUNT
&& _required <= ownerCount
&& _required != 0
&& ownerCount != 0);
_;
}
/// @dev Fallback function allows to deposit ether.
fallback()
external
payable
{
if (msg.value > 0)
emit Deposit(msg.sender, msg.value);
}
receive()
external
payable
{
if (msg.value > 0)
emit Deposit(msg.sender, msg.value);
}
/*
* Public functions
*/
/// @dev Contract constructor sets initial owners and required number of confirmations.
/// @param _owners List of initial owners.
/// @param _required Number of required confirmations.
function MultiSigWallet_initialize(address[] memory _owners, uint _required)
validRequirement(_owners.length, _required) internal
{
for (uint i=0; i<_owners.length; i++) {
require(!isOwner[_owners[i]] && _owners[i] != address(0));
isOwner[_owners[i]] = true;
}
owners = _owners;
required = _required;
}
/// @dev Allows to add a new owner. Transaction has to be sent by wallet.
/// @param owner Address of new owner.
function addOwner(address owner)
public
onlyWallet
ownerDoesNotExist(owner)
notNull(owner)
validRequirement(owners.length + 1, required)
{
isOwner[owner] = true;
owners.push(owner);
emit OwnerAddition(owner);
}
/// @dev Allows to remove an owner. Transaction has to be sent by wallet.
/// @param owner Address of owner.
function removeOwner(address owner)
public
onlyWallet
ownerExists(owner)
{
isOwner[owner] = false;
for (uint i=0; i<owners.length - 1; i++)
if (owners[i] == owner) {
owners[i] = owners[owners.length - 1];
break;
}
owners.pop();
if (required > owners.length)
changeRequirement(owners.length);
emit OwnerRemoval(owner);
}
/// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
/// @param owner Address of owner to be replaced.
/// @param newOwner Address of new owner.
function replaceOwner(address owner, address newOwner)
public
onlyWallet
ownerExists(owner)
ownerDoesNotExist(newOwner)
{
for (uint i=0; i<owners.length; i++)
if (owners[i] == owner) {
owners[i] = newOwner;
break;
}
isOwner[owner] = false;
isOwner[newOwner] = true;
emit OwnerRemoval(owner);
emit OwnerAddition(newOwner);
}
/// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
/// @param _required Number of required confirmations.
function changeRequirement(uint _required)
public
onlyWallet
validRequirement(owners.length, _required)
{
required = _required;
emit RequirementChange(_required);
}
/// @dev Allows an owner to submit and confirm a transaction.
/// @param destination Transaction target address.
/// @param value Transaction ether value.
/// @param data Transaction data payload.
/// @return transactionId Returns transaction ID.
function submitTransaction(address destination, uint value, bytes memory data)
public
returns (uint transactionId)
{
transactionId = addTransaction(destination, value, data);
confirmTransaction(transactionId);
}
/// @dev Allows an owner to confirm a transaction.
/// @param transactionId Transaction ID.
function confirmTransaction(uint transactionId)
public
virtual
ownerExists(msg.sender)
transactionExists(transactionId)
notConfirmed(transactionId, msg.sender)
{
confirmations[transactionId][msg.sender] = true;
emit Confirmation(msg.sender, transactionId);
executeTransaction(transactionId);
}
/// @dev Allows an owner to revoke a confirmation for a transaction.
/// @param transactionId Transaction ID.
function revokeConfirmation(uint transactionId)
public
ownerExists(msg.sender)
confirmed(transactionId, msg.sender)
notExecuted(transactionId)
{
confirmations[transactionId][msg.sender] = false;
emit Revocation(msg.sender, transactionId);
}
/// @dev Allows anyone to execute a confirmed transaction.
/// @param transactionId Transaction ID.
function executeTransaction(uint transactionId)
public
virtual
ownerExists(msg.sender)
confirmed(transactionId, msg.sender)
notExecuted(transactionId)
{
if (isConfirmed(transactionId)) {
Transaction storage txn = transactions[transactionId];
txn.executed = true;
if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
emit Execution(transactionId);
else {
emit ExecutionFailure(transactionId);
txn.executed = false;
}
}
}
// call has been separated into its own function in order to take advantage
// of the Solidity's code generator to produce a loop that copies tx.data into memory.
function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {
bool result;
assembly {
let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
result := call(
sub(gas(), 34710), // 34710 is the value that solidity is currently emitting
// It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
// callNewAccountGas (25000, in case the destination address does not exist and needs creating)
destination,
value,
d,
dataLength, // Size of the input (in bytes) - this is what fixes the padding problem
x,
0 // Output is ignored, therefore the output size is zero
)
}
return result;
}
/// @dev Returns the confirmation status of a transaction.
/// @param transactionId Transaction ID.
/// @return Confirmation status.
function isConfirmed(uint transactionId)
public
view
returns (bool)
{
uint count = 0;
for (uint i=0; i<owners.length; i++) {
if (confirmations[transactionId][owners[i]])
count += 1;
if (count == required)
return true;
}
return false;
}
/*
* Internal functions
*/
/// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
/// @param destination Transaction target address.
/// @param value Transaction ether value.
/// @param data Transaction data payload.
/// @return transactionId Returns transaction ID.
function addTransaction(address destination, uint value, bytes memory data)
internal
notNull(destination)
returns (uint transactionId)
{
transactionId = transactionCount;
transactions[transactionId] = Transaction({
destination: destination,
value: value,
data: data,
executed: false
});
transactionCount += 1;
emit Submission(transactionId);
}
/*
* Web3 call functions
*/
/// @dev Returns number of confirmations of a transaction.
/// @param transactionId Transaction ID.
/// @return count Number of confirmations.
function getConfirmationCount(uint transactionId)
public
view
returns (uint count)
{
for (uint i=0; i<owners.length; i++)
if (confirmations[transactionId][owners[i]])
count += 1;
}
/// @dev Returns total number of transactions after filers are applied.
/// @param pending Include pending transactions.
/// @param executed Include executed transactions.
/// @return count Total number of transactions after filters are applied.
function getTransactionCount(bool pending, bool executed)
public
view
returns (uint count)
{
for (uint i=0; i<transactionCount; i++)
if ( pending && !transactions[i].executed
|| executed && transactions[i].executed)
count += 1;
}
/// @dev Returns list of owners.
/// @return List of owner addresses.
function getOwners()
public
view
returns (address[] memory)
{
return owners;
}
/// @dev Returns array with owner addresses, which confirmed transaction.
/// @param transactionId Transaction ID.
/// @return _confirmations Returns array of owner addresses.
function getConfirmations(uint transactionId)
public
view
returns (address[] memory _confirmations)
{
address[] memory confirmationsTemp = new address[](owners.length);
uint count = 0;
uint i;
for (i=0; i<owners.length; i++)
if (confirmations[transactionId][owners[i]]) {
confirmationsTemp[count] = owners[i];
count += 1;
}
_confirmations = new address[](count);
for (i=0; i<count; i++)
_confirmations[i] = confirmationsTemp[i];
}
/// @dev Returns list of transaction IDs in defined range.
/// @param from Index start position of transaction array.
/// @param to Index end position of transaction array.
/// @param pending Include pending transactions.
/// @param executed Include executed transactions.
/// @return _transactionIds Returns array of transaction IDs.
function getTransactionIds(uint from, uint to, bool pending, bool executed)
public
view
returns (uint[] memory _transactionIds)
{
uint[] memory transactionIdsTemp = new uint[](transactionCount);
uint count = 0;
uint i;
for (i=0; i<transactionCount; i++)
if ( pending && !transactions[i].executed
|| executed && transactions[i].executed)
{
transactionIdsTemp[count] = i;
count += 1;
}
_transactionIds = new uint[](to - from);
for (i=from; i<to; i++)
_transactionIds[i - from] = transactionIdsTemp[i];
}
}
// File contracts/MultiSigVesting.sol
pragma solidity 0.8.7;
contract MultiSigVesting is MultiSigWallet,VestingWallet{
address public _tokenLp;
address public _token;
address private _wrei;
// address private _pool;
address private immutable _idopool;
constructor() {
_idopool = msg.sender;
}
function initialize(
address[] memory _owners,
uint256 _required,
uint64 _durationSeconds,
address _benefit,
uint64 _time,
address token,
address _lpAddr,
address wrei
) external {
require(msg.sender == _idopool,"only pool");
MultiSigWallet_initialize(_owners, _required);
VestingWallet_initialize(_benefit,_time,_durationSeconds);
_token = token;
_wrei = wrei;
_tokenLp = _lpAddr;
}
function releaseLp() public onlyWallet {
uint256 releasable = vestedAmount(_tokenLp, uint64(block.timestamp));
emit ERC20Released(_tokenLp, releasable);
SafeERC20.safeTransfer(IERC20(_tokenLp), beneficiary(), releasable);
}
function release(uint256 _amount) public onlyWallet {
uint256 value;
require(start() < block.timestamp,"end!");
if(_token == _wrei) {
value = address(this).balance;
require(_amount <= value,"amount lt balanceOf");
payable(beneficiary()).transfer(_amount);
}else{
value = IERC20(_token).balanceOf(address(this));
require(_amount <= value,"amount lt balanceOf");
IERC20(_token).transfer(beneficiary(), _amount);
}
emit EtherReleased(_amount);
}
}
// File contracts/libraries/IDOData.sol
pragma solidity 0.8.7;
library IDOData {
struct IDOinput {
address _addr;
uint256 _tokenPrice;
uint256 _pairPrice;
uint256 _targetAmount;
IERC20 _srcToken;
IERC20 _rewardToken;
uint256 _startTimestamp;
uint256 _finishTimestamp;
uint256 _perMaxDistributedTokenAmount;
address _rei;
address _factory;
address _router;
}
}
// File contracts/IDOPool.sol
pragma solidity 0.8.7;
interface IERC20Detail {
function decimals() external view returns (uint8);
}
interface IRouter{
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}
interface IFactory{
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IMultiSigVest{
function initialize(
address[] memory _owners,
uint256 _required,
uint64 _durationSeconds,
address _benefit,
uint64 _time,
address token,
address _lpAddr,
address wrei
) external;
}
contract IDOPool is ReentrancyGuard{
using SafeMath for uint256;
using SafeERC20 for IERC20;
address public owner;
uint256 public tokenPrice;
IERC20 public sellToken;
IERC20 public rewardToken;
uint256 public buyDecimals;
uint256 public sellDecimals;
uint256 public startTimestamp;
uint256 public finishTimestamp;
uint256 public maxDistributedTokenAmount;
uint256 public perMaxDistributedTokenAmount;
uint256 public tokensForDistribution;
bool public finish;
address private wrei;
IRouter private router;
IFactory private factory;
address private dao;
uint256 private pairPrice;
address[] public signAddrs = [0x06677520c1449D9977E7A245f0797A65e7efF219,0xb9EB39C42d0E9f4966d411bDfBfc711235945936,0xA551a1683FF764a4F5Ff143f57206067fF29fAc5];
uint64 private constant periors = 31536000;
uint256 public interval;
uint256 public duration;
uint256 public start;
struct Vesting {
uint256 balance;
uint256 released;
}
mapping (address => Vesting) private _vestings;
event TokensSell(
address indexed holder,
uint256 ethAmount,
uint256 tokenAmount
);
event Released(uint256 amount);
event MultiSigVestingEvent(address multiSigVesting,address sender,uint256 amount);
constructor(
IDOData.IDOinput memory input
) {
owner = input._addr;
tokenPrice = input._tokenPrice;
sellToken = input._srcToken;
rewardToken = input._rewardToken;
sellDecimals = IERC20Detail(address(sellToken)).decimals();
pairPrice = input._pairPrice;
wrei = input._rei;
router = IRouter(input._router);
factory = IFactory(input._factory);
maxDistributedTokenAmount = input._targetAmount;
perMaxDistributedTokenAmount = input._perMaxDistributedTokenAmount;
require(
input._startTimestamp < input._finishTimestamp,
"Start number must be less than finish number"
);
require(
input._finishTimestamp > block.timestamp,
"Finish number must be more than current block"
);
startTimestamp = input._startTimestamp;
finishTimestamp = input._finishTimestamp;
interval = 86400;
duration = 31536000;
start = finishTimestamp;
}
function pay() payable external nonReentrant{
require(address(rewardToken) == wrei,"payREI:Not Rei");
require(block.timestamp >= startTimestamp, "payREI:Not started");
require(block.timestamp < finishTimestamp, "payREI:Ended");
require(!finish,"payREI:Finished");
uint256 amount = msg.value;
uint256 tokenAmount = getTokenAmount(amount);
require(perMaxDistributedTokenAmount >= tokenAmount,"payREI: perMaxDistributedTokenAmount");
if(tokensForDistribution.add(amount) > maxDistributedTokenAmount) {
finish = true;
payable(msg.sender).transfer(amount.sub(maxDistributedTokenAmount.sub(tokensForDistribution)));
amount = maxDistributedTokenAmount.sub(tokensForDistribution);
}
tokensForDistribution = tokensForDistribution.add(amount);
tokenAmount = getTokenAmount(amount);
createVesting(msg.sender,tokenAmount);
if(finish){
dealFinish();
}
emit TokensSell(msg.sender, amount, tokenAmount);
}
function pay(uint256 _amount) external nonReentrant {
require(block.timestamp >= startTimestamp, "pay:Not started");
require(block.timestamp < finishTimestamp, "pay:ended");
require(!finish,"payREI:Finished");
uint256 tokenAmount = getTokenAmount(_amount);
require(perMaxDistributedTokenAmount >= tokenAmount,"payREI: perMaxDistributedTokenAmount");
if(tokensForDistribution.add(_amount) >= maxDistributedTokenAmount) {
finish = true;
_amount = maxDistributedTokenAmount.sub(tokensForDistribution);
}
tokensForDistribution = tokensForDistribution.add(_amount);
rewardToken.safeTransferFrom(msg.sender, address(address(this)), _amount);
tokenAmount = getTokenAmount(_amount);
createVesting(msg.sender,tokenAmount);
if(finish){
dealFinish();
}
emit TokensSell(msg.sender, _amount, tokenAmount);
}
function getTokenAmount(uint256 amount)
internal
view
returns (uint256)
{
return amount.mul(10**sellDecimals).div(tokenPrice);
}
function finished() public nonReentrant {
require(block.timestamp > finishTimestamp, "pay:Not started");
require(!finish,"already finished");
dealFinish();
}
function dealFinish() private {
bytes32 salt = keccak256(abi.encodePacked(owner, rewardToken,sellToken));
bytes memory bytecode = type(MultiSigVesting).creationCode;
address multiSigVestAddr = Create2.deploy(0, salt, bytecode);
address lpToken;
if(address(rewardToken) == wrei) {
uint256 value = address(this).balance;
uint256 amountBDesired = value.mul(20).div(100).mul(10**sellDecimals).div(pairPrice);
sellToken.safeApprove(address(router),amountBDesired);
(,,uint liquidity) = router.addLiquidityETH{value:value.mul(20).div(100)}(address(sellToken),amountBDesired,0,0,address(multiSigVestAddr),uint64(block.timestamp));
lpToken = factory.getPair(wrei,address(sellToken));
emit MultiSigVestingEvent(address(multiSigVestAddr),owner,liquidity);
payable(multiSigVestAddr).transfer(value.mul(80).div(100));
}else{
uint256 amountADesired = rewardToken.balanceOf(address(this));
uint256 amountBDesired = amountADesired.mul(20).div(100).mul(10**sellDecimals).div(pairPrice);
rewardToken.safeApprove(address(router),amountADesired);
sellToken.safeApprove(address(router),amountBDesired);
(,,uint liquidity) = router.addLiquidity(address(rewardToken),address(sellToken),amountADesired.mul(20).div(100),amountBDesired,0,0,address(multiSigVestAddr),uint64(block.timestamp));
lpToken = factory.getPair(address(rewardToken),address(sellToken));
rewardToken.safeTransfer(address(multiSigVestAddr),amountADesired.mul(80).div(100));
emit MultiSigVestingEvent(address(multiSigVestAddr),owner,liquidity);
}
IMultiSigVest(multiSigVestAddr).initialize(signAddrs,2,periors,owner,uint64(block.timestamp),address(rewardToken),lpToken,wrei);
}
function createVesting(
address beneficiary,
uint256 amount
) private {
require(interval > 0 , "TokenVesting #createVesting: interval must be greater than 0");
require(duration >= interval, "TokenVesting #createVesting: interval cannot be bigger than duration");
Vesting storage vest = _vestings[beneficiary];
vest.balance = vest.balance.add(amount);
}
function getInfo(address beneficiary) public view returns (uint256, uint256, uint256) {
Vesting memory v = _vestings[beneficiary];
return (v.balance+v.released,releasableAmount(beneficiary),v.released);
}
function release(address beneficiary) external {
uint256 unreleased = releasableAmount(beneficiary);
require(unreleased > 0, "TokenVesting #release: nothing to release");
Vesting storage vest = _vestings[beneficiary];
vest.released = vest.released.add(unreleased);
vest.balance = vest.balance.sub(unreleased);
sellToken.safeTransfer(beneficiary, unreleased);
emit Released(unreleased);
}
function releasableAmount(address beneficiary) public view returns (uint256) {
return vestedAmount(beneficiary).sub(_vestings[beneficiary].released);
}
function vestedAmount(address beneficiary) public view returns (uint256) {
Vesting memory vest = _vestings[beneficiary];
uint256 currentBalance = vest.balance;
uint256 totalBalance = currentBalance.add(vest.released);
if(start > block.timestamp) {
return 0;
}
if (block.timestamp >= start.add(duration)) {
return totalBalance;
} else {
uint256 numberOfInvervals = block.timestamp.sub(start).div(interval);
uint256 totalIntervals = duration.div(interval);
return totalBalance.mul(numberOfInvervals).div(totalIntervals);
}
}
}
// File contracts/IDOMaster.sol
pragma solidity 0.8.7;
contract IDOMaster {
using SafeMath for uint256;
using SafeERC20 for IERC20;
uint256 private count;
struct itemsInfo {
address owner;
address idoPool;
uint256 tokenPrice;
uint256 targetAmount;
address srcToken;
address rewardToken;
uint256 startTimestamp;
uint256 finishTimestamp;
uint256 perMaxDistributedTokenAmount;
}
mapping(uint256=>itemsInfo) private itemsInfos;
event IDOCreated(address owner, address idoPool,
uint256 tokenPrice,
uint256 targetAmount,
address srcToken,
address rewardToken,
uint256 startTimestamp,
uint256 finishTimestamp,
uint256 perMaxDistributedTokenAmount
);
function createIDO(
IDOData.IDOinput calldata input
) external {
IDOPool idoPool =
new IDOPool(
input
);
transferAmount(input._targetAmount,input._tokenPrice,input._pairPrice,input._srcToken,address(idoPool));
emit IDOCreated(input._addr,
address(idoPool),
input._tokenPrice,
input._targetAmount,
address(input._srcToken),
address(input._rewardToken),
input._startTimestamp,
input._finishTimestamp,
input._perMaxDistributedTokenAmount);
itemsInfos[count] = itemsInfo ({
owner: input._addr,
idoPool: address(idoPool),
tokenPrice: input._tokenPrice,
targetAmount: input._targetAmount,
srcToken: address(input._srcToken),
rewardToken: address(input._rewardToken),
startTimestamp: input._startTimestamp,
finishTimestamp: input._finishTimestamp,
perMaxDistributedTokenAmount:input._perMaxDistributedTokenAmount
});
count++;
}
function getItemCount() external view returns(uint256){
return count;
}
function getItemInfo(uint256 index) external view returns(itemsInfo memory ){
return itemsInfos[index];
}
function transferAmount(uint256 _targetAmount,uint256 _tokenPrice,uint256 _pairPrice,IERC20 _srcToken,address _idoPool) private {
uint256 amount = _targetAmount.mul(10**18).div(_tokenPrice).add(_targetAmount.mul(10**18).mul(20).div(100).div(_pairPrice));
_srcToken.safeTransferFrom(
msg.sender,
_idoPool,
amount
);
}
}
Contract ABI
[{"type":"event","name":"IDOCreated","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"address","name":"idoPool","internalType":"address","indexed":false},{"type":"uint256","name":"tokenPrice","internalType":"uint256","indexed":false},{"type":"uint256","name":"targetAmount","internalType":"uint256","indexed":false},{"type":"address","name":"srcToken","internalType":"address","indexed":false},{"type":"address","name":"rewardToken","internalType":"address","indexed":false},{"type":"uint256","name":"startTimestamp","internalType":"uint256","indexed":false},{"type":"uint256","name":"finishTimestamp","internalType":"uint256","indexed":false},{"type":"uint256","name":"perMaxDistributedTokenAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createIDO","inputs":[{"type":"tuple","name":"input","internalType":"struct IDOData.IDOinput","components":[{"type":"address","name":"_addr","internalType":"address"},{"type":"uint256","name":"_tokenPrice","internalType":"uint256"},{"type":"uint256","name":"_pairPrice","internalType":"uint256"},{"type":"uint256","name":"_targetAmount","internalType":"uint256"},{"type":"address","name":"_srcToken","internalType":"contract IERC20"},{"type":"address","name":"_rewardToken","internalType":"contract IERC20"},{"type":"uint256","name":"_startTimestamp","internalType":"uint256"},{"type":"uint256","name":"_finishTimestamp","internalType":"uint256"},{"type":"uint256","name":"_perMaxDistributedTokenAmount","internalType":"uint256"},{"type":"address","name":"_rei","internalType":"address"},{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_router","internalType":"address"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getItemCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IDOMaster.itemsInfo","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"idoPool","internalType":"address"},{"type":"uint256","name":"tokenPrice","internalType":"uint256"},{"type":"uint256","name":"targetAmount","internalType":"uint256"},{"type":"address","name":"srcToken","internalType":"address"},{"type":"address","name":"rewardToken","internalType":"address"},{"type":"uint256","name":"startTimestamp","internalType":"uint256"},{"type":"uint256","name":"finishTimestamp","internalType":"uint256"},{"type":"uint256","name":"perMaxDistributedTokenAmount","internalType":"uint256"}]}],"name":"getItemInfo","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b506152b6806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c8063707f507c146200004b5780637749cf231462000064578063de7fe3e7146200007a575b600080fd5b620000626200005c3660046200087f565b6200010b565b005b6000546040519081526020015b60405180910390f35b620000916200008b36600462000899565b6200039f565b60405162000071919081516001600160a01b039081168252602080840151821690830152604080840151908301526060808401519083015260808084015182169083015260a0808401519091169082015260c0808301519082015260e0808301519082015261010091820151918101919091526101200190565b6000816040516200011c906200081b565b62000128919062000906565b604051809103906000f08015801562000145573d6000803e3d6000fd5b509050620001746060830135602084013560408501356200016d60a08701608088016200083b565b856200049d565b7fdf28fe625edaab14d82ac291ae937512fc672b0977357600f5f48a68209aa599620001a460208401846200083b565b8260208501356060860135620001c160a08801608089016200083b565b620001d360c0890160a08a016200083b565b604080516001600160a01b039788168152958716602087015285019390935260608401919091528316608083015290911660a082015260c0848101359082015260e0808501359082015261010080850135908201526101200160405180910390a1604080516101208101909152806200025060208501856200083b565b6001600160a01b03168152602001826001600160a01b0316815260200183602001358152602001836060013581526020018360800160208101906200029691906200083b565b6001600160a01b03168152602001620002b660c0850160a086016200083b565b6001600160a01b03908116825260c08581013560208085019190915260e080880135604080870191909152610100808a013560609788015260008054815260018086528382208a5181546001600160a01b0319908116918b16919091178255968b015191810180548816928a16929092179091559289015160028401559688015160038301556080880151600483018054861691881691909117905560a088015160058301805490951696169590951790925591850151600682015590840151600782015592015160089092019190915580549080620003968362000a8a565b91905055505050565b6200041360405180610120016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b5060009081526001602081815260409283902083516101208101855281546001600160a01b0390811682529382015484169281019290925260028101549382019390935260038301546060820152600483015482166080820152600583015490911660a0820152600682015460c0820152600782015460e082015260089091015461010082015290565b6000620004f3620004d385620004cc6064816014620004c58d670de0b6b3a764000062000514565b9062000514565b9062000529565b620004ec87620004cc8a670de0b6b3a764000062000514565b9062000537565b90506200050c6001600160a01b03841633848462000545565b505050505050565b600062000522828462000a39565b9392505050565b600062000522828462000a16565b6000620005228284620009fb565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052620005a1908590620005a7565b50505050565b6000620005fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620006899092919063ffffffff16565b8051909150156200068457808060200190518101906200061f91906200085b565b620006845760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b505050565b60606200069a8484600085620006a2565b949350505050565b606082471015620007055760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200067b565b6001600160a01b0385163b6200075e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200067b565b600080866001600160a01b031685876040516200077c9190620008b3565b60006040518083038185875af1925050503d8060008114620007bb576040519150601f19603f3d011682016040523d82523d6000602084013e620007c0565b606091505b5091509150620007d2828286620007dd565b979650505050505050565b60608315620007ee57508162000522565b825115620007ff5782518084602001fd5b8160405162461bcd60e51b81526004016200067b9190620008d1565b6147a98062000ad883390190565b8035620008368162000abe565b919050565b6000602082840312156200084e57600080fd5b8135620005228162000abe565b6000602082840312156200086e57600080fd5b815180151581146200052257600080fd5b600061018082840312156200089357600080fd5b50919050565b600060208284031215620008ac57600080fd5b5035919050565b60008251620008c781846020870162000a5b565b9190910192915050565b6020815260008251806020840152620008f281604085016020870162000a5b565b601f01601f19169190910160400192915050565b610180810162000928826200091b8562000829565b6001600160a01b03169052565b602083013560208301526040830135604083015260608301356060830152620009546080840162000829565b6001600160a01b031660808301526200097060a0840162000829565b6001600160a01b031660a083015260c0838101359083015260e080840135908301526101008084013590830152610120620009ad81850162000829565b6001600160a01b031690830152610140620009ca84820162000829565b6001600160a01b031690830152610160620009e784820162000829565b6001600160a01b0316920191909152919050565b6000821982111562000a115762000a1162000aa8565b500190565b60008262000a3457634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161562000a565762000a5662000aa8565b500290565b60005b8381101562000a7857818101518382015260200162000a5e565b83811115620005a15750506000910152565b600060001982141562000aa15762000aa162000aa8565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000ad457600080fd5b5056fe60e06040527306677520c1449d9977e7a245f0797a65e7eff219608090815273b9eb39c42d0e9f4966d411bdfbfc71123594593660a05273a551a1683ff764a4f5ff143f57206067ff29fac560c0526200005e906011906003620002d2565b503480156200006c57600080fd5b50604051620047a9380380620047a98339810160408190526200008f9162000370565b60016000819055815181546001600160a01b039182166001600160a01b0319918216179092556020808401516002556080840151600380549184169185168217905560a0850151600480549190941694169390931782556040805163313ce56760e01b8152905163313ce567938281019392829003018186803b1580156200011657600080fd5b505afa1580156200012b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000151919062000442565b60ff166006556040810151601055610120810151600c80546001600160a01b03928316610100908102610100600160a81b031990921691909117909155610160830151600d80549184166001600160a01b0319928316179055610140840151600e8054919094169116179091556060820151600955810151600a5560e081015160c0820151106200023e5760405162461bcd60e51b815260206004820152602c60248201527f5374617274206e756d626572206d757374206265206c657373207468616e206660448201526b34b734b9b410373ab6b132b960a11b60648201526084015b60405180910390fd5b428160e0015111620002a95760405162461bcd60e51b815260206004820152602d60248201527f46696e697368206e756d626572206d757374206265206d6f7265207468616e2060448201526c63757272656e7420626c6f636b60981b606482015260840162000235565b60c081015160075560e001516008819055620151806012556301e13380601355601455620004a6565b8280548282559060005260206000209081019282156200032a579160200282015b828111156200032a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620002f3565b50620003389291506200033c565b5090565b5b808211156200033857600081556001016200033d565b80516001600160a01b03811681146200036b57600080fd5b919050565b600061018082840312156200038457600080fd5b6200038e6200046e565b620003998362000353565b8152602083015160208201526040830151604082015260608301516060820152620003c76080840162000353565b6080820152620003da60a0840162000353565b60a082015260c083015160c082015260e083015160e08201526101008084015181830152506101206200040f81850162000353565b908201526101406200042384820162000353565b908201526101606200043784820162000353565b908201529392505050565b6000602082840312156200045557600080fd5b815160ff811681146200046757600080fd5b9392505050565b60405161018081016001600160401b0381118282101715620004a057634e487b7160e01b600052604160045260246000fd5b60405290565b6142f380620004b66000396000f3fe6080604052600436106101405760003560e01c8063947a36fb116100b6578063d56b28891161006f578063d56b28891461031f578063d6df2e5814610349578063e0ee43a21461035f578063e6fd48bc14610375578063f7c618c11461038b578063ffdd5cf1146103ab57600080fd5b8063947a36fb1461027e5780639769f0b014610294578063be9a6555146102b4578063bef4876b146102ca578063c290d691146102df578063c8d88871146102ff57600080fd5b8063384711cc11610108578063384711cc146101ce57806343d7d321146101ee57806349c08238146102045780634b1a4c0c1461021a5780637ff9b596146102305780638da5cb5b1461024657600080fd5b80630fb5a6b4146101455780631726cbc81461016e578063191655871461018e5780631b9265b8146101b05780632382f645146101b8575b600080fd5b34801561015157600080fd5b5061015b60135481565b6040519081526020015b60405180910390f35b34801561017a57600080fd5b5061015b6101893660046117bb565b6103e6565b34801561019a57600080fd5b506101ae6101a93660046117bb565b61041b565b005b6101ae610518565b3480156101c457600080fd5b5061015b600a5481565b3480156101da57600080fd5b5061015b6101e93660046117bb565b61078d565b3480156101fa57600080fd5b5061015b60085481565b34801561021057600080fd5b5061015b60065481565b34801561022657600080fd5b5061015b600b5481565b34801561023c57600080fd5b5061015b60025481565b34801561025257600080fd5b50600154610266906001600160a01b031681565b6040516001600160a01b039091168152602001610165565b34801561028a57600080fd5b5061015b60125481565b3480156102a057600080fd5b50600354610266906001600160a01b031681565b3480156102c057600080fd5b5061015b60145481565b3480156102d657600080fd5b506101ae61085d565b3480156102eb57600080fd5b506101ae6102fa366004611817565b61091d565b34801561030b57600080fd5b5061026661031a366004611817565b610a9f565b34801561032b57600080fd5b50600c546103399060ff1681565b6040519015158152602001610165565b34801561035557600080fd5b5061015b60055481565b34801561036b57600080fd5b5061015b60095481565b34801561038157600080fd5b5061015b60075481565b34801561039757600080fd5b50600454610266906001600160a01b031681565b3480156103b757600080fd5b506103cb6103c63660046117bb565b610ac9565b60408051938452602084019290925290820152606001610165565b6001600160a01b0381166000908152601560205260408120600101546104159061040f8461078d565b90610b27565b92915050565b6000610426826103e6565b90506000811161048f5760405162461bcd60e51b815260206004820152602960248201527f546f6b656e56657374696e67202372656c656173653a206e6f7468696e6720746044820152686f2072656c6561736560b81b60648201526084015b60405180910390fd5b6001600160a01b038216600090815260156020526040902060018101546104b69083610b3a565b600182015580546104c79083610b27565b81556003546104e0906001600160a01b03168484610b46565b6040518281527ffb81f9b30d73d830c3544b34d827c08142579ee75710b490bab0b3995468c5659060200160405180910390a1505050565b6002600054141561053b5760405162461bcd60e51b8152600401610486906119a1565b6002600055600c546004546001600160a01b0390811661010090920416146105965760405162461bcd60e51b815260206004820152600e60248201526d7061795245493a4e6f742052656960901b6044820152606401610486565b6007544210156105dd5760405162461bcd60e51b81526020600482015260126024820152711c185e5491524e939bdd081cdd185c9d195960721b6044820152606401610486565b600854421061061d5760405162461bcd60e51b815260206004820152600c60248201526b1c185e5491524e915b99195960a21b6044820152606401610486565b600c5460ff16156106625760405162461bcd60e51b815260206004820152600f60248201526e1c185e5491524e919a5b9a5cda1959608a1b6044820152606401610486565b34600061066e82610bae565b905080600a5410156106925760405162461bcd60e51b81526004016104869061195d565b600954600b546106a29084610b3a565b111561071157600c805460ff19166001179055600b5460095433916108fc916106d6916106cf9190610b27565b8590610b27565b6040518115909202916000818181858888f193505050501580156106fe573d6000803e3d6000fd5b50600b5460095461070e91610b27565b91505b600b5461071e9083610b3a565b600b5561072a82610bae565b90506107363382610bcf565b600c5460ff161561074957610749610cf9565b604080518381526020810183905233917fba7a32849fb0a371567222ea0cb62b2055fead07c17efb43d99728b10f09d699910160405180910390a250506001600055565b6001600160a01b038116600090815260156020908152604080832081518083019092528054808352600190910154928201839052909183906107d0908390610b3a565b90504260145411156107e757506000949350505050565b6013546014546107f691610b3a565b421061080457949350505050565b600061082760125461082160145442610b2790919063ffffffff16565b90611354565b9050600061084260125460135461135490919063ffffffff16565b9050610852816108218585611360565b979650505050505050565b600260005414156108805760405162461bcd60e51b8152600401610486906119a1565b600260005560085442116108c85760405162461bcd60e51b815260206004820152600f60248201526e1c185e4e939bdd081cdd185c9d1959608a1b6044820152606401610486565b600c5460ff161561090e5760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48199a5b9a5cda195960821b6044820152606401610486565b610916610cf9565b6001600055565b600260005414156109405760405162461bcd60e51b8152600401610486906119a1565b60026000556007544210156109895760405162461bcd60e51b815260206004820152600f60248201526e1c185e4e939bdd081cdd185c9d1959608a1b6044820152606401610486565b60085442106109c65760405162461bcd60e51b81526020600482015260096024820152681c185e4e995b99195960ba1b6044820152606401610486565b600c5460ff1615610a0b5760405162461bcd60e51b815260206004820152600f60248201526e1c185e5491524e919a5b9a5cda1959608a1b6044820152606401610486565b6000610a1682610bae565b905080600a541015610a3a5760405162461bcd60e51b81526004016104869061195d565b600954600b54610a4a9084610b3a565b10610a6e57600c805460ff19166001179055600b54600954610a6b91610b27565b91505b600b54610a7b9083610b3a565b600b55600454610a96906001600160a01b031633308561136c565b61072a82610bae565b60118181548110610aaf57600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b0381166000908152601560209081526040808320815180830190925280548083526001909101549282018390528392839291610b0c91906119d8565b610b15866103e6565b60209092015190969195509350915050565b6000610b338284611b1c565b9392505050565b6000610b3382846119d8565b6040516001600160a01b038316602482015260448101829052610ba990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526113aa565b505050565b6000610415600254610821600654600a610bc89190611a55565b8590611360565b600060125411610c475760405162461bcd60e51b815260206004820152603c60248201527f546f6b656e56657374696e67202363726561746556657374696e673a20696e7460448201527f657276616c206d7573742062652067726561746572207468616e2030000000006064820152608401610486565b6012546013541015610ccf5760405162461bcd60e51b8152602060048201526044602482018190527f546f6b656e56657374696e67202363726561746556657374696e673a20696e74908201527f657276616c2063616e6e6f7420626520626967676572207468616e20647572616064820152633a34b7b760e11b608482015260a401610486565b6001600160a01b03821660009081526015602052604090208054610cf39083610b3a565b90555050565b6001546004546003546040516bffffffffffffffffffffffff19606094851b8116602083015292841b83166034820152921b166048820152600090605c01604051602081830303815290604052805190602001209050600060405180602001610d61906117ae565b601f1982820381018352601f9091011660405290506000610d8381848461147c565b600c546004549192506000916001600160a01b03908116610100909204161415610ffb5760004790506000610ddc601054610821600654600a610dc69190611a55565b610dd66064610821886014611360565b90611360565b600d54600354919250610dfc916001600160a01b03908116911683611586565b600d546000906001600160a01b031663f305d719610e206064610821876014611360565b60035460405160e084901b6001600160e01b03191681526001600160a01b039182166004820152602481018790526000604482018190526064820152908916608482015267ffffffffffffffff421660a482015260c4016060604051808303818588803b158015610e9057600080fd5b505af1158015610ea4573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ec99190611849565b600e54600c5460035460405163e6a4390560e01b81526001600160a01b0361010090930483166004820152908216602482015292955016925063e6a43905915060440160206040518083038186803b158015610f2457600080fd5b505afa158015610f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5c91906117d8565b600154604080516001600160a01b03808a168252909216602083015281018390529094507f6443c245157515cfcdd90c76a3e200a6736156f16241f7237ff1810282f349bb9060600160405180910390a16001600160a01b0385166108fc610fca6064610821876050611360565b6040518115909202916000818181858888f19350505050158015610ff2573d6000803e3d6000fd5b505050506112c8565b600480546040516370a0823160e01b815230928101929092526000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561104457600080fd5b505afa158015611058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107c9190611830565b90506000611098601054610821600654600a610dc69190611a55565b600d546004549192506110b8916001600160a01b03908116911684611586565b600d546003546110d5916001600160a01b03918216911683611586565b600d546004546003546000926001600160a01b039081169263e8e337009290821691166111086064610821896014611360565b6040516001600160e01b031960e086901b1681526001600160a01b039384166004820152918316602483015260448201526064810186905260006084820181905260a482015290881660c482015267ffffffffffffffff421660e482015261010401606060405180830381600087803b15801561118457600080fd5b505af1158015611198573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111bc9190611849565b600e546004805460035460405163e6a4390560e01b81526001600160a01b0392831693810193909352811660248301529295509116925063e6a43905915060440160206040518083038186803b15801561121557600080fd5b505afa158015611229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124d91906117d8565b9350611276856112636064610821876050611360565b6004546001600160a01b03169190610b46565b600154604080516001600160a01b038089168252909216602083015281018290527f6443c245157515cfcdd90c76a3e200a6736156f16241f7237ff1810282f349bb9060600160405180910390a15050505b60015460048054600c5460405163cf5bf23f60e01b81526001600160a01b038088169563cf5bf23f9561131c956011956002956301e1338095948516944294938116938d9361010090049091169101611893565b600060405180830381600087803b15801561133657600080fd5b505af115801561134a573d6000803e3d6000fd5b5050505050505050565b6000610b3382846119f0565b6000610b338284611afd565b6040516001600160a01b03808516602483015283166044820152606481018290526113a49085906323b872dd60e01b90608401610b72565b50505050565b60006113ff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116aa9092919063ffffffff16565b805190915015610ba9578080602001905181019061141d91906117f5565b610ba95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610486565b600080844710156114cf5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610486565b825161151d5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610486565b8383516020850187f590506001600160a01b03811661157e5760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610486565b949350505050565b80158061160f5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156115d557600080fd5b505afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190611830565b155b61167a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610486565b6040516001600160a01b038316602482015260448101829052610ba990849063095ea7b360e01b90606401610b72565b606061157e8484600085856001600160a01b0385163b61170c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610486565b600080866001600160a01b031685876040516117289190611877565b60006040518083038185875af1925050503d8060008114611765576040519150601f19603f3d011682016040523d82523d6000602084013e61176a565b606091505b509150915061085282828660608315611784575081610b33565b8251156117945782518084602001fd5b8160405162461bcd60e51b8152600401610486919061192a565b61273080611b8e83390190565b6000602082840312156117cd57600080fd5b8135610b3381611b75565b6000602082840312156117ea57600080fd5b8151610b3381611b75565b60006020828403121561180757600080fd5b81518015158114610b3357600080fd5b60006020828403121561182957600080fd5b5035919050565b60006020828403121561184257600080fd5b5051919050565b60008060006060848603121561185e57600080fd5b8351925060208401519150604084015190509250925092565b60008251611889818460208701611b33565b9190910192915050565b610100808252895490820181905260008a815260208082209192610120850192845b828110156118da5781546001600160a01b0316855293830193600191820191016118b5565b5050508301999099525067ffffffffffffffff96871660408201526001600160a01b03958616606082015293909516608084015290831660a0830152821660c0820152911660e090910152919050565b6020815260008251806020840152611949816040850160208701611b33565b601f01601f19169190910160400192915050565b60208082526024908201527f7061795245493a207065724d61784469737472696275746564546f6b656e416d6040820152631bdd5b9d60e21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082198211156119eb576119eb611b5f565b500190565b600082611a0d57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115611a4d578160001904821115611a3357611a33611b5f565b80851615611a4057918102915b93841c9390800290611a17565b509250929050565b6000610b338383600082611a6b57506001610415565b81611a7857506000610415565b8160018114611a8e5760028114611a9857611ab4565b6001915050610415565b60ff841115611aa957611aa9611b5f565b50506001821b610415565b5060208310610133831016604e8410600b8410161715611ad7575081810a610415565b611ae18383611a12565b8060001904821115611af557611af5611b5f565b029392505050565b6000816000190483118215151615611b1757611b17611b5f565b500290565b600082821015611b2e57611b2e611b5f565b500390565b60005b83811015611b4e578181015183820152602001611b36565b838111156113a45750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114611b8a57600080fd5b5056fe60a060405234801561001057600080fd5b5033606081901b6080526126fe61003260003960006115ce01526126fe6000f3fe6080604052600436106101dc5760003560e01c80639ace38c211610102578063c642747411610095578063dc8452cd11610064578063dc8452cd14610625578063e20056e61461063b578063ecd0c0c31461065b578063ee22610b1461067b57610220565b8063c6427474146105a9578063cf5bf23f146105c9578063d6c3179d146105e9578063d74f8edd1461061057610220565b8063b77bf600116100d1578063b77bf6001461052e578063ba51a6df14610544578063be9a655514610564578063c01a8c841461058957610220565b80639ace38c21461048f578063a0e67e2b146104bf578063a8abe69a146104e1578063b5dc40c31461050e57610220565b806337bdc99b1161017a5780637065cb48116101495780637065cb481461040f578063784547a71461042f578063810ec23b1461044f5780638b51d13f1461046f57610220565b806337bdc99b1461039c57806338af3eed146103bc57806343ad92d5146103da57806354741525146103ef57610220565b8063173825d9116101b6578063173825d9146102e157806320ea8d86146103015780632f54bf6e146103215780633411c81c1461036157610220565b8063025e7c27146102585780630a17b06b146102955780630fb5a6b4146102c357610220565b3661022057341561021e5760405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c906020015b60405180910390a25b005b341561021e5760405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90602001610215565b34801561026457600080fd5b506102786102733660046123af565b61069b565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102a157600080fd5b506102b56102b036600461244e565b6106c5565b60405190815260200161028c565b3480156102cf57600080fd5b506007546001600160401b03166102b5565b3480156102ed57600080fd5b5061021e6102fc36600461210e565b6106d7565b34801561030d57600080fd5b5061021e61031c3660046123af565b61088e565b34801561032d57600080fd5b5061035161033c36600461210e565b60026020526000908152604090205460ff1681565b604051901515815260200161028c565b34801561036d57600080fd5b5061035161037c3660046123e1565b600160209081526000928352604080842090915290825290205460ff1681565b3480156103a857600080fd5b5061021e6103b73660046123af565b610944565b3480156103c857600080fd5b506006546001600160a01b0316610278565b3480156103e657600080fd5b5061021e610bec565b3480156103fb57600080fd5b506102b561040a366004612376565b610c95565b34801561041b57600080fd5b5061021e61042a36600461210e565b610d12565b34801561043b57600080fd5b5061035161044a3660046123af565b610e2b565b34801561045b57600080fd5b506102b561046a36600461220a565b610eca565b34801561047b57600080fd5b506102b561048a3660046123af565b610f55565b34801561049b57600080fd5b506104af6104aa3660046123af565b610fdb565b60405161028c94939291906124b1565b3480156104cb57600080fd5b506104d4611099565b60405161028c91906124eb565b3480156104ed57600080fd5b506105016104fc366004612404565b6110fb565b60405161028c9190612538565b34801561051a57600080fd5b506104d46105293660046123af565b611291565b34801561053a57600080fd5b506102b560055481565b34801561055057600080fd5b5061021e61055f3660046123af565b611467565b34801561057057600080fd5b50600654600160a01b90046001600160401b03166102b5565b34801561059557600080fd5b5061021e6105a43660046123af565b6114e4565b3480156105b557600080fd5b506102b56105c436600461215c565b6115ab565b3480156105d557600080fd5b5061021e6105e4366004612234565b6115c3565b3480156105f557600080fd5b5060075461027890600160401b90046001600160a01b031681565b34801561061c57600080fd5b506102b5603281565b34801561063157600080fd5b506102b560045481565b34801561064757600080fd5b5061021e610656366004612129565b611698565b34801561066757600080fd5b50600854610278906001600160a01b031681565b34801561068757600080fd5b5061021e6106963660046123af565b61182b565b600381815481106106ab57600080fd5b6000918252602090912001546001600160a01b0316905081565b60006106d147836119ee565b92915050565b3330146106e357600080fd5b6001600160a01b038116600090815260026020526040902054819060ff1661070a57600080fd5b6001600160a01b0382166000908152600260205260408120805460ff191690555b60035461073a906001906125cb565b81101561080a57826001600160a01b03166003828154811061075e5761075e61268e565b6000918252602090912001546001600160a01b031614156107f85760038054610789906001906125cb565b815481106107995761079961268e565b600091825260209091200154600380546001600160a01b0390921691839081106107c5576107c561268e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061080a565b8061080281612647565b91505061072b565b50600380548061081c5761081c612678565b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156108565760035461085690611467565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff166108aa57600080fd5b60008281526001602090815260408083203380855292529091205483919060ff166108d457600080fd5b600084815260208190526040902060030154849060ff16156108f557600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b33301461095057600080fd5b60004261096d6006546001600160401b03600160a01b9091041690565b106109ac5760405162461bcd60e51b81526004016109a390602080825260049082015263656e642160e01b604082015260600190565b60405180910390fd5b6009546008546001600160a01b0390811691161415610a4d57504780821115610a0d5760405162461bcd60e51b815260206004820152601360248201527230b6b7bab73a10363a103130b630b731b2a7b360691b60448201526064016109a3565b6006546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015610a47573d6000803e3d6000fd5b50610bb5565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac891906123c8565b905080821115610b105760405162461bcd60e51b815260206004820152601360248201527230b6b7bab73a10363a103130b630b731b2a7b360691b60448201526064016109a3565b6008546001600160a01b031663a9059cbb610b336006546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b158015610b7b57600080fd5b505af1158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190612359565b505b6040518281527fda9d4e5f101b8b9b1c5b76d0c5a9f7923571acfc02376aa076b75a8c080c956b9060200160405180910390a15050565b333014610bf857600080fd5b600754600090610c1890600160401b90046001600160a01b031642610eca565b600754604051828152919250600160401b90046001600160a01b0316907fc0e523490dd523c33b1878c9eb14ff46991e3f5b2cd33710918618f2a39cba1b9060200160405180910390a2600754610c92906001600160a01b03600160401b90910416610c8c6006546001600160a01b031690565b83611a3d565b50565b6000805b600554811015610d0b57838015610cc2575060008181526020819052604090206003015460ff16155b80610ce65750828015610ce6575060008181526020819052604090206003015460ff165b15610cf957610cf66001836125b3565b91505b80610d0381612647565b915050610c99565b5092915050565b333014610d1e57600080fd5b6001600160a01b038116600090815260026020526040902054819060ff1615610d4657600080fd5b816001600160a01b038116610d5a57600080fd5b600354610d689060016125b3565b60045460328211158015610d7c5750818111155b8015610d8757508015155b8015610d9257508115155b610d9b57600080fd5b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610ec05760008481526001602052604081206003805491929184908110610e5f57610e5f61268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610e9a57610e976001836125b3565b91505b600454821415610eae575060019392505050565b80610eb881612647565b915050610e30565b5060009392505050565b6040516370a0823160e01b8152306004820152600090610f4e906001600160a01b038516906370a082319060240160206040518083038186803b158015610f1057600080fd5b505afa158015610f24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4891906123c8565b836119ee565b9392505050565b6000805b600354811015610fd55760008381526001602052604081206003805491929184908110610f8857610f8861268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610fc357610fc06001836125b3565b91505b80610fcd81612647565b915050610f59565b50919050565b6000602081905290815260409020805460018201546002830180546001600160a01b0390931693919261100d90612612565b80601f016020809104026020016040519081016040528092919081815260200182805461103990612612565b80156110865780601f1061105b57610100808354040283529160200191611086565b820191906000526020600020905b81548152906001019060200180831161106957829003601f168201915b5050506003909301549192505060ff1684565b606060038054806020026020016040519081016040528092919081815260200182805480156110f157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d3575b5050505050905090565b606060006005546001600160401b03811115611119576111196126a4565b604051908082528060200260200182016040528015611142578160200160208202803683370190505b5090506000805b6005548110156111d957858015611172575060008181526020819052604090206003015460ff16155b806111965750848015611196575060008181526020819052604090206003015460ff165b156111c757808383815181106111ae576111ae61268e565b60209081029190910101526111c46001836125b3565b91505b806111d181612647565b915050611149565b6111e388886125cb565b6001600160401b038111156111fa576111fa6126a4565b604051908082528060200260200182016040528015611223578160200160208202803683370190505b5093508790505b86811015611286578281815181106112445761124461268e565b602002602001015184898361125991906125cb565b815181106112695761126961268e565b60209081029190910101528061127e81612647565b91505061122a565b505050949350505050565b6003546060906000906001600160401b038111156112b1576112b16126a4565b6040519080825280602002602001820160405280156112da578160200160208202803683370190505b5090506000805b6003548110156113b857600085815260016020526040812060038054919291849081106113105761131061268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156113a657600381815481106113505761135061268e565b9060005260206000200160009054906101000a90046001600160a01b03168383815181106113805761138061268e565b6001600160a01b03909216602092830291909101909101526113a36001836125b3565b91505b806113b081612647565b9150506112e1565b816001600160401b038111156113d0576113d06126a4565b6040519080825280602002602001820160405280156113f9578160200160208202803683370190505b509350600090505b8181101561145f5782818151811061141b5761141b61268e565b60200260200101518482815181106114355761143561268e565b6001600160a01b03909216602092830291909101909101528061145781612647565b915050611401565b505050919050565b33301461147357600080fd5b60035481603282118015906114885750818111155b801561149357508015155b801561149e57508115155b6114a757600080fd5b60048390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b3360008181526002602052604090205460ff1661150057600080fd5b60008281526020819052604090205482906001600160a01b031661152357600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561154e57600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36115a48561182b565b5050505050565b60006115b8848484611a94565b9050610f4e816114e4565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116275760405162461bcd60e51b81526020600482015260096024820152681bdb9b1e481c1bdbdb60ba1b60448201526064016109a3565b6116318888611b87565b61163c858588611cbe565b600880546001600160a01b039485166001600160a01b03199182161790915560098054928516929091169190911790556007805491909216600160401b0268010000000000000000600160e01b03199091161790555050505050565b3330146116a457600080fd5b6001600160a01b038216600090815260026020526040902054829060ff166116cb57600080fd5b6001600160a01b038216600090815260026020526040902054829060ff16156116f357600080fd5b60005b60035481101561179157846001600160a01b03166003828154811061171d5761171d61268e565b6000918252602090912001546001600160a01b0316141561177f57836003828154811061174c5761174c61268e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550611791565b8061178981612647565b9150506116f6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff1661184757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1661187157600080fd5b600084815260208190526040902060030154849060ff161561189257600080fd5b61189b85610e2b565b156115a457600085815260208190526040902060038101805460ff19166001908117909155815490820154600283018054611979936001600160a01b03169291906118e590612612565b90508460020180546118f690612612565b80601f016020809104026020016040519081016040528092919081815260200182805461192290612612565b801561196f5780601f106119445761010080835404028352916020019161196f565b820191906000526020600020905b81548152906001019060200180831161195257829003601f168201915b5050505050611d77565b156119ae5760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26119e6565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000611a026007546001600160401b031690565b600654600160a01b90046001600160401b0316611a1f91906125b3565b826001600160401b031610611a355750816106d1565b5060006106d1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611a8f908490611d9a565b505050565b6000836001600160a01b038116611aaa57600080fd5b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b03191694169390931783555160018301559251805194965091939092611b1d926002850192910190611fed565b50606091909101516003909101805460ff19169115159190911790556005805460019190600090611b4f9084906125b3565b909155505060405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b81518160328211158015611b9b5750818111155b8015611ba657508015155b8015611bb157508115155b611bba57600080fd5b60005b8451811015611ca15760026000868381518110611bdc57611bdc61268e565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015611c3c575060006001600160a01b0316858281518110611c2857611c2861268e565b60200260200101516001600160a01b031614155b611c4557600080fd5b600160026000878481518110611c5d57611c5d61268e565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580611c9981612647565b915050611bbd565b508351611cb5906003906020870190612071565b50505060045550565b6001600160a01b038316611d275760405162461bcd60e51b815260206004820152602a60248201527f56657374696e6757616c6c65743a2062656e6566696369617279206973207a65604482015269726f206164647265737360b01b60648201526084016109a3565b600680546001600160a01b03949094166001600160e01b031990941693909317600160a01b6001600160401b0393841602179092556007805467ffffffffffffffff191692909116919091179055565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b6000611def826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e6c9092919063ffffffff16565b805190915015611a8f5780806020019051810190611e0d9190612359565b611a8f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109a3565b6060611e7b8484600085611e83565b949350505050565b606082471015611ee45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109a3565b6001600160a01b0385163b611f3b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109a3565b600080866001600160a01b03168587604051611f579190612495565b60006040518083038185875af1925050503d8060008114611f94576040519150601f19603f3d011682016040523d82523d6000602084013e611f99565b606091505b5091509150611fa9828286611fb4565b979650505050505050565b60608315611fc3575081610f4e565b825115611fd35782518084602001fd5b8160405162461bcd60e51b81526004016109a39190612570565b828054611ff990612612565b90600052602060002090601f01602090048101928261201b5760008555612061565b82601f1061203457805160ff1916838001178555612061565b82800160010185558215612061579182015b82811115612061578251825591602001919060010190612046565b5061206d9291506120c6565b5090565b828054828255906000526020600020908101928215612061579160200282015b8281111561206157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612091565b5b8082111561206d57600081556001016120c7565b80356001600160a01b03811681146120f257600080fd5b919050565b80356001600160401b03811681146120f257600080fd5b60006020828403121561212057600080fd5b610f4e826120db565b6000806040838503121561213c57600080fd5b612145836120db565b9150612153602084016120db565b90509250929050565b60008060006060848603121561217157600080fd5b61217a846120db565b9250602080850135925060408501356001600160401b038082111561219e57600080fd5b818701915087601f8301126121b257600080fd5b8135818111156121c4576121c46126a4565b6121d6601f8201601f19168501612583565b915080825288848285010111156121ec57600080fd5b80848401858401376000848284010152508093505050509250925092565b6000806040838503121561221d57600080fd5b612226836120db565b9150612153602084016120f7565b600080600080600080600080610100898b03121561225157600080fd5b6001600160401b03808a35111561226757600080fd5b89358a018b601f82011261227a57600080fd5b80358281111561228c5761228c6126a4565b8060051b925061229e60208401612583565b80828252602082019150602084018f60208787010111156122be57600080fd5b600095505b838610156122e9576122d4816120db565b835260019590950194602092830192016122c3565b509b5050505060208a01359750612304905060408a016120f7565b955061231260608a016120db565b945061232060808a016120f7565b935061232e60a08a016120db565b925061233c60c08a016120db565b915061234a60e08a016120db565b90509295985092959890939650565b60006020828403121561236b57600080fd5b8151610f4e816126ba565b6000806040838503121561238957600080fd5b8235612394816126ba565b915060208301356123a4816126ba565b809150509250929050565b6000602082840312156123c157600080fd5b5035919050565b6000602082840312156123da57600080fd5b5051919050565b600080604083850312156123f457600080fd5b82359150612153602084016120db565b6000806000806080858703121561241a57600080fd5b84359350602085013592506040850135612433816126ba565b91506060850135612443816126ba565b939692955090935050565b60006020828403121561246057600080fd5b610f4e826120f7565b600081518084526124818160208601602086016125e2565b601f01601f19169290920160200192915050565b600082516124a78184602087016125e2565b9190910192915050565b60018060a01b03851681528360208201526080604082015260006124d86080830185612469565b9050821515606083015295945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561252c5783516001600160a01b031683529284019291840191600101612507565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561252c57835183529284019291840191600101612554565b602081526000610f4e6020830184612469565b604051601f8201601f191681016001600160401b03811182821017156125ab576125ab6126a4565b604052919050565b600082198211156125c6576125c6612662565b500190565b6000828210156125dd576125dd612662565b500390565b60005b838110156125fd5781810151838201526020016125e5565b8381111561260c576000848401525b50505050565b600181811c9082168061262657607f821691505b60208210811415610fd557634e487b7160e01b600052602260045260246000fd5b600060001982141561265b5761265b612662565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610c9257600080fdfea2646970667358221220ad5f1b47d2adf92bad4533ffe2cbf7d6d45660df712721af9b5b08a8d8a1354664736f6c63430008070033a264697066735822122081140cab24b2f20e9a5b523d33c6c2a7ee164454b8124f96173f9b1fbcb19e2964736f6c63430008070033a264697066735822122083966f1bf2e54ad35d555dfb0382060ad6b77a5f07635e8bb19f15134b060f3a64736f6c63430008070033
Deployed ByteCode
0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c8063707f507c146200004b5780637749cf231462000064578063de7fe3e7146200007a575b600080fd5b620000626200005c3660046200087f565b6200010b565b005b6000546040519081526020015b60405180910390f35b620000916200008b36600462000899565b6200039f565b60405162000071919081516001600160a01b039081168252602080840151821690830152604080840151908301526060808401519083015260808084015182169083015260a0808401519091169082015260c0808301519082015260e0808301519082015261010091820151918101919091526101200190565b6000816040516200011c906200081b565b62000128919062000906565b604051809103906000f08015801562000145573d6000803e3d6000fd5b509050620001746060830135602084013560408501356200016d60a08701608088016200083b565b856200049d565b7fdf28fe625edaab14d82ac291ae937512fc672b0977357600f5f48a68209aa599620001a460208401846200083b565b8260208501356060860135620001c160a08801608089016200083b565b620001d360c0890160a08a016200083b565b604080516001600160a01b039788168152958716602087015285019390935260608401919091528316608083015290911660a082015260c0848101359082015260e0808501359082015261010080850135908201526101200160405180910390a1604080516101208101909152806200025060208501856200083b565b6001600160a01b03168152602001826001600160a01b0316815260200183602001358152602001836060013581526020018360800160208101906200029691906200083b565b6001600160a01b03168152602001620002b660c0850160a086016200083b565b6001600160a01b03908116825260c08581013560208085019190915260e080880135604080870191909152610100808a013560609788015260008054815260018086528382208a5181546001600160a01b0319908116918b16919091178255968b015191810180548816928a16929092179091559289015160028401559688015160038301556080880151600483018054861691881691909117905560a088015160058301805490951696169590951790925591850151600682015590840151600782015592015160089092019190915580549080620003968362000a8a565b91905055505050565b6200041360405180610120016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b5060009081526001602081815260409283902083516101208101855281546001600160a01b0390811682529382015484169281019290925260028101549382019390935260038301546060820152600483015482166080820152600583015490911660a0820152600682015460c0820152600782015460e082015260089091015461010082015290565b6000620004f3620004d385620004cc6064816014620004c58d670de0b6b3a764000062000514565b9062000514565b9062000529565b620004ec87620004cc8a670de0b6b3a764000062000514565b9062000537565b90506200050c6001600160a01b03841633848462000545565b505050505050565b600062000522828462000a39565b9392505050565b600062000522828462000a16565b6000620005228284620009fb565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052620005a1908590620005a7565b50505050565b6000620005fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620006899092919063ffffffff16565b8051909150156200068457808060200190518101906200061f91906200085b565b620006845760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b505050565b60606200069a8484600085620006a2565b949350505050565b606082471015620007055760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200067b565b6001600160a01b0385163b6200075e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200067b565b600080866001600160a01b031685876040516200077c9190620008b3565b60006040518083038185875af1925050503d8060008114620007bb576040519150601f19603f3d011682016040523d82523d6000602084013e620007c0565b606091505b5091509150620007d2828286620007dd565b979650505050505050565b60608315620007ee57508162000522565b825115620007ff5782518084602001fd5b8160405162461bcd60e51b81526004016200067b9190620008d1565b6147a98062000ad883390190565b8035620008368162000abe565b919050565b6000602082840312156200084e57600080fd5b8135620005228162000abe565b6000602082840312156200086e57600080fd5b815180151581146200052257600080fd5b600061018082840312156200089357600080fd5b50919050565b600060208284031215620008ac57600080fd5b5035919050565b60008251620008c781846020870162000a5b565b9190910192915050565b6020815260008251806020840152620008f281604085016020870162000a5b565b601f01601f19169190910160400192915050565b610180810162000928826200091b8562000829565b6001600160a01b03169052565b602083013560208301526040830135604083015260608301356060830152620009546080840162000829565b6001600160a01b031660808301526200097060a0840162000829565b6001600160a01b031660a083015260c0838101359083015260e080840135908301526101008084013590830152610120620009ad81850162000829565b6001600160a01b031690830152610140620009ca84820162000829565b6001600160a01b031690830152610160620009e784820162000829565b6001600160a01b0316920191909152919050565b6000821982111562000a115762000a1162000aa8565b500190565b60008262000a3457634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161562000a565762000a5662000aa8565b500290565b60005b8381101562000a7857818101518382015260200162000a5e565b83811115620005a15750506000910152565b600060001982141562000aa15762000aa162000aa8565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000ad457600080fd5b5056fe60e06040527306677520c1449d9977e7a245f0797a65e7eff219608090815273b9eb39c42d0e9f4966d411bdfbfc71123594593660a05273a551a1683ff764a4f5ff143f57206067ff29fac560c0526200005e906011906003620002d2565b503480156200006c57600080fd5b50604051620047a9380380620047a98339810160408190526200008f9162000370565b60016000819055815181546001600160a01b039182166001600160a01b0319918216179092556020808401516002556080840151600380549184169185168217905560a0850151600480549190941694169390931782556040805163313ce56760e01b8152905163313ce567938281019392829003018186803b1580156200011657600080fd5b505afa1580156200012b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000151919062000442565b60ff166006556040810151601055610120810151600c80546001600160a01b03928316610100908102610100600160a81b031990921691909117909155610160830151600d80549184166001600160a01b0319928316179055610140840151600e8054919094169116179091556060820151600955810151600a5560e081015160c0820151106200023e5760405162461bcd60e51b815260206004820152602c60248201527f5374617274206e756d626572206d757374206265206c657373207468616e206660448201526b34b734b9b410373ab6b132b960a11b60648201526084015b60405180910390fd5b428160e0015111620002a95760405162461bcd60e51b815260206004820152602d60248201527f46696e697368206e756d626572206d757374206265206d6f7265207468616e2060448201526c63757272656e7420626c6f636b60981b606482015260840162000235565b60c081015160075560e001516008819055620151806012556301e13380601355601455620004a6565b8280548282559060005260206000209081019282156200032a579160200282015b828111156200032a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620002f3565b50620003389291506200033c565b5090565b5b808211156200033857600081556001016200033d565b80516001600160a01b03811681146200036b57600080fd5b919050565b600061018082840312156200038457600080fd5b6200038e6200046e565b620003998362000353565b8152602083015160208201526040830151604082015260608301516060820152620003c76080840162000353565b6080820152620003da60a0840162000353565b60a082015260c083015160c082015260e083015160e08201526101008084015181830152506101206200040f81850162000353565b908201526101406200042384820162000353565b908201526101606200043784820162000353565b908201529392505050565b6000602082840312156200045557600080fd5b815160ff811681146200046757600080fd5b9392505050565b60405161018081016001600160401b0381118282101715620004a057634e487b7160e01b600052604160045260246000fd5b60405290565b6142f380620004b66000396000f3fe6080604052600436106101405760003560e01c8063947a36fb116100b6578063d56b28891161006f578063d56b28891461031f578063d6df2e5814610349578063e0ee43a21461035f578063e6fd48bc14610375578063f7c618c11461038b578063ffdd5cf1146103ab57600080fd5b8063947a36fb1461027e5780639769f0b014610294578063be9a6555146102b4578063bef4876b146102ca578063c290d691146102df578063c8d88871146102ff57600080fd5b8063384711cc11610108578063384711cc146101ce57806343d7d321146101ee57806349c08238146102045780634b1a4c0c1461021a5780637ff9b596146102305780638da5cb5b1461024657600080fd5b80630fb5a6b4146101455780631726cbc81461016e578063191655871461018e5780631b9265b8146101b05780632382f645146101b8575b600080fd5b34801561015157600080fd5b5061015b60135481565b6040519081526020015b60405180910390f35b34801561017a57600080fd5b5061015b6101893660046117bb565b6103e6565b34801561019a57600080fd5b506101ae6101a93660046117bb565b61041b565b005b6101ae610518565b3480156101c457600080fd5b5061015b600a5481565b3480156101da57600080fd5b5061015b6101e93660046117bb565b61078d565b3480156101fa57600080fd5b5061015b60085481565b34801561021057600080fd5b5061015b60065481565b34801561022657600080fd5b5061015b600b5481565b34801561023c57600080fd5b5061015b60025481565b34801561025257600080fd5b50600154610266906001600160a01b031681565b6040516001600160a01b039091168152602001610165565b34801561028a57600080fd5b5061015b60125481565b3480156102a057600080fd5b50600354610266906001600160a01b031681565b3480156102c057600080fd5b5061015b60145481565b3480156102d657600080fd5b506101ae61085d565b3480156102eb57600080fd5b506101ae6102fa366004611817565b61091d565b34801561030b57600080fd5b5061026661031a366004611817565b610a9f565b34801561032b57600080fd5b50600c546103399060ff1681565b6040519015158152602001610165565b34801561035557600080fd5b5061015b60055481565b34801561036b57600080fd5b5061015b60095481565b34801561038157600080fd5b5061015b60075481565b34801561039757600080fd5b50600454610266906001600160a01b031681565b3480156103b757600080fd5b506103cb6103c63660046117bb565b610ac9565b60408051938452602084019290925290820152606001610165565b6001600160a01b0381166000908152601560205260408120600101546104159061040f8461078d565b90610b27565b92915050565b6000610426826103e6565b90506000811161048f5760405162461bcd60e51b815260206004820152602960248201527f546f6b656e56657374696e67202372656c656173653a206e6f7468696e6720746044820152686f2072656c6561736560b81b60648201526084015b60405180910390fd5b6001600160a01b038216600090815260156020526040902060018101546104b69083610b3a565b600182015580546104c79083610b27565b81556003546104e0906001600160a01b03168484610b46565b6040518281527ffb81f9b30d73d830c3544b34d827c08142579ee75710b490bab0b3995468c5659060200160405180910390a1505050565b6002600054141561053b5760405162461bcd60e51b8152600401610486906119a1565b6002600055600c546004546001600160a01b0390811661010090920416146105965760405162461bcd60e51b815260206004820152600e60248201526d7061795245493a4e6f742052656960901b6044820152606401610486565b6007544210156105dd5760405162461bcd60e51b81526020600482015260126024820152711c185e5491524e939bdd081cdd185c9d195960721b6044820152606401610486565b600854421061061d5760405162461bcd60e51b815260206004820152600c60248201526b1c185e5491524e915b99195960a21b6044820152606401610486565b600c5460ff16156106625760405162461bcd60e51b815260206004820152600f60248201526e1c185e5491524e919a5b9a5cda1959608a1b6044820152606401610486565b34600061066e82610bae565b905080600a5410156106925760405162461bcd60e51b81526004016104869061195d565b600954600b546106a29084610b3a565b111561071157600c805460ff19166001179055600b5460095433916108fc916106d6916106cf9190610b27565b8590610b27565b6040518115909202916000818181858888f193505050501580156106fe573d6000803e3d6000fd5b50600b5460095461070e91610b27565b91505b600b5461071e9083610b3a565b600b5561072a82610bae565b90506107363382610bcf565b600c5460ff161561074957610749610cf9565b604080518381526020810183905233917fba7a32849fb0a371567222ea0cb62b2055fead07c17efb43d99728b10f09d699910160405180910390a250506001600055565b6001600160a01b038116600090815260156020908152604080832081518083019092528054808352600190910154928201839052909183906107d0908390610b3a565b90504260145411156107e757506000949350505050565b6013546014546107f691610b3a565b421061080457949350505050565b600061082760125461082160145442610b2790919063ffffffff16565b90611354565b9050600061084260125460135461135490919063ffffffff16565b9050610852816108218585611360565b979650505050505050565b600260005414156108805760405162461bcd60e51b8152600401610486906119a1565b600260005560085442116108c85760405162461bcd60e51b815260206004820152600f60248201526e1c185e4e939bdd081cdd185c9d1959608a1b6044820152606401610486565b600c5460ff161561090e5760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48199a5b9a5cda195960821b6044820152606401610486565b610916610cf9565b6001600055565b600260005414156109405760405162461bcd60e51b8152600401610486906119a1565b60026000556007544210156109895760405162461bcd60e51b815260206004820152600f60248201526e1c185e4e939bdd081cdd185c9d1959608a1b6044820152606401610486565b60085442106109c65760405162461bcd60e51b81526020600482015260096024820152681c185e4e995b99195960ba1b6044820152606401610486565b600c5460ff1615610a0b5760405162461bcd60e51b815260206004820152600f60248201526e1c185e5491524e919a5b9a5cda1959608a1b6044820152606401610486565b6000610a1682610bae565b905080600a541015610a3a5760405162461bcd60e51b81526004016104869061195d565b600954600b54610a4a9084610b3a565b10610a6e57600c805460ff19166001179055600b54600954610a6b91610b27565b91505b600b54610a7b9083610b3a565b600b55600454610a96906001600160a01b031633308561136c565b61072a82610bae565b60118181548110610aaf57600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b0381166000908152601560209081526040808320815180830190925280548083526001909101549282018390528392839291610b0c91906119d8565b610b15866103e6565b60209092015190969195509350915050565b6000610b338284611b1c565b9392505050565b6000610b3382846119d8565b6040516001600160a01b038316602482015260448101829052610ba990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526113aa565b505050565b6000610415600254610821600654600a610bc89190611a55565b8590611360565b600060125411610c475760405162461bcd60e51b815260206004820152603c60248201527f546f6b656e56657374696e67202363726561746556657374696e673a20696e7460448201527f657276616c206d7573742062652067726561746572207468616e2030000000006064820152608401610486565b6012546013541015610ccf5760405162461bcd60e51b8152602060048201526044602482018190527f546f6b656e56657374696e67202363726561746556657374696e673a20696e74908201527f657276616c2063616e6e6f7420626520626967676572207468616e20647572616064820152633a34b7b760e11b608482015260a401610486565b6001600160a01b03821660009081526015602052604090208054610cf39083610b3a565b90555050565b6001546004546003546040516bffffffffffffffffffffffff19606094851b8116602083015292841b83166034820152921b166048820152600090605c01604051602081830303815290604052805190602001209050600060405180602001610d61906117ae565b601f1982820381018352601f9091011660405290506000610d8381848461147c565b600c546004549192506000916001600160a01b03908116610100909204161415610ffb5760004790506000610ddc601054610821600654600a610dc69190611a55565b610dd66064610821886014611360565b90611360565b600d54600354919250610dfc916001600160a01b03908116911683611586565b600d546000906001600160a01b031663f305d719610e206064610821876014611360565b60035460405160e084901b6001600160e01b03191681526001600160a01b039182166004820152602481018790526000604482018190526064820152908916608482015267ffffffffffffffff421660a482015260c4016060604051808303818588803b158015610e9057600080fd5b505af1158015610ea4573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ec99190611849565b600e54600c5460035460405163e6a4390560e01b81526001600160a01b0361010090930483166004820152908216602482015292955016925063e6a43905915060440160206040518083038186803b158015610f2457600080fd5b505afa158015610f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5c91906117d8565b600154604080516001600160a01b03808a168252909216602083015281018390529094507f6443c245157515cfcdd90c76a3e200a6736156f16241f7237ff1810282f349bb9060600160405180910390a16001600160a01b0385166108fc610fca6064610821876050611360565b6040518115909202916000818181858888f19350505050158015610ff2573d6000803e3d6000fd5b505050506112c8565b600480546040516370a0823160e01b815230928101929092526000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561104457600080fd5b505afa158015611058573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107c9190611830565b90506000611098601054610821600654600a610dc69190611a55565b600d546004549192506110b8916001600160a01b03908116911684611586565b600d546003546110d5916001600160a01b03918216911683611586565b600d546004546003546000926001600160a01b039081169263e8e337009290821691166111086064610821896014611360565b6040516001600160e01b031960e086901b1681526001600160a01b039384166004820152918316602483015260448201526064810186905260006084820181905260a482015290881660c482015267ffffffffffffffff421660e482015261010401606060405180830381600087803b15801561118457600080fd5b505af1158015611198573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111bc9190611849565b600e546004805460035460405163e6a4390560e01b81526001600160a01b0392831693810193909352811660248301529295509116925063e6a43905915060440160206040518083038186803b15801561121557600080fd5b505afa158015611229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124d91906117d8565b9350611276856112636064610821876050611360565b6004546001600160a01b03169190610b46565b600154604080516001600160a01b038089168252909216602083015281018290527f6443c245157515cfcdd90c76a3e200a6736156f16241f7237ff1810282f349bb9060600160405180910390a15050505b60015460048054600c5460405163cf5bf23f60e01b81526001600160a01b038088169563cf5bf23f9561131c956011956002956301e1338095948516944294938116938d9361010090049091169101611893565b600060405180830381600087803b15801561133657600080fd5b505af115801561134a573d6000803e3d6000fd5b5050505050505050565b6000610b3382846119f0565b6000610b338284611afd565b6040516001600160a01b03808516602483015283166044820152606481018290526113a49085906323b872dd60e01b90608401610b72565b50505050565b60006113ff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116aa9092919063ffffffff16565b805190915015610ba9578080602001905181019061141d91906117f5565b610ba95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610486565b600080844710156114cf5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610486565b825161151d5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610486565b8383516020850187f590506001600160a01b03811661157e5760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610486565b949350505050565b80158061160f5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156115d557600080fd5b505afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190611830565b155b61167a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610486565b6040516001600160a01b038316602482015260448101829052610ba990849063095ea7b360e01b90606401610b72565b606061157e8484600085856001600160a01b0385163b61170c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610486565b600080866001600160a01b031685876040516117289190611877565b60006040518083038185875af1925050503d8060008114611765576040519150601f19603f3d011682016040523d82523d6000602084013e61176a565b606091505b509150915061085282828660608315611784575081610b33565b8251156117945782518084602001fd5b8160405162461bcd60e51b8152600401610486919061192a565b61273080611b8e83390190565b6000602082840312156117cd57600080fd5b8135610b3381611b75565b6000602082840312156117ea57600080fd5b8151610b3381611b75565b60006020828403121561180757600080fd5b81518015158114610b3357600080fd5b60006020828403121561182957600080fd5b5035919050565b60006020828403121561184257600080fd5b5051919050565b60008060006060848603121561185e57600080fd5b8351925060208401519150604084015190509250925092565b60008251611889818460208701611b33565b9190910192915050565b610100808252895490820181905260008a815260208082209192610120850192845b828110156118da5781546001600160a01b0316855293830193600191820191016118b5565b5050508301999099525067ffffffffffffffff96871660408201526001600160a01b03958616606082015293909516608084015290831660a0830152821660c0820152911660e090910152919050565b6020815260008251806020840152611949816040850160208701611b33565b601f01601f19169190910160400192915050565b60208082526024908201527f7061795245493a207065724d61784469737472696275746564546f6b656e416d6040820152631bdd5b9d60e21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082198211156119eb576119eb611b5f565b500190565b600082611a0d57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115611a4d578160001904821115611a3357611a33611b5f565b80851615611a4057918102915b93841c9390800290611a17565b509250929050565b6000610b338383600082611a6b57506001610415565b81611a7857506000610415565b8160018114611a8e5760028114611a9857611ab4565b6001915050610415565b60ff841115611aa957611aa9611b5f565b50506001821b610415565b5060208310610133831016604e8410600b8410161715611ad7575081810a610415565b611ae18383611a12565b8060001904821115611af557611af5611b5f565b029392505050565b6000816000190483118215151615611b1757611b17611b5f565b500290565b600082821015611b2e57611b2e611b5f565b500390565b60005b83811015611b4e578181015183820152602001611b36565b838111156113a45750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114611b8a57600080fd5b5056fe60a060405234801561001057600080fd5b5033606081901b6080526126fe61003260003960006115ce01526126fe6000f3fe6080604052600436106101dc5760003560e01c80639ace38c211610102578063c642747411610095578063dc8452cd11610064578063dc8452cd14610625578063e20056e61461063b578063ecd0c0c31461065b578063ee22610b1461067b57610220565b8063c6427474146105a9578063cf5bf23f146105c9578063d6c3179d146105e9578063d74f8edd1461061057610220565b8063b77bf600116100d1578063b77bf6001461052e578063ba51a6df14610544578063be9a655514610564578063c01a8c841461058957610220565b80639ace38c21461048f578063a0e67e2b146104bf578063a8abe69a146104e1578063b5dc40c31461050e57610220565b806337bdc99b1161017a5780637065cb48116101495780637065cb481461040f578063784547a71461042f578063810ec23b1461044f5780638b51d13f1461046f57610220565b806337bdc99b1461039c57806338af3eed146103bc57806343ad92d5146103da57806354741525146103ef57610220565b8063173825d9116101b6578063173825d9146102e157806320ea8d86146103015780632f54bf6e146103215780633411c81c1461036157610220565b8063025e7c27146102585780630a17b06b146102955780630fb5a6b4146102c357610220565b3661022057341561021e5760405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c906020015b60405180910390a25b005b341561021e5760405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90602001610215565b34801561026457600080fd5b506102786102733660046123af565b61069b565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102a157600080fd5b506102b56102b036600461244e565b6106c5565b60405190815260200161028c565b3480156102cf57600080fd5b506007546001600160401b03166102b5565b3480156102ed57600080fd5b5061021e6102fc36600461210e565b6106d7565b34801561030d57600080fd5b5061021e61031c3660046123af565b61088e565b34801561032d57600080fd5b5061035161033c36600461210e565b60026020526000908152604090205460ff1681565b604051901515815260200161028c565b34801561036d57600080fd5b5061035161037c3660046123e1565b600160209081526000928352604080842090915290825290205460ff1681565b3480156103a857600080fd5b5061021e6103b73660046123af565b610944565b3480156103c857600080fd5b506006546001600160a01b0316610278565b3480156103e657600080fd5b5061021e610bec565b3480156103fb57600080fd5b506102b561040a366004612376565b610c95565b34801561041b57600080fd5b5061021e61042a36600461210e565b610d12565b34801561043b57600080fd5b5061035161044a3660046123af565b610e2b565b34801561045b57600080fd5b506102b561046a36600461220a565b610eca565b34801561047b57600080fd5b506102b561048a3660046123af565b610f55565b34801561049b57600080fd5b506104af6104aa3660046123af565b610fdb565b60405161028c94939291906124b1565b3480156104cb57600080fd5b506104d4611099565b60405161028c91906124eb565b3480156104ed57600080fd5b506105016104fc366004612404565b6110fb565b60405161028c9190612538565b34801561051a57600080fd5b506104d46105293660046123af565b611291565b34801561053a57600080fd5b506102b560055481565b34801561055057600080fd5b5061021e61055f3660046123af565b611467565b34801561057057600080fd5b50600654600160a01b90046001600160401b03166102b5565b34801561059557600080fd5b5061021e6105a43660046123af565b6114e4565b3480156105b557600080fd5b506102b56105c436600461215c565b6115ab565b3480156105d557600080fd5b5061021e6105e4366004612234565b6115c3565b3480156105f557600080fd5b5060075461027890600160401b90046001600160a01b031681565b34801561061c57600080fd5b506102b5603281565b34801561063157600080fd5b506102b560045481565b34801561064757600080fd5b5061021e610656366004612129565b611698565b34801561066757600080fd5b50600854610278906001600160a01b031681565b34801561068757600080fd5b5061021e6106963660046123af565b61182b565b600381815481106106ab57600080fd5b6000918252602090912001546001600160a01b0316905081565b60006106d147836119ee565b92915050565b3330146106e357600080fd5b6001600160a01b038116600090815260026020526040902054819060ff1661070a57600080fd5b6001600160a01b0382166000908152600260205260408120805460ff191690555b60035461073a906001906125cb565b81101561080a57826001600160a01b03166003828154811061075e5761075e61268e565b6000918252602090912001546001600160a01b031614156107f85760038054610789906001906125cb565b815481106107995761079961268e565b600091825260209091200154600380546001600160a01b0390921691839081106107c5576107c561268e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061080a565b8061080281612647565b91505061072b565b50600380548061081c5761081c612678565b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156108565760035461085690611467565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff166108aa57600080fd5b60008281526001602090815260408083203380855292529091205483919060ff166108d457600080fd5b600084815260208190526040902060030154849060ff16156108f557600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b33301461095057600080fd5b60004261096d6006546001600160401b03600160a01b9091041690565b106109ac5760405162461bcd60e51b81526004016109a390602080825260049082015263656e642160e01b604082015260600190565b60405180910390fd5b6009546008546001600160a01b0390811691161415610a4d57504780821115610a0d5760405162461bcd60e51b815260206004820152601360248201527230b6b7bab73a10363a103130b630b731b2a7b360691b60448201526064016109a3565b6006546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015610a47573d6000803e3d6000fd5b50610bb5565b6008546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac891906123c8565b905080821115610b105760405162461bcd60e51b815260206004820152601360248201527230b6b7bab73a10363a103130b630b731b2a7b360691b60448201526064016109a3565b6008546001600160a01b031663a9059cbb610b336006546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b158015610b7b57600080fd5b505af1158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190612359565b505b6040518281527fda9d4e5f101b8b9b1c5b76d0c5a9f7923571acfc02376aa076b75a8c080c956b9060200160405180910390a15050565b333014610bf857600080fd5b600754600090610c1890600160401b90046001600160a01b031642610eca565b600754604051828152919250600160401b90046001600160a01b0316907fc0e523490dd523c33b1878c9eb14ff46991e3f5b2cd33710918618f2a39cba1b9060200160405180910390a2600754610c92906001600160a01b03600160401b90910416610c8c6006546001600160a01b031690565b83611a3d565b50565b6000805b600554811015610d0b57838015610cc2575060008181526020819052604090206003015460ff16155b80610ce65750828015610ce6575060008181526020819052604090206003015460ff165b15610cf957610cf66001836125b3565b91505b80610d0381612647565b915050610c99565b5092915050565b333014610d1e57600080fd5b6001600160a01b038116600090815260026020526040902054819060ff1615610d4657600080fd5b816001600160a01b038116610d5a57600080fd5b600354610d689060016125b3565b60045460328211158015610d7c5750818111155b8015610d8757508015155b8015610d9257508115155b610d9b57600080fd5b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610ec05760008481526001602052604081206003805491929184908110610e5f57610e5f61268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610e9a57610e976001836125b3565b91505b600454821415610eae575060019392505050565b80610eb881612647565b915050610e30565b5060009392505050565b6040516370a0823160e01b8152306004820152600090610f4e906001600160a01b038516906370a082319060240160206040518083038186803b158015610f1057600080fd5b505afa158015610f24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4891906123c8565b836119ee565b9392505050565b6000805b600354811015610fd55760008381526001602052604081206003805491929184908110610f8857610f8861268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610fc357610fc06001836125b3565b91505b80610fcd81612647565b915050610f59565b50919050565b6000602081905290815260409020805460018201546002830180546001600160a01b0390931693919261100d90612612565b80601f016020809104026020016040519081016040528092919081815260200182805461103990612612565b80156110865780601f1061105b57610100808354040283529160200191611086565b820191906000526020600020905b81548152906001019060200180831161106957829003601f168201915b5050506003909301549192505060ff1684565b606060038054806020026020016040519081016040528092919081815260200182805480156110f157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d3575b5050505050905090565b606060006005546001600160401b03811115611119576111196126a4565b604051908082528060200260200182016040528015611142578160200160208202803683370190505b5090506000805b6005548110156111d957858015611172575060008181526020819052604090206003015460ff16155b806111965750848015611196575060008181526020819052604090206003015460ff165b156111c757808383815181106111ae576111ae61268e565b60209081029190910101526111c46001836125b3565b91505b806111d181612647565b915050611149565b6111e388886125cb565b6001600160401b038111156111fa576111fa6126a4565b604051908082528060200260200182016040528015611223578160200160208202803683370190505b5093508790505b86811015611286578281815181106112445761124461268e565b602002602001015184898361125991906125cb565b815181106112695761126961268e565b60209081029190910101528061127e81612647565b91505061122a565b505050949350505050565b6003546060906000906001600160401b038111156112b1576112b16126a4565b6040519080825280602002602001820160405280156112da578160200160208202803683370190505b5090506000805b6003548110156113b857600085815260016020526040812060038054919291849081106113105761131061268e565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156113a657600381815481106113505761135061268e565b9060005260206000200160009054906101000a90046001600160a01b03168383815181106113805761138061268e565b6001600160a01b03909216602092830291909101909101526113a36001836125b3565b91505b806113b081612647565b9150506112e1565b816001600160401b038111156113d0576113d06126a4565b6040519080825280602002602001820160405280156113f9578160200160208202803683370190505b509350600090505b8181101561145f5782818151811061141b5761141b61268e565b60200260200101518482815181106114355761143561268e565b6001600160a01b03909216602092830291909101909101528061145781612647565b915050611401565b505050919050565b33301461147357600080fd5b60035481603282118015906114885750818111155b801561149357508015155b801561149e57508115155b6114a757600080fd5b60048390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b3360008181526002602052604090205460ff1661150057600080fd5b60008281526020819052604090205482906001600160a01b031661152357600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561154e57600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36115a48561182b565b5050505050565b60006115b8848484611a94565b9050610f4e816114e4565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116275760405162461bcd60e51b81526020600482015260096024820152681bdb9b1e481c1bdbdb60ba1b60448201526064016109a3565b6116318888611b87565b61163c858588611cbe565b600880546001600160a01b039485166001600160a01b03199182161790915560098054928516929091169190911790556007805491909216600160401b0268010000000000000000600160e01b03199091161790555050505050565b3330146116a457600080fd5b6001600160a01b038216600090815260026020526040902054829060ff166116cb57600080fd5b6001600160a01b038216600090815260026020526040902054829060ff16156116f357600080fd5b60005b60035481101561179157846001600160a01b03166003828154811061171d5761171d61268e565b6000918252602090912001546001600160a01b0316141561177f57836003828154811061174c5761174c61268e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550611791565b8061178981612647565b9150506116f6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff1661184757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1661187157600080fd5b600084815260208190526040902060030154849060ff161561189257600080fd5b61189b85610e2b565b156115a457600085815260208190526040902060038101805460ff19166001908117909155815490820154600283018054611979936001600160a01b03169291906118e590612612565b90508460020180546118f690612612565b80601f016020809104026020016040519081016040528092919081815260200182805461192290612612565b801561196f5780601f106119445761010080835404028352916020019161196f565b820191906000526020600020905b81548152906001019060200180831161195257829003601f168201915b5050505050611d77565b156119ae5760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26119e6565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000611a026007546001600160401b031690565b600654600160a01b90046001600160401b0316611a1f91906125b3565b826001600160401b031610611a355750816106d1565b5060006106d1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611a8f908490611d9a565b505050565b6000836001600160a01b038116611aaa57600080fd5b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b03191694169390931783555160018301559251805194965091939092611b1d926002850192910190611fed565b50606091909101516003909101805460ff19169115159190911790556005805460019190600090611b4f9084906125b3565b909155505060405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b81518160328211158015611b9b5750818111155b8015611ba657508015155b8015611bb157508115155b611bba57600080fd5b60005b8451811015611ca15760026000868381518110611bdc57611bdc61268e565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015611c3c575060006001600160a01b0316858281518110611c2857611c2861268e565b60200260200101516001600160a01b031614155b611c4557600080fd5b600160026000878481518110611c5d57611c5d61268e565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580611c9981612647565b915050611bbd565b508351611cb5906003906020870190612071565b50505060045550565b6001600160a01b038316611d275760405162461bcd60e51b815260206004820152602a60248201527f56657374696e6757616c6c65743a2062656e6566696369617279206973207a65604482015269726f206164647265737360b01b60648201526084016109a3565b600680546001600160a01b03949094166001600160e01b031990941693909317600160a01b6001600160401b0393841602179092556007805467ffffffffffffffff191692909116919091179055565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b6000611def826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e6c9092919063ffffffff16565b805190915015611a8f5780806020019051810190611e0d9190612359565b611a8f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109a3565b6060611e7b8484600085611e83565b949350505050565b606082471015611ee45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109a3565b6001600160a01b0385163b611f3b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109a3565b600080866001600160a01b03168587604051611f579190612495565b60006040518083038185875af1925050503d8060008114611f94576040519150601f19603f3d011682016040523d82523d6000602084013e611f99565b606091505b5091509150611fa9828286611fb4565b979650505050505050565b60608315611fc3575081610f4e565b825115611fd35782518084602001fd5b8160405162461bcd60e51b81526004016109a39190612570565b828054611ff990612612565b90600052602060002090601f01602090048101928261201b5760008555612061565b82601f1061203457805160ff1916838001178555612061565b82800160010185558215612061579182015b82811115612061578251825591602001919060010190612046565b5061206d9291506120c6565b5090565b828054828255906000526020600020908101928215612061579160200282015b8281111561206157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612091565b5b8082111561206d57600081556001016120c7565b80356001600160a01b03811681146120f257600080fd5b919050565b80356001600160401b03811681146120f257600080fd5b60006020828403121561212057600080fd5b610f4e826120db565b6000806040838503121561213c57600080fd5b612145836120db565b9150612153602084016120db565b90509250929050565b60008060006060848603121561217157600080fd5b61217a846120db565b9250602080850135925060408501356001600160401b038082111561219e57600080fd5b818701915087601f8301126121b257600080fd5b8135818111156121c4576121c46126a4565b6121d6601f8201601f19168501612583565b915080825288848285010111156121ec57600080fd5b80848401858401376000848284010152508093505050509250925092565b6000806040838503121561221d57600080fd5b612226836120db565b9150612153602084016120f7565b600080600080600080600080610100898b03121561225157600080fd5b6001600160401b03808a35111561226757600080fd5b89358a018b601f82011261227a57600080fd5b80358281111561228c5761228c6126a4565b8060051b925061229e60208401612583565b80828252602082019150602084018f60208787010111156122be57600080fd5b600095505b838610156122e9576122d4816120db565b835260019590950194602092830192016122c3565b509b5050505060208a01359750612304905060408a016120f7565b955061231260608a016120db565b945061232060808a016120f7565b935061232e60a08a016120db565b925061233c60c08a016120db565b915061234a60e08a016120db565b90509295985092959890939650565b60006020828403121561236b57600080fd5b8151610f4e816126ba565b6000806040838503121561238957600080fd5b8235612394816126ba565b915060208301356123a4816126ba565b809150509250929050565b6000602082840312156123c157600080fd5b5035919050565b6000602082840312156123da57600080fd5b5051919050565b600080604083850312156123f457600080fd5b82359150612153602084016120db565b6000806000806080858703121561241a57600080fd5b84359350602085013592506040850135612433816126ba565b91506060850135612443816126ba565b939692955090935050565b60006020828403121561246057600080fd5b610f4e826120f7565b600081518084526124818160208601602086016125e2565b601f01601f19169290920160200192915050565b600082516124a78184602087016125e2565b9190910192915050565b60018060a01b03851681528360208201526080604082015260006124d86080830185612469565b9050821515606083015295945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561252c5783516001600160a01b031683529284019291840191600101612507565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561252c57835183529284019291840191600101612554565b602081526000610f4e6020830184612469565b604051601f8201601f191681016001600160401b03811182821017156125ab576125ab6126a4565b604052919050565b600082198211156125c6576125c6612662565b500190565b6000828210156125dd576125dd612662565b500390565b60005b838110156125fd5781810151838201526020016125e5565b8381111561260c576000848401525b50505050565b600181811c9082168061262657607f821691505b60208210811415610fd557634e487b7160e01b600052602260045260246000fd5b600060001982141561265b5761265b612662565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610c9257600080fdfea2646970667358221220ad5f1b47d2adf92bad4533ffe2cbf7d6d45660df712721af9b5b08a8d8a1354664736f6c63430008070033a264697066735822122081140cab24b2f20e9a5b523d33c6c2a7ee164454b8124f96173f9b1fbcb19e2964736f6c63430008070033a264697066735822122083966f1bf2e54ad35d555dfb0382060ad6b77a5f07635e8bb19f15134b060f3a64736f6c63430008070033