Source Code
Overview
S Balance
S Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 279227 | 411 days ago | IN | 0 S | 0.00012319 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PairFactory
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/**
*Submitted for verification at SonicScan.org on 2025-01-04
*/
/**
*Submitted for verification at basescan.org on 2024-05-16
*/
/**v3.6.0
*0xd7627edf607c49f525212fc09d650a91a9b222e1
*Submitted for verification at basescan.org on 2023-10-04
*/
/**0x653ce153d56f749671d42d58b749d02fd9ad3414
*v3.0.1
*Submitted for verification at basescan.org on 2023-09-23
*/
/**
*v3.0.0
*0xc295f619afc2b8543d91c8970ea4c0726f197250
*Submitted for verification at basescan.org on 2023-09-19
*/
/**
*v1.3.11
*0x8db550677053f2ca3d3bf677cb4e06cc10511958
*Submitted for verification at FtmScan.com on 2023-02-21
*/
/**
*v1.1.0
*0xc9ab1ab21358f4fc36cbbbe27f3b3ead423ec33b
*Submitted for verification at FtmScan.com on 2022-11-03
*/
/**
* EQUALIZER EXCHANGE
* The New Liquidity Hub of XChain Decentralized Finance!
* https://equalizer.exchange (Dapp)
* https://discord.gg/MaMhbgHMby (Community)
*
* SPDX-License-Identifier: UNLICENSED
*
*
* Equalizer v3 Pair Factory
* - Equalizer Stableswap 2pool
* - Equalizer Classic AMM
*
*
*
*
* Version: v3.0.2
* - Allow for universal 0 fees Swaps
*
* Version: v3.0.1
* - Introducing 3-Dimensional Fees
* - 0° : Constant Fees for all pools
* - 1° : Dual Fees - Stablepools vs Volatile pools
* - 2° : Fees Overrides: Custom Fees per Pool
* - 3° : 🆕 Dynamic Fees Overrides using EⅢ Manangerial Approach
* - Fully Dynamic Custom Fees per Pool
* - Real Time Variable/Static/Streaming
* - EⅢ DEX's Dynamic Fee plugins (https://eliteness.network/e3)
* - Volatility-derived Fees adjustment for higher Fee APR
* - Auto-adjusting: Low Volume --> Low Fees, attracts trades
* - Curve.fi's "A-factor ramp" inspired Trade Fee On/Off Ramps
* - Balancer's "Liquidity Bootstrapping Pool" inspired
* Quadratic Fees downramps for fine-grained smooth curves, for
* New pools/IDO/LGE/Fair Launches via Guru Network's SeedR🌱 plugin
*
*
* Version: v3.0.0
* - Fee Precision upto 1 atto of a token
* - Zero-fee Trading for amounts less than PRECISION / getRealFee)
* - Example: For BTC/USDT with 0.01% trade fee & decimals 8 & 6,
* NO FEES is charged on token amounts traded that are
* less than 0.001 USDC or 0.00001 BTC!
*
*
* Version: 1.3.11 (Deployed at v2.0.0)
* - Fees Overrides
* - Per Pair Customizable Fees
* - Introduce `getRealFees(_pool)` as a new Standard
*
*
* Version: 1.3.8
* - Clarify Fee-Claims are once per veNFT per 7 days per pool
* - Real-time Countdown
*
*
* Version: 1.0.2
* - Dual-fee algorithm based on pool stability (correlativity)
* - For lower Stableswap fees & higher Volatile pool fee
* - Independently adjustable `stableFee` & `volatileFee`
*
*
*
* Contributors:
* - Andre Cronje, Solidly.Exchange
* - 543 (Sam), ftm.guru, Eliteness.network & Equalizer.exchange
*
*
*
*/
// File: contracts/interfaces/IPairFactory.sol
pragma solidity 0.8.9;
interface IPairFactory {
function isPaused() external view returns (bool);
function allPairsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function pairCodeHash() external pure returns (bytes32);
function getFee(bool _stable) external view returns(uint256);
function getRealFee(address _pair) external view returns(uint256);
function feesTakers(address) external view returns(address);
function getPair(address tokenA, address token, bool stable) external view returns (address);
function getInitializable() external view returns (address, address, bool);
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair);
}
// File: contracts/interfaces/IPairCallee.sol
pragma solidity 0.8.9;
interface IPairCallee {
function hook(address sender, uint amount0, uint amount1, bytes calldata data) external;
}
// File: contracts/interfaces/IFeeManager.sol
pragma solidity 0.8.9;
interface IFeeManager {
function getFee(address pool) external view returns(uint256);
}
// File: contracts/interfaces/IPairCallee.sol
pragma solidity 0.8.9;
interface IPair {
function stable() external view returns (bool _s);
}
// File: contracts/interfaces/IERC20.sol
pragma solidity 0.8.9;
interface IERC20 {
function totalSupply() external view returns (uint256);
function transfer(address recipient, uint amount) external returns (bool);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function balanceOf(address) external view returns (uint);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
// File: contracts/libraries/Math.sol
pragma solidity 0.8.9;
library Math {
function max(uint a, uint b) internal pure returns (uint) {
return a >= b ? a : b;
}
function min(uint a, uint b) internal pure returns (uint) {
return a < b ? a : b;
}
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
function cbrt(uint256 n) internal pure returns (uint256) { unchecked {
uint256 x = 0;
for (uint256 y = 1 << 255; y > 0; y >>= 3) {
x <<= 1;
uint256 z = 3 * x * (x + 1) + 1;
if (n / y >= z) {
n -= y * z;
x += 1;
}
}
return x;
}}
}
// File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
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. Equivalent to `reinitializer(1)`.
*/
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.
*
* `initializer` is equivalent to `reinitializer(1)`, so 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.
*
* 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.
*/
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.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
}
// File: contracts/PairFees.sol
pragma solidity 0.8.9;
/**
* @title Pair Fees
* @notice used as a 1:1 pair relationship to split out fees, this ensures
* that the curve does not need to be modified for LP shares
*/
contract PairFees is Initializable {
address internal pair; // The pair it is bonded to
address internal token0; // token0 of pair, saved localy and statically for gas optimization
address internal token1; // Token1 of pair, saved localy and statically for gas optimization
function initialize(address _token0, address _token1) public initializer {
pair = msg.sender;
token0 = _token0;
token1 = _token1;
}
function _safeTransfer(address token,address to,uint256 value) internal {
require(token.code.length > 0, "PairFees: invalid token");
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "PairFees: transfer failed");
}
// Allow the pair to transfer fees to users
function claimFeesFor(address recipient, uint amount0, uint amount1) external {
require(msg.sender == pair, "Only pair contract can call");
// forfeit deficits from Fee-on-Transfer tokens
uint _bal0 = IERC20(token0).balanceOf(address(this));
uint _bal1 = IERC20(token1).balanceOf(address(this));
if (amount0 > _bal0) amount0 = _bal0;
if (amount1 > _bal1) amount1 = _bal1;
if (amount0 > 0) _safeTransfer(token0, recipient, amount0);
if (amount1 > 0) _safeTransfer(token1, recipient, amount1);
}
}
// File: contracts/Pair.sol
pragma solidity 0.8.9;
contract Pair is Initializable {
string public name;
string public symbol;
uint8 public constant decimals = 18;
/// @notice Used to denote stable or volatile pair, not immutable since construction happens in the initialize method for CREATE2 deterministic addresses
bool public stable;
uint256 public totalSupply;
mapping(address => mapping (address => uint)) public allowance;
mapping(address => uint) public balanceOf;
bytes32 internal DOMAIN_SEPARATOR;
/// @dev keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 internal constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint) public nonces;
uint256 internal constant MINIMUM_LIQUIDITY = 10**3;
address public token0;
address public token1;
address public fees;
address public factory;
// Structure to capture time period obervations every 30 minutes, used for local oracles
struct Observation {
uint timestamp;
uint reserve0Cumulative;
uint reserve1Cumulative;
}
// Capture oracle reading every 30 minutes
uint constant periodSize = 1800;
Observation[] public observations;
uint internal decimals0;
uint internal decimals1;
uint public reserve0;
uint public reserve1;
uint public blockTimestampLast;
uint public reserve0CumulativeLast;
uint public reserve1CumulativeLast;
// index0 and index1 are used to accumulate fees, this is split out from normal trades to keep the swap "clean"
// this further allows LP holders to easily claim fees for tokens they have/staked
uint public index0;
uint public index1;
// position assigned to each LP to track their current index0 & index1 vs the global position
mapping(address => uint) public supplyIndex0;
mapping(address => uint) public supplyIndex1;
// tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1
mapping(address => uint) public claimable0;
mapping(address => uint) public claimable1;
/// @dev simple re-entrancy check
bool internal _locked;
event Fees(address indexed sender, uint amount0, uint amount1);
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint reserve0, uint reserve1);
event Claim(address indexed sender, address indexed recipient, uint amount0, uint amount1);
event Transfer(address indexed from, address indexed to, uint amount);
event Approval(address indexed owner, address indexed spender, uint amount);
modifier lock() {
require(!_locked, "No re-entrancy");
_locked = true;
_;
_locked = false;
}
function initialize() public initializer {
factory = msg.sender;
(address _token0, address _token1, bool _stable) = IPairFactory(msg.sender).getInitializable();
(token0, token1, stable) = (_token0, _token1, _stable);
PairFees pairFees = new PairFees();
pairFees.initialize(_token0, _token1);
fees = address(pairFees);
if (_stable) {
name = string(abi.encodePacked("Equalizer Stableswap 2pool - ", IERC20(_token0).name(), " paired with ", IERC20(_token1).name()));
symbol = string(abi.encodePacked("s-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
} else {
name = string(abi.encodePacked("Equalizer Classic AMM - ", IERC20(_token0).name(), " paired with ", IERC20(_token1).name()));
symbol = string(abi.encodePacked("v-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
}
decimals0 = 10**IERC20(_token0).decimals();
decimals1 = 10**IERC20(_token1).decimals();
observations.push(Observation(block.timestamp, 0, 0));
}
function observationLength() external view returns (uint) {
return observations.length;
}
function lastObservation() public view returns (Observation memory) {
return observations[observations.length-1];
}
function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1) {
return (decimals0, decimals1, reserve0, reserve1, stable, token0, token1);
}
function tokens() external view returns (address, address) {
return (token0, token1);
}
/// @dev claim accumulated but unclaimed fees (viewable via claimable0 and claimable1)
function claimFees() external returns (uint claimed0, uint claimed1) {
_updateFor(msg.sender);
claimed0 = claimable0[msg.sender];
claimed1 = claimable1[msg.sender];
if (claimed0 > 0 || claimed1 > 0) {
claimable0[msg.sender] = 0;
claimable1[msg.sender] = 0;
PairFees(fees).claimFeesFor(msg.sender, claimed0, claimed1);
emit Claim(msg.sender, msg.sender, claimed0, claimed1);
}
}
/// @dev Accrue fees on token0
function _update0(uint amount) internal {
_safeTransfer(token0, fees, amount); // transfer the fees out to PairFees
uint256 _ratio = amount * 1e18 / totalSupply; // 1e18 adjustment is removed during claim
if (_ratio > 0) {
index0 += _ratio;
}
emit Fees(msg.sender, amount, 0);
}
/// @dev Accrue fees on token1
function _update1(uint amount) internal {
_safeTransfer(token1, fees, amount);
uint256 _ratio = amount * 1e18 / totalSupply;
if (_ratio > 0) {
index1 += _ratio;
}
emit Fees(msg.sender, 0, amount);
}
/**
* @notice This function must be called on any balance changes, otherwise can be used to infinitely claim fees
* Fees are segregated from core funds, so fees can never put liquidity at risk
*/
function _updateFor(address recipient) internal {
uint _supplied = balanceOf[recipient]; // get LP balance of `recipient`
if (_supplied > 0) {
uint _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient
uint _supplyIndex1 = supplyIndex1[recipient];
uint _index0 = index0; // get global index0 for accumulated fees
uint _index1 = index1;
supplyIndex0[recipient] = _index0; // update user current position to global position
supplyIndex1[recipient] = _index1;
uint _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued
uint _delta1 = _index1 - _supplyIndex1;
if (_delta0 > 0) {
uint _share = _supplied * _delta0 / 1e18; // add accrued difference for each supplied token
claimable0[recipient] += _share;
}
if (_delta1 > 0) {
uint _share = _supplied * _delta1 / 1e18;
claimable1[recipient] += _share;
}
} else {
supplyIndex0[recipient] = index0; // new users are set to the default global state
supplyIndex1[recipient] = index1;
}
}
function getReserves() public view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast) {
_reserve0 = reserve0;
_reserve1 = reserve1;
_blockTimestampLast = blockTimestampLast;
}
/// @dev update reserves and, on the first call per block, price accumulators
function _update(uint balance0, uint balance1, uint _reserve0, uint _reserve1) internal {
uint blockTimestamp = block.timestamp;
uint timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
reserve0CumulativeLast += _reserve0 * timeElapsed;
reserve1CumulativeLast += _reserve1 * timeElapsed;
}
Observation memory _point = lastObservation();
timeElapsed = blockTimestamp - _point.timestamp; // compare the last observation with current timestamp, if greater than 30 minutes, record a new event
if (timeElapsed > periodSize) {
observations.push(Observation(blockTimestamp, reserve0CumulativeLast, reserve1CumulativeLast));
}
reserve0 = balance0;
reserve1 = balance1;
blockTimestampLast = blockTimestamp;
emit Sync(reserve0, reserve1);
}
/// @dev produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
function currentCumulativePrices() public view returns (uint reserve0Cumulative, uint reserve1Cumulative, uint blockTimestamp) {
blockTimestamp = block.timestamp;
reserve0Cumulative = reserve0CumulativeLast;
reserve1Cumulative = reserve1CumulativeLast;
// if time has elapsed since the last update on the pair, mock the accumulated price values
(uint _reserve0, uint _reserve1, uint _blockTimestampLast) = getReserves();
if (_blockTimestampLast != blockTimestamp) {
// subtraction overflow is desired
uint timeElapsed = blockTimestamp - _blockTimestampLast;
reserve0Cumulative += _reserve0 * timeElapsed;
reserve1Cumulative += _reserve1 * timeElapsed;
}
}
/// @dev gives the current twap price measured from amountIn * tokenIn gives amountOut
function current(address tokenIn, uint amountIn) external view returns (uint amountOut) {
Observation memory _observation = lastObservation();
(uint reserve0Cumulative, uint reserve1Cumulative,) = currentCumulativePrices();
if (block.timestamp == _observation.timestamp) {
_observation = observations[observations.length-2];
}
uint timeElapsed = block.timestamp - _observation.timestamp;
uint _reserve0 = (reserve0Cumulative - _observation.reserve0Cumulative) / timeElapsed;
uint _reserve1 = (reserve1Cumulative - _observation.reserve1Cumulative) / timeElapsed;
amountOut = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
}
/// @dev as per `current`, however allows user configured granularity, up to the full window size
function quote(address tokenIn, uint amountIn, uint granularity) external view returns (uint amountOut) {
uint [] memory _prices = sample(tokenIn, amountIn, granularity, 1);
uint priceAverageCumulative;
for (uint i = 0; i < _prices.length; i++) {
priceAverageCumulative += _prices[i];
}
return priceAverageCumulative / granularity;
}
/// @dev returns a memory set of twap prices
function prices(address tokenIn, uint amountIn, uint points) external view returns (uint[] memory) {
return sample(tokenIn, amountIn, points, 1);
}
function sample(address tokenIn, uint amountIn, uint points, uint window) public view returns (uint[] memory) {
uint[] memory _prices = new uint[](points);
uint length = observations.length-1;
uint i = length - (points * window);
uint nextIndex = 0;
uint index = 0;
for (; i < length; i+=window) {
nextIndex = i + window;
uint timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp;
uint _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed;
uint _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed;
_prices[index] = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
// index < length; length cannot overflow
unchecked {
index = index + 1;
}
}
return _prices;
}
/**
* @notice this low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks
* standard uniswap v2 implementation
*/
function mint(address to) external lock returns (uint liquidity) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
uint _balance0 = IERC20(token0).balanceOf(address(this));
uint _balance1 = IERC20(token1).balanceOf(address(this));
uint _amount0 = _balance0 - _reserve0;
uint _amount1 = _balance1 - _reserve1;
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(_amount0 * _amount1) - MINIMUM_LIQUIDITY;
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(_amount0 * _totalSupply / _reserve0, _amount1 * _totalSupply / _reserve1);
}
require(liquidity > 0, "ILM"); // Pair: INSUFFICIENT_LIQUIDITY_MINTED
_mint(to, liquidity);
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Mint(msg.sender, _amount0, _amount1);
}
/**
* @notice this low-level function should be called from a contract which performs important safety checks
* standard uniswap v2 implementation
*/
function burn(address to) external lock returns (uint amount0, uint amount1) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
(address _token0, address _token1) = (token0, token1);
uint _balance0 = IERC20(_token0).balanceOf(address(this));
uint _balance1 = IERC20(_token1).balanceOf(address(this));
uint _liquidity = balanceOf[address(this)];
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
amount0 = _liquidity * _balance0 / _totalSupply; // using balances ensures pro-rata distribution
amount1 = _liquidity * _balance1 / _totalSupply; // using balances ensures pro-rata distribution
require(amount0 > 0 && amount1 > 0, "ILB"); // Pair: INSUFFICIENT_LIQUIDITY_BURNED
_burn(address(this), _liquidity);
_safeTransfer(_token0, to, amount0);
_safeTransfer(_token1, to, amount1);
_balance0 = IERC20(_token0).balanceOf(address(this));
_balance1 = IERC20(_token1).balanceOf(address(this));
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Burn(msg.sender, amount0, amount1, to);
}
/// @dev this low-level function should be called from a contract which performs important safety checks
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
require(!IPairFactory(factory).isPaused());
require(amount0Out > 0 || amount1Out > 0, "IOA"); // Pair: INSUFFICIENT_OUTPUT_AMOUNT
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
require(amount0Out < _reserve0 && amount1Out < _reserve1, "IL"); // Pair: INSUFFICIENT_LIQUIDITY
uint _balance0;
uint _balance1;
{ // scope for _token{0,1}, avoids stack too deep errors
(address _token0, address _token1) = (token0, token1);
require(to != _token0 && to != _token1, "IT"); // Pair: INVALID_TO
if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
if (data.length > 0) IPairCallee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans
_balance0 = IERC20(_token0).balanceOf(address(this));
_balance1 = IERC20(_token1).balanceOf(address(this));
}
uint amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0;
uint amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0;
require(amount0In > 0 || amount1In > 0, "IIA"); // Pair: INSUFFICIENT_INPUT_AMOUNT
{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors
(address _token0, address _token1) = (token0, token1);
if (amount0In > 0) _update0(amount0In * IPairFactory(factory).getRealFee(address(this)) / 1e18); // accrue fees for token0 and move them out of pool
if (amount1In > 0) _update1(amount1In * IPairFactory(factory).getRealFee(address(this)) / 1e18); // accrue fees for token1 and move them out of pool
_balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000 (1e18 in V3), but doing balanceOf again as safety check
_balance1 = IERC20(_token1).balanceOf(address(this));
// The curve, either x3y+y3x for stable pools, or x*y for volatile pools
require(_k(_balance0, _balance1) >= _k(_reserve0, _reserve1), "K"); // Pair: K
}
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
/// @dev force balances to match reserves
function skim(address to) external lock {
address _ft = IPairFactory(factory).feesTakers(address(this));
if(_ft != address(0)) { to = _ft; }
(address _token0, address _token1) = (token0, token1);
_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)) - (reserve0));
_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)) - (reserve1));
}
/// @dev force reserves to match balances
function sync() external lock {
_update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
}
function _f(uint x0, uint y) internal pure returns (uint) {
return x0*(y*y/1e18*y/1e18)/1e18+(x0*x0/1e18*x0/1e18)*y/1e18;
}
function _d(uint x0, uint y) internal pure returns (uint) {
return 3*x0*(y*y/1e18)/1e18+(x0*x0/1e18*x0/1e18);
}
function _get_y(uint x0, uint xy, uint y) internal pure returns (uint) {
for (uint i = 0; i < 255; i++) {
uint y_prev = y;
uint k = _f(x0, y);
if (k < xy) {
uint dy = (xy - k)*1e18/_d(x0, y);
y = y + dy;
} else {
uint dy = (k - xy)*1e18/_d(x0, y);
y = y - dy;
}
if (y > y_prev) {
if (y - y_prev <= 1) {
return y;
}
} else {
if (y_prev - y <= 1) {
return y;
}
}
}
return y;
}
function getAmountOut(uint amountIn, address tokenIn) external view returns (uint) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
amountIn -= amountIn * IPairFactory(factory).getRealFee(address(this)) / 1e18; // remove fee from amount received
return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
}
function _getAmountOut(uint amountIn, address tokenIn, uint _reserve0, uint _reserve1) internal view returns (uint) {
if (stable) {
uint xy = _k(_reserve0, _reserve1);
_reserve0 = _reserve0 * 1e18 / decimals0;
_reserve1 = _reserve1 * 1e18 / decimals1;
(uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);
amountIn = tokenIn == token0 ? amountIn * 1e18 / decimals0 : amountIn * 1e18 / decimals1;
uint y = reserveB - _get_y(amountIn+reserveA, xy, reserveB);
return y * (tokenIn == token0 ? decimals1 : decimals0) / 1e18;
} else {
(uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);
return amountIn * reserveB / (reserveA + amountIn);
}
}
function _k(uint x, uint y) internal view returns (uint) {
if (stable) {
uint _x = x * 1e18 / decimals0;
uint _y = y * 1e18 / decimals1;
uint _a = (_x * _y) / 1e18;
uint _b = ((_x * _x) / 1e18 + (_y * _y) / 1e18);
return _a * _b / 1e18; // x3y+y3x >= k
} else {
return x * y; // xy >= k
}
}
function _mint(address dst, uint amount) internal {
_updateFor(dst); // balances must be updated on mint/burn/transfer
totalSupply += amount;
balanceOf[dst] += amount;
emit Transfer(address(0), dst, amount);
}
function _burn(address dst, uint amount) internal {
_updateFor(dst);
totalSupply -= amount;
balanceOf[dst] -= amount;
emit Transfer(dst, address(0), amount);
}
function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
require(deadline >= block.timestamp, "Pair: EXPIRED");
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
block.chainid,
address(this)
)
);
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "Pair: INVALID_SIGNATURE");
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function transfer(address dst, uint amount) external returns (bool) {
_transferTokens(msg.sender, dst, amount);
return true;
}
function transferFrom(address src, address dst, uint amount) external returns (bool) {
address spender = msg.sender;
uint spenderAllowance = allowance[src][spender];
if (spender != src && spenderAllowance != type(uint).max) {
uint newAllowance = spenderAllowance - amount;
allowance[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
_transferTokens(src, dst, amount);
return true;
}
function _transferTokens(address src, address dst, uint amount) internal {
_updateFor(src); // update fee position for src
_updateFor(dst); // update fee position for dst
balanceOf[src] -= amount;
balanceOf[dst] += amount;
emit Transfer(src, dst, amount);
}
function _safeTransfer(address token,address to,uint256 value) internal {
require(token.code.length > 0, "Pair: invalid token");
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "Pair: transfer failed");
}
}
// File: contracts/factories/PairFactory.sol
pragma solidity 0.8.9;
contract PairFactory is Initializable {
bool public isPaused;
address public pauser;
address public pendingPauser;
uint256 public stableFee;
uint256 public volatileFee;
address public feeManager;
address public pendingFeeManager;
mapping(address => mapping(address => mapping(bool => address))) public getPair;
address[] public allPairs;
mapping(address => bool) public isPair; // simplified check if its a pair, given that `stable` flag might not be available in peripherals
address internal _temp0;
address internal _temp1;
bool internal _temp;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/// VARIBALES ARE STATEFUL ! DONT MESS WITH THEM SLOTS !!
/// ADDITIONAL SLOTS ATTACHED TO TAIL -- DONT DELETE ANY VARIABLES, ONLY ADD NEW ONES TO THE TAIL!!!
/// (There are a limited number of slots! (almost infinte, dont worry;))
/// v1.3.11
//(Using a new variable instead at Tail to not cause slot collision, as this contract will be used as Equalizer's PairFactory implementation)
uint256 public constant MAX_FEE = 1 ether;
mapping(address => uint256) public feesOverrideStatic;
mapping(address => address) public feesOverrideDynamic;
mapping(address => address) public feesTakers;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *ALL STATEFUL STUFF ABOVE!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Such events, much eventful
* @notice Events are stateless, ordering doesn't matter.
*/
event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* wow functions, very fun
* @notice Functions are stateless, ordering doesn't matter.
*/
function initialize() public initializer {
pauser = msg.sender;
isPaused = false;
feeManager = msg.sender;
stableFee = 0.0002 ether;
volatileFee = 0.01 ether;
}
function allPairsLength() external view returns (uint) {
return allPairs.length;
}
function setPauser(address _pauser) external {
require(msg.sender == pauser, "PairFactory: not a pauser");
pendingPauser = _pauser;
}
function acceptPauser() external {
require(msg.sender == pendingPauser, "PairFactory: not a pendingPauser");
pauser = pendingPauser;
}
function setPause(bool _state) external {
require(msg.sender == pauser, "PairFactory: not a pauser");
isPaused = _state;
}
function setFeeManager(address _feeManager) external {
require(msg.sender == feeManager, "not fee manager");
pendingFeeManager = _feeManager;
}
function acceptFeeManager() external {
require(msg.sender == pendingFeeManager, "not pending fee manager");
feeManager = pendingFeeManager;
}
function setFeeDefaults(uint256 _stable, uint256 _volatile) external {
require(msg.sender == feeManager, "not fee manager");
require(_stable < MAX_FEE, "fee too high");
require(_volatile < MAX_FEE, "fee too high");
//require(_volatile * _stable != 0, "fee must be nonzero");
stableFee = _stable;
volatileFee = _volatile;
}
function setFeesOverrideStatic(address _pair, uint256 _fee) external {
require(msg.sender == feeManager, "not fee manager");
require(_fee <= MAX_FEE, "fee too high");
//require(_fee != 0, "fee must be nonzero");
feesOverrideStatic[_pair] = _fee;
}
function setFeesOverrideDynamic(address _pair, address _feeManager) external {
require(msg.sender == feeManager, "not fee manager");
require(AddressUpgradeable.isContract(_feeManager), "invalid fee manager");
uint _fee = IFeeManager(_feeManager).getFee(_pair);
require(_fee < MAX_FEE, "fee too high");
//require(_fee != 0, "fee must be nonzero");
feesOverrideDynamic[_pair] = _feeManager;
}
function setFeesTakers(address _p, address _t) external {
require(msg.sender == feeManager, "not fee manager");
feesTakers[_p] = _t;
}
function getRealFee(address _pair) public view returns(uint256) {
/// to get base fees, call `stableFee()` or `volatileFee()`
uint _fos = feesOverrideStatic[ _pair ];
if( _fos > 0 ) {
return _fos;
}
address _fod = feesOverrideDynamic[_pair];
if( _fod != address(0) ) {
return Math.min(
Math.max(
1,
IFeeManager(_fod).getFee(_pair)
),
1 ether - 1
);
}
return IPair(_pair).stable()
? stableFee
: volatileFee
;
}
/// This method was retired in v3.0.1
/// This method was added in v1.3.11
/// This method, when called by an actual Pair contract itself, would return the real fees.
/// If simply read, it will show basic fees: stableFee, or the volatileFee.
/// Please use the `getRealFee` method instead for your Analytics / Dapps / Usecases!
/// If you want to request a flashloan from any Pair, please query `getRealFee` instead.
/*
function getFee(bool _stable) public view returns(uint256) {
address _c = msg.sender;
if(isPair[ _c ]) {
uint _fo = feesOverrides[ _c ];
if( _fo > 0 ) {
return _fo;
}
else return _stable ? stableFee : volatileFee; //non-overridden fee is base fee.
}
else return _stable ? stableFee : volatileFee; //non-pair callers (_c) see base fee.
}
*/
// Past implementaion of `getFee() for 2° Fees reference
function getFee(bool _stable) public view returns(uint256) {
return _stable ? stableFee : volatileFee;
}
function pairCodeHash() external pure returns (bytes32) {
return keccak256(type(Pair).creationCode);
}
function getInitializable() external view returns (address, address, bool) {
return (_temp0, _temp1, _temp);
}
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair) {
require(tokenA != tokenB, "IA"); // Pair: IDENTICAL_ADDRESSES
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), "ZA"); // Pair: ZERO_ADDRESS
require(getPair[token0][token1][stable] == address(0), "PE"); // Pair: PAIR_EXISTS - single check is sufficient
bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters
(_temp0, _temp1, _temp) = (token0, token1, stable);
Pair newPair = new Pair{salt:salt}();
newPair.initialize();
pair = address(newPair);
getPair[token0][token1][stable] = pair;
getPair[token1][token0][stable] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
isPair[pair] = true;
emit PairCreated(token0, token1, stable, pair, allPairs.length);
}
}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":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesOverrideDynamic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesOverrideStatic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesTakers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getRealFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingFeeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stable","type":"uint256"},{"internalType":"uint256","name":"_volatile","type":"uint256"}],"name":"setFeeDefaults","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeesOverrideDynamic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFeesOverrideStatic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_p","type":"address"},{"internalType":"address","name":"_t","type":"address"}],"name":"setFeesTakers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pauser","type":"address"}],"name":"setPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50615954806100206000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80638a4fa0d211610104578063c62f835f116100a2578063ea65b54b11610071578063ea65b54b14610427578063eb13c4cf14610450578063f1efebb414610488578063f94c53c71461049b57600080fd5b8063c62f835f146103cb578063d0fb0203146103de578063d2986436146103f1578063e5e31b131461040457600080fd5b80639fd0506d116100de5780639fd0506d1461036c578063b187bd2614610386578063bc063e1a146103a9578063bedb86fb146103b857600080fd5b80638a4fa0d21461033e5780639a7165e4146103515780639aab92481461036457600080fd5b80635084ed031161017c5780636801cc301161014b5780636801cc30146102d657806377ef0a40146103105780638129fc1c1461032357806382dfdce41461032b57600080fd5b80635084ed031461029f578063512b45ea146102a8578063574f2ba3146102bb5780636652f0bf146102c357600080fd5b80631f13d9f5116101b85780631f13d9f5146102475780632d88af4a1461027057806340bbd77514610283578063472d35b91461028c57600080fd5b8063167a6f90146101df57806317003e98146101e95780631e3dd18b1461021c575b600080fd5b6101e76104a3565b005b6102096101f736600461104c565b600b6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022f61022a366004611067565b61052f565b6040516001600160a01b039091168152602001610213565b61022f61025536600461104c565b600c602052600090815260409020546001600160a01b031681565b6101e761027e36600461104c565b610559565b61020960025481565b6101e761029a36600461104c565b6105d8565b61020960035481565b6102096102b636600461108e565b610624565b600754610209565b6102096102d136600461104c565b61063d565b61022f6102e43660046110ab565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6101e761031e3660046110f2565b6107ab565b6101e761082e565b61022f6103393660046110ab565b610984565b60055461022f906001600160a01b031681565b60015461022f906001600160a01b031681565b610209610cc0565b60005461022f90630100000090046001600160a01b031681565b6000546103999062010000900460ff1681565b6040519015158152602001610213565b610209670de0b6b3a764000081565b6101e76103c636600461108e565b610cf2565b6101e76103d9366004611114565b610d6b565b60045461022f906001600160a01b031681565b6101e76103ff366004611114565b610dc3565b61039961041236600461104c565b60086020526000908152604090205460ff1681565b61022f61043536600461104c565b600d602052600090815260409020546001600160a01b031681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001610213565b6101e7610496366004611147565b610f0f565b6101e7610f7d565b6001546001600160a01b031633146105025760405162461bcd60e51b815260206004820181905260248201527f50616972466163746f72793a206e6f7420612070656e64696e6750617573657260448201526064015b60405180910390fd5b600154600080546301000000600160b81b0319166001600160a01b03909216630100000002919091179055565b6007818154811061053f57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054630100000090046001600160a01b031633146105b65760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b60448201526064016104f9565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146106025760405162461bcd60e51b81526004016104f990611171565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b60008161063357600354610637565b6002545b92915050565b6001600160a01b0381166000908152600b602052604081205480156106625792915050565b6001600160a01b038084166000908152600c602052604090205416801561072357604051631711922960e31b81526001600160a01b03858116600483015261071b9161070d916001919085169063b88c91489060240160206040518083038186803b1580156106d057600080fd5b505afa1580156106e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610708919061119a565b610ffb565b670de0b6b3a763ffff611014565b949350505050565b836001600160a01b03166322be3de16040518163ffffffff1660e01b815260040160206040518083038186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079491906111b3565b6107a05760035461071b565b600254949350505050565b6004546001600160a01b031633146107d55760405162461bcd60e51b81526004016104f990611171565b670de0b6b3a764000082106107fc5760405162461bcd60e51b81526004016104f9906111d0565b670de0b6b3a764000081106108235760405162461bcd60e51b81526004016104f9906111d0565b600291909155600355565b600054610100900460ff161580801561084e5750600054600160ff909116105b806108685750303b158015610868575060005460ff166001145b6108cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f9565b6000805460ff1916600117905580156108ee576000805461ff0019166101001790555b6000805462010000600160b81b031916336301000000810262ff0000191691909117909155600480546001600160a01b031916909117905565b5e620f48000600255662386f26fc100006003558015610981576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000826001600160a01b0316846001600160a01b031614156109cd5760405162461bcd60e51b8152602060048201526002602482015261494160f01b60448201526064016104f9565b600080846001600160a01b0316866001600160a01b0316106109f05784866109f3565b85855b90925090506001600160a01b038216610a335760405162461bcd60e51b81526020600482015260026024820152615a4160f01b60448201526064016104f9565b6001600160a01b0382811660009081526006602090815260408083208585168452825280832088151584529091529020541615610a975760405162461bcd60e51b8152602060048201526002602482015261504560f01b60448201526064016104f9565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591506000908290610b3f90611023565b8190604051809103906000f5905080158015610b5f573d6000803e3d6000fd5b509050806001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff19169098179097559354815196875291860192909252908401529296508692917fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a3505050509392505050565b600060405180602001610cd290611023565b6020820181038252601f19601f8201166040525080519060200120905090565b600054630100000090046001600160a01b03163314610d4f5760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b60448201526064016104f9565b60008054911515620100000262ff000019909216919091179055565b6004546001600160a01b03163314610d955760405162461bcd60e51b81526004016104f990611171565b6001600160a01b039182166000908152600d6020526040902080546001600160a01b03191691909216179055565b6004546001600160a01b03163314610ded5760405162461bcd60e51b81526004016104f990611171565b6001600160a01b0381163b610e3a5760405162461bcd60e51b815260206004820152601360248201527234b73b30b634b2103332b29036b0b730b3b2b960691b60448201526064016104f9565b604051631711922960e31b81526001600160a01b0383811660048301526000919083169063b88c91489060240160206040518083038186803b158015610e7f57600080fd5b505afa158015610e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb7919061119a565b9050670de0b6b3a76400008110610ee05760405162461bcd60e51b81526004016104f9906111d0565b506001600160a01b039182166000908152600c6020526040902080546001600160a01b03191691909216179055565b6004546001600160a01b03163314610f395760405162461bcd60e51b81526004016104f990611171565b670de0b6b3a7640000811115610f615760405162461bcd60e51b81526004016104f9906111d0565b6001600160a01b039091166000908152600b6020526040902055565b6005546001600160a01b03163314610fd75760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016104f9565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b60008183101561100b578161100d565b825b9392505050565b600081831061100b578161100d565b614728806111f783390190565b80356001600160a01b038116811461104757600080fd5b919050565b60006020828403121561105e57600080fd5b61100d82611030565b60006020828403121561107957600080fd5b5035919050565b801515811461098157600080fd5b6000602082840312156110a057600080fd5b813561100d81611080565b6000806000606084860312156110c057600080fd5b6110c984611030565b92506110d760208501611030565b915060408401356110e781611080565b809150509250925092565b6000806040838503121561110557600080fd5b50508035926020909101359150565b6000806040838503121561112757600080fd5b61113083611030565b915061113e60208401611030565b90509250929050565b6000806040838503121561115a57600080fd5b61116383611030565b946020939093013593505050565b6020808252600f908201526e3737ba103332b29036b0b730b3b2b960891b604082015260600190565b6000602082840312156111ac57600080fd5b5051919050565b6000602082840312156111c557600080fd5b815161100d81611080565b6020808252600c908201526b0cccaca40e8dede40d0d2ced60a31b60408201526060019056fe608060405234801561001057600080fd5b50614708806100206000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80638129fc1c1161015c578063bda39cad116100ce578063d294f09311610087578063d294f0931461064e578063d505accf14610656578063dd62ed3e14610669578063ebeb31db14610694578063f140a35a1461069c578063fff6cae9146106af57600080fd5b8063bda39cad14610604578063bf944dbc1461060d578063c245febc14610616578063c45a01551461061f578063c5700a0214610632578063d21220a71461063b57600080fd5b80639d63848a116101205780639d63848a146105655780639e8cc04b1461058b5780639f767c881461059e578063a1ac4d13146105be578063a9059cbb146105de578063bc25cf77146105f157600080fd5b80638129fc1c146104f057806389afcb44146104f85780638a7b8cf21461052057806395d89b411461054a5780639af1d35a1461055257600080fd5b8063252c09d711610200578063517b3f82116101b9578063517b3f821461046e5780635881c475146104815780635a76f25e146104945780636a6278421461049d57806370a08231146104b05780637ecebe00146104d057600080fd5b8063252c09d7146103b4578063313ce567146103c757806332c0defd146103e1578063392f37e9146103ea578063443cb4bc146104455780634d5a9f8a1461044e57600080fd5b806313345fe11161025257806313345fe11461033557806318160ddd146103555780631df8c7171461036c578063205aabf11461037457806322be3de11461039457806323b872dd146103a157600080fd5b8063022c0d9f1461028f57806306fdde03146102a45780630902f1ac146102c2578063095ea7b3146102e75780630dfe16811461030a575b600080fd5b6102a261029d36600461378e565b6106b7565b005b6102ac610da7565b6040516102b99190613854565b60405180910390f35b6010546011546012545b604080519384526020840192909252908201526060016102b9565b6102fa6102f5366004613887565b610e35565b60405190151581526020016102b9565b60095461031d906001600160a01b031681565b6040516001600160a01b0390911681526020016102b9565b6103486103433660046138b3565b610ea2565b6040516102b991906138ee565b61035e60045481565b6040519081526020016102b9565b6102cc61109e565b61035e610382366004613932565b60186020526000908152604090205481565b6003546102fa9060ff1681565b6102fa6103af36600461394f565b61110d565b6102cc6103c2366004613990565b6111d6565b6103cf601281565b60405160ff90911681526020016102b9565b61035e60155481565b600e54600f54601054601154600354600954600a5460408051978852602088019690965294860193909352606085019190915260ff16151560808401526001600160a01b0390811660a08401521660c082015260e0016102b9565b61035e60105481565b61035e61045c366004613932565b60196020526000908152604090205481565b61035e61047c366004613887565b611209565b61034861048f3660046139a9565b6112f2565b61035e60115481565b61035e6104ab366004613932565b611301565b61035e6104be366004613932565b60066020526000908152604090205481565b61035e6104de366004613932565b60086020526000908152604090205481565b6102a2611564565b61050b610506366004613932565b611e1e565b604080519283526020830191909152016102b9565b610528612164565b60408051825181526020808401519082015291810151908201526060016102b9565b6102ac6121e4565b600b5461031d906001600160a01b031681565b600954600a54604080516001600160a01b039384168152929091166020830152016102b9565b61035e6105993660046139a9565b6121f1565b61035e6105ac366004613932565b60176020526000908152604090205481565b61035e6105cc366004613932565b601a6020526000908152604090205481565b6102fa6105ec366004613887565b61225e565b6102a26105ff366004613932565b612274565b61035e60165481565b61035e60135481565b61035e60145481565b600c5461031d906001600160a01b031681565b61035e60125481565b600a5461031d906001600160a01b031681565b61050b61241d565b6102a26106643660046139ed565b612527565b61035e610677366004613a5e565b600560209081526000928352604080842090915290825290205481565b600d5461035e565b61035e6106aa366004613a97565b61282f565b6102a26128f4565b601b5460ff16156106e35760405162461bcd60e51b81526004016106da90613abc565b60405180910390fd5b601b805460ff19166001179055600c54604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561073557600080fd5b505afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190613af4565b1561077757600080fd5b60008511806107865750600084115b6107b85760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064016106da565b60105460115481871080156107cc57508086105b6107fd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b60448201526064016106da565b600954600a5460009182916001600160a01b0391821691908116908916821480159061083b5750806001600160a01b0316896001600160a01b031614155b61086c5760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106da565b8a1561087d5761087d828a8d612a33565b891561088e5761088e818a8c612a33565b86156108fb57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906108c89033908f908f908e908e90600401613b0f565b600060405180830381600087803b1580156108e257600080fd5b505af11580156108f6573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109729190613b5b565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ec9190613b5b565b92505050600089856109fe9190613b8a565b8311610a0b576000610a1f565b610a158a86613b8a565b610a1f9084613b8a565b90506000610a2d8a86613b8a565b8311610a3a576000610a4e565b610a448a86613b8a565b610a4e9084613b8a565b90506000821180610a5f5750600081115b610a915760405162461bcd60e51b815260206004820152600360248201526249494160e81b60448201526064016106da565b600954600a546001600160a01b0391821691168315610b4c57600c54604051636652f0bf60e01b8152306004820152610b4c91670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b158015610afb57600080fd5b505afa158015610b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b339190613b5b565b610b3d9087613ba1565b610b479190613bc0565b612b96565b8215610bf457600c54604051636652f0bf60e01b8152306004820152610bf491670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b158015610ba357600080fd5b505afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb9190613b5b565b610be59086613ba1565b610bef9190613bc0565b612c35565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610c3357600080fd5b505afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190613b5b565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a082319060240160206040518083038186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce59190613b5b565b9450610cf18888612ccd565b610cfb8787612ccd565b1015610d2d5760405162461bcd60e51b81526020600482015260016024820152604b60f81b60448201526064016106da565b5050610d3b84848888612dc6565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a35050601b805460ff19169055505050505050505050565b60018054610db490613be2565b80601f0160208091040260200160405190810160405280929190818152602001828054610de090613be2565b8015610e2d5780601f10610e0257610100808354040283529160200191610e2d565b820191906000526020600020905b815481529060010190602001808311610e1057829003601f168201915b505050505081565b3360008181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610e909086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115610ebf57610ebf613c17565b604051908082528060200260200182016040528015610ee8578160200160208202803683370190505b50600d54909150600090610efe90600190613b8a565b90506000610f0c8587613ba1565b610f169083613b8a565b90506000805b8383101561108e57610f2e8784613c2d565b91506000600d8481548110610f4557610f45613c45565b906000526020600020906003020160000154600d8481548110610f6a57610f6a613c45565b906000526020600020906003020160000154610f869190613b8a565b9050600081600d8681548110610f9e57610f9e613c45565b906000526020600020906003020160010154600d8681548110610fc357610fc3613c45565b906000526020600020906003020160010154610fdf9190613b8a565b610fe99190613bc0565b9050600082600d878154811061100157611001613c45565b906000526020600020906003020160020154600d878154811061102657611026613c45565b9060005260206000209060030201600201546110429190613b8a565b61104c9190613bc0565b905061105a8c8e8484612f5a565b88858151811061106c5761106c613c45565b60209081029190910101525050506001016110878784613c2d565b9250610f1c565b509293505050505b949350505050565b60135460145442600080806110bc6010546011546012549192909190565b9250925092508381146111055760006110d58286613b8a565b90506110e18185613ba1565b6110eb9088613c2d565b96506110f78184613ba1565b6111019087613c2d565b9550505b505050909192565b6001600160a01b03831660008181526005602090815260408083203380855292528220549192909190821480159061114757506000198114155b156111bd5760006111588583613b8a565b6001600160a01b038881166000818152600560209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6111c88686866130fb565b6001925050505b9392505050565b600d81815481106111e657600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600080611214612164565b905060008061122161109e565b508451919350915042141561128a57600d805461124090600290613b8a565b8154811061125057611250613c45565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906112999042613b8a565b90506000818560200151856112ae9190613b8a565b6112b89190613bc0565b90506000828660400151856112cd9190613b8a565b6112d79190613bc0565b90506112e5888a8484612f5a565b9998505050505050505050565b60606110968484846001610ea2565b601b5460009060ff16156113275760405162461bcd60e51b81526004016106da90613abc565b601b805460ff191660011790556010546011546009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561137e57600080fd5b505afa158015611392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b69190613b5b565b600a546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b1580156113ff57600080fd5b505afa158015611413573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114379190613b5b565b905060006114458584613b8a565b905060006114538584613b8a565b60045490915080611491576103e861147361146e8486613ba1565b6131bb565b61147d9190613b8a565b975061148c60006103e861322b565b6114c6565b6114c38761149f8386613ba1565b6114a99190613bc0565b876114b48486613ba1565b6114be9190613bc0565b6132be565b97505b600088116114fc5760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b60448201526064016106da565b611506898961322b565b61151285858989612dc6565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25050601b805460ff19169055509395945050505050565b600054610100900460ff16158080156115845750600054600160ff909116105b8061159e5750303b15801561159e575060005460ff166001145b6116015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106da565b6000805460ff191660011790558015611624576000805461ff0019166101001790555b600c80546001600160a01b031916339081179091556040805163eb13c4cf60e01b815290516000928392839263eb13c4cf91600480820192606092909190829003018186803b15801561167657600080fd5b505afa15801561168a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ae9190613c5b565b6003805482151560ff19909116179055600a80546001600160a01b038085166001600160a01b03199283161790925560098054928616929091169190911790556040519295509093509150600090611705906136d3565b604051809103906000f080158015611721573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529192509082169063485cc95590604401600060405180830381600087803b15801561177157600080fd5b505af1158015611785573d6000803e3d6000fd5b5050600b80546001600160a01b0319166001600160a01b038516179055505081156119ef57836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261181f9190810190613ca3565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561185857600080fd5b505afa15801561186c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118949190810190613ca3565b6040516020016118a5929190613d50565b604051602081830303815290604052600190805190602001906118c99291906136e0565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561190357600080fd5b505afa158015611917573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261193f9190810190613ca3565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561197857600080fd5b505afa15801561198c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119b49190810190613ca3565b6040516020016119c5929190613dc1565b604051602081830303815290604052600290805190602001906119e99291906136e0565b50611c30565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611a2857600080fd5b505afa158015611a3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a649190810190613ca3565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611a9d57600080fd5b505afa158015611ab1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ad99190810190613ca3565b604051602001611aea929190613e0b565b60405160208183030381529060405260019080519060200190611b0e9291906136e0565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b4857600080fd5b505afa158015611b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b849190810190613ca3565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bbd57600080fd5b505afa158015611bd1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf99190810190613ca3565b604051602001611c0a929190613e7c565b60405160208183030381529060405260029080519060200190611c2e9291906136e0565b505b836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611c6957600080fd5b505afa158015611c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca19190613e99565b611cac90600a613f9a565b600e81905550826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ceb57600080fd5b505afa158015611cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d239190613e99565b611d2e90600a613f9a565b600f55505060408051606081018252428152600060208201818152928201818152600d8054600181018255925291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb560039092029182015591517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb6830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb79091015550508015611e1b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b601b54600090819060ff1615611e465760405162461bcd60e51b81526004016106da90613abc565b601b805460ff19166001179055601054601154600954600a546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a082319060240160206040518083038186803b158015611ea857600080fd5b505afa158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613b5b565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015611f2557600080fd5b505afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d9190613b5b565b306000908152600660205260409020546004549192509080611f7f8584613ba1565b611f899190613bc0565b995080611f968484613ba1565b611fa09190613bc0565b985060008a118015611fb25750600089115b611fe45760405162461bcd60e51b815260206004820152600360248201526224a62160e91b60448201526064016106da565b611fee30836132d4565b611ff9868c8c612a33565b612004858c8b612a33565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a082319060240160206040518083038186803b15801561204357600080fd5b505afa158015612057573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207b9190613b5b565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a082319060240160206040518083038186803b1580156120bd57600080fd5b505afa1580156120d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f59190613b5b565b925061210384848a8a612dc6565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050601b805460ff1916905550959794965093945050505050565b61218860405180606001604052806000815260200160008152602001600081525090565b600d805461219890600190613b8a565b815481106121a8576121a8613c45565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60028054610db490613be2565b6000806122018585856001610ea2565b90506000805b82518110156122495782818151811061222257612222613c45565b6020026020010151826122359190613c2d565b91508061224181613fa9565b915050612207565b506122548482613bc0565b9695505050505050565b600061226b3384846130fb565b50600192915050565b601b5460ff16156122975760405162461bcd60e51b81526004016106da90613abc565b601b805460ff19166001179055600c5460405163ea65b54b60e01b81523060048201526000916001600160a01b03169063ea65b54b9060240160206040518083038186803b1580156122e857600080fd5b505afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613fc4565b90506001600160a01b03811615612335578091505b600954600a546010546040516370a0823160e01b81523060048201526001600160a01b0393841693909216916123d591849187919083906370a08231906024015b60206040518083038186803b15801561238e57600080fd5b505afa1580156123a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c69190613b5b565b6123d09190613b8a565b612a33565b6011546040516370a0823160e01b815230600482015261240d9183918791906001600160a01b038416906370a0823190602401612376565b5050601b805460ff191690555050565b6000806124293361335f565b505033600090815260196020908152604080832054601a90925290912054811515806124555750600081115b1561252357336000818152601960209081526040808320839055601a90915280822091909155600b54905163299e7ae760e11b8152600481019290925260248201849052604482018390526001600160a01b03169063533cf5ce90606401600060405180830381600087803b1580156124cd57600080fd5b505af11580156124e1573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b428410156125675760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b60448201526064016106da565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60016040516125979190613fe1565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060078190556001600160a01b038a166000908152600890935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761266283613fa9565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016126db92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612746573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061277c5750886001600160a01b0316816001600160a01b0316145b6127c85760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016106da565b6001600160a01b038981166000818152600560209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b601054601154600c54604051636652f0bf60e01b81523060048201526000939291670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b15801561288757600080fd5b505afa15801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf9190613b5b565b6128c99087613ba1565b6128d39190613bc0565b6128dd9086613b8a565b94506128eb85858484612f5a565b95945050505050565b601b5460ff16156129175760405162461bcd60e51b81526004016106da90613abc565b601b805460ff191660011790556009546040516370a0823160e01b8152306004820152612a27916001600160a01b0316906370a082319060240160206040518083038186803b15801561296957600080fd5b505afa15801561297d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a19190613b5b565b600a546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156129e457600080fd5b505afa1580156129f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1c9190613b5b565b601054601154612dc6565b601b805460ff19169055565b6000836001600160a01b03163b11612a835760405162461bcd60e51b81526020600482015260136024820152722830b4b91d1034b73b30b634b2103a37b5b2b760691b60448201526064016106da565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612adf919061407d565b6000604051808303816000865af19150503d8060008114612b1c576040519150601f19603f3d011682016040523d82523d6000602084013e612b21565b606091505b5091509150818015612b4b575080511580612b4b575080806020019051810190612b4b9190613af4565b612b8f5760405162461bcd60e51b815260206004820152601560248201527414185a5c8e881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016106da565b5050505050565b600954600b54612bb3916001600160a01b03908116911683612a33565b600454600090612bcb83670de0b6b3a7640000613ba1565b612bd59190613bc0565b90508015612bf5578060156000828254612bef9190613c2d565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b600a54600b54612c52916001600160a01b03908116911683612a33565b600454600090612c6a83670de0b6b3a7640000613ba1565b612c749190613bc0565b90508015612c94578060166000828254612c8e9190613c2d565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612c29565b60035460009060ff1615612db557600e54600090612cf385670de0b6b3a7640000613ba1565b612cfd9190613bc0565b90506000600f5484670de0b6b3a7640000612d189190613ba1565b612d229190613bc0565b90506000670de0b6b3a7640000612d398385613ba1565b612d439190613bc0565b90506000670de0b6b3a7640000612d5a8480613ba1565b612d649190613bc0565b670de0b6b3a7640000612d778680613ba1565b612d819190613bc0565b612d8b9190613c2d565b9050670de0b6b3a7640000612da08284613ba1565b612daa9190613bc0565b945050505050610e9c565b612dbf8284613ba1565b9050610e9c565b6012544290600090612dd89083613b8a565b9050600081118015612de957508315155b8015612df457508215155b15612e3b57612e038185613ba1565b60136000828254612e149190613c2d565b90915550612e2490508184613ba1565b60146000828254612e359190613c2d565b90915550505b6000612e45612164565b8051909150612e549084613b8a565b9150610708821115612f09576040805160608101825284815260135460208201908152601454928201928352600d805460018101825560009190915291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5600390930292830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb682015590517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb7909101555b60108790556011869055601283905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60035460009060ff16156130ab576000612f748484612ccd565b600e54909150612f8c85670de0b6b3a7640000613ba1565b612f969190613bc0565b600f54909450612fae84670de0b6b3a7640000613ba1565b612fb89190613bc0565b60095490935060009081906001600160a01b03888116911614612fdc578486612fdf565b85855b60095491935091506001600160a01b0388811691161461301d57600f5461300e89670de0b6b3a7640000613ba1565b6130189190613bc0565b61303c565b600e5461303289670de0b6b3a7640000613ba1565b61303c9190613bc0565b9750600061305461304d848b613c2d565b85846134bf565b61305e9083613b8a565b600954909150670de0b6b3a7640000906001600160a01b038a811691161461308857600e5461308c565b600f545b6130969083613ba1565b6130a09190613bc0565b945050505050611096565b60095460009081906001600160a01b038781169116146130cc5783856130cf565b84845b90925090506130de8783613c2d565b6130e88289613ba1565b6130f29190613bc0565b92505050611096565b6131048361335f565b61310d8261335f565b6001600160a01b03831660009081526006602052604081208054839290613135908490613b8a565b90915550506001600160a01b03821660009081526006602052604081208054839290613162908490613c2d565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516131ae91815260200190565b60405180910390a3505050565b6000600382111561321c57508060006131d5600283613bc0565b6131e0906001613c2d565b90505b81811015613216579050806002816131fb8186613bc0565b6132059190613c2d565b61320f9190613bc0565b90506131e3565b50919050565b8115613226575060015b919050565b6132348261335f565b80600460008282546132469190613c2d565b90915550506001600160a01b03821660009081526006602052604081208054839290613273908490613c2d565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008183106132cd57816111cf565b5090919050565b6132dd8261335f565b80600460008282546132ef9190613b8a565b90915550506001600160a01b0382166000908152600660205260408120805483929061331c908490613b8a565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016132b2565b6001600160a01b038116600090815260066020526040902054801561348d576001600160a01b03821660009081526017602090815260408083208054601880855292852080546015546016549481905594909552829055936133c18584613b8a565b905060006133cf8584613b8a565b9050811561342a576000670de0b6b3a76400006133ec848a613ba1565b6133f69190613bc0565b6001600160a01b038a16600090815260196020526040812080549293508392909190613423908490613c2d565b9091555050505b8015613483576000670de0b6b3a7640000613445838a613ba1565b61344f9190613bc0565b6001600160a01b038a166000908152601a602052604081208054929350839290919061347c908490613c2d565b9091555050505b5050505050505050565b6015546001600160a01b0383166000908152601760209081526040808320939093556016546018909152919020555050565b6000805b60ff8110156135c5578260006134d987836135ce565b9050858110156135295760006134ef888761366b565b6134f98389613b8a565b61350b90670de0b6b3a7640000613ba1565b6135159190613bc0565b90506135218187613c2d565b95505061356b565b6000613535888761366b565b61353f8884613b8a565b61355190670de0b6b3a7640000613ba1565b61355b9190613bc0565b90506135678187613b8a565b9550505b8185111561359457600161357f8387613b8a565b1161358f578493505050506111cf565b6135b0565b60016135a08684613b8a565b116135b0578493505050506111cf565b505080806135bd90613fa9565b9150506134c3565b50909392505050565b6000670de0b6b3a7640000828185816135e78280613ba1565b6135f19190613bc0565b6135fb9190613ba1565b6136059190613bc0565b61360f9190613ba1565b6136199190613bc0565b670de0b6b3a764000080848161362f8280613ba1565b6136399190613bc0565b6136439190613ba1565b61364d9190613bc0565b6136579086613ba1565b6136619190613bc0565b6111cf9190613c2d565b6000670de0b6b3a764000083816136828280613ba1565b61368c9190613bc0565b6136969190613ba1565b6136a09190613bc0565b670de0b6b3a7640000806136b48580613ba1565b6136be9190613bc0565b6136c9866003613ba1565b6136579190613ba1565b6106398061409a83390190565b8280546136ec90613be2565b90600052602060002090601f01602090048101928261370e5760008555613754565b82601f1061372757805160ff1916838001178555613754565b82800160010185558215613754579182015b82811115613754578251825591602001919060010190613739565b50613760929150613764565b5090565b5b808211156137605760008155600101613765565b6001600160a01b0381168114611e1b57600080fd5b6000806000806000608086880312156137a657600080fd5b853594506020860135935060408601356137bf81613779565b9250606086013567ffffffffffffffff808211156137dc57600080fd5b818801915088601f8301126137f057600080fd5b8135818111156137ff57600080fd5b89602082850101111561381157600080fd5b9699959850939650602001949392505050565b60005b8381101561383f578181015183820152602001613827565b8381111561384e576000848401525b50505050565b6020815260008251806020840152613873816040850160208701613824565b601f01601f19169190910160400192915050565b6000806040838503121561389a57600080fd5b82356138a581613779565b946020939093013593505050565b600080600080608085870312156138c957600080fd5b84356138d481613779565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b818110156139265783518352928401929184019160010161390a565b50909695505050505050565b60006020828403121561394457600080fd5b81356111cf81613779565b60008060006060848603121561396457600080fd5b833561396f81613779565b9250602084013561397f81613779565b929592945050506040919091013590565b6000602082840312156139a257600080fd5b5035919050565b6000806000606084860312156139be57600080fd5b83356139c981613779565b95602085013595506040909401359392505050565b60ff81168114611e1b57600080fd5b600080600080600080600060e0888a031215613a0857600080fd5b8735613a1381613779565b96506020880135613a2381613779565b955060408801359450606088013593506080880135613a41816139de565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613a7157600080fd5b8235613a7c81613779565b91506020830135613a8c81613779565b809150509250929050565b60008060408385031215613aaa57600080fd5b823591506020830135613a8c81613779565b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b8051801515811461322657600080fd5b600060208284031215613b0657600080fd5b6111cf82613ae4565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613b6d57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613b9c57613b9c613b74565b500390565b6000816000190483118215151615613bbb57613bbb613b74565b500290565b600082613bdd57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c90821680613bf657607f821691505b6020821081141561321657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008219821115613c4057613c40613b74565b500190565b634e487b7160e01b600052603260045260246000fd5b600080600060608486031215613c7057600080fd5b8351613c7b81613779565b6020850151909350613c8c81613779565b9150613c9a60408501613ae4565b90509250925092565b600060208284031215613cb557600080fd5b815167ffffffffffffffff80821115613ccd57600080fd5b818401915084601f830112613ce157600080fd5b815181811115613cf357613cf3613c17565b604051601f8201601f19908116603f01168101908382118183101715613d1b57613d1b613c17565b81604052828152876020848701011115613d3457600080fd5b613d45836020830160208801613824565b979650505050505050565b7f457175616c697a657220537461626c65737761702032706f6f6c202d20000000815260008351613d8881601d850160208801613824565b6c0103830b4b932b2103bb4ba341609d1b601d918401918201528351613db581602a840160208801613824565b01602a01949350505050565b61732d60f01b815260008351613dde816002850160208801613824565b602f60f81b6002918401918201528351613dff816003840160208801613824565b01600301949350505050565b7f457175616c697a657220436c617373696320414d4d202d200000000000000000815260008351613e43816018850160208801613824565b6c0103830b4b932b2103bb4ba341609d1b6018918401918201528351613e70816025840160208801613824565b01602501949350505050565b61762d60f01b815260008351613dde816002850160208801613824565b600060208284031215613eab57600080fd5b81516111cf816139de565b600181815b80851115613ef1578160001904821115613ed757613ed7613b74565b80851615613ee457918102915b93841c9390800290613ebb565b509250929050565b600082613f0857506001610e9c565b81613f1557506000610e9c565b8160018114613f2b5760028114613f3557613f51565b6001915050610e9c565b60ff841115613f4657613f46613b74565b50506001821b610e9c565b5060208310610133831016604e8410600b8410161715613f74575081810a610e9c565b613f7e8383613eb6565b8060001904821115613f9257613f92613b74565b029392505050565b60006111cf60ff841683613ef9565b6000600019821415613fbd57613fbd613b74565b5060010190565b600060208284031215613fd657600080fd5b81516111cf81613779565b600080835481600182811c915080831680613ffd57607f831692505b602080841082141561401d57634e487b7160e01b86526022600452602486fd5b81801561403157600181146140425761406f565b60ff1986168952848901965061406f565b60008a81526020902060005b868110156140675781548b82015290850190830161404e565b505084890196505b509498975050505050505050565b6000825161408f818460208701613824565b919091019291505056fe608060405234801561001057600080fd5b50610619806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063485cc9551461003b578063533cf5ce14610050575b600080fd5b61004e610049366004610500565b610063565b005b61004e61005e366004610533565b6101be565b600054610100900460ff16158080156100835750600054600160ff909116105b8061009d5750303b15801561009d575060005460ff166001145b6101055760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610128576000805461ff0019166101001790555b6000805462010000330262010000600160b01b0319909116179055600180546001600160a01b038581166001600160a01b031992831617909255600280549285169290911691909117905580156101b9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000546201000090046001600160a01b0316331461021e5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79207061697220636f6e74726163742063616e2063616c6c000000000060448201526064016100fc565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561026257600080fd5b505afa158015610276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029a9190610566565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b1580156102e357600080fd5b505afa1580156102f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031b9190610566565b905081841115610329578193505b80831115610335578092505b831561035257600154610352906001600160a01b03168686610376565b821561036f5760025461036f906001600160a01b03168685610376565b5050505050565b6000836001600160a01b03163b116103d05760405162461bcd60e51b815260206004820152601760248201527f50616972466565733a20696e76616c696420746f6b656e00000000000000000060448201526064016100fc565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161042c919061057f565b6000604051808303816000865af19150503d8060008114610469576040519150601f19603f3d011682016040523d82523d6000602084013e61046e565b606091505b509150915081801561049857508051158061049857508080602001905181019061049891906105ba565b61036f5760405162461bcd60e51b815260206004820152601960248201527f50616972466565733a207472616e73666572206661696c65640000000000000060448201526064016100fc565b80356001600160a01b03811681146104fb57600080fd5b919050565b6000806040838503121561051357600080fd5b61051c836104e4565b915061052a602084016104e4565b90509250929050565b60008060006060848603121561054857600080fd5b610551846104e4565b95602085013595506040909401359392505050565b60006020828403121561057857600080fd5b5051919050565b6000825160005b818110156105a05760208186018101518583015201610586565b818111156105af576000828501525b509190910192915050565b6000602082840312156105cc57600080fd5b815180151581146105dc57600080fd5b939250505056fea2646970667358221220ab85609b0e4066fb80f5f4db9c98ce5dd85c56475b3e3fdb67565561ebc0262d64736f6c63430008090033a26469706673582212200c1e79eb9aa897572d1f7371e6402b9b476892959b2c9a3161c94c12b52d84e364736f6c63430008090033a2646970667358221220add9494f3c9a8b2ae69175d77cd1afd0a1003ebcd8dbcf43a59ac96031a7715064736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80638a4fa0d211610104578063c62f835f116100a2578063ea65b54b11610071578063ea65b54b14610427578063eb13c4cf14610450578063f1efebb414610488578063f94c53c71461049b57600080fd5b8063c62f835f146103cb578063d0fb0203146103de578063d2986436146103f1578063e5e31b131461040457600080fd5b80639fd0506d116100de5780639fd0506d1461036c578063b187bd2614610386578063bc063e1a146103a9578063bedb86fb146103b857600080fd5b80638a4fa0d21461033e5780639a7165e4146103515780639aab92481461036457600080fd5b80635084ed031161017c5780636801cc301161014b5780636801cc30146102d657806377ef0a40146103105780638129fc1c1461032357806382dfdce41461032b57600080fd5b80635084ed031461029f578063512b45ea146102a8578063574f2ba3146102bb5780636652f0bf146102c357600080fd5b80631f13d9f5116101b85780631f13d9f5146102475780632d88af4a1461027057806340bbd77514610283578063472d35b91461028c57600080fd5b8063167a6f90146101df57806317003e98146101e95780631e3dd18b1461021c575b600080fd5b6101e76104a3565b005b6102096101f736600461104c565b600b6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022f61022a366004611067565b61052f565b6040516001600160a01b039091168152602001610213565b61022f61025536600461104c565b600c602052600090815260409020546001600160a01b031681565b6101e761027e36600461104c565b610559565b61020960025481565b6101e761029a36600461104c565b6105d8565b61020960035481565b6102096102b636600461108e565b610624565b600754610209565b6102096102d136600461104c565b61063d565b61022f6102e43660046110ab565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6101e761031e3660046110f2565b6107ab565b6101e761082e565b61022f6103393660046110ab565b610984565b60055461022f906001600160a01b031681565b60015461022f906001600160a01b031681565b610209610cc0565b60005461022f90630100000090046001600160a01b031681565b6000546103999062010000900460ff1681565b6040519015158152602001610213565b610209670de0b6b3a764000081565b6101e76103c636600461108e565b610cf2565b6101e76103d9366004611114565b610d6b565b60045461022f906001600160a01b031681565b6101e76103ff366004611114565b610dc3565b61039961041236600461104c565b60086020526000908152604090205460ff1681565b61022f61043536600461104c565b600d602052600090815260409020546001600160a01b031681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001610213565b6101e7610496366004611147565b610f0f565b6101e7610f7d565b6001546001600160a01b031633146105025760405162461bcd60e51b815260206004820181905260248201527f50616972466163746f72793a206e6f7420612070656e64696e6750617573657260448201526064015b60405180910390fd5b600154600080546301000000600160b81b0319166001600160a01b03909216630100000002919091179055565b6007818154811061053f57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054630100000090046001600160a01b031633146105b65760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b60448201526064016104f9565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031633146106025760405162461bcd60e51b81526004016104f990611171565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b60008161063357600354610637565b6002545b92915050565b6001600160a01b0381166000908152600b602052604081205480156106625792915050565b6001600160a01b038084166000908152600c602052604090205416801561072357604051631711922960e31b81526001600160a01b03858116600483015261071b9161070d916001919085169063b88c91489060240160206040518083038186803b1580156106d057600080fd5b505afa1580156106e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610708919061119a565b610ffb565b670de0b6b3a763ffff611014565b949350505050565b836001600160a01b03166322be3de16040518163ffffffff1660e01b815260040160206040518083038186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079491906111b3565b6107a05760035461071b565b600254949350505050565b6004546001600160a01b031633146107d55760405162461bcd60e51b81526004016104f990611171565b670de0b6b3a764000082106107fc5760405162461bcd60e51b81526004016104f9906111d0565b670de0b6b3a764000081106108235760405162461bcd60e51b81526004016104f9906111d0565b600291909155600355565b600054610100900460ff161580801561084e5750600054600160ff909116105b806108685750303b158015610868575060005460ff166001145b6108cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f9565b6000805460ff1916600117905580156108ee576000805461ff0019166101001790555b6000805462010000600160b81b031916336301000000810262ff0000191691909117909155600480546001600160a01b031916909117905565b5e620f48000600255662386f26fc100006003558015610981576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000826001600160a01b0316846001600160a01b031614156109cd5760405162461bcd60e51b8152602060048201526002602482015261494160f01b60448201526064016104f9565b600080846001600160a01b0316866001600160a01b0316106109f05784866109f3565b85855b90925090506001600160a01b038216610a335760405162461bcd60e51b81526020600482015260026024820152615a4160f01b60448201526064016104f9565b6001600160a01b0382811660009081526006602090815260408083208585168452825280832088151584529091529020541615610a975760405162461bcd60e51b8152602060048201526002602482015261504560f01b60448201526064016104f9565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591506000908290610b3f90611023565b8190604051809103906000f5905080158015610b5f573d6000803e3d6000fd5b509050806001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b505050506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff19169098179097559354815196875291860192909252908401529296508692917fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a3505050509392505050565b600060405180602001610cd290611023565b6020820181038252601f19601f8201166040525080519060200120905090565b600054630100000090046001600160a01b03163314610d4f5760405162461bcd60e51b81526020600482015260196024820152782830b4b92330b1ba37b93c9d103737ba1030903830bab9b2b960391b60448201526064016104f9565b60008054911515620100000262ff000019909216919091179055565b6004546001600160a01b03163314610d955760405162461bcd60e51b81526004016104f990611171565b6001600160a01b039182166000908152600d6020526040902080546001600160a01b03191691909216179055565b6004546001600160a01b03163314610ded5760405162461bcd60e51b81526004016104f990611171565b6001600160a01b0381163b610e3a5760405162461bcd60e51b815260206004820152601360248201527234b73b30b634b2103332b29036b0b730b3b2b960691b60448201526064016104f9565b604051631711922960e31b81526001600160a01b0383811660048301526000919083169063b88c91489060240160206040518083038186803b158015610e7f57600080fd5b505afa158015610e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb7919061119a565b9050670de0b6b3a76400008110610ee05760405162461bcd60e51b81526004016104f9906111d0565b506001600160a01b039182166000908152600c6020526040902080546001600160a01b03191691909216179055565b6004546001600160a01b03163314610f395760405162461bcd60e51b81526004016104f990611171565b670de0b6b3a7640000811115610f615760405162461bcd60e51b81526004016104f9906111d0565b6001600160a01b039091166000908152600b6020526040902055565b6005546001600160a01b03163314610fd75760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016104f9565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b60008183101561100b578161100d565b825b9392505050565b600081831061100b578161100d565b614728806111f783390190565b80356001600160a01b038116811461104757600080fd5b919050565b60006020828403121561105e57600080fd5b61100d82611030565b60006020828403121561107957600080fd5b5035919050565b801515811461098157600080fd5b6000602082840312156110a057600080fd5b813561100d81611080565b6000806000606084860312156110c057600080fd5b6110c984611030565b92506110d760208501611030565b915060408401356110e781611080565b809150509250925092565b6000806040838503121561110557600080fd5b50508035926020909101359150565b6000806040838503121561112757600080fd5b61113083611030565b915061113e60208401611030565b90509250929050565b6000806040838503121561115a57600080fd5b61116383611030565b946020939093013593505050565b6020808252600f908201526e3737ba103332b29036b0b730b3b2b960891b604082015260600190565b6000602082840312156111ac57600080fd5b5051919050565b6000602082840312156111c557600080fd5b815161100d81611080565b6020808252600c908201526b0cccaca40e8dede40d0d2ced60a31b60408201526060019056fe608060405234801561001057600080fd5b50614708806100206000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80638129fc1c1161015c578063bda39cad116100ce578063d294f09311610087578063d294f0931461064e578063d505accf14610656578063dd62ed3e14610669578063ebeb31db14610694578063f140a35a1461069c578063fff6cae9146106af57600080fd5b8063bda39cad14610604578063bf944dbc1461060d578063c245febc14610616578063c45a01551461061f578063c5700a0214610632578063d21220a71461063b57600080fd5b80639d63848a116101205780639d63848a146105655780639e8cc04b1461058b5780639f767c881461059e578063a1ac4d13146105be578063a9059cbb146105de578063bc25cf77146105f157600080fd5b80638129fc1c146104f057806389afcb44146104f85780638a7b8cf21461052057806395d89b411461054a5780639af1d35a1461055257600080fd5b8063252c09d711610200578063517b3f82116101b9578063517b3f821461046e5780635881c475146104815780635a76f25e146104945780636a6278421461049d57806370a08231146104b05780637ecebe00146104d057600080fd5b8063252c09d7146103b4578063313ce567146103c757806332c0defd146103e1578063392f37e9146103ea578063443cb4bc146104455780634d5a9f8a1461044e57600080fd5b806313345fe11161025257806313345fe11461033557806318160ddd146103555780631df8c7171461036c578063205aabf11461037457806322be3de11461039457806323b872dd146103a157600080fd5b8063022c0d9f1461028f57806306fdde03146102a45780630902f1ac146102c2578063095ea7b3146102e75780630dfe16811461030a575b600080fd5b6102a261029d36600461378e565b6106b7565b005b6102ac610da7565b6040516102b99190613854565b60405180910390f35b6010546011546012545b604080519384526020840192909252908201526060016102b9565b6102fa6102f5366004613887565b610e35565b60405190151581526020016102b9565b60095461031d906001600160a01b031681565b6040516001600160a01b0390911681526020016102b9565b6103486103433660046138b3565b610ea2565b6040516102b991906138ee565b61035e60045481565b6040519081526020016102b9565b6102cc61109e565b61035e610382366004613932565b60186020526000908152604090205481565b6003546102fa9060ff1681565b6102fa6103af36600461394f565b61110d565b6102cc6103c2366004613990565b6111d6565b6103cf601281565b60405160ff90911681526020016102b9565b61035e60155481565b600e54600f54601054601154600354600954600a5460408051978852602088019690965294860193909352606085019190915260ff16151560808401526001600160a01b0390811660a08401521660c082015260e0016102b9565b61035e60105481565b61035e61045c366004613932565b60196020526000908152604090205481565b61035e61047c366004613887565b611209565b61034861048f3660046139a9565b6112f2565b61035e60115481565b61035e6104ab366004613932565b611301565b61035e6104be366004613932565b60066020526000908152604090205481565b61035e6104de366004613932565b60086020526000908152604090205481565b6102a2611564565b61050b610506366004613932565b611e1e565b604080519283526020830191909152016102b9565b610528612164565b60408051825181526020808401519082015291810151908201526060016102b9565b6102ac6121e4565b600b5461031d906001600160a01b031681565b600954600a54604080516001600160a01b039384168152929091166020830152016102b9565b61035e6105993660046139a9565b6121f1565b61035e6105ac366004613932565b60176020526000908152604090205481565b61035e6105cc366004613932565b601a6020526000908152604090205481565b6102fa6105ec366004613887565b61225e565b6102a26105ff366004613932565b612274565b61035e60165481565b61035e60135481565b61035e60145481565b600c5461031d906001600160a01b031681565b61035e60125481565b600a5461031d906001600160a01b031681565b61050b61241d565b6102a26106643660046139ed565b612527565b61035e610677366004613a5e565b600560209081526000928352604080842090915290825290205481565b600d5461035e565b61035e6106aa366004613a97565b61282f565b6102a26128f4565b601b5460ff16156106e35760405162461bcd60e51b81526004016106da90613abc565b60405180910390fd5b601b805460ff19166001179055600c54604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561073557600080fd5b505afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190613af4565b1561077757600080fd5b60008511806107865750600084115b6107b85760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064016106da565b60105460115481871080156107cc57508086105b6107fd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b60448201526064016106da565b600954600a5460009182916001600160a01b0391821691908116908916821480159061083b5750806001600160a01b0316896001600160a01b031614155b61086c5760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106da565b8a1561087d5761087d828a8d612a33565b891561088e5761088e818a8c612a33565b86156108fb57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906108c89033908f908f908e908e90600401613b0f565b600060405180830381600087803b1580156108e257600080fd5b505af11580156108f6573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109729190613b5b565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a082319060240160206040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ec9190613b5b565b92505050600089856109fe9190613b8a565b8311610a0b576000610a1f565b610a158a86613b8a565b610a1f9084613b8a565b90506000610a2d8a86613b8a565b8311610a3a576000610a4e565b610a448a86613b8a565b610a4e9084613b8a565b90506000821180610a5f5750600081115b610a915760405162461bcd60e51b815260206004820152600360248201526249494160e81b60448201526064016106da565b600954600a546001600160a01b0391821691168315610b4c57600c54604051636652f0bf60e01b8152306004820152610b4c91670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b158015610afb57600080fd5b505afa158015610b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b339190613b5b565b610b3d9087613ba1565b610b479190613bc0565b612b96565b8215610bf457600c54604051636652f0bf60e01b8152306004820152610bf491670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b158015610ba357600080fd5b505afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb9190613b5b565b610be59086613ba1565b610bef9190613bc0565b612c35565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610c3357600080fd5b505afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190613b5b565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a082319060240160206040518083038186803b158015610cad57600080fd5b505afa158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce59190613b5b565b9450610cf18888612ccd565b610cfb8787612ccd565b1015610d2d5760405162461bcd60e51b81526020600482015260016024820152604b60f81b60448201526064016106da565b5050610d3b84848888612dc6565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a35050601b805460ff19169055505050505050505050565b60018054610db490613be2565b80601f0160208091040260200160405190810160405280929190818152602001828054610de090613be2565b8015610e2d5780601f10610e0257610100808354040283529160200191610e2d565b820191906000526020600020905b815481529060010190602001808311610e1057829003601f168201915b505050505081565b3360008181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610e909086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115610ebf57610ebf613c17565b604051908082528060200260200182016040528015610ee8578160200160208202803683370190505b50600d54909150600090610efe90600190613b8a565b90506000610f0c8587613ba1565b610f169083613b8a565b90506000805b8383101561108e57610f2e8784613c2d565b91506000600d8481548110610f4557610f45613c45565b906000526020600020906003020160000154600d8481548110610f6a57610f6a613c45565b906000526020600020906003020160000154610f869190613b8a565b9050600081600d8681548110610f9e57610f9e613c45565b906000526020600020906003020160010154600d8681548110610fc357610fc3613c45565b906000526020600020906003020160010154610fdf9190613b8a565b610fe99190613bc0565b9050600082600d878154811061100157611001613c45565b906000526020600020906003020160020154600d878154811061102657611026613c45565b9060005260206000209060030201600201546110429190613b8a565b61104c9190613bc0565b905061105a8c8e8484612f5a565b88858151811061106c5761106c613c45565b60209081029190910101525050506001016110878784613c2d565b9250610f1c565b509293505050505b949350505050565b60135460145442600080806110bc6010546011546012549192909190565b9250925092508381146111055760006110d58286613b8a565b90506110e18185613ba1565b6110eb9088613c2d565b96506110f78184613ba1565b6111019087613c2d565b9550505b505050909192565b6001600160a01b03831660008181526005602090815260408083203380855292528220549192909190821480159061114757506000198114155b156111bd5760006111588583613b8a565b6001600160a01b038881166000818152600560209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6111c88686866130fb565b6001925050505b9392505050565b600d81815481106111e657600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600080611214612164565b905060008061122161109e565b508451919350915042141561128a57600d805461124090600290613b8a565b8154811061125057611250613c45565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906112999042613b8a565b90506000818560200151856112ae9190613b8a565b6112b89190613bc0565b90506000828660400151856112cd9190613b8a565b6112d79190613bc0565b90506112e5888a8484612f5a565b9998505050505050505050565b60606110968484846001610ea2565b601b5460009060ff16156113275760405162461bcd60e51b81526004016106da90613abc565b601b805460ff191660011790556010546011546009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561137e57600080fd5b505afa158015611392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b69190613b5b565b600a546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b1580156113ff57600080fd5b505afa158015611413573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114379190613b5b565b905060006114458584613b8a565b905060006114538584613b8a565b60045490915080611491576103e861147361146e8486613ba1565b6131bb565b61147d9190613b8a565b975061148c60006103e861322b565b6114c6565b6114c38761149f8386613ba1565b6114a99190613bc0565b876114b48486613ba1565b6114be9190613bc0565b6132be565b97505b600088116114fc5760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b60448201526064016106da565b611506898961322b565b61151285858989612dc6565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25050601b805460ff19169055509395945050505050565b600054610100900460ff16158080156115845750600054600160ff909116105b8061159e5750303b15801561159e575060005460ff166001145b6116015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106da565b6000805460ff191660011790558015611624576000805461ff0019166101001790555b600c80546001600160a01b031916339081179091556040805163eb13c4cf60e01b815290516000928392839263eb13c4cf91600480820192606092909190829003018186803b15801561167657600080fd5b505afa15801561168a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ae9190613c5b565b6003805482151560ff19909116179055600a80546001600160a01b038085166001600160a01b03199283161790925560098054928616929091169190911790556040519295509093509150600090611705906136d3565b604051809103906000f080158015611721573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529192509082169063485cc95590604401600060405180830381600087803b15801561177157600080fd5b505af1158015611785573d6000803e3d6000fd5b5050600b80546001600160a01b0319166001600160a01b038516179055505081156119ef57836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261181f9190810190613ca3565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561185857600080fd5b505afa15801561186c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118949190810190613ca3565b6040516020016118a5929190613d50565b604051602081830303815290604052600190805190602001906118c99291906136e0565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561190357600080fd5b505afa158015611917573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261193f9190810190613ca3565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561197857600080fd5b505afa15801561198c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119b49190810190613ca3565b6040516020016119c5929190613dc1565b604051602081830303815290604052600290805190602001906119e99291906136e0565b50611c30565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611a2857600080fd5b505afa158015611a3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a649190810190613ca3565b836001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015611a9d57600080fd5b505afa158015611ab1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ad99190810190613ca3565b604051602001611aea929190613e0b565b60405160208183030381529060405260019080519060200190611b0e9291906136e0565b50836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b4857600080fd5b505afa158015611b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b849190810190613ca3565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bbd57600080fd5b505afa158015611bd1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf99190810190613ca3565b604051602001611c0a929190613e7c565b60405160208183030381529060405260029080519060200190611c2e9291906136e0565b505b836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611c6957600080fd5b505afa158015611c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca19190613e99565b611cac90600a613f9a565b600e81905550826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ceb57600080fd5b505afa158015611cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d239190613e99565b611d2e90600a613f9a565b600f55505060408051606081018252428152600060208201818152928201818152600d8054600181018255925291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb560039092029182015591517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb6830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb79091015550508015611e1b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b601b54600090819060ff1615611e465760405162461bcd60e51b81526004016106da90613abc565b601b805460ff19166001179055601054601154600954600a546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a082319060240160206040518083038186803b158015611ea857600080fd5b505afa158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613b5b565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015611f2557600080fd5b505afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d9190613b5b565b306000908152600660205260409020546004549192509080611f7f8584613ba1565b611f899190613bc0565b995080611f968484613ba1565b611fa09190613bc0565b985060008a118015611fb25750600089115b611fe45760405162461bcd60e51b815260206004820152600360248201526224a62160e91b60448201526064016106da565b611fee30836132d4565b611ff9868c8c612a33565b612004858c8b612a33565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a082319060240160206040518083038186803b15801561204357600080fd5b505afa158015612057573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207b9190613b5b565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a082319060240160206040518083038186803b1580156120bd57600080fd5b505afa1580156120d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f59190613b5b565b925061210384848a8a612dc6565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050601b805460ff1916905550959794965093945050505050565b61218860405180606001604052806000815260200160008152602001600081525090565b600d805461219890600190613b8a565b815481106121a8576121a8613c45565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60028054610db490613be2565b6000806122018585856001610ea2565b90506000805b82518110156122495782818151811061222257612222613c45565b6020026020010151826122359190613c2d565b91508061224181613fa9565b915050612207565b506122548482613bc0565b9695505050505050565b600061226b3384846130fb565b50600192915050565b601b5460ff16156122975760405162461bcd60e51b81526004016106da90613abc565b601b805460ff19166001179055600c5460405163ea65b54b60e01b81523060048201526000916001600160a01b03169063ea65b54b9060240160206040518083038186803b1580156122e857600080fd5b505afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613fc4565b90506001600160a01b03811615612335578091505b600954600a546010546040516370a0823160e01b81523060048201526001600160a01b0393841693909216916123d591849187919083906370a08231906024015b60206040518083038186803b15801561238e57600080fd5b505afa1580156123a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c69190613b5b565b6123d09190613b8a565b612a33565b6011546040516370a0823160e01b815230600482015261240d9183918791906001600160a01b038416906370a0823190602401612376565b5050601b805460ff191690555050565b6000806124293361335f565b505033600090815260196020908152604080832054601a90925290912054811515806124555750600081115b1561252357336000818152601960209081526040808320839055601a90915280822091909155600b54905163299e7ae760e11b8152600481019290925260248201849052604482018390526001600160a01b03169063533cf5ce90606401600060405180830381600087803b1580156124cd57600080fd5b505af11580156124e1573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b428410156125675760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b60448201526064016106da565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60016040516125979190613fe1565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060078190556001600160a01b038a166000908152600890935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b91908761266283613fa9565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016126db92919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612746573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061277c5750886001600160a01b0316816001600160a01b0316145b6127c85760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016106da565b6001600160a01b038981166000818152600560209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b601054601154600c54604051636652f0bf60e01b81523060048201526000939291670de0b6b3a7640000916001600160a01b0390911690636652f0bf9060240160206040518083038186803b15801561288757600080fd5b505afa15801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf9190613b5b565b6128c99087613ba1565b6128d39190613bc0565b6128dd9086613b8a565b94506128eb85858484612f5a565b95945050505050565b601b5460ff16156129175760405162461bcd60e51b81526004016106da90613abc565b601b805460ff191660011790556009546040516370a0823160e01b8152306004820152612a27916001600160a01b0316906370a082319060240160206040518083038186803b15801561296957600080fd5b505afa15801561297d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a19190613b5b565b600a546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156129e457600080fd5b505afa1580156129f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1c9190613b5b565b601054601154612dc6565b601b805460ff19169055565b6000836001600160a01b03163b11612a835760405162461bcd60e51b81526020600482015260136024820152722830b4b91d1034b73b30b634b2103a37b5b2b760691b60448201526064016106da565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612adf919061407d565b6000604051808303816000865af19150503d8060008114612b1c576040519150601f19603f3d011682016040523d82523d6000602084013e612b21565b606091505b5091509150818015612b4b575080511580612b4b575080806020019051810190612b4b9190613af4565b612b8f5760405162461bcd60e51b815260206004820152601560248201527414185a5c8e881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016106da565b5050505050565b600954600b54612bb3916001600160a01b03908116911683612a33565b600454600090612bcb83670de0b6b3a7640000613ba1565b612bd59190613bc0565b90508015612bf5578060156000828254612bef9190613c2d565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b600a54600b54612c52916001600160a01b03908116911683612a33565b600454600090612c6a83670de0b6b3a7640000613ba1565b612c749190613bc0565b90508015612c94578060166000828254612c8e9190613c2d565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a86029101612c29565b60035460009060ff1615612db557600e54600090612cf385670de0b6b3a7640000613ba1565b612cfd9190613bc0565b90506000600f5484670de0b6b3a7640000612d189190613ba1565b612d229190613bc0565b90506000670de0b6b3a7640000612d398385613ba1565b612d439190613bc0565b90506000670de0b6b3a7640000612d5a8480613ba1565b612d649190613bc0565b670de0b6b3a7640000612d778680613ba1565b612d819190613bc0565b612d8b9190613c2d565b9050670de0b6b3a7640000612da08284613ba1565b612daa9190613bc0565b945050505050610e9c565b612dbf8284613ba1565b9050610e9c565b6012544290600090612dd89083613b8a565b9050600081118015612de957508315155b8015612df457508215155b15612e3b57612e038185613ba1565b60136000828254612e149190613c2d565b90915550612e2490508184613ba1565b60146000828254612e359190613c2d565b90915550505b6000612e45612164565b8051909150612e549084613b8a565b9150610708821115612f09576040805160608101825284815260135460208201908152601454928201928352600d805460018101825560009190915291517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5600390930292830155517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb682015590517fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb7909101555b60108790556011869055601283905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60035460009060ff16156130ab576000612f748484612ccd565b600e54909150612f8c85670de0b6b3a7640000613ba1565b612f969190613bc0565b600f54909450612fae84670de0b6b3a7640000613ba1565b612fb89190613bc0565b60095490935060009081906001600160a01b03888116911614612fdc578486612fdf565b85855b60095491935091506001600160a01b0388811691161461301d57600f5461300e89670de0b6b3a7640000613ba1565b6130189190613bc0565b61303c565b600e5461303289670de0b6b3a7640000613ba1565b61303c9190613bc0565b9750600061305461304d848b613c2d565b85846134bf565b61305e9083613b8a565b600954909150670de0b6b3a7640000906001600160a01b038a811691161461308857600e5461308c565b600f545b6130969083613ba1565b6130a09190613bc0565b945050505050611096565b60095460009081906001600160a01b038781169116146130cc5783856130cf565b84845b90925090506130de8783613c2d565b6130e88289613ba1565b6130f29190613bc0565b92505050611096565b6131048361335f565b61310d8261335f565b6001600160a01b03831660009081526006602052604081208054839290613135908490613b8a565b90915550506001600160a01b03821660009081526006602052604081208054839290613162908490613c2d565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516131ae91815260200190565b60405180910390a3505050565b6000600382111561321c57508060006131d5600283613bc0565b6131e0906001613c2d565b90505b81811015613216579050806002816131fb8186613bc0565b6132059190613c2d565b61320f9190613bc0565b90506131e3565b50919050565b8115613226575060015b919050565b6132348261335f565b80600460008282546132469190613c2d565b90915550506001600160a01b03821660009081526006602052604081208054839290613273908490613c2d565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008183106132cd57816111cf565b5090919050565b6132dd8261335f565b80600460008282546132ef9190613b8a565b90915550506001600160a01b0382166000908152600660205260408120805483929061331c908490613b8a565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016132b2565b6001600160a01b038116600090815260066020526040902054801561348d576001600160a01b03821660009081526017602090815260408083208054601880855292852080546015546016549481905594909552829055936133c18584613b8a565b905060006133cf8584613b8a565b9050811561342a576000670de0b6b3a76400006133ec848a613ba1565b6133f69190613bc0565b6001600160a01b038a16600090815260196020526040812080549293508392909190613423908490613c2d565b9091555050505b8015613483576000670de0b6b3a7640000613445838a613ba1565b61344f9190613bc0565b6001600160a01b038a166000908152601a602052604081208054929350839290919061347c908490613c2d565b9091555050505b5050505050505050565b6015546001600160a01b0383166000908152601760209081526040808320939093556016546018909152919020555050565b6000805b60ff8110156135c5578260006134d987836135ce565b9050858110156135295760006134ef888761366b565b6134f98389613b8a565b61350b90670de0b6b3a7640000613ba1565b6135159190613bc0565b90506135218187613c2d565b95505061356b565b6000613535888761366b565b61353f8884613b8a565b61355190670de0b6b3a7640000613ba1565b61355b9190613bc0565b90506135678187613b8a565b9550505b8185111561359457600161357f8387613b8a565b1161358f578493505050506111cf565b6135b0565b60016135a08684613b8a565b116135b0578493505050506111cf565b505080806135bd90613fa9565b9150506134c3565b50909392505050565b6000670de0b6b3a7640000828185816135e78280613ba1565b6135f19190613bc0565b6135fb9190613ba1565b6136059190613bc0565b61360f9190613ba1565b6136199190613bc0565b670de0b6b3a764000080848161362f8280613ba1565b6136399190613bc0565b6136439190613ba1565b61364d9190613bc0565b6136579086613ba1565b6136619190613bc0565b6111cf9190613c2d565b6000670de0b6b3a764000083816136828280613ba1565b61368c9190613bc0565b6136969190613ba1565b6136a09190613bc0565b670de0b6b3a7640000806136b48580613ba1565b6136be9190613bc0565b6136c9866003613ba1565b6136579190613ba1565b6106398061409a83390190565b8280546136ec90613be2565b90600052602060002090601f01602090048101928261370e5760008555613754565b82601f1061372757805160ff1916838001178555613754565b82800160010185558215613754579182015b82811115613754578251825591602001919060010190613739565b50613760929150613764565b5090565b5b808211156137605760008155600101613765565b6001600160a01b0381168114611e1b57600080fd5b6000806000806000608086880312156137a657600080fd5b853594506020860135935060408601356137bf81613779565b9250606086013567ffffffffffffffff808211156137dc57600080fd5b818801915088601f8301126137f057600080fd5b8135818111156137ff57600080fd5b89602082850101111561381157600080fd5b9699959850939650602001949392505050565b60005b8381101561383f578181015183820152602001613827565b8381111561384e576000848401525b50505050565b6020815260008251806020840152613873816040850160208701613824565b601f01601f19169190910160400192915050565b6000806040838503121561389a57600080fd5b82356138a581613779565b946020939093013593505050565b600080600080608085870312156138c957600080fd5b84356138d481613779565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b818110156139265783518352928401929184019160010161390a565b50909695505050505050565b60006020828403121561394457600080fd5b81356111cf81613779565b60008060006060848603121561396457600080fd5b833561396f81613779565b9250602084013561397f81613779565b929592945050506040919091013590565b6000602082840312156139a257600080fd5b5035919050565b6000806000606084860312156139be57600080fd5b83356139c981613779565b95602085013595506040909401359392505050565b60ff81168114611e1b57600080fd5b600080600080600080600060e0888a031215613a0857600080fd5b8735613a1381613779565b96506020880135613a2381613779565b955060408801359450606088013593506080880135613a41816139de565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613a7157600080fd5b8235613a7c81613779565b91506020830135613a8c81613779565b809150509250929050565b60008060408385031215613aaa57600080fd5b823591506020830135613a8c81613779565b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b8051801515811461322657600080fd5b600060208284031215613b0657600080fd5b6111cf82613ae4565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215613b6d57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613b9c57613b9c613b74565b500390565b6000816000190483118215151615613bbb57613bbb613b74565b500290565b600082613bdd57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c90821680613bf657607f821691505b6020821081141561321657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008219821115613c4057613c40613b74565b500190565b634e487b7160e01b600052603260045260246000fd5b600080600060608486031215613c7057600080fd5b8351613c7b81613779565b6020850151909350613c8c81613779565b9150613c9a60408501613ae4565b90509250925092565b600060208284031215613cb557600080fd5b815167ffffffffffffffff80821115613ccd57600080fd5b818401915084601f830112613ce157600080fd5b815181811115613cf357613cf3613c17565b604051601f8201601f19908116603f01168101908382118183101715613d1b57613d1b613c17565b81604052828152876020848701011115613d3457600080fd5b613d45836020830160208801613824565b979650505050505050565b7f457175616c697a657220537461626c65737761702032706f6f6c202d20000000815260008351613d8881601d850160208801613824565b6c0103830b4b932b2103bb4ba341609d1b601d918401918201528351613db581602a840160208801613824565b01602a01949350505050565b61732d60f01b815260008351613dde816002850160208801613824565b602f60f81b6002918401918201528351613dff816003840160208801613824565b01600301949350505050565b7f457175616c697a657220436c617373696320414d4d202d200000000000000000815260008351613e43816018850160208801613824565b6c0103830b4b932b2103bb4ba341609d1b6018918401918201528351613e70816025840160208801613824565b01602501949350505050565b61762d60f01b815260008351613dde816002850160208801613824565b600060208284031215613eab57600080fd5b81516111cf816139de565b600181815b80851115613ef1578160001904821115613ed757613ed7613b74565b80851615613ee457918102915b93841c9390800290613ebb565b509250929050565b600082613f0857506001610e9c565b81613f1557506000610e9c565b8160018114613f2b5760028114613f3557613f51565b6001915050610e9c565b60ff841115613f4657613f46613b74565b50506001821b610e9c565b5060208310610133831016604e8410600b8410161715613f74575081810a610e9c565b613f7e8383613eb6565b8060001904821115613f9257613f92613b74565b029392505050565b60006111cf60ff841683613ef9565b6000600019821415613fbd57613fbd613b74565b5060010190565b600060208284031215613fd657600080fd5b81516111cf81613779565b600080835481600182811c915080831680613ffd57607f831692505b602080841082141561401d57634e487b7160e01b86526022600452602486fd5b81801561403157600181146140425761406f565b60ff1986168952848901965061406f565b60008a81526020902060005b868110156140675781548b82015290850190830161404e565b505084890196505b509498975050505050505050565b6000825161408f818460208701613824565b919091019291505056fe608060405234801561001057600080fd5b50610619806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063485cc9551461003b578063533cf5ce14610050575b600080fd5b61004e610049366004610500565b610063565b005b61004e61005e366004610533565b6101be565b600054610100900460ff16158080156100835750600054600160ff909116105b8061009d5750303b15801561009d575060005460ff166001145b6101055760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610128576000805461ff0019166101001790555b6000805462010000330262010000600160b01b0319909116179055600180546001600160a01b038581166001600160a01b031992831617909255600280549285169290911691909117905580156101b9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6000546201000090046001600160a01b0316331461021e5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79207061697220636f6e74726163742063616e2063616c6c000000000060448201526064016100fc565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561026257600080fd5b505afa158015610276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029a9190610566565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b1580156102e357600080fd5b505afa1580156102f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031b9190610566565b905081841115610329578193505b80831115610335578092505b831561035257600154610352906001600160a01b03168686610376565b821561036f5760025461036f906001600160a01b03168685610376565b5050505050565b6000836001600160a01b03163b116103d05760405162461bcd60e51b815260206004820152601760248201527f50616972466565733a20696e76616c696420746f6b656e00000000000000000060448201526064016100fc565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161042c919061057f565b6000604051808303816000865af19150503d8060008114610469576040519150601f19603f3d011682016040523d82523d6000602084013e61046e565b606091505b509150915081801561049857508051158061049857508080602001905181019061049891906105ba565b61036f5760405162461bcd60e51b815260206004820152601960248201527f50616972466565733a207472616e73666572206661696c65640000000000000060448201526064016100fc565b80356001600160a01b03811681146104fb57600080fd5b919050565b6000806040838503121561051357600080fd5b61051c836104e4565b915061052a602084016104e4565b90509250929050565b60008060006060848603121561054857600080fd5b610551846104e4565b95602085013595506040909401359392505050565b60006020828403121561057857600080fd5b5051919050565b6000825160005b818110156105a05760208186018101518583015201610586565b818111156105af576000828501525b509190910192915050565b6000602082840312156105cc57600080fd5b815180151581146105dc57600080fd5b939250505056fea2646970667358221220ab85609b0e4066fb80f5f4db9c98ce5dd85c56475b3e3fdb67565561ebc0262d64736f6c63430008090033a26469706673582212200c1e79eb9aa897572d1f7371e6402b9b476892959b2c9a3161c94c12b52d84e364736f6c63430008090033a2646970667358221220add9494f3c9a8b2ae69175d77cd1afd0a1003ebcd8dbcf43a59ac96031a7715064736f6c63430008090033
Deployed Bytecode Sourcemap
45655:8911:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49672:157;;;:::i;:::-;;47548:53;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;529:25:1;;;517:2;502:18;47548:53:0;;;;;;;;46017:25;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;914:32:1;;;896:51;;884:2;869:18;46017:25:0;750:203:1;47608:54:0;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;47608:54:0;;;49508:156;;;;;;:::i;:::-;;:::i;45794:24::-;;;;;;49990:166;;;;;;:::i;:::-;;:::i;45825:26::-;;;;;;53135:118;;;;;;:::i;:::-;;:::i;49404:96::-;49477:8;:15;49404:96;;51643:545;;;;;;:::i;:::-;;:::i;45931:79::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45931:79:0;;;50336:381;;;;;;:::i;:::-;;:::i;49186:210::-;;;:::i;53517:1044::-;;;;;;:::i;:::-;;:::i;45890:32::-;;;;;-1:-1:-1;;;;;45890:32:0;;;45757:28;;;;;-1:-1:-1;;;;;45757:28:0;;;53261:116;;;:::i;45729:21::-;;;;;;;;-1:-1:-1;;;;;45729:21:0;;;45702:20;;;;;;;;;;;;;;;2321:14:1;;2314:22;2296:41;;2284:2;2269:18;45702:20:0;2156:187:1;47500:41:0;;47534:7;47500:41;;49837:145;;;;;;:::i;:::-;;:::i;51478:157::-;;;;;;:::i;:::-;;:::i;45858:25::-;;;;;-1:-1:-1;;;;;45858:25:0;;;51021:449;;;;;;:::i;:::-;;:::i;46049:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;47669:45;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;47669:45:0;;;53385:124;53479:6;;53487;;53385:124;;;-1:-1:-1;;;;;53479:6:0;;;2847:34:1;;53487:6:0;;;2912:2:1;2897:18;;2890:43;-1:-1:-1;;;53495:5:0;;;;;2976:14:1;2969:22;2949:18;;;2942:50;2797:2;2782:18;53385:124:0;2613:385:1;50725:288:0;;;;;;:::i;:::-;;:::i;50164:164::-;;;:::i;49672:157::-;49738:13;;-1:-1:-1;;;;;49738:13:0;49724:10;:27;49716:72;;;;-1:-1:-1;;;49716:72:0;;3464:2:1;49716:72:0;;;3446:21:1;;;3483:18;;;3476:30;3542:34;3522:18;;;3515:62;3594:18;;49716:72:0;;;;;;;;;49808:13;;;49799:22;;-1:-1:-1;;;;;;49799:22:0;-1:-1:-1;;;;;49808:13:0;;;49799:22;;;;;;;;49672:157::o;46017:25::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46017:25:0;;-1:-1:-1;46017:25:0;:::o;49508:156::-;49586:6;;;;;-1:-1:-1;;;;;49586:6:0;49572:10;:20;49564:58;;;;-1:-1:-1;;;49564:58:0;;3825:2:1;49564:58:0;;;3807:21:1;3864:2;3844:18;;;3837:30;-1:-1:-1;;;3883:18:1;;;3876:55;3948:18;;49564:58:0;3623:349:1;49564:58:0;49633:13;:23;;-1:-1:-1;;;;;;49633:23:0;-1:-1:-1;;;;;49633:23:0;;;;;;;;;;49508:156::o;49990:166::-;50076:10;;-1:-1:-1;;;;;50076:10:0;50062;:24;50054:52;;;;-1:-1:-1;;;50054:52:0;;;;;;;:::i;:::-;50117:17;:31;;-1:-1:-1;;;;;;50117:31:0;-1:-1:-1;;;;;50117:31:0;;;;;;;;;;49990:166::o;53135:118::-;53185:7;53212;:33;;53234:11;;53212:33;;;53222:9;;53212:33;53205:40;53135:118;-1:-1:-1;;53135:118:0:o;51643:545::-;-1:-1:-1;;;;;51793:27:0;;51698:7;51793:27;;;:18;:27;;;;;;51832:8;;51828:44;;51859:4;51643:545;-1:-1:-1;;51643:545:0:o;51828:44::-;-1:-1:-1;;;;;51894:26:0;;;51879:12;51894:26;;;:19;:26;;;;;;;51932:18;;51928:170;;52018:31;;-1:-1:-1;;;52018:31:0;;-1:-1:-1;;;;;914:32:1;;;52018:31:0;;;896:51:1;51969:120:0;;51987:72;;52006:1;;52018:24;;;;;;869:18:1;;52018:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51987:8;:72::i;:::-;52069:11;51969:8;:120::i;:::-;51962:127;51643:545;-1:-1:-1;;;;51643:545:0:o;51928:170::-;52118:5;-1:-1:-1;;;;;52112:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;;52162:11;;52112:61;;;52143:9;;52105:68;51643:545;-1:-1:-1;;;;51643:545:0:o;50336:381::-;50438:10;;-1:-1:-1;;;;;50438:10:0;50424;:24;50416:52;;;;-1:-1:-1;;;50416:52:0;;;;;;;:::i;:::-;47534:7;50487;:17;50479:42;;;;-1:-1:-1;;;50479:42:0;;;;;;;:::i;:::-;47534:7;50540:9;:19;50532:44;;;;-1:-1:-1;;;50532:44:0;;;;;;;:::i;:::-;50656:9;:19;;;;50686:11;:23;50336:381::o;49186:210::-;17067:19;17090:13;;;;;;17089:14;;17137:34;;;;-1:-1:-1;17155:12:0;;17170:1;17155:12;;;;:16;17137:34;17136:108;;;-1:-1:-1;17216:4:0;7829:19;:23;;;17177:66;;-1:-1:-1;17226:12:0;;;;;:17;17177:66;17114:204;;;;-1:-1:-1;;;17114:204:0;;5303:2:1;17114:204:0;;;5285:21:1;5342:2;5322:18;;;5315:30;5381:34;5361:18;;;5354:62;-1:-1:-1;;;5432:18:1;;;5425:44;5486:19;;17114:204:0;5101:410:1;17114:204:0;17329:12;:16;;-1:-1:-1;;17329:16:0;17344:1;17329:16;;;17356:67;;;;17391:13;:20;;-1:-1:-1;;17391:20:0;;;;;17356:67;49238:6:::1;:19:::0;;-1:-1:-1;;;;;;49268:16:0;49247:10:::1;49238:19:::0;;::::1;-1:-1:-1::0;;49268:16:0;;;;;;;;49295:10:::1;:23:::0;;-1:-1:-1;;;;;;49295:23:0::1;::::0;;::::1;::::0;;49341:12:::1;49268:8;49329:24:::0;49378:10:::1;49238:6;49364:24:::0;17445:102;;;;17496:5;17480:21;;-1:-1:-1;;17480:21:0;;;17521:14;;-1:-1:-1;5668:36:1;;17521:14:0;;5656:2:1;5641:18;17521:14:0;;;;;;;17445:102;17056:498;49186:210::o;53517:1044::-;53600:12;53643:6;-1:-1:-1;;;;;53633:16:0;:6;-1:-1:-1;;;;;53633:16:0;;;53625:31;;;;-1:-1:-1;;;53625:31:0;;5917:2:1;53625:31:0;;;5899:21:1;5956:1;5936:18;;;5929:29;-1:-1:-1;;;5974:18:1;;;5967:32;6016:18;;53625:31:0;5715:325:1;53625:31:0;53697:14;53713;53740:6;-1:-1:-1;;;;;53731:15:0;:6;-1:-1:-1;;;;;53731:15:0;;:53;;53769:6;53777;53731:53;;;53750:6;53758;53731:53;53696:88;;-1:-1:-1;53696:88:0;-1:-1:-1;;;;;;53803:20:0;;53795:35;;;;-1:-1:-1;;;53795:35:0;;6247:2:1;53795:35:0;;;6229:21:1;6286:1;6266:18;;;6259:29;-1:-1:-1;;;6304:18:1;;;6297:32;6346:18;;53795:35:0;6045:325:1;53795:35:0;-1:-1:-1;;;;;53871:15:0;;;53914:1;53871:15;;;:7;:15;;;;;;;;:23;;;;;;;;;;:31;;;;;;;;;;;;:45;53863:60;;;;-1:-1:-1;;;53863:60:0;;6577:2:1;53863:60:0;;;6559:21:1;6616:1;6596:18;;;6589:29;-1:-1:-1;;;6634:18:1;;;6627:32;6676:18;;53863:60:0;6375:325:1;53863:60:0;54009:40;;-1:-1:-1;;6954:2:1;6950:15;;;6946:24;;54009:40:0;;;6934:37:1;7005:15;;;7001:24;6987:12;;;6980:46;7072:14;;7065:22;7060:3;7056:32;7042:12;;;7035:54;53984:12:0;;7105::1;;54009:40:0;;;-1:-1:-1;;54009:40:0;;;;;;;;;;53999:51;;54009:40;53999:51;;;;54123:6;54114:50;;-1:-1:-1;;;;;54114:50:0;;;-1:-1:-1;;;;;;54114:50:0;;;-1:-1:-1;;;54114:50:0;;;-1:-1:-1;;;;;;54114:50:0;;;;;;;;;;;54115:6;54114:50;;;;;;;;;;;;;;;53999:51;-1:-1:-1;54115:6:0;;53999:51;;54190:21;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;54175:36;;54222:7;-1:-1:-1;;;;;54222:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;54287:15:0;;;;;;;:7;:15;;;;;;;;:23;;;;;;;;;;;;:31;;;;;;;;;;;;:38;;;;;-1:-1:-1;;;;;;54287:38:0;;;;;;;;54336:15;;;;;;;;;:23;;;;;;;;:31;;;;;;;;:38;;;;;;;;54430:8;:19;;-1:-1:-1;54430:19:0;;;;;;;;;;;;;;;;;;;54460:12;;;:6;:12;;;;;;:19;;-1:-1:-1;;54460:19:0;;;;;;;54537:15;;54495:58;;7324:41:1;;;7381:18;;;7374:60;;;;7450:18;;;7443:34;54287:38:0;;-1:-1:-1;54287:38:0;;:23;54495:58;;7312:2:1;7297:18;54495:58:0;;;;;;;53614:947;;;;53517:1044;;;;;:::o;53261:116::-;53308:7;53345:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;53335:34;;;;;;53328:41;;53261:116;:::o;49837:145::-;49910:6;;;;;-1:-1:-1;;;;;49910:6:0;49896:10;:20;49888:58;;;;-1:-1:-1;;;49888:58:0;;3825:2:1;49888:58:0;;;3807:21:1;3864:2;3844:18;;;3837:30;-1:-1:-1;;;3883:18:1;;;3876:55;3948:18;;49888:58:0;3623:349:1;49888:58:0;49957:8;:17;;;;;;;-1:-1:-1;;49957:17:0;;;;;;;;;49837:145::o;51478:157::-;51567:10;;-1:-1:-1;;;;;51567:10:0;51553;:24;51545:52;;;;-1:-1:-1;;;51545:52:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51608:14:0;;;;;;;:10;:14;;;;;:19;;-1:-1:-1;;;;;;51608:19:0;;;;;;;;51478:157::o;51021:449::-;51131:10;;-1:-1:-1;;;;;51131:10:0;51117;:24;51109:52;;;;-1:-1:-1;;;51109:52:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;7829:19:0;;;51172:74;;;;-1:-1:-1;;;51172:74:0;;7690:2:1;51172:74:0;;;7672:21:1;7729:2;7709:18;;;7702:30;-1:-1:-1;;;7748:18:1;;;7741:49;7807:18;;51172:74:0;7488:343:1;51172:74:0;51269:38;;-1:-1:-1;;;51269:38:0;;-1:-1:-1;;;;;914:32:1;;;51269:38:0;;;896:51:1;51257:9:0;;51269:31;;;;;;869:18:1;;51269:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51257:50;;47534:7;51326:4;:14;51318:39;;;;-1:-1:-1;;;51318:39:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;51422:26:0;;;;;;;:19;:26;;;;;:40;;-1:-1:-1;;;;;;51422:40:0;;;;;;;;51021:449::o;50725:288::-;50827:10;;-1:-1:-1;;;;;50827:10:0;50813;:24;50805:52;;;;-1:-1:-1;;;50805:52:0;;;;;;;:::i;:::-;47534:7;50876:4;:15;;50868:40;;;;-1:-1:-1;;;50868:40:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50973:25:0;;;;;;;:18;:25;;;;;:32;50725:288::o;50164:164::-;50234:17;;-1:-1:-1;;;;;50234:17:0;50220:10;:31;50212:67;;;;-1:-1:-1;;;50212:67:0;;8038:2:1;50212:67:0;;;8020:21:1;8077:2;8057:18;;;8050:30;8116:25;8096:18;;;8089:53;8159:18;;50212:67:0;7836:347:1;50212:67:0;50303:17;;50290:10;:30;;-1:-1:-1;;;;;;50290:30:0;-1:-1:-1;;;;;50303:17:0;;;50290:30;;;;;;50164:164::o;5390:98::-;5442:4;5471:1;5466;:6;;:14;;5479:1;5466:14;;;5475:1;5466:14;5459:21;5390:98;-1:-1:-1;;;5390:98:0:o;5494:97::-;5546:4;5574:1;5570;:5;:13;;5582:1;5570:13;;-1:-1:-1;;;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;565:180::-;624:6;677:2;665:9;656:7;652:23;648:32;645:52;;;693:1;690;683:12;645:52;-1:-1:-1;716:23:1;;565:180;-1:-1:-1;565:180:1:o;958:118::-;1044:5;1037:13;1030:21;1023:5;1020:32;1010:60;;1066:1;1063;1056:12;1081:241;1137:6;1190:2;1178:9;1169:7;1165:23;1161:32;1158:52;;;1206:1;1203;1196:12;1158:52;1245:9;1232:23;1264:28;1286:5;1264:28;:::i;1327:389::-;1401:6;1409;1417;1470:2;1458:9;1449:7;1445:23;1441:32;1438:52;;;1486:1;1483;1476:12;1438:52;1509:29;1528:9;1509:29;:::i;:::-;1499:39;;1557:38;1591:2;1580:9;1576:18;1557:38;:::i;:::-;1547:48;;1645:2;1634:9;1630:18;1617:32;1658:28;1680:5;1658:28;:::i;:::-;1705:5;1695:15;;;1327:389;;;;;:::o;1721:248::-;1789:6;1797;1850:2;1838:9;1829:7;1825:23;1821:32;1818:52;;;1866:1;1863;1856:12;1818:52;-1:-1:-1;;1889:23:1;;;1959:2;1944:18;;;1931:32;;-1:-1:-1;1721:248:1:o;2348:260::-;2416:6;2424;2477:2;2465:9;2456:7;2452:23;2448:32;2445:52;;;2493:1;2490;2483:12;2445:52;2516:29;2535:9;2516:29;:::i;:::-;2506:39;;2564:38;2598:2;2587:9;2583:18;2564:38;:::i;:::-;2554:48;;2348:260;;;;;:::o;3003:254::-;3071:6;3079;3132:2;3120:9;3111:7;3107:23;3103:32;3100:52;;;3148:1;3145;3138:12;3100:52;3171:29;3190:9;3171:29;:::i;:::-;3161:39;3247:2;3232:18;;;;3219:32;;-1:-1:-1;;;3003:254:1:o;3977:339::-;4179:2;4161:21;;;4218:2;4198:18;;;4191:30;-1:-1:-1;;;4252:2:1;4237:18;;4230:45;4307:2;4292:18;;3977:339::o;4321:184::-;4391:6;4444:2;4432:9;4423:7;4419:23;4415:32;4412:52;;;4460:1;4457;4450:12;4412:52;-1:-1:-1;4483:16:1;;4321:184;-1:-1:-1;4321:184:1:o;4510:245::-;4577:6;4630:2;4618:9;4609:7;4605:23;4601:32;4598:52;;;4646:1;4643;4636:12;4598:52;4678:9;4672:16;4697:28;4719:5;4697:28;:::i;4760:336::-;4962:2;4944:21;;;5001:2;4981:18;;;4974:30;-1:-1:-1;;;5035:2:1;5020:18;;5013:42;5087:2;5072:18;;4760:336::o
Swarm Source
ipfs://add9494f3c9a8b2ae69175d77cd1afd0a1003ebcd8dbcf43a59ac96031a77150
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.