Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OpenHatchV11
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Internal function that returns the initialized version. Returns `_initialized`
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Internal function that returns the initialized version. Returns `_initializing`
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
contract ContextUpgradable is Initializable {
function initialize() external initializer {
__init(true);
}
function __init(bool callChain) internal {
}
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address ) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
abstract contract OwnableUpgradeable is ContextUpgradable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
interface IERC20Upgradeable {
/**
* @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);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
/**
* @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);
}
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
interface IERC20PermitUpgradeable {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
library CountersUpgradeable {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
library MathUpgradeable {
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 StringsUpgradeable {
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 = MathUpgradeable.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, MathUpgradeable.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 ERC20Upgradeable is Initializable, ContextUpgradable, IERC20Upgradeable, IERC20MetadataUpgradeable {
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.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_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:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, 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}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, 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}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, 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) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, 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) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* 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:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, 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;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_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;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_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 Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - 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 {}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[45] private __gap;
}
library ECDSAUpgradeable {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. 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]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
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.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @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.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} 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.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// 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 (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): 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.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @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) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @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 Message, created from `s`. 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(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s));
}
/**
* @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));
}
}
abstract contract EIP712Upgradeable is Initializable {
/* solhint-disable var-name-mixedcase */
bytes32 private _HASHED_NAME;
bytes32 private _HASHED_VERSION;
bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(string memory name, string memory version) internal onlyInitializing {
__EIP712_init_unchained(name, version);
}
function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712NameHash() internal virtual view returns (bytes32) {
return _HASHED_NAME;
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712VersionHash() internal virtual view returns (bytes32) {
return _HASHED_VERSION;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
mapping(address => CountersUpgradeable.Counter) private _nonces;
// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
/**
* @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
* However, to ensure consistency with the upgradeable transpiler, we will continue
* to reserve a slot.
* @custom:oz-renamed-from _PERMIT_TYPEHASH
*/
// solhint-disable-next-line var-name-mixedcase
bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
function __ERC20Permit_init(string memory name) internal onlyInitializing {
__EIP712_init_unchained(name, "1");
}
function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}
/**
* @dev See {IERC20Permit-permit}.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSAUpgradeable.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
/**
* @dev See {IERC20Permit-nonces}.
*/
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
/**
* @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
/**
* @dev "Consume a nonce": return the current value and increment.
*
* _Available since v4.1._
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
CountersUpgradeable.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
library SafeERC20Upgradeable {
using AddressUpgradeable for address;
function safeTransfer(
IERC20Upgradeable token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20Upgradeable 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(
IERC20Upgradeable 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(
IERC20Upgradeable 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(
IERC20Upgradeable 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));
}
}
function safePermit(
IERC20PermitUpgradeable token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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(IERC20Upgradeable 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");
}
}
}
contract OpenHatchV11 is OwnableUpgradeable {
using SafeMathUpgradeable for *;
using SafeERC20Upgradeable for ERC20Upgradeable;
event Log_i(string message, uint data);
event Log_s(string message, string data);
uint256 public _days;
address public fundBox;
uint256 private submit_fee ; // 2% foundation
// uint256 private fee = 200; // 2% foundation
//variables defined
address[] public judges;
string private code;
enum TYPEBOX{ REWARDS, FEES }
struct Proposal_str {
uint256 budget;
uint256[] slot_budget;
uint256[] slot_paid;
address author;
address acceptor;
string id;
uint256 start_date;
uint256 due_date;
bool active;
address base_token;
}
struct Judge_form {
address judge;
address _base_token;
uint256 deposit;
string id;
bool active;
bool withdraw;
}
struct Subscribe_form {
address owner;
uint256 fee;
bool active;
bool monthly;
uint256 due_date;
uint256 start_date;
address base_token;
}
struct create_form {
address owner;
uint256 fee;
uint256 due_date;
uint256 start_date;
address base_token;
}
struct Box_Fees {
TYPEBOX boxType;
uint sum;
}
mapping(string => Subscribe_form) private _Subscribe;
mapping(string => uint256) private balanceSubscription;
mapping(string => Proposal_str) _OpenHatch;
mapping(string => Judge_form) _judges;
mapping(address => uint) private _depositJudges;
mapping(address => mapping(TYPEBOX => uint)) public _depositBox;
mapping(address => uint) private _limitionWithdraw;
mapping(string =>create_form) public creaet_subscribe;
mapping(string => mapping(string => Subscribe_form)) public new_Subscribe;
mapping(string => mapping(address => uint256)) public balanceSubscription_v2;
event Log_bool(string message, uint data);
event Log_a(string message, address _address);
function setup(
string memory _code
) public initializer {
code = _code;
_days = 30;
submit_fee = 10;
}
//modifiers
modifier onlyAuthor(string memory id) {
require(msg.sender == _OpenHatch[id].author, "Not owner");
// Underscore is a special character only used inside
// a function modifier and it tells Solidity to
// execute the rest of the code.
_;
}
modifier isOpen(string memory id) {
require(_OpenHatch[id].active, "Not owner");
// Underscore is a special character only used inside
// a function modifier and it tells Solidity to
// execute the rest of the code.
_;
}
//functions
function submit_openHatch(
address[] memory mix_addresses,// author , acceptor , bastoken
uint256 _budget,
uint256[] memory _slot_budget,
uint256[] memory _slot_paid,
string memory _id,
uint256 _due_date
) public returns (bool) {
//
require(
keccak256(bytes(_OpenHatch[_id].id)) != keccak256(bytes(_id)),
"This OpenHatck has been registerd "
);
// uint f = _budget;
uint256 totalFee = (_budget * get_submitFee()) / 10000 ;
uint256 real_budget = _budget - totalFee;
uint256 fee_rewards = totalFee/2;
uint256 fee_admin = totalFee - fee_rewards;
//check******************************************************** 10 => 1 =>9 slot 9
if(ERC20Upgradeable( mix_addresses[2]).balanceOf( msg.sender) < _budget){
revert("Insufficient balnace!");
}
ERC20Upgradeable( mix_addresses[2]).safeTransferFrom(msg.sender,address(this), _budget);
//send to fund box
_depositBox[mix_addresses[2]][TYPEBOX.FEES] = _depositBox[mix_addresses[2]][TYPEBOX.FEES] + fee_admin;
_depositBox[mix_addresses[2]][TYPEBOX.REWARDS] = _depositBox[mix_addresses[2]][TYPEBOX.REWARDS] + fee_rewards;
_OpenHatch[_id] = Proposal_str(
real_budget,
_slot_budget,
_slot_paid,
msg.sender,
mix_addresses[1],
_id,
timestamp(),
_due_date,
true,
mix_addresses[2]
);
emit Log_i("Create new Hatch",_budget);
return true;
}
modifier slot_(
uint256 _budget,
uint256[] memory _slot_budget
)
{
bool result = false;
uint total = 0;
for (uint256 i = 0; i < _slot_budget.length; i++) {
total = _slot_budget[i]+total;
}
if(total == _budget){
result = true;
}
require(total != _budget, "the budget is opposite of slots");
// Underscore is a special character only used inside
// a function modifier and it tells Solidity to
// execute the rest of the code.
_;
}
function get_openHatck(string memory id)
public
view
returns (Proposal_str memory)
{
return _OpenHatch[id];
}
function get_rewardsBox(address base_token)
public
view
returns ( uint)
{
return _depositBox[base_token][TYPEBOX.REWARDS];
}
function get_adminBox(address base_token)
public
view
returns ( uint)
{
return _depositBox[base_token][TYPEBOX.FEES];
}
function set_submitFee(uint _fee)
public
onlyOwner
returns(bool)
{
if(_fee <= 0){
revert( "the fee number is wrong!");
}
if(_fee > 25){
revert( "the fee number is wrong!");
}
submit_fee = _fee;
emit Log_i("changed the fee",_fee);
return true;
}
function get_submitFee()
public
view
returns ( uint)
{
return submit_fee*100;
}
function close_openHatch(string memory id)
public
onlyAuthor(id)
isOpen(id)
{
_OpenHatch[id].active = false;
emit Log_s("close openHatch",id);
}
function requestSubscribe(
uint256 _fee,
string memory _authorId,
address _base_token
) public returns (bool) {
if(_fee > balance_token(_base_token, msg.sender)){
revert( "Please submit the asking fee!");
}
transferToContract(_base_token, msg.sender, _fee);
creaet_subscribe[_authorId] = create_form(
msg.sender,
_fee,
timestampDays(_days),
timestamp(),
_base_token
);
emit Log_i("request Subscribe",_fee);
return true;
}
function submitAsSubscribe(
uint256 _feeBox,
string memory _authorId,
string memory _boxId,
address _base_token,
bool _monthly
) public returns (bool) {
if(_feeBox > balance_token(_base_token, msg.sender)){
revert( "Please submit the asking fee!");
}
if( timestamp() > creaet_subscribe[_authorId].due_date ){
revert( "Please submit the asking fee!");
}
if( creaet_subscribe[_authorId].owner != msg.sender){
revert( "This Subscribe Is Not owner !");
}
if(new_Subscribe[_authorId][_boxId].active == true){
revert( "This Subscribe Is active !");
}
new_Subscribe[_authorId][_boxId] = Subscribe_form(
msg.sender,
_feeBox,
true,
_monthly,
timestampDays(_days),
timestamp(),
_base_token
);
emit Log_i("create Subscribe",_feeBox);
return true;
}
function submitSubscription(uint256 _fee, string memory _authorId, string memory _boxId)
public
returns (bool)
{
address token = new_Subscribe[_authorId][_boxId].base_token;
if(_fee > balance_token(token, msg.sender) ){
revert( "Please submit the asking fee!");
}
if(timestamp() > creaet_subscribe[_authorId].due_date ){
revert( "Please submit the asking fee!");
}
if(new_Subscribe[_authorId][_boxId].monthly == false){
transferToContract(token, msg.sender, _fee);
balanceSubscription_v2[_authorId][token] = balanceSubscription_v2[_authorId][token] + _fee;
emit Log_i("submit Subscribe",_fee);
return true;
}else{
if( timestamp() > new_Subscribe[_authorId][_boxId].due_date ){
revert( "Please submit the asking fee!");
}
transferToContract(token, msg.sender, _fee);
balanceSubscription_v2[_authorId][token] = balanceSubscription_v2[_authorId][token] + _fee;
emit Log_i("submit Subscribe",_fee);
return true;
}
}
function returnRequestSubscribe(string memory _authorId)
public
view
returns (create_form memory)
{
return creaet_subscribe[_authorId];
}
function returnSubscribe(string memory _authorId, string memory _boxId)
public
view
returns (Subscribe_form memory,uint )
{
return (new_Subscribe[_authorId][_boxId],balanceSubscription_v2[_authorId][new_Subscribe[_authorId][_boxId].base_token]);
}
function WithdrawSubscrip(uint256 _fee, string memory _authorId, string memory _boxId)
public
returns (bool)
{
if(new_Subscribe[_authorId][_boxId].active == false){
revert( "This Subscribe Is unavailable !");
}
if(_fee > balanceSubscription_v2[_authorId][new_Subscribe[_authorId][_boxId].base_token]){
revert( "Please submit the asking fee!");
}
if( new_Subscribe[_authorId][_boxId].owner != msg.sender){
revert( "This Subscribe Is unavailable !");
}
balanceSubscription_v2[_authorId][new_Subscribe[_authorId][_boxId].base_token] = balanceSubscription_v2[_authorId][new_Subscribe[_authorId][_boxId].base_token] - _fee;
transferFromContract(
new_Subscribe[_authorId][_boxId].base_token,
new_Subscribe[_authorId][_boxId].owner,
_fee
);
emit Log_i("withdraw Subscrip",_fee);
return true;
}
function withdrawReward(uint256 amount, string memory _judgeId,address base_token,string memory _code)
public
returns (bool)
{
Judge_form memory _jud = _judges[_judgeId];
if(_jud.active == false){
revert('his _judgeId Is unavailable !');
}
if(amount>1000){
revert('You can not withdraw more than max!');
}
if(_jud.judge != msg.sender){
revert('Just judge can withdraw!');
}
if(_limitionWithdraw[msg.sender]>timestamp()){
revert('You should back in 8 days later ');
}
if( _depositBox[base_token][TYPEBOX.REWARDS]< amount){
revert("Exceed the amount of rewards!");
}
if (
(keccak256(abi.encodePacked((_code))) !=
keccak256(abi.encodePacked((code))))
) {
revert("This code not found");
}
_depositBox[base_token][TYPEBOX.REWARDS] =_depositBox[base_token][TYPEBOX.REWARDS]- amount ;
transferFromContract(
base_token,
_jud.judge,
amount
);
_limitionWithdraw[msg.sender] = timestampDays(8);
emit Log_i("Judge Withdraw Reward",amount);
return true;
}
function limitaionJudge() public view returns (uint){
return _limitionWithdraw[msg.sender];
}
function withdrawRewardAdmin(uint256 amount, address base_token)
public
onlyOwner
returns (bool)
{
if(amount > _depositBox[base_token][TYPEBOX.FEES] ){
revert('"Insufficient inventory!"');
}
_depositBox[base_token][TYPEBOX.FEES] = _depositBox[base_token][TYPEBOX.FEES] - amount ;
transferFromContract(
base_token,
owner(),
amount
);
emit Log_i("admin withdraw the Reward",amount);
return true;
}
function close_openHatch_admin(string memory id)
public
onlyOwner
isOpen(id)
{
_OpenHatch[id].active = false;
}
function add_pays(uint256[] memory phase_indexs, string memory id)
public
onlyAuthor(id)
isOpen(id)
{
for (uint256 i = 0; i < phase_indexs.length; i++) {
add_pay(phase_indexs[i], id);
}
}
function add_pay(uint256 phase_index, string memory id)
public
onlyAuthor(id)
isOpen(id)
returns(bool)
{
Proposal_str storage openhatch = _OpenHatch[id];
if (phase_index > openhatch.slot_paid.length) {
revert("phase_index is wrong");
}
//paid success
openhatch.slot_paid.push(openhatch.slot_paid.length + 1);
///send to acceptor
transferFromContract(
openhatch.base_token,
openhatch.acceptor,
openhatch.slot_budget[phase_index]
);
emit Log_a("acceptor ",openhatch.acceptor);
emit Log_i("pay ",openhatch.slot_budget[phase_index]);
emit Log_a("base_token",openhatch.base_token);
emit Log_s("author paid ","amount");
return true;
}
function add_pay_admin(uint256 phase_index, string memory id)
public
onlyOwner
isOpen(id)
{
Proposal_str storage openhatch = _OpenHatch[id];
// proposal_str = _OpenHatch[id];
if (phase_index > openhatch.slot_paid.length) return;
//paid success
openhatch.slot_paid.push(openhatch.slot_paid.length + 1);
//send to acceptor
transferFromContract(
openhatch.base_token,
openhatch.acceptor,
openhatch.slot_budget[phase_index]
);
}
function add_judge(
string memory id,
string memory _code,
uint256 deposit,
address _base_token
) public {
if (
(keccak256(abi.encodePacked((_code))) !=
keccak256(abi.encodePacked((code))))
) {
revert("This code not found");
}
require(
keccak256(bytes(_judges[id].id)) != keccak256(bytes(id)),
"This Judge has been registerd "
);
_judges[id] = Judge_form(
msg.sender,
_base_token,
deposit,
id,
true,
false
);
//send deposit to contarct
transferToContract(_base_token, msg.sender, deposit);
emit Log_i("New Judge added ",deposit);
}
function get_judge(string memory _id)
public
view
returns (Judge_form memory)
{
return _judges[_id];
}
function pop_judge(string memory _id) internal onlyOwner {
_judges[_id].active = false;
_judges[_id].withdraw = true;
Judge_form memory _jud = _judges[_id];
transferFromContract(
_jud._base_token,
_jud.judge,
_jud.deposit
);
}
function remove_judge(string memory _id) public {
require(
_judges[_id].judge != msg.sender,
"This Subscribe Is unavailable !"
);
require(
_judges[_id].active != false,
"This Subscribe Is unavailable !"
);
_judges[_id].active = false;
_judges[_id].withdraw = true;
Judge_form memory _jud = _judges[_id];
//back deposit to judge
// //send to owner of platform
transferFromContract(
_jud._base_token,
_jud.judge,
_jud.deposit
);
}
function _isContract(address addr) private view returns (bool) {
uint size;
assembly { size := extcodesize(addr) }
return size > 0;
}
//helpers
function sum_array(uint256[] memory array, uint256 total)
internal
pure
returns (bool)
{
uint256 sum = 0;
for (uint256 i = 0; i < array.length; i++) {
sum = array[i] + sum;
}
if (sum > total) {
return false;
} else {
return true;
}
}
function transferToContract(
address token,
address from,
uint256 amount
) internal {
// requires approval from `victim` to `TokenSwap`
ERC20Upgradeable(token).safeTransferFrom(from,address(this), amount);
// bool owner_share_sent = payable(_owner).send(owner_share);
}
function balance_token(address token, address own)
public
view
returns (uint256)
{
// requires approval from `victim` to `TokenSwap`
return ERC20Upgradeable(token).balanceOf(own);
}
function transferFromContract(
address token,
address to,
uint256 amount
) internal {
ERC20Upgradeable(token).safeTransfer(to, amount);
}
function allowcheck(
address token,
address owner,
address spender
) public view returns (uint256) {
return ERC20Upgradeable(token).allowance(owner, spender);
}
function timestamp() private view returns (uint256) {
return block.timestamp; // solidity count seconds, not miliseconds
}
function timestampDays(uint _day) private view returns (uint256) {
uint256 time = block.timestamp+ (_day * 86400);
return time; // solidity count seconds, not miliseconds
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"Log_a","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"Log_bool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"Log_i","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"Log_s","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"string","name":"_authorId","type":"string"},{"internalType":"string","name":"_boxId","type":"string"}],"name":"WithdrawSubscrip","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_days","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum OpenHatchV11.TYPEBOX","name":"","type":"uint8"}],"name":"_depositBox","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"_code","type":"string"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"_base_token","type":"address"}],"name":"add_judge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"phase_index","type":"uint256"},{"internalType":"string","name":"id","type":"string"}],"name":"add_pay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"phase_index","type":"uint256"},{"internalType":"string","name":"id","type":"string"}],"name":"add_pay_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"phase_indexs","type":"uint256[]"},{"internalType":"string","name":"id","type":"string"}],"name":"add_pays","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowcheck","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"}],"name":"balanceSubscription_v2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"own","type":"address"}],"name":"balance_token","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"id","type":"string"}],"name":"close_openHatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"id","type":"string"}],"name":"close_openHatch_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"creaet_subscribe","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"due_date","type":"uint256"},{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"address","name":"base_token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundBox","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base_token","type":"address"}],"name":"get_adminBox","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"}],"name":"get_judge","outputs":[{"components":[{"internalType":"address","name":"judge","type":"address"},{"internalType":"address","name":"_base_token","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"string","name":"id","type":"string"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"withdraw","type":"bool"}],"internalType":"struct OpenHatchV11.Judge_form","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"id","type":"string"}],"name":"get_openHatck","outputs":[{"components":[{"internalType":"uint256","name":"budget","type":"uint256"},{"internalType":"uint256[]","name":"slot_budget","type":"uint256[]"},{"internalType":"uint256[]","name":"slot_paid","type":"uint256[]"},{"internalType":"address","name":"author","type":"address"},{"internalType":"address","name":"acceptor","type":"address"},{"internalType":"string","name":"id","type":"string"},{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"uint256","name":"due_date","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"address","name":"base_token","type":"address"}],"internalType":"struct OpenHatchV11.Proposal_str","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base_token","type":"address"}],"name":"get_rewardsBox","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_submitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"judges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitaionJudge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"name":"new_Subscribe","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"monthly","type":"bool"},{"internalType":"uint256","name":"due_date","type":"uint256"},{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"address","name":"base_token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"}],"name":"remove_judge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"string","name":"_authorId","type":"string"},{"internalType":"address","name":"_base_token","type":"address"}],"name":"requestSubscribe","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_authorId","type":"string"}],"name":"returnRequestSubscribe","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"due_date","type":"uint256"},{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"address","name":"base_token","type":"address"}],"internalType":"struct OpenHatchV11.create_form","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_authorId","type":"string"},{"internalType":"string","name":"_boxId","type":"string"}],"name":"returnSubscribe","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"monthly","type":"bool"},{"internalType":"uint256","name":"due_date","type":"uint256"},{"internalType":"uint256","name":"start_date","type":"uint256"},{"internalType":"address","name":"base_token","type":"address"}],"internalType":"struct OpenHatchV11.Subscribe_form","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"set_submitFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_code","type":"string"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeBox","type":"uint256"},{"internalType":"string","name":"_authorId","type":"string"},{"internalType":"string","name":"_boxId","type":"string"},{"internalType":"address","name":"_base_token","type":"address"},{"internalType":"bool","name":"_monthly","type":"bool"}],"name":"submitAsSubscribe","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"string","name":"_authorId","type":"string"},{"internalType":"string","name":"_boxId","type":"string"}],"name":"submitSubscription","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"mix_addresses","type":"address[]"},{"internalType":"uint256","name":"_budget","type":"uint256"},{"internalType":"uint256[]","name":"_slot_budget","type":"uint256[]"},{"internalType":"uint256[]","name":"_slot_paid","type":"uint256[]"},{"internalType":"string","name":"_id","type":"string"},{"internalType":"uint256","name":"_due_date","type":"uint256"}],"name":"submit_openHatch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"_judgeId","type":"string"},{"internalType":"address","name":"base_token","type":"address"},{"internalType":"string","name":"_code","type":"string"}],"name":"withdrawReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"base_token","type":"address"}],"name":"withdrawRewardAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061429b806100206000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80638da5cb5b11610130578063cd9e09b4116100b8578063f1ba40721161007c578063f1ba407214610651578063f2fde38b146106cc578063f4d5c893146106df578063fd1b9a4714610718578063fd73a3881461072b57600080fd5b8063cd9e09b4146105f0578063d037f95414610603578063dd63266a14610618578063dfdb5e8b1461062b578063e7d683331461063e57600080fd5b8063b115f498116100ff578063b115f49814610552578063b25bc8a11461055b578063b38dd7a4146105b7578063c8b9d84f146105ca578063cd575291146105dd57600080fd5b80638da5cb5b1461048e578063a512ac14146104a5578063ac9464e11461052c578063b06b03681461053f57600080fd5b80634e12955a116101b35780636292e2a6116101825780636292e2a61461041f57806365907f7e14610432578063715018a61461046b5780638129fc1c1461047357806389656f0b1461047b57600080fd5b80634e12955a1461030857806356d0b1b7146103ce57806358e9aaa6146103e1578063607dbcdb1461040c57600080fd5b80632d3a6c45116101fa5780632d3a6c451461029c578063381c6e42146102af578063425abe51146102c2578063433ba9c8146102d55780634c9bc8c1146102e857600080fd5b80630491bd1b1461022c5780631c027d7a146102545780631e606fdb146102675780632bc3853114610287575b600080fd5b61023f61023a36600461370c565b610733565b60405190151581526020015b60405180910390f35b61023f6102623660046137ca565b610d0d565b61027a6102753660046137e3565b610e02565b60405161024b91906138a2565b61029a6102953660046137e3565b61104d565b005b61029a6102aa3660046137e3565b611127565b61023f6102bd366004613991565b611227565b61029a6102d03660046137e3565b61151d565b61029a6102e3366004613a23565b6115a1565b6102fb6102f63660046137e3565b61167a565b60405161024b9190613a86565b610389610316366004613af0565b8151602081840181018051603f8252928201948201949094209190935281518083018401805192815290840192909301919091209152805460018201546002830154600384015460048501546005909501546001600160a01b0394851695939460ff808516956101009095041693911687565b604080516001600160a01b0398891681526020810197909752941515948601949094529115156060850152608084015260a083015290911660c082015260e00161024b565b61029a6103dc3660046137e3565b6117b6565b6033546103f4906001600160a01b031681565b6040516001600160a01b03909116815260200161024b565b61029a61041a366004613b26565b6119e2565b61023f61042d366004613ba3565b611c2e565b61045d610440366004613bdf565b603c60209081526000928352604080842090915290825290205481565b60405190815260200161024b565b61029a611f31565b61029a611f45565b61029a610489366004613ba3565b612007565b6000546201000090046001600160a01b03166103f4565b6104f86104b33660046137e3565b8051602081830181018051603e82529282019190930120915280546001820154600283015460038401546004909401546001600160a01b039384169492939192911685565b604080516001600160a01b03968716815260208101959095528401929092526060830152909116608082015260a00161024b565b61023f61053a366004613c1a565b6120ec565b6103f461054d3660046137ca565b612340565b61045d60325481565b61056e6105693660046137e3565b61236a565b60405161024b919081516001600160a01b039081168252602080840151908301526040808401519083015260608084015190830152608092830151169181019190915260a00190565b61023f6105c5366004613c86565b612419565b61045d6105d8366004613cb2565b612563565b61045d6105eb366004613ccd565b6125a5565b61023f6105fe366004613cf7565b612613565b336000908152603d602052604090205461045d565b61023f610626366004613c1a565b612a6a565b61023f610639366004613d74565b612dbd565b61045d61064c366004613dca565b612ef5565b61066461065f366004613af0565b612f73565b60405161024b92919082516001600160a01b039081168252602080850151908301526040808501511515908301526060808501511515908301526080808501519083015260a0848101519083015260c093840151169281019290925260e08201526101000190565b61029a6106da366004613cb2565b6130cd565b61045d6106ed366004613e04565b8151602081840181018051604080835293830195830195909520949052929092526000908152205481565b61045d610726366004613cb2565b613143565b61045d613163565b6000828051906020012060398460405161074d9190613e48565b908152602001604051809103902060050160405161076b9190613f11565b6040518091039020036107d05760405162461bcd60e51b815260206004820152602260248201527f54686973204f70656e486174636b20686173206265656e207265676973746572604482015261032160f51b60648201526084015b60405180910390fd5b60006127106107dd613163565b6107e79089613f33565b6107f19190613f4a565b905060006107ff8289613f6c565b9050600061080e600284613f4a565b9050600061081c8285613f6c565b9050898b60028151811061083257610832613f7f565b60209081029190910101516040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f95565b10156108ec5760405162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e742062616c6e6163652160581b60448201526064016107c7565b61092633308c8e60028151811061090557610905613f7f565b60200260200101516001600160a01b0316613179909392919063ffffffff16565b80603c60008d60028151811061093e5761093e613f7f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600060018081111561097a5761097a613fae565b600181111561098b5761098b613fae565b8152602001908152602001600020546109a49190613fc4565b603c60008d6002815181106109bb576109bb613f7f565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006001808111156109f7576109f7613fae565b6001811115610a0857610a08613fae565b81526020019081526020016000208190555081603c60008d600281518110610a3257610a32613f7f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000806001811115610a6e57610a6e613fae565b6001811115610a7f57610a7f613fae565b815260200190815260200160002054610a989190613fc4565b603c60008d600281518110610aaf57610aaf613f7f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000806001811115610aeb57610aeb613fae565b6001811115610afc57610afc613fae565b8152602001908152602001600020819055506040518061014001604052808481526020018a8152602001898152602001336001600160a01b031681526020018c600181518110610b4e57610b4e613f7f565b60200260200101516001600160a01b03168152602001888152602001610b714290565b81526020018781526020016001151581526020018c600281518110610b9857610b98613f7f565b60200260200101516001600160a01b0316815250603988604051610bbc9190613e48565b9081526020016040518091039020600082015181600001556020820151816001019080519060200190610bf09291906134f0565b5060408201518051610c0c9160028401916020909101906134f0565b5060608201516003820180546001600160a01b039283166001600160a01b031991821617909155608084015160048401805491909316911617905560a08201516005820190610c5b9082614025565b5060c0820151600682015560e082015160078201556101008083015160089092018054610120909401516001600160a01b0316909102610100600160a81b0319921515929092166001600160a81b031990931692909217179055604080518181526010818301526f086e4cac2e8ca40dccaee4090c2e8c6d60831b6060820152602081018c905290516000805160206142468339815191529181900360800190a15060019a9950505050505050505050565b6000610d176131e4565b60008211610d625760405162461bcd60e51b815260206004820152601860248201527774686520666565206e756d6265722069732077726f6e672160401b60448201526064016107c7565b6019821115610dae5760405162461bcd60e51b815260206004820152601860248201527774686520666565206e756d6265722069732077726f6e672160401b60448201526064016107c7565b603482905560408051818152600f818301526e6368616e676564207468652066656560881b60608201526020810184905290516000805160206142468339815191529181900360800190a15060015b919050565b610e7560405180610140016040528060008152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160608152602001600081526020016000815260200160001515815260200160006001600160a01b031681525090565b603982604051610e859190613e48565b9081526020016040518091039020604051806101400160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020018280548015610ef857602002820191906000526020600020905b815481526020019060010190808311610ee4575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610f5057602002820191906000526020600020905b815481526020019060010190808311610f3c575b505050918352505060038201546001600160a01b0390811660208301526004830154166040820152600582018054606090920191610f8d90613e64565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb990613e64565b80156110065780601f10610fdb57610100808354040283529160200191611006565b820191906000526020600020905b815481529060010190602001808311610fe957829003601f168201915b5050509183525050600682015460208201526007820154604082015260089091015460ff81161515606083015261010090046001600160a01b031660809091015292915050565b600054610100900460ff161580801561106d5750600054600160ff909116105b806110875750303b158015611087575060005460ff166001145b6110a35760405162461bcd60e51b81526004016107c7906140e4565b6000805460ff1916600117905580156110c6576000805461ff0019166101001790555b60366110d28382614025565b50601e603255600a6034558015611123576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b806039816040516111389190613e48565b90815260405190819003602001902060030154336001600160a01b03909116146111745760405162461bcd60e51b81526004016107c790614132565b816039816040516111859190613e48565b9081526040519081900360200190206008015460ff166111b75760405162461bcd60e51b81526004016107c790614132565b60006039846040516111c99190613e48565b908152604051908190036020018120600801805492151560ff19909316929092179091557f0fdb92177627c58bc2b166040cabcd29dc886024d10328c479d2f0337810579a9061121a908590614155565b60405180910390a1505050565b600061123383336125a5565b8611156112525760405162461bcd60e51b81526004016107c79061418e565b603e856040516112629190613e48565b90815260200160405180910390206002015461127b4290565b11156112995760405162461bcd60e51b81526004016107c79061418e565b336001600160a01b0316603e866040516112b39190613e48565b908152604051908190036020019020546001600160a01b0316146113195760405162461bcd60e51b815260206004820152601e60248201527f5468697320537562736372696265204973204e6f74206f776e6572202021000060448201526064016107c7565b603f856040516113299190613e48565b9081526020016040518091039020846040516113459190613e48565b9081526040519081900360200190206002015460ff1615156001036113ac5760405162461bcd60e51b815260206004820152601a60248201527f546869732053756273637269626520497320616374697665202100000000000060448201526064016107c7565b6040518060e00160405280336001600160a01b0316815260200187815260200160011515815260200183151581526020016113e8603254613245565b8152602001428152602001846001600160a01b0316815250603f866040516114109190613e48565b90815260200160405180910390208560405161142c9190613e48565b908152604080519182900360209081018320845181546001600160a01b039182166001600160a01b031991821617835592860151600183015592850151600282018054606088015115156101000261ff00199315159390931661ffff19909116179190911790556080850151600382015560a0850151600482015560c09094015160059094018054949092169316929092179091556000805160206142468339815191529061150990889060408082526010908201526f6372656174652053756273637269626560801b6060820152602081019190915260800190565b60405180910390a150600195945050505050565b6115256131e4565b806039816040516115369190613e48565b9081526040519081900360200190206008015460ff166115685760405162461bcd60e51b81526004016107c790614132565b600060398360405161157a9190613e48565b908152604051908190036020019020600801805491151560ff199092169190911790555050565b806039816040516115b29190613e48565b90815260405190819003602001902060030154336001600160a01b03909116146115ee5760405162461bcd60e51b81526004016107c790614132565b816039816040516115ff9190613e48565b9081526040519081900360200190206008015460ff166116315760405162461bcd60e51b81526004016107c790614132565b60005b84518110156116735761166085828151811061165257611652613f7f565b602002602001015185611c2e565b508061166b816141c5565b915050611634565b5050505050565b6040805160c0810182526000808252602082018190528183018190526060808301526080820181905260a08201529051603a906116b8908490613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061170d90613e64565b80601f016020809104026020016040519081016040528092919081815260200182805461173990613e64565b80156117865780601f1061175b57610100808354040283529160200191611786565b820191906000526020600020905b81548152906001019060200180831161176957829003601f168201915b50505091835250506004919091015460ff8082161515602084015261010090910416151560409091015292915050565b336001600160a01b0316603a826040516117d09190613e48565b908152604051908190036020019020546001600160a01b0316036118065760405162461bcd60e51b81526004016107c7906141de565b603a816040516118169190613e48565b9081526040519081900360200190206004015460ff16151560000361184d5760405162461bcd60e51b81526004016107c7906141de565b6000603a8260405161185f9190613e48565b908152604051908190036020018120600401805492151560ff1990931692909217909155600190603a90611894908490613e48565b908152602001604051809103902060040160016101000a81548160ff0219169083151502179055506000603a826040516118ce9190613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061192390613e64565b80601f016020809104026020016040519081016040528092919081815260200182805461194f90613e64565b801561199c5780601f106119715761010080835404028352916020019161199c565b820191906000526020600020905b81548152906001019060200180831161197f57829003601f168201915b50505091835250506004919091015460ff80821615156020808501919091526101009092041615156040928301528201518251918301519293506111239290919061325f565b60366040516020016119f49190613f11565b6040516020818303038152906040528051906020012083604051602001611a1b9190613e48565b6040516020818303038152906040528051906020012014611a745760405162461bcd60e51b8152602060048201526013602482015272151a1a5cc818dbd919481b9bdd08199bdd5b99606a1b60448201526064016107c7565b8380519060200120603a85604051611a8c9190613e48565b9081526020016040518091039020600301604051611aaa9190613f11565b604051809103902003611aff5760405162461bcd60e51b815260206004820152601e60248201527f54686973204a7564676520686173206265656e2072656769737465726420000060448201526064016107c7565b6040805160c0810182523381526001600160a01b03831660208201528082018490526060810186905260016080820152600060a08201529051603a90611b46908790613e48565b9081526040805160209281900383019020835181546001600160a01b03199081166001600160a01b0392831617835593850151600183018054909516911617909255820151600282015560608201516003820190611ba49082614025565b5060808201516004909101805460a09093015115156101000261ff00199215159290921661ffff1990931692909217179055611be1813384613273565b604080518181526010818301526f02732bb90253ab233b29030b23232b2160851b60608201526020810184905290516000805160206142468339815191529181900360800190a150505050565b600081603981604051611c419190613e48565b90815260405190819003602001902060030154336001600160a01b0390911614611c7d5760405162461bcd60e51b81526004016107c790614132565b82603981604051611c8e9190613e48565b9081526040519081900360200190206008015460ff16611cc05760405162461bcd60e51b81526004016107c790614132565b6000603985604051611cd29190613e48565b9081526040519081900360200190206002810154909150861115611d2f5760405162461bcd60e51b815260206004820152601460248201527370686173655f696e6465782069732077726f6e6760601b60448201526064016107c7565b600281018054611d40906001613fc4565b815460018181018455600093845260209093200155600882015460048301549183018054611d9c936001600160a01b036101009094048416931691908a908110611d8c57611d8c613f7f565b906000526020600020015461325f565b60048101546040805181815260098183015268030b1b1b2b83a37b9160bd1b60608201526001600160a01b039092166020830152517f29cceaa768a511b1433880b50fe557bb0332f2a343551e6bfe919a946950a9d89181900360800190a1600080516020614246833981519152816001018781548110611e1f57611e1f613f7f565b9060005260206000200154604051611e58919060408082526004908201526303830bc960e51b6060820152602081019190915260800190565b60405180910390a1600881015460408051818152600a81830152693130b9b2afba37b5b2b760b11b60608201526101009092046001600160a01b03166020830152517f29cceaa768a511b1433880b50fe557bb0332f2a343551e6bfe919a946950a9d8916080908290030190a17f0fdb92177627c58bc2b166040cabcd29dc886024d10328c479d2f0337810579a604051611509906040808252600c908201526b030baba3437b9103830b4b2160a51b606082015260806020820181905260069082015265185b5bdd5b9d60d21b60a082015260c00190565b611f396131e4565b611f436000613288565b565b600054610100900460ff1615808015611f655750600054600160ff909116105b80611f7f5750303b158015611f7f575060005460ff166001145b611f9b5760405162461bcd60e51b81526004016107c7906140e4565b6000805460ff191660011790558015611fbe576000805461ff0019166101001790555b8015612004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b61200f6131e4565b806039816040516120209190613e48565b9081526040519081900360200190206008015460ff166120525760405162461bcd60e51b81526004016107c790614132565b60006039836040516120649190613e48565b90815260405190819003602001902060028101549091508411156120885750505050565b600281018054612099906001613fc4565b8154600181810184556000938452602090932001556008820154600483015491830180546120e5936001600160a01b0361010090940484169316919088908110611d8c57611d8c613f7f565b505b505050565b600080603f846040516120ff9190613e48565b90815260200160405180910390208360405161211b9190613e48565b908152604051908190036020019020600501546001600160a01b0316905061214381336125a5565b8511156121625760405162461bcd60e51b81526004016107c79061418e565b603e846040516121729190613e48565b90815260200160405180910390206002015461218b4290565b11156121a95760405162461bcd60e51b81526004016107c79061418e565b603f846040516121b99190613e48565b9081526020016040518091039020836040516121d59190613e48565b9081526040519081900360200190206002015460ff6101009091041615156000036122cb57612205813387613273565b846040856040516122169190613e48565b90815260408051602092819003830190206001600160a01b038516600090815292529020546122459190613fc4565b6040856040516122559190613e48565b90815260408051602092819003830181206001600160a01b0386166000908152908452829020939093558083526010908301526f7375626d69742053756273637269626560801b606083015281018690526000805160206142468339815191529060800160405180910390a16001915050612339565b603f846040516122db9190613e48565b9081526020016040518091039020836040516122f79190613e48565b9081526020016040518091039020600301546123104290565b111561232e5760405162461bcd60e51b81526004016107c79061418e565b612205813387613273565b9392505050565b6035818154811061235057600080fd5b6000918252602090912001546001600160a01b0316905081565b6123ae6040518060a0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b603e826040516123be9190613e48565b90815260408051918290036020908101832060a08401835280546001600160a01b0390811685526001820154928501929092526002810154928401929092526003820154606084015260049091015416608082015292915050565b60006124236131e4565b6001600160a01b0382166000908152603c60209081526040808320600184529091529020548311156124975760405162461bcd60e51b815260206004820152601960248201527f22496e73756666696369656e7420696e76656e746f727921220000000000000060448201526064016107c7565b6001600160a01b0382166000908152603c60209081526040808320600184529091529020546124c7908490613f6c565b6001600160a01b038381166000908152603c60209081526040808320600184529091528120929092559054612505918491620100009004168561325f565b604080518181526019818301527f61646d696e20776974686472617720746865205265776172640000000000000060608201526020810185905290516000805160206142468339815191529181900360800190a15060015b92915050565b6001600160a01b0381166000908152603c6020526040812081805b600181111561258f5761258f613fae565b8152602001908152602001600020549050919050565b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190613f95565b600080603a856040516126269190613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061267b90613e64565b80601f01602080910402602001604051908101604052809291908181526020018280546126a790613e64565b80156126f45780601f106126c9576101008083540402835291602001916126f4565b820191906000526020600020905b8154815290600101906020018083116126d757829003601f168201915b50505091835250506004919091015460ff80821615156020840152610100909104161515604090910152608081015190915015156000036127775760405162461bcd60e51b815260206004820152601d60248201527f686973205f6a75646765496420497320756e617661696c61626c65202100000060448201526064016107c7565b6103e88611156127d55760405162461bcd60e51b815260206004820152602360248201527f596f752063616e206e6f74207769746864726177206d6f7265207468616e206d60448201526261782160e81b60648201526084016107c7565b80516001600160a01b0316331461282e5760405162461bcd60e51b815260206004820152601860248201527f4a757374206a756467652063616e20776974686472617721000000000000000060448201526064016107c7565b42336000908152603d602052604090205411156128975760405162461bcd60e51b815260206004820152602160248201527f596f752073686f756c6420206261636b20696e20382064617973206c617465726044820152600160fd1b60648201526084016107c7565b6001600160a01b0384166000908152603c6020908152604080832083805290915290205486111561290a5760405162461bcd60e51b815260206004820152601d60248201527f4578636565642074686520616d6f756e74206f6620726577617264732100000060448201526064016107c7565b603660405160200161291c9190613f11565b60405160208183030381529060405280519060200120836040516020016129439190613e48565b604051602081830303815290604052805190602001201461299c5760405162461bcd60e51b8152602060048201526013602482015272151a1a5cc818dbd919481b9bdd08199bdd5b99606a1b60448201526064016107c7565b6001600160a01b0384166000908152603c602090815260408083208380529091529020546129cb908790613f6c565b6001600160a01b0385166000908152603c6020908152604080832083805290915290205580516129fd9085908861325f565b612a076008613245565b336000908152603d602052604090819020919091555160008051602061424683398151915290611509908890604080825260159082015274129d5919d94815da5d1a191c985dc814995dd85c99605a1b6060820152602081019190915260800190565b6000603f83604051612a7c9190613e48565b908152602001604051809103902082604051612a989190613e48565b9081526040519081900360200190206002015460ff161515600003612acf5760405162461bcd60e51b81526004016107c7906141de565b604083604051612adf9190613e48565b90815260200160405180910390206000603f85604051612aff9190613e48565b908152602001604051809103902084604051612b1b9190613e48565b9081526040805160209281900383019020600501546001600160a01b03168352908201929092520160002054841115612b665760405162461bcd60e51b81526004016107c79061418e565b336001600160a01b0316603f84604051612b809190613e48565b908152602001604051809103902083604051612b9c9190613e48565b908152604051908190036020019020546001600160a01b031614612bd25760405162461bcd60e51b81526004016107c7906141de565b83604084604051612be39190613e48565b90815260200160405180910390206000603f86604051612c039190613e48565b908152602001604051809103902085604051612c1f9190613e48565b9081526040805160209281900383019020600501546001600160a01b03168352908201929092520160002054612c559190613f6c565b604084604051612c659190613e48565b90815260200160405180910390206000603f86604051612c859190613e48565b908152602001604051809103902085604051612ca19190613e48565b9081526040805160209281900383019020600501546001600160a01b031683529082019290925281016000209190915551612d6690603f90612ce4908690613e48565b908152602001604051809103902083604051612d009190613e48565b908152604051908190036020018120600501546001600160a01b031690603f90612d2b908790613e48565b908152602001604051809103902084604051612d479190613e48565b908152604051908190036020019020546001600160a01b03168661325f565b60408051818152601191810191909152700776974686472617720537562736372697607c1b606082015260208101859052600080516020614246833981519152906080015b60405180910390a15060019392505050565b6000612dc982336125a5565b841115612de85760405162461bcd60e51b81526004016107c79061418e565b612df3823386613273565b6040518060a00160405280336001600160a01b03168152602001858152602001612e1e603254613245565b8152602001428152602001836001600160a01b0316815250603e84604051612e469190613e48565b908152604080519182900360209081018320845181546001600160a01b039182166001600160a01b031991821617835592860151600183015592850151600282015560608501516003820155608090940151600490940180549490921693169290921790915560008051602061424683398151915290612dab908690604080825260119082015270726571756573742053756273637269626560781b6060820152602081019190915260800190565b604051636eb1769f60e11b81526001600160a01b03838116600483015282811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612f47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6b9190613f95565b949350505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526000603f84604051612fbe9190613e48565b908152602001604051809103902083604051612fda9190613e48565b9081526020016040518091039020604085604051612ff89190613e48565b90815260200160405180910390206000603f876040516130189190613e48565b9081526020016040518091039020866040516130349190613e48565b90815260408051602092819003830190206005908101546001600160a01b0390811685528484019590955292810160002054815160e081018352865486168152600187015493810193909352600286015460ff80821615159385019390935261010090049091161515606083015260038501546080830152600485015460a0830152939091015490911660c08201529590945092505050565b6130d56131e4565b6001600160a01b03811661313a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c7565b61200481613288565b6001600160a01b0381166000908152603c6020526040812081600161257e565b600060345460646131749190613f33565b905090565b6040516001600160a01b03808516602483015283166044820152606481018290526120e59085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526132e3565b6000546001600160a01b0362010000909104163314611f435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107c7565b6000806132558362015180613f33565b6123399042613fc4565b6120e76001600160a01b03841683836133b5565b6120e76001600160a01b038416833084613179565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b6000613338826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133e59092919063ffffffff16565b8051909150156120e757808060200190518101906133569190614215565b6120e75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107c7565b6040516001600160a01b0383166024820152604481018290526120e790849063a9059cbb60e01b906064016131ad565b6060612f6b848460008585843b61343e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107c7565b600080866001600160a01b0316858760405161345a9190613e48565b60006040518083038185875af1925050503d8060008114613497576040519150601f19603f3d011682016040523d82523d6000602084013e61349c565b606091505b50915091506134ac8282866134b7565b979650505050505050565b606083156134c6575081612339565b8251156134d65782518084602001fd5b8160405162461bcd60e51b81526004016107c79190614232565b82805482825590600052602060002090810192821561352b579160200282015b8281111561352b578251825591602001919060010190613510565b5061353792915061353b565b5090565b5b80821115613537576000815560010161353c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561358e5761358e613550565b604052919050565b60006001600160401b038211156135af576135af613550565b5060051b60200190565b80356001600160a01b0381168114610dfd57600080fd5b600082601f8301126135e157600080fd5b813560206135f66135f183613596565b613566565b82815260059290921b8401810191818101908684111561361557600080fd5b8286015b848110156136375761362a816135b9565b8352918301918301613619565b509695505050505050565b600082601f83011261365357600080fd5b813560206136636135f183613596565b82815260059290921b8401810191818101908684111561368257600080fd5b8286015b848110156136375780358352918301918301613686565b600082601f8301126136ae57600080fd5b81356001600160401b038111156136c7576136c7613550565b6136da601f8201601f1916602001613566565b8181528460208386010111156136ef57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561372557600080fd5b86356001600160401b038082111561373c57600080fd5b6137488a838b016135d0565b975060208901359650604089013591508082111561376557600080fd5b6137718a838b01613642565b9550606089013591508082111561378757600080fd5b6137938a838b01613642565b945060808901359150808211156137a957600080fd5b506137b689828a0161369d565b92505060a087013590509295509295509295565b6000602082840312156137dc57600080fd5b5035919050565b6000602082840312156137f557600080fd5b81356001600160401b0381111561380b57600080fd5b612f6b8482850161369d565b600081518084526020808501945080840160005b838110156138475781518752958201959082019060010161382b565b509495945050505050565b60005b8381101561386d578181015183820152602001613855565b50506000910152565b6000815180845261388e816020860160208601613852565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516101408060408501526138cb610160850183613817565b91506040850151601f19808685030160608701526138e98483613817565b93506060870151915061390760808701836001600160a01b03169052565b60808701516001600160a01b03811660a0880152915060a08701519150808685030160c0870152506139398382613876565b92505060c085015160e085015260e085015161010081818701528087015191505061012061396a8187018315159052565b909501516001600160a01b031693019290925250919050565b801515811461200457600080fd5b600080600080600060a086880312156139a957600080fd5b8535945060208601356001600160401b03808211156139c757600080fd5b6139d389838a0161369d565b955060408801359150808211156139e957600080fd5b506139f68882890161369d565b935050613a05606087016135b9565b91506080860135613a1581613983565b809150509295509295909350565b60008060408385031215613a3657600080fd5b82356001600160401b0380821115613a4d57600080fd5b613a5986838701613642565b93506020850135915080821115613a6f57600080fd5b50613a7c8582860161369d565b9150509250929050565b60208152600060018060a01b038084511660208401528060208501511660408401525060408301516060830152606083015160c06080840152613acc60e0840182613876565b90506080840151151560a084015260a0840151151560c08401528091505092915050565b60008060408385031215613b0357600080fd5b82356001600160401b0380821115613b1a57600080fd5b613a598683870161369d565b60008060008060808587031215613b3c57600080fd5b84356001600160401b0380821115613b5357600080fd5b613b5f8883890161369d565b95506020870135915080821115613b7557600080fd5b50613b828782880161369d565b93505060408501359150613b98606086016135b9565b905092959194509250565b60008060408385031215613bb657600080fd5b8235915060208301356001600160401b03811115613bd357600080fd5b613a7c8582860161369d565b60008060408385031215613bf257600080fd5b613bfb836135b9565b9150602083013560028110613c0f57600080fd5b809150509250929050565b600080600060608486031215613c2f57600080fd5b8335925060208401356001600160401b0380821115613c4d57600080fd5b613c598783880161369d565b93506040860135915080821115613c6f57600080fd5b50613c7c8682870161369d565b9150509250925092565b60008060408385031215613c9957600080fd5b82359150613ca9602084016135b9565b90509250929050565b600060208284031215613cc457600080fd5b612339826135b9565b60008060408385031215613ce057600080fd5b613ce9836135b9565b9150613ca9602084016135b9565b60008060008060808587031215613d0d57600080fd5b8435935060208501356001600160401b0380821115613d2b57600080fd5b613d378883890161369d565b9450613d45604088016135b9565b93506060870135915080821115613d5b57600080fd5b50613d688782880161369d565b91505092959194509250565b600080600060608486031215613d8957600080fd5b8335925060208401356001600160401b03811115613da657600080fd5b613db28682870161369d565b925050613dc1604085016135b9565b90509250925092565b600080600060608486031215613ddf57600080fd5b613de8846135b9565b9250613df6602085016135b9565b9150613dc1604085016135b9565b60008060408385031215613e1757600080fd5b82356001600160401b03811115613e2d57600080fd5b613e398582860161369d565b925050613ca9602084016135b9565b60008251613e5a818460208701613852565b9190910192915050565b600181811c90821680613e7857607f821691505b602082108103613e9857634e487b7160e01b600052602260045260246000fd5b50919050565b60008154613eab81613e64565b60018281168015613ec35760018114613ed857613f07565b60ff1984168752821515830287019450613f07565b8560005260208060002060005b85811015613efe5781548a820152908401908201613ee5565b50505082870194505b5050505092915050565b60006123398284613e9e565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761255d5761255d613f1d565b600082613f6757634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561255d5761255d613f1d565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613fa757600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b8082018082111561255d5761255d613f1d565b601f8211156120e757600081815260208120601f850160051c81016020861015613ffe5750805b601f850160051c820191505b8181101561401d5782815560010161400a565b505050505050565b81516001600160401b0381111561403e5761403e613550565b6140528161404c8454613e64565b84613fd7565b602080601f831160018114614087576000841561406f5750858301515b600019600386901b1c1916600185901b17855561401d565b600085815260208120601f198616915b828110156140b657888601518255948401946001909101908401614097565b50858210156140d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600990820152682737ba1037bbb732b960b91b604082015260600190565b60408152600f60408201526e0c6d8dee6ca40dee0cadc90c2e8c6d608b1b60608201526080602082015260006123396080830184613876565b6020808252601d908201527f506c65617365207375626d6974207468652061736b696e672066656521000000604082015260600190565b6000600182016141d7576141d7613f1d565b5060010190565b6020808252601f908201527f546869732053756273637269626520497320756e617661696c61626c65202100604082015260600190565b60006020828403121561422757600080fd5b815161233981613983565b602081526000612339602083018461387656fe8dbda374896f6318363c99c211f864696d7a0b03a4bb4aa9c94d88324497ea14a2646970667358221220caa28bde9535089fb176882e92c5370f0a5851848bdf8b720cadf35d2847dfe164736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102275760003560e01c80638da5cb5b11610130578063cd9e09b4116100b8578063f1ba40721161007c578063f1ba407214610651578063f2fde38b146106cc578063f4d5c893146106df578063fd1b9a4714610718578063fd73a3881461072b57600080fd5b8063cd9e09b4146105f0578063d037f95414610603578063dd63266a14610618578063dfdb5e8b1461062b578063e7d683331461063e57600080fd5b8063b115f498116100ff578063b115f49814610552578063b25bc8a11461055b578063b38dd7a4146105b7578063c8b9d84f146105ca578063cd575291146105dd57600080fd5b80638da5cb5b1461048e578063a512ac14146104a5578063ac9464e11461052c578063b06b03681461053f57600080fd5b80634e12955a116101b35780636292e2a6116101825780636292e2a61461041f57806365907f7e14610432578063715018a61461046b5780638129fc1c1461047357806389656f0b1461047b57600080fd5b80634e12955a1461030857806356d0b1b7146103ce57806358e9aaa6146103e1578063607dbcdb1461040c57600080fd5b80632d3a6c45116101fa5780632d3a6c451461029c578063381c6e42146102af578063425abe51146102c2578063433ba9c8146102d55780634c9bc8c1146102e857600080fd5b80630491bd1b1461022c5780631c027d7a146102545780631e606fdb146102675780632bc3853114610287575b600080fd5b61023f61023a36600461370c565b610733565b60405190151581526020015b60405180910390f35b61023f6102623660046137ca565b610d0d565b61027a6102753660046137e3565b610e02565b60405161024b91906138a2565b61029a6102953660046137e3565b61104d565b005b61029a6102aa3660046137e3565b611127565b61023f6102bd366004613991565b611227565b61029a6102d03660046137e3565b61151d565b61029a6102e3366004613a23565b6115a1565b6102fb6102f63660046137e3565b61167a565b60405161024b9190613a86565b610389610316366004613af0565b8151602081840181018051603f8252928201948201949094209190935281518083018401805192815290840192909301919091209152805460018201546002830154600384015460048501546005909501546001600160a01b0394851695939460ff808516956101009095041693911687565b604080516001600160a01b0398891681526020810197909752941515948601949094529115156060850152608084015260a083015290911660c082015260e00161024b565b61029a6103dc3660046137e3565b6117b6565b6033546103f4906001600160a01b031681565b6040516001600160a01b03909116815260200161024b565b61029a61041a366004613b26565b6119e2565b61023f61042d366004613ba3565b611c2e565b61045d610440366004613bdf565b603c60209081526000928352604080842090915290825290205481565b60405190815260200161024b565b61029a611f31565b61029a611f45565b61029a610489366004613ba3565b612007565b6000546201000090046001600160a01b03166103f4565b6104f86104b33660046137e3565b8051602081830181018051603e82529282019190930120915280546001820154600283015460038401546004909401546001600160a01b039384169492939192911685565b604080516001600160a01b03968716815260208101959095528401929092526060830152909116608082015260a00161024b565b61023f61053a366004613c1a565b6120ec565b6103f461054d3660046137ca565b612340565b61045d60325481565b61056e6105693660046137e3565b61236a565b60405161024b919081516001600160a01b039081168252602080840151908301526040808401519083015260608084015190830152608092830151169181019190915260a00190565b61023f6105c5366004613c86565b612419565b61045d6105d8366004613cb2565b612563565b61045d6105eb366004613ccd565b6125a5565b61023f6105fe366004613cf7565b612613565b336000908152603d602052604090205461045d565b61023f610626366004613c1a565b612a6a565b61023f610639366004613d74565b612dbd565b61045d61064c366004613dca565b612ef5565b61066461065f366004613af0565b612f73565b60405161024b92919082516001600160a01b039081168252602080850151908301526040808501511515908301526060808501511515908301526080808501519083015260a0848101519083015260c093840151169281019290925260e08201526101000190565b61029a6106da366004613cb2565b6130cd565b61045d6106ed366004613e04565b8151602081840181018051604080835293830195830195909520949052929092526000908152205481565b61045d610726366004613cb2565b613143565b61045d613163565b6000828051906020012060398460405161074d9190613e48565b908152602001604051809103902060050160405161076b9190613f11565b6040518091039020036107d05760405162461bcd60e51b815260206004820152602260248201527f54686973204f70656e486174636b20686173206265656e207265676973746572604482015261032160f51b60648201526084015b60405180910390fd5b60006127106107dd613163565b6107e79089613f33565b6107f19190613f4a565b905060006107ff8289613f6c565b9050600061080e600284613f4a565b9050600061081c8285613f6c565b9050898b60028151811061083257610832613f7f565b60209081029190910101516040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f95565b10156108ec5760405162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e742062616c6e6163652160581b60448201526064016107c7565b61092633308c8e60028151811061090557610905613f7f565b60200260200101516001600160a01b0316613179909392919063ffffffff16565b80603c60008d60028151811061093e5761093e613f7f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600060018081111561097a5761097a613fae565b600181111561098b5761098b613fae565b8152602001908152602001600020546109a49190613fc4565b603c60008d6002815181106109bb576109bb613f7f565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006001808111156109f7576109f7613fae565b6001811115610a0857610a08613fae565b81526020019081526020016000208190555081603c60008d600281518110610a3257610a32613f7f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000806001811115610a6e57610a6e613fae565b6001811115610a7f57610a7f613fae565b815260200190815260200160002054610a989190613fc4565b603c60008d600281518110610aaf57610aaf613f7f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000806001811115610aeb57610aeb613fae565b6001811115610afc57610afc613fae565b8152602001908152602001600020819055506040518061014001604052808481526020018a8152602001898152602001336001600160a01b031681526020018c600181518110610b4e57610b4e613f7f565b60200260200101516001600160a01b03168152602001888152602001610b714290565b81526020018781526020016001151581526020018c600281518110610b9857610b98613f7f565b60200260200101516001600160a01b0316815250603988604051610bbc9190613e48565b9081526020016040518091039020600082015181600001556020820151816001019080519060200190610bf09291906134f0565b5060408201518051610c0c9160028401916020909101906134f0565b5060608201516003820180546001600160a01b039283166001600160a01b031991821617909155608084015160048401805491909316911617905560a08201516005820190610c5b9082614025565b5060c0820151600682015560e082015160078201556101008083015160089092018054610120909401516001600160a01b0316909102610100600160a81b0319921515929092166001600160a81b031990931692909217179055604080518181526010818301526f086e4cac2e8ca40dccaee4090c2e8c6d60831b6060820152602081018c905290516000805160206142468339815191529181900360800190a15060019a9950505050505050505050565b6000610d176131e4565b60008211610d625760405162461bcd60e51b815260206004820152601860248201527774686520666565206e756d6265722069732077726f6e672160401b60448201526064016107c7565b6019821115610dae5760405162461bcd60e51b815260206004820152601860248201527774686520666565206e756d6265722069732077726f6e672160401b60448201526064016107c7565b603482905560408051818152600f818301526e6368616e676564207468652066656560881b60608201526020810184905290516000805160206142468339815191529181900360800190a15060015b919050565b610e7560405180610140016040528060008152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160608152602001600081526020016000815260200160001515815260200160006001600160a01b031681525090565b603982604051610e859190613e48565b9081526020016040518091039020604051806101400160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020018280548015610ef857602002820191906000526020600020905b815481526020019060010190808311610ee4575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610f5057602002820191906000526020600020905b815481526020019060010190808311610f3c575b505050918352505060038201546001600160a01b0390811660208301526004830154166040820152600582018054606090920191610f8d90613e64565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb990613e64565b80156110065780601f10610fdb57610100808354040283529160200191611006565b820191906000526020600020905b815481529060010190602001808311610fe957829003601f168201915b5050509183525050600682015460208201526007820154604082015260089091015460ff81161515606083015261010090046001600160a01b031660809091015292915050565b600054610100900460ff161580801561106d5750600054600160ff909116105b806110875750303b158015611087575060005460ff166001145b6110a35760405162461bcd60e51b81526004016107c7906140e4565b6000805460ff1916600117905580156110c6576000805461ff0019166101001790555b60366110d28382614025565b50601e603255600a6034558015611123576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b806039816040516111389190613e48565b90815260405190819003602001902060030154336001600160a01b03909116146111745760405162461bcd60e51b81526004016107c790614132565b816039816040516111859190613e48565b9081526040519081900360200190206008015460ff166111b75760405162461bcd60e51b81526004016107c790614132565b60006039846040516111c99190613e48565b908152604051908190036020018120600801805492151560ff19909316929092179091557f0fdb92177627c58bc2b166040cabcd29dc886024d10328c479d2f0337810579a9061121a908590614155565b60405180910390a1505050565b600061123383336125a5565b8611156112525760405162461bcd60e51b81526004016107c79061418e565b603e856040516112629190613e48565b90815260200160405180910390206002015461127b4290565b11156112995760405162461bcd60e51b81526004016107c79061418e565b336001600160a01b0316603e866040516112b39190613e48565b908152604051908190036020019020546001600160a01b0316146113195760405162461bcd60e51b815260206004820152601e60248201527f5468697320537562736372696265204973204e6f74206f776e6572202021000060448201526064016107c7565b603f856040516113299190613e48565b9081526020016040518091039020846040516113459190613e48565b9081526040519081900360200190206002015460ff1615156001036113ac5760405162461bcd60e51b815260206004820152601a60248201527f546869732053756273637269626520497320616374697665202100000000000060448201526064016107c7565b6040518060e00160405280336001600160a01b0316815260200187815260200160011515815260200183151581526020016113e8603254613245565b8152602001428152602001846001600160a01b0316815250603f866040516114109190613e48565b90815260200160405180910390208560405161142c9190613e48565b908152604080519182900360209081018320845181546001600160a01b039182166001600160a01b031991821617835592860151600183015592850151600282018054606088015115156101000261ff00199315159390931661ffff19909116179190911790556080850151600382015560a0850151600482015560c09094015160059094018054949092169316929092179091556000805160206142468339815191529061150990889060408082526010908201526f6372656174652053756273637269626560801b6060820152602081019190915260800190565b60405180910390a150600195945050505050565b6115256131e4565b806039816040516115369190613e48565b9081526040519081900360200190206008015460ff166115685760405162461bcd60e51b81526004016107c790614132565b600060398360405161157a9190613e48565b908152604051908190036020019020600801805491151560ff199092169190911790555050565b806039816040516115b29190613e48565b90815260405190819003602001902060030154336001600160a01b03909116146115ee5760405162461bcd60e51b81526004016107c790614132565b816039816040516115ff9190613e48565b9081526040519081900360200190206008015460ff166116315760405162461bcd60e51b81526004016107c790614132565b60005b84518110156116735761166085828151811061165257611652613f7f565b602002602001015185611c2e565b508061166b816141c5565b915050611634565b5050505050565b6040805160c0810182526000808252602082018190528183018190526060808301526080820181905260a08201529051603a906116b8908490613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061170d90613e64565b80601f016020809104026020016040519081016040528092919081815260200182805461173990613e64565b80156117865780601f1061175b57610100808354040283529160200191611786565b820191906000526020600020905b81548152906001019060200180831161176957829003601f168201915b50505091835250506004919091015460ff8082161515602084015261010090910416151560409091015292915050565b336001600160a01b0316603a826040516117d09190613e48565b908152604051908190036020019020546001600160a01b0316036118065760405162461bcd60e51b81526004016107c7906141de565b603a816040516118169190613e48565b9081526040519081900360200190206004015460ff16151560000361184d5760405162461bcd60e51b81526004016107c7906141de565b6000603a8260405161185f9190613e48565b908152604051908190036020018120600401805492151560ff1990931692909217909155600190603a90611894908490613e48565b908152602001604051809103902060040160016101000a81548160ff0219169083151502179055506000603a826040516118ce9190613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061192390613e64565b80601f016020809104026020016040519081016040528092919081815260200182805461194f90613e64565b801561199c5780601f106119715761010080835404028352916020019161199c565b820191906000526020600020905b81548152906001019060200180831161197f57829003601f168201915b50505091835250506004919091015460ff80821615156020808501919091526101009092041615156040928301528201518251918301519293506111239290919061325f565b60366040516020016119f49190613f11565b6040516020818303038152906040528051906020012083604051602001611a1b9190613e48565b6040516020818303038152906040528051906020012014611a745760405162461bcd60e51b8152602060048201526013602482015272151a1a5cc818dbd919481b9bdd08199bdd5b99606a1b60448201526064016107c7565b8380519060200120603a85604051611a8c9190613e48565b9081526020016040518091039020600301604051611aaa9190613f11565b604051809103902003611aff5760405162461bcd60e51b815260206004820152601e60248201527f54686973204a7564676520686173206265656e2072656769737465726420000060448201526064016107c7565b6040805160c0810182523381526001600160a01b03831660208201528082018490526060810186905260016080820152600060a08201529051603a90611b46908790613e48565b9081526040805160209281900383019020835181546001600160a01b03199081166001600160a01b0392831617835593850151600183018054909516911617909255820151600282015560608201516003820190611ba49082614025565b5060808201516004909101805460a09093015115156101000261ff00199215159290921661ffff1990931692909217179055611be1813384613273565b604080518181526010818301526f02732bb90253ab233b29030b23232b2160851b60608201526020810184905290516000805160206142468339815191529181900360800190a150505050565b600081603981604051611c419190613e48565b90815260405190819003602001902060030154336001600160a01b0390911614611c7d5760405162461bcd60e51b81526004016107c790614132565b82603981604051611c8e9190613e48565b9081526040519081900360200190206008015460ff16611cc05760405162461bcd60e51b81526004016107c790614132565b6000603985604051611cd29190613e48565b9081526040519081900360200190206002810154909150861115611d2f5760405162461bcd60e51b815260206004820152601460248201527370686173655f696e6465782069732077726f6e6760601b60448201526064016107c7565b600281018054611d40906001613fc4565b815460018181018455600093845260209093200155600882015460048301549183018054611d9c936001600160a01b036101009094048416931691908a908110611d8c57611d8c613f7f565b906000526020600020015461325f565b60048101546040805181815260098183015268030b1b1b2b83a37b9160bd1b60608201526001600160a01b039092166020830152517f29cceaa768a511b1433880b50fe557bb0332f2a343551e6bfe919a946950a9d89181900360800190a1600080516020614246833981519152816001018781548110611e1f57611e1f613f7f565b9060005260206000200154604051611e58919060408082526004908201526303830bc960e51b6060820152602081019190915260800190565b60405180910390a1600881015460408051818152600a81830152693130b9b2afba37b5b2b760b11b60608201526101009092046001600160a01b03166020830152517f29cceaa768a511b1433880b50fe557bb0332f2a343551e6bfe919a946950a9d8916080908290030190a17f0fdb92177627c58bc2b166040cabcd29dc886024d10328c479d2f0337810579a604051611509906040808252600c908201526b030baba3437b9103830b4b2160a51b606082015260806020820181905260069082015265185b5bdd5b9d60d21b60a082015260c00190565b611f396131e4565b611f436000613288565b565b600054610100900460ff1615808015611f655750600054600160ff909116105b80611f7f5750303b158015611f7f575060005460ff166001145b611f9b5760405162461bcd60e51b81526004016107c7906140e4565b6000805460ff191660011790558015611fbe576000805461ff0019166101001790555b8015612004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b61200f6131e4565b806039816040516120209190613e48565b9081526040519081900360200190206008015460ff166120525760405162461bcd60e51b81526004016107c790614132565b60006039836040516120649190613e48565b90815260405190819003602001902060028101549091508411156120885750505050565b600281018054612099906001613fc4565b8154600181810184556000938452602090932001556008820154600483015491830180546120e5936001600160a01b0361010090940484169316919088908110611d8c57611d8c613f7f565b505b505050565b600080603f846040516120ff9190613e48565b90815260200160405180910390208360405161211b9190613e48565b908152604051908190036020019020600501546001600160a01b0316905061214381336125a5565b8511156121625760405162461bcd60e51b81526004016107c79061418e565b603e846040516121729190613e48565b90815260200160405180910390206002015461218b4290565b11156121a95760405162461bcd60e51b81526004016107c79061418e565b603f846040516121b99190613e48565b9081526020016040518091039020836040516121d59190613e48565b9081526040519081900360200190206002015460ff6101009091041615156000036122cb57612205813387613273565b846040856040516122169190613e48565b90815260408051602092819003830190206001600160a01b038516600090815292529020546122459190613fc4565b6040856040516122559190613e48565b90815260408051602092819003830181206001600160a01b0386166000908152908452829020939093558083526010908301526f7375626d69742053756273637269626560801b606083015281018690526000805160206142468339815191529060800160405180910390a16001915050612339565b603f846040516122db9190613e48565b9081526020016040518091039020836040516122f79190613e48565b9081526020016040518091039020600301546123104290565b111561232e5760405162461bcd60e51b81526004016107c79061418e565b612205813387613273565b9392505050565b6035818154811061235057600080fd5b6000918252602090912001546001600160a01b0316905081565b6123ae6040518060a0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b603e826040516123be9190613e48565b90815260408051918290036020908101832060a08401835280546001600160a01b0390811685526001820154928501929092526002810154928401929092526003820154606084015260049091015416608082015292915050565b60006124236131e4565b6001600160a01b0382166000908152603c60209081526040808320600184529091529020548311156124975760405162461bcd60e51b815260206004820152601960248201527f22496e73756666696369656e7420696e76656e746f727921220000000000000060448201526064016107c7565b6001600160a01b0382166000908152603c60209081526040808320600184529091529020546124c7908490613f6c565b6001600160a01b038381166000908152603c60209081526040808320600184529091528120929092559054612505918491620100009004168561325f565b604080518181526019818301527f61646d696e20776974686472617720746865205265776172640000000000000060608201526020810185905290516000805160206142468339815191529181900360800190a15060015b92915050565b6001600160a01b0381166000908152603c6020526040812081805b600181111561258f5761258f613fae565b8152602001908152602001600020549050919050565b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa1580156125ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190613f95565b600080603a856040516126269190613e48565b90815260408051918290036020908101832060c08401835280546001600160a01b0390811685526001820154169184019190915260028101549183019190915260038101805460608401919061267b90613e64565b80601f01602080910402602001604051908101604052809291908181526020018280546126a790613e64565b80156126f45780601f106126c9576101008083540402835291602001916126f4565b820191906000526020600020905b8154815290600101906020018083116126d757829003601f168201915b50505091835250506004919091015460ff80821615156020840152610100909104161515604090910152608081015190915015156000036127775760405162461bcd60e51b815260206004820152601d60248201527f686973205f6a75646765496420497320756e617661696c61626c65202100000060448201526064016107c7565b6103e88611156127d55760405162461bcd60e51b815260206004820152602360248201527f596f752063616e206e6f74207769746864726177206d6f7265207468616e206d60448201526261782160e81b60648201526084016107c7565b80516001600160a01b0316331461282e5760405162461bcd60e51b815260206004820152601860248201527f4a757374206a756467652063616e20776974686472617721000000000000000060448201526064016107c7565b42336000908152603d602052604090205411156128975760405162461bcd60e51b815260206004820152602160248201527f596f752073686f756c6420206261636b20696e20382064617973206c617465726044820152600160fd1b60648201526084016107c7565b6001600160a01b0384166000908152603c6020908152604080832083805290915290205486111561290a5760405162461bcd60e51b815260206004820152601d60248201527f4578636565642074686520616d6f756e74206f6620726577617264732100000060448201526064016107c7565b603660405160200161291c9190613f11565b60405160208183030381529060405280519060200120836040516020016129439190613e48565b604051602081830303815290604052805190602001201461299c5760405162461bcd60e51b8152602060048201526013602482015272151a1a5cc818dbd919481b9bdd08199bdd5b99606a1b60448201526064016107c7565b6001600160a01b0384166000908152603c602090815260408083208380529091529020546129cb908790613f6c565b6001600160a01b0385166000908152603c6020908152604080832083805290915290205580516129fd9085908861325f565b612a076008613245565b336000908152603d602052604090819020919091555160008051602061424683398151915290611509908890604080825260159082015274129d5919d94815da5d1a191c985dc814995dd85c99605a1b6060820152602081019190915260800190565b6000603f83604051612a7c9190613e48565b908152602001604051809103902082604051612a989190613e48565b9081526040519081900360200190206002015460ff161515600003612acf5760405162461bcd60e51b81526004016107c7906141de565b604083604051612adf9190613e48565b90815260200160405180910390206000603f85604051612aff9190613e48565b908152602001604051809103902084604051612b1b9190613e48565b9081526040805160209281900383019020600501546001600160a01b03168352908201929092520160002054841115612b665760405162461bcd60e51b81526004016107c79061418e565b336001600160a01b0316603f84604051612b809190613e48565b908152602001604051809103902083604051612b9c9190613e48565b908152604051908190036020019020546001600160a01b031614612bd25760405162461bcd60e51b81526004016107c7906141de565b83604084604051612be39190613e48565b90815260200160405180910390206000603f86604051612c039190613e48565b908152602001604051809103902085604051612c1f9190613e48565b9081526040805160209281900383019020600501546001600160a01b03168352908201929092520160002054612c559190613f6c565b604084604051612c659190613e48565b90815260200160405180910390206000603f86604051612c859190613e48565b908152602001604051809103902085604051612ca19190613e48565b9081526040805160209281900383019020600501546001600160a01b031683529082019290925281016000209190915551612d6690603f90612ce4908690613e48565b908152602001604051809103902083604051612d009190613e48565b908152604051908190036020018120600501546001600160a01b031690603f90612d2b908790613e48565b908152602001604051809103902084604051612d479190613e48565b908152604051908190036020019020546001600160a01b03168661325f565b60408051818152601191810191909152700776974686472617720537562736372697607c1b606082015260208101859052600080516020614246833981519152906080015b60405180910390a15060019392505050565b6000612dc982336125a5565b841115612de85760405162461bcd60e51b81526004016107c79061418e565b612df3823386613273565b6040518060a00160405280336001600160a01b03168152602001858152602001612e1e603254613245565b8152602001428152602001836001600160a01b0316815250603e84604051612e469190613e48565b908152604080519182900360209081018320845181546001600160a01b039182166001600160a01b031991821617835592860151600183015592850151600282015560608501516003820155608090940151600490940180549490921693169290921790915560008051602061424683398151915290612dab908690604080825260119082015270726571756573742053756273637269626560781b6060820152602081019190915260800190565b604051636eb1769f60e11b81526001600160a01b03838116600483015282811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612f47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6b9190613f95565b949350505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526000603f84604051612fbe9190613e48565b908152602001604051809103902083604051612fda9190613e48565b9081526020016040518091039020604085604051612ff89190613e48565b90815260200160405180910390206000603f876040516130189190613e48565b9081526020016040518091039020866040516130349190613e48565b90815260408051602092819003830190206005908101546001600160a01b0390811685528484019590955292810160002054815160e081018352865486168152600187015493810193909352600286015460ff80821615159385019390935261010090049091161515606083015260038501546080830152600485015460a0830152939091015490911660c08201529590945092505050565b6130d56131e4565b6001600160a01b03811661313a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c7565b61200481613288565b6001600160a01b0381166000908152603c6020526040812081600161257e565b600060345460646131749190613f33565b905090565b6040516001600160a01b03808516602483015283166044820152606481018290526120e59085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526132e3565b6000546001600160a01b0362010000909104163314611f435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107c7565b6000806132558362015180613f33565b6123399042613fc4565b6120e76001600160a01b03841683836133b5565b6120e76001600160a01b038416833084613179565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b6000613338826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133e59092919063ffffffff16565b8051909150156120e757808060200190518101906133569190614215565b6120e75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107c7565b6040516001600160a01b0383166024820152604481018290526120e790849063a9059cbb60e01b906064016131ad565b6060612f6b848460008585843b61343e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107c7565b600080866001600160a01b0316858760405161345a9190613e48565b60006040518083038185875af1925050503d8060008114613497576040519150601f19603f3d011682016040523d82523d6000602084013e61349c565b606091505b50915091506134ac8282866134b7565b979650505050505050565b606083156134c6575081612339565b8251156134d65782518084602001fd5b8160405162461bcd60e51b81526004016107c79190614232565b82805482825590600052602060002090810192821561352b579160200282015b8281111561352b578251825591602001919060010190613510565b5061353792915061353b565b5090565b5b80821115613537576000815560010161353c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561358e5761358e613550565b604052919050565b60006001600160401b038211156135af576135af613550565b5060051b60200190565b80356001600160a01b0381168114610dfd57600080fd5b600082601f8301126135e157600080fd5b813560206135f66135f183613596565b613566565b82815260059290921b8401810191818101908684111561361557600080fd5b8286015b848110156136375761362a816135b9565b8352918301918301613619565b509695505050505050565b600082601f83011261365357600080fd5b813560206136636135f183613596565b82815260059290921b8401810191818101908684111561368257600080fd5b8286015b848110156136375780358352918301918301613686565b600082601f8301126136ae57600080fd5b81356001600160401b038111156136c7576136c7613550565b6136da601f8201601f1916602001613566565b8181528460208386010111156136ef57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561372557600080fd5b86356001600160401b038082111561373c57600080fd5b6137488a838b016135d0565b975060208901359650604089013591508082111561376557600080fd5b6137718a838b01613642565b9550606089013591508082111561378757600080fd5b6137938a838b01613642565b945060808901359150808211156137a957600080fd5b506137b689828a0161369d565b92505060a087013590509295509295509295565b6000602082840312156137dc57600080fd5b5035919050565b6000602082840312156137f557600080fd5b81356001600160401b0381111561380b57600080fd5b612f6b8482850161369d565b600081518084526020808501945080840160005b838110156138475781518752958201959082019060010161382b565b509495945050505050565b60005b8381101561386d578181015183820152602001613855565b50506000910152565b6000815180845261388e816020860160208601613852565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516101408060408501526138cb610160850183613817565b91506040850151601f19808685030160608701526138e98483613817565b93506060870151915061390760808701836001600160a01b03169052565b60808701516001600160a01b03811660a0880152915060a08701519150808685030160c0870152506139398382613876565b92505060c085015160e085015260e085015161010081818701528087015191505061012061396a8187018315159052565b909501516001600160a01b031693019290925250919050565b801515811461200457600080fd5b600080600080600060a086880312156139a957600080fd5b8535945060208601356001600160401b03808211156139c757600080fd5b6139d389838a0161369d565b955060408801359150808211156139e957600080fd5b506139f68882890161369d565b935050613a05606087016135b9565b91506080860135613a1581613983565b809150509295509295909350565b60008060408385031215613a3657600080fd5b82356001600160401b0380821115613a4d57600080fd5b613a5986838701613642565b93506020850135915080821115613a6f57600080fd5b50613a7c8582860161369d565b9150509250929050565b60208152600060018060a01b038084511660208401528060208501511660408401525060408301516060830152606083015160c06080840152613acc60e0840182613876565b90506080840151151560a084015260a0840151151560c08401528091505092915050565b60008060408385031215613b0357600080fd5b82356001600160401b0380821115613b1a57600080fd5b613a598683870161369d565b60008060008060808587031215613b3c57600080fd5b84356001600160401b0380821115613b5357600080fd5b613b5f8883890161369d565b95506020870135915080821115613b7557600080fd5b50613b828782880161369d565b93505060408501359150613b98606086016135b9565b905092959194509250565b60008060408385031215613bb657600080fd5b8235915060208301356001600160401b03811115613bd357600080fd5b613a7c8582860161369d565b60008060408385031215613bf257600080fd5b613bfb836135b9565b9150602083013560028110613c0f57600080fd5b809150509250929050565b600080600060608486031215613c2f57600080fd5b8335925060208401356001600160401b0380821115613c4d57600080fd5b613c598783880161369d565b93506040860135915080821115613c6f57600080fd5b50613c7c8682870161369d565b9150509250925092565b60008060408385031215613c9957600080fd5b82359150613ca9602084016135b9565b90509250929050565b600060208284031215613cc457600080fd5b612339826135b9565b60008060408385031215613ce057600080fd5b613ce9836135b9565b9150613ca9602084016135b9565b60008060008060808587031215613d0d57600080fd5b8435935060208501356001600160401b0380821115613d2b57600080fd5b613d378883890161369d565b9450613d45604088016135b9565b93506060870135915080821115613d5b57600080fd5b50613d688782880161369d565b91505092959194509250565b600080600060608486031215613d8957600080fd5b8335925060208401356001600160401b03811115613da657600080fd5b613db28682870161369d565b925050613dc1604085016135b9565b90509250925092565b600080600060608486031215613ddf57600080fd5b613de8846135b9565b9250613df6602085016135b9565b9150613dc1604085016135b9565b60008060408385031215613e1757600080fd5b82356001600160401b03811115613e2d57600080fd5b613e398582860161369d565b925050613ca9602084016135b9565b60008251613e5a818460208701613852565b9190910192915050565b600181811c90821680613e7857607f821691505b602082108103613e9857634e487b7160e01b600052602260045260246000fd5b50919050565b60008154613eab81613e64565b60018281168015613ec35760018114613ed857613f07565b60ff1984168752821515830287019450613f07565b8560005260208060002060005b85811015613efe5781548a820152908401908201613ee5565b50505082870194505b5050505092915050565b60006123398284613e9e565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761255d5761255d613f1d565b600082613f6757634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561255d5761255d613f1d565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613fa757600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b8082018082111561255d5761255d613f1d565b601f8211156120e757600081815260208120601f850160051c81016020861015613ffe5750805b601f850160051c820191505b8181101561401d5782815560010161400a565b505050505050565b81516001600160401b0381111561403e5761403e613550565b6140528161404c8454613e64565b84613fd7565b602080601f831160018114614087576000841561406f5750858301515b600019600386901b1c1916600185901b17855561401d565b600085815260208120601f198616915b828110156140b657888601518255948401946001909101908401614097565b50858210156140d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600990820152682737ba1037bbb732b960b91b604082015260600190565b60408152600f60408201526e0c6d8dee6ca40dee0cadc90c2e8c6d608b1b60608201526080602082015260006123396080830184613876565b6020808252601d908201527f506c65617365207375626d6974207468652061736b696e672066656521000000604082015260600190565b6000600182016141d7576141d7613f1d565b5060010190565b6020808252601f908201527f546869732053756273637269626520497320756e617661696c61626c65202100604082015260600190565b60006020828403121561422757600080fd5b815161233981613983565b602081526000612339602083018461387656fe8dbda374896f6318363c99c211f864696d7a0b03a4bb4aa9c94d88324497ea14a2646970667358221220caa28bde9535089fb176882e92c5370f0a5851848bdf8b720cadf35d2847dfe164736f6c63430008110033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.