- Contract name:
- TreasuryV3
- Optimization enabled
- true
- Compiler version
- v0.8.9+commit.e5eed63a
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-06-01T19:12:14.658299Z
Contract source code
// Sources flattened with hardhat v2.8.3 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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/math/[email protected] // 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/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/lib/Babylonian.sol pragma solidity 0.8.9; library Babylonian { function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } // else z = 0 } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File contracts/owner/Operator.sol pragma solidity 0.8.9; contract Operator is Context, Ownable { address private _operator; event OperatorTransferred(address indexed previousOperator, address indexed newOperator); constructor() { _operator = _msgSender(); emit OperatorTransferred(address(0), _operator); } function operator() public view returns (address) { return _operator; } modifier onlyOperator() { require(_operator == msg.sender, "operator: caller is not the operator"); _; } function isOperator() public view returns (bool) { return _msgSender() == _operator; } function transferOperator(address newOperator_) public onlyOwner { _transferOperator(newOperator_); } function _transferOperator(address newOperator_) internal { require(newOperator_ != address(0), "operator: zero address given for new operator"); emit OperatorTransferred(address(0), newOperator_); _operator = newOperator_; } } // File contracts/utils/ContractGuard.sol pragma solidity 0.8.9; contract ContractGuard { mapping(uint256 => mapping(address => bool)) private _status; function checkSameOriginReentranted() internal view returns (bool) { return _status[block.number][tx.origin]; } function checkSameSenderReentranted() internal view returns (bool) { return _status[block.number][msg.sender]; } modifier onlyOneBlock() { require(!checkSameOriginReentranted(), "ContractGuard: one block, one function"); require(!checkSameSenderReentranted(), "ContractGuard: one block, one function"); _; _status[block.number][tx.origin] = true; _status[block.number][msg.sender] = true; } } // File contracts/interfaces/IBasisAsset.sol pragma solidity 0.8.9; interface IBasisAsset { function mint(address recipient, uint256 amount) external returns (bool); function burn(uint256 amount) external; function burnFrom(address from, uint256 amount) external; function isOperator() external returns (bool); function operator() external view returns (address); function transferOperator(address newOperator_) external; } // File contracts/interfaces/IPrinter.sol pragma solidity 0.8.9; interface IPrinter { function balanceOf(address _mason) external view returns (uint256); function earned(address _mason) external view returns (uint256); function canWithdraw(address _mason) external view returns (bool); function canClaimReward(address _mason) external view returns (bool); function epoch() external view returns (uint256); function nextEpochPoint() external view returns (uint256); function setOperator(address _operator) external; function setLockUp(uint256 _withdrawLockupEpochs, uint256 _rewardLockupEpochs) external; function stake(uint256 _amount) external; function withdraw(uint256 _amount) external; function exit() external; function claimReward() external; function allocateSeigniorage(uint256 _amount) external; function governanceRecoverUnsupported(address _token, uint256 _amount, address _to) external; } // File contracts/interfaces/IInk.sol pragma solidity 0.8.9; interface IInk { function mint(address recipient, uint256 amount) external returns (bool); function burn(uint256 amount) external; function burnFrom(address from, uint256 amount) external; function isOperator() external returns (bool); function operator() external view returns (address); function transferOperator(address newOperator_) external; function setTaxRate(uint256 _taxRate) external; function setNoTaxSenderAddr(address _noTaxSenderAddr, bool _value) external; function setNoTaxRecipientAddr(address _noTaxRecipientAddr, bool _value) external; function setNoTax(address _noTaxAddr, bool _value) external; function setInvestmentFundAddress(address _investmentFund) external; function setDevFundAddress(address _devFund) external; } // File contracts/TreasuryV3.sol pragma solidity 0.8.9; contract TreasuryV3 is ContractGuard { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; // governance address public operator; mapping(address => bool) public bridgeOperators; mapping(address => bool) public bridgeAdmins; // flags bool public initialized = false; // epoch uint256 public startTime; uint256 public epoch = 0; uint256 public epochPeriod = 6 hours; // core components address public paper; address public ink; address public printer; // supply uint256 public totalPaperMinted; uint256 public lastMint; uint256 public maxPaperToMint = 5000000 ether; uint16[] public mintTable = [ 10,26,42,58,74,90,106,121,137,152,167,182,197,212,227,242,256,270,285,299,313,327,341,355,368,382,395,408,422,435,448,461,473,486,499,511,523,536,548,560,572,584,595,607,619,630,642,653,664,675,686,697,708,719,729,740,750,761,771,781,791,801,811,821,831,840,850,859,869,878,887,896,906,915,923,932,941,950,958,967,975,984,992,1000,1008,1016,1024,1032,1040,1048,1055,1063,1071,1078,1085,1093,1100,1107,1114,1121,1128, 1135,1142,1149,1155,1162,1169,1175,1181,1188,1194,1200,1207,1213,1219,1225,1231,1236,1242,1248,1254,1259,1265,1270,1276,1281,1286,1292,1297,1302,1307,1312,1317,1322,1327,1331,1336,1341,1345,1350,1355,1359,1363,1368,1372,1376,1381,1385,1389,1393,1397,1401,1405,1409,1412,1416,1420,1423,1427,1431,1434,1438,1441,1444,1448,1451,1454,1457,1460,1464,1467,1470,1473,1475,1478,1481,1484,1487,1489,1492,1495,1497,1500,1502,1505,1507,1510,1512,1514,1516,1519,1521,1523,1525,1527,1529,1531,1533,1535,1537,1539,1541, 1542,1544,1546,1547,1549,1551,1552,1554,1555,1557,1558,1560,1561,1562,1564,1565,1566,1567,1568,1570,1571,1572,1573,1574,1575,1576,1577,1578,1578,1579,1580,1581,1582,1582,1583,1584,1584,1585,1585,1586,1587,1587,1588,1588,1588,1589,1589,1589,1590,1590,1590,1591,1591,1591,1591,1591,1591,1592,1592,1592,1592,1592,1592,1592,1592,1591,1591,1591,1591,1591,1591,1591,1590,1590,1590,1589,1589,1589,1588,1588,1588,1587,1587,1586,1586,1585,1585,1584,1584,1583,1583,1582,1581,1581,1580,1579,1579,1578,1577,1576,1576, 1575,1574,1573,1572,1572,1571,1570,1569,1568,1567,1566,1565,1564,1563,1562,1561,1560,1559,1558,1557,1556,1555,1554,1552,1551,1550,1549,1548,1547,1545,1544,1543,1542,1540,1539,1538,1536,1535,1534,1532,1531,1530,1528,1527,1526,1524,1523,1521,1520,1518,1517,1515,1514,1512,1511,1509,1508,1506,1505,1503,1502,1500,1499,1498,1496,1495,1494,1493,1492,1491,1490,1488,1487,1486,1485,1484,1483,1482,1480,1479,1478,1477,1476,1475,1474,1472,1471,1470,1469,1468,1467,1466,1464,1463,1462,1461,1460,1459,1458,1456,1455, 1454,1453,1452,1451,1450,1448,1447,1446,1445,1444,1443,1442,1440,1439,1438,1437,1436,1435,1434,1432,1431,1430,1429,1428,1427,1426,1424,1423,1422,1421,1420,1419,1418,1416,1415,1414,1413,1412,1411,1410,1408,1407,1406,1405,1404,1403,1402,1400,1399,1398,1397,1396,1395,1394,1392,1391,1390,1389,1388,1387,1386,1384,1383,1382,1381,1380,1379,1378,1376,1375,1374,1373,1372,1371,1370,1368,1367,1366,1365,1364,1363,1362,1360,1359,1358,1357,1356,1355,1354,1352,1351,1350,1349,1348,1347,1345,1344,1343,1342,1341,1340, 1339,1337,1336,1335,1334,1333,1332,1331,1329,1328,1327,1326,1325,1324,1323,1321,1320,1319,1318,1317,1316,1315,1313,1312,1311,1310,1309,1308,1307,1305,1304,1303,1302,1301,1300,1299,1297,1296,1295,1294,1293,1292,1291,1289,1288,1287,1286,1285,1284,1283,1281,1280,1279,1278,1277,1276,1275,1273,1272,1271,1270,1269,1268,1267,1265,1264,1263,1262,1261,1260,1259,1257,1256,1255,1254,1253,1252,1251,1249,1248,1247,1246,1245,1244,1243,1241,1240,1239,1238,1237,1236,1235,1233,1232,1231,1230,1229,1228,1227,1225,1224, 1223,1222,1221,1220,1219,1217,1216,1215,1214,1213,1212,1211,1209,1208,1207,1206,1205,1204,1203,1201,1200,1199,1198,1197,1196,1194,1193,1192,1191,1190,1189,1188,1186,1185,1184,1183,1182,1181,1180,1178,1177,1176,1175,1174,1173,1172,1170,1169,1168,1167,1166,1165,1164,1162,1161,1160,1159,1158,1157,1156,1154,1153,1152,1151,1150,1149,1148,1146,1145,1144,1143,1142,1141,1140,1138,1137,1136,1135,1134,1133,1132,1130,1129,1128,1127,1126,1125,1124,1122,1121,1120,1119,1118,1117,1116,1114,1113,1112,1111,1110,1109, 1108,1106,1105,1104,1103,1102,1101,1100,1098,1097,1096,1095,1094,1093,1092,1090,1089,1088,1087,1086,1085,1084,1082,1081,1080,1079,1078,1077,1076,1074,1073,1072,1071,1070,1069,1068,1066,1065,1064,1063,1062,1061,1060,1058,1057,1056,1055,1054,1053,1051,1050,1049,1048,1047,1046,1045,1043,1042,1041,1040,1039,1038,1037,1035,1034,1033,1032,1031,1030,1029,1027,1026,1025,1024,1023,1022,1021,1019,1018,1017,1016,1015,1014,1013,1011,1010,1009,1008,1007,1006,1005,1003,1002,1001,1000,999,998,997,995,994,993, 992,991,990,989,987,986,985,984,983,982,981,979,978,977,976,975,974,973,971,970,969,968,967,966,965,963,962,961,960,959,958,957,955,954,953,952,951,950,949,947,946,945,944,943,942,941,939,938,937,936,935,934,933,931,930,929,928,927,926,925,923,922,921,920,919,918,917,915,914,913,912,911,910,909,907,906,905,904,903,902,900,899,898,897,896,895,894,892,891,890,889,888,887,886,884,883,882,881,880,879,878, 876,875,874,873,872,871,870,868,867,866,865,864,863,862,860,859,858,857,856,855,854,852,851,850,849,848,847,846,844,843,842,841,840,839,838,836,835,834,833,832,831,830,828,827,826,825,824,823,822,820,819,818,817,816,815,814,812,811,810,809,808,807,806,804,803,802,801,800,799,798,796,795,794,793,792,791,790,788,787,786,785,784,783,782,780,779,778,777,776,775,774,772,771,770,769,768,767,766,764,763,762, 761,760,759,758,756,755,754,753,752,751,749,748,747,746,745,744,743,741,740,739,738,737,736,735,733,732,731,730,729,728,727,725,724,723,722,721,720,719,717,716,715,714,713,712,711,709,708,707,706,705,704,703,701,700,699,698,697,696,695,693,692,691,690,689,688,687,685,684,683,682,681,680,679,677,676,675,674,673,672,671,669,668,667,666 ]; // events event Initialized(address indexed executor, uint256 at); event PrinterFunded (uint256 timestamp, uint256 seigniorage); event SetBridgeAdmin(address adminAddress, bool enabled); event SetBridgeOperator(address operatorAddress, bool enabled); event SetMaxPaperToMint(uint256 paperAmount); event SetTotalPaperMinted(uint256 paperAmount); event SetInkTaxRate(uint256 taxRate); event SetOperator(address operator); event SetEpoch(uint256 epoch); event SetStartTime(uint256 startTime); event ClearBridgeAdmins(); event ClearBridgeOperators(); modifier onlyOperator() { require(operator == msg.sender, "Treasury: caller is not the operator"); _; } modifier onlyBridgeOperators { require(bridgeOperators[msg.sender] == true, "Treasury: caller is not a bridge operator"); _; } modifier onlyBridgeAdmins { require(bridgeAdmins[msg.sender] == true, "Treasury: caller is not a bridge admin"); _; } modifier checkCondition { require(block.timestamp >= startTime, "Treasury: not started yet"); _; } modifier checkEpoch { require(block.timestamp >= nextEpochPoint(), "Treasury: not opened yet"); _; epoch = epoch.add(1); } modifier checkOperator { require( IBasisAsset(paper).operator() == address(this) && IBasisAsset(ink).operator() == address(this) && Operator(printer).operator() == address(this), "Treasury: need more permission" ); _; } modifier notInitialized { require(!initialized, "Treasury: already initialized"); _; } /* ========== VIEW FUNCTIONS ========== */ function isInitialized() public view returns (bool) { return initialized; } // epoch function nextEpochPoint() public view returns (uint256) { return startTime.add(epoch.mul(epochPeriod)); } /* ========== GOVERNANCE ========== */ function initialize( address _paper, address _ink, address _printer, uint256 _startTime, uint256 _epochPeriod ) public notInitialized { paper = _paper; ink = _ink; printer = _printer; startTime = _startTime; epochPeriod = _epochPeriod; initialized = true; operator = msg.sender; bridgeAdmins[msg.sender] = true; emit Initialized(msg.sender, block.number); } /* PUBLIC FUNCTIONS */ function allocateSeigniorage() external onlyOneBlock checkCondition checkEpoch checkOperator { require(totalPaperMinted <= maxPaperToMint, "Treasury: Max paper already minted"); uint256 _toMint; uint256 _dayIndex = epoch/4; if (_dayIndex < 365) { if (_dayIndex >= mintTable.length) { _dayIndex = mintTable.length - 1; } _toMint = uint256(mintTable[_dayIndex]) * (10**18); } else { _toMint = lastMint - (0.29 ether); } if(totalPaperMinted + _toMint > maxPaperToMint) { _toMint = maxPaperToMint - totalPaperMinted; } totalPaperMinted = totalPaperMinted + _toMint; lastMint = _toMint; _sendToPrinter(_toMint); } /* END PUBLIC FUNCTIONS */ /* OPERATOR FUNCTIONS */ function setMaxPaperToMint(uint256 _paperAmount) external onlyOperator { maxPaperToMint = _paperAmount; emit SetMaxPaperToMint(_paperAmount); } function setTotalPaperMinted(uint256 _paperAmount) external onlyOperator { totalPaperMinted = _paperAmount; emit SetTotalPaperMinted(_paperAmount); } function setEpoch(uint256 _epoch) external onlyOperator { epoch = _epoch; emit SetEpoch(_epoch); } function setStartTime(uint256 _startTime) external onlyOperator { startTime = _startTime; emit SetStartTime(_startTime); } function setOperator(address _operator) external onlyOperator { operator = _operator; emit SetOperator(_operator); } function setInkTaxRate(uint256 _taxRate) external onlyOperator { IInk(ink).setTaxRate(_taxRate); emit SetInkTaxRate(_taxRate); } function setInkNoTaxSenderAddr(address _noTaxSenderAddr, bool _value) external onlyOperator { IInk(ink).setNoTaxSenderAddr(_noTaxSenderAddr, _value); } function setInkNoTaxRecipientAddr(address _noTaxRecipientAddr, bool _value) external onlyOperator { IInk(ink).setNoTaxRecipientAddr(_noTaxRecipientAddr, _value); } function setInkNoTax(address _noTaxAddr, bool _value) external onlyOperator { IInk(ink).setNoTax(_noTaxAddr, _value); } function setInkInvestmentFundAddress(address _investmentFund) external onlyOperator { IInk(ink).setInvestmentFundAddress(_investmentFund); } function setInkDevFundAddress(address _devFund) external onlyOperator { IInk(ink).setDevFundAddress(_devFund); } function governanceRecoverUnsupported( IERC20 _token, uint256 _amount, address _to ) external onlyOperator { _token.safeTransfer(_to, _amount); } function paperSetOperator(address _operator) external onlyOperator { IBasisAsset(paper).transferOperator(_operator); } function inkSetOperator(address _operator) external onlyOperator { IBasisAsset(ink).transferOperator(_operator); } function printerSetOperator(address _operator) external onlyOperator { IPrinter(printer).setOperator(_operator); } function printerSetLockUp(uint256 _withdrawLockupEpochs, uint256 _rewardLockupEpochs) external onlyOperator { IPrinter(printer).setLockUp(_withdrawLockupEpochs, _rewardLockupEpochs); } function printerGovernanceRecoverUnsupported( address _token, uint256 _amount, address _to ) external onlyOperator { IPrinter(printer).governanceRecoverUnsupported(_token, _amount, _to); } /* END OPERATOR FUNCTIONS */ /* BRIDGE ADMIN FUNCTIONS */ function setBridgeOperator(address _operatorAddress, bool _enabled) external onlyBridgeAdmins { bridgeOperators[_operatorAddress] = _enabled; emit SetBridgeOperator(_operatorAddress, _enabled); } function setBridgeAdmin(address _adminAddress, bool _enabled) external onlyBridgeAdmins { bridgeAdmins[_adminAddress] = _enabled; emit SetBridgeAdmin(_adminAddress, _enabled); } /* END BRIDGE ADMIN FUNCTIONS */ /* BRIDGE OPERATOR FUNCTIONS */ function bridgeMint(address _recipient, uint256 _amount) external onlyBridgeOperators { IBasisAsset(paper).mint(_recipient, _amount); } /* END BRIDGE OPERATOR FUNCTIONS */ /* INTERNAL FUNCTIONS */ function _sendToPrinter(uint256 _amount) internal { IBasisAsset(paper).mint(address(this), _amount); IERC20(paper).safeApprove(printer, 0); IERC20(paper).safeApprove(printer, _amount); IPrinter(printer).allocateSeigniorage(_amount); emit PrinterFunded(block.timestamp, _amount); } /* END INTERNAL FUNCTIONS */ }
Contract ABI
[{"type":"event","name":"ClearBridgeAdmins","inputs":[],"anonymous":false},{"type":"event","name":"ClearBridgeOperators","inputs":[],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"address","name":"executor","internalType":"address","indexed":true},{"type":"uint256","name":"at","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"PrinterFunded","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"uint256","name":"seigniorage","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetBridgeAdmin","inputs":[{"type":"address","name":"adminAddress","internalType":"address","indexed":false},{"type":"bool","name":"enabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"SetBridgeOperator","inputs":[{"type":"address","name":"operatorAddress","internalType":"address","indexed":false},{"type":"bool","name":"enabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"SetEpoch","inputs":[{"type":"uint256","name":"epoch","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetInkTaxRate","inputs":[{"type":"uint256","name":"taxRate","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetMaxPaperToMint","inputs":[{"type":"uint256","name":"paperAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetOperator","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetStartTime","inputs":[{"type":"uint256","name":"startTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetTotalPaperMinted","inputs":[{"type":"uint256","name":"paperAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"allocateSeigniorage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"bridgeAdmins","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"bridgeMint","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"bridgeOperators","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"epoch","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"epochPeriod","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"governanceRecoverUnsupported","inputs":[{"type":"address","name":"_token","internalType":"contract IERC20"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_paper","internalType":"address"},{"type":"address","name":"_ink","internalType":"address"},{"type":"address","name":"_printer","internalType":"address"},{"type":"uint256","name":"_startTime","internalType":"uint256"},{"type":"uint256","name":"_epochPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"initialized","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"ink","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"inkSetOperator","inputs":[{"type":"address","name":"_operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isInitialized","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastMint","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxPaperToMint","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"mintTable","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nextEpochPoint","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"operator","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"paper","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"paperSetOperator","inputs":[{"type":"address","name":"_operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"printer","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"printerGovernanceRecoverUnsupported","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"printerSetLockUp","inputs":[{"type":"uint256","name":"_withdrawLockupEpochs","internalType":"uint256"},{"type":"uint256","name":"_rewardLockupEpochs","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"printerSetOperator","inputs":[{"type":"address","name":"_operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBridgeAdmin","inputs":[{"type":"address","name":"_adminAddress","internalType":"address"},{"type":"bool","name":"_enabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBridgeOperator","inputs":[{"type":"address","name":"_operatorAddress","internalType":"address"},{"type":"bool","name":"_enabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEpoch","inputs":[{"type":"uint256","name":"_epoch","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkDevFundAddress","inputs":[{"type":"address","name":"_devFund","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkInvestmentFundAddress","inputs":[{"type":"address","name":"_investmentFund","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkNoTax","inputs":[{"type":"address","name":"_noTaxAddr","internalType":"address"},{"type":"bool","name":"_value","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkNoTaxRecipientAddr","inputs":[{"type":"address","name":"_noTaxRecipientAddr","internalType":"address"},{"type":"bool","name":"_value","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkNoTaxSenderAddr","inputs":[{"type":"address","name":"_noTaxSenderAddr","internalType":"address"},{"type":"bool","name":"_value","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInkTaxRate","inputs":[{"type":"uint256","name":"_taxRate","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxPaperToMint","inputs":[{"type":"uint256","name":"_paperAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setOperator","inputs":[{"type":"address","name":"_operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStartTime","inputs":[{"type":"uint256","name":"_startTime","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTotalPaperMinted","inputs":[{"type":"uint256","name":"_paperAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalPaperMinted","inputs":[]}]
Contract Creation Code
0x60806040526000600460006101000a81548160ff02191690831515021790555060006006556154606007556a0422ca8b0a00a425000000600d55604051806188c00160405280600a61ffff168152602001601a61ffff168152602001602a61ffff168152602001603a61ffff168152602001604a61ffff168152602001605a61ffff168152602001606a61ffff168152602001607961ffff168152602001608961ffff168152602001609861ffff16815260200160a761ffff16815260200160b661ffff16815260200160c561ffff16815260200160d461ffff16815260200160e361ffff16815260200160f261ffff16815260200161010061ffff16815260200161010e61ffff16815260200161011d61ffff16815260200161012b61ffff16815260200161013961ffff16815260200161014761ffff16815260200161015561ffff16815260200161016361ffff16815260200161017061ffff16815260200161017e61ffff16815260200161018b61ffff16815260200161019861ffff1681526020016101a661ffff1681526020016101b361ffff1681526020016101c061ffff1681526020016101cd61ffff1681526020016101d961ffff1681526020016101e661ffff1681526020016101f361ffff1681526020016101ff61ffff16815260200161020b61ffff16815260200161021861ffff16815260200161022461ffff16815260200161023061ffff16815260200161023c61ffff16815260200161024861ffff16815260200161025361ffff16815260200161025f61ffff16815260200161026b61ffff16815260200161027661ffff16815260200161028261ffff16815260200161028d61ffff16815260200161029861ffff1681526020016102a361ffff1681526020016102ae61ffff1681526020016102b961ffff1681526020016102c461ffff1681526020016102cf61ffff1681526020016102d961ffff1681526020016102e461ffff1681526020016102ee61ffff1681526020016102f961ffff16815260200161030361ffff16815260200161030d61ffff16815260200161031761ffff16815260200161032161ffff16815260200161032b61ffff16815260200161033561ffff16815260200161033f61ffff16815260200161034861ffff16815260200161035261ffff16815260200161035b61ffff16815260200161036561ffff16815260200161036e61ffff16815260200161037761ffff16815260200161038061ffff16815260200161038a61ffff16815260200161039361ffff16815260200161039b61ffff1681526020016103a461ffff1681526020016103ad61ffff1681526020016103b661ffff1681526020016103be61ffff1681526020016103c761ffff1681526020016103cf61ffff1681526020016103d861ffff1681526020016103e061ffff1681526020016103e861ffff1681526020016103f061ffff1681526020016103f861ffff16815260200161040061ffff16815260200161040861ffff16815260200161041061ffff16815260200161041861ffff16815260200161041f61ffff16815260200161042761ffff16815260200161042f61ffff16815260200161043661ffff16815260200161043d61ffff16815260200161044561ffff16815260200161044c61ffff16815260200161045361ffff16815260200161045a61ffff16815260200161046161ffff16815260200161046861ffff16815260200161046f61ffff16815260200161047661ffff16815260200161047d61ffff16815260200161048361ffff16815260200161048a61ffff16815260200161049161ffff16815260200161049761ffff16815260200161049d61ffff1681526020016104a461ffff1681526020016104aa61ffff1681526020016104b061ffff1681526020016104b761ffff1681526020016104bd61ffff1681526020016104c361ffff1681526020016104c961ffff1681526020016104cf61ffff1681526020016104d461ffff1681526020016104da61ffff1681526020016104e061ffff1681526020016104e661ffff1681526020016104eb61ffff1681526020016104f161ffff1681526020016104f661ffff1681526020016104fc61ffff16815260200161050161ffff16815260200161050661ffff16815260200161050c61ffff16815260200161051161ffff16815260200161051661ffff16815260200161051b61ffff16815260200161052061ffff16815260200161052561ffff16815260200161052a61ffff16815260200161052f61ffff16815260200161053361ffff16815260200161053861ffff16815260200161053d61ffff16815260200161054161ffff16815260200161054661ffff16815260200161054b61ffff16815260200161054f61ffff16815260200161055361ffff16815260200161055861ffff16815260200161055c61ffff16815260200161056061ffff16815260200161056561ffff16815260200161056961ffff16815260200161056d61ffff16815260200161057161ffff16815260200161057561ffff16815260200161057961ffff16815260200161057d61ffff16815260200161058161ffff16815260200161058461ffff16815260200161058861ffff16815260200161058c61ffff16815260200161058f61ffff16815260200161059361ffff16815260200161059761ffff16815260200161059a61ffff16815260200161059e61ffff1681526020016105a161ffff1681526020016105a461ffff1681526020016105a861ffff1681526020016105ab61ffff1681526020016105ae61ffff1681526020016105b161ffff1681526020016105b461ffff1681526020016105b861ffff1681526020016105bb61ffff1681526020016105be61ffff1681526020016105c161ffff1681526020016105c361ffff1681526020016105c661ffff1681526020016105c961ffff1681526020016105cc61ffff1681526020016105cf61ffff1681526020016105d161ffff1681526020016105d461ffff1681526020016105d761ffff1681526020016105d961ffff1681526020016105dc61ffff1681526020016105de61ffff1681526020016105e161ffff1681526020016105e361ffff1681526020016105e661ffff1681526020016105e861ffff1681526020016105ea61ffff1681526020016105ec61ffff1681526020016105ef61ffff1681526020016105f161ffff1681526020016105f361ffff1681526020016105f561ffff1681526020016105f761ffff1681526020016105f961ffff1681526020016105fb61ffff1681526020016105fd61ffff1681526020016105ff61ffff16815260200161060161ffff16815260200161060361ffff16815260200161060561ffff16815260200161060661ffff16815260200161060861ffff16815260200161060a61ffff16815260200161060b61ffff16815260200161060d61ffff16815260200161060f61ffff16815260200161061061ffff16815260200161061261ffff16815260200161061361ffff16815260200161061561ffff16815260200161061661ffff16815260200161061861ffff16815260200161061961ffff16815260200161061a61ffff16815260200161061c61ffff16815260200161061d61ffff16815260200161061e61ffff16815260200161061f61ffff16815260200161062061ffff16815260200161062261ffff16815260200161062361ffff16815260200161062461ffff16815260200161062561ffff16815260200161062661ffff16815260200161062761ffff16815260200161062861ffff16815260200161062961ffff16815260200161062a61ffff16815260200161062a61ffff16815260200161062b61ffff16815260200161062c61ffff16815260200161062d61ffff16815260200161062e61ffff16815260200161062e61ffff16815260200161062f61ffff16815260200161063061ffff16815260200161063061ffff16815260200161063161ffff16815260200161063161ffff16815260200161063261ffff16815260200161063361ffff16815260200161063361ffff16815260200161063461ffff16815260200161063461ffff16815260200161063461ffff16815260200161063561ffff16815260200161063561ffff16815260200161063561ffff16815260200161063661ffff16815260200161063661ffff16815260200161063661ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063861ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063761ffff16815260200161063661ffff16815260200161063661ffff16815260200161063661ffff16815260200161063561ffff16815260200161063561ffff16815260200161063561ffff16815260200161063461ffff16815260200161063461ffff16815260200161063461ffff16815260200161063361ffff16815260200161063361ffff16815260200161063261ffff16815260200161063261ffff16815260200161063161ffff16815260200161063161ffff16815260200161063061ffff16815260200161063061ffff16815260200161062f61ffff16815260200161062f61ffff16815260200161062e61ffff16815260200161062d61ffff16815260200161062d61ffff16815260200161062c61ffff16815260200161062b61ffff16815260200161062b61ffff16815260200161062a61ffff16815260200161062961ffff16815260200161062861ffff16815260200161062861ffff16815260200161062761ffff16815260200161062661ffff16815260200161062561ffff16815260200161062461ffff16815260200161062461ffff16815260200161062361ffff16815260200161062261ffff16815260200161062161ffff16815260200161062061ffff16815260200161061f61ffff16815260200161061e61ffff16815260200161061d61ffff16815260200161061c61ffff16815260200161061b61ffff16815260200161061a61ffff16815260200161061961ffff16815260200161061861ffff16815260200161061761ffff16815260200161061661ffff16815260200161061561ffff16815260200161061461ffff16815260200161061361ffff16815260200161061261ffff16815260200161061061ffff16815260200161060f61ffff16815260200161060e61ffff16815260200161060d61ffff16815260200161060c61ffff16815260200161060b61ffff16815260200161060961ffff16815260200161060861ffff16815260200161060761ffff16815260200161060661ffff16815260200161060461ffff16815260200161060361ffff16815260200161060261ffff16815260200161060061ffff1681526020016105ff61ffff1681526020016105fe61ffff1681526020016105fc61ffff1681526020016105fb61ffff1681526020016105fa61ffff1681526020016105f861ffff1681526020016105f761ffff1681526020016105f661ffff1681526020016105f461ffff1681526020016105f361ffff1681526020016105f161ffff1681526020016105f061ffff1681526020016105ee61ffff1681526020016105ed61ffff1681526020016105eb61ffff1681526020016105ea61ffff1681526020016105e861ffff1681526020016105e761ffff1681526020016105e561ffff1681526020016105e461ffff1681526020016105e261ffff1681526020016105e161ffff1681526020016105df61ffff1681526020016105de61ffff1681526020016105dc61ffff1681526020016105db61ffff1681526020016105da61ffff1681526020016105d861ffff1681526020016105d761ffff1681526020016105d661ffff1681526020016105d561ffff1681526020016105d461ffff1681526020016105d361ffff1681526020016105d261ffff1681526020016105d061ffff1681526020016105cf61ffff1681526020016105ce61ffff1681526020016105cd61ffff1681526020016105cc61ffff1681526020016105cb61ffff1681526020016105ca61ffff1681526020016105c861ffff1681526020016105c761ffff1681526020016105c661ffff1681526020016105c561ffff1681526020016105c461ffff1681526020016105c361ffff1681526020016105c261ffff1681526020016105c061ffff1681526020016105bf61ffff1681526020016105be61ffff1681526020016105bd61ffff1681526020016105bc61ffff1681526020016105bb61ffff1681526020016105ba61ffff1681526020016105b861ffff1681526020016105b761ffff1681526020016105b661ffff1681526020016105b561ffff1681526020016105b461ffff1681526020016105b361ffff1681526020016105b261ffff1681526020016105b061ffff1681526020016105af61ffff1681526020016105ae61ffff1681526020016105ad61ffff1681526020016105ac61ffff1681526020016105ab61ffff1681526020016105aa61ffff1681526020016105a861ffff1681526020016105a761ffff1681526020016105a661ffff1681526020016105a561ffff1681526020016105a461ffff1681526020016105a361ffff1681526020016105a261ffff1681526020016105a061ffff16815260200161059f61ffff16815260200161059e61ffff16815260200161059d61ffff16815260200161059c61ffff16815260200161059b61ffff16815260200161059a61ffff16815260200161059861ffff16815260200161059761ffff16815260200161059661ffff16815260200161059561ffff16815260200161059461ffff16815260200161059361ffff16815260200161059261ffff16815260200161059061ffff16815260200161058f61ffff16815260200161058e61ffff16815260200161058d61ffff16815260200161058c61ffff16815260200161058b61ffff16815260200161058a61ffff16815260200161058861ffff16815260200161058761ffff16815260200161058661ffff16815260200161058561ffff16815260200161058461ffff16815260200161058361ffff16815260200161058261ffff16815260200161058061ffff16815260200161057f61ffff16815260200161057e61ffff16815260200161057d61ffff16815260200161057c61ffff16815260200161057b61ffff16815260200161057a61ffff16815260200161057861ffff16815260200161057761ffff16815260200161057661ffff16815260200161057561ffff16815260200161057461ffff16815260200161057361ffff16815260200161057261ffff16815260200161057061ffff16815260200161056f61ffff16815260200161056e61ffff16815260200161056d61ffff16815260200161056c61ffff16815260200161056b61ffff16815260200161056a61ffff16815260200161056861ffff16815260200161056761ffff16815260200161056661ffff16815260200161056561ffff16815260200161056461ffff16815260200161056361ffff16815260200161056261ffff16815260200161056061ffff16815260200161055f61ffff16815260200161055e61ffff16815260200161055d61ffff16815260200161055c61ffff16815260200161055b61ffff16815260200161055a61ffff16815260200161055861ffff16815260200161055761ffff16815260200161055661ffff16815260200161055561ffff16815260200161055461ffff16815260200161055361ffff16815260200161055261ffff16815260200161055061ffff16815260200161054f61ffff16815260200161054e61ffff16815260200161054d61ffff16815260200161054c61ffff16815260200161054b61ffff16815260200161054a61ffff16815260200161054861ffff16815260200161054761ffff16815260200161054661ffff16815260200161054561ffff16815260200161054461ffff16815260200161054361ffff16815260200161054161ffff16815260200161054061ffff16815260200161053f61ffff16815260200161053e61ffff16815260200161053d61ffff16815260200161053c61ffff16815260200161053b61ffff16815260200161053961ffff16815260200161053861ffff16815260200161053761ffff16815260200161053661ffff16815260200161053561ffff16815260200161053461ffff16815260200161053361ffff16815260200161053161ffff16815260200161053061ffff16815260200161052f61ffff16815260200161052e61ffff16815260200161052d61ffff16815260200161052c61ffff16815260200161052b61ffff16815260200161052961ffff16815260200161052861ffff16815260200161052761ffff16815260200161052661ffff16815260200161052561ffff16815260200161052461ffff16815260200161052361ffff16815260200161052161ffff16815260200161052061ffff16815260200161051f61ffff16815260200161051e61ffff16815260200161051d61ffff16815260200161051c61ffff16815260200161051b61ffff16815260200161051961ffff16815260200161051861ffff16815260200161051761ffff16815260200161051661ffff16815260200161051561ffff16815260200161051461ffff16815260200161051361ffff16815260200161051161ffff16815260200161051061ffff16815260200161050f61ffff16815260200161050e61ffff16815260200161050d61ffff16815260200161050c61ffff16815260200161050b61ffff16815260200161050961ffff16815260200161050861ffff16815260200161050761ffff16815260200161050661ffff16815260200161050561ffff16815260200161050461ffff16815260200161050361ffff16815260200161050161ffff16815260200161050061ffff1681526020016104ff61ffff1681526020016104fe61ffff1681526020016104fd61ffff1681526020016104fc61ffff1681526020016104fb61ffff1681526020016104f961ffff1681526020016104f861ffff1681526020016104f761ffff1681526020016104f661ffff1681526020016104f561ffff1681526020016104f461ffff1681526020016104f361ffff1681526020016104f161ffff1681526020016104f061ffff1681526020016104ef61ffff1681526020016104ee61ffff1681526020016104ed61ffff1681526020016104ec61ffff1681526020016104eb61ffff1681526020016104e961ffff1681526020016104e861ffff1681526020016104e761ffff1681526020016104e661ffff1681526020016104e561ffff1681526020016104e461ffff1681526020016104e361ffff1681526020016104e161ffff1681526020016104e061ffff1681526020016104df61ffff1681526020016104de61ffff1681526020016104dd61ffff1681526020016104dc61ffff1681526020016104db61ffff1681526020016104d961ffff1681526020016104d861ffff1681526020016104d761ffff1681526020016104d661ffff1681526020016104d561ffff1681526020016104d461ffff1681526020016104d361ffff1681526020016104d161ffff1681526020016104d061ffff1681526020016104cf61ffff1681526020016104ce61ffff1681526020016104cd61ffff1681526020016104cc61ffff1681526020016104cb61ffff1681526020016104c961ffff1681526020016104c861ffff1681526020016104c761ffff1681526020016104c661ffff1681526020016104c561ffff1681526020016104c461ffff1681526020016104c361ffff1681526020016104c161ffff1681526020016104c061ffff1681526020016104bf61ffff1681526020016104be61ffff1681526020016104bd61ffff1681526020016104bc61ffff1681526020016104bb61ffff1681526020016104b961ffff1681526020016104b861ffff1681526020016104b761ffff1681526020016104b661ffff1681526020016104b561ffff1681526020016104b461ffff1681526020016104b361ffff1681526020016104b161ffff1681526020016104b061ffff1681526020016104af61ffff1681526020016104ae61ffff1681526020016104ad61ffff1681526020016104ac61ffff1681526020016104aa61ffff1681526020016104a961ffff1681526020016104a861ffff1681526020016104a761ffff1681526020016104a661ffff1681526020016104a561ffff1681526020016104a461ffff1681526020016104a261ffff1681526020016104a161ffff1681526020016104a061ffff16815260200161049f61ffff16815260200161049e61ffff16815260200161049d61ffff16815260200161049c61ffff16815260200161049a61ffff16815260200161049961ffff16815260200161049861ffff16815260200161049761ffff16815260200161049661ffff16815260200161049561ffff16815260200161049461ffff16815260200161049261ffff16815260200161049161ffff16815260200161049061ffff16815260200161048f61ffff16815260200161048e61ffff16815260200161048d61ffff16815260200161048c61ffff16815260200161048a61ffff16815260200161048961ffff16815260200161048861ffff16815260200161048761ffff16815260200161048661ffff16815260200161048561ffff16815260200161048461ffff16815260200161048261ffff16815260200161048161ffff16815260200161048061ffff16815260200161047f61ffff16815260200161047e61ffff16815260200161047d61ffff16815260200161047c61ffff16815260200161047a61ffff16815260200161047961ffff16815260200161047861ffff16815260200161047761ffff16815260200161047661ffff16815260200161047561ffff16815260200161047461ffff16815260200161047261ffff16815260200161047161ffff16815260200161047061ffff16815260200161046f61ffff16815260200161046e61ffff16815260200161046d61ffff16815260200161046c61ffff16815260200161046a61ffff16815260200161046961ffff16815260200161046861ffff16815260200161046761ffff16815260200161046661ffff16815260200161046561ffff16815260200161046461ffff16815260200161046261ffff16815260200161046161ffff16815260200161046061ffff16815260200161045f61ffff16815260200161045e61ffff16815260200161045d61ffff16815260200161045c61ffff16815260200161045a61ffff16815260200161045961ffff16815260200161045861ffff16815260200161045761ffff16815260200161045661ffff16815260200161045561ffff16815260200161045461ffff16815260200161045261ffff16815260200161045161ffff16815260200161045061ffff16815260200161044f61ffff16815260200161044e61ffff16815260200161044d61ffff16815260200161044c61ffff16815260200161044a61ffff16815260200161044961ffff16815260200161044861ffff16815260200161044761ffff16815260200161044661ffff16815260200161044561ffff16815260200161044461ffff16815260200161044261ffff16815260200161044161ffff16815260200161044061ffff16815260200161043f61ffff16815260200161043e61ffff16815260200161043d61ffff16815260200161043c61ffff16815260200161043a61ffff16815260200161043961ffff16815260200161043861ffff16815260200161043761ffff16815260200161043661ffff16815260200161043561ffff16815260200161043461ffff16815260200161043261ffff16815260200161043161ffff16815260200161043061ffff16815260200161042f61ffff16815260200161042e61ffff16815260200161042d61ffff16815260200161042c61ffff16815260200161042a61ffff16815260200161042961ffff16815260200161042861ffff16815260200161042761ffff16815260200161042661ffff16815260200161042561ffff16815260200161042461ffff16815260200161042261ffff16815260200161042161ffff16815260200161042061ffff16815260200161041f61ffff16815260200161041e61ffff16815260200161041d61ffff16815260200161041b61ffff16815260200161041a61ffff16815260200161041961ffff16815260200161041861ffff16815260200161041761ffff16815260200161041661ffff16815260200161041561ffff16815260200161041361ffff16815260200161041261ffff16815260200161041161ffff16815260200161041061ffff16815260200161040f61ffff16815260200161040e61ffff16815260200161040d61ffff16815260200161040b61ffff16815260200161040a61ffff16815260200161040961ffff16815260200161040861ffff16815260200161040761ffff16815260200161040661ffff16815260200161040561ffff16815260200161040361ffff16815260200161040261ffff16815260200161040161ffff16815260200161040061ffff1681526020016103ff61ffff1681526020016103fe61ffff1681526020016103fd61ffff1681526020016103fb61ffff1681526020016103fa61ffff1681526020016103f961ffff1681526020016103f861ffff1681526020016103f761ffff1681526020016103f661ffff1681526020016103f561ffff1681526020016103f361ffff1681526020016103f261ffff1681526020016103f161ffff1681526020016103f061ffff1681526020016103ef61ffff1681526020016103ee61ffff1681526020016103ed61ffff1681526020016103eb61ffff1681526020016103ea61ffff1681526020016103e961ffff1681526020016103e861ffff1681526020016103e761ffff1681526020016103e661ffff1681526020016103e561ffff1681526020016103e361ffff1681526020016103e261ffff1681526020016103e161ffff1681526020016103e061ffff1681526020016103df61ffff1681526020016103de61ffff1681526020016103dd61ffff1681526020016103db61ffff1681526020016103da61ffff1681526020016103d961ffff1681526020016103d861ffff1681526020016103d761ffff1681526020016103d661ffff1681526020016103d561ffff1681526020016103d361ffff1681526020016103d261ffff1681526020016103d161ffff1681526020016103d061ffff1681526020016103cf61ffff1681526020016103ce61ffff1681526020016103cd61ffff1681526020016103cb61ffff1681526020016103ca61ffff1681526020016103c961ffff1681526020016103c861ffff1681526020016103c761ffff1681526020016103c661ffff1681526020016103c561ffff1681526020016103c361ffff1681526020016103c261ffff1681526020016103c161ffff1681526020016103c061ffff1681526020016103bf61ffff1681526020016103be61ffff1681526020016103bd61ffff1681526020016103bb61ffff1681526020016103ba61ffff1681526020016103b961ffff1681526020016103b861ffff1681526020016103b761ffff1681526020016103b661ffff1681526020016103b561ffff1681526020016103b361ffff1681526020016103b261ffff1681526020016103b161ffff1681526020016103b061ffff1681526020016103af61ffff1681526020016103ae61ffff1681526020016103ad61ffff1681526020016103ab61ffff1681526020016103aa61ffff1681526020016103a961ffff1681526020016103a861ffff1681526020016103a761ffff1681526020016103a661ffff1681526020016103a561ffff1681526020016103a361ffff1681526020016103a261ffff1681526020016103a161ffff1681526020016103a061ffff16815260200161039f61ffff16815260200161039e61ffff16815260200161039d61ffff16815260200161039b61ffff16815260200161039a61ffff16815260200161039961ffff16815260200161039861ffff16815260200161039761ffff16815260200161039661ffff16815260200161039561ffff16815260200161039361ffff16815260200161039261ffff16815260200161039161ffff16815260200161039061ffff16815260200161038f61ffff16815260200161038e61ffff16815260200161038d61ffff16815260200161038b61ffff16815260200161038a61ffff16815260200161038961ffff16815260200161038861ffff16815260200161038761ffff16815260200161038661ffff16815260200161038461ffff16815260200161038361ffff16815260200161038261ffff16815260200161038161ffff16815260200161038061ffff16815260200161037f61ffff16815260200161037e61ffff16815260200161037c61ffff16815260200161037b61ffff16815260200161037a61ffff16815260200161037961ffff16815260200161037861ffff16815260200161037761ffff16815260200161037661ffff16815260200161037461ffff16815260200161037361ffff16815260200161037261ffff16815260200161037161ffff16815260200161037061ffff16815260200161036f61ffff16815260200161036e61ffff16815260200161036c61ffff16815260200161036b61ffff16815260200161036a61ffff16815260200161036961ffff16815260200161036861ffff16815260200161036761ffff16815260200161036661ffff16815260200161036461ffff16815260200161036361ffff16815260200161036261ffff16815260200161036161ffff16815260200161036061ffff16815260200161035f61ffff16815260200161035e61ffff16815260200161035c61ffff16815260200161035b61ffff16815260200161035a61ffff16815260200161035961ffff16815260200161035861ffff16815260200161035761ffff16815260200161035661ffff16815260200161035461ffff16815260200161035361ffff16815260200161035261ffff16815260200161035161ffff16815260200161035061ffff16815260200161034f61ffff16815260200161034e61ffff16815260200161034c61ffff16815260200161034b61ffff16815260200161034a61ffff16815260200161034961ffff16815260200161034861ffff16815260200161034761ffff16815260200161034661ffff16815260200161034461ffff16815260200161034361ffff16815260200161034261ffff16815260200161034161ffff16815260200161034061ffff16815260200161033f61ffff16815260200161033e61ffff16815260200161033c61ffff16815260200161033b61ffff16815260200161033a61ffff16815260200161033961ffff16815260200161033861ffff16815260200161033761ffff16815260200161033661ffff16815260200161033461ffff16815260200161033361ffff16815260200161033261ffff16815260200161033161ffff16815260200161033061ffff16815260200161032f61ffff16815260200161032e61ffff16815260200161032c61ffff16815260200161032b61ffff16815260200161032a61ffff16815260200161032961ffff16815260200161032861ffff16815260200161032761ffff16815260200161032661ffff16815260200161032461ffff16815260200161032361ffff16815260200161032261ffff16815260200161032161ffff16815260200161032061ffff16815260200161031f61ffff16815260200161031e61ffff16815260200161031c61ffff16815260200161031b61ffff16815260200161031a61ffff16815260200161031961ffff16815260200161031861ffff16815260200161031761ffff16815260200161031661ffff16815260200161031461ffff16815260200161031361ffff16815260200161031261ffff16815260200161031161ffff16815260200161031061ffff16815260200161030f61ffff16815260200161030e61ffff16815260200161030c61ffff16815260200161030b61ffff16815260200161030a61ffff16815260200161030961ffff16815260200161030861ffff16815260200161030761ffff16815260200161030661ffff16815260200161030461ffff16815260200161030361ffff16815260200161030261ffff16815260200161030161ffff16815260200161030061ffff1681526020016102ff61ffff1681526020016102fe61ffff1681526020016102fc61ffff1681526020016102fb61ffff1681526020016102fa61ffff1681526020016102f961ffff1681526020016102f861ffff1681526020016102f761ffff1681526020016102f661ffff1681526020016102f461ffff1681526020016102f361ffff1681526020016102f261ffff1681526020016102f161ffff1681526020016102f061ffff1681526020016102ef61ffff1681526020016102ed61ffff1681526020016102ec61ffff1681526020016102eb61ffff1681526020016102ea61ffff1681526020016102e961ffff1681526020016102e861ffff1681526020016102e761ffff1681526020016102e561ffff1681526020016102e461ffff1681526020016102e361ffff1681526020016102e261ffff1681526020016102e161ffff1681526020016102e061ffff1681526020016102df61ffff1681526020016102dd61ffff1681526020016102dc61ffff1681526020016102db61ffff1681526020016102da61ffff1681526020016102d961ffff1681526020016102d861ffff1681526020016102d761ffff1681526020016102d561ffff1681526020016102d461ffff1681526020016102d361ffff1681526020016102d261ffff1681526020016102d161ffff1681526020016102d061ffff1681526020016102cf61ffff1681526020016102cd61ffff1681526020016102cc61ffff1681526020016102cb61ffff1681526020016102ca61ffff1681526020016102c961ffff1681526020016102c861ffff1681526020016102c761ffff1681526020016102c561ffff1681526020016102c461ffff1681526020016102c361ffff1681526020016102c261ffff1681526020016102c161ffff1681526020016102c061ffff1681526020016102bf61ffff1681526020016102bd61ffff1681526020016102bc61ffff1681526020016102bb61ffff1681526020016102ba61ffff1681526020016102b961ffff1681526020016102b861ffff1681526020016102b761ffff1681526020016102b561ffff1681526020016102b461ffff1681526020016102b361ffff1681526020016102b261ffff1681526020016102b161ffff1681526020016102b061ffff1681526020016102af61ffff1681526020016102ad61ffff1681526020016102ac61ffff1681526020016102ab61ffff1681526020016102aa61ffff1681526020016102a961ffff1681526020016102a861ffff1681526020016102a761ffff1681526020016102a561ffff1681526020016102a461ffff1681526020016102a361ffff1681526020016102a261ffff1681526020016102a161ffff1681526020016102a061ffff16815260200161029f61ffff16815260200161029d61ffff16815260200161029c61ffff16815260200161029b61ffff16815260200161029a61ffff16815250600e906104466200338e929190620033a3565b503480156200339c57600080fd5b506200346a565b82805482825590600052602060002090600f01601090048101928215620034415791602002820160005b838211156200340f57835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302620033cd565b80156200343f5782816101000a81549061ffff02191690556002016020816001010492830192600103026200340f565b505b506200344f92915062003453565b5090565b5b808211156200344f576000815560010162003454565b611dd8806200347a6000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c8063755f041111610130578063ba8d4dee116100b8578063d7a164ee1161007c578063d7a164ee1461049a578063e89485d4146104ad578063ee08c300146104d0578063f83a1a7f146104e3578063f8c587ac1461050657600080fd5b8063ba8d4dee1461045a578063c47ee61d14610463578063c52e417e14610476578063c5967c2614610489578063d5604fa21461049157600080fd5b8063900cf0cf116100ff578063900cf0cf1461040f578063a693c9ee14610418578063a6b63eb81461042b578063b3ab15fb1461043e578063b5b7a1841461045157600080fd5b8063755f0411146103cd57806378e97925146103e05780637df3fa82146103e95780638c2a993e146103fc57600080fd5b80633e0a322d116101be5780635b756179116101825780635b756179146103665780635bf2cb551461036e5780636254df78146103815780636908f0f31461039457806374eac9d2146103a757600080fd5b80633e0a322d146103035780634ab7f20d1461031657806354575af414610329578063570ca7351461033c578063586fc5b51461034f57600080fd5b80632a018786116102055780632a018786146102ac5780632b46206c146102bf57806334ae2535146102d2578063392e53cd146102e55780633ab043b2146102f057600080fd5b80630ceb2cef14610237578063158ef93e1461024c5780631d3a0c981461026e57806324a063ee14610299575b600080fd5b61024a6102453660046119e4565b610519565b005b6004546102599060ff1681565b60405190151581526020015b60405180910390f35b600a54610281906001600160a01b031681565b6040516001600160a01b039091168152602001610265565b61024a6102a7366004611a23565b610588565b61024a6102ba366004611a23565b61061e565b61024a6102cd3660046119e4565b6106b6565b61024a6102e0366004611a5c565b610715565b60045460ff16610259565b61024a6102fe366004611a23565b6107a2565b61024a6103113660046119e4565b610832565b61024a610324366004611a23565b610891565b61024a610337366004611a79565b6108f5565b600154610281906001600160a01b031681565b610358600c5481565b604051908152602001610265565b61024a610938565b61024a61037c366004611a5c565b610dd5565b61024a61038f366004611a5c565b610e31565b61024a6103a2366004611a23565b610e8d565b6103ba6103b53660046119e4565b610ef1565b60405161ffff9091168152602001610265565b61024a6103db366004611a5c565b610f29565b61035860055481565b61024a6103f7366004611abb565b610f85565b61024a61040a366004611add565b610fe7565b61035860065481565b61024a6104263660046119e4565b6110e3565b61024a610439366004611b09565b611142565b61024a61044c366004611a5c565b61124b565b61035860075481565b610358600b5481565b61024a610471366004611a5c565b6112c3565b61024a6104843660046119e4565b61131f565b6103586113d8565b610358600d5481565b61024a6104a8366004611a79565b611402565b6102596104bb366004611a5c565b60036020526000908152604090205460ff1681565b600954610281906001600160a01b031681565b6102596104f1366004611a5c565b60026020526000908152604090205460ff1681565b600854610281906001600160a01b031681565b6001546001600160a01b0316331461054c5760405162461bcd60e51b815260040161054390611b64565b60405180910390fd5b60068190556040518181527f98ea2c8840699940892e55a1179c1b4fa1bf54d8e1e9b653e52cb4bda9b11849906020015b60405180910390a150565b6001546001600160a01b031633146105b25760405162461bcd60e51b815260040161054390611b64565b600954604051632f507df760e01b81526001600160a01b038481166004830152831515602483015290911690632f507df7906044015b600060405180830381600087803b15801561060257600080fd5b505af1158015610616573d6000803e3d6000fd5b505050505050565b3360009081526003602052604090205460ff1615156001146106525760405162461bcd60e51b815260040161054390611ba8565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527ff9ac756fc793b6681391c0d51419515e57429852bc8bd4b37040ad5e5c3addd491015b60405180910390a15050565b6001546001600160a01b031633146106e05760405162461bcd60e51b815260040161054390611b64565b600d8190556040518181527f77c7ba9de8933559168f05d084288c5afefbc158768783a41fb296567951d0719060200161057d565b6001546001600160a01b0316331461073f5760405162461bcd60e51b815260040161054390611b64565b600a5460405163b3ab15fb60e01b81526001600160a01b0383811660048301529091169063b3ab15fb906024015b600060405180830381600087803b15801561078757600080fd5b505af115801561079b573d6000803e3d6000fd5b5050505050565b3360009081526003602052604090205460ff1615156001146107d65760405162461bcd60e51b815260040161054390611ba8565b6001600160a01b038216600081815260026020908152604091829020805460ff19168515159081179091558251938452908301527f8cd3ccab08c47cc8be9e03c5a939a1233d1deffbd661c7d3b36782a67fb9200091016106aa565b6001546001600160a01b0316331461085c5760405162461bcd60e51b815260040161054390611b64565b60058190556040518181527f191dde3e99ae398f28f0457d7346866a4fa04805ac0b57190b944935b5aa75509060200161057d565b6001546001600160a01b031633146108bb5760405162461bcd60e51b815260040161054390611b64565b6009546040516363afa05f60e01b81526001600160a01b0384811660048301528315156024830152909116906363afa05f906044016105e8565b6001546001600160a01b0316331461091f5760405162461bcd60e51b815260040161054390611b64565b6109336001600160a01b038416828461149f565b505050565b4360009081526020818152604080832032845290915290205460ff16156109715760405162461bcd60e51b815260040161054390611bee565b4360009081526020818152604080832033845290915290205460ff16156109aa5760405162461bcd60e51b815260040161054390611bee565b6005544210156109fc5760405162461bcd60e51b815260206004820152601960248201527f54726561737572793a206e6f74207374617274656420796574000000000000006044820152606401610543565b610a046113d8565b421015610a535760405162461bcd60e51b815260206004820152601860248201527f54726561737572793a206e6f74206f70656e65642079657400000000000000006044820152606401610543565b6008546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610a9757600080fd5b505afa158015610aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acf9190611c34565b6001600160a01b0316148015610b6757506009546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610b2457600080fd5b505afa158015610b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5c9190611c34565b6001600160a01b0316145b8015610bf55750600a546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190611c34565b6001600160a01b0316145b610c415760405162461bcd60e51b815260206004820152601e60248201527f54726561737572793a206e656564206d6f7265207065726d697373696f6e00006044820152606401610543565b600d54600b541115610ca05760405162461bcd60e51b815260206004820152602260248201527f54726561737572793a204d617820706170657220616c7265616479206d696e74604482015261195960f21b6064820152608401610543565b6000806004600654610cb29190611c67565b905061016d811015610d2557600e548110610cd957600e54610cd690600190611c89565b90505b600e8181548110610cec57610cec611ca0565b60009182526020909120601082040154610d1e91600f166002026101000a900461ffff16670de0b6b3a7640000611cb6565b9150610d3e565b6704064976a8dd0000600c54610d3b9190611c89565b91505b600d5482600b54610d4f9190611cd5565b1115610d6857600b54600d54610d659190611c89565b91505b81600b54610d769190611cd5565b600b55600c829055610d8782611502565b5050600654610d97906001611657565b600655436000908152602081815260408083203284529091528082208054600160ff1991821681179092553384529190922080549091169091179055565b6001546001600160a01b03163314610dff5760405162461bcd60e51b815260040161054390611b64565b6009546040516329605e7760e01b81526001600160a01b038381166004830152909116906329605e779060240161076d565b6001546001600160a01b03163314610e5b5760405162461bcd60e51b815260040161054390611b64565b60095460405163c09c52f960e01b81526001600160a01b0383811660048301529091169063c09c52f99060240161076d565b6001546001600160a01b03163314610eb75760405162461bcd60e51b815260040161054390611b64565b6009546040516336aa5ba560e21b81526001600160a01b03848116600483015283151560248301529091169063daa96e94906044016105e8565b600e8181548110610f0157600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b6001546001600160a01b03163314610f535760405162461bcd60e51b815260040161054390611b64565b6008546040516329605e7760e01b81526001600160a01b038381166004830152909116906329605e779060240161076d565b6001546001600160a01b03163314610faf5760405162461bcd60e51b815260040161054390611b64565b600a54604051632ffaaa0960e01b815260048101849052602481018390526001600160a01b0390911690632ffaaa09906044016105e8565b3360009081526002602052604090205460ff16151560011461105d5760405162461bcd60e51b815260206004820152602960248201527f54726561737572793a2063616c6c6572206973206e6f742061206272696467656044820152681037b832b930ba37b960b91b6064820152608401610543565b6008546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f1990604401602060405180830381600087803b1580156110ab57600080fd5b505af11580156110bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109339190611ced565b6001546001600160a01b0316331461110d5760405162461bcd60e51b815260040161054390611b64565b600b8190556040518181527f34ea73fb0751bbd4db087574f4193f62aff186824b3879ec3b87d7f4ae30cb3e9060200161057d565b60045460ff16156111955760405162461bcd60e51b815260206004820152601d60248201527f54726561737572793a20616c726561647920696e697469616c697a65640000006044820152606401610543565b600880546001600160a01b03199081166001600160a01b0388811691909117909255600980548216878416179055600a8054821692861692909217909155600583905560078290556004805460ff1990811660019081179092558154339316831782556000838152600360209081526040918290208054909316909317909155514381527f25ff68dd81b34665b5ba7e553ee5511bf6812e12adb4a7e2c0d9e26b3099ce79910160405180910390a25050505050565b6001546001600160a01b031633146112755760405162461bcd60e51b815260040161054390611b64565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee9060200161057d565b6001546001600160a01b031633146112ed5760405162461bcd60e51b815260040161054390611b64565b6009546040516325dbbffb60e11b81526001600160a01b03838116600483015290911690634bb77ff69060240161076d565b6001546001600160a01b031633146113495760405162461bcd60e51b815260040161054390611b64565b600954604051630c6d69a360e41b8152600481018390526001600160a01b039091169063c6d69a3090602401600060405180830381600087803b15801561138f57600080fd5b505af11580156113a3573d6000803e3d6000fd5b505050507f2959071862f63af16037343b53d0c5997d8ea464e99168a08ed49ad4dcf3e1498160405161057d91815260200190565b60006113fd6113f460075460065461166a90919063ffffffff16565b60055490611657565b905090565b6001546001600160a01b0316331461142c5760405162461bcd60e51b815260040161054390611b64565b600a54604051631515d6bd60e21b81526001600160a01b038581166004830152602482018590528381166044830152909116906354575af490606401600060405180830381600087803b15801561148257600080fd5b505af1158015611496573d6000803e3d6000fd5b50505050505050565b6040516001600160a01b03831660248201526044810182905261093390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611676565b6008546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401602060405180830381600087803b15801561154e57600080fd5b505af1158015611562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115869190611ced565b50600a546008546115a5916001600160a01b0391821691166000611748565b600a546008546115c2916001600160a01b03918216911683611748565b600a546040516397ffe1d760e01b8152600481018390526001600160a01b03909116906397ffe1d790602401600060405180830381600087803b15801561160857600080fd5b505af115801561161c573d6000803e3d6000fd5b505060408051428152602081018590527f1017a1b301524a5f6e72c0f53dd3bd6c0ecad65bfa98482c119a849ae8cdbbdb935001905061057d565b60006116638284611cd5565b9392505050565b60006116638284611cb6565b60006116cb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661186c9092919063ffffffff16565b80519091501561093357808060200190518101906116e99190611ced565b6109335760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610543565b8015806117d15750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561179757600080fd5b505afa1580156117ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cf9190611d0a565b155b61183c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610543565b6040516001600160a01b03831660248201526044810182905261093390849063095ea7b360e01b906064016114cb565b606061187b8484600085611883565b949350505050565b6060824710156118e45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610543565b843b6119325760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610543565b600080866001600160a01b0316858760405161194e9190611d53565b60006040518083038185875af1925050503d806000811461198b576040519150601f19603f3d011682016040523d82523d6000602084013e611990565b606091505b50915091506119a08282866119ab565b979650505050505050565b606083156119ba575081611663565b8251156119ca5782518084602001fd5b8160405162461bcd60e51b81526004016105439190611d6f565b6000602082840312156119f657600080fd5b5035919050565b6001600160a01b0381168114611a1257600080fd5b50565b8015158114611a1257600080fd5b60008060408385031215611a3657600080fd5b8235611a41816119fd565b91506020830135611a5181611a15565b809150509250929050565b600060208284031215611a6e57600080fd5b8135611663816119fd565b600080600060608486031215611a8e57600080fd5b8335611a99816119fd565b9250602084013591506040840135611ab0816119fd565b809150509250925092565b60008060408385031215611ace57600080fd5b50508035926020909101359150565b60008060408385031215611af057600080fd5b8235611afb816119fd565b946020939093013593505050565b600080600080600060a08688031215611b2157600080fd5b8535611b2c816119fd565b94506020860135611b3c816119fd565b93506040860135611b4c816119fd565b94979396509394606081013594506080013592915050565b60208082526024908201527f54726561737572793a2063616c6c6572206973206e6f7420746865206f70657260408201526330ba37b960e11b606082015260800190565b60208082526026908201527f54726561737572793a2063616c6c6572206973206e6f742061206272696467656040820152651030b236b4b760d11b606082015260800190565b60208082526026908201527f436f6e747261637447756172643a206f6e6520626c6f636b2c206f6e652066756040820152653731ba34b7b760d11b606082015260800190565b600060208284031215611c4657600080fd5b8151611663816119fd565b634e487b7160e01b600052601160045260246000fd5b600082611c8457634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611c9b57611c9b611c51565b500390565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611cd057611cd0611c51565b500290565b60008219821115611ce857611ce8611c51565b500190565b600060208284031215611cff57600080fd5b815161166381611a15565b600060208284031215611d1c57600080fd5b5051919050565b60005b83811015611d3e578181015183820152602001611d26565b83811115611d4d576000848401525b50505050565b60008251611d65818460208701611d23565b9190910192915050565b6020815260008251806020840152611d8e816040850160208701611d23565b601f01601f1916919091016040019291505056fea26469706673582212207107d75c061ed4ea04ff4f78f8d99ce8edc2bda706ee2aeeafaac55e31fd129864736f6c63430008090033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102325760003560e01c8063755f041111610130578063ba8d4dee116100b8578063d7a164ee1161007c578063d7a164ee1461049a578063e89485d4146104ad578063ee08c300146104d0578063f83a1a7f146104e3578063f8c587ac1461050657600080fd5b8063ba8d4dee1461045a578063c47ee61d14610463578063c52e417e14610476578063c5967c2614610489578063d5604fa21461049157600080fd5b8063900cf0cf116100ff578063900cf0cf1461040f578063a693c9ee14610418578063a6b63eb81461042b578063b3ab15fb1461043e578063b5b7a1841461045157600080fd5b8063755f0411146103cd57806378e97925146103e05780637df3fa82146103e95780638c2a993e146103fc57600080fd5b80633e0a322d116101be5780635b756179116101825780635b756179146103665780635bf2cb551461036e5780636254df78146103815780636908f0f31461039457806374eac9d2146103a757600080fd5b80633e0a322d146103035780634ab7f20d1461031657806354575af414610329578063570ca7351461033c578063586fc5b51461034f57600080fd5b80632a018786116102055780632a018786146102ac5780632b46206c146102bf57806334ae2535146102d2578063392e53cd146102e55780633ab043b2146102f057600080fd5b80630ceb2cef14610237578063158ef93e1461024c5780631d3a0c981461026e57806324a063ee14610299575b600080fd5b61024a6102453660046119e4565b610519565b005b6004546102599060ff1681565b60405190151581526020015b60405180910390f35b600a54610281906001600160a01b031681565b6040516001600160a01b039091168152602001610265565b61024a6102a7366004611a23565b610588565b61024a6102ba366004611a23565b61061e565b61024a6102cd3660046119e4565b6106b6565b61024a6102e0366004611a5c565b610715565b60045460ff16610259565b61024a6102fe366004611a23565b6107a2565b61024a6103113660046119e4565b610832565b61024a610324366004611a23565b610891565b61024a610337366004611a79565b6108f5565b600154610281906001600160a01b031681565b610358600c5481565b604051908152602001610265565b61024a610938565b61024a61037c366004611a5c565b610dd5565b61024a61038f366004611a5c565b610e31565b61024a6103a2366004611a23565b610e8d565b6103ba6103b53660046119e4565b610ef1565b60405161ffff9091168152602001610265565b61024a6103db366004611a5c565b610f29565b61035860055481565b61024a6103f7366004611abb565b610f85565b61024a61040a366004611add565b610fe7565b61035860065481565b61024a6104263660046119e4565b6110e3565b61024a610439366004611b09565b611142565b61024a61044c366004611a5c565b61124b565b61035860075481565b610358600b5481565b61024a610471366004611a5c565b6112c3565b61024a6104843660046119e4565b61131f565b6103586113d8565b610358600d5481565b61024a6104a8366004611a79565b611402565b6102596104bb366004611a5c565b60036020526000908152604090205460ff1681565b600954610281906001600160a01b031681565b6102596104f1366004611a5c565b60026020526000908152604090205460ff1681565b600854610281906001600160a01b031681565b6001546001600160a01b0316331461054c5760405162461bcd60e51b815260040161054390611b64565b60405180910390fd5b60068190556040518181527f98ea2c8840699940892e55a1179c1b4fa1bf54d8e1e9b653e52cb4bda9b11849906020015b60405180910390a150565b6001546001600160a01b031633146105b25760405162461bcd60e51b815260040161054390611b64565b600954604051632f507df760e01b81526001600160a01b038481166004830152831515602483015290911690632f507df7906044015b600060405180830381600087803b15801561060257600080fd5b505af1158015610616573d6000803e3d6000fd5b505050505050565b3360009081526003602052604090205460ff1615156001146106525760405162461bcd60e51b815260040161054390611ba8565b6001600160a01b038216600081815260036020908152604091829020805460ff19168515159081179091558251938452908301527ff9ac756fc793b6681391c0d51419515e57429852bc8bd4b37040ad5e5c3addd491015b60405180910390a15050565b6001546001600160a01b031633146106e05760405162461bcd60e51b815260040161054390611b64565b600d8190556040518181527f77c7ba9de8933559168f05d084288c5afefbc158768783a41fb296567951d0719060200161057d565b6001546001600160a01b0316331461073f5760405162461bcd60e51b815260040161054390611b64565b600a5460405163b3ab15fb60e01b81526001600160a01b0383811660048301529091169063b3ab15fb906024015b600060405180830381600087803b15801561078757600080fd5b505af115801561079b573d6000803e3d6000fd5b5050505050565b3360009081526003602052604090205460ff1615156001146107d65760405162461bcd60e51b815260040161054390611ba8565b6001600160a01b038216600081815260026020908152604091829020805460ff19168515159081179091558251938452908301527f8cd3ccab08c47cc8be9e03c5a939a1233d1deffbd661c7d3b36782a67fb9200091016106aa565b6001546001600160a01b0316331461085c5760405162461bcd60e51b815260040161054390611b64565b60058190556040518181527f191dde3e99ae398f28f0457d7346866a4fa04805ac0b57190b944935b5aa75509060200161057d565b6001546001600160a01b031633146108bb5760405162461bcd60e51b815260040161054390611b64565b6009546040516363afa05f60e01b81526001600160a01b0384811660048301528315156024830152909116906363afa05f906044016105e8565b6001546001600160a01b0316331461091f5760405162461bcd60e51b815260040161054390611b64565b6109336001600160a01b038416828461149f565b505050565b4360009081526020818152604080832032845290915290205460ff16156109715760405162461bcd60e51b815260040161054390611bee565b4360009081526020818152604080832033845290915290205460ff16156109aa5760405162461bcd60e51b815260040161054390611bee565b6005544210156109fc5760405162461bcd60e51b815260206004820152601960248201527f54726561737572793a206e6f74207374617274656420796574000000000000006044820152606401610543565b610a046113d8565b421015610a535760405162461bcd60e51b815260206004820152601860248201527f54726561737572793a206e6f74206f70656e65642079657400000000000000006044820152606401610543565b6008546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610a9757600080fd5b505afa158015610aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acf9190611c34565b6001600160a01b0316148015610b6757506009546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610b2457600080fd5b505afa158015610b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5c9190611c34565b6001600160a01b0316145b8015610bf55750600a546040805163570ca73560e01b8152905130926001600160a01b03169163570ca735916004808301926020929190829003018186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190611c34565b6001600160a01b0316145b610c415760405162461bcd60e51b815260206004820152601e60248201527f54726561737572793a206e656564206d6f7265207065726d697373696f6e00006044820152606401610543565b600d54600b541115610ca05760405162461bcd60e51b815260206004820152602260248201527f54726561737572793a204d617820706170657220616c7265616479206d696e74604482015261195960f21b6064820152608401610543565b6000806004600654610cb29190611c67565b905061016d811015610d2557600e548110610cd957600e54610cd690600190611c89565b90505b600e8181548110610cec57610cec611ca0565b60009182526020909120601082040154610d1e91600f166002026101000a900461ffff16670de0b6b3a7640000611cb6565b9150610d3e565b6704064976a8dd0000600c54610d3b9190611c89565b91505b600d5482600b54610d4f9190611cd5565b1115610d6857600b54600d54610d659190611c89565b91505b81600b54610d769190611cd5565b600b55600c829055610d8782611502565b5050600654610d97906001611657565b600655436000908152602081815260408083203284529091528082208054600160ff1991821681179092553384529190922080549091169091179055565b6001546001600160a01b03163314610dff5760405162461bcd60e51b815260040161054390611b64565b6009546040516329605e7760e01b81526001600160a01b038381166004830152909116906329605e779060240161076d565b6001546001600160a01b03163314610e5b5760405162461bcd60e51b815260040161054390611b64565b60095460405163c09c52f960e01b81526001600160a01b0383811660048301529091169063c09c52f99060240161076d565b6001546001600160a01b03163314610eb75760405162461bcd60e51b815260040161054390611b64565b6009546040516336aa5ba560e21b81526001600160a01b03848116600483015283151560248301529091169063daa96e94906044016105e8565b600e8181548110610f0157600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b6001546001600160a01b03163314610f535760405162461bcd60e51b815260040161054390611b64565b6008546040516329605e7760e01b81526001600160a01b038381166004830152909116906329605e779060240161076d565b6001546001600160a01b03163314610faf5760405162461bcd60e51b815260040161054390611b64565b600a54604051632ffaaa0960e01b815260048101849052602481018390526001600160a01b0390911690632ffaaa09906044016105e8565b3360009081526002602052604090205460ff16151560011461105d5760405162461bcd60e51b815260206004820152602960248201527f54726561737572793a2063616c6c6572206973206e6f742061206272696467656044820152681037b832b930ba37b960b91b6064820152608401610543565b6008546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f1990604401602060405180830381600087803b1580156110ab57600080fd5b505af11580156110bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109339190611ced565b6001546001600160a01b0316331461110d5760405162461bcd60e51b815260040161054390611b64565b600b8190556040518181527f34ea73fb0751bbd4db087574f4193f62aff186824b3879ec3b87d7f4ae30cb3e9060200161057d565b60045460ff16156111955760405162461bcd60e51b815260206004820152601d60248201527f54726561737572793a20616c726561647920696e697469616c697a65640000006044820152606401610543565b600880546001600160a01b03199081166001600160a01b0388811691909117909255600980548216878416179055600a8054821692861692909217909155600583905560078290556004805460ff1990811660019081179092558154339316831782556000838152600360209081526040918290208054909316909317909155514381527f25ff68dd81b34665b5ba7e553ee5511bf6812e12adb4a7e2c0d9e26b3099ce79910160405180910390a25050505050565b6001546001600160a01b031633146112755760405162461bcd60e51b815260040161054390611b64565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee9060200161057d565b6001546001600160a01b031633146112ed5760405162461bcd60e51b815260040161054390611b64565b6009546040516325dbbffb60e11b81526001600160a01b03838116600483015290911690634bb77ff69060240161076d565b6001546001600160a01b031633146113495760405162461bcd60e51b815260040161054390611b64565b600954604051630c6d69a360e41b8152600481018390526001600160a01b039091169063c6d69a3090602401600060405180830381600087803b15801561138f57600080fd5b505af11580156113a3573d6000803e3d6000fd5b505050507f2959071862f63af16037343b53d0c5997d8ea464e99168a08ed49ad4dcf3e1498160405161057d91815260200190565b60006113fd6113f460075460065461166a90919063ffffffff16565b60055490611657565b905090565b6001546001600160a01b0316331461142c5760405162461bcd60e51b815260040161054390611b64565b600a54604051631515d6bd60e21b81526001600160a01b038581166004830152602482018590528381166044830152909116906354575af490606401600060405180830381600087803b15801561148257600080fd5b505af1158015611496573d6000803e3d6000fd5b50505050505050565b6040516001600160a01b03831660248201526044810182905261093390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611676565b6008546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401602060405180830381600087803b15801561154e57600080fd5b505af1158015611562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115869190611ced565b50600a546008546115a5916001600160a01b0391821691166000611748565b600a546008546115c2916001600160a01b03918216911683611748565b600a546040516397ffe1d760e01b8152600481018390526001600160a01b03909116906397ffe1d790602401600060405180830381600087803b15801561160857600080fd5b505af115801561161c573d6000803e3d6000fd5b505060408051428152602081018590527f1017a1b301524a5f6e72c0f53dd3bd6c0ecad65bfa98482c119a849ae8cdbbdb935001905061057d565b60006116638284611cd5565b9392505050565b60006116638284611cb6565b60006116cb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661186c9092919063ffffffff16565b80519091501561093357808060200190518101906116e99190611ced565b6109335760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610543565b8015806117d15750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561179757600080fd5b505afa1580156117ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cf9190611d0a565b155b61183c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610543565b6040516001600160a01b03831660248201526044810182905261093390849063095ea7b360e01b906064016114cb565b606061187b8484600085611883565b949350505050565b6060824710156118e45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610543565b843b6119325760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610543565b600080866001600160a01b0316858760405161194e9190611d53565b60006040518083038185875af1925050503d806000811461198b576040519150601f19603f3d011682016040523d82523d6000602084013e611990565b606091505b50915091506119a08282866119ab565b979650505050505050565b606083156119ba575081611663565b8251156119ca5782518084602001fd5b8160405162461bcd60e51b81526004016105439190611d6f565b6000602082840312156119f657600080fd5b5035919050565b6001600160a01b0381168114611a1257600080fd5b50565b8015158114611a1257600080fd5b60008060408385031215611a3657600080fd5b8235611a41816119fd565b91506020830135611a5181611a15565b809150509250929050565b600060208284031215611a6e57600080fd5b8135611663816119fd565b600080600060608486031215611a8e57600080fd5b8335611a99816119fd565b9250602084013591506040840135611ab0816119fd565b809150509250925092565b60008060408385031215611ace57600080fd5b50508035926020909101359150565b60008060408385031215611af057600080fd5b8235611afb816119fd565b946020939093013593505050565b600080600080600060a08688031215611b2157600080fd5b8535611b2c816119fd565b94506020860135611b3c816119fd565b93506040860135611b4c816119fd565b94979396509394606081013594506080013592915050565b60208082526024908201527f54726561737572793a2063616c6c6572206973206e6f7420746865206f70657260408201526330ba37b960e11b606082015260800190565b60208082526026908201527f54726561737572793a2063616c6c6572206973206e6f742061206272696467656040820152651030b236b4b760d11b606082015260800190565b60208082526026908201527f436f6e747261637447756172643a206f6e6520626c6f636b2c206f6e652066756040820152653731ba34b7b760d11b606082015260800190565b600060208284031215611c4657600080fd5b8151611663816119fd565b634e487b7160e01b600052601160045260246000fd5b600082611c8457634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611c9b57611c9b611c51565b500390565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611cd057611cd0611c51565b500290565b60008219821115611ce857611ce8611c51565b500190565b600060208284031215611cff57600080fd5b815161166381611a15565b600060208284031215611d1c57600080fd5b5051919050565b60005b83811015611d3e578181015183820152602001611d26565b83811115611d4d576000848401525b50505050565b60008251611d65818460208701611d23565b9190910192915050565b6020815260008251806020840152611d8e816040850160208701611d23565b601f01601f1916919091016040019291505056fea26469706673582212207107d75c061ed4ea04ff4f78f8d99ce8edc2bda706ee2aeeafaac55e31fd129864736f6c63430008090033