Source Code
Overview
GLMR Balance
GLMR Value
$0.00View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ExchangeSystem
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity)
/**
*Submitted for verification at moonbeam.moonscan.io on 2022-08-23
*/
// SPDX-License-Identifier: MIT
pragma solidity =0.8.15;
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
/**
* @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);
}
}
}
}
/**
* @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);
}
}
}
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {}
function __Context_init_unchained() internal onlyInitializing {}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) {
return (false, 0);
}
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) {
return (false, 0);
}
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return (true, 0);
}
uint256 c = a * b;
if (c / a != b) {
return (false, 0);
}
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) {
return (false, 0);
}
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) {
return (false, 0);
}
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
interface IAsset {
function keyName() external view returns (bytes32);
function mint(address account, uint256 amount) external;
function burn(address account, uint256 amount) external;
function move(address from, address to, uint256 amount) external;
}
interface IAssetRegistry {
function assetSymbolToAddresses(bytes32 key) external view returns (address value);
function perpAddresses(bytes32 symbol) external view returns (address);
function perpSymbols(address perpAddress) external view returns (bytes32);
function isPerpAddressRegistered(address perpAddress) external view returns (bool);
function totalAssetsInUsd() external view returns (uint256 rTotal);
}
interface IConfig {
function getUint(bytes32 key) external view returns (uint256);
}
interface IOracleRouter {
function getPrice(bytes32 currencyKey) external view returns (uint256);
function exchange(bytes32 sourceKey, uint256 sourceAmount, bytes32 destKey) external view returns (uint256);
}
library SafeDecimalMath {
uint8 internal constant decimals = 18;
uint8 internal constant highPrecisionDecimals = 27;
uint256 internal constant UNIT = 10 ** uint256(decimals);
uint256 internal constant PRECISE_UNIT = 10 ** uint256(highPrecisionDecimals);
uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10 ** uint256(highPrecisionDecimals - decimals);
function unit() internal pure returns (uint256) {
return UNIT;
}
function preciseUnit() internal pure returns (uint256) {
return PRECISE_UNIT;
}
function multiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x * y / UNIT;
}
function _multiplyDecimalRound(uint256 x, uint256 y, uint256 precisionUnit) private pure returns (uint256) {
uint256 quotientTimesTen = x * y / (precisionUnit / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
function multiplyDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
return _multiplyDecimalRound(x, y, PRECISE_UNIT);
}
function multiplyDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
return _multiplyDecimalRound(x, y, UNIT);
}
function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x * UNIT / y;
}
function _divideDecimalRound(uint256 x, uint256 y, uint256 precisionUnit) private pure returns (uint256) {
uint256 resultTimesTen = x * (precisionUnit * 10) / y;
if (resultTimesTen % 10 >= 5) {
resultTimesTen += 10;
}
return resultTimesTen / 10;
}
function divideDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
return _divideDecimalRound(x, y, UNIT);
}
function divideDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
return _divideDecimalRound(x, y, PRECISE_UNIT);
}
function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) {
return i * UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR;
}
function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) {
uint256 quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
}
contract ExchangeSystem is OwnableUpgradeable {
using SafeDecimalMath for uint256;
using SafeMathUpgradeable for uint256;
event ExchangeAsset(
address fromAddr,
bytes32 sourceKey,
uint256 sourceAmount,
address destAddr,
bytes32 destKey,
uint256 destRecived,
uint256 feeForPool,
uint256 feeForFoundation
);
event FoundationFeeHolderChanged(address oldHolder, address newHolder);
event ExitPositionOnlyChanged(bool oldValue, bool newValue);
event PendingExchangeAdded(
uint256 id, address fromAddr, address destAddr, uint256 fromAmount, bytes32 fromCurrency, bytes32 toCurrency
);
event PendingExchangeSettled(
uint256 id, address settler, uint256 destRecived, uint256 feeForPool, uint256 feeForFoundation
);
event PendingExchangeReverted(uint256 id);
event AssetExitPositionOnlyChanged(bytes32 asset, bool newValue);
struct PendingExchangeEntry {
uint64 id;
uint64 timestamp;
address fromAddr;
address destAddr;
uint256 fromAmount;
bytes32 fromCurrency;
bytes32 toCurrency;
}
IAssetRegistry mAssets;
IOracleRouter mPrices;
IConfig mConfig;
address mRewardSys;
address foundationFeeHolder;
bool public exitPositionOnly;
uint256 public lastPendingExchangeEntryId;
mapping(uint256 => PendingExchangeEntry) public pendingExchangeEntries;
mapping(bytes32 => bool) assetExitPositionOnly;
bytes32 private constant CONFIG_FEE_SPLIT = "FoundationFeeSplit";
bytes32 private constant CONFIG_TRADE_SETTLEMENT_DELAY = "TradeSettlementDelay";
bytes32 private constant CONFIG_TRADE_REVERT_DELAY = "TradeRevertDelay";
bytes32 private constant LUSD_KEY = "athUSD";
function __ExchangeSystem_init(
IAssetRegistry _mAssets,
IOracleRouter _mPrices,
IConfig _mConfig,
address _mRewardSys
)
public
initializer
{
__Ownable_init();
require(address(_mAssets) != address(0), "ExchangeSystem: zero address");
require(address(_mPrices) != address(0), "ExchangeSystem: zero address");
require(address(_mConfig) != address(0), "ExchangeSystem: zero address");
require(address(_mRewardSys) != address(0), "ExchangeSystem: zero address");
mAssets = _mAssets;
mPrices = _mPrices;
mConfig = _mConfig;
mRewardSys = _mRewardSys;
}
function setFoundationFeeHolder(address _foundationFeeHolder) public onlyOwner {
require(_foundationFeeHolder != address(0), "ExchangeSystem: zero address");
require(_foundationFeeHolder != foundationFeeHolder, "ExchangeSystem: foundation fee holder not changed");
address oldHolder = foundationFeeHolder;
foundationFeeHolder = _foundationFeeHolder;
emit FoundationFeeHolderChanged(oldHolder, foundationFeeHolder);
}
function setExitPositionOnly(bool newValue) public onlyOwner {
require(exitPositionOnly != newValue, "ExchangeSystem: value not changed");
bool oldValue = exitPositionOnly;
exitPositionOnly = newValue;
emit ExitPositionOnlyChanged(oldValue, newValue);
}
function setAssetExitPositionOnly(bytes32 asset, bool newValue) public onlyOwner {
require(assetExitPositionOnly[asset] != newValue, "LnExchangeSystem: value not changed");
assetExitPositionOnly[asset] = newValue;
emit AssetExitPositionOnlyChanged(asset, newValue);
}
function exchange(bytes32 sourceKey, uint256 sourceAmount, address destAddr, bytes32 destKey) external {
return _exchange(msg.sender, sourceKey, sourceAmount, destAddr, destKey);
}
function settle(uint256 pendingExchangeEntryId) external {
_settle(pendingExchangeEntryId, msg.sender);
}
function revert(uint256 pendingExchangeEntryId) external {
_revert(pendingExchangeEntryId, msg.sender);
}
function _exchange(address fromAddr, bytes32 sourceKey, uint256 sourceAmount, address destAddr, bytes32 destKey)
private
{
// The global flag forces everyone to trade into lUSD
if (exitPositionOnly) {
require(destKey == LUSD_KEY, "ExchangeSystem: can only exit position");
}
// The asset-specific flag only forbids entering (can sell into other assets)
require(!assetExitPositionOnly[destKey], "LnExchangeSystem: can only exit position for this asset");
// We don't need the return value here. It's just for preventing entering invalid trades
getAssetByKey(destKey);
IAsset source = getAssetByKey(sourceKey);
// Only lock up the source amount here. Everything else will be performed in settlement.
// The `move` method is a special variant of `transferForm` that doesn't require approval.
source.move(fromAddr, address(this), sourceAmount);
// Record the pending entry
PendingExchangeEntry memory newPendingEntry = PendingExchangeEntry({
id: uint64(++lastPendingExchangeEntryId),
timestamp: uint64(block.timestamp),
fromAddr: fromAddr,
destAddr: destAddr,
fromAmount: sourceAmount,
fromCurrency: sourceKey,
toCurrency: destKey
});
pendingExchangeEntries[uint256(newPendingEntry.id)] = newPendingEntry;
// Emit event for off-chain indexing
emit PendingExchangeAdded(newPendingEntry.id, fromAddr, destAddr, sourceAmount, sourceKey, destKey);
}
function _settle(uint256 pendingExchangeEntryId, address settler) private {
PendingExchangeEntry memory exchangeEntry = pendingExchangeEntries[pendingExchangeEntryId];
require(exchangeEntry.id > 0, "ExchangeSystem: pending entry not found");
uint256 settlementDelay = mConfig.getUint(CONFIG_TRADE_SETTLEMENT_DELAY);
uint256 revertDelay = mConfig.getUint(CONFIG_TRADE_REVERT_DELAY);
require(settlementDelay > 0, "ExchangeSystem: settlement delay not set");
require(revertDelay > 0, "ExchangeSystem: revert delay not set");
require(
block.timestamp >= exchangeEntry.timestamp + settlementDelay, "ExchangeSystem: settlement delay not passed"
);
require(
block.timestamp <= exchangeEntry.timestamp + revertDelay, "ExchangeSystem: trade can only be reverted now"
);
IAsset source = getAssetByKey(exchangeEntry.fromCurrency);
IAsset dest = getAssetByKey(exchangeEntry.toCurrency);
uint256 destAmount =
mPrices.exchange(exchangeEntry.fromCurrency, exchangeEntry.fromAmount, exchangeEntry.toCurrency);
// This might cause a transaction to deadlock, but impact would be negligible
require(destAmount > 0, "ExchangeSystem: zero dest amount");
uint256 feeRate = mConfig.getUint(exchangeEntry.toCurrency);
uint256 destRecived = destAmount.multiplyDecimal(SafeDecimalMath.unit().sub(feeRate));
uint256 fee = destAmount.sub(destRecived);
// Fee going into the pool, to be adjusted based on foundation split
uint256 feeForPoolInUsd = mPrices.exchange(exchangeEntry.toCurrency, fee, LUSD_KEY);
// Split the fee between pool and foundation when both holder and ratio are set
uint256 foundationSplit;
if (foundationFeeHolder == address(0)) {
foundationSplit = 0;
} else {
uint256 splitRatio = mConfig.getUint(CONFIG_FEE_SPLIT);
if (splitRatio == 0) {
foundationSplit = 0;
} else {
foundationSplit = feeForPoolInUsd.multiplyDecimal(splitRatio);
feeForPoolInUsd = feeForPoolInUsd.sub(foundationSplit);
}
}
IAsset lusd = getAssetByKey(LUSD_KEY);
if (feeForPoolInUsd > 0) {
lusd.mint(mRewardSys, feeForPoolInUsd);
}
if (foundationSplit > 0) {
lusd.mint(foundationFeeHolder, foundationSplit);
}
source.burn(address(this), exchangeEntry.fromAmount);
dest.mint(exchangeEntry.destAddr, destRecived);
delete pendingExchangeEntries[pendingExchangeEntryId];
emit PendingExchangeSettled(exchangeEntry.id, settler, destRecived, feeForPoolInUsd, foundationSplit);
}
function _revert(uint256 pendingExchangeEntryId, address reverter) private {
PendingExchangeEntry memory exchangeEntry = pendingExchangeEntries[pendingExchangeEntryId];
require(exchangeEntry.id > 0, "ExchangeSystem: pending entry not found");
uint256 revertDelay = mConfig.getUint(CONFIG_TRADE_REVERT_DELAY);
require(revertDelay > 0, "ExchangeSystem: revert delay not set");
require(block.timestamp > exchangeEntry.timestamp + revertDelay, "ExchangeSystem: revert delay not passed");
IAsset source = getAssetByKey(exchangeEntry.fromCurrency);
// Refund the amount locked
source.move(address(this), exchangeEntry.fromAddr, exchangeEntry.fromAmount);
delete pendingExchangeEntries[pendingExchangeEntryId];
emit PendingExchangeReverted(exchangeEntry.id);
}
function getAssetByKey(bytes32 key) private view returns (IAsset asset) {
address assetAddress = mAssets.assetSymbolToAddresses(key);
require(assetAddress != address(0), "ExchangeSystem: asset no tfound");
return IAsset(assetAddress);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"asset","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"newValue","type":"bool"}],"name":"AssetExitPositionOnlyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fromAddr","type":"address"},{"indexed":false,"internalType":"bytes32","name":"sourceKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"destAddr","type":"address"},{"indexed":false,"internalType":"bytes32","name":"destKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"destRecived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeForPool","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeForFoundation","type":"uint256"}],"name":"ExchangeAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"oldValue","type":"bool"},{"indexed":false,"internalType":"bool","name":"newValue","type":"bool"}],"name":"ExitPositionOnlyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldHolder","type":"address"},{"indexed":false,"internalType":"address","name":"newHolder","type":"address"}],"name":"FoundationFeeHolderChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"fromAddr","type":"address"},{"indexed":false,"internalType":"address","name":"destAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"fromCurrency","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"toCurrency","type":"bytes32"}],"name":"PendingExchangeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"PendingExchangeReverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"settler","type":"address"},{"indexed":false,"internalType":"uint256","name":"destRecived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeForPool","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeForFoundation","type":"uint256"}],"name":"PendingExchangeSettled","type":"event"},{"inputs":[{"internalType":"contract IAssetRegistry","name":"_mAssets","type":"address"},{"internalType":"contract IOracleRouter","name":"_mPrices","type":"address"},{"internalType":"contract IConfig","name":"_mConfig","type":"address"},{"internalType":"address","name":"_mRewardSys","type":"address"}],"name":"__ExchangeSystem_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sourceKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"bytes32","name":"destKey","type":"bytes32"}],"name":"exchange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exitPositionOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPendingExchangeEntryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pendingExchangeEntries","outputs":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"address","name":"fromAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"bytes32","name":"fromCurrency","type":"bytes32"},{"internalType":"bytes32","name":"toCurrency","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pendingExchangeEntryId","type":"uint256"}],"name":"revert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"asset","type":"bytes32"},{"internalType":"bool","name":"newValue","type":"bool"}],"name":"setAssetExitPositionOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newValue","type":"bool"}],"name":"setExitPositionOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_foundationFeeHolder","type":"address"}],"name":"setFoundationFeeHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pendingExchangeEntryId","type":"uint256"}],"name":"settle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061283f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80638da5cb5b1161008c578063cd5d72be11610066578063cd5d72be1461027e578063d8d41a6414610295578063f2fde38b146102a8578063fcc90307146102bb57600080fd5b80638da5cb5b146102305780638df8280014610258578063a742ca021461026b57600080fd5b806371aff5a6116100bd57806371aff5a61461013b57806378ebc0be1461014e578063896bd9a21461016157600080fd5b806334938187146100e45780634609fe6c1461011e578063715018a614610133575b600080fd5b6069546101099074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020015b60405180910390f35b61013161012c36600461245f565b6102ce565b005b6101316103f9565b6101316101493660046124ad565b61040d565b61013161015c366004612509565b610807565b6101d661016f366004612526565b606b6020526000908152604090208054600182015460028301546003840154600485015460059095015467ffffffffffffffff8086169668010000000000000000909604169473ffffffffffffffffffffffffffffffffffffffff94851694909316929087565b6040805167ffffffffffffffff988916815297909616602088015273ffffffffffffffffffffffffffffffffffffffff94851695870195909552929091166060850152608084015260a083015260c082015260e001610115565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610115565b610131610266366004612526565b6109b6565b61013161027936600461253f565b6109c3565b610287606a5481565b604051908152602001610115565b6101316102a336600461257e565b6109d6565b6101316102b6366004612509565b610b0b565b6101316102c9366004612526565b610bbf565b6102d6610bc9565b6000828152606c602052604090205481151560ff909116151503610381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c6e45786368616e676553797374656d3a2076616c7565206e6f74206368616e60448201527f676564000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000828152606c602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168415159081179091558251858152918201527f2075f1bc531af9326a235c2a38c010b7e62f8c6438206bb3921758a91772959291015b60405180910390a15050565b610401610bc9565b61040b6000610c4a565b565b600054610100900460ff161580801561042d5750600054600160ff909116105b806104475750303b158015610447575060005460ff166001145b6104d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610378565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561053157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610539610cc1565b73ffffffffffffffffffffffffffffffffffffffff85166105b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff8416610633576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff83166106b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff821661072d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b6065805473ffffffffffffffffffffffffffffffffffffffff8088167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560668054878416908316179055606780548684169083161790556068805492851692909116919091179055801561080057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050505050565b61080f610bc9565b73ffffffffffffffffffffffffffffffffffffffff811661088c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b60695473ffffffffffffffffffffffffffffffffffffffff90811690821603610937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f45786368616e676553797374656d3a20666f756e646174696f6e20666565206860448201527f6f6c646572206e6f74206368616e6765640000000000000000000000000000006064820152608401610378565b6069805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fcabde22613e39ed1c8b90350ad1ae3add701158bdb714ad20f957a66e46603f991016103ed565b6109c08133610d60565b50565b6109d033858585856119ec565b50505050565b6109de610bc9565b801515606960149054906101000a900460ff16151503610a80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45786368616e676553797374656d3a2076616c7565206e6f74206368616e676560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610378565b606980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff81167401000000000000000000000000000000000000000084151581810292909217909355604080519390920460ff1680151584526020840191909152917f7e8d80276f3c46ca7cf8c3fb5a8ed9b360d0a4600b9e1fe7fc994824375a93dc91016103ed565b610b13610bc9565b73ffffffffffffffffffffffffffffffffffffffff8116610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610378565b6109c081610c4a565b6109c08133611dd5565b60335473ffffffffffffffffffffffffffffffffffffffff16331461040b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610378565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610378565b61040b612245565b6000828152606b6020908152604091829020825160e081018452815467ffffffffffffffff808216808452680100000000000000009092041693820193909352600182015473ffffffffffffffffffffffffffffffffffffffff908116948201949094526002820154909316606084015260038101546080840152600481015460a08401526005015460c0830152610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a2070656e64696e6720656e747279206e6f60448201527f7420666f756e64000000000000000000000000000000000000000000000000006064820152608401610378565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f5472616465536574746c656d656e7444656c6179000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190612599565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f547261646552657665727444656c617900000000000000000000000000000000600482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063bd02d0f590602401602060405180830381865afa158015610fc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe59190612599565b905060008211611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45786368616e676553797374656d3a20736574746c656d656e742064656c617960448201527f206e6f74207365740000000000000000000000000000000000000000000000006064820152608401610378565b60008111611106576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20736574000000000000000000000000000000000000000000000000000000006064820152608401610378565b81836020015167ffffffffffffffff1661112091906125e1565b4210156111af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f45786368616e676553797374656d3a20736574746c656d656e742064656c617960448201527f206e6f74207061737365640000000000000000000000000000000000000000006064820152608401610378565b80836020015167ffffffffffffffff166111c991906125e1565b421115611258576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45786368616e676553797374656d3a2074726164652063616e206f6e6c79206260448201527f65207265766572746564206e6f770000000000000000000000000000000000006064820152608401610378565b60006112678460a001516122e5565b905060006112788560c001516122e5565b60665460a0870151608088015160c08901516040517fee52a2f300000000000000000000000000000000000000000000000000000000815260048101939093526024830191909152604482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063ee52a2f390606401602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e9190612599565b90506000811161139a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f45786368616e676553797374656d3a207a65726f206465737420616d6f756e746044820152606401610378565b60675460c08701516040517fbd02d0f5000000000000000000000000000000000000000000000000000000008152600481019190915260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015611410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114349190612599565b9050600061145461144d83611447612402565b90612415565b8490612428565b905060006114628483612415565b60665460c08b01516040517fee52a2f30000000000000000000000000000000000000000000000000000000081526004810191909152602481018390527f6174685553440000000000000000000000000000000000000000000000000000604482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063ee52a2f390606401602060405180830381865afa15801561150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152e9190612599565b60695490915060009073ffffffffffffffffffffffffffffffffffffffff166115595750600061163a565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f466f756e646174696f6e46656553706c69740000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa1580156115e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160c9190612599565b90508060000361161f5760009150611638565b6116298382612428565b91506116358383612415565b92505b505b60006116657f61746855534400000000000000000000000000000000000000000000000000006122e5565b905082156116fa576068546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101859052908216906340c10f1990604401600060405180830381600087803b1580156116e157600080fd5b505af11580156116f5573d6000803e3d6000fd5b505050505b811561178d576069546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101849052908216906340c10f1990604401600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505b60808c01516040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481019190915273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b5050505060608c01516040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101879052908916906340c10f1990604401600060405180830381600087803b15801561188f57600080fd5b505af11580156118a3573d6000803e3d6000fd5b50505050606b60008f8152602001908152602001600020600080820160006101000a81549067ffffffffffffffff02191690556000820160086101000a81549067ffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038201600090556004820160009055600582016000905550507f294326ba97b3f6180491a5766b80aa7734496d7853114ebc895c767bc2ab0e468c600001518e8786866040516119d495949392919067ffffffffffffffff95909516855273ffffffffffffffffffffffffffffffffffffffff93909316602085015260408401919091526060830152608082015260a00190565b60405180910390a15050505050505050505050505050565b60695474010000000000000000000000000000000000000000900460ff1615611abe577f61746855534400000000000000000000000000000000000000000000000000008114611abe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45786368616e676553797374656d3a2063616e206f6e6c79206578697420706f60448201527f736974696f6e00000000000000000000000000000000000000000000000000006064820152608401610378565b6000818152606c602052604090205460ff1615611b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c6e45786368616e676553797374656d3a2063616e206f6e6c7920657869742060448201527f706f736974696f6e20666f7220746869732061737365740000000000000000006064820152608401610378565b611b66816122e5565b506000611b72856122e5565b6040517fbb35783b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152306024830152604482018790529192509082169063bb35783b90606401600060405180830381600087803b158015611bec57600080fd5b505af1158015611c00573d6000803e3d6000fd5b5050505060006040518060e00160405280606a60008154611c20906125f9565b918290555067ffffffffffffffff908116825242811660208084019190915273ffffffffffffffffffffffffffffffffffffffff808c1660408086019190915289821660608087019190915260808087018d905260a08088018f905260c09788018c9052885187166000908152606b875284902089518154978b0151891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090981698811698909817969096178655888401516001870180549187167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617905592890151600287018054919096169316929092179093559186015160038401559085015160048301559284015160059091015590519192507f60e876ffeda9093127dc8640a033c7e04db47b91b58a7f0e78eb7d52562d362491611dc491908a9088908a908c908a9067ffffffffffffffff96909616865273ffffffffffffffffffffffffffffffffffffffff94851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a150505050505050565b6000828152606b6020908152604091829020825160e081018452815467ffffffffffffffff808216808452680100000000000000009092041693820193909352600182015473ffffffffffffffffffffffffffffffffffffffff908116948201949094526002820154909316606084015260038101546080840152600481015460a08401526005015460c0830152611eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a2070656e64696e6720656e747279206e6f60448201527f7420666f756e64000000000000000000000000000000000000000000000000006064820152608401610378565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f547261646552657665727444656c617900000000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015611f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa29190612599565b905060008111612033576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20736574000000000000000000000000000000000000000000000000000000006064820152608401610378565b80826020015167ffffffffffffffff1661204d91906125e1565b42116120db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20706173736564000000000000000000000000000000000000000000000000006064820152608401610378565b60006120ea8360a001516122e5565b604080850151608086015191517fbb35783b00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff918216602482015260448101929092529192509082169063bb35783b90606401600060405180830381600087803b15801561216f57600080fd5b505af1158015612183573d6000803e3d6000fd5b5050506000868152606b6020908152604080832080547fffffffffffffffffffffffffffffffff000000000000000000000000000000001681556001810180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560028201805490911690556003810184905560048101849055600501929092558551915167ffffffffffffffff90921682527f175f0c84f551b67a31e8cca5a55fa66184a65cf9263c6f5a52aa9156e12e0fef9250016107f7565b600054610100900460ff166122dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610378565b61040b33610c4a565b6065546040517f01fb403600000000000000000000000000000000000000000000000000000000815260048101839052600091829173ffffffffffffffffffffffffffffffffffffffff909116906301fb403690602401602060405180830381865afa158015612359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237d9190612631565b905073ffffffffffffffffffffffffffffffffffffffff81166123fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45786368616e676553797374656d3a206173736574206e6f2074666f756e64006044820152606401610378565b92915050565b60006124106012600a61276e565b905090565b6000612421828461277a565b9392505050565b60006124366012600a61276e565b6124408385612791565b61242191906127ce565b8035801515811461245a57600080fd5b919050565b6000806040838503121561247257600080fd5b823591506124826020840161244a565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff811681146109c057600080fd5b600080600080608085870312156124c357600080fd5b84356124ce8161248b565b935060208501356124de8161248b565b925060408501356124ee8161248b565b915060608501356124fe8161248b565b939692955090935050565b60006020828403121561251b57600080fd5b81356124218161248b565b60006020828403121561253857600080fd5b5035919050565b6000806000806080858703121561255557600080fd5b8435935060208501359250604085013561256e8161248b565b9396929550929360600135925050565b60006020828403121561259057600080fd5b6124218261244a565b6000602082840312156125ab57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156125f4576125f46125b2565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361262a5761262a6125b2565b5060010190565b60006020828403121561264357600080fd5b81516124218161248b565b600181815b808511156126a757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561268d5761268d6125b2565b8085161561269a57918102915b93841c9390800290612653565b509250929050565b6000826126be575060016123fc565b816126cb575060006123fc565b81600181146126e157600281146126eb57612707565b60019150506123fc565b60ff8411156126fc576126fc6125b2565b50506001821b6123fc565b5060208310610133831016604e8410600b841016171561272a575081810a6123fc565b612734838361264e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612766576127666125b2565b029392505050565b600061242183836126af565b60008282101561278c5761278c6125b2565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127c9576127c96125b2565b500290565b600082612804577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea2646970667358221220b62103c406ae9a79ff020549436b019377509cbbeb9321a4943efadcc531cc3964736f6c634300080f0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80638da5cb5b1161008c578063cd5d72be11610066578063cd5d72be1461027e578063d8d41a6414610295578063f2fde38b146102a8578063fcc90307146102bb57600080fd5b80638da5cb5b146102305780638df8280014610258578063a742ca021461026b57600080fd5b806371aff5a6116100bd57806371aff5a61461013b57806378ebc0be1461014e578063896bd9a21461016157600080fd5b806334938187146100e45780634609fe6c1461011e578063715018a614610133575b600080fd5b6069546101099074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020015b60405180910390f35b61013161012c36600461245f565b6102ce565b005b6101316103f9565b6101316101493660046124ad565b61040d565b61013161015c366004612509565b610807565b6101d661016f366004612526565b606b6020526000908152604090208054600182015460028301546003840154600485015460059095015467ffffffffffffffff8086169668010000000000000000909604169473ffffffffffffffffffffffffffffffffffffffff94851694909316929087565b6040805167ffffffffffffffff988916815297909616602088015273ffffffffffffffffffffffffffffffffffffffff94851695870195909552929091166060850152608084015260a083015260c082015260e001610115565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610115565b610131610266366004612526565b6109b6565b61013161027936600461253f565b6109c3565b610287606a5481565b604051908152602001610115565b6101316102a336600461257e565b6109d6565b6101316102b6366004612509565b610b0b565b6101316102c9366004612526565b610bbf565b6102d6610bc9565b6000828152606c602052604090205481151560ff909116151503610381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c6e45786368616e676553797374656d3a2076616c7565206e6f74206368616e60448201527f676564000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000828152606c602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168415159081179091558251858152918201527f2075f1bc531af9326a235c2a38c010b7e62f8c6438206bb3921758a91772959291015b60405180910390a15050565b610401610bc9565b61040b6000610c4a565b565b600054610100900460ff161580801561042d5750600054600160ff909116105b806104475750303b158015610447575060005460ff166001145b6104d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610378565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561053157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610539610cc1565b73ffffffffffffffffffffffffffffffffffffffff85166105b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff8416610633576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff83166106b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b73ffffffffffffffffffffffffffffffffffffffff821661072d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b6065805473ffffffffffffffffffffffffffffffffffffffff8088167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560668054878416908316179055606780548684169083161790556068805492851692909116919091179055801561080057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050505050565b61080f610bc9565b73ffffffffffffffffffffffffffffffffffffffff811661088c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45786368616e676553797374656d3a207a65726f2061646472657373000000006044820152606401610378565b60695473ffffffffffffffffffffffffffffffffffffffff90811690821603610937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f45786368616e676553797374656d3a20666f756e646174696f6e20666565206860448201527f6f6c646572206e6f74206368616e6765640000000000000000000000000000006064820152608401610378565b6069805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fcabde22613e39ed1c8b90350ad1ae3add701158bdb714ad20f957a66e46603f991016103ed565b6109c08133610d60565b50565b6109d033858585856119ec565b50505050565b6109de610bc9565b801515606960149054906101000a900460ff16151503610a80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45786368616e676553797374656d3a2076616c7565206e6f74206368616e676560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610378565b606980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff81167401000000000000000000000000000000000000000084151581810292909217909355604080519390920460ff1680151584526020840191909152917f7e8d80276f3c46ca7cf8c3fb5a8ed9b360d0a4600b9e1fe7fc994824375a93dc91016103ed565b610b13610bc9565b73ffffffffffffffffffffffffffffffffffffffff8116610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610378565b6109c081610c4a565b6109c08133611dd5565b60335473ffffffffffffffffffffffffffffffffffffffff16331461040b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610378565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610378565b61040b612245565b6000828152606b6020908152604091829020825160e081018452815467ffffffffffffffff808216808452680100000000000000009092041693820193909352600182015473ffffffffffffffffffffffffffffffffffffffff908116948201949094526002820154909316606084015260038101546080840152600481015460a08401526005015460c0830152610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a2070656e64696e6720656e747279206e6f60448201527f7420666f756e64000000000000000000000000000000000000000000000000006064820152608401610378565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f5472616465536574746c656d656e7444656c6179000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190612599565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f547261646552657665727444656c617900000000000000000000000000000000600482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063bd02d0f590602401602060405180830381865afa158015610fc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe59190612599565b905060008211611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45786368616e676553797374656d3a20736574746c656d656e742064656c617960448201527f206e6f74207365740000000000000000000000000000000000000000000000006064820152608401610378565b60008111611106576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20736574000000000000000000000000000000000000000000000000000000006064820152608401610378565b81836020015167ffffffffffffffff1661112091906125e1565b4210156111af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f45786368616e676553797374656d3a20736574746c656d656e742064656c617960448201527f206e6f74207061737365640000000000000000000000000000000000000000006064820152608401610378565b80836020015167ffffffffffffffff166111c991906125e1565b421115611258576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45786368616e676553797374656d3a2074726164652063616e206f6e6c79206260448201527f65207265766572746564206e6f770000000000000000000000000000000000006064820152608401610378565b60006112678460a001516122e5565b905060006112788560c001516122e5565b60665460a0870151608088015160c08901516040517fee52a2f300000000000000000000000000000000000000000000000000000000815260048101939093526024830191909152604482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063ee52a2f390606401602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e9190612599565b90506000811161139a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f45786368616e676553797374656d3a207a65726f206465737420616d6f756e746044820152606401610378565b60675460c08701516040517fbd02d0f5000000000000000000000000000000000000000000000000000000008152600481019190915260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015611410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114349190612599565b9050600061145461144d83611447612402565b90612415565b8490612428565b905060006114628483612415565b60665460c08b01516040517fee52a2f30000000000000000000000000000000000000000000000000000000081526004810191909152602481018390527f6174685553440000000000000000000000000000000000000000000000000000604482015291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063ee52a2f390606401602060405180830381865afa15801561150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152e9190612599565b60695490915060009073ffffffffffffffffffffffffffffffffffffffff166115595750600061163a565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f466f756e646174696f6e46656553706c69740000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa1580156115e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160c9190612599565b90508060000361161f5760009150611638565b6116298382612428565b91506116358383612415565b92505b505b60006116657f61746855534400000000000000000000000000000000000000000000000000006122e5565b905082156116fa576068546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101859052908216906340c10f1990604401600060405180830381600087803b1580156116e157600080fd5b505af11580156116f5573d6000803e3d6000fd5b505050505b811561178d576069546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101849052908216906340c10f1990604401600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505b60808c01516040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481019190915273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b5050505060608c01516040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101879052908916906340c10f1990604401600060405180830381600087803b15801561188f57600080fd5b505af11580156118a3573d6000803e3d6000fd5b50505050606b60008f8152602001908152602001600020600080820160006101000a81549067ffffffffffffffff02191690556000820160086101000a81549067ffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038201600090556004820160009055600582016000905550507f294326ba97b3f6180491a5766b80aa7734496d7853114ebc895c767bc2ab0e468c600001518e8786866040516119d495949392919067ffffffffffffffff95909516855273ffffffffffffffffffffffffffffffffffffffff93909316602085015260408401919091526060830152608082015260a00190565b60405180910390a15050505050505050505050505050565b60695474010000000000000000000000000000000000000000900460ff1615611abe577f61746855534400000000000000000000000000000000000000000000000000008114611abe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45786368616e676553797374656d3a2063616e206f6e6c79206578697420706f60448201527f736974696f6e00000000000000000000000000000000000000000000000000006064820152608401610378565b6000818152606c602052604090205460ff1615611b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c6e45786368616e676553797374656d3a2063616e206f6e6c7920657869742060448201527f706f736974696f6e20666f7220746869732061737365740000000000000000006064820152608401610378565b611b66816122e5565b506000611b72856122e5565b6040517fbb35783b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152306024830152604482018790529192509082169063bb35783b90606401600060405180830381600087803b158015611bec57600080fd5b505af1158015611c00573d6000803e3d6000fd5b5050505060006040518060e00160405280606a60008154611c20906125f9565b918290555067ffffffffffffffff908116825242811660208084019190915273ffffffffffffffffffffffffffffffffffffffff808c1660408086019190915289821660608087019190915260808087018d905260a08088018f905260c09788018c9052885187166000908152606b875284902089518154978b0151891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090981698811698909817969096178655888401516001870180549187167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617905592890151600287018054919096169316929092179093559186015160038401559085015160048301559284015160059091015590519192507f60e876ffeda9093127dc8640a033c7e04db47b91b58a7f0e78eb7d52562d362491611dc491908a9088908a908c908a9067ffffffffffffffff96909616865273ffffffffffffffffffffffffffffffffffffffff94851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a150505050505050565b6000828152606b6020908152604091829020825160e081018452815467ffffffffffffffff808216808452680100000000000000009092041693820193909352600182015473ffffffffffffffffffffffffffffffffffffffff908116948201949094526002820154909316606084015260038101546080840152600481015460a08401526005015460c0830152611eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a2070656e64696e6720656e747279206e6f60448201527f7420666f756e64000000000000000000000000000000000000000000000000006064820152608401610378565b6067546040517fbd02d0f50000000000000000000000000000000000000000000000000000000081527f547261646552657665727444656c617900000000000000000000000000000000600482015260009173ffffffffffffffffffffffffffffffffffffffff169063bd02d0f590602401602060405180830381865afa158015611f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa29190612599565b905060008111612033576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20736574000000000000000000000000000000000000000000000000000000006064820152608401610378565b80826020015167ffffffffffffffff1661204d91906125e1565b42116120db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45786368616e676553797374656d3a207265766572742064656c6179206e6f7460448201527f20706173736564000000000000000000000000000000000000000000000000006064820152608401610378565b60006120ea8360a001516122e5565b604080850151608086015191517fbb35783b00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff918216602482015260448101929092529192509082169063bb35783b90606401600060405180830381600087803b15801561216f57600080fd5b505af1158015612183573d6000803e3d6000fd5b5050506000868152606b6020908152604080832080547fffffffffffffffffffffffffffffffff000000000000000000000000000000001681556001810180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560028201805490911690556003810184905560048101849055600501929092558551915167ffffffffffffffff90921682527f175f0c84f551b67a31e8cca5a55fa66184a65cf9263c6f5a52aa9156e12e0fef9250016107f7565b600054610100900460ff166122dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610378565b61040b33610c4a565b6065546040517f01fb403600000000000000000000000000000000000000000000000000000000815260048101839052600091829173ffffffffffffffffffffffffffffffffffffffff909116906301fb403690602401602060405180830381865afa158015612359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237d9190612631565b905073ffffffffffffffffffffffffffffffffffffffff81166123fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45786368616e676553797374656d3a206173736574206e6f2074666f756e64006044820152606401610378565b92915050565b60006124106012600a61276e565b905090565b6000612421828461277a565b9392505050565b60006124366012600a61276e565b6124408385612791565b61242191906127ce565b8035801515811461245a57600080fd5b919050565b6000806040838503121561247257600080fd5b823591506124826020840161244a565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff811681146109c057600080fd5b600080600080608085870312156124c357600080fd5b84356124ce8161248b565b935060208501356124de8161248b565b925060408501356124ee8161248b565b915060608501356124fe8161248b565b939692955090935050565b60006020828403121561251b57600080fd5b81356124218161248b565b60006020828403121561253857600080fd5b5035919050565b6000806000806080858703121561255557600080fd5b8435935060208501359250604085013561256e8161248b565b9396929550929360600135925050565b60006020828403121561259057600080fd5b6124218261244a565b6000602082840312156125ab57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156125f4576125f46125b2565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361262a5761262a6125b2565b5060010190565b60006020828403121561264357600080fd5b81516124218161248b565b600181815b808511156126a757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561268d5761268d6125b2565b8085161561269a57918102915b93841c9390800290612653565b509250929050565b6000826126be575060016123fc565b816126cb575060006123fc565b81600181146126e157600281146126eb57612707565b60019150506123fc565b60ff8411156126fc576126fc6125b2565b50506001821b6123fc565b5060208310610133831016604e8410600b841016171561272a575081810a6123fc565b612734838361264e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612766576127666125b2565b029392505050565b600061242183836126af565b60008282101561278c5761278c6125b2565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127c9576127c96125b2565b500290565b600082612804577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea2646970667358221220b62103c406ae9a79ff020549436b019377509cbbeb9321a4943efadcc531cc3964736f6c634300080f0033
Deployed Bytecode Sourcemap
30974:9750:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32323:28;;;;;;;;;;;;;;;179:14:1;;172:22;154:41;;142:2;127:18;32323:28:0;;;;;;;;34324:303;;;;;;:::i;:::-;;:::i;:::-;;16414:103;;;:::i;32832:700::-;;;;;;:::i;:::-;;:::i;33540:470::-;;;;;;:::i;:::-;;:::i;32408:70::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2374:18:1;2419:15;;;2401:34;;2471:15;;;;2466:2;2451:18;;2444:43;2506:42;2584:15;;;2564:18;;;2557:43;;;;2636:15;;;;2631:2;2616:18;;2609:43;2683:3;2668:19;;2661:35;2727:3;2712:19;;2705:35;2771:3;2756:19;;2749:35;2351:3;2336:19;32408:70:0;2053:737:1;15766:87:0;15839:6;;15766:87;;15839:6;;;;2941:74:1;;2929:2;2914:18;15766:87:0;2795:226:1;34837:119:0;;;;;;:::i;:::-;;:::i;34635:194::-;;;;;;:::i;:::-;;:::i;32360:41::-;;;;;;;;;3645:25:1;;;3633:2;3618:18;32360:41:0;3499:177:1;34018:298:0;;;;;;:::i;:::-;;:::i;16672:201::-;;;;;;:::i;:::-;;:::i;34964:119::-;;;;;;:::i;:::-;;:::i;34324:303::-;15652:13;:11;:13::i;:::-;34424:28:::1;::::0;;;:21:::1;:28;::::0;;;;;:40;::::1;;:28;::::0;;::::1;:40;;::::0;34416:88:::1;;;::::0;::::1;::::0;;4068:2:1;34416:88:0::1;::::0;::::1;4050:21:1::0;4107:2;4087:18;;;4080:30;4146:34;4126:18;;;4119:62;4217:5;4197:18;;;4190:33;4240:19;;34416:88:0::1;;;;;;;;;34517:28;::::0;;;:21:::1;:28;::::0;;;;;;;;:39;;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;34574:45;;4438:25:1;;;4479:18;;;4472:50;34574:45:0::1;::::0;4411:18:1;34574:45:0::1;;;;;;;;34324:303:::0;;:::o;16414:103::-;15652:13;:11;:13::i;:::-;16479:30:::1;16506:1;16479:18;:30::i;:::-;16414:103::o:0;32832:700::-;10664:19;10687:13;;;;;;10686:14;;10734:34;;;;-1:-1:-1;10752:12:0;;10767:1;10752:12;;;;:16;10734:34;10733:108;;;-1:-1:-1;10813:4:0;1724:19;:23;;;10774:66;;-1:-1:-1;10823:12:0;;;;;:17;10774:66;10711:204;;;;;;;4735:2:1;10711:204:0;;;4717:21:1;4774:2;4754:18;;;4747:30;4813:34;4793:18;;;4786:62;4884:16;4864:18;;;4857:44;4918:19;;10711:204:0;4533:410:1;10711:204:0;10926:12;:16;;;;10941:1;10926:16;;;10953:67;;;;10988:13;:20;;;;;;;;10953:67;33047:16:::1;:14;:16::i;:::-;33084:31;::::0;::::1;33076:72;;;::::0;::::1;::::0;;5150:2:1;33076:72:0::1;::::0;::::1;5132:21:1::0;5189:2;5169:18;;;5162:30;5228;5208:18;;;5201:58;5276:18;;33076:72:0::1;4948:352:1::0;33076:72:0::1;33167:31;::::0;::::1;33159:72;;;::::0;::::1;::::0;;5150:2:1;33159:72:0::1;::::0;::::1;5132:21:1::0;5189:2;5169:18;;;5162:30;5228;5208:18;;;5201:58;5276:18;;33159:72:0::1;4948:352:1::0;33159:72:0::1;33250:31;::::0;::::1;33242:72;;;::::0;::::1;::::0;;5150:2:1;33242:72:0::1;::::0;::::1;5132:21:1::0;5189:2;5169:18;;;5162:30;5228;5208:18;;;5201:58;5276:18;;33242:72:0::1;4948:352:1::0;33242:72:0::1;33333:34;::::0;::::1;33325:75;;;::::0;::::1;::::0;;5150:2:1;33325:75:0::1;::::0;::::1;5132:21:1::0;5189:2;5169:18;;;5162:30;5228;5208:18;;;5201:58;5276:18;;33325:75:0::1;4948:352:1::0;33325:75:0::1;33413:7;:18:::0;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;;33442:7:::1;:18:::0;;;;::::1;::::0;;::::1;;::::0;;33471:7:::1;:18:::0;;;;::::1;::::0;;::::1;;::::0;;33500:10:::1;:24:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;11042:102;;;;11093:5;11077:21;;;;;;11118:14;;-1:-1:-1;5457:36:1;;11118:14:0;;5445:2:1;5430:18;11118:14:0;;;;;;;;11042:102;10653:498;32832:700;;;;:::o;33540:470::-;15652:13;:11;:13::i;:::-;33638:34:::1;::::0;::::1;33630:75;;;::::0;::::1;::::0;;5150:2:1;33630:75:0::1;::::0;::::1;5132:21:1::0;5189:2;5169:18;;;5162:30;5228;5208:18;;;5201:58;5276:18;;33630:75:0::1;4948:352:1::0;33630:75:0::1;33748:19;::::0;::::1;::::0;;::::1;33724:43:::0;;::::1;::::0;33716:105:::1;;;::::0;::::1;::::0;;5706:2:1;33716:105:0::1;::::0;::::1;5688:21:1::0;5745:2;5725:18;;;5718:30;5784:34;5764:18;;;5757:62;5855:19;5835:18;;;5828:47;5892:19;;33716:105:0::1;5504:413:1::0;33716:105:0::1;33854:19;::::0;;::::1;33884:42:::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;33944:58:::1;::::0;;33854:19;;;::::1;6157:34:1::0;;;6222:2;6207:18;;6200:43;;;;33944:58:0::1;::::0;6069:18:1;33944:58:0::1;5922:327:1::0;34837:119:0;34905:43;34913:22;34937:10;34905:7;:43::i;:::-;34837:119;:::o;34635:194::-;34756:65;34766:10;34778:9;34789:12;34803:8;34813:7;34756:9;:65::i;:::-;34635:194;;;;:::o;34018:298::-;15652:13;:11;:13::i;:::-;34118:8:::1;34098:28;;:16;;;;;;;;;;;:28;;::::0;34090:74:::1;;;::::0;::::1;::::0;;6456:2:1;34090:74:0::1;::::0;::::1;6438:21:1::0;6495:2;6475:18;;;6468:30;6534:34;6514:18;;;6507:62;6605:3;6585:18;;;6578:31;6626:19;;34090:74:0::1;6254:397:1::0;34090:74:0::1;34193:16;::::0;;34220:27;;::::1;34193:16:::0;34220:27;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;34265:43:::1;::::0;;34193:16;;;::::1;;;6843:14:1::0;;6836:22;6818:41;;6890:2;6875:18;;6868:50;;;;34193:16:0;34265:43:::1;::::0;6791:18:1;34265:43:0::1;6656:268:1::0;16672:201:0;15652:13;:11;:13::i;:::-;16761:22:::1;::::0;::::1;16753:73;;;::::0;::::1;::::0;;7131:2:1;16753:73:0::1;::::0;::::1;7113:21:1::0;7170:2;7150:18;;;7143:30;7209:34;7189:18;;;7182:62;7280:8;7260:18;;;7253:36;7306:19;;16753:73:0::1;6929:402:1::0;16753:73:0::1;16837:28;16856:8;16837:18;:28::i;34964:119::-:0;35032:43;35040:22;35064:10;35032:7;:43::i;15931:132::-;15839:6;;15995:23;15839:6;14067:10;15995:23;15987:68;;;;;;;7538:2:1;15987:68:0;;;7520:21:1;;;7557:18;;;7550:30;7616:34;7596:18;;;7589:62;7668:18;;15987:68:0;7336:356:1;17033:191:0;17126:6;;;;17143:17;;;;;;;;;;;17176:40;;17126:6;;;17143:17;17126:6;;17176:40;;17107:16;;17176:40;17096:128;17033:191;:::o;15309:97::-;12505:13;;;;;;;12497:69;;;;;;;7899:2:1;12497:69:0;;;7881:21:1;7938:2;7918:18;;;7911:30;7977:34;7957:18;;;7950:62;8048:13;8028:18;;;8021:41;8079:19;;12497:69:0;7697:407:1;12497:69:0;15372:26:::1;:24;:26::i;36728:2849::-:0;36813:41;36857:46;;;:22;:46;;;;;;;;;36813:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36914:72;;;;;;;8311:2:1;36914:72:0;;;8293:21:1;8350:2;8330:18;;;8323:30;8389:34;8369:18;;;8362:62;8460:9;8440:18;;;8433:37;8487:19;;36914:72:0;8109:403:1;36914:72:0;37025:7;;:46;;;;;37041:29;37025:46;;;3645:25:1;36999:23:0;;37025:7;;;:15;;3618:18:1;;37025:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37104:7;;:42;;;;;37120:25;37104:42;;;3645:25:1;36999:72:0;;-1:-1:-1;37082:19:0;;37104:7;;;;;:15;;3618:18:1;;37104:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37082:64;;37183:1;37165:15;:19;37157:72;;;;;;;9090:2:1;37157:72:0;;;9072:21:1;9129:2;9109:18;;;9102:30;9168:34;9148:18;;;9141:62;9239:10;9219:18;;;9212:38;9267:19;;37157:72:0;8888:404:1;37157:72:0;37262:1;37248:11;:15;37240:64;;;;;;;9499:2:1;37240:64:0;;;9481:21:1;9538:2;9518:18;;;9511:30;9577:34;9557:18;;;9550:62;9648:6;9628:18;;;9621:34;9672:19;;37240:64:0;9297:400:1;37240:64:0;37382:15;37356:13;:23;;;:41;;;;;;:::i;:::-;37337:15;:60;;37315:140;;;;;;;10226:2:1;37315:140:0;;;10208:21:1;10265:2;10245:18;;;10238:30;10304:34;10284:18;;;10277:62;10375:13;10355:18;;;10348:41;10406:19;;37315:140:0;10024:407:1;37315:140:0;37533:11;37507:13;:23;;;:37;;;;;;:::i;:::-;37488:15;:56;;37466:139;;;;;;;10638:2:1;37466:139:0;;;10620:21:1;10677:2;10657:18;;;10650:30;10716:34;10696:18;;;10689:62;10787:16;10767:18;;;10760:44;10821:19;;37466:139:0;10436:410:1;37466:139:0;37618:13;37634:41;37648:13;:26;;;37634:13;:41::i;:::-;37618:57;;37686:11;37700:39;37714:13;:24;;;37700:13;:39::i;:::-;37784:7;;37801:26;;;;37829:24;;;;37855;;;;37784:96;;;;;;;;11053:25:1;;;;11094:18;;;11087:34;;;;11137:18;;;11130:34;37686:53:0;;-1:-1:-1;37750:18:0;;37784:7;;;;;:16;;11026:18:1;;37784:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37750:130;;38001:1;37988:10;:14;37980:59;;;;;;;11377:2:1;37980:59:0;;;11359:21:1;;;11396:18;;;11389:30;11455:34;11435:18;;;11428:62;11507:18;;37980:59:0;11175:356:1;37980:59:0;38070:7;;38086:24;;;;38070:41;;;;;;;;3645:25:1;;;;38052:15:0;;38070:7;;;:15;;3618:18:1;;38070:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38052:59;;38122:19;38144:63;38171:35;38198:7;38171:22;:20;:22::i;:::-;:26;;:35::i;:::-;38144:10;;:26;:63::i;:::-;38122:85;-1:-1:-1;38218:11:0;38232:27;:10;38122:85;38232:14;:27::i;:::-;38376:7;;38393:24;;;;38376:57;;;;;;;;11053:25:1;;;;11094:18;;;11087:34;;;38424:8:0;11137:18:1;;;11130:34;38218:41:0;;-1:-1:-1;38350:23:0;;38376:7;;;;;:16;;11026:18:1;;38376:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38573:19;;38350:83;;-1:-1:-1;38535:23:0;;38573:33;:19;38569:438;;-1:-1:-1;38641:1:0;38569:438;;;38696:7;;:33;;;;;38712:16;38696:33;;;3645:25:1;38675:18:0;;38696:7;;;:15;;3618:18:1;;38696:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38675:54;;38750:10;38764:1;38750:15;38746:250;;38804:1;38786:19;;38746:250;;;38864:43;:15;38896:10;38864:31;:43::i;:::-;38846:61;-1:-1:-1;38944:36:0;:15;38846:61;38944:19;:36::i;:::-;38926:54;;38746:250;38660:347;38569:438;39019:11;39033:23;39047:8;39033:13;:23::i;:::-;39019:37;-1:-1:-1;39073:19:0;;39069:90;;39119:10;;39109:38;;;;;:9;39119:10;;;39109:38;;;11710:74:1;11800:18;;;11793:34;;;39109:9:0;;;;;;11683:18:1;;39109:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39069:90;39173:19;;39169:99;;39219:19;;39209:47;;;;;:9;39219:19;;;39209:47;;;11710:74:1;11800:18;;;11793:34;;;39209:9:0;;;;;;11683:18:1;;39209:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39169:99;39307:24;;;;39280:52;;;;;39300:4;39280:52;;;11710:74:1;11800:18;;;11793:34;;;;39280:11:0;;;;;;11683:18:1;;39280:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;39353:22:0;;;;39343:46;;;;;:9;11728:55:1;;;39343:46:0;;;11710:74:1;11800:18;;;11793:34;;;39343:9:0;;;;;;11683:18:1;;39343:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39409:22;:46;39432:22;39409:46;;;;;;;;;;;;39402:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39473:96;39496:13;:16;;;39514:7;39523:11;39536:15;39553;39473:96;;;;;;;;;12126:18:1;12114:31;;;;12096:50;;12194:42;12182:55;;;;12177:2;12162:18;;12155:83;12269:2;12254:18;;12247:34;;;;12312:2;12297:18;;12290:34;12355:3;12340:19;;12333:35;12083:3;12068:19;;11838:536;39473:96:0;;;;;;;;36802:2775;;;;;;;;;;;;36728:2849;;:::o;35091:1629::-;35304:16;;;;;;;35300:119;;;35356:8;35345:7;:19;35337:70;;;;;;;12581:2:1;35337:70:0;;;12563:21:1;12620:2;12600:18;;;12593:30;12659:34;12639:18;;;12632:62;12730:8;12710:18;;;12703:36;12756:19;;35337:70:0;12379:402:1;35337:70:0;35527:30;;;;:21;:30;;;;;;;;35526:31;35518:99;;;;;;;12988:2:1;35518:99:0;;;12970:21:1;13027:2;13007:18;;;13000:30;13066:34;13046:18;;;13039:62;13137:25;13117:18;;;13110:53;13180:19;;35518:99:0;12786:419:1;35518:99:0;35728:22;35742:7;35728:13;:22::i;:::-;;35763:13;35779:24;35793:9;35779:13;:24::i;:::-;36014:50;;;;;:11;13491:15:1;;;36014:50:0;;;13473:34:1;36044:4:0;13523:18:1;;;13516:43;13575:18;;;13568:34;;;35763:40:0;;-1:-1:-1;36014:11:0;;;;;;13385:18:1;;36014:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36114:43;36160:314;;;;;;;;36209:26;;36207:28;;;;;:::i;:::-;;;;;-1:-1:-1;36160:314:0;;;;;;36269:15;36160:314;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36516:18;;36508:27;;-1:-1:-1;36485:51:0;;;:22;:51;;;;;:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36618:94;;36114:360;;-1:-1:-1;36618:94:0;;;;36485:69;36310:8;;36343;;36378:12;;36419:9;;36455:7;;14129:18:1;14117:31;;;;14099:50;;14168:42;14246:15;;;14241:2;14226:18;;14219:43;14298:15;;;;14293:2;14278:18;;14271:43;14345:2;14330:18;;14323:34;14388:3;14373:19;;14366:35;;;;14432:3;14417:19;;14410:35;14086:3;14071:19;;13813:638;36618:94:0;;;;;;;;35226:1494;;35091:1629;;;;;:::o;39585:858::-;39671:41;39715:46;;;:22;:46;;;;;;;;;39671:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39772:72;;;;;;;8311:2:1;39772:72:0;;;8293:21:1;8350:2;8330:18;;;8323:30;8389:34;8369:18;;;8362:62;8460:9;8440:18;;;8433:37;8487:19;;39772:72:0;8109:403:1;39772:72:0;39879:7;;:42;;;;;39895:25;39879:42;;;3645:25:1;39857:19:0;;39879:7;;;:15;;3618:18:1;;39879:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39857:64;;39954:1;39940:11;:15;39932:64;;;;;;;9499:2:1;39932:64:0;;;9481:21:1;9538:2;9518:18;;;9511:30;9577:34;9557:18;;;9550:62;9648:6;9628:18;;;9621:34;9672:19;;39932:64:0;9297:400:1;39932:64:0;40059:11;40033:13;:23;;;:37;;;;;;:::i;:::-;40015:15;:55;40007:107;;;;;;;14658:2:1;40007:107:0;;;14640:21:1;14697:2;14677:18;;;14670:30;14736:34;14716:18;;;14709:62;14807:9;14787:18;;;14780:37;14834:19;;40007:107:0;14456:403:1;40007:107:0;40127:13;40143:41;40157:13;:26;;;40143:13;:41::i;:::-;40261:22;;;;;40285:24;;;;40234:76;;;;;40254:4;40234:76;;;13473:34:1;40234:11:0;13543:15:1;;;13523:18;;;13516:43;13575:18;;;13568:34;;;;40127:57:0;;-1:-1:-1;40234:11:0;;;;;;13385:18:1;;40234:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;40330:46:0;;;;:22;:46;;;;;;;;40323:53;;;;;;-1:-1:-1;40323:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40418:16;;40394:41;;15039:18:1;15027:31;;;15009:50;;40394:41:0;;-1:-1:-1;14982:18:1;40394:41:0;14864:201:1;15414:113:0;12505:13;;;;;;;12497:69;;;;;;;7899:2:1;12497:69:0;;;7881:21:1;7938:2;7918:18;;;7911:30;7977:34;7957:18;;;7950:62;8048:13;8028:18;;;8021:41;8079:19;;12497:69:0;7697:407:1;12497:69:0;15487:32:::1;14067:10:::0;15487:18:::1;:32::i;40451:270::-:0;40557:7;;:35;;;;;;;;3645:25:1;;;40509:12:0;;;;40557:7;;;;;:30;;3618:18:1;;40557:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40534:58;-1:-1:-1;40611:26:0;;;40603:70;;;;;;;15544:2:1;40603:70:0;;;15526:21:1;15583:2;15563:18;;;15556:30;15622:33;15602:18;;;15595:61;15673:18;;40603:70:0;15342:355:1;40603:70:0;40700:12;40451:270;-1:-1:-1;;40451:270:0:o;28809:78::-;28848:7;28569:23;28468:2;28569;:23;:::i;:::-;28868:11;;28809:78;:::o;20912:98::-;20970:7;20997:5;21001:1;20997;:5;:::i;:::-;20990:12;20912:98;-1:-1:-1;;;20912:98:0:o;28996:117::-;29066:7;28569:23;28468:2;28569;:23;:::i;:::-;29093:5;29097:1;29093;:5;:::i;:::-;:12;;;;:::i;206:160:1:-;271:20;;327:13;;320:21;310:32;;300:60;;356:1;353;346:12;300:60;206:160;;;:::o;371:248::-;436:6;444;497:2;485:9;476:7;472:23;468:32;465:52;;;513:1;510;503:12;465:52;549:9;536:23;526:33;;578:35;609:2;598:9;594:18;578:35;:::i;:::-;568:45;;371:248;;;;;:::o;624:170::-;726:42;719:5;715:54;708:5;705:65;695:93;;784:1;781;774:12;799:796;946:6;954;962;970;1023:3;1011:9;1002:7;998:23;994:33;991:53;;;1040:1;1037;1030:12;991:53;1079:9;1066:23;1098:47;1139:5;1098:47;:::i;:::-;1164:5;-1:-1:-1;1221:2:1;1206:18;;1193:32;1234:49;1193:32;1234:49;:::i;:::-;1302:7;-1:-1:-1;1361:2:1;1346:18;;1333:32;1374:49;1333:32;1374:49;:::i;:::-;1442:7;-1:-1:-1;1501:2:1;1486:18;;1473:32;1514:49;1473:32;1514:49;:::i;:::-;799:796;;;;-1:-1:-1;799:796:1;;-1:-1:-1;;799:796:1:o;1600:263::-;1659:6;1712:2;1700:9;1691:7;1687:23;1683:32;1680:52;;;1728:1;1725;1718:12;1680:52;1767:9;1754:23;1786:47;1827:5;1786:47;:::i;1868:180::-;1927:6;1980:2;1968:9;1959:7;1955:23;1951:32;1948:52;;;1996:1;1993;1986:12;1948:52;-1:-1:-1;2019:23:1;;1868:180;-1:-1:-1;1868:180:1:o;3026:468::-;3112:6;3120;3128;3136;3189:3;3177:9;3168:7;3164:23;3160:33;3157:53;;;3206:1;3203;3196:12;3157:53;3242:9;3229:23;3219:33;;3299:2;3288:9;3284:18;3271:32;3261:42;;3353:2;3342:9;3338:18;3325:32;3366:47;3407:5;3366:47;:::i;:::-;3026:468;;;;-1:-1:-1;3432:5:1;;3484:2;3469:18;3456:32;;-1:-1:-1;;3026:468:1:o;3681:180::-;3737:6;3790:2;3778:9;3769:7;3765:23;3761:32;3758:52;;;3806:1;3803;3796:12;3758:52;3829:26;3845:9;3829:26;:::i;8699:184::-;8769:6;8822:2;8810:9;8801:7;8797:23;8793:32;8790:52;;;8838:1;8835;8828:12;8790:52;-1:-1:-1;8861:16:1;;8699:184;-1:-1:-1;8699:184:1:o;9702:::-;9754:77;9751:1;9744:88;9851:4;9848:1;9841:15;9875:4;9872:1;9865:15;9891:128;9931:3;9962:1;9958:6;9955:1;9952:13;9949:39;;;9968:18;;:::i;:::-;-1:-1:-1;10004:9:1;;9891:128::o;13613:195::-;13652:3;13683:66;13676:5;13673:77;13670:103;;13753:18;;:::i;:::-;-1:-1:-1;13800:1:1;13789:13;;13613:195::o;15070:267::-;15140:6;15193:2;15181:9;15172:7;15168:23;15164:32;15161:52;;;15209:1;15206;15199:12;15161:52;15241:9;15235:16;15260:47;15301:5;15260:47;:::i;15702:482::-;15791:1;15834:5;15791:1;15848:330;15869:7;15859:8;15856:21;15848:330;;;15988:4;15920:66;15916:77;15910:4;15907:87;15904:113;;;15997:18;;:::i;:::-;16047:7;16037:8;16033:22;16030:55;;;16067:16;;;;16030:55;16146:22;;;;16106:15;;;;15848:330;;;15852:3;15702:482;;;;;:::o;16189:866::-;16238:5;16268:8;16258:80;;-1:-1:-1;16309:1:1;16323:5;;16258:80;16357:4;16347:76;;-1:-1:-1;16394:1:1;16408:5;;16347:76;16439:4;16457:1;16452:59;;;;16525:1;16520:130;;;;16432:218;;16452:59;16482:1;16473:10;;16496:5;;;16520:130;16557:3;16547:8;16544:17;16541:43;;;16564:18;;:::i;:::-;-1:-1:-1;;16620:1:1;16606:16;;16635:5;;16432:218;;16734:2;16724:8;16721:16;16715:3;16709:4;16706:13;16702:36;16696:2;16686:8;16683:16;16678:2;16672:4;16669:12;16665:35;16662:77;16659:159;;;-1:-1:-1;16771:19:1;;;16803:5;;16659:159;16850:34;16875:8;16869:4;16850:34;:::i;:::-;16980:6;16912:66;16908:79;16899:7;16896:92;16893:118;;;16991:18;;:::i;:::-;17029:20;;16189:866;-1:-1:-1;;;16189:866:1:o;17060:131::-;17120:5;17149:36;17176:8;17170:4;17149:36;:::i;17196:125::-;17236:4;17264:1;17261;17258:8;17255:34;;;17269:18;;:::i;:::-;-1:-1:-1;17306:9:1;;17196:125::o;17326:228::-;17366:7;17492:1;17424:66;17420:74;17417:1;17414:81;17409:1;17402:9;17395:17;17391:105;17388:131;;;17499:18;;:::i;:::-;-1:-1:-1;17539:9:1;;17326:228::o;17559:274::-;17599:1;17625;17615:189;;17660:77;17657:1;17650:88;17761:4;17758:1;17751:15;17789:4;17786:1;17779:15;17615:189;-1:-1:-1;17818:9:1;;17559:274::o
Swarm Source
ipfs://b62103c406ae9a79ff020549436b019377509cbbeb9321a4943efadcc531cc39
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.