Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 105 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit | 17130725 | 697 days ago | IN | 0 ETH | 0.01130651 | ||||
Deposit | 16805181 | 743 days ago | IN | 0 ETH | 0.01022019 | ||||
Deposit | 16770616 | 747 days ago | IN | 0 ETH | 0.01144837 | ||||
Deposit | 16512867 | 784 days ago | IN | 0 ETH | 0.00562019 | ||||
Deposit | 16356711 | 805 days ago | IN | 0 ETH | 0.00401646 | ||||
Deposit | 16306535 | 812 days ago | IN | 0 ETH | 0.00760357 | ||||
Deposit | 16190995 | 828 days ago | IN | 0 ETH | 0.00867553 | ||||
Deposit | 16055984 | 847 days ago | IN | 0 ETH | 0.0020925 | ||||
Deposit | 16053377 | 848 days ago | IN | 0 ETH | 0.00431473 | ||||
Deposit | 15988837 | 857 days ago | IN | 0 ETH | 0.00222214 | ||||
Deposit | 15974531 | 859 days ago | IN | 0 ETH | 0.00431138 | ||||
Deposit | 15938314 | 864 days ago | IN | 0 ETH | 0.00669913 | ||||
Deposit | 15931325 | 865 days ago | IN | 0 ETH | 0.00851021 | ||||
Deposit | 15795856 | 884 days ago | IN | 0 ETH | 0.00520133 | ||||
Deposit | 15760923 | 889 days ago | IN | 0 ETH | 0.00376727 | ||||
Deposit | 15704363 | 896 days ago | IN | 0 ETH | 0.00349606 | ||||
Deposit | 15652047 | 904 days ago | IN | 0 ETH | 0.0029726 | ||||
Deposit | 15589921 | 912 days ago | IN | 0 ETH | 0.00713716 | ||||
Deposit | 15519935 | 923 days ago | IN | 0 ETH | 0.00385269 | ||||
Deposit | 15489386 | 928 days ago | IN | 0 ETH | 0.00237763 | ||||
Deposit | 15395963 | 943 days ago | IN | 0 ETH | 0.0029203 | ||||
Deposit | 15256173 | 965 days ago | IN | 0 ETH | 0.00489152 | ||||
Deposit | 15127338 | 985 days ago | IN | 0 ETH | 0.00469143 | ||||
Deposit | 15063955 | 994 days ago | IN | 0 ETH | 0.0047673 | ||||
Deposit | 15001614 | 1006 days ago | IN | 0 ETH | 0.00703305 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FeeCollector
Compiler Version
v0.6.8+commit.0bbfe453
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-01-27 */ // File: @openzeppelin/contracts/utils/EnumerableSet.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity >=0.6.2 <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; // solhint-disable-next-line no-inline-assembly 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/GSN/Context.sol pragma solidity >=0.6.0 <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 GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/access/AccessControl.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol pragma solidity >=0.6.0 <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/math/SafeMath.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol pragma solidity >=0.6.0 <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 SafeMath for uint256; 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' // solhint-disable-next-line max-line-length 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).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } // File: @uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol pragma solidity >=0.6.2; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } // File: contracts/interfaces/IFeeCollector.sol pragma solidity >=0.6.0 <=0.7.5; interface IFeeCollector { function deposit(bool[] calldata _depositTokensEnabled, uint256[] calldata _minTokenOut, uint256 _minPoolAmountOut) external; // called by whitelisted address function setSplitAllocation(uint256[] calldata _allocations) external; // allocation of fees sent SmartTreasury vs FeeTreasury // function setFeeTreasuryAddress(address _feeTreasuryAddress) external; // called by admin function addBeneficiaryAddress(address _newBeneficiary, uint256[] calldata _newAllocation) external; function removeBeneficiaryAt(uint256 _index, uint256[] calldata _newAllocation) external; function replaceBeneficiaryAt(uint256 _index, address _newBeneficiary, uint256[] calldata _newAllocation) external; function setSmartTreasuryAddress(address _smartTreasuryAddress) external; // If for any reason the pool needs to be migrated, call this function. Called by admin function addAddressToWhiteList(address _addressToAdd) external; // Whitelist address. Called by admin function removeAddressFromWhiteList(address _addressToRemove) external; // Remove from whitelist. Called by admin function registerTokenToDepositList(address _tokenAddress) external; // Register a token which can converted to ETH and deposited to smart treasury. Called by admin function removeTokenFromDepositList(address _tokenAddress) external; // Unregister a token. Called by admin // withdraw arbitrary token to address. Called by admin function withdraw(address _token, address _toAddress, uint256 _amount) external; // exchange liquidity token for underlying token and withdraw to _toAddress function withdrawUnderlying(address _toAddress, uint256 _amount, uint256[] calldata minTokenOut) external; function replaceAdmin(address _newAdmin) external; // called by admin } // File: contracts/interfaces/BalancerInterface.sol pragma solidity = 0.6.8; pragma experimental ABIEncoderV2; interface BPool { event LOG_SWAP( address indexed caller, address indexed tokenIn, address indexed tokenOut, uint256 tokenAmountIn, uint256 tokenAmountOut ); event LOG_JOIN( address indexed caller, address indexed tokenIn, uint256 tokenAmountIn ); event LOG_EXIT( address indexed caller, address indexed tokenOut, uint256 tokenAmountOut ); event LOG_CALL( bytes4 indexed sig, address indexed caller, bytes data ) anonymous; function isPublicSwap() external view returns (bool); function isFinalized() external view returns (bool); function isBound(address t) external view returns (bool); function getNumTokens() external view returns (uint); function getCurrentTokens() external view returns (address[] memory tokens); function getFinalTokens() external view returns (address[] memory tokens); function getDenormalizedWeight(address token) external view returns (uint); function getTotalDenormalizedWeight() external view returns (uint); function getNormalizedWeight(address token) external view returns (uint); function getBalance(address token) external view returns (uint); function getSwapFee() external view returns (uint); function getController() external view returns (address); function setSwapFee(uint swapFee) external; function setController(address manager) external; function setPublicSwap(bool public_) external; function finalize() external; function bind(address token, uint balance, uint denorm) external; function unbind(address token) external; function gulp(address token) external; function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint spotPrice); function getSpotPriceSansFee(address tokenIn, address tokenOut) external view returns (uint spotPrice); function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) external; function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external; function swapExactAmountIn( address tokenIn, uint tokenAmountIn, address tokenOut, uint minAmountOut, uint maxPrice ) external returns (uint tokenAmountOut, uint spotPriceAfter); function swapExactAmountOut( address tokenIn, uint maxAmountIn, address tokenOut, uint tokenAmountOut, uint maxPrice ) external returns (uint tokenAmountIn, uint spotPriceAfter); function joinswapExternAmountIn( address tokenIn, uint tokenAmountIn, uint minPoolAmountOut ) external returns (uint poolAmountOut); function joinswapPoolAmountOut( address tokenIn, uint poolAmountOut, uint maxAmountIn ) external returns (uint tokenAmountIn); function exitswapPoolAmountIn( address tokenOut, uint poolAmountIn, uint minAmountOut ) external returns (uint tokenAmountOut); function exitswapExternAmountOut( address tokenOut, uint tokenAmountOut, uint maxPoolAmountIn ) external returns (uint poolAmountIn); function totalSupply() external view returns (uint); function balanceOf(address whom) external view returns (uint); function allowance(address src, address dst) external view returns (uint); function approve(address dst, uint amt) external returns (bool); function transfer(address dst, uint amt) external returns (bool); function transferFrom( address src, address dst, uint amt ) external returns (bool); } interface ConfigurableRightsPool { event LogCall( bytes4 indexed sig, address indexed caller, bytes data ) anonymous; event LogJoin( address indexed caller, address indexed tokenIn, uint tokenAmountIn ); event LogExit( address indexed caller, address indexed tokenOut, uint tokenAmountOut ); event CapChanged( address indexed caller, uint oldCap, uint newCap ); event NewTokenCommitted( address indexed token, address indexed pool, address indexed caller ); function createPool( uint initialSupply // uint minimumWeightChangeBlockPeriodParam, // uint addTokenTimeLockInBlocksParam ) external; function createPool( uint initialSupply, uint minimumWeightChangeBlockPeriodParam, uint addTokenTimeLockInBlocksParam ) external; function updateWeightsGradually( uint[] calldata newWeights, uint startBlock, uint endBlock ) external; function joinswapExternAmountIn( address tokenIn, uint tokenAmountIn, uint minPoolAmountOut ) external; function whitelistLiquidityProvider(address provider) external; function removeWhitelistedLiquidityProvider(address provider) external; function canProvideLiquidity(address provider) external returns (bool); function getController() external view returns (address); function setController(address newOwner) external; function transfer(address recipient, uint amount) external returns (bool); function balanceOf(address account) external returns (uint); function totalSupply() external returns (uint); function bPool() external view returns (BPool); function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external; } interface IBFactory { event LOG_NEW_POOL( address indexed caller, address indexed pool ); event LOG_BLABS( address indexed caller, address indexed blabs ); function isBPool(address b) external view returns (bool); function newBPool() external returns (BPool); } interface ICRPFactory { event LogNewCrp( address indexed caller, address indexed pool ); struct PoolParams { // Balancer Pool Token (representing shares of the pool) string poolTokenSymbol; string poolTokenName; // Tokens inside the Pool address[] constituentTokens; uint[] tokenBalances; uint[] tokenWeights; uint swapFee; } struct Rights { bool canPauseSwapping; bool canChangeSwapFee; bool canChangeWeights; bool canAddRemoveTokens; bool canWhitelistLPs; bool canChangeCap; } function newCrp( address factoryAddress, PoolParams calldata poolParams, Rights calldata rights ) external returns (ConfigurableRightsPool); } // File: contracts/FeeCollector.sol pragma solidity = 0.6.8; /** @title Idle finance Fee collector @author Asaf Silman @notice Receives fees from idle strategy tokens and routes to fee treasury and smart treasury */ contract FeeCollector is IFeeCollector, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; using SafeMath for uint256; using SafeERC20 for IERC20; IUniswapV2Router02 private constant uniswapRouterV2 = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); address private immutable weth; // Need to use openzeppelin enumerableset EnumerableSet.AddressSet private depositTokens; uint256[] private allocations; // 100000 = 100%. allocation sent to beneficiaries address[] private beneficiaries; // Who are the beneficiaries of the fees generated from IDLE. The first beneficiary is always going to be the smart treasury uint128 public constant MAX_BENEFICIARIES = 5; uint128 public constant MIN_BENEFICIARIES = 2; uint256 public constant FULL_ALLOC = 100000; uint256 public constant MAX_NUM_FEE_TOKENS = 15; // Cap max tokens to 15 bytes32 public constant WHITELISTED = keccak256("WHITELISTED_ROLE"); modifier smartTreasurySet { require(beneficiaries[0]!=address(0), "Smart Treasury not set"); _; } modifier onlyAdmin { require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Unauthorised"); _; } modifier onlyWhitelisted { require(hasRole(WHITELISTED, msg.sender), "Unauthorised"); _; } /** @author Asaf Silman @notice Initialise the FeeCollector contract. @dev Sets the smartTreasury, weth address, uniswap router, and fee split allocations. @dev Also initialises the sender as admin, and whitelists for calling `deposit()` @dev At deploy time the smart treasury will not have been deployed yet. setSmartTreasuryAddress should be called after the treasury has been deployed. @param _weth The wrapped ethereum address. @param _feeTreasuryAddress The address of idle's fee treasury. @param _idleRebalancer Idle rebalancer address @param _multisig The multisig account to transfer ownership to after contract initialised @param _initialDepositTokens The initial tokens to register with the fee deposit */ constructor ( address _weth, address _feeTreasuryAddress, address _idleRebalancer, address _multisig, address[] memory _initialDepositTokens ) public { require(_weth != address(0), "WETH cannot be the 0 address"); require(_feeTreasuryAddress != address(0), "Fee Treasury cannot be 0 address"); require(_idleRebalancer != address(0), "Rebalancer cannot be 0 address"); require(_multisig != address(0), "Multisig cannot be 0 address"); require(_initialDepositTokens.length <= MAX_NUM_FEE_TOKENS); _setupRole(DEFAULT_ADMIN_ROLE, _multisig); // setup multisig as admin _setupRole(WHITELISTED, _multisig); // setup multisig as whitelisted address _setupRole(WHITELISTED, _idleRebalancer); // setup multisig as whitelisted address // configure weth address and ERC20 interface weth = _weth; allocations = new uint256[](3); // setup fee split ratio allocations[0] = 80000; allocations[1] = 15000; allocations[2] = 5000; beneficiaries = new address[](3); // setup beneficiaries beneficiaries[1] = _feeTreasuryAddress; // setup fee treasury address beneficiaries[2] = _idleRebalancer; // setup fee treasury address address _depositToken; for (uint256 index = 0; index < _initialDepositTokens.length; index++) { _depositToken = _initialDepositTokens[index]; require(_depositToken != address(0), "Token cannot be 0 address"); require(_depositToken != _weth, "WETH not supported"); // There is no WETH -> WETH pool in uniswap require(depositTokens.contains(_depositToken) == false, "Already exists"); IERC20(_depositToken).safeIncreaseAllowance(address(uniswapRouterV2), type(uint256).max); // max approval depositTokens.add(_depositToken); } } /** @author Asaf Silman @notice Converts all registered fee tokens to WETH and deposits to fee treasury and smart treasury based on split allocations. @dev The fees are swaped using Uniswap simple route. E.g. Token -> WETH. */ function deposit( bool[] memory _depositTokensEnabled, uint256[] memory _minTokenOut, uint256 _minPoolAmountOut ) public override smartTreasurySet onlyWhitelisted { _deposit(_depositTokensEnabled, _minTokenOut, _minPoolAmountOut); } /** @author Asaf Silman @dev implements deposit() */ function _deposit( bool[] memory _depositTokensEnabled, uint256[] memory _minTokenOut, uint256 _minPoolAmountOut ) internal { uint256 counter = depositTokens.length(); require(_depositTokensEnabled.length == counter, "Invalid length"); require(_minTokenOut.length == counter, "Invalid length"); uint256 _currentBalance; IERC20 _tokenInterface; uint256 wethBalance; address[] memory path = new address[](2); path[1] = weth; // output will always be weth // iterate through all registered deposit tokens for (uint256 index = 0; index < counter; index++) { if (_depositTokensEnabled[index] == false) {continue;} _tokenInterface = IERC20(depositTokens.at(index)); _currentBalance = _tokenInterface.balanceOf(address(this)); // Only swap if balance > 0 if (_currentBalance > 0) { // create simple route; token->WETH path[0] = address(_tokenInterface); // swap token uniswapRouterV2.swapExactTokensForTokensSupportingFeeOnTransferTokens( _currentBalance, _minTokenOut[index], path, address(this), block.timestamp.add(1800) ); } } // deposit all swapped WETH + the already present weth balance // to beneficiaries // the beneficiary at index 0 is the smart treasury wethBalance = IERC20(weth).balanceOf(address(this)); if (wethBalance > 0){ // feeBalances[0] is fee sent to smartTreasury uint256[] memory feeBalances = _amountsFromAllocations(allocations, wethBalance); uint256 smartTreasuryFee = feeBalances[0]; if (wethBalance.sub(smartTreasuryFee) > 0){ // NOTE: allocation starts at 1, NOT 0, since 0 is reserved for smart treasury for (uint256 a_index = 1; a_index < allocations.length; a_index++){ IERC20(weth).safeTransfer(beneficiaries[a_index], feeBalances[a_index]); } } if (smartTreasuryFee > 0) { ConfigurableRightsPool crp = ConfigurableRightsPool(beneficiaries[0]); // the smart treasury is at index 0 crp.joinswapExternAmountIn(weth, smartTreasuryFee, _minPoolAmountOut); } } } /** @author Asaf Silman @notice Sets the split allocations of fees to send to fee beneficiaries @dev The split allocations must sum to 100000. @dev Before the split allocation is updated internally a call to `deposit()` is made such that all fee accrued using the previous allocations. @dev smartTreasury must be set for this to be called. @param _allocations The updated split ratio. */ function setSplitAllocation(uint256[] calldata _allocations) external override smartTreasurySet onlyAdmin { _depositAllTokens(); _setSplitAllocation(_allocations); } /** @author Asaf Silman @notice Internal function to sets the split allocations of fees to send to fee beneficiaries @dev The split allocations must sum to 100000. @dev smartTreasury must be set for this to be called. @param _allocations The updated split ratio. */ function _setSplitAllocation(uint256[] memory _allocations) internal { require(_allocations.length == beneficiaries.length, "Invalid length"); uint256 sum=0; for (uint256 i=0; i<_allocations.length; i++) { sum = sum.add(_allocations[i]); } require(sum == FULL_ALLOC, "Ratio does not equal 100000"); allocations = _allocations; } /** @author Andrea @ idle.finance @notice Helper function to deposit all tokens */ function _depositAllTokens() internal { uint256 numTokens = depositTokens.length(); bool[] memory depositTokensEnabled = new bool[](numTokens); uint256[] memory minTokenOut = new uint256[](numTokens); for (uint256 i = 0; i < numTokens; i++) { depositTokensEnabled[i] = true; minTokenOut[i] = 1; } _deposit(depositTokensEnabled, minTokenOut, 1); } /** @author Asaf Silman @notice Adds an address as a beneficiary to the idle fees @dev The new beneficiary will be pushed to the end of the beneficiaries array. The new allocations must include the new beneficiary @dev There is a maximum of 5 beneficiaries which can be registered with the fee collector @param _newBeneficiary The new beneficiary to add @param _newAllocation The new allocation of fees including the new beneficiary */ function addBeneficiaryAddress(address _newBeneficiary, uint256[] calldata _newAllocation) external override smartTreasurySet onlyAdmin { require(beneficiaries.length < MAX_BENEFICIARIES, "Max beneficiaries"); require(_newBeneficiary!=address(0), "beneficiary cannot be 0 address"); for (uint256 i = 0; i < beneficiaries.length; i++) { require(beneficiaries[i] != _newBeneficiary, "Duplicate beneficiary"); } _depositAllTokens(); beneficiaries.push(_newBeneficiary); _setSplitAllocation(_newAllocation); } /** @author Asaf Silman @notice removes a beneficiary at a given index. @notice WARNING: when using this method be very careful to note the new allocations The beneficiary at the LAST index, will be replaced with the beneficiary at `_index`. The new allocations need to reflect this updated array. eg. if beneficiaries = [a, b, c, d] and removeBeneficiaryAt(1, [...]) is called the final beneficiaries array will be [a, d, c] `_newAllocations` should be based off of this final array. @dev Cannot remove beneficiary past MIN_BENEFICIARIES. set to 2 @dev Cannot replace the smart treasury beneficiary at index 0 @param _index The index of the beneficiary to remove @param _newAllocation The new allocation of fees removing the beneficiary. NOTE !! The order of beneficiaries will change !! */ function removeBeneficiaryAt(uint256 _index, uint256[] calldata _newAllocation) external override smartTreasurySet onlyAdmin { require(_index >= 1, "Invalid beneficiary to remove"); require(_index < beneficiaries.length, "Out of range"); require(beneficiaries.length > MIN_BENEFICIARIES, "Min beneficiaries"); _depositAllTokens(); // replace beneficiary with index with final beneficiary, and call pop beneficiaries[_index] = beneficiaries[beneficiaries.length-1]; beneficiaries.pop(); // NOTE THE ORDER OF ALLOCATIONS _setSplitAllocation(_newAllocation); } /** @author Asaf Silman @notice replaces a beneficiary at a given index with a new one @notice a new allocation must be passed for this method @dev Cannot replace the smart treasury beneficiary at index 0 @param _index The index of the beneficiary to replace @param _newBeneficiary The new beneficiary address @param _newAllocation The new allocation of fees */ function replaceBeneficiaryAt(uint256 _index, address _newBeneficiary, uint256[] calldata _newAllocation) external override smartTreasurySet onlyAdmin { require(_index >= 1, "Invalid beneficiary to remove"); require(_newBeneficiary!=address(0), "Beneficiary cannot be 0 address"); for (uint256 i = 0; i < beneficiaries.length; i++) { require(beneficiaries[i] != _newBeneficiary, "Duplicate beneficiary"); } _depositAllTokens(); beneficiaries[_index] = _newBeneficiary; _setSplitAllocation(_newAllocation); } /** @author Asaf Silman @notice Sets the smart treasury address. @dev This needs to be called atleast once to properly initialise the contract @dev Sets maximum approval for WETH to the new smart Treasury @dev The smart treasury address cannot be the 0 address. @param _smartTreasuryAddress The new smart treasury address */ function setSmartTreasuryAddress(address _smartTreasuryAddress) external override onlyAdmin { require(_smartTreasuryAddress!=address(0), "Smart treasury cannot be 0 address"); // When contract is initialised, the smart treasury address is not yet set // Only call change allowance to 0 if previous smartTreasury was not the 0 address. if (beneficiaries[0] != address(0)) { IERC20(weth).safeApprove(beneficiaries[0], 0); // set approval for previous fee address to 0 } // max approval for new smartTreasuryAddress IERC20(weth).safeIncreaseAllowance(_smartTreasuryAddress, type(uint256).max); beneficiaries[0] = _smartTreasuryAddress; } /** @author Asaf Silman @notice Gives an address the WHITELISTED role. Used for calling `deposit()`. @dev Can only be called by admin. @param _addressToAdd The address to grant the role. */ function addAddressToWhiteList(address _addressToAdd) external override onlyAdmin{ grantRole(WHITELISTED, _addressToAdd); } /** @author Asaf Silman @notice Removed an address from whitelist. @dev Can only be called by admin @param _addressToRemove The address to revoke the WHITELISTED role. */ function removeAddressFromWhiteList(address _addressToRemove) external override onlyAdmin { revokeRole(WHITELISTED, _addressToRemove); } /** @author Asaf Silman @notice Registers a fee token to the fee collecter @dev There is a maximum of 15 fee tokens than can be registered. @dev WETH cannot be accepted as a fee token. @dev The token must be a complient ERC20 token. @dev The fee token is approved for the uniswap router @param _tokenAddress The token address to register */ function registerTokenToDepositList(address _tokenAddress) external override onlyAdmin { require(depositTokens.length() < MAX_NUM_FEE_TOKENS, "Too many tokens"); require(_tokenAddress != address(0), "Token cannot be 0 address"); require(_tokenAddress != weth, "WETH not supported"); // There is no WETH -> WETH pool in uniswap require(depositTokens.contains(_tokenAddress) == false, "Already exists"); IERC20(_tokenAddress).safeIncreaseAllowance(address(uniswapRouterV2), type(uint256).max); // max approval depositTokens.add(_tokenAddress); } /** @author Asaf Silman @notice Removed a fee token from the fee collector. @dev Resets uniswap approval to 0. @param _tokenAddress The fee token address to remove. */ function removeTokenFromDepositList(address _tokenAddress) external override onlyAdmin { IERC20(_tokenAddress).safeApprove(address(uniswapRouterV2), 0); // 0 approval for uniswap depositTokens.remove(_tokenAddress); } /** @author Asaf Silman @notice Withdraws a arbitrarty ERC20 token from feeCollector to an arbitrary address. @param _token The ERC20 token address. @param _toAddress The destination address. @param _amount The amount to transfer. */ function withdraw(address _token, address _toAddress, uint256 _amount) external override onlyAdmin { IERC20(_token).safeTransfer(_toAddress, _amount); } /** * Copied from idle.finance IdleTokenGovernance.sol * * Calculate amounts from percentage allocations (100000 => 100%) * @author idle.finance * @param _allocations : token allocations percentages * @param total : total amount * @return newAmounts : array with amounts */ function _amountsFromAllocations(uint256[] memory _allocations, uint256 total) internal pure returns (uint256[] memory newAmounts) { newAmounts = new uint256[](_allocations.length); uint256 currBalance; uint256 allocatedBalance; for (uint256 i = 0; i < _allocations.length; i++) { if (i == _allocations.length - 1) { newAmounts[i] = total.sub(allocatedBalance); } else { currBalance = total.mul(_allocations[i]).div(FULL_ALLOC); allocatedBalance = allocatedBalance.add(currBalance); newAmounts[i] = currBalance; } } return newAmounts; } /** @author Asaf Silman @notice Exchanges balancer pool token for the underlying assets and withdraws @param _toAddress The address to send the underlying tokens to @param _amount The underlying amount of balancer pool tokens to exchange */ function withdrawUnderlying(address _toAddress, uint256 _amount, uint256[] calldata minTokenOut) external override smartTreasurySet onlyAdmin{ ConfigurableRightsPool crp = ConfigurableRightsPool(beneficiaries[0]); BPool smartTreasuryBPool = crp.bPool(); uint256 numTokensInPool = smartTreasuryBPool.getNumTokens(); require(minTokenOut.length == numTokensInPool, "Invalid length"); address[] memory poolTokens = smartTreasuryBPool.getCurrentTokens(); uint256[] memory feeCollectorTokenBalances = new uint256[](numTokensInPool); for (uint256 i=0; i<poolTokens.length; i++) { // get the balance of a poolToken of the fee collector feeCollectorTokenBalances[i] = IERC20(poolTokens[i]).balanceOf(address(this)); } // tokens are exitted to feeCollector crp.exitPool(_amount, minTokenOut); IERC20 tokenInterface; uint256 tokenBalanceToTransfer; for (uint256 i=0; i<poolTokens.length; i++) { tokenInterface = IERC20(poolTokens[i]); tokenBalanceToTransfer = tokenInterface.balanceOf(address(this)).sub( // get the new balance of token feeCollectorTokenBalances[i] // subtract previous balance ); if (tokenBalanceToTransfer > 0) { // transfer to `_toAddress` [newBalance - oldBalance] tokenInterface.safeTransfer( _toAddress, tokenBalanceToTransfer ); // transfer to `_toAddress` } } } /** @author Asaf Silman @notice Replaces the current admin with a new admin. @dev The current admin rights are revoked, and given the new address. @dev The caller must be admin (see onlyAdmin modifier). @param _newAdmin The new admin address. */ function replaceAdmin(address _newAdmin) external override onlyAdmin { grantRole(DEFAULT_ADMIN_ROLE, _newAdmin); revokeRole(DEFAULT_ADMIN_ROLE, msg.sender); // caller must be admin } function getSplitAllocation() external view returns (uint256[] memory) { return (allocations); } function isAddressWhitelisted(address _address) external view returns (bool) {return (hasRole(WHITELISTED, _address)); } function isAddressAdmin(address _address) external view returns (bool) {return (hasRole(DEFAULT_ADMIN_ROLE, _address)); } function getBeneficiaries() external view returns (address[] memory) { return (beneficiaries); } function getSmartTreasuryAddress() external view returns (address) { return (beneficiaries[0]); } function isTokenInDespositList(address _tokenAddress) external view returns (bool) {return (depositTokens.contains(_tokenAddress)); } function getNumTokensInDepositList() external view returns (uint256) {return (depositTokens.length());} function getDepositTokens() external view returns (address[] memory) { uint256 numTokens = depositTokens.length(); address[] memory depositTokenList = new address[](numTokens); for (uint256 index = 0; index < numTokens; index++) { depositTokenList[index] = depositTokens.at(index); } return (depositTokenList); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_feeTreasuryAddress","type":"address"},{"internalType":"address","name":"_idleRebalancer","type":"address"},{"internalType":"address","name":"_multisig","type":"address"},{"internalType":"address[]","name":"_initialDepositTokens","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FULL_ALLOC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BENEFICIARIES","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NUM_FEE_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BENEFICIARIES","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELISTED","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addressToAdd","type":"address"}],"name":"addAddressToWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newBeneficiary","type":"address"},{"internalType":"uint256[]","name":"_newAllocation","type":"uint256[]"}],"name":"addBeneficiaryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool[]","name":"_depositTokensEnabled","type":"bool[]"},{"internalType":"uint256[]","name":"_minTokenOut","type":"uint256[]"},{"internalType":"uint256","name":"_minPoolAmountOut","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBeneficiaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumTokensInDepositList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSmartTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSplitAllocation","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isAddressAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isAddressWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"isTokenInDespositList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"registerTokenToDepositList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addressToRemove","type":"address"}],"name":"removeAddressFromWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256[]","name":"_newAllocation","type":"uint256[]"}],"name":"removeBeneficiaryAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"removeTokenFromDepositList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"replaceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_newBeneficiary","type":"address"},{"internalType":"uint256[]","name":"_newAllocation","type":"uint256[]"}],"name":"replaceBeneficiaryAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_smartTreasuryAddress","type":"address"}],"name":"setSmartTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_allocations","type":"uint256[]"}],"name":"setSplitAllocation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_toAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_toAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256[]","name":"minTokenOut","type":"uint256[]"}],"name":"withdrawUnderlying","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200410938038062004109833981016040819052620000349162000966565b6001600160a01b038516620000665760405162461bcd60e51b81526004016200005d9062000d76565b60405180910390fd5b6001600160a01b0384166200008f5760405162461bcd60e51b81526004016200005d9062000cf7565b6001600160a01b038316620000b85760405162461bcd60e51b81526004016200005d9062000b81565b6001600160a01b038216620000e15760405162461bcd60e51b81526004016200005d9062000c89565b600f81511115620000f157600080fd5b620001076000836001600160e01b03620003e616565b62000132604051620001199062000ac6565b604051908190039020836001600160e01b03620003e616565b6200015d604051620001449062000ac6565b604051908190039020846001600160e01b03620003e616565b606085901b6001600160601b03191660809081526040805160038082529281019091529081602001602082028036833750508151620001a492600392506020019062000854565b50620138806003600081548110620001b857fe5b9060005260206000200181905550613a986003600181548110620001d857fe5b90600052602060002001819055506113886003600281548110620001f857fe5b60009182526020909120015560408051600380825260808201909252908160200160208202803683375050815162000238926004925060200190620008a4565b508360046001815481106200024957fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260046002815481106200028757fe5b6000918252602082200180546001600160a01b0319166001600160a01b039390931692909217909155805b8251811015620003d957828181518110620002c957fe5b6020026020010151915060006001600160a01b0316826001600160a01b03161415620003095760405162461bcd60e51b81526004016200005d9062000b4a565b866001600160a01b0316826001600160a01b031614156200033e5760405162461bcd60e51b81526004016200005d9062000bef565b62000359826001620003ff60201b6200166e1790919060201c565b15620003795760405162461bcd60e51b81526004016200005d9062000c1b565b620003b4737a250d5630b4cf539739df2c5dacb4c659f2488d600019846001600160a01b03166200042860201b62001683179092919060201c565b620003cf8260016200052a60201b6200176b1790919060201c565b50600101620002b2565b5050505050505062000e03565b620003fb82826001600160e01b036200054a16565b5050565b60006200041f836001600160a01b0384166001600160e01b03620005cc16565b90505b92915050565b6000620004c782856001600160a01b031663dd62ed3e30876040518363ffffffff1660e01b81526004016200045f92919062000ae2565b60206040518083038186803b1580156200047857600080fd5b505afa1580156200048d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004b3919062000a8f565b620005e460201b620017801790919060201c565b9050620005248463095ea7b360e01b8584604051602401620004eb92919062000afc565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200060c16565b50505050565b60006200041f836001600160a01b0384166001600160e01b03620006ad16565b6000828152602081815260409091206200056f9183906200176b6200052a821b17901c565b15620003fb57620005886001600160e01b036200070516565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60009081526001919091016020526040902054151590565b6000828201838110156200041f5760405162461bcd60e51b81526004016200005d9062000bb8565b606062000668826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200070a60201b620017a5179092919060201c565b805190915015620006a8578080602001905181019062000689919062000a6d565b620006a85760405162461bcd60e51b81526004016200005d9062000d2c565b505050565b6000620006c483836001600160e01b03620005cc16565b620006fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000422565b50600062000422565b335b90565b60606200072484846000856001600160e01b036200072e16565b90505b9392505050565b606082471015620007535760405162461bcd60e51b81526004016200005d9062000c43565b62000767856001600160e01b036200081016565b620007865760405162461bcd60e51b81526004016200005d9062000cc0565b60006060866001600160a01b03168587604051620007a5919062000aa8565b60006040518083038185875af1925050503d8060008114620007e4576040519150601f19603f3d011682016040523d82523d6000602084013e620007e9565b606091505b509092509050620008058282866001600160e01b036200081616565b979650505050505050565b3b151590565b606083156200082757508162000727565b825115620008385782518084602001fd5b8160405162461bcd60e51b81526004016200005d919062000b15565b82805482825590600052602060002090810192821562000892579160200282015b828111156200089257825182559160200191906001019062000875565b50620008a09291506200090a565b5090565b828054828255906000526020600020908101928215620008fc579160200282015b82811115620008fc57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620008c5565b50620008a092915062000927565b6200070791905b80821115620008a0576000815560010162000911565b6200070791905b80821115620008a05780546001600160a01b03191681556001016200092e565b80516001600160a01b03811681146200042257600080fd5b600080600080600060a086880312156200097e578081fd5b6200098a87876200094e565b945060206200099c888289016200094e565b9450620009ad88604089016200094e565b9350620009be88606089016200094e565b60808801519093506001600160401b0380821115620009db578384fd5b8189018a601f820112620009ed578485fd5b8051925081831115620009fe578485fd5b838302915062000a1084830162000dad565b8381528481019082860184840187018e101562000a2b578788fd5b8794505b8585101562000a595762000a448e826200094e565b83526001949094019391860191860162000a2f565b508096505050505050509295509295909350565b60006020828403121562000a7f578081fd5b815180151581146200041f578182fd5b60006020828403121562000aa1578081fd5b5051919050565b6000825162000abc81846020870162000dd4565b9190910192915050565b6f57484954454c49535445445f524f4c4560801b815260100190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b600060208252825180602084015262000b3681604085016020870162000dd4565b601f01601f19169190910160400192915050565b60208082526019908201527f546f6b656e2063616e6e6f742062652030206164647265737300000000000000604082015260600190565b6020808252601e908201527f526562616c616e6365722063616e6e6f74206265203020616464726573730000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526012908201527115d15512081b9bdd081cdd5c1c1bdc9d195960721b604082015260600190565b6020808252600e908201526d416c72656164792065786973747360901b604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601c908201527f4d756c74697369672063616e6e6f742062652030206164647265737300000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252818101527f4665652054726561737572792063616e6e6f7420626520302061646472657373604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601c908201527f574554482063616e6e6f74206265207468652030206164647265737300000000604082015260600190565b6040518181016001600160401b038111828210171562000dcc57600080fd5b604052919050565b60005b8381101562000df157818101518382015260200162000dd7565b83811115620005245750506000910152565b60805160601c6132ca62000e3f6000398061088952806108c05280610c695280611b6a5280611d615280611ed15280611f5c52506132ca6000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c806388f133141161011a578063b6bc8ae9116100ad578063d9caed121161007c578063d9caed1214610428578063dfd5b1c91461043b578063ea5330cb14610443578063ee9d496b14610456578063fb01600d1461046957610206565b8063b6bc8ae9146103dc578063c4f4face146103ef578063ca15c87314610402578063d547741f1461041557610206565b80639244f496116100e95780639244f4961461039b578063a217fddf146103ae578063aa7f3177146103b6578063ad556cd9146103c957610206565b806388f13314146103585780639010d07c14610360578063913b722c1461037357806391d148541461038857610206565b806348c9189b1161019d5780636052147a1161016c5780636052147a1461030f5780636bbb010814610317578063810a79ca1461032a578063846b130b1461033d57806386e0b8bc1461035057610206565b806348c9189b146102c15780634bb01abb146102d65780634f1d5ef2146102e95780634fa902d7146102fc57610206565b80632348dd18116101d95780632348dd1814610271578063248a9ca3146102865780632f2ff15d1461029957806336568abe146102ae57610206565b80630b71f1161461020b57806313f44d101461022957806318a02ecd146102495780631f7197561461025c575b600080fd5b610213610471565b6040516102209190612b69565b60405180910390f35b61023c610237366004612650565b610488565b6040516102209190612b5e565b61023c610257366004612650565b6104ad565b6102646104c0565b6040516102209190612b1a565b610279610519565b6040516102209190613165565b610213610294366004612917565b61051e565b6102ac6102a736600461292f565b610533565b005b6102ac6102bc36600461292f565b610584565b6102c96105c6565b6040516102209190612a9f565b6102ac6102e4366004612650565b6105f0565b6102ac6102f73660046126ac565b610637565b6102ac61030a366004612650565b6107e3565b61021361092f565b6102ac6103253660046128bc565b610940565b6102ac6103383660046127f2565b6109f7565b6102ac61034b366004612650565b610a87565b610213610aee565b610279610af3565b6102c961036e36600461295e565b610af8565b61037b610b1d565b6040516102209190612b07565b61023c61039636600461292f565b610b7e565b6102ac6103a9366004612650565b610b9c565b610213610be0565b61023c6103c4366004612650565b610be5565b6102ac6103d7366004612650565b610bf1565b6102ac6103ea3660046129f4565b610d28565b6102ac6103fd366004612650565b610edc565b610213610410366004612917565b610f19565b6102ac61042336600461292f565b610f30565b6102ac61043636600461266c565b610f6a565b610213610fab565b6102ac6104513660046126fe565b610fb2565b6102ac6104643660046129b3565b61142a565b61037b6115ca565b60405161047d90612a83565b604051809103902081565b60006104a760405161049990612a83565b604051809103902083610b7e565b92915050565b60006104a760018363ffffffff61166e16565b6060600380548060200260200160405190810160405280929190818152602001828054801561050e57602002820191906000526020600020905b8154815260200190600101908083116104fa575b505050505090505b90565b600581565b60009081526020819052604090206002015490565b600082815260208190526040902060020154610551906103966117bc565b6105765760405162461bcd60e51b815260040161056d90612c46565b60405180910390fd5b61058082826117c0565b5050565b61058c6117bc565b6001600160a01b0316816001600160a01b0316146105bc5760405162461bcd60e51b815260040161056d90613116565b610580828261182f565b600060046000815481106105d657fe5b6000918252602090912001546001600160a01b0316905090565b6105fb600033610b7e565b6106175760405162461bcd60e51b815260040161056d90612ec9565b61063460405161062690612a83565b604051809103902082610f30565b50565b60006001600160a01b0316600460008154811061065057fe5b6000918252602090912001546001600160a01b031614156106835760405162461bcd60e51b815260040161056d90612dd1565b61068e600033610b7e565b6106aa5760405162461bcd60e51b815260040161056d90612ec9565b6004546005116106cc5760405162461bcd60e51b815260040161056d906130eb565b6001600160a01b0383166106f25760405162461bcd60e51b815260040161056d90612d2c565b60005b60045481101561075157836001600160a01b03166004828154811061071657fe5b6000918252602090912001546001600160a01b031614156107495760405162461bcd60e51b815260040161056d90612e01565b6001016106f5565b5061075a61189e565b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b03851617905560408051602083810280830182019093528382526107de9285918591829185019084908082843760009201919091525061198f92505050565b505050565b6107ee600033610b7e565b61080a5760405162461bcd60e51b815260040161056d90612ec9565b6001600160a01b0381166108305760405162461bcd60e51b815260040161056d90612d8f565b60006001600160a01b0316600460008154811061084957fe5b6000918252602090912001546001600160a01b0316146108b3576108b3600460008154811061087457fe5b60009182526020822001546001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692911690611a24565b6108ef6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168260001963ffffffff61168316565b8060046000815481106108fe57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b600061093b6001611ae7565b905090565b60006001600160a01b0316600460008154811061095957fe5b6000918252602090912001546001600160a01b0316141561098c5760405162461bcd60e51b815260040161056d90612dd1565b610997600033610b7e565b6109b35760405162461bcd60e51b815260040161056d90612ec9565b6109bb61189e565b61058082828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b60006001600160a01b03166004600081548110610a1057fe5b6000918252602090912001546001600160a01b03161415610a435760405162461bcd60e51b815260040161056d90612dd1565b610a60604051610a5290612a83565b604051809103902033610b7e565b610a7c5760405162461bcd60e51b815260040161056d90612ec9565b6107de838383611af2565b610a92600033610b7e565b610aae5760405162461bcd60e51b815260040161056d90612ec9565b610add6001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d600063ffffffff611a2416565b61058060018263ffffffff611fc916565b600f81565b600281565b6000828152602081905260408120610b16908363ffffffff611fde16565b9392505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561050e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b57575050505050905090565b6000828152602081905260408120610b16908363ffffffff61166e16565b610ba7600033610b7e565b610bc35760405162461bcd60e51b815260040161056d90612ec9565b610634604051610bd290612a83565b604051809103902082610533565b600081565b60006104a78183610b7e565b610bfc600033610b7e565b610c185760405162461bcd60e51b815260040161056d90612ec9565b600f610c246001611ae7565b10610c415760405162461bcd60e51b815260040161056d90612ccc565b6001600160a01b038116610c675760405162461bcd60e51b815260040161056d90612be7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03161415610cb95760405162461bcd60e51b815260040161056d90612d63565b610cca60018263ffffffff61166e16565b15610ce75760405162461bcd60e51b815260040161056d90612e30565b610d176001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d60001963ffffffff61168316565b61058060018263ffffffff61176b16565b60006001600160a01b03166004600081548110610d4157fe5b6000918252602090912001546001600160a01b03161415610d745760405162461bcd60e51b815260040161056d90612dd1565b610d7f600033610b7e565b610d9b5760405162461bcd60e51b815260040161056d90612ec9565b6001831015610dbc5760405162461bcd60e51b815260040161056d9061305e565b6004548310610ddd5760405162461bcd60e51b815260040161056d90612fb7565b600454600210610dff5760405162461bcd60e51b815260040161056d90612e58565b610e0761189e565b600480546000198101908110610e1957fe5b600091825260209091200154600480546001600160a01b039092169185908110610e3f57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480610e7857fe5b6001900381819060005260206000200160006101000a8154906001600160a01b03021916905590556107de82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b610ee7600033610b7e565b610f035760405162461bcd60e51b815260040161056d90612ec9565b610f0e600082610533565b610634600033610f30565b60008181526020819052604081206104a790611ae7565b600082815260208190526040902060020154610f4e906103966117bc565b6105bc5760405162461bcd60e51b815260040161056d90612eef565b610f75600033610b7e565b610f915760405162461bcd60e51b815260040161056d90612ec9565b6107de6001600160a01b038416838363ffffffff611fea16565b620186a081565b60006001600160a01b03166004600081548110610fcb57fe5b6000918252602090912001546001600160a01b03161415610ffe5760405162461bcd60e51b815260040161056d90612dd1565b611009600033610b7e565b6110255760405162461bcd60e51b815260040161056d90612ec9565b6000600460008154811061103557fe5b60009182526020808320909101546040805163b64ef17b60e01b815290516001600160a01b039092169450849263b64ef17b92600480840193829003018186803b15801561108257600080fd5b505afa158015611096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ba919061297f565b90506000816001600160a01b031663cd2ed8fb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110f757600080fd5b505afa15801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f919061299b565b90508381146111505760405162461bcd60e51b815260040161056d90612c1e565b6060826001600160a01b031663cc77828d6040518163ffffffff1660e01b815260040160006040518083038186803b15801561118b57600080fd5b505afa15801561119f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111c79190810190612757565b90506060826001600160401b03811180156111e157600080fd5b5060405190808252806020026020018201604052801561120b578160200160208202803683370190505b50905060005b82518110156112c85782818151811061122657fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016112599190612a9f565b60206040518083038186803b15801561127157600080fd5b505afa158015611285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a9919061299b565b8282815181106112b557fe5b6020908102919091010152600101611211565b5060405163b02f0b7360e01b81526001600160a01b0386169063b02f0b73906112f9908b908b908b90600401613182565b600060405180830381600087803b15801561131357600080fd5b505af1158015611327573d6000803e3d6000fd5b5050505060008060008090505b845181101561141c5784818151811061134957fe5b602002602001015192506113f284828151811061136257fe5b6020026020010151846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016113969190612a9f565b60206040518083038186803b1580156113ae57600080fd5b505afa1580156113c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e6919061299b565b9063ffffffff61200916565b91508115611414576114146001600160a01b0384168d8463ffffffff611fea16565b600101611334565b505050505050505050505050565b60006001600160a01b0316600460008154811061144357fe5b6000918252602090912001546001600160a01b031614156114765760405162461bcd60e51b815260040161056d90612dd1565b611481600033610b7e565b61149d5760405162461bcd60e51b815260040161056d90612ec9565b60018410156114be5760405162461bcd60e51b815260040161056d9061305e565b6001600160a01b0383166114e45760405162461bcd60e51b815260040161056d90612c95565b60005b60045481101561154357836001600160a01b03166004828154811061150857fe5b6000918252602090912001546001600160a01b0316141561153b5760405162461bcd60e51b815260040161056d90612e01565b6001016114e7565b5061154c61189e565b826004858154811061155a57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506115c482828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b50505050565b606060006115d86001611ae7565b90506060816001600160401b03811180156115f257600080fd5b5060405190808252806020026020018201604052801561161c578160200160208202803683370190505b50905060005b828110156116675761163b60018263ffffffff611fde16565b82828151811061164757fe5b6001600160a01b0390921660209283029190910190910152600101611622565b5091505090565b6000610b16836001600160a01b03841661204b565b600061171382856001600160a01b031663dd62ed3e30876040518363ffffffff1660e01b81526004016116b7929190612ab3565b60206040518083038186803b1580156116cf57600080fd5b505afa1580156116e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611707919061299b565b9063ffffffff61178016565b90506115c48463095ea7b360e01b8584604051602401611734929190612acd565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612063565b6000610b16836001600160a01b0384166120f2565b600082820183811015610b165760405162461bcd60e51b815260040161056d90612cf5565b60606117b4848460008561213c565b949350505050565b3390565b60008281526020819052604090206117de908263ffffffff61176b16565b15610580576117eb6117bc565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260208190526040902061184d908263ffffffff611fc916565b156105805761185a6117bc565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006118aa6001611ae7565b90506060816001600160401b03811180156118c457600080fd5b506040519080825280602002602001820160405280156118ee578160200160208202803683370190505b5090506060826001600160401b038111801561190957600080fd5b50604051908082528060200260200182016040528015611933578160200160208202803683370190505b50905060005b8381101561198257600183828151811061194f57fe5b602002602001019015159081151581525050600182828151811061196f57fe5b6020908102919091010152600101611939565b506107de82826001611af2565b6004548151146119b15760405162461bcd60e51b815260040161056d90612c1e565b6000805b82518110156119ee576119e48382815181106119cd57fe5b60200260200101518361178090919063ffffffff16565b91506001016119b5565b50620186a08114611a115760405162461bcd60e51b815260040161056d90612f80565b81516107de90600390602085019061252a565b801580611aac5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90611a5a9030908690600401612ab3565b60206040518083038186803b158015611a7257600080fd5b505afa158015611a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aaa919061299b565b155b611ac85760405162461bcd60e51b815260040161056d90613095565b6107de8363095ea7b360e01b8484604051602401611734929190612acd565b60006104a7826121fd565b6000611afe6001611ae7565b905080845114611b205760405162461bcd60e51b815260040161056d90612c1e565b80835114611b405760405162461bcd60e51b815260040161056d90612c1e565b604080516002808252606080830184526000938493849390916020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600181518110611b9657fe5b6001600160a01b039092166020928302919091019091015260005b85811015611d4957888181518110611bc557fe5b6020908102919091010151611bd957611d41565b611bea60018263ffffffff611fde16565b6040516370a0823160e01b81529094506001600160a01b038516906370a0823190611c19903090600401612a9f565b60206040518083038186803b158015611c3157600080fd5b505afa158015611c45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c69919061299b565b94508415611d41578382600081518110611c7f57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b0316635c11d795868a8481518110611ccf57fe5b60200260200101518530611cee6107084261178090919063ffffffff16565b6040518663ffffffff1660e01b8152600401611d0e9594939291906131c4565b600060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b505050505b600101611bb1565b506040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190611d96903090600401612a9f565b60206040518083038186803b158015611dae57600080fd5b505afa158015611dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de6919061299b565b91508115611fbf576060611e4a6003805480602002602001604051908101604052809291908181526020018280548015611e3f57602002820191906000526020600020905b815481526020019060010190808311611e2b575b505050505084612201565b9050600081600081518110611e5b57fe5b602002602001015190506000611e7a828661200990919063ffffffff16565b1115611f125760015b600354811015611f1057611f0860048281548110611e9d57fe5b9060005260206000200160009054906101000a90046001600160a01b0316848381518110611ec757fe5b60200260200101517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fea9092919063ffffffff16565b600101611e83565b505b8015611fbc5760006004600081548110611f2857fe5b600091825260209091200154604051635db3427760e01b81526001600160a01b0390911691508190635db3427790611f88907f00000000000000000000000000000000000000000000000000000000000000009086908e90600401612ae6565b600060405180830381600087803b158015611fa257600080fd5b505af1158015611fb6573d6000803e3d6000fd5b50505050505b50505b5050505050505050565b6000610b16836001600160a01b038416612306565b6000610b1683836123cc565b6107de8363a9059cbb60e01b8484604051602401611734929190612acd565b6000610b1683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612411565b60009081526001919091016020526040902054151590565b60606120b8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117a59092919063ffffffff16565b8051909150156107de57808060200190518101906120d691906128fb565b6107de5760405162461bcd60e51b815260040161056d90613014565b60006120fe838361204b565b612134575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104a7565b5060006104a7565b60608247101561215e5760405162461bcd60e51b815260040161056d90612e83565b6121678561243d565b6121835760405162461bcd60e51b815260040161056d90612fdd565b60006060866001600160a01b031685876040516121a09190612a67565b60006040518083038185875af1925050503d80600081146121dd576040519150601f19603f3d011682016040523d82523d6000602084013e6121e2565b606091505b50915091506121f2828286612443565b979650505050505050565b5490565b606082516001600160401b038111801561221a57600080fd5b50604051908082528060200260200182016040528015612244578160200160208202803683370190505b509050600080805b85518110156122fd57600186510381141561228e57612271858363ffffffff61200916565b84828151811061227d57fe5b6020026020010181815250506122f5565b6122c7620186a06122bb8884815181106122a457fe5b60200260200101518861247c90919063ffffffff16565b9063ffffffff6124b616565b92506122d9828463ffffffff61178016565b9150828482815181106122e857fe5b6020026020010181815250505b60010161224c565b50505092915050565b600081815260018301602052604081205480156123c2578354600019808301919081019060009087908390811061233957fe5b906000526020600020015490508087600001848154811061235657fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061238657fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506104a7565b60009150506104a7565b815460009082106123ef5760405162461bcd60e51b815260040161056d90612ba5565b8260000182815481106123fe57fe5b9060005260206000200154905092915050565b600081848411156124355760405162461bcd60e51b815260040161056d9190612b72565b505050900390565b3b151590565b60608315612452575081610b16565b8251156124625782518084602001fd5b8160405162461bcd60e51b815260040161056d9190612b72565b60008261248b575060006104a7565b8282028284828161249857fe5b0414610b165760405162461bcd60e51b815260040161056d90612f3f565b6000610b1683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250600081836125145760405162461bcd60e51b815260040161056d9190612b72565b50600083858161252057fe5b0495945050505050565b828054828255906000526020600020908101928215612565579160200282015b8281111561256557825182559160200191906001019061254a565b50612571929150612575565b5090565b61051691905b80821115612571576000815560010161257b565b60008083601f8401126125a0578182fd5b5081356001600160401b038111156125b6578182fd5b60208301915083602080830285010111156125d057600080fd5b9250929050565b600082601f8301126125e7578081fd5b81356125fa6125f582613226565b613200565b81815291506020808301908481018184028601820187101561261b57600080fd5b60005b8481101561263a5781358452928201929082019060010161261e565b505050505092915050565b80356104a781613286565b600060208284031215612661578081fd5b8135610b1681613271565b600080600060608486031215612680578182fd5b833561268b81613271565b9250602084013561269b81613271565b929592945050506040919091013590565b6000806000604084860312156126c0578283fd5b83356126cb81613271565b925060208401356001600160401b038111156126e5578283fd5b6126f18682870161258f565b9497909650939450505050565b60008060008060608587031215612713578081fd5b843561271e81613271565b93506020850135925060408501356001600160401b0381111561273f578182fd5b61274b8782880161258f565b95989497509550505050565b60006020808385031215612769578182fd5b82516001600160401b0381111561277e578283fd5b80840185601f82011261278f578384fd5b8051915061279f6125f583613226565b82815283810190828501858502840186018910156127bb578687fd5b8693505b848410156127e65780516127d281613271565b8352600193909301929185019185016127bf565b50979650505050505050565b600080600060608486031215612806578283fd5b83356001600160401b038082111561281c578485fd5b81860187601f82011261282d578586fd5b8035925061283d6125f584613226565b80848252602080830192508084018b82838902870101111561285d57898afd5b8994505b86851015612887576128738c82612645565b845260019490940193928101928101612861565b50909750880135935050508082111561289e578384fd5b506128ab868287016125d7565b925050604084013590509250925092565b600080602083850312156128ce578182fd5b82356001600160401b038111156128e3578283fd5b6128ef8582860161258f565b90969095509350505050565b60006020828403121561290c578081fd5b8151610b1681613286565b600060208284031215612928578081fd5b5035919050565b60008060408385031215612941578182fd5b82359150602083013561295381613271565b809150509250929050565b60008060408385031215612970578182fd5b50508035926020909101359150565b600060208284031215612990578081fd5b8151610b1681613271565b6000602082840312156129ac578081fd5b5051919050565b600080600080606085870312156129c8578182fd5b8435935060208501356129da81613271565b925060408501356001600160401b0381111561273f578283fd5b600080600060408486031215612a08578081fd5b8335925060208401356001600160401b038111156126e5578182fd5b6000815180845260208085019450808401835b83811015612a5c5781516001600160a01b031687529582019590820190600101612a37565b509495945050505050565b60008251612a79818460208701613245565b9190910192915050565b6f57484954454c49535445445f524f4c4560801b815260100190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b600060208252610b166020830184612a24565b6020808252825182820181905260009190848201906040850190845b81811015612b5257835183529284019291840191600101612b36565b50909695505050505050565b901515815260200190565b90815260200190565b6000602082528251806020840152612b91816040850160208701613245565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526019908201527f546f6b656e2063616e6e6f742062652030206164647265737300000000000000604082015260600190565b6020808252600e908201526d092dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601f908201527f42656e65666963696172792063616e6e6f742062652030206164647265737300604082015260600190565b6020808252600f908201526e546f6f206d616e7920746f6b656e7360881b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601f908201527f62656e65666963696172792063616e6e6f742062652030206164647265737300604082015260600190565b60208082526012908201527115d15512081b9bdd081cdd5c1c1bdc9d195960721b604082015260600190565b60208082526022908201527f536d6172742074726561737572792063616e6e6f742062652030206164647265604082015261737360f01b606082015260800190565b60208082526016908201527514db585c9d08151c99585cdd5c9e481b9bdd081cd95d60521b604082015260600190565b6020808252601590820152744475706c69636174652062656e656669636961727960581b604082015260600190565b6020808252600e908201526d416c72656164792065786973747360901b604082015260600190565b6020808252601190820152704d696e2062656e6566696369617269657360781b604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252600c908201526b155b985d5d1a1bdc9a5cd95960a21b604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601b908201527f526174696f20646f6573206e6f7420657175616c203130303030300000000000604082015260600190565b6020808252600c908201526b4f7574206f662072616e676560a01b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601d908201527f496e76616c69642062656e656669636961727920746f2072656d6f7665000000604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252601190820152704d61782062656e6566696369617269657360781b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6fffffffffffffffffffffffffffffffff91909116815260200190565b838152604060208201819052810182905260006001600160fb1b038311156131a8578081fd5b6020830280856060850137919091016060019081529392505050565b600086825285602083015260a060408301526131e360a0830186612a24565b6001600160a01b0394909416606083015250608001529392505050565b6040518181016001600160401b038111828210171561321e57600080fd5b604052919050565b60006001600160401b0382111561323b578081fd5b5060209081020190565b60005b83811015613260578181015183820152602001613248565b838111156115c45750506000910152565b6001600160a01b038116811461063457600080fd5b801515811461063457600080fdfea26469706673582212205b898a15cb0a34155ddffe2fdf6e10a8ec694f7105b1f2a452c3125868cb88d664736f6c63430006080033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000069a62c24f16d4914a48919613e8ee330641bcb94000000000000000000000000b3c8e5534f0063545cbbb7ce86854bf42db8872b000000000000000000000000e8ea8bae250028a8709a3841e0ae1a44820d677b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000070000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000085d4780b73119b644ae5ecd22b37600000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f510000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c806388f133141161011a578063b6bc8ae9116100ad578063d9caed121161007c578063d9caed1214610428578063dfd5b1c91461043b578063ea5330cb14610443578063ee9d496b14610456578063fb01600d1461046957610206565b8063b6bc8ae9146103dc578063c4f4face146103ef578063ca15c87314610402578063d547741f1461041557610206565b80639244f496116100e95780639244f4961461039b578063a217fddf146103ae578063aa7f3177146103b6578063ad556cd9146103c957610206565b806388f13314146103585780639010d07c14610360578063913b722c1461037357806391d148541461038857610206565b806348c9189b1161019d5780636052147a1161016c5780636052147a1461030f5780636bbb010814610317578063810a79ca1461032a578063846b130b1461033d57806386e0b8bc1461035057610206565b806348c9189b146102c15780634bb01abb146102d65780634f1d5ef2146102e95780634fa902d7146102fc57610206565b80632348dd18116101d95780632348dd1814610271578063248a9ca3146102865780632f2ff15d1461029957806336568abe146102ae57610206565b80630b71f1161461020b57806313f44d101461022957806318a02ecd146102495780631f7197561461025c575b600080fd5b610213610471565b6040516102209190612b69565b60405180910390f35b61023c610237366004612650565b610488565b6040516102209190612b5e565b61023c610257366004612650565b6104ad565b6102646104c0565b6040516102209190612b1a565b610279610519565b6040516102209190613165565b610213610294366004612917565b61051e565b6102ac6102a736600461292f565b610533565b005b6102ac6102bc36600461292f565b610584565b6102c96105c6565b6040516102209190612a9f565b6102ac6102e4366004612650565b6105f0565b6102ac6102f73660046126ac565b610637565b6102ac61030a366004612650565b6107e3565b61021361092f565b6102ac6103253660046128bc565b610940565b6102ac6103383660046127f2565b6109f7565b6102ac61034b366004612650565b610a87565b610213610aee565b610279610af3565b6102c961036e36600461295e565b610af8565b61037b610b1d565b6040516102209190612b07565b61023c61039636600461292f565b610b7e565b6102ac6103a9366004612650565b610b9c565b610213610be0565b61023c6103c4366004612650565b610be5565b6102ac6103d7366004612650565b610bf1565b6102ac6103ea3660046129f4565b610d28565b6102ac6103fd366004612650565b610edc565b610213610410366004612917565b610f19565b6102ac61042336600461292f565b610f30565b6102ac61043636600461266c565b610f6a565b610213610fab565b6102ac6104513660046126fe565b610fb2565b6102ac6104643660046129b3565b61142a565b61037b6115ca565b60405161047d90612a83565b604051809103902081565b60006104a760405161049990612a83565b604051809103902083610b7e565b92915050565b60006104a760018363ffffffff61166e16565b6060600380548060200260200160405190810160405280929190818152602001828054801561050e57602002820191906000526020600020905b8154815260200190600101908083116104fa575b505050505090505b90565b600581565b60009081526020819052604090206002015490565b600082815260208190526040902060020154610551906103966117bc565b6105765760405162461bcd60e51b815260040161056d90612c46565b60405180910390fd5b61058082826117c0565b5050565b61058c6117bc565b6001600160a01b0316816001600160a01b0316146105bc5760405162461bcd60e51b815260040161056d90613116565b610580828261182f565b600060046000815481106105d657fe5b6000918252602090912001546001600160a01b0316905090565b6105fb600033610b7e565b6106175760405162461bcd60e51b815260040161056d90612ec9565b61063460405161062690612a83565b604051809103902082610f30565b50565b60006001600160a01b0316600460008154811061065057fe5b6000918252602090912001546001600160a01b031614156106835760405162461bcd60e51b815260040161056d90612dd1565b61068e600033610b7e565b6106aa5760405162461bcd60e51b815260040161056d90612ec9565b6004546005116106cc5760405162461bcd60e51b815260040161056d906130eb565b6001600160a01b0383166106f25760405162461bcd60e51b815260040161056d90612d2c565b60005b60045481101561075157836001600160a01b03166004828154811061071657fe5b6000918252602090912001546001600160a01b031614156107495760405162461bcd60e51b815260040161056d90612e01565b6001016106f5565b5061075a61189e565b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b03851617905560408051602083810280830182019093528382526107de9285918591829185019084908082843760009201919091525061198f92505050565b505050565b6107ee600033610b7e565b61080a5760405162461bcd60e51b815260040161056d90612ec9565b6001600160a01b0381166108305760405162461bcd60e51b815260040161056d90612d8f565b60006001600160a01b0316600460008154811061084957fe5b6000918252602090912001546001600160a01b0316146108b3576108b3600460008154811061087457fe5b60009182526020822001546001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811692911690611a24565b6108ef6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168260001963ffffffff61168316565b8060046000815481106108fe57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b600061093b6001611ae7565b905090565b60006001600160a01b0316600460008154811061095957fe5b6000918252602090912001546001600160a01b0316141561098c5760405162461bcd60e51b815260040161056d90612dd1565b610997600033610b7e565b6109b35760405162461bcd60e51b815260040161056d90612ec9565b6109bb61189e565b61058082828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b60006001600160a01b03166004600081548110610a1057fe5b6000918252602090912001546001600160a01b03161415610a435760405162461bcd60e51b815260040161056d90612dd1565b610a60604051610a5290612a83565b604051809103902033610b7e565b610a7c5760405162461bcd60e51b815260040161056d90612ec9565b6107de838383611af2565b610a92600033610b7e565b610aae5760405162461bcd60e51b815260040161056d90612ec9565b610add6001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d600063ffffffff611a2416565b61058060018263ffffffff611fc916565b600f81565b600281565b6000828152602081905260408120610b16908363ffffffff611fde16565b9392505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561050e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b57575050505050905090565b6000828152602081905260408120610b16908363ffffffff61166e16565b610ba7600033610b7e565b610bc35760405162461bcd60e51b815260040161056d90612ec9565b610634604051610bd290612a83565b604051809103902082610533565b600081565b60006104a78183610b7e565b610bfc600033610b7e565b610c185760405162461bcd60e51b815260040161056d90612ec9565b600f610c246001611ae7565b10610c415760405162461bcd60e51b815260040161056d90612ccc565b6001600160a01b038116610c675760405162461bcd60e51b815260040161056d90612be7565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316816001600160a01b03161415610cb95760405162461bcd60e51b815260040161056d90612d63565b610cca60018263ffffffff61166e16565b15610ce75760405162461bcd60e51b815260040161056d90612e30565b610d176001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d60001963ffffffff61168316565b61058060018263ffffffff61176b16565b60006001600160a01b03166004600081548110610d4157fe5b6000918252602090912001546001600160a01b03161415610d745760405162461bcd60e51b815260040161056d90612dd1565b610d7f600033610b7e565b610d9b5760405162461bcd60e51b815260040161056d90612ec9565b6001831015610dbc5760405162461bcd60e51b815260040161056d9061305e565b6004548310610ddd5760405162461bcd60e51b815260040161056d90612fb7565b600454600210610dff5760405162461bcd60e51b815260040161056d90612e58565b610e0761189e565b600480546000198101908110610e1957fe5b600091825260209091200154600480546001600160a01b039092169185908110610e3f57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480610e7857fe5b6001900381819060005260206000200160006101000a8154906001600160a01b03021916905590556107de82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b610ee7600033610b7e565b610f035760405162461bcd60e51b815260040161056d90612ec9565b610f0e600082610533565b610634600033610f30565b60008181526020819052604081206104a790611ae7565b600082815260208190526040902060020154610f4e906103966117bc565b6105bc5760405162461bcd60e51b815260040161056d90612eef565b610f75600033610b7e565b610f915760405162461bcd60e51b815260040161056d90612ec9565b6107de6001600160a01b038416838363ffffffff611fea16565b620186a081565b60006001600160a01b03166004600081548110610fcb57fe5b6000918252602090912001546001600160a01b03161415610ffe5760405162461bcd60e51b815260040161056d90612dd1565b611009600033610b7e565b6110255760405162461bcd60e51b815260040161056d90612ec9565b6000600460008154811061103557fe5b60009182526020808320909101546040805163b64ef17b60e01b815290516001600160a01b039092169450849263b64ef17b92600480840193829003018186803b15801561108257600080fd5b505afa158015611096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ba919061297f565b90506000816001600160a01b031663cd2ed8fb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110f757600080fd5b505afa15801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f919061299b565b90508381146111505760405162461bcd60e51b815260040161056d90612c1e565b6060826001600160a01b031663cc77828d6040518163ffffffff1660e01b815260040160006040518083038186803b15801561118b57600080fd5b505afa15801561119f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111c79190810190612757565b90506060826001600160401b03811180156111e157600080fd5b5060405190808252806020026020018201604052801561120b578160200160208202803683370190505b50905060005b82518110156112c85782818151811061122657fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016112599190612a9f565b60206040518083038186803b15801561127157600080fd5b505afa158015611285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a9919061299b565b8282815181106112b557fe5b6020908102919091010152600101611211565b5060405163b02f0b7360e01b81526001600160a01b0386169063b02f0b73906112f9908b908b908b90600401613182565b600060405180830381600087803b15801561131357600080fd5b505af1158015611327573d6000803e3d6000fd5b5050505060008060008090505b845181101561141c5784818151811061134957fe5b602002602001015192506113f284828151811061136257fe5b6020026020010151846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016113969190612a9f565b60206040518083038186803b1580156113ae57600080fd5b505afa1580156113c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e6919061299b565b9063ffffffff61200916565b91508115611414576114146001600160a01b0384168d8463ffffffff611fea16565b600101611334565b505050505050505050505050565b60006001600160a01b0316600460008154811061144357fe5b6000918252602090912001546001600160a01b031614156114765760405162461bcd60e51b815260040161056d90612dd1565b611481600033610b7e565b61149d5760405162461bcd60e51b815260040161056d90612ec9565b60018410156114be5760405162461bcd60e51b815260040161056d9061305e565b6001600160a01b0383166114e45760405162461bcd60e51b815260040161056d90612c95565b60005b60045481101561154357836001600160a01b03166004828154811061150857fe5b6000918252602090912001546001600160a01b0316141561153b5760405162461bcd60e51b815260040161056d90612e01565b6001016114e7565b5061154c61189e565b826004858154811061155a57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506115c482828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061198f92505050565b50505050565b606060006115d86001611ae7565b90506060816001600160401b03811180156115f257600080fd5b5060405190808252806020026020018201604052801561161c578160200160208202803683370190505b50905060005b828110156116675761163b60018263ffffffff611fde16565b82828151811061164757fe5b6001600160a01b0390921660209283029190910190910152600101611622565b5091505090565b6000610b16836001600160a01b03841661204b565b600061171382856001600160a01b031663dd62ed3e30876040518363ffffffff1660e01b81526004016116b7929190612ab3565b60206040518083038186803b1580156116cf57600080fd5b505afa1580156116e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611707919061299b565b9063ffffffff61178016565b90506115c48463095ea7b360e01b8584604051602401611734929190612acd565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612063565b6000610b16836001600160a01b0384166120f2565b600082820183811015610b165760405162461bcd60e51b815260040161056d90612cf5565b60606117b4848460008561213c565b949350505050565b3390565b60008281526020819052604090206117de908263ffffffff61176b16565b15610580576117eb6117bc565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260208190526040902061184d908263ffffffff611fc916565b156105805761185a6117bc565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006118aa6001611ae7565b90506060816001600160401b03811180156118c457600080fd5b506040519080825280602002602001820160405280156118ee578160200160208202803683370190505b5090506060826001600160401b038111801561190957600080fd5b50604051908082528060200260200182016040528015611933578160200160208202803683370190505b50905060005b8381101561198257600183828151811061194f57fe5b602002602001019015159081151581525050600182828151811061196f57fe5b6020908102919091010152600101611939565b506107de82826001611af2565b6004548151146119b15760405162461bcd60e51b815260040161056d90612c1e565b6000805b82518110156119ee576119e48382815181106119cd57fe5b60200260200101518361178090919063ffffffff16565b91506001016119b5565b50620186a08114611a115760405162461bcd60e51b815260040161056d90612f80565b81516107de90600390602085019061252a565b801580611aac5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90611a5a9030908690600401612ab3565b60206040518083038186803b158015611a7257600080fd5b505afa158015611a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aaa919061299b565b155b611ac85760405162461bcd60e51b815260040161056d90613095565b6107de8363095ea7b360e01b8484604051602401611734929190612acd565b60006104a7826121fd565b6000611afe6001611ae7565b905080845114611b205760405162461bcd60e51b815260040161056d90612c1e565b80835114611b405760405162461bcd60e51b815260040161056d90612c1e565b604080516002808252606080830184526000938493849390916020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110611b9657fe5b6001600160a01b039092166020928302919091019091015260005b85811015611d4957888181518110611bc557fe5b6020908102919091010151611bd957611d41565b611bea60018263ffffffff611fde16565b6040516370a0823160e01b81529094506001600160a01b038516906370a0823190611c19903090600401612a9f565b60206040518083038186803b158015611c3157600080fd5b505afa158015611c45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c69919061299b565b94508415611d41578382600081518110611c7f57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b0316635c11d795868a8481518110611ccf57fe5b60200260200101518530611cee6107084261178090919063ffffffff16565b6040518663ffffffff1660e01b8152600401611d0e9594939291906131c4565b600060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b505050505b600101611bb1565b506040516370a0823160e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190611d96903090600401612a9f565b60206040518083038186803b158015611dae57600080fd5b505afa158015611dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de6919061299b565b91508115611fbf576060611e4a6003805480602002602001604051908101604052809291908181526020018280548015611e3f57602002820191906000526020600020905b815481526020019060010190808311611e2b575b505050505084612201565b9050600081600081518110611e5b57fe5b602002602001015190506000611e7a828661200990919063ffffffff16565b1115611f125760015b600354811015611f1057611f0860048281548110611e9d57fe5b9060005260206000200160009054906101000a90046001600160a01b0316848381518110611ec757fe5b60200260200101517f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316611fea9092919063ffffffff16565b600101611e83565b505b8015611fbc5760006004600081548110611f2857fe5b600091825260209091200154604051635db3427760e01b81526001600160a01b0390911691508190635db3427790611f88907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29086908e90600401612ae6565b600060405180830381600087803b158015611fa257600080fd5b505af1158015611fb6573d6000803e3d6000fd5b50505050505b50505b5050505050505050565b6000610b16836001600160a01b038416612306565b6000610b1683836123cc565b6107de8363a9059cbb60e01b8484604051602401611734929190612acd565b6000610b1683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612411565b60009081526001919091016020526040902054151590565b60606120b8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117a59092919063ffffffff16565b8051909150156107de57808060200190518101906120d691906128fb565b6107de5760405162461bcd60e51b815260040161056d90613014565b60006120fe838361204b565b612134575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104a7565b5060006104a7565b60608247101561215e5760405162461bcd60e51b815260040161056d90612e83565b6121678561243d565b6121835760405162461bcd60e51b815260040161056d90612fdd565b60006060866001600160a01b031685876040516121a09190612a67565b60006040518083038185875af1925050503d80600081146121dd576040519150601f19603f3d011682016040523d82523d6000602084013e6121e2565b606091505b50915091506121f2828286612443565b979650505050505050565b5490565b606082516001600160401b038111801561221a57600080fd5b50604051908082528060200260200182016040528015612244578160200160208202803683370190505b509050600080805b85518110156122fd57600186510381141561228e57612271858363ffffffff61200916565b84828151811061227d57fe5b6020026020010181815250506122f5565b6122c7620186a06122bb8884815181106122a457fe5b60200260200101518861247c90919063ffffffff16565b9063ffffffff6124b616565b92506122d9828463ffffffff61178016565b9150828482815181106122e857fe5b6020026020010181815250505b60010161224c565b50505092915050565b600081815260018301602052604081205480156123c2578354600019808301919081019060009087908390811061233957fe5b906000526020600020015490508087600001848154811061235657fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061238657fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506104a7565b60009150506104a7565b815460009082106123ef5760405162461bcd60e51b815260040161056d90612ba5565b8260000182815481106123fe57fe5b9060005260206000200154905092915050565b600081848411156124355760405162461bcd60e51b815260040161056d9190612b72565b505050900390565b3b151590565b60608315612452575081610b16565b8251156124625782518084602001fd5b8160405162461bcd60e51b815260040161056d9190612b72565b60008261248b575060006104a7565b8282028284828161249857fe5b0414610b165760405162461bcd60e51b815260040161056d90612f3f565b6000610b1683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250600081836125145760405162461bcd60e51b815260040161056d9190612b72565b50600083858161252057fe5b0495945050505050565b828054828255906000526020600020908101928215612565579160200282015b8281111561256557825182559160200191906001019061254a565b50612571929150612575565b5090565b61051691905b80821115612571576000815560010161257b565b60008083601f8401126125a0578182fd5b5081356001600160401b038111156125b6578182fd5b60208301915083602080830285010111156125d057600080fd5b9250929050565b600082601f8301126125e7578081fd5b81356125fa6125f582613226565b613200565b81815291506020808301908481018184028601820187101561261b57600080fd5b60005b8481101561263a5781358452928201929082019060010161261e565b505050505092915050565b80356104a781613286565b600060208284031215612661578081fd5b8135610b1681613271565b600080600060608486031215612680578182fd5b833561268b81613271565b9250602084013561269b81613271565b929592945050506040919091013590565b6000806000604084860312156126c0578283fd5b83356126cb81613271565b925060208401356001600160401b038111156126e5578283fd5b6126f18682870161258f565b9497909650939450505050565b60008060008060608587031215612713578081fd5b843561271e81613271565b93506020850135925060408501356001600160401b0381111561273f578182fd5b61274b8782880161258f565b95989497509550505050565b60006020808385031215612769578182fd5b82516001600160401b0381111561277e578283fd5b80840185601f82011261278f578384fd5b8051915061279f6125f583613226565b82815283810190828501858502840186018910156127bb578687fd5b8693505b848410156127e65780516127d281613271565b8352600193909301929185019185016127bf565b50979650505050505050565b600080600060608486031215612806578283fd5b83356001600160401b038082111561281c578485fd5b81860187601f82011261282d578586fd5b8035925061283d6125f584613226565b80848252602080830192508084018b82838902870101111561285d57898afd5b8994505b86851015612887576128738c82612645565b845260019490940193928101928101612861565b50909750880135935050508082111561289e578384fd5b506128ab868287016125d7565b925050604084013590509250925092565b600080602083850312156128ce578182fd5b82356001600160401b038111156128e3578283fd5b6128ef8582860161258f565b90969095509350505050565b60006020828403121561290c578081fd5b8151610b1681613286565b600060208284031215612928578081fd5b5035919050565b60008060408385031215612941578182fd5b82359150602083013561295381613271565b809150509250929050565b60008060408385031215612970578182fd5b50508035926020909101359150565b600060208284031215612990578081fd5b8151610b1681613271565b6000602082840312156129ac578081fd5b5051919050565b600080600080606085870312156129c8578182fd5b8435935060208501356129da81613271565b925060408501356001600160401b0381111561273f578283fd5b600080600060408486031215612a08578081fd5b8335925060208401356001600160401b038111156126e5578182fd5b6000815180845260208085019450808401835b83811015612a5c5781516001600160a01b031687529582019590820190600101612a37565b509495945050505050565b60008251612a79818460208701613245565b9190910192915050565b6f57484954454c49535445445f524f4c4560801b815260100190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b600060208252610b166020830184612a24565b6020808252825182820181905260009190848201906040850190845b81811015612b5257835183529284019291840191600101612b36565b50909695505050505050565b901515815260200190565b90815260200190565b6000602082528251806020840152612b91816040850160208701613245565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526019908201527f546f6b656e2063616e6e6f742062652030206164647265737300000000000000604082015260600190565b6020808252600e908201526d092dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601f908201527f42656e65666963696172792063616e6e6f742062652030206164647265737300604082015260600190565b6020808252600f908201526e546f6f206d616e7920746f6b656e7360881b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601f908201527f62656e65666963696172792063616e6e6f742062652030206164647265737300604082015260600190565b60208082526012908201527115d15512081b9bdd081cdd5c1c1bdc9d195960721b604082015260600190565b60208082526022908201527f536d6172742074726561737572792063616e6e6f742062652030206164647265604082015261737360f01b606082015260800190565b60208082526016908201527514db585c9d08151c99585cdd5c9e481b9bdd081cd95d60521b604082015260600190565b6020808252601590820152744475706c69636174652062656e656669636961727960581b604082015260600190565b6020808252600e908201526d416c72656164792065786973747360901b604082015260600190565b6020808252601190820152704d696e2062656e6566696369617269657360781b604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252600c908201526b155b985d5d1a1bdc9a5cd95960a21b604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601b908201527f526174696f20646f6573206e6f7420657175616c203130303030300000000000604082015260600190565b6020808252600c908201526b4f7574206f662072616e676560a01b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601d908201527f496e76616c69642062656e656669636961727920746f2072656d6f7665000000604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252601190820152704d61782062656e6566696369617269657360781b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6fffffffffffffffffffffffffffffffff91909116815260200190565b838152604060208201819052810182905260006001600160fb1b038311156131a8578081fd5b6020830280856060850137919091016060019081529392505050565b600086825285602083015260a060408301526131e360a0830186612a24565b6001600160a01b0394909416606083015250608001529392505050565b6040518181016001600160401b038111828210171561321e57600080fd5b604052919050565b60006001600160401b0382111561323b578081fd5b5060209081020190565b60005b83811015613260578181015183820152602001613248565b838111156115c45750506000910152565b6001600160a01b038116811461063457600080fd5b801515811461063457600080fdfea26469706673582212205b898a15cb0a34155ddffe2fdf6e10a8ec694f7105b1f2a452c3125868cb88d664736f6c63430006080033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000069a62c24f16d4914a48919613e8ee330641bcb94000000000000000000000000b3c8e5534f0063545cbbb7ce86854bf42db8872b000000000000000000000000e8ea8bae250028a8709a3841e0ae1a44820d677b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000070000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000085d4780b73119b644ae5ecd22b37600000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f510000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888
-----Decoded View---------------
Arg [0] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _feeTreasuryAddress (address): 0x69a62C24F16d4914a48919613e8eE330641Bcb94
Arg [2] : _idleRebalancer (address): 0xB3C8e5534F0063545CBbb7Ce86854Bf42dB8872B
Arg [3] : _multisig (address): 0xe8eA8bAE250028a8709A3841E0Ae1a44820d677b
Arg [4] : _initialDepositTokens (address[]): 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599,0x0000000000085d4780B73119b644AE5ecd22b376,0x57Ab1ec28D129707052df4dF418D58a2D46d5f51,0x6B175474E89094C44Da98b954EedeAC495271d0F,0xdAC17F958D2ee523a2206206994597C13D831ec7,0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48,0xc00e94Cb662C3520282E6f5717214004A7f26888
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 00000000000000000000000069a62c24f16d4914a48919613e8ee330641bcb94
Arg [2] : 000000000000000000000000b3c8e5534f0063545cbbb7ce86854bf42db8872b
Arg [3] : 000000000000000000000000e8ea8bae250028a8709a3841e0ae1a44820d677b
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [6] : 0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599
Arg [7] : 0000000000000000000000000000000000085d4780b73119b644ae5ecd22b376
Arg [8] : 00000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f51
Arg [9] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [10] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [11] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [12] : 000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888
Deployed Bytecode Sourcemap
50982:19870:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;50982:19870:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;51890:67:0;;;:::i;:::-;;;;;;;;;;;;;;;;69800:120;;;;;;;;;:::i;:::-;;;;;;;;70254:133;;;;;;;;;:::i;69698:96::-;;;:::i;:::-;;;;;;;;51664:45;;;:::i;:::-;;;;;;;;22050:114;;;;;;;;;:::i;22426:227::-;;;;;;;;;:::i;:::-;;23635:209;;;;;;;;;:::i;70151:97::-;;;:::i;:::-;;;;;;;;64598:144;;;;;;;;;:::i;60020:558::-;;;;;;;;;:::i;63370:686::-;;;;;;;;;:::i;70391:103::-;;;:::i;58199:180::-;;;;;;;;;:::i;55143:258::-;;;;;;;;;:::i;65892:230::-;;;;;;;;;:::i;51814:47::-;;;:::i;51714:45::-;;;:::i;21723:138::-;;;;;;;;;:::i;70051:96::-;;;:::i;:::-;;;;;;;;20684:139;;;;;;;;;:::i;64271:131::-;;;;;;;;;:::i;19429:49::-;;;:::i;69924:121::-;;;;;;;;;:::i;65121:578::-;;;;;;;;;:::i;61434:619::-;;;;;;;;;:::i;69497:195::-;;;;;;;;;:::i;20997:127::-;;;;;;;;;:::i;22898:230::-;;;;;;;;;:::i;66384:160::-;;;;;;;;;:::i;51764:43::-;;;:::i;67752:1471::-;;;;;;;;;:::i;62448:564::-;;;;;;;;;:::i;70500:349::-;;;:::i;51890:67::-;51928:29;;;;;;;;;;;;;;51890:67;:::o;69800:120::-;69871:4;69886:30;51928:29;;;;;;;;;;;;;;69907:8;69886:7;:30::i;:::-;69878:39;69800:120;-1:-1:-1;;69800:120:0:o;70254:133::-;70331:4;70346:37;:13;70369;70346:37;:22;:37;:::i;69698:96::-;69751:16;69779:11;69771:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69698:96;;:::o;51664:45::-;51708:1;51664:45;:::o;22050:114::-;22107:7;22134:12;;;;;;;;;;:22;;;;22050:114::o;22426:227::-;22518:6;:12;;;;;;;;;;:22;;;22510:45;;22542:12;:10;:12::i;22510:45::-;22502:105;;;;-1:-1:-1;;;22502:105:0;;;;;;;;;;;;;;;;;22620:25;22631:4;22637:7;22620:10;:25::i;:::-;22426:227;;:::o;23635:209::-;23733:12;:10;:12::i;:::-;-1:-1:-1;;;;;23722:23:0;:7;-1:-1:-1;;;;;23722:23:0;;23714:83;;;;-1:-1:-1;;;23714:83:0;;;;;;;;;23810:26;23822:4;23828:7;23810:11;:26::i;70151:97::-;70209:7;70228:13;70242:1;70228:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70228:16:0;;-1:-1:-1;70151:97:0;:::o;64598:144::-;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;64695:41:::1;51928:29;;;;;;;;;;;;;;64719:16;64695:10;:41::i;:::-;64598:144:::0;:::o;60020:558::-;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52114:39:::1;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1::0;;;52106:64:0::1;;;;;;;;;60171:13:::2;:20:::0;51708:1:::2;-1:-1:-1::0;60163:70:0::2;;;;-1:-1:-1::0;;;60163:70:0::2;;;;;;;;;-1:-1:-1::0;;;;;60248:27:0;::::2;60240:71;;;;-1:-1:-1::0;;;60240:71:0::2;;;;;;;;;60325:9;60320:137;60344:13;:20:::0;60340:24;::::2;60320:137;;;60408:15;-1:-1:-1::0;;;;;60388:35:0::2;:13;60402:1;60388:16;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;60388:16:0::2;:35;;60380:69;;;;-1:-1:-1::0;;;60380:69:0::2;;;;;;;;;60366:3;;60320:137;;;;60465:19;:17;:19::i;:::-;60493:13;27:10:-1::0;;39:1:::2;23:18:::0;::::2;45:23:::0;;-1:-1;60493:35:0;;;;;::::2;::::0;;-1:-1:-1;;;;;;60493:35:0::2;-1:-1:-1::0;;;;;60493:35:0;::::2;;::::0;;60537::::2;::::0;;60493::::2;60537::::0;;::::2;::::0;;;;;;;;;;;::::2;::::0;60557:14;;60537:35;;;;;::::2;::::0;60557:14;;60537:35;60557:14;60537:35;1:33:-1::2;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;60537:19:0::2;::::0;-1:-1:-1;;;60537:35:0:i:2;:::-;60020:558:::0;;;:::o;63370:686::-;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;-1:-1:-1;;;;;63477:33:0;::::1;63469:80;;;;-1:-1:-1::0;;;63469:80:0::1;;;;;;;;;63759:1;-1:-1:-1::0;;;;;63731:30:0::1;:13;63745:1;63731:16;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;63731:16:0::1;:30;63727:144;;63772:45;63797:13;63811:1;63797:16;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;63779:4:0::1;63772:24:::0;::::1;::::0;63797:16;::::1;::::0;63772:24:::1;:45::i;:::-;63927:76;-1:-1:-1::0;;;;;63934:4:0::1;63927:34;63962:21:::0;-1:-1:-1;;63927:76:0::1;:34;:76;:::i;:::-;64029:21;64010:13;64024:1;64010:16;;;;;;;;;;;;;;;;:40;;;;;-1:-1:-1::0;;;;;64010:40:0::1;;;;;-1:-1:-1::0;;;;;64010:40:0::1;;;;;;63370:686:::0;:::o;70391:103::-;70451:7;70469:22;:13;:20;:22::i;:::-;70461:31;;70391:103;:::o;58199:180::-;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52114:39:::1;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1::0;;;52106:64:0::1;;;;;;;;;58312:19:::2;:17;:19::i;:::-;58340:33;58360:12;;58340:33;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;58340:19:0::2;::::0;-1:-1:-1;;;58340:33:0:i:2;55143:258::-:0;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52230:32:::1;51928:29;;;;;;;;;;;;;;52251:10;52230:7;:32::i;:::-;52222:57;;;;-1:-1:-1::0;;;52222:57:0::1;;;;;;;;;55331:64:::2;55340:21;55363:12;55377:17;55331:8;:64::i;65892:230::-:0;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;65986:62:::1;-1:-1:-1::0;;;;;65986:33:0;::::1;51231:42;66046:1;65986:62;:33;:62;:::i;:::-;66081:35;:13;66102::::0;66081:35:::1;:20;:35;:::i;51814:47::-:0;51859:2;51814:47;:::o;51714:45::-;51758:1;51714:45;:::o;21723:138::-;21796:7;21823:12;;;;;;;;;;:30;;21847:5;21823:30;:23;:30;:::i;:::-;21816:37;21723:138;-1:-1:-1;;;21723:138:0:o;70051:96::-;70102:16;70130:13;70122:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70122:22:0;;;;;;;;;;;;;;;;;;;;;;70051:96;:::o;20684:139::-;20753:4;20777:12;;;;;;;;;;:38;;20807:7;20777:38;:29;:38;:::i;64271:131::-;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;64359:37:::1;51928:29;;;;;;;;;;;;;;64382:13;64359:9;:37::i;19429:49::-:0;19474:4;19429:49;:::o;69924:121::-;69989:4;70004:37;69989:4;70032:8;70004:7;:37::i;65121:578::-;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;51859:2:::1;65223:22;:13;:20;:22::i;:::-;:43;65215:71;;;;-1:-1:-1::0;;;65215:71:0::1;;;;;;;;;-1:-1:-1::0;;;;;65301:27:0;::::1;65293:65;;;;-1:-1:-1::0;;;65293:65:0::1;;;;;;;;;65390:4;-1:-1:-1::0;;;;;65373:21:0::1;:13;-1:-1:-1::0;;;;;65373:21:0::1;;;65365:52;;;;-1:-1:-1::0;;;65365:52:0::1;;;;;;;;;65476:37;:13;65499::::0;65476:37:::1;:22;:37;:::i;:::-;:46;65468:73;;;;-1:-1:-1::0;;;65468:73:0::1;;;;;;;;;65550:88;-1:-1:-1::0;;;;;65550:43:0;::::1;51231:42;-1:-1:-1::0;;65550:88:0::1;:43;:88;:::i;:::-;65661:32;:13;65679::::0;65661:32:::1;:17;:32;:::i;61434:619::-:0;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52114:39:::1;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1::0;;;52106:64:0::1;;;;;;;;;61584:1:::2;61574:6;:11;;61566:53;;;;-1:-1:-1::0;;;61566:53:0::2;;;;;;;;;61643:13;:20:::0;61634:29;::::2;61626:54;;;;-1:-1:-1::0;;;61626:54:0::2;;;;;;;;;61695:13;:20:::0;51758:1:::2;-1:-1:-1::0;61687:70:0::2;;;;-1:-1:-1::0;;;61687:70:0::2;;;;;;;;;61770:19;:17;:19::i;:::-;61898:13;61912:20:::0;;-1:-1:-1;;61912:22:0;;;61898:37;::::2;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;61874:13:::2;:21:::0;;-1:-1:-1;;;;;61898:37:0;;::::2;::::0;61888:6;;61874:21;::::2;;;;;;;;;;;;;:61;;;;;-1:-1:-1::0;;;;;61874:61:0::2;;;;;-1:-1:-1::0;;;;;61874:61:0::2;;;;;;61942:13;:19;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;61942:19:0::2;;;;;;;62012:35;62032:14;;62012:35;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;62012:19:0::2;::::0;-1:-1:-1;;;62012:35:0:i:2;69497:195::-:0;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;69573:40:::1;19474:4;69603:9:::0;69573::::1;:40::i;:::-;69620:42;19474:4;69651:10;69620;:42::i;20997:127::-:0;21060:7;21087:12;;;;;;;;;;:29;;:27;:29::i;22898:230::-;22991:6;:12;;;;;;;;;;:22;;;22983:45;;23015:12;:10;:12::i;22983:45::-;22975:106;;;;-1:-1:-1;;;22975:106:0;;;;;;;;66384:160;52114:39;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1;;;52106:64:0;;;;;;;;;66490:48:::1;-1:-1:-1::0;;;;;66490:27:0;::::1;66518:10:::0;66530:7;66490:48:::1;:27;:48;:::i;51764:43::-:0;51801:6;51764:43;:::o;67752:1471::-;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52114:39:::1;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1::0;;;52106:64:0::1;;;;;;;;;67900:26:::2;67952:13;67966:1;67952:16;;;;;;;;;::::0;;;::::2;::::0;;;;;::::2;::::0;68003:11:::2;::::0;;-1:-1:-1;;;68003:11:0;;;;-1:-1:-1;;;;;67952:16:0;;::::2;::::0;-1:-1:-1;67952:16:0;;68003:9:::2;::::0;:11:::2;::::0;;::::2;::::0;;;;;;67952:16;68003:11;::::2;;2:2:-1::0;::::2;;;27:1;24::::0;17:12:::2;2:2;68003:11:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68003:11:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68003:11:0;;;;;;;;;67976:38;;68023:23;68049:18;-1:-1:-1::0;;;;;68049:31:0::2;;:33;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68049:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68049:33:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68049:33:0;;;;;;;;;68023:59:::0;-1:-1:-1;68097:37:0;;::::2;68089:64;;;;-1:-1:-1::0;;;68089:64:0::2;;;;;;;;;68164:27;68194:18;-1:-1:-1::0;;;;;68194:35:0::2;;:37;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68194:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68194:37:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;68194:37:0;80:15:-1::0;;::::2;-1:-1:::0;;76:31:::2;65:43:::0;::::2;120:4;113:20:::0;68194:37:0::2;::::0;;;::::2;::::0;::::2;;;68164:67;;68238:42;68297:15;-1:-1:-1::0;;;;;68283:30:0::2;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68283:30:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;::::0;-1:-1;68283:30:0::2;-1:-1:-1::0;68238:75:0;-1:-1:-1;68327:9:0::2;68322:200;68342:10;:17;68340:1;:19;68322:200;;;68475:10;68486:1;68475:13;;;;;;;;;;;;;;-1:-1:-1::0;;;;;68468:31:0::2;;68508:4;68468:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68468:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68468:46:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68468:46:0;;;;;;;;;68437:25;68463:1;68437:28;;;;;;;;;::::0;;::::2;::::0;;;;;:77;68361:3:::2;;68322:200;;;-1:-1:-1::0;68573:34:0::2;::::0;-1:-1:-1;;;68573:34:0;;-1:-1:-1;;;;;68573:12:0;::::2;::::0;::::2;::::0;:34:::2;::::0;68586:7;;68595:11;;;;68573:34:::2;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68573:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68573:34:0;;;;68616:21;68644:30:::0;68686:9:::2;68696:1:::0;68686:11:::2;;68681:537;68701:10;:17;68699:1;:19;68681:537;;;68758:10;68769:1;68758:13;;;;;;;;;;;;;;68734:38;;68808:152;68894:25;68920:1;68894:28;;;;;;;;;;;;;;68808:14;-1:-1:-1::0;;;;;68808:24:0::2;;68841:4;68808:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;68808:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;68808:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68808:39:0;;;;;;;;;:43:::0;:152:::2;:43;:152;:::i;:::-;68783:177:::0;-1:-1:-1;68975:26:0;;68971:240:::2;;69077:96;-1:-1:-1::0;;;;;69077:27:0;::::2;69117:10:::0;69140:22;69077:96:::2;:27;:96;:::i;:::-;68720:3;;68681:537;;;;52177:1;;;;;;;67752:1471:::0;;;;:::o;62448:564::-;52031:1;-1:-1:-1;;;;;52005:28:0;:13;52019:1;52005:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52005:16:0;:28;;51997:63;;;;-1:-1:-1;;;51997:63:0;;;;;;;;;52114:39:::1;19474:4;52142:10;52114:7;:39::i;:::-;52106:64;;;;-1:-1:-1::0;;;52106:64:0::1;;;;;;;;;62624:1:::2;62614:6;:11;;62606:53;;;;-1:-1:-1::0;;;62606:53:0::2;;;;;;;;;-1:-1:-1::0;;;;;62674:27:0;::::2;62666:71;;;;-1:-1:-1::0;;;62666:71:0::2;;;;;;;;;62751:9;62746:137;62770:13;:20:::0;62766:24;::::2;62746:137;;;62834:15;-1:-1:-1::0;;;;;62814:35:0::2;:13;62828:1;62814:16;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;62814:16:0::2;:35;;62806:69;;;;-1:-1:-1::0;;;62806:69:0::2;;;;;;;;;62792:3;;62746:137;;;;62891:19;:17;:19::i;:::-;62947:15;62923:13;62937:6;62923:21;;;;;;;;;;;;;;;;:39;;;;;-1:-1:-1::0;;;;;62923:39:0::2;;;;;-1:-1:-1::0;;;;;62923:39:0::2;;;;;;62971:35;62991:14;;62971:35;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;62971:19:0::2;::::0;-1:-1:-1;;;62971:35:0:i:2;:::-;62448:564:::0;;;;:::o;70500:349::-;70551:16;70576:17;70596:22;:13;:20;:22::i;:::-;70576:42;;70627:33;70677:9;-1:-1:-1;;;;;70663:24:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;70663:24:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;70663:24:0;-1:-1:-1;70627:60:0;-1:-1:-1;70699:13:0;70694:118;70726:9;70718:5;:17;70694:118;;;70781:23;:13;70798:5;70781:23;:16;:23;:::i;:::-;70755:16;70772:5;70755:23;;;;;;;;-1:-1:-1;;;;;70755:49:0;;;:23;;;;;;;;;;;:49;70737:7;;70694:118;;;-1:-1:-1;70826:16:0;-1:-1:-1;;70500:349:0;:::o;7243:158::-;7323:4;7347:46;7357:3;-1:-1:-1;;;;;7377:14:0;;7347:9;:46::i;35420:286::-;35517:20;35540:50;35584:5;35540;-1:-1:-1;;;;;35540:15:0;;35564:4;35571:7;35540:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;35540:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35540:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;35540:39:0;;;;;;;;;:43;:50;:43;:50;:::i;:::-;35517:73;;35601:97;35621:5;35651:22;;;35675:7;35684:12;35628:69;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;35628:69:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;35628:69:0;;;179:29:-1;;;;160:49;;;35601:19:0;:97::i;6689:143::-;6759:4;6783:41;6788:3;-1:-1:-1;;;;;6808:14:0;;6783:4;:41::i;29009:181::-;29067:7;29099:5;;;29123:6;;;;29115:46;;;;-1:-1:-1;;;29115:46:0;;;;;;;;13399:195;13502:12;13534:52;13556:6;13564:4;13570:1;13573:12;13534:21;:52::i;:::-;13527:59;13399:195;-1:-1:-1;;;;13399:195:0:o;17366:106::-;17454:10;17366:106;:::o;24878:188::-;24952:6;:12;;;;;;;;;;:33;;24977:7;24952:33;:24;:33;:::i;:::-;24948:111;;;25034:12;:10;:12::i;:::-;-1:-1:-1;;;;;25007:40:0;25025:7;-1:-1:-1;;;;;25007:40:0;25019:4;25007:40;;;;;;;;;;24878:188;;:::o;25074:192::-;25149:6;:12;;;;;;;;;;:36;;25177:7;25149:36;:27;:36;:::i;:::-;25145:114;;;25234:12;:10;:12::i;:::-;-1:-1:-1;;;;;25207:40:0;25225:7;-1:-1:-1;;;;;25207:40:0;25219:4;25207:40;;;;;;;;;;25074:192;;:::o;59153:397::-;59198:17;59218:22;:13;:20;:22::i;:::-;59198:42;;59247:34;59295:9;-1:-1:-1;;;;;59284:21:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59284:21:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;59284:21:0;;59247:58;;59312:28;59357:9;-1:-1:-1;;;;;59343:24:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59343:24:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;59343:24:0;-1:-1:-1;59312:55:0;-1:-1:-1;59381:9:0;59376:114;59400:9;59396:1;:13;59376:114;;;59451:4;59425:20;59446:1;59425:23;;;;;;;;;;;;;:30;;;;;;;;;;;59481:1;59464:11;59476:1;59464:14;;;;;;;;;;;;;;;;;:18;59411:3;;59376:114;;;;59498:46;59507:20;59529:11;59542:1;59498:8;:46::i;58673:378::-;58780:13;:20;58757:19;;:43;58749:70;;;;-1:-1:-1;;;58749:70:0;;;;;;;;;58832:11;;58852:93;58872:12;:19;58870:1;:21;58852:93;;;58913:24;58921:12;58934:1;58921:15;;;;;;;;;;;;;;58913:3;:7;;:24;;;;:::i;:::-;58907:30;-1:-1:-1;58893:3:0;;58852:93;;;;51801:6;58961:3;:17;58953:57;;;;-1:-1:-1;;;58953:57:0;;;;;;;;;59019:26;;;;:11;;:26;;;;;:::i;34790:622::-;35160:10;;;35159:62;;-1:-1:-1;35176:39:0;;-1:-1:-1;;;35176:39:0;;-1:-1:-1;;;;;35176:15:0;;;;;:39;;35200:4;;35207:7;;35176:39;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;35176:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35176:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;35176:39:0;;;;;;;;;:44;35159:62;35151:152;;;;-1:-1:-1;;;35151:152:0;;;;;;;;;35314:90;35334:5;35364:22;;;35388:7;35397:5;35341:62;;;;;;;;;;7487:117;7550:7;7577:19;7585:3;7577:7;:19::i;55473:2299::-;55622:15;55640:22;:13;:20;:22::i;:::-;55622:40;;55709:7;55677:21;:28;:39;55669:66;;;;-1:-1:-1;;;55669:66:0;;;;;;;;;55773:7;55750:12;:19;:30;55742:57;;;;-1:-1:-1;;;55742:57:0;;;;;;;;;55921:16;;;55935:1;55921:16;;;55897:21;55921:16;;;;;55808:23;;;;;;55921:16;;;;;;;109:14:-1;55921:16:0;88:42:-1;144:17;;-1:-1;55921:16:0;55897:40;;55954:4;55944;55949:1;55944:7;;;;;;;;-1:-1:-1;;;;;55944:14:0;;;:7;;;;;;;;;;;:14;56060:13;56055:701;56087:7;56079:5;:15;56055:701;;;56118:21;56140:5;56118:28;;;;;;;;;;;;;;;;;;56114:54;;56158:8;;56114:54;56203:23;:13;56220:5;56203:23;:16;:23;:::i;:::-;56256:40;;-1:-1:-1;;;56256:40:0;;56178:49;;-1:-1:-1;;;;;;56256:25:0;;;;;:40;;56290:4;;56256:40;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56256:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56256:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56256:40:0;;;;;;;;;56238:58;-1:-1:-1;56352:19:0;;56348:401;;56457:15;56439:4;56444:1;56439:7;;;;;;;;;;;;;:34;-1:-1:-1;;;;;56439:34:0;;;-1:-1:-1;;;;;56439:34:0;;;;;51231:42;-1:-1:-1;;;;;56517:69:0;;56599:15;56627:12;56640:5;56627:19;;;;;;;;;;;;;;56660:4;56685;56703:25;56723:4;56703:15;:19;;:25;;;;:::i;:::-;56517:222;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56517:222:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56517:222:0;;;;56348:401;56096:7;;56055:701;;;-1:-1:-1;56928:37:0;;-1:-1:-1;;;56928:37:0;;-1:-1:-1;;;;;56935:4:0;56928:22;;;;:37;;56959:4;;56928:37;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56928:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56928:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56928:37:0;;;;;;;;;56914:51;-1:-1:-1;56976:15:0;;56972:795;;57055:28;57086:49;57110:11;57086:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57123:11;57086:23;:49::i;:::-;57055:80;;57144:24;57171:11;57183:1;57171:14;;;;;;;;;;;;;;57144:41;;57236:1;57200:33;57216:16;57200:11;:15;;:33;;;;:::i;:::-;:37;57196:322;;;57364:1;57341:166;57377:11;:18;57367:28;;57341:166;;;57422:71;57448:13;57462:7;57448:22;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57448:22:0;57472:11;57484:7;57472:20;;;;;;;;;;;;;;57429:4;-1:-1:-1;;;;;57422:25:0;;;:71;;;;;:::i;:::-;57397:9;;57341:166;;;;57196:322;57532:20;;57528:232;;57565:26;57617:13;57631:1;57617:16;;;;;;;;;;;;;;;;;;57681:69;;-1:-1:-1;;;57681:69:0;;-1:-1:-1;;;;;57617:16:0;;;;-1:-1:-1;57617:16:0;;57681:26;;:69;;57708:4;;57714:16;;57732:17;;57681:69;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57681:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57681:69:0;;;;57528:232;;56972:795;;;55473:2299;;;;;;;;:::o;7008:149::-;7081:4;7105:44;7113:3;-1:-1:-1;;;;;7133:14:0;;7105:7;:44::i;7948:149::-;8022:7;8065:22;8069:3;8081:5;8065:3;:22::i;34131:177::-;34214:86;34234:5;34264:23;;;34289:2;34293:5;34241:58;;;;;;;;;;29473:136;29531:7;29558:43;29562:1;29565;29558:43;;;;;;;;;;;;;;;;;:3;:43::i;3973:129::-;4046:4;4070:19;;;:12;;;;;:19;;;;;;:24;;;3973:129::o;36436:761::-;36860:23;36886:69;36914:4;36886:69;;;;;;;;;;;;;;;;;36894:5;-1:-1:-1;;;;;36886:27:0;;;:69;;;;;:::i;:::-;36970:17;;36860:95;;-1:-1:-1;36970:21:0;36966:224;;37112:10;37101:30;;;;;;;;;;;;;;37093:85;;;;-1:-1:-1;;;37093:85:0;;;;;;;;1753:414;1816:4;1838:21;1848:3;1853:5;1838:9;:21::i;:::-;1833:327;;-1:-1:-1;27:10;;39:1;23:18;;;45:23;;1876:11:0;:23;;;;;;;;;;;;;2059:18;;2037:19;;;:12;;;:19;;;;;;:40;;;;2092:11;;1833:327;-1:-1:-1;2143:5:0;2136:12;;14451:530;14578:12;14636:5;14611:21;:30;;14603:81;;;;-1:-1:-1;;;14603:81:0;;;;;;;;;14703:18;14714:6;14703:10;:18::i;:::-;14695:60;;;;-1:-1:-1;;;14695:60:0;;;;;;;;;14829:12;14843:23;14870:6;-1:-1:-1;;;;;14870:11:0;14890:5;14898:4;14870:33;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;14828:75:0;;;;14921:52;14939:7;14948:10;14960:12;14921:17;:52::i;:::-;14914:59;14451:530;-1:-1:-1;;;;;;;14451:530:0:o;4188:109::-;4271:18;;4188:109::o;66859:628::-;66961:27;67024:12;:19;-1:-1:-1;;;;;67010:34:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67010:34:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;67010:34:0;-1:-1:-1;66997:47:0;-1:-1:-1;67051:19:0;;;67110:348;67134:12;:19;67130:1;:23;67110:348;;;67200:1;67178:12;:19;:23;67173:1;:28;67169:282;;;67230:27;:5;67240:16;67230:27;:9;:27;:::i;:::-;67214:10;67225:1;67214:13;;;;;;;;;;;;;:43;;;;;67169:282;;;67298:42;51801:6;67298:26;67308:12;67321:1;67308:15;;;;;;;;;;;;;;67298:5;:9;;:26;;;;:::i;:::-;:30;:42;:30;:42;:::i;:::-;67284:56;-1:-1:-1;67370:33:0;:16;67284:56;67370:33;:20;:33;:::i;:::-;67351:52;;67430:11;67414:10;67425:1;67414:13;;;;;;;;;;;;;:27;;;;;67169:282;67155:3;;67110:348;;;-1:-1:-1;;;66859:628:0;;;;:::o;2343:1544::-;2409:4;2548:19;;;:12;;;:19;;;;;;2584:15;;2580:1300;;3019:18;;-1:-1:-1;;2970:14:0;;;;3019:22;;;;2946:21;;3019:3;;:22;;3306;;;;;;;;;;;;;;3286:42;;3452:9;3423:3;:11;;3435:13;3423:26;;;;;;;;;;;;;;;;;;;:38;;;;3529:23;;;3571:1;3529:12;;;:23;;;;;;3555:17;;;3529:43;;3681:17;;3529:3;;3681:17;;;;;;;;;;;;;;;;;;;;;;3776:3;:12;;:19;3789:5;3776:19;;;;;;;;;;;3769:26;;;3819:4;3812:11;;;;;;;;2580:1300;3863:5;3856:12;;;;;4641:204;4736:18;;4708:7;;4736:26;-1:-1:-1;4728:73:0;;;;-1:-1:-1;;;4728:73:0;;;;;;;;;4819:3;:11;;4831:5;4819:18;;;;;;;;;;;;;;;;4812:25;;4641:204;;;;:::o;29912:192::-;29998:7;30034:12;30026:6;;;;30018:29;;;;-1:-1:-1;;;30018:29:0;;;;;;;;;;-1:-1:-1;;;30070:5:0;;;29912:192::o;10481:422::-;10848:20;10887:8;;;10481:422::o;15987:742::-;16102:12;16131:7;16127:595;;;-1:-1:-1;16162:10:0;16155:17;;16127:595;16276:17;;:21;16272:439;;16539:10;16533:17;16600:15;16587:10;16583:2;16579:19;16572:44;16487:148;16682:12;16675:20;;-1:-1:-1;;;16675:20:0;;;;;;;;;30363:471;30421:7;30666:6;30662:47;;-1:-1:-1;30696:1:0;30689:8;;30662:47;30733:5;;;30737:1;30733;:5;:1;30757:5;;;;;:10;30749:56;;;;-1:-1:-1;;;30749:56:0;;;;;;;;31310:132;31368:7;31395:39;31399:1;31402;31395:39;;;;;;;;;;;;;;;;;32024:7;32059:12;32052:5;32044:28;;;;-1:-1:-1;;;32044:28:0;;;;;;;;;;;32083:9;32099:1;32095;:5;;;;;;;31938:278;-1:-1:-1;;;;;31938:278:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;1770:352;;;1900:3;1893:4;1885:6;1881:17;1877:27;1867:2;;-1:-1;;1908:12;1867:2;-1:-1;1938:20;;-1:-1;;;;;1967:30;;1964:2;;;-1:-1;;2000:12;1964:2;2044:4;2036:6;2032:17;2020:29;;2095:3;2044:4;;2079:6;2075:17;2036:6;2061:32;;2058:41;2055:2;;;2112:1;;2102:12;2055:2;1860:262;;;;;;2148:707;;2265:3;2258:4;2250:6;2246:17;2242:27;2232:2;;-1:-1;;2273:12;2232:2;2320:6;2307:20;2342:80;2357:64;2414:6;2357:64;;;2342:80;;;2450:21;;;2333:89;-1:-1;2494:4;2507:14;;;;2482:17;;;2596;;;2587:27;;;;2584:36;-1:-1;2581:2;;;2633:1;;2623:12;2581:2;2658:1;2643:206;2668:6;2665:1;2662:13;2643:206;;;3502:20;;2736:50;;2800:14;;;;2828;;;;2690:1;2683:9;2643:206;;;2647:14;;;;;2225:630;;;;;2863:124;2927:20;;2952:30;2927:20;2952:30;;3713:241;;3817:2;3805:9;3796:7;3792:23;3788:32;3785:2;;;-1:-1;;3823:12;3785:2;85:6;72:20;97:33;124:5;97:33;;3961:491;;;;4099:2;4087:9;4078:7;4074:23;4070:32;4067:2;;;-1:-1;;4105:12;4067:2;85:6;72:20;97:33;124:5;97:33;;;4157:63;-1:-1;4257:2;4296:22;;72:20;97:33;72:20;97:33;;;4061:391;;4265:63;;-1:-1;;;4365:2;4404:22;;;;3502:20;;4061:391;4459:522;;;;4615:2;4603:9;4594:7;4590:23;4586:32;4583:2;;;-1:-1;;4621:12;4583:2;85:6;72:20;97:33;124:5;97:33;;;4673:63;-1:-1;4801:2;4786:18;;4773:32;-1:-1;;;;;4814:30;;4811:2;;;-1:-1;;4847:12;4811:2;4885:80;4957:7;4948:6;4937:9;4933:22;4885:80;;;4577:404;;4875:90;;-1:-1;4875:90;;-1:-1;;;;4577:404;4988:647;;;;;5161:2;5149:9;5140:7;5136:23;5132:32;5129:2;;;-1:-1;;5167:12;5129:2;85:6;72:20;97:33;124:5;97:33;;;5219:63;-1:-1;5319:2;5358:22;;3502:20;;-1:-1;5455:2;5440:18;;5427:32;-1:-1;;;;;5468:30;;5465:2;;;-1:-1;;5501:12;5465:2;5539:80;5611:7;5602:6;5591:9;5587:22;5539:80;;;5123:512;;;;-1:-1;5529:90;-1:-1;;;;5123:512;5642:392;;5782:2;;5770:9;5761:7;5757:23;5753:32;5750:2;;;-1:-1;;5788:12;5750:2;5839:17;5833:24;-1:-1;;;;;5869:6;5866:30;5863:2;;;-1:-1;;5899:12;5863:2;6001:6;5990:9;5986:22;429:3;422:4;414:6;410:17;406:27;396:2;;-1:-1;;437:12;396:2;477:6;471:13;457:27;;499:80;514:64;571:6;514:64;;499:80;607:21;;;664:14;;;;639:17;;;753;;;744:27;;;;741:36;-1:-1;738:2;;;-1:-1;;780:12;738:2;-1:-1;806:10;;800:217;825:6;822:1;819:13;800:217;;;226:6;220:13;238:33;265:5;238:33;;;893:61;;847:1;840:9;;;;;968:14;;;;996;;800:217;;;-1:-1;5919:99;5744:290;-1:-1;;;;;;;5744:290;6041:757;;;;6226:2;6214:9;6205:7;6201:23;6197:32;6194:2;;;-1:-1;;6232:12;6194:2;6290:17;6277:31;-1:-1;;;;;6328:18;6320:6;6317:30;6314:2;;;-1:-1;;6350:12;6314:2;6438:6;6427:9;6423:22;1160:3;1153:4;1145:6;1141:17;1137:27;1127:2;;-1:-1;;1168:12;1127:2;1215:6;1202:20;1188:34;;1237:77;1252:61;1306:6;1252:61;;1237:77;1320:16;1356:6;1349:5;1342:21;1386:4;;1403:3;1399:14;1392:21;;1386:4;1378:6;1374:17;1508:3;1386:4;;1492:6;1488:17;1378:6;1479:27;;1476:36;1473:2;;;-1:-1;;1515:12;1473:2;-1:-1;1541:10;;1535:203;1560:6;1557:1;1554:13;1535:203;;;1640:34;1670:3;1658:10;1640:34;;;1628:47;;1582:1;1575:9;;;;;1689:14;;;;1717;;1535:203;;;-1:-1;6370:85;;-1:-1;6505:18;;6492:32;;-1:-1;;;6533:30;;;6530:2;;;-1:-1;;6566:12;6530:2;;6596:78;6666:7;6657:6;6646:9;6642:22;6596:78;;;6586:88;;;6711:2;6754:9;6750:22;3502:20;6719:63;;6188:610;;;;;;6805:397;;;6944:2;6932:9;6923:7;6919:23;6915:32;6912:2;;;-1:-1;;6950:12;6912:2;7008:17;6995:31;-1:-1;;;;;7038:6;7035:30;7032:2;;;-1:-1;;7068:12;7032:2;7106:80;7178:7;7169:6;7158:9;7154:22;7106:80;;;7096:90;;;;-1:-1;6906:296;-1:-1;;;;6906:296;7209:257;;7321:2;7309:9;7300:7;7296:23;7292:32;7289:2;;;-1:-1;;7327:12;7289:2;3075:6;3069:13;3087:30;3111:5;3087:30;;7473:241;;7577:2;7565:9;7556:7;7552:23;7548:32;7545:2;;;-1:-1;;7583:12;7545:2;-1:-1;3196:20;;7539:175;-1:-1;7539:175;7721:366;;;7842:2;7830:9;7821:7;7817:23;7813:32;7810:2;;;-1:-1;;7848:12;7810:2;3209:6;3196:20;7900:63;;8000:2;8043:9;8039:22;72:20;97:33;124:5;97:33;;;8008:63;;;;7804:283;;;;;;8094:366;;;8215:2;8203:9;8194:7;8190:23;8186:32;8183:2;;;-1:-1;;8221:12;8183:2;-1:-1;;3196:20;;;8373:2;8412:22;;;3502:20;;-1:-1;8177:283;8467:291;;8596:2;8584:9;8575:7;8571:23;8567:32;8564:2;;;-1:-1;;8602:12;8564:2;3364:6;3358:13;3376:47;3417:5;3376:47;;8765:263;;8880:2;8868:9;8859:7;8855:23;8851:32;8848:2;;;-1:-1;;8886:12;8848:2;-1:-1;3650:13;;8842:186;-1:-1;8842:186;9035:647;;;;;9208:2;9196:9;9187:7;9183:23;9179:32;9176:2;;;-1:-1;;9214:12;9176:2;3515:6;3502:20;9266:63;;9366:2;9409:9;9405:22;72:20;97:33;124:5;97:33;;;9374:63;-1:-1;9502:2;9487:18;;9474:32;-1:-1;;;;;9515:30;;9512:2;;;-1:-1;;9548:12;9689:522;;;;9845:2;9833:9;9824:7;9820:23;9816:32;9813:2;;;-1:-1;;9851:12;9813:2;3515:6;3502:20;9903:63;;10031:2;10020:9;10016:18;10003:32;-1:-1;;;;;10047:6;10044:30;10041:2;;;-1:-1;;10077:12;10843:690;;11036:5;41482:12;42285:6;42280:3;42273:19;42322:4;;42317:3;42313:14;11048:93;;42322:4;11212:5;41178:14;-1:-1;11251:260;11276:6;11273:1;11270:13;11251:260;;;11337:13;;-1:-1;;;;;43570:54;10643:37;;10372:14;;;;42013;;;;1978:18;11291:9;11251:260;;;-1:-1;11517:10;;10967:566;-1:-1;;;;;10967:566;23540:271;;13167:5;41482:12;13278:52;13323:6;13318:3;13311:4;13304:5;13300:16;13278:52;;;13342:16;;;;;23674:137;-1:-1;;23674:137;23818:381;-1:-1;;;19887:39;;19871:2;19945:12;;24007:192;24206:222;-1:-1;;;;;43570:54;;;;10643:37;;24333:2;24318:18;;24304:124;24435:333;-1:-1;;;;;43570:54;;;10643:37;;43570:54;;24754:2;24739:18;;10643:37;24590:2;24575:18;;24561:207;24775:333;-1:-1;;;;;43570:54;;;;10643:37;;25094:2;25079:18;;12958:37;24930:2;24915:18;;24901:207;25115:444;-1:-1;;;;;43570:54;;;;10643:37;;25462:2;25447:18;;12958:37;;;;25545:2;25530:18;;12958:37;25298:2;25283:18;;25269:290;25566:370;;25743:2;25764:17;25757:47;25818:108;25743:2;25732:9;25728:18;25912:6;25818:108;;25943:370;26120:2;26134:47;;;41482:12;;26105:18;;;42273:19;;;25943:370;;26120:2;41178:14;;;;42313;;;;25943:370;12486:260;12511:6;12508:1;12505:13;12486:260;;;12572:13;;12958:37;;42013:14;;;;10554;;;;12533:1;12526:9;12486:260;;;-1:-1;26187:116;;26091:222;-1:-1;;;;;;26091:222;26320:210;43171:13;;43164:21;12841:34;;26441:2;26426:18;;26412:118;26537:222;12958:37;;;26664:2;26649:18;;26635:124;26766:310;;26913:2;26934:17;26927:47;13515:5;41482:12;42285:6;26913:2;26902:9;26898:18;42273:19;13609:52;13654:6;42313:14;26902:9;42313:14;26913:2;13635:5;13631:16;13609:52;;;44230:7;44214:14;-1:-1;;44210:28;13673:39;;;;42313:14;13673:39;;26884:192;-1:-1;;26884:192;27083:416;27283:2;27297:47;;;13949:2;27268:18;;;42273:19;13985:34;42313:14;;;13965:55;-1:-1;;;14040:12;;;14033:26;14078:12;;;27254:245;27506:416;27706:2;27720:47;;;14329:2;27691:18;;;42273:19;14365:27;42313:14;;;14345:48;14412:12;;;27677:245;27929:416;28129:2;28143:47;;;14663:2;28114:18;;;42273:19;-1:-1;;;42313:14;;;14679:37;14735:12;;;28100:245;28352:416;28552:2;28566:47;;;14986:2;28537:18;;;42273:19;15022:34;42313:14;;;15002:55;-1:-1;;;15077:12;;;15070:39;15128:12;;;28523:245;28775:416;28975:2;28989:47;;;15379:2;28960:18;;;42273:19;15415:33;42313:14;;;15395:54;15468:12;;;28946:245;29198:416;29398:2;29412:47;;;15719:2;29383:18;;;42273:19;-1:-1;;;42313:14;;;15735:38;15792:12;;;29369:245;29621:416;29821:2;29835:47;;;16043:2;29806:18;;;42273:19;16079:29;42313:14;;;16059:50;16128:12;;;29792:245;30044:416;30244:2;30258:47;;;16379:2;30229:18;;;42273:19;16415:33;42313:14;;;16395:54;16468:12;;;30215:245;30467:416;30667:2;30681:47;;;16719:2;30652:18;;;42273:19;-1:-1;;;42313:14;;;16735:41;16795:12;;;30638:245;30890:416;31090:2;31104:47;;;17046:2;31075:18;;;42273:19;17082:34;42313:14;;;17062:55;-1:-1;;;17137:12;;;17130:26;17175:12;;;31061:245;31313:416;31513:2;31527:47;;;17426:2;31498:18;;;42273:19;-1:-1;;;42313:14;;;17442:45;17506:12;;;31484:245;31736:416;31936:2;31950:47;;;17757:2;31921:18;;;42273:19;-1:-1;;;42313:14;;;17773:44;17836:12;;;31907:245;32159:416;32359:2;32373:47;;;18087:2;32344:18;;;42273:19;-1:-1;;;42313:14;;;18103:37;18159:12;;;32330:245;32582:416;32782:2;32796:47;;;18410:2;32767:18;;;42273:19;-1:-1;;;42313:14;;;18426:40;18485:12;;;32753:245;33005:416;33205:2;33219:47;;;18736:2;33190:18;;;42273:19;18772:34;42313:14;;;18752:55;-1:-1;;;18827:12;;;18820:30;18869:12;;;33176:245;33428:416;33628:2;33642:47;;;19120:2;33613:18;;;42273:19;-1:-1;;;42313:14;;;19136:35;19190:12;;;33599:245;33851:416;34051:2;34065:47;;;19441:2;34036:18;;;42273:19;19477:34;42313:14;;;19457:55;-1:-1;;;19532:12;;;19525:40;19584:12;;;34022:245;34274:416;34474:2;34488:47;;;20196:2;34459:18;;;42273:19;20232:34;42313:14;;;20212:55;-1:-1;;;20287:12;;;20280:25;20324:12;;;34445:245;34697:416;34897:2;34911:47;;;20575:2;34882:18;;;42273:19;20611:29;42313:14;;;20591:50;20660:12;;;34868:245;35120:416;35320:2;35334:47;;;20911:2;35305:18;;;42273:19;-1:-1;;;42313:14;;;20927:35;20981:12;;;35291:245;35543:416;35743:2;35757:47;;;21232:2;35728:18;;;42273:19;21268:31;42313:14;;;21248:52;21319:12;;;35714:245;35966:416;36166:2;36180:47;;;21570:2;36151:18;;;42273:19;21606:34;42313:14;;;21586:55;-1:-1;;;21661:12;;;21654:34;21707:12;;;36137:245;36389:416;36589:2;36603:47;;;21958:2;36574:18;;;42273:19;21994:31;42313:14;;;21974:52;22045:12;;;36560:245;36812:416;37012:2;37026:47;;;22296:2;36997:18;;;42273:19;22332:34;42313:14;;;22312:55;-1:-1;;;22387:12;;;22380:46;22445:12;;;36983:245;37235:416;37435:2;37449:47;;;22696:2;37420:18;;;42273:19;-1:-1;;;42313:14;;;22712:40;22771:12;;;37406:245;37658:416;37858:2;37872:47;;;23022:2;37843:18;;;42273:19;23058:34;42313:14;;;23038:55;-1:-1;;;23113:12;;;23106:39;23164:12;;;37829:245;38081:222;43461:34;43450:46;;;;23261:37;;38208:2;38193:18;;38179:124;38539:501;12958:37;;;38754:2;38872;38857:18;;38850:48;;;38739:18;;42273:19;;;38539:501;-1:-1;;;;;11820:78;;11817:2;;;-1:-1;;11901:12;11817:2;38872;11936:6;11932:17;43797:6;43792:3;42313:14;38743:9;42313:14;43774:30;43835:16;;;;42313:14;43835:16;43828:27;;;43835:16;38725:315;-1:-1;;;38725:315;39047:816;;12988:5;12965:3;12958:37;12988:5;39501:2;39490:9;39486:18;12958:37;39336:3;39538:2;39527:9;39523:18;39516:48;39578:108;39336:3;39325:9;39321:19;39672:6;39578:108;;;-1:-1;;;;;43570:54;;;;39765:2;39750:18;;10643:37;-1:-1;39848:3;39833:19;12958:37;39570:116;39307:556;-1:-1;;;39307:556;39870:256;39932:2;39926:9;39958:17;;;-1:-1;;;;;40018:34;;40054:22;;;40015:62;40012:2;;;40090:1;;40080:12;40012:2;39932;40099:22;39910:216;;-1:-1;39910:216;40133:304;;-1:-1;;;;;40284:6;40281:30;40278:2;;;-1:-1;;40314:12;40278:2;-1:-1;40359:4;40347:17;;;40412:15;;40215:222;43870:268;43935:1;43942:101;43956:6;43953:1;43950:13;43942:101;;;44023:11;;;44017:18;44004:11;;;43997:39;43978:2;43971:10;43942:101;;;44058:6;44055:1;44052:13;44049:2;;;-1:-1;;43935:1;44105:16;;44098:27;43919:219;44251:117;-1:-1;;;;;43570:54;;44310:35;;44300:2;;44359:1;;44349:12;44375:111;44456:5;43171:13;43164:21;44434:5;44431:32;44421:2;;44477:1;;44467:12
Swarm Source
ipfs://5b898a15cb0a34155ddffe2fdf6e10a8ec694f7105b1f2a452c3125868cb88d6
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.