- Contract name:
- Dao
- Optimization enabled
- true
- Compiler version
- v0.8.15+commit.e14f2714
- Optimization runs
- 200
- Verified at
- 2023-04-29T00:06:59.730382Z
Constructor Arguments
00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000a4269746765727444414f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044244414f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000854db5c41419a42967de4ec6a47c011b28b227eb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f636f6e74726163742d6170692e64616f747269702e78797a2f64616f2f424954474552542f00000000000000000000000000000000000000
Arg [0] (string) : BitgertDAO
Arg [1] (string) : BDAO
Arg [2] (uint8) : 50
Arg [3] (address[]) : [0x854db5c41419a42967de4ec6a47c011b28b227eb]
Arg [4] (uint256[]) : [100000000]
Arg [5] (string) : https://contract-api.daotrip.xyz/dao/BITGERT/
Contract source code
// created by cryptodo.app // _____ _ _____ // / ____| | | | __ \ // | | _ __ _ _ _ __ | |_ ___ | | | | ___ // | | | '__|| | | || '_ \ | __|/ _ \ | | | | / _ \ // | |____ | | | |_| || |_) || |_| (_) || |__| || (_) | // \_____||_| \__, || .__/ \__|\___/ |_____/ \___/ // __/ || | // |___/ |_| // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.7; 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; if (lastIndex != toDeleteIndex) { 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] = valueIndex; // Replace lastvalue's index to valueIndex } // 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) { 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(uint160(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(uint160(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(uint160(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(uint160(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)); } } 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); } library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return recover(hash, r, vs); } else { revert("ECDSA: invalid signature length"); } } /** * @dev Overload of {ECDSA-recover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require( uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value" ); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } interface IAdapter { function withdraw( address _recipient, address _pool, uint256 _share // multiplied by 1e18, for example 20% = 2e17 ) external returns (bool); } interface ENSInterface { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); function setSubnodeOwner( bytes32 node, bytes32 label, address owner ) external; function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); } interface PointerInterface { function getAddress() external view returns (address); } interface OwnableInterface { function owner() external returns (address); function transferOwnership(address recipient) external; function acceptOwnership() external; } contract ConfirmedOwnerWithProposal is OwnableInterface { address private s_owner; address private s_pendingOwner; event OwnershipTransferRequested(address indexed from, address indexed to); event OwnershipTransferred(address indexed from, address indexed to); constructor(address newOwner, address pendingOwner) { require(newOwner != address(0), "Cannot set owner to zero"); s_owner = newOwner; if (pendingOwner != address(0)) { _transferOwnership(pendingOwner); } } /** * @notice Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address to) public override onlyOwner { _transferOwnership(to); } /** * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external override { require(msg.sender == s_pendingOwner, "Must be proposed owner"); address oldOwner = s_owner; s_owner = msg.sender; s_pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @notice Get the current owner */ function owner() public view override returns (address) { return s_owner; } /** * @notice validate, transfer ownership, and emit relevant events */ function _transferOwnership(address to) private { require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /** * @notice validate access */ function _validateOwnership() internal view { require(msg.sender == s_owner, "Only callable by owner"); } /** * @notice Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { _validateOwnership(); _; } } contract ConfirmedOwner is ConfirmedOwnerWithProposal { constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {} } library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } contract Dao is ReentrancyGuard, ERC20, ConfirmedOwner { using EnumerableSet for EnumerableSet.AddressSet; using SafeERC20 for IERC20; using Address for address; using Address for address payable; using ECDSA for bytes32; /*----STATE------------------------------------------*/ //voting duration in days uint32 public VOTING_DURATION = 3 days; // These contracts help burn LP's EnumerableSet.AddressSet private adapters; // LP Token Address address public lp = address(0); // Quorum >=1 <=100 uint8 public quorum; //Voting api url string apiUrl; //Contract address nonce uint nonce = 0; address[] partners; uint256[] shares; // Proposals struct Proposal { address target; bytes data; uint256 value; string discription; uint256 timestamp; } uint lastProposalId; mapping(uint => Proposal) proposals; mapping(uint => bool) proposalPreQuorum; // Executed Proposal struct ExecutedProposal { address target; bytes data; uint256 value; uint256 nonce; uint256 timestamp; uint256 executionTimestamp; bytes32 txHash; bytes[] sigs; } ExecutedProposal[] internal executedProposal; mapping(bytes32 => bool) public executedTx; // GT bool public mintable = true; bool public burnable = true; /*----EVENTS-----------------------------------------*/ event RequestQuorumStatus(bytes32 indexed requestId, uint id, bool status); event Executed( address indexed target, bytes data, uint256 value, uint256 indexed nonce, uint256 timestamp, uint256 executionTimestamp, bytes32 txHash ); /*----MODIFIERS--------------------------------------*/ modifier onlyDao() { require( msg.sender == address(this), "DAO: this function is only for DAO" ); _; } /*----CONSTRUCTOR------------------------------------*/ constructor( string memory _name, string memory _symbol, uint8 _quorum, address[] memory _partners, uint256[] memory _shares, string memory _apiUrl ) ERC20(_name, _symbol) ConfirmedOwner(msg.sender) { require( _quorum >= 1 && _quorum <= 100, "DAO: quorum should be 1 <= q <= 100" ); quorum = _quorum; require( _partners.length > 0 && _partners.length == _shares.length, "DAO: shares distribution is invalid" ); partners = _partners; shares = _shares; apiUrl = _apiUrl; apiUrl = _apiUrl; for (uint256 i = 0; i < _partners.length; i++) { _mint(_partners[i], _shares[i]); } } /*----MAIN FUNCTIONS TO RULE--------------------------*/ function addProposal( address target, bytes calldata data, uint256 value, string calldata discription ) external nonReentrant returns (uint thisId) { require(balanceOf(msg.sender) > 0, "DAO: only for members"); thisId = lastProposalId++; uint256 timestamp = block.timestamp; proposals[thisId] = Proposal(target, data, value, discription, timestamp); } function execute( uint256 _proposalId, bytes[] memory _sigs ) external nonReentrant returns (bool) { require(balanceOf(msg.sender) > 0, "DAO: only for members"); require(proposalPreQuorum[_proposalId], "DAO: preQuorum is not reached"); Proposal memory proposal = getProposalById(_proposalId); address _target = proposal.target; bytes memory _data = proposal.data; uint256 _value = proposal.value; uint256 _timestamp = proposal.timestamp; uint256 _nonce = nonce; require( _timestamp + VOTING_DURATION >= block.timestamp, "DAO: voting is over" ); bytes32 txHash = getTxHash(_target, _data, _value, _nonce, _timestamp); require(!executedTx[txHash], "DAO: propose already executed"); require(_checkSigs(_sigs, txHash), "DAO: quorum is not reached"); executedTx[txHash] = true; executedProposal.push( ExecutedProposal({ target: _target, data: _data, value: _value, nonce: _nonce, timestamp: _timestamp, executionTimestamp: block.timestamp, txHash: txHash, sigs: _sigs }) ); emit Executed( _target, _data, _value, _nonce, _timestamp, block.timestamp, txHash ); nonce++; if (_data.length == 0) { payable(_target).sendValue(_value); } else { if (_value == 0) { _target.functionCall(_data); } else { _target.functionCallWithValue(_data, _value); } } return true; } function getTxHash( address _target, bytes memory _data, uint256 _value, uint256 _nonce, uint256 _timestamp ) public view returns (bytes32) { return keccak256( abi.encode( address(this), _target, _data, _value, _nonce, _timestamp, block.chainid ) ); } function _checkSigs(bytes[] memory _sigs, bytes32 _txHash) public view returns (bool) { bytes32 ethSignedHash = _txHash.toEthSignedMessageHash(); uint256 share = 0; address[] memory signers = new address[](_sigs.length); for (uint256 i = 0; i < _sigs.length; i++) { address signer = ethSignedHash.recover(_sigs[i]); signers[i] = signer; } require(!_hasDuplicate(signers), "DAO: signatures are not unique"); for (uint256 i = 0; i < signers.length; i++) { share += balanceOf(signers[i]); } if (share * 100 < totalSupply() * quorum) { return false; } return true; } /*----BURN LP TOKENS---------------------------------*/ function burnLp( address _recipient, uint256 _share, address[] memory _tokens, address[] memory _adapters, address[] memory _pools ) external nonReentrant returns (bool) { require(lp != address(0), "DAO: LP not set yet"); require(msg.sender == lp, "DAO: only for LP"); require( !_hasDuplicate(_tokens), "DAO: duplicates are prohibited (tokens)" ); for (uint256 i = 0; i < _tokens.length; i++) { require( _tokens[i] != lp && _tokens[i] != address(this), "DAO: LP and GT cannot be part of a share" ); } require(_adapters.length == _pools.length, "DAO: adapters error"); if (_adapters.length > 0) { uint256 length = _adapters.length; if (length > 1) { for (uint256 i = 0; i < length - 1; i++) { for (uint256 j = i + 1; j < length; j++) { require( !(_adapters[i] == _adapters[j] && _pools[i] == _pools[j]), "DAO: duplicates are prohibited (adapters)" ); } } } } // ETH payable(_recipient).sendValue((address(this).balance * _share) / 1e18); // Tokens if (_tokens.length > 0) { uint256[] memory _tokenShares = new uint256[](_tokens.length); for (uint256 i = 0; i < _tokens.length; i++) { _tokenShares[i] = ((IERC20(_tokens[i]).balanceOf( address(this) ) * _share) / 1e18); } for (uint256 i = 0; i < _tokens.length; i++) { IERC20(_tokens[i]).safeTransfer(_recipient, _tokenShares[i]); } } // Adapters if (_adapters.length > 0) { uint256 length = _adapters.length; for (uint256 i = 0; i < length; i++) { require( adapters.contains(_adapters[i]), "DAO: this is not an adapter" ); bool b = IAdapter(_adapters[i]).withdraw( _recipient, _pools[i], _share ); require(b, "DAO: withdrawal error"); } } return true; } /*----GT MANAGEMENT----------------------------------*/ function mint(address _to, uint256 _amount) external onlyDao returns (bool) { require(mintable, "DAO: GT minting is disabled"); _mint(_to, _amount); return true; } function burn(address _to, uint256 _amount) external onlyDao returns (bool) { require(burnable, "DAO: GT burning is disabled"); _burn(_to, _amount); return true; } function move( address _sender, address _recipient, uint256 _amount ) external onlyDao returns (bool) { _transfer(_sender, _recipient, _amount); return true; } function disableMinting() external onlyDao returns (bool) { mintable = false; return true; } function disableBurning() external onlyDao returns (bool) { burnable = false; return true; } /*----LP---------------------------------------------*/ function setLp(address _lp) external onlyDao returns (bool) { // onlyDao check for feauture edit require(lp == address(0), "DAO: LP address has already been set"); //require(msg.sender == shop, "DAO: only Shop can set LP"); lp = _lp; return true; } /*----QUORUM-----------------------------------------*/ function changeQuorum(uint8 _q) external onlyDao returns (bool) { require(_q >= 1 && _q <= 100, "DAO: quorum should be 1 <= q <= 100"); quorum = _q; return true; } /*----VIEW FUNCTIONS---------------------------------*/ function getPartners() external view returns (address[] memory) { return partners; } function getShares() external view returns (uint256[] memory) { return shares; } function getProposalById(uint id) public view returns (Proposal memory) { return proposals[id]; } function executedProposalByIndex(uint256 _index) external view returns (ExecutedProposal memory) { return executedProposal[_index]; } function getExecutedProposal() external view returns (ExecutedProposal[] memory) { return executedProposal; } function numberOfAdapters() external view returns (uint256) { return adapters.length(); } function containsAdapter(address a) external view returns (bool) { return adapters.contains(a); } function getAdapters() external view returns (address[] memory) { uint256 adaptersLength = adapters.length(); if (adaptersLength == 0) { return new address[](0); } else { address[] memory adaptersArray = new address[](adaptersLength); for (uint256 i = 0; i < adaptersLength; i++) { adaptersArray[i] = adapters.at(i); } return adaptersArray; } } /*----PURE FUNCTIONS---------------------------------*/ function toAsciiString(address x) internal pure returns (string memory) { bytes memory s = new bytes(40); for (uint i = 0; i < 20; i++) { bytes1 b = bytes1(uint8(uint(uint160(x)) / (2**(8*(19 - i))))); bytes1 hi = bytes1(uint8(b) / 16); bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi)); s[2*i] = char(hi); s[2*i+1] = char(lo); } return string(s); } function char(bytes1 b) internal pure returns (bytes1 c) { if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); else return bytes1(uint8(b) + 0x57); } function appendString(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) { return string(abi.encodePacked(_a, _b, _c)); } function _hasDuplicate(address[] memory A) internal pure returns (bool) { if (A.length <= 1) { return false; } else { for (uint256 i = 0; i < A.length - 1; i++) { address current = A[i]; for (uint256 j = i + 1; j < A.length; j++) { if (current == A[j]) { return true; } } } } return false; } function transfer(address, uint256) public pure override returns (bool) { revert("GT: transfer is prohibited"); } function transferFrom( address, address, uint256 ) public pure override returns (bool) { revert("GT: transferFrom is prohibited"); } /*----RECEIVE ETH------------------------------------*/ event Received(address indexed, uint256); receive() external payable { emit Received(msg.sender, msg.value); } /*----Change voting duration---------------------------*/ function changeVotingDuration(uint32 _days) external onlyDao returns (bool) { require(_days >= 1 && _days <= 255, "DAO: Unsupported voting duration"); VOTING_DURATION = _days * 1 days; return true; } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"_name","internalType":"string"},{"type":"string","name":"_symbol","internalType":"string"},{"type":"uint8","name":"_quorum","internalType":"uint8"},{"type":"address[]","name":"_partners","internalType":"address[]"},{"type":"uint256[]","name":"_shares","internalType":"uint256[]"},{"type":"string","name":"_apiUrl","internalType":"string"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Executed","inputs":[{"type":"address","name":"target","internalType":"address","indexed":true},{"type":"bytes","name":"data","internalType":"bytes","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false},{"type":"uint256","name":"nonce","internalType":"uint256","indexed":true},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"uint256","name":"executionTimestamp","internalType":"uint256","indexed":false},{"type":"bytes32","name":"txHash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferRequested","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Received","inputs":[{"type":"address","name":"","internalType":"address","indexed":true},{"type":"uint256","name":"","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RequestQuorumStatus","inputs":[{"type":"bytes32","name":"requestId","internalType":"bytes32","indexed":true},{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"VOTING_DURATION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"_checkSigs","inputs":[{"type":"bytes[]","name":"_sigs","internalType":"bytes[]"},{"type":"bytes32","name":"_txHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"thisId","internalType":"uint256"}],"name":"addProposal","inputs":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"string","name":"discription","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burn","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burnLp","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_share","internalType":"uint256"},{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"address[]","name":"_adapters","internalType":"address[]"},{"type":"address[]","name":"_pools","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burnable","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"changeQuorum","inputs":[{"type":"uint8","name":"_q","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"changeVotingDuration","inputs":[{"type":"uint32","name":"_days","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"containsAdapter","inputs":[{"type":"address","name":"a","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"disableBurning","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"disableMinting","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"execute","inputs":[{"type":"uint256","name":"_proposalId","internalType":"uint256"},{"type":"bytes[]","name":"_sigs","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dao.ExecutedProposal","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"nonce","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"},{"type":"uint256","name":"executionTimestamp","internalType":"uint256"},{"type":"bytes32","name":"txHash","internalType":"bytes32"},{"type":"bytes[]","name":"sigs","internalType":"bytes[]"}]}],"name":"executedProposalByIndex","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"executedTx","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getAdapters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct Dao.ExecutedProposal[]","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"nonce","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"},{"type":"uint256","name":"executionTimestamp","internalType":"uint256"},{"type":"bytes32","name":"txHash","internalType":"bytes32"},{"type":"bytes[]","name":"sigs","internalType":"bytes[]"}]}],"name":"getExecutedProposal","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getPartners","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dao.Proposal","components":[{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"string","name":"discription","internalType":"string"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]}],"name":"getProposalById","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getShares","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getTxHash","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"uint256","name":"_nonce","internalType":"uint256"},{"type":"uint256","name":"_timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"lp","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"mint","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"mintable","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"move","inputs":[{"type":"address","name":"_sender","internalType":"address"},{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numberOfAdapters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"quorum","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setLp","inputs":[{"type":"address","name":"_lp","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"to","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60806040526007805463ffffffff60a01b19166107e960a71b179055600a80546001600160a01b03191690556000600c556014805461ffff19166101011790553480156200004c57600080fd5b5060405162004a3838038062004a388339810160408190526200006f9162000744565b6001600090815533908190888860046200008a8382620008c4565b506005620000998282620008c4565b5050506001600160a01b038216620000f85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0319166001600160a01b03848116919091179091558116156200012b576200012b81620002e8565b50505060018460ff161015801562000147575060648460ff1611155b620001a15760405162461bcd60e51b815260206004820152602360248201527f44414f3a2071756f72756d2073686f756c642062652031203c3d2071203c3d2060448201526203130360ec1b6064820152608401620000ef565b600a805460ff60a01b1916600160a01b60ff871602179055825115801590620001cb575081518351145b620002255760405162461bcd60e51b815260206004820152602360248201527f44414f3a2073686172657320646973747269627574696f6e20697320696e76616044820152621b1a5960ea1b6064820152608401620000ef565b82516200023a90600d9060208601906200047e565b5081516200025090600e906020850190620004e8565b50600b6200025f8282620008c4565b50600b6200026e8282620008c4565b5060005b8351811015620002db57620002c684828151811062000295576200029562000990565b6020026020010151848381518110620002b257620002b262000990565b60200260200101516200039460201b60201c565b80620002d281620009bc565b91505062000272565b50505050505050620009f3565b336001600160a01b03821603620003425760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000ef565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6001600160a01b038216620003ec5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620000ef565b8060036000828254620004009190620009d8565b90915550506001600160a01b038216600090815260016020526040812080548392906200042f908490620009d8565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b505050565b828054828255906000526020600020908101928215620004d6579160200282015b82811115620004d657825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200049f565b50620004e492915062000526565b5090565b828054828255906000526020600020908101928215620004d6579160200282015b82811115620004d657825182559160200191906001019062000509565b5b80821115620004e4576000815560010162000527565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156200057e576200057e6200053d565b604052919050565b600082601f8301126200059857600080fd5b81516001600160401b03811115620005b457620005b46200053d565b6020620005ca601f8301601f1916820162000553565b8281528582848701011115620005df57600080fd5b60005b83811015620005ff578581018301518282018401528201620005e2565b83811115620006115760008385840101525b5095945050505050565b805160ff811681146200062d57600080fd5b919050565b60006001600160401b038211156200064e576200064e6200053d565b5060051b60200190565b600082601f8301126200066a57600080fd5b81516020620006836200067d8362000632565b62000553565b82815260059290921b84018101918181019086841115620006a357600080fd5b8286015b84811015620006d75780516001600160a01b0381168114620006c95760008081fd5b8352918301918301620006a7565b509695505050505050565b600082601f830112620006f457600080fd5b81516020620007076200067d8362000632565b82815260059290921b840181019181810190868411156200072757600080fd5b8286015b84811015620006d757805183529183019183016200072b565b60008060008060008060c087890312156200075e57600080fd5b86516001600160401b03808211156200077657600080fd5b620007848a838b0162000586565b975060208901519150808211156200079b57600080fd5b620007a98a838b0162000586565b9650620007b960408a016200061b565b95506060890151915080821115620007d057600080fd5b620007de8a838b0162000658565b94506080890151915080821115620007f557600080fd5b620008038a838b01620006e2565b935060a08901519150808211156200081a57600080fd5b506200082989828a0162000586565b9150509295509295509295565b600181811c908216806200084b57607f821691505b6020821081036200086c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200047957600081815260208120601f850160051c810160208610156200089b5750805b601f850160051c820191505b81811015620008bc57828155600101620008a7565b505050505050565b81516001600160401b03811115620008e057620008e06200053d565b620008f881620008f1845462000836565b8462000872565b602080601f831160018114620009305760008415620009175750858301515b600019600386901b1c1916600185901b178555620008bc565b600085815260208120601f198616915b82811015620009615788860151825594840194600190910190840162000940565b5085821015620009805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620009d157620009d1620009a6565b5060010190565b60008219821115620009ee57620009ee620009a6565b500190565b6140358062000a036000396000f3fe60806040526004361061024a5760003560e01c80637e5cd5c111610139578063bb35783b116100b6578063e5a076781161007a578063e5a076781461074d578063f00d192c1461076d578063f2fde38b1461079a578063f46c503d146107ba578063f4c2baa9146107dc578063fba4e62e146107fc57600080fd5b8063bb35783b14610675578063cbe380fc14610695578063cdb2c042146106b5578063d73fe0aa146106e5578063dd62ed3e1461070757600080fd5b8063a07c7ce4116100fd578063a07c7ce4146105c8578063a438d208146105e7578063a457c2d714610620578063a9059cbb14610640578063b82e16e31461066057600080fd5b80637e5cd5c11461054b5780638da5cb5b1461056057806395d89b411461057e57806398603cca146105935780639dc29fac146105a857600080fd5b806339509351116101c75780634bf365df1161018b5780634bf365df146104ad5780634faa2e7b146104c757806370a08231146104dc57806373e29b0d1461051257806379ba50971461053457600080fd5b8063395093511461040d5780633d4581831461042d5780633ef103421461044d57806340c10f191461046d578063442ec5821461048d57600080fd5b806323b872dd1161020e57806323b872dd14610354578063313c06a014610374578063313ce567146103ac5780633372358f146103c05780633656de21146103e057600080fd5b806305cf79b91461028b57806306fdde03146102c0578063095ea7b3146102e25780631703a0181461030257806318160ddd1461033557600080fd5b366102865760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561029757600080fd5b506102ab6102a6366004613469565b61081c565b60405190151581526020015b60405180910390f35b3480156102cc57600080fd5b506102d56108d7565b6040516102b791906134e4565b3480156102ee57600080fd5b506102ab6102fd36600461350e565b610969565b34801561030e57600080fd5b50600a5461032390600160a01b900460ff1681565b60405160ff90911681526020016102b7565b34801561034157600080fd5b506003545b6040519081526020016102b7565b34801561036057600080fd5b506102ab61036f366004613538565b610980565b34801561038057600080fd5b50600a54610394906001600160a01b031681565b6040516001600160a01b0390911681526020016102b7565b3480156103b857600080fd5b506012610323565b3480156103cc57600080fd5b506103466103db366004613629565b6109cb565b3480156103ec57600080fd5b506104006103fb366004613691565b610a0b565b6040516102b791906136aa565b34801561041957600080fd5b506102ab61042836600461350e565b610bb1565b34801561043957600080fd5b506102ab610448366004613716565b610bed565b34801561045957600080fd5b506102ab6104683660046137e3565b610bfa565b34801561047957600080fd5b506102ab61048836600461350e565b611024565b34801561049957600080fd5b506103466104a8366004613871565b6110a1565b3480156104b957600080fd5b506014546102ab9060ff1681565b3480156104d357600080fd5b50610346611249565b3480156104e857600080fd5b506103466104f7366004613716565b6001600160a01b031660009081526001602052604090205490565b34801561051e57600080fd5b5061052761125a565b6040516102b791906138fa565b34801561054057600080fd5b506105496112bb565b005b34801561055757600080fd5b506102ab611369565b34801561056c57600080fd5b506006546001600160a01b0316610394565b34801561058a57600080fd5b506102d561139a565b34801561059f57600080fd5b506102ab6113a9565b3480156105b457600080fd5b506102ab6105c336600461350e565b6113db565b3480156105d457600080fd5b506014546102ab90610100900460ff1681565b3480156105f357600080fd5b5060075461060b90600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016102b7565b34801561062c57600080fd5b506102ab61063b36600461350e565b61145d565b34801561064c57600080fd5b506102ab61065b36600461350e565b6114f6565b34801561066c57600080fd5b50610527611541565b34801561068157600080fd5b506102ab610690366004613538565b611610565b3480156106a157600080fd5b506102ab6106b0366004613947565b611643565b3480156106c157600080fd5b506102ab6106d0366004613691565b60136020526000908152604090205460ff1681565b3480156106f157600080fd5b506106fa611865565b6040516102b7919061398b565b34801561071357600080fd5b506103466107223660046139c3565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b34801561075957600080fd5b506102ab6107683660046139f6565b6118bc565b34801561077957600080fd5b5061078d610788366004613691565b611981565b6040516102b79190613adc565b3480156107a657600080fd5b506105496107b5366004613716565b611bbc565b3480156107c657600080fd5b506107cf611bd0565b6040516102b79190613aef565b3480156107e857600080fd5b506102ab6107f7366004613716565b611de3565b34801561080857600080fd5b506102ab610817366004613bb3565b611e8e565b60003330146108465760405162461bcd60e51b815260040161083d90613c55565b60405180910390fd5b60018260ff161015801561085e575060648260ff1611155b6108b65760405162461bcd60e51b815260206004820152602360248201527f44414f3a2071756f72756d2073686f756c642062652031203c3d2071203c3d2060448201526203130360ec1b606482015260840161083d565b50600a805460ff60a01b1916600160a01b60ff84160217905560015b919050565b6060600480546108e690613c97565b80601f016020809104026020016040519081016040528092919081815260200182805461091290613c97565b801561095f5780601f106109345761010080835404028352916020019161095f565b820191906000526020600020905b81548152906001019060200180831161094257829003601f168201915b5050505050905090565b60006109763384846125ce565b5060015b92915050565b60405162461bcd60e51b815260206004820152601e60248201527f47543a207472616e7366657246726f6d2069732070726f686962697465640000604482015260009060640161083d565b6000308686868686466040516020016109ea9796959493929190613cd1565b60405160208183030381529060405280519060200120905095945050505050565b610a466040518060a0016040528060006001600160a01b03168152602001606081526020016000815260200160608152602001600081525090565b600082815260106020908152604091829020825160a0810190935280546001600160a01b031683526001810180549192840191610a8290613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae90613c97565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b5050505050815260200160028201548152602001600382018054610b1e90613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4a90613c97565b8015610b975780601f10610b6c57610100808354040283529160200191610b97565b820191906000526020600020905b815481529060010190602001808311610b7a57829003601f168201915b505050505081526020016004820154815250509050919050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610976918590610be8908690613d39565b6125ce565b600061097a6008836126f2565b6000600260005403610c1e5760405162461bcd60e51b815260040161083d90613d51565b600260009081553381526001602052604081205411610c775760405162461bcd60e51b815260206004820152601560248201527444414f3a206f6e6c7920666f72206d656d6265727360581b604482015260640161083d565b60008381526011602052604090205460ff16610cd55760405162461bcd60e51b815260206004820152601d60248201527f44414f3a2070726551756f72756d206973206e6f742072656163686564000000604482015260640161083d565b6000610ce084610a0b565b8051602082015160408301516080840151600c546007549596509394929391929091904290610d1c90600160a01b900463ffffffff1684613d39565b1015610d605760405162461bcd60e51b81526020600482015260136024820152722220a79d103b37ba34b7339034b99037bb32b960691b604482015260640161083d565b6000610d6f86868685876109cb565b60008181526013602052604090205490915060ff1615610dd15760405162461bcd60e51b815260206004820152601d60248201527f44414f3a2070726f706f736520616c7265616479206578656375746564000000604482015260640161083d565b610ddb8982611643565b610e275760405162461bcd60e51b815260206004820152601a60248201527f44414f3a2071756f72756d206973206e6f742072656163686564000000000000604482015260640161083d565b60008181526013602090815260408083208054600160ff1990911681179091558151610100810183526001600160a01b038b811682529381018a815292810189905260608101879052608081018890524260a082015260c0810186905260e081018e905260128054928301815590945283517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444600890920291820180546001600160a01b0319169190941617835590517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344590910190610f069082613dd6565b5060408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201518051610f549160078401916020909101906133b4565b50505081866001600160a01b03167fd1b2db6ce2b127bbccbacbc1d2917e54605dfc8765b24f8240cf1adb16a3ec3e8787874287604051610f99959493929190613e95565b60405180910390a3600c8054906000610fb183613ecc565b91905055508451600003610fd757610fd26001600160a01b03871685612714565b61100e565b83600003610ff857610ff26001600160a01b03871686612832565b5061100e565b61100c6001600160a01b0387168686612874565b505b6001975050505050505050600160005592915050565b60003330146110455760405162461bcd60e51b815260040161083d90613c55565b60145460ff166110975760405162461bcd60e51b815260206004820152601b60248201527f44414f3a204754206d696e74696e672069732064697361626c65640000000000604482015260640161083d565b61097683836128a2565b60006002600054036110c55760405162461bcd60e51b815260040161083d90613d51565b60026000908155338152600160205260408120541161111e5760405162461bcd60e51b815260206004820152601560248201527444414f3a206f6e6c7920666f72206d656d6265727360581b604482015260640161083d565b600f805490600061112e83613ecc565b91905055905060004290506040518060a00160405280896001600160a01b0316815260200188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602080820188905260408051601f88018390048302810183018252878152920191908790879081908401838280828437600092018290525093855250505060209182018490528481526010825260409020825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061120c9082613dd6565b50604082015160028201556060820151600382019061122b9082613dd6565b50608091909101516004909101555060016000559695505050505050565b60006112556008612981565b905090565b6060600d80548060200260200160405190810160405280929190818152602001828054801561095f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611294575050505050905090565b6007546001600160a01b0316331461130e5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015260640161083d565b600680546001600160a01b0319808216339081179093556007805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b600033301461138a5760405162461bcd60e51b815260040161083d90613c55565b506014805460ff19169055600190565b6060600580546108e690613c97565b60003330146113ca5760405162461bcd60e51b815260040161083d90613c55565b506014805461ff0019169055600190565b60003330146113fc5760405162461bcd60e51b815260040161083d90613c55565b601454610100900460ff166114535760405162461bcd60e51b815260206004820152601b60248201527f44414f3a204754206275726e696e672069732064697361626c65640000000000604482015260640161083d565b610976838361298b565b3360009081526002602090815260408083206001600160a01b0386168452909152812054828110156114df5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161083d565b6114ec33858584036125ce565b5060019392505050565b60405162461bcd60e51b815260206004820152601a60248201527f47543a207472616e736665722069732070726f68696269746564000000000000604482015260009060640161083d565b6060600061154f6008612981565b90508060000361156d57505060408051600081526020810190915290565b6000816001600160401b0381111561158757611587613574565b6040519080825280602002602001820160405280156115b0578160200160208202803683370190505b50905060005b82811015611605576115c9600882612ad9565b8282815181106115db576115db613ee5565b6001600160a01b0390921660209283029190910190910152806115fd81613ecc565b9150506115b6565b5092915050565b5090565b60003330146116315760405162461bcd60e51b815260040161083d90613c55565b6114ec848484612ae5565b9392505050565b60008061169d836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060008085516001600160401b038111156116bb576116bb613574565b6040519080825280602002602001820160405280156116e4578160200160208202803683370190505b50905060005b865181101561176157600061172188838151811061170a5761170a613ee5565b602002602001015186612cb590919063ffffffff16565b90508083838151811061173657611736613ee5565b6001600160a01b0390921660209283029190910190910152508061175981613ecc565b9150506116ea565b5061176b81612d57565b156117b85760405162461bcd60e51b815260206004820152601e60248201527f44414f3a207369676e61747572657320617265206e6f7420756e697175650000604482015260640161083d565b60005b815181101561181a576117fc8282815181106117d9576117d9613ee5565b60200260200101516001600160a01b031660009081526001602052604090205490565b6118069084613d39565b92508061181281613ecc565b9150506117bb565b50600a5460ff600160a01b9091041661183260035490565b61183c9190613efb565b611847836064613efb565b1015611859576000935050505061097a565b50600195945050505050565b6060600e80548060200260200160405190810160405280929190818152602001828054801561095f57602002820191906000526020600020905b81548152602001906001019080831161189f575050505050905090565b60003330146118dd5760405162461bcd60e51b815260040161083d90613c55565b60018263ffffffff16101580156118fb575060ff8263ffffffff1611155b6119475760405162461bcd60e51b815260206004820181905260248201527f44414f3a20556e737570706f7274656420766f74696e67206475726174696f6e604482015260640161083d565b6119548262015180613f1a565b6007805463ffffffff92909216600160a01b0263ffffffff60a01b19909216919091179055506001919050565b6119d560405180610100016040528060006001600160a01b03168152602001606081526020016000815260200160008152602001600081526020016000815260200160008019168152602001606081525090565b601282815481106119e8576119e8613ee5565b600091825260209182902060408051610100810190915260089092020180546001600160a01b031682526001810180549293919291840191611a2990613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5590613c97565b8015611aa25780601f10611a7757610100808354040283529160200191611aa2565b820191906000526020600020905b815481529060010190602001808311611a8557829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201805480602002602001604051908101604052809291908181526020016000905b82821015611bae578382906000526020600020018054611b2190613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611b4d90613c97565b8015611b9a5780601f10611b6f57610100808354040283529160200191611b9a565b820191906000526020600020905b815481529060010190602001808311611b7d57829003601f168201915b505050505081526020019060010190611b02565b505050915250909392505050565b611bc4612e28565b611bcd81612e7d565b50565b60606012805480602002602001604051908101604052809291908181526020016000905b82821015611dda5760008481526020908190206040805161010081019091526008850290910180546001600160a01b031682526001810180549293919291840191611c3e90613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611c6a90613c97565b8015611cb75780601f10611c8c57610100808354040283529160200191611cb7565b820191906000526020600020905b815481529060010190602001808311611c9a57829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201805480602002602001604051908101604052809291908181526020016000905b82821015611dc3578382906000526020600020018054611d3690613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611d6290613c97565b8015611daf5780601f10611d8457610100808354040283529160200191611daf565b820191906000526020600020905b815481529060010190602001808311611d9257829003601f168201915b505050505081526020019060010190611d17565b505050508152505081526020019060010190611bf4565b50505050905090565b6000333014611e045760405162461bcd60e51b815260040161083d90613c55565b600a546001600160a01b031615611e695760405162461bcd60e51b8152602060048201526024808201527f44414f3a204c5020616464726573732068617320616c7265616479206265656e604482015263081cd95d60e21b606482015260840161083d565b50600a80546001600160a01b0383166001600160a01b03199091161790556001919050565b6000600260005403611eb25760405162461bcd60e51b815260040161083d90613d51565b6002600055600a546001600160a01b0316611f055760405162461bcd60e51b8152602060048201526013602482015272111053ce881314081b9bdd081cd95d081e595d606a1b604482015260640161083d565b600a546001600160a01b03163314611f525760405162461bcd60e51b815260206004820152601060248201526f044414f3a206f6e6c7920666f72204c560841b604482015260640161083d565b611f5b84612d57565b15611fb85760405162461bcd60e51b815260206004820152602760248201527f44414f3a206475706c696361746573206172652070726f686962697465642028604482015266746f6b656e732960c81b606482015260840161083d565b60005b84518110156120a057600a5485516001600160a01b0390911690869083908110611fe757611fe7613ee5565b60200260200101516001600160a01b0316141580156120315750306001600160a01b031685828151811061201d5761201d613ee5565b60200260200101516001600160a01b031614155b61208e5760405162461bcd60e51b815260206004820152602860248201527f44414f3a204c5020616e642047542063616e6e6f742062652070617274206f66604482015267206120736861726560c01b606482015260840161083d565b8061209881613ecc565b915050611fbb565b5081518351146120e85760405162461bcd60e51b81526020600482015260136024820152722220a79d1030b230b83a32b9399032b93937b960691b604482015260640161083d565b82511561224557825160018111156122435760005b612108600183613f46565b81101561224157600061211c826001613d39565b90505b8281101561222e5785818151811061213957612139613ee5565b60200260200101516001600160a01b031686838151811061215c5761215c613ee5565b60200260200101516001600160a01b03161480156121bd575084818151811061218757612187613ee5565b60200260200101516001600160a01b03168583815181106121aa576121aa613ee5565b60200260200101516001600160a01b0316145b1561221c5760405162461bcd60e51b815260206004820152602960248201527f44414f3a206475706c696361746573206172652070726f68696269746564202860448201526861646170746572732960b81b606482015260840161083d565b8061222681613ecc565b91505061211f565b508061223981613ecc565b9150506120fd565b505b505b612275670de0b6b3a764000061225b8747613efb565b6122659190613f5d565b6001600160a01b03881690612714565b83511561241457600084516001600160401b0381111561229757612297613574565b6040519080825280602002602001820160405280156122c0578160200160208202803683370190505b50905060005b85518110156123a257670de0b6b3a7640000878783815181106122eb576122eb613ee5565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561233b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235f9190613f7f565b6123699190613efb565b6123739190613f5d565b82828151811061238557612385613ee5565b60209081029190910101528061239a81613ecc565b9150506122c6565b5060005b8551811015612411576123ff888383815181106123c5576123c5613ee5565b60200260200101518884815181106123df576123df613ee5565b60200260200101516001600160a01b0316612f279092919063ffffffff16565b8061240981613ecc565b9150506123a6565b50505b8251156125be57825160005b818110156125bb5761245585828151811061243d5761243d613ee5565b602002602001015160086126f290919063ffffffff16565b6124a15760405162461bcd60e51b815260206004820152601b60248201527f44414f3a2074686973206973206e6f7420616e20616461707465720000000000604482015260640161083d565b60008582815181106124b5576124b5613ee5565b60200260200101516001600160a01b031663d9caed128a8785815181106124de576124de613ee5565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018b90526064016020604051808303816000875af115801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613f98565b9050806125a85760405162461bcd60e51b81526020600482015260156024820152742220a79d103bb4ba34323930bbb0b61032b93937b960591b604482015260640161083d565b50806125b381613ecc565b915050612420565b50505b5060018060005595945050505050565b6001600160a01b0383166126305760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161083d565b6001600160a01b0382166126915760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161083d565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0381166000908152600183016020526040812054151561163c565b804710156127645760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161083d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146127b1576040519150601f19603f3d011682016040523d82523d6000602084013e6127b6565b606091505b505090508061282d5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161083d565b505050565b606061163c83836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250612f79565b606061289a848484604051806060016040528060298152602001613fd760299139612f84565b949350505050565b6001600160a01b0382166128f85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161083d565b806003600082825461290a9190613d39565b90915550506001600160a01b03821660009081526001602052604081208054839290612937908490613d39565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600061097a825490565b6001600160a01b0382166129eb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161083d565b6001600160a01b03821660009081526001602052604090205481811015612a5f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161083d565b6001600160a01b0383166000908152600160205260408120838303905560038054849290612a8e908490613f46565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600061163c83836130ac565b6001600160a01b038316612b495760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161083d565b6001600160a01b038216612bab5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161083d565b6001600160a01b03831660009081526001602052604090205481811015612c235760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161083d565b6001600160a01b03808516600090815260016020526040808220858503905591851681529081208054849290612c5a908490613d39565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ca691815260200190565b60405180910390a35b50505050565b60008151604103612ce85760208201516040830151606084015160001a612cde868285856130d6565b935050505061097a565b8151604003612d0f5760208201516040830151612d0685838361327f565b9250505061097a565b60405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161083d565b60006001825111612d6a57506000919050565b60005b60018351612d7b9190613f46565b811015612e1f576000838281518110612d9657612d96613ee5565b602002602001015190506000826001612daf9190613d39565b90505b8451811015612e0a57848181518110612dcd57612dcd613ee5565b60200260200101516001600160a01b0316826001600160a01b031603612df857506001949350505050565b80612e0281613ecc565b915050612db2565b50508080612e1790613ecc565b915050612d6d565b50506000919050565b6006546001600160a01b03163314612e7b5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604482015260640161083d565b565b336001600160a01b03821603612ed55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161083d565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261282d9084906132a9565b606061289a84846000855b606082471015612fe55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161083d565b843b6130335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161083d565b600080866001600160a01b0316858760405161304f9190613fba565b60006040518083038185875af1925050503d806000811461308c576040519150601f19603f3d011682016040523d82523d6000602084013e613091565b606091505b50915091506130a182828661337b565b979650505050505050565b60008260000182815481106130c3576130c3613ee5565b9060005260206000200154905092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156131535760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161083d565b8360ff16601b148061316857508360ff16601c145b6131bf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161083d565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613213573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132765760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161083d565b95945050505050565b60006001600160ff1b03821660ff83901c601b0161329f868287856130d6565b9695505050505050565b60006132fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612f799092919063ffffffff16565b80519091501561282d578080602001905181019061331c9190613f98565b61282d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161083d565b6060831561338a57508161163c565b82511561339a5782518084602001fd5b8160405162461bcd60e51b815260040161083d91906134e4565b8280548282559060005260206000209081019282156133fa579160200282015b828111156133fa57825182906133ea9082613dd6565b50916020019190600101906133d4565b5061160c9291505b8082111561160c576000613416828261341f565b50600101613402565b50805461342b90613c97565b6000825580601f1061343b575050565b601f016020900490600052602060002090810190611bcd91905b8082111561160c5760008155600101613455565b60006020828403121561347b57600080fd5b813560ff8116811461163c57600080fd5b60005b838110156134a757818101518382015260200161348f565b83811115612caf5750506000910152565b600081518084526134d081602086016020860161348c565b601f01601f19169290920160200192915050565b60208152600061163c60208301846134b8565b80356001600160a01b03811681146108d257600080fd5b6000806040838503121561352157600080fd5b61352a836134f7565b946020939093013593505050565b60008060006060848603121561354d57600080fd5b613556846134f7565b9250613564602085016134f7565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156135b2576135b2613574565b604052919050565b600082601f8301126135cb57600080fd5b81356001600160401b038111156135e4576135e4613574565b6135f7601f8201601f191660200161358a565b81815284602083860101111561360c57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561364157600080fd5b61364a866134f7565b945060208601356001600160401b0381111561366557600080fd5b613671888289016135ba565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156136a357600080fd5b5035919050565b602080825282516001600160a01b03168282015282015160a060408301526000906136d860c08401826134b8565b9050604084015160608401526060840151601f198483030160808501526136ff82826134b8565b915050608084015160a08401528091505092915050565b60006020828403121561372857600080fd5b61163c826134f7565b60006001600160401b0382111561374a5761374a613574565b5060051b60200190565b600082601f83011261376557600080fd5b8135602061377a61377583613731565b61358a565b82815260059290921b8401810191818101908684111561379957600080fd5b8286015b848110156137d85780356001600160401b038111156137bc5760008081fd5b6137ca8986838b01016135ba565b84525091830191830161379d565b509695505050505050565b600080604083850312156137f657600080fd5b8235915060208301356001600160401b0381111561381357600080fd5b61381f85828601613754565b9150509250929050565b60008083601f84011261383b57600080fd5b5081356001600160401b0381111561385257600080fd5b60208301915083602082850101111561386a57600080fd5b9250929050565b6000806000806000806080878903121561388a57600080fd5b613893876134f7565b955060208701356001600160401b03808211156138af57600080fd5b6138bb8a838b01613829565b90975095506040890135945060608901359150808211156138db57600080fd5b506138e889828a01613829565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b8181101561393b5783516001600160a01b031683529284019291840191600101613916565b50909695505050505050565b6000806040838503121561395a57600080fd5b82356001600160401b0381111561397057600080fd5b61397c85828601613754565b95602094909401359450505050565b6020808252825182820181905260009190848201906040850190845b8181101561393b578351835292840192918401916001016139a7565b600080604083850312156139d657600080fd5b6139df836134f7565b91506139ed602084016134f7565b90509250929050565b600060208284031215613a0857600080fd5b813563ffffffff8116811461163c57600080fd5b600061010060018060a01b0383511684526020808401518282870152613a44838701826134b8565b92505060408401516040860152606084015160608601526080840151608086015260a084015160a086015260c084015160c086015260e084015185830360e08701528281518085528385019150838160051b860101848401935060005b82811015613acf57601f19878303018452613abd8286516134b8565b94860194938601939150600101613aa1565b5098975050505050505050565b60208152600061163c6020830184613a1c565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613b4457603f19888603018452613b32858351613a1c565b94509285019290850190600101613b16565b5092979650505050505050565b600082601f830112613b6257600080fd5b81356020613b7261377583613731565b82815260059290921b84018101918181019086841115613b9157600080fd5b8286015b848110156137d857613ba6816134f7565b8352918301918301613b95565b600080600080600060a08688031215613bcb57600080fd5b613bd4866134f7565b94506020860135935060408601356001600160401b0380821115613bf757600080fd5b613c0389838a01613b51565b94506060880135915080821115613c1957600080fd5b613c2589838a01613b51565b93506080880135915080821115613c3b57600080fd5b50613c4888828901613b51565b9150509295509295909350565b60208082526022908201527f44414f3a20746869732066756e6374696f6e206973206f6e6c7920666f722044604082015261414f60f01b606082015260800190565b600181811c90821680613cab57607f821691505b602082108103613ccb57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0388811682528716602082015260e060408201819052600090613cfd908301886134b8565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b60008219821115613d4c57613d4c613d23565b500190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b601f82111561282d57600081815260208120601f850160051c81016020861015613daf5750805b601f850160051c820191505b81811015613dce57828155600101613dbb565b505050505050565b81516001600160401b03811115613def57613def613574565b613e0381613dfd8454613c97565b84613d88565b602080601f831160018114613e385760008415613e205750858301515b600019600386901b1c1916600185901b178555613dce565b600085815260208120601f198616915b82811015613e6757888601518255948401946001909101908401613e48565b5085821015613e855787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60a081526000613ea860a08301886134b8565b90508560208301528460408301528360608301528260808301529695505050505050565b600060018201613ede57613ede613d23565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615613f1557613f15613d23565b500290565b600063ffffffff80831681851681830481118215151615613f3d57613f3d613d23565b02949350505050565b600082821015613f5857613f58613d23565b500390565b600082613f7a57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613f9157600080fd5b5051919050565b600060208284031215613faa57600080fd5b8151801515811461163c57600080fd5b60008251613fcc81846020870161348c565b919091019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220bdac98fc3108881d6bcf375b0854582e85733c8f83a4ee3da986a76f4f55b0fc64736f6c634300080f003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000a4269746765727444414f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044244414f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000854db5c41419a42967de4ec6a47c011b28b227eb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f636f6e74726163742d6170692e64616f747269702e78797a2f64616f2f424954474552542f00000000000000000000000000000000000000
Deployed ByteCode
0x60806040526004361061024a5760003560e01c80637e5cd5c111610139578063bb35783b116100b6578063e5a076781161007a578063e5a076781461074d578063f00d192c1461076d578063f2fde38b1461079a578063f46c503d146107ba578063f4c2baa9146107dc578063fba4e62e146107fc57600080fd5b8063bb35783b14610675578063cbe380fc14610695578063cdb2c042146106b5578063d73fe0aa146106e5578063dd62ed3e1461070757600080fd5b8063a07c7ce4116100fd578063a07c7ce4146105c8578063a438d208146105e7578063a457c2d714610620578063a9059cbb14610640578063b82e16e31461066057600080fd5b80637e5cd5c11461054b5780638da5cb5b1461056057806395d89b411461057e57806398603cca146105935780639dc29fac146105a857600080fd5b806339509351116101c75780634bf365df1161018b5780634bf365df146104ad5780634faa2e7b146104c757806370a08231146104dc57806373e29b0d1461051257806379ba50971461053457600080fd5b8063395093511461040d5780633d4581831461042d5780633ef103421461044d57806340c10f191461046d578063442ec5821461048d57600080fd5b806323b872dd1161020e57806323b872dd14610354578063313c06a014610374578063313ce567146103ac5780633372358f146103c05780633656de21146103e057600080fd5b806305cf79b91461028b57806306fdde03146102c0578063095ea7b3146102e25780631703a0181461030257806318160ddd1461033557600080fd5b366102865760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561029757600080fd5b506102ab6102a6366004613469565b61081c565b60405190151581526020015b60405180910390f35b3480156102cc57600080fd5b506102d56108d7565b6040516102b791906134e4565b3480156102ee57600080fd5b506102ab6102fd36600461350e565b610969565b34801561030e57600080fd5b50600a5461032390600160a01b900460ff1681565b60405160ff90911681526020016102b7565b34801561034157600080fd5b506003545b6040519081526020016102b7565b34801561036057600080fd5b506102ab61036f366004613538565b610980565b34801561038057600080fd5b50600a54610394906001600160a01b031681565b6040516001600160a01b0390911681526020016102b7565b3480156103b857600080fd5b506012610323565b3480156103cc57600080fd5b506103466103db366004613629565b6109cb565b3480156103ec57600080fd5b506104006103fb366004613691565b610a0b565b6040516102b791906136aa565b34801561041957600080fd5b506102ab61042836600461350e565b610bb1565b34801561043957600080fd5b506102ab610448366004613716565b610bed565b34801561045957600080fd5b506102ab6104683660046137e3565b610bfa565b34801561047957600080fd5b506102ab61048836600461350e565b611024565b34801561049957600080fd5b506103466104a8366004613871565b6110a1565b3480156104b957600080fd5b506014546102ab9060ff1681565b3480156104d357600080fd5b50610346611249565b3480156104e857600080fd5b506103466104f7366004613716565b6001600160a01b031660009081526001602052604090205490565b34801561051e57600080fd5b5061052761125a565b6040516102b791906138fa565b34801561054057600080fd5b506105496112bb565b005b34801561055757600080fd5b506102ab611369565b34801561056c57600080fd5b506006546001600160a01b0316610394565b34801561058a57600080fd5b506102d561139a565b34801561059f57600080fd5b506102ab6113a9565b3480156105b457600080fd5b506102ab6105c336600461350e565b6113db565b3480156105d457600080fd5b506014546102ab90610100900460ff1681565b3480156105f357600080fd5b5060075461060b90600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016102b7565b34801561062c57600080fd5b506102ab61063b36600461350e565b61145d565b34801561064c57600080fd5b506102ab61065b36600461350e565b6114f6565b34801561066c57600080fd5b50610527611541565b34801561068157600080fd5b506102ab610690366004613538565b611610565b3480156106a157600080fd5b506102ab6106b0366004613947565b611643565b3480156106c157600080fd5b506102ab6106d0366004613691565b60136020526000908152604090205460ff1681565b3480156106f157600080fd5b506106fa611865565b6040516102b7919061398b565b34801561071357600080fd5b506103466107223660046139c3565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b34801561075957600080fd5b506102ab6107683660046139f6565b6118bc565b34801561077957600080fd5b5061078d610788366004613691565b611981565b6040516102b79190613adc565b3480156107a657600080fd5b506105496107b5366004613716565b611bbc565b3480156107c657600080fd5b506107cf611bd0565b6040516102b79190613aef565b3480156107e857600080fd5b506102ab6107f7366004613716565b611de3565b34801561080857600080fd5b506102ab610817366004613bb3565b611e8e565b60003330146108465760405162461bcd60e51b815260040161083d90613c55565b60405180910390fd5b60018260ff161015801561085e575060648260ff1611155b6108b65760405162461bcd60e51b815260206004820152602360248201527f44414f3a2071756f72756d2073686f756c642062652031203c3d2071203c3d2060448201526203130360ec1b606482015260840161083d565b50600a805460ff60a01b1916600160a01b60ff84160217905560015b919050565b6060600480546108e690613c97565b80601f016020809104026020016040519081016040528092919081815260200182805461091290613c97565b801561095f5780601f106109345761010080835404028352916020019161095f565b820191906000526020600020905b81548152906001019060200180831161094257829003601f168201915b5050505050905090565b60006109763384846125ce565b5060015b92915050565b60405162461bcd60e51b815260206004820152601e60248201527f47543a207472616e7366657246726f6d2069732070726f686962697465640000604482015260009060640161083d565b6000308686868686466040516020016109ea9796959493929190613cd1565b60405160208183030381529060405280519060200120905095945050505050565b610a466040518060a0016040528060006001600160a01b03168152602001606081526020016000815260200160608152602001600081525090565b600082815260106020908152604091829020825160a0810190935280546001600160a01b031683526001810180549192840191610a8290613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae90613c97565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b5050505050815260200160028201548152602001600382018054610b1e90613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4a90613c97565b8015610b975780601f10610b6c57610100808354040283529160200191610b97565b820191906000526020600020905b815481529060010190602001808311610b7a57829003601f168201915b505050505081526020016004820154815250509050919050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610976918590610be8908690613d39565b6125ce565b600061097a6008836126f2565b6000600260005403610c1e5760405162461bcd60e51b815260040161083d90613d51565b600260009081553381526001602052604081205411610c775760405162461bcd60e51b815260206004820152601560248201527444414f3a206f6e6c7920666f72206d656d6265727360581b604482015260640161083d565b60008381526011602052604090205460ff16610cd55760405162461bcd60e51b815260206004820152601d60248201527f44414f3a2070726551756f72756d206973206e6f742072656163686564000000604482015260640161083d565b6000610ce084610a0b565b8051602082015160408301516080840151600c546007549596509394929391929091904290610d1c90600160a01b900463ffffffff1684613d39565b1015610d605760405162461bcd60e51b81526020600482015260136024820152722220a79d103b37ba34b7339034b99037bb32b960691b604482015260640161083d565b6000610d6f86868685876109cb565b60008181526013602052604090205490915060ff1615610dd15760405162461bcd60e51b815260206004820152601d60248201527f44414f3a2070726f706f736520616c7265616479206578656375746564000000604482015260640161083d565b610ddb8982611643565b610e275760405162461bcd60e51b815260206004820152601a60248201527f44414f3a2071756f72756d206973206e6f742072656163686564000000000000604482015260640161083d565b60008181526013602090815260408083208054600160ff1990911681179091558151610100810183526001600160a01b038b811682529381018a815292810189905260608101879052608081018890524260a082015260c0810186905260e081018e905260128054928301815590945283517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444600890920291820180546001600160a01b0319169190941617835590517fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344590910190610f069082613dd6565b5060408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201518051610f549160078401916020909101906133b4565b50505081866001600160a01b03167fd1b2db6ce2b127bbccbacbc1d2917e54605dfc8765b24f8240cf1adb16a3ec3e8787874287604051610f99959493929190613e95565b60405180910390a3600c8054906000610fb183613ecc565b91905055508451600003610fd757610fd26001600160a01b03871685612714565b61100e565b83600003610ff857610ff26001600160a01b03871686612832565b5061100e565b61100c6001600160a01b0387168686612874565b505b6001975050505050505050600160005592915050565b60003330146110455760405162461bcd60e51b815260040161083d90613c55565b60145460ff166110975760405162461bcd60e51b815260206004820152601b60248201527f44414f3a204754206d696e74696e672069732064697361626c65640000000000604482015260640161083d565b61097683836128a2565b60006002600054036110c55760405162461bcd60e51b815260040161083d90613d51565b60026000908155338152600160205260408120541161111e5760405162461bcd60e51b815260206004820152601560248201527444414f3a206f6e6c7920666f72206d656d6265727360581b604482015260640161083d565b600f805490600061112e83613ecc565b91905055905060004290506040518060a00160405280896001600160a01b0316815260200188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602080820188905260408051601f88018390048302810183018252878152920191908790879081908401838280828437600092018290525093855250505060209182018490528481526010825260409020825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061120c9082613dd6565b50604082015160028201556060820151600382019061122b9082613dd6565b50608091909101516004909101555060016000559695505050505050565b60006112556008612981565b905090565b6060600d80548060200260200160405190810160405280929190818152602001828054801561095f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611294575050505050905090565b6007546001600160a01b0316331461130e5760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015260640161083d565b600680546001600160a01b0319808216339081179093556007805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b600033301461138a5760405162461bcd60e51b815260040161083d90613c55565b506014805460ff19169055600190565b6060600580546108e690613c97565b60003330146113ca5760405162461bcd60e51b815260040161083d90613c55565b506014805461ff0019169055600190565b60003330146113fc5760405162461bcd60e51b815260040161083d90613c55565b601454610100900460ff166114535760405162461bcd60e51b815260206004820152601b60248201527f44414f3a204754206275726e696e672069732064697361626c65640000000000604482015260640161083d565b610976838361298b565b3360009081526002602090815260408083206001600160a01b0386168452909152812054828110156114df5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161083d565b6114ec33858584036125ce565b5060019392505050565b60405162461bcd60e51b815260206004820152601a60248201527f47543a207472616e736665722069732070726f68696269746564000000000000604482015260009060640161083d565b6060600061154f6008612981565b90508060000361156d57505060408051600081526020810190915290565b6000816001600160401b0381111561158757611587613574565b6040519080825280602002602001820160405280156115b0578160200160208202803683370190505b50905060005b82811015611605576115c9600882612ad9565b8282815181106115db576115db613ee5565b6001600160a01b0390921660209283029190910190910152806115fd81613ecc565b9150506115b6565b5092915050565b5090565b60003330146116315760405162461bcd60e51b815260040161083d90613c55565b6114ec848484612ae5565b9392505050565b60008061169d836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060008085516001600160401b038111156116bb576116bb613574565b6040519080825280602002602001820160405280156116e4578160200160208202803683370190505b50905060005b865181101561176157600061172188838151811061170a5761170a613ee5565b602002602001015186612cb590919063ffffffff16565b90508083838151811061173657611736613ee5565b6001600160a01b0390921660209283029190910190910152508061175981613ecc565b9150506116ea565b5061176b81612d57565b156117b85760405162461bcd60e51b815260206004820152601e60248201527f44414f3a207369676e61747572657320617265206e6f7420756e697175650000604482015260640161083d565b60005b815181101561181a576117fc8282815181106117d9576117d9613ee5565b60200260200101516001600160a01b031660009081526001602052604090205490565b6118069084613d39565b92508061181281613ecc565b9150506117bb565b50600a5460ff600160a01b9091041661183260035490565b61183c9190613efb565b611847836064613efb565b1015611859576000935050505061097a565b50600195945050505050565b6060600e80548060200260200160405190810160405280929190818152602001828054801561095f57602002820191906000526020600020905b81548152602001906001019080831161189f575050505050905090565b60003330146118dd5760405162461bcd60e51b815260040161083d90613c55565b60018263ffffffff16101580156118fb575060ff8263ffffffff1611155b6119475760405162461bcd60e51b815260206004820181905260248201527f44414f3a20556e737570706f7274656420766f74696e67206475726174696f6e604482015260640161083d565b6119548262015180613f1a565b6007805463ffffffff92909216600160a01b0263ffffffff60a01b19909216919091179055506001919050565b6119d560405180610100016040528060006001600160a01b03168152602001606081526020016000815260200160008152602001600081526020016000815260200160008019168152602001606081525090565b601282815481106119e8576119e8613ee5565b600091825260209182902060408051610100810190915260089092020180546001600160a01b031682526001810180549293919291840191611a2990613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5590613c97565b8015611aa25780601f10611a7757610100808354040283529160200191611aa2565b820191906000526020600020905b815481529060010190602001808311611a8557829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201805480602002602001604051908101604052809291908181526020016000905b82821015611bae578382906000526020600020018054611b2190613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611b4d90613c97565b8015611b9a5780601f10611b6f57610100808354040283529160200191611b9a565b820191906000526020600020905b815481529060010190602001808311611b7d57829003601f168201915b505050505081526020019060010190611b02565b505050915250909392505050565b611bc4612e28565b611bcd81612e7d565b50565b60606012805480602002602001604051908101604052809291908181526020016000905b82821015611dda5760008481526020908190206040805161010081019091526008850290910180546001600160a01b031682526001810180549293919291840191611c3e90613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611c6a90613c97565b8015611cb75780601f10611c8c57610100808354040283529160200191611cb7565b820191906000526020600020905b815481529060010190602001808311611c9a57829003601f168201915b50505050508152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201805480602002602001604051908101604052809291908181526020016000905b82821015611dc3578382906000526020600020018054611d3690613c97565b80601f0160208091040260200160405190810160405280929190818152602001828054611d6290613c97565b8015611daf5780601f10611d8457610100808354040283529160200191611daf565b820191906000526020600020905b815481529060010190602001808311611d9257829003601f168201915b505050505081526020019060010190611d17565b505050508152505081526020019060010190611bf4565b50505050905090565b6000333014611e045760405162461bcd60e51b815260040161083d90613c55565b600a546001600160a01b031615611e695760405162461bcd60e51b8152602060048201526024808201527f44414f3a204c5020616464726573732068617320616c7265616479206265656e604482015263081cd95d60e21b606482015260840161083d565b50600a80546001600160a01b0383166001600160a01b03199091161790556001919050565b6000600260005403611eb25760405162461bcd60e51b815260040161083d90613d51565b6002600055600a546001600160a01b0316611f055760405162461bcd60e51b8152602060048201526013602482015272111053ce881314081b9bdd081cd95d081e595d606a1b604482015260640161083d565b600a546001600160a01b03163314611f525760405162461bcd60e51b815260206004820152601060248201526f044414f3a206f6e6c7920666f72204c560841b604482015260640161083d565b611f5b84612d57565b15611fb85760405162461bcd60e51b815260206004820152602760248201527f44414f3a206475706c696361746573206172652070726f686962697465642028604482015266746f6b656e732960c81b606482015260840161083d565b60005b84518110156120a057600a5485516001600160a01b0390911690869083908110611fe757611fe7613ee5565b60200260200101516001600160a01b0316141580156120315750306001600160a01b031685828151811061201d5761201d613ee5565b60200260200101516001600160a01b031614155b61208e5760405162461bcd60e51b815260206004820152602860248201527f44414f3a204c5020616e642047542063616e6e6f742062652070617274206f66604482015267206120736861726560c01b606482015260840161083d565b8061209881613ecc565b915050611fbb565b5081518351146120e85760405162461bcd60e51b81526020600482015260136024820152722220a79d1030b230b83a32b9399032b93937b960691b604482015260640161083d565b82511561224557825160018111156122435760005b612108600183613f46565b81101561224157600061211c826001613d39565b90505b8281101561222e5785818151811061213957612139613ee5565b60200260200101516001600160a01b031686838151811061215c5761215c613ee5565b60200260200101516001600160a01b03161480156121bd575084818151811061218757612187613ee5565b60200260200101516001600160a01b03168583815181106121aa576121aa613ee5565b60200260200101516001600160a01b0316145b1561221c5760405162461bcd60e51b815260206004820152602960248201527f44414f3a206475706c696361746573206172652070726f68696269746564202860448201526861646170746572732960b81b606482015260840161083d565b8061222681613ecc565b91505061211f565b508061223981613ecc565b9150506120fd565b505b505b612275670de0b6b3a764000061225b8747613efb565b6122659190613f5d565b6001600160a01b03881690612714565b83511561241457600084516001600160401b0381111561229757612297613574565b6040519080825280602002602001820160405280156122c0578160200160208202803683370190505b50905060005b85518110156123a257670de0b6b3a7640000878783815181106122eb576122eb613ee5565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561233b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235f9190613f7f565b6123699190613efb565b6123739190613f5d565b82828151811061238557612385613ee5565b60209081029190910101528061239a81613ecc565b9150506122c6565b5060005b8551811015612411576123ff888383815181106123c5576123c5613ee5565b60200260200101518884815181106123df576123df613ee5565b60200260200101516001600160a01b0316612f279092919063ffffffff16565b8061240981613ecc565b9150506123a6565b50505b8251156125be57825160005b818110156125bb5761245585828151811061243d5761243d613ee5565b602002602001015160086126f290919063ffffffff16565b6124a15760405162461bcd60e51b815260206004820152601b60248201527f44414f3a2074686973206973206e6f7420616e20616461707465720000000000604482015260640161083d565b60008582815181106124b5576124b5613ee5565b60200260200101516001600160a01b031663d9caed128a8785815181106124de576124de613ee5565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018b90526064016020604051808303816000875af115801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613f98565b9050806125a85760405162461bcd60e51b81526020600482015260156024820152742220a79d103bb4ba34323930bbb0b61032b93937b960591b604482015260640161083d565b50806125b381613ecc565b915050612420565b50505b5060018060005595945050505050565b6001600160a01b0383166126305760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161083d565b6001600160a01b0382166126915760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161083d565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0381166000908152600183016020526040812054151561163c565b804710156127645760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161083d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146127b1576040519150601f19603f3d011682016040523d82523d6000602084013e6127b6565b606091505b505090508061282d5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161083d565b505050565b606061163c83836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250612f79565b606061289a848484604051806060016040528060298152602001613fd760299139612f84565b949350505050565b6001600160a01b0382166128f85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161083d565b806003600082825461290a9190613d39565b90915550506001600160a01b03821660009081526001602052604081208054839290612937908490613d39565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600061097a825490565b6001600160a01b0382166129eb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161083d565b6001600160a01b03821660009081526001602052604090205481811015612a5f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161083d565b6001600160a01b0383166000908152600160205260408120838303905560038054849290612a8e908490613f46565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600061163c83836130ac565b6001600160a01b038316612b495760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161083d565b6001600160a01b038216612bab5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161083d565b6001600160a01b03831660009081526001602052604090205481811015612c235760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161083d565b6001600160a01b03808516600090815260016020526040808220858503905591851681529081208054849290612c5a908490613d39565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ca691815260200190565b60405180910390a35b50505050565b60008151604103612ce85760208201516040830151606084015160001a612cde868285856130d6565b935050505061097a565b8151604003612d0f5760208201516040830151612d0685838361327f565b9250505061097a565b60405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161083d565b60006001825111612d6a57506000919050565b60005b60018351612d7b9190613f46565b811015612e1f576000838281518110612d9657612d96613ee5565b602002602001015190506000826001612daf9190613d39565b90505b8451811015612e0a57848181518110612dcd57612dcd613ee5565b60200260200101516001600160a01b0316826001600160a01b031603612df857506001949350505050565b80612e0281613ecc565b915050612db2565b50508080612e1790613ecc565b915050612d6d565b50506000919050565b6006546001600160a01b03163314612e7b5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604482015260640161083d565b565b336001600160a01b03821603612ed55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161083d565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261282d9084906132a9565b606061289a84846000855b606082471015612fe55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161083d565b843b6130335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161083d565b600080866001600160a01b0316858760405161304f9190613fba565b60006040518083038185875af1925050503d806000811461308c576040519150601f19603f3d011682016040523d82523d6000602084013e613091565b606091505b50915091506130a182828661337b565b979650505050505050565b60008260000182815481106130c3576130c3613ee5565b9060005260206000200154905092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156131535760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161083d565b8360ff16601b148061316857508360ff16601c145b6131bf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161083d565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613213573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132765760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161083d565b95945050505050565b60006001600160ff1b03821660ff83901c601b0161329f868287856130d6565b9695505050505050565b60006132fe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612f799092919063ffffffff16565b80519091501561282d578080602001905181019061331c9190613f98565b61282d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161083d565b6060831561338a57508161163c565b82511561339a5782518084602001fd5b8160405162461bcd60e51b815260040161083d91906134e4565b8280548282559060005260206000209081019282156133fa579160200282015b828111156133fa57825182906133ea9082613dd6565b50916020019190600101906133d4565b5061160c9291505b8082111561160c576000613416828261341f565b50600101613402565b50805461342b90613c97565b6000825580601f1061343b575050565b601f016020900490600052602060002090810190611bcd91905b8082111561160c5760008155600101613455565b60006020828403121561347b57600080fd5b813560ff8116811461163c57600080fd5b60005b838110156134a757818101518382015260200161348f565b83811115612caf5750506000910152565b600081518084526134d081602086016020860161348c565b601f01601f19169290920160200192915050565b60208152600061163c60208301846134b8565b80356001600160a01b03811681146108d257600080fd5b6000806040838503121561352157600080fd5b61352a836134f7565b946020939093013593505050565b60008060006060848603121561354d57600080fd5b613556846134f7565b9250613564602085016134f7565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156135b2576135b2613574565b604052919050565b600082601f8301126135cb57600080fd5b81356001600160401b038111156135e4576135e4613574565b6135f7601f8201601f191660200161358a565b81815284602083860101111561360c57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561364157600080fd5b61364a866134f7565b945060208601356001600160401b0381111561366557600080fd5b613671888289016135ba565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156136a357600080fd5b5035919050565b602080825282516001600160a01b03168282015282015160a060408301526000906136d860c08401826134b8565b9050604084015160608401526060840151601f198483030160808501526136ff82826134b8565b915050608084015160a08401528091505092915050565b60006020828403121561372857600080fd5b61163c826134f7565b60006001600160401b0382111561374a5761374a613574565b5060051b60200190565b600082601f83011261376557600080fd5b8135602061377a61377583613731565b61358a565b82815260059290921b8401810191818101908684111561379957600080fd5b8286015b848110156137d85780356001600160401b038111156137bc5760008081fd5b6137ca8986838b01016135ba565b84525091830191830161379d565b509695505050505050565b600080604083850312156137f657600080fd5b8235915060208301356001600160401b0381111561381357600080fd5b61381f85828601613754565b9150509250929050565b60008083601f84011261383b57600080fd5b5081356001600160401b0381111561385257600080fd5b60208301915083602082850101111561386a57600080fd5b9250929050565b6000806000806000806080878903121561388a57600080fd5b613893876134f7565b955060208701356001600160401b03808211156138af57600080fd5b6138bb8a838b01613829565b90975095506040890135945060608901359150808211156138db57600080fd5b506138e889828a01613829565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b8181101561393b5783516001600160a01b031683529284019291840191600101613916565b50909695505050505050565b6000806040838503121561395a57600080fd5b82356001600160401b0381111561397057600080fd5b61397c85828601613754565b95602094909401359450505050565b6020808252825182820181905260009190848201906040850190845b8181101561393b578351835292840192918401916001016139a7565b600080604083850312156139d657600080fd5b6139df836134f7565b91506139ed602084016134f7565b90509250929050565b600060208284031215613a0857600080fd5b813563ffffffff8116811461163c57600080fd5b600061010060018060a01b0383511684526020808401518282870152613a44838701826134b8565b92505060408401516040860152606084015160608601526080840151608086015260a084015160a086015260c084015160c086015260e084015185830360e08701528281518085528385019150838160051b860101848401935060005b82811015613acf57601f19878303018452613abd8286516134b8565b94860194938601939150600101613aa1565b5098975050505050505050565b60208152600061163c6020830184613a1c565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613b4457603f19888603018452613b32858351613a1c565b94509285019290850190600101613b16565b5092979650505050505050565b600082601f830112613b6257600080fd5b81356020613b7261377583613731565b82815260059290921b84018101918181019086841115613b9157600080fd5b8286015b848110156137d857613ba6816134f7565b8352918301918301613b95565b600080600080600060a08688031215613bcb57600080fd5b613bd4866134f7565b94506020860135935060408601356001600160401b0380821115613bf757600080fd5b613c0389838a01613b51565b94506060880135915080821115613c1957600080fd5b613c2589838a01613b51565b93506080880135915080821115613c3b57600080fd5b50613c4888828901613b51565b9150509295509295909350565b60208082526022908201527f44414f3a20746869732066756e6374696f6e206973206f6e6c7920666f722044604082015261414f60f01b606082015260800190565b600181811c90821680613cab57607f821691505b602082108103613ccb57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0388811682528716602082015260e060408201819052600090613cfd908301886134b8565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b60008219821115613d4c57613d4c613d23565b500190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b601f82111561282d57600081815260208120601f850160051c81016020861015613daf5750805b601f850160051c820191505b81811015613dce57828155600101613dbb565b505050505050565b81516001600160401b03811115613def57613def613574565b613e0381613dfd8454613c97565b84613d88565b602080601f831160018114613e385760008415613e205750858301515b600019600386901b1c1916600185901b178555613dce565b600085815260208120601f198616915b82811015613e6757888601518255948401946001909101908401613e48565b5085821015613e855787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60a081526000613ea860a08301886134b8565b90508560208301528460408301528360608301528260808301529695505050505050565b600060018201613ede57613ede613d23565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615613f1557613f15613d23565b500290565b600063ffffffff80831681851681830481118215151615613f3d57613f3d613d23565b02949350505050565b600082821015613f5857613f58613d23565b500390565b600082613f7a57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613f9157600080fd5b5051919050565b600060208284031215613faa57600080fd5b8151801515811461163c57600080fd5b60008251613fcc81846020870161348c565b919091019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220bdac98fc3108881d6bcf375b0854582e85733c8f83a4ee3da986a76f4f55b0fc64736f6c634300080f0033