Source Code
Overview
S Balance
S Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PriceManager
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./interfaces/IPriceManager.sol";
import "./interfaces/IOperators.sol";
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";
import {Constants} from "../access/Constants.sol";
contract PriceManager is Constants, Initializable, IPriceManager {
IOperators public operators;
IPyth public pyth;
mapping(uint256 => Asset) public assets;
struct Asset {
string symbol;
bytes32 pythId;
uint256 price;
uint256 timestamp;
uint256 allowedStaleness;
uint256 allowedDeviation;
uint256 maxLeverage;
uint256 tokenDecimals; // for usd stablecoin only
}
mapping(address => uint256) public tokenAddressToAssetId; // for usd stablecoin
// an array to track valid assets
uint256[] private validAssetIds;
event SetAsset(
uint256 assetId,
string symbol,
bytes32 pythId,
uint256 price,
uint256 timestamp,
uint256 allowedStaleness,
uint256 allowedDeviation,
uint256 maxLeverage
);
event SetUsdAsset(
address tokenAddress,
uint256 assetId,
string symbol,
bytes32 pythId,
uint256 price,
uint256 timestamp,
uint256 allowedStaleness,
uint256 allowedDeviation,
uint256 tokenDecimals
);
event SetPrice(uint256 assetId, uint256 price, uint256 timestamp);
modifier onlyOperator(uint256 level) {
require(operators.getOperatorLevel(msg.sender) >= level, "invalid operator");
_;
}
function initialize(address _operators, address _pyth) public initializer {
require(AddressUpgradeable.isContract(_operators), "operators invalid");
require(AddressUpgradeable.isContract(_pyth), "pyth invalid");
operators = IOperators(_operators);
pyth = IPyth(_pyth);
}
function setAsset(
uint256 _assetId,
string calldata _symbol,
bytes32 _pythId,
uint256 _price,
uint256 _allowedStaleness,
uint256 _allowedDeviation,
uint256 _maxLeverage
) external onlyOperator(4) {
require(_maxLeverage > MIN_LEVERAGE, "Max Leverage should be greater than Min Leverage");
// new asset
if (assets[_assetId].maxLeverage == 0) {
validAssetIds.push(_assetId);
}
assets[_assetId] = Asset({
symbol: _symbol,
pythId: _pythId,
price: _price,
timestamp: block.timestamp,
allowedStaleness: _allowedStaleness,
allowedDeviation: _allowedDeviation,
maxLeverage: _maxLeverage,
tokenDecimals: 0
});
emit SetAsset(
_assetId,
_symbol,
_pythId,
_price,
block.timestamp,
_allowedStaleness,
_allowedDeviation,
_maxLeverage
);
}
function batchSetAllowedDeviation(uint256[] memory _assetIds, uint256 _allowedDeviation) external onlyOperator(3) {
for (uint256 i; i < _assetIds.length; i++) {
uint256 _assetId = _assetIds[i];
Asset memory asset = assets[_assetId];
require(asset.maxLeverage > 0, "!newAsset");
asset.allowedDeviation = _allowedDeviation;
assets[_assetId] = asset;
emit SetAsset(
_assetId,
asset.symbol,
asset.pythId,
asset.price,
asset.timestamp,
asset.allowedStaleness,
asset.allowedDeviation,
asset.maxLeverage
);
}
}
function batchSetAllowedStaleness(uint256[] memory _assetIds, uint256 _allowedStaleness) external onlyOperator(3) {
for (uint256 i; i < _assetIds.length; i++) {
uint256 _assetId = _assetIds[i];
Asset memory asset = assets[_assetId];
require(asset.maxLeverage > 0, "!newAsset");
asset.allowedStaleness = _allowedStaleness;
assets[_assetId] = asset;
emit SetAsset(
_assetId,
asset.symbol,
asset.pythId,
asset.price,
asset.timestamp,
asset.allowedStaleness,
asset.allowedDeviation,
asset.maxLeverage
);
}
}
function batchSetMaxLeverage(uint256[] memory _assetIds, uint256 _maxLeverage) external onlyOperator(3) {
for (uint256 i; i < _assetIds.length; i++) {
uint256 _assetId = _assetIds[i];
Asset memory asset = assets[_assetId];
require(asset.maxLeverage > 0, "!newAsset");
asset.maxLeverage = _maxLeverage;
assets[_assetId] = asset;
emit SetAsset(
_assetId,
asset.symbol,
asset.pythId,
asset.price,
asset.timestamp,
asset.allowedStaleness,
asset.allowedDeviation,
asset.maxLeverage
);
}
}
function setUsdAsset(
address _tokenAddress,
uint256 _assetId,
string calldata _symbol,
bytes32 _pythId,
uint256 _price,
uint256 _allowedStaleness,
uint256 _allowedDeviation,
uint256 _tokenDecimals
) external onlyOperator(4) {
// new asset
if (assets[_assetId].tokenDecimals == 0) {
validAssetIds.push(_assetId);
}
tokenAddressToAssetId[_tokenAddress] = _assetId;
assets[_assetId] = Asset({
symbol: _symbol,
pythId: _pythId,
price: _price,
timestamp: block.timestamp,
allowedStaleness: _allowedStaleness,
allowedDeviation: _allowedDeviation,
maxLeverage: 0,
tokenDecimals: _tokenDecimals
});
emit SetUsdAsset(
_tokenAddress,
_assetId,
_symbol,
_pythId,
_price,
block.timestamp,
_allowedStaleness,
_allowedDeviation,
_tokenDecimals
);
}
function getPythLastPrice(uint256 _assetId, bool _requireFreshness) public view returns (uint256) {
PythStructs.Price memory priceInfo = pyth.getPriceUnsafe(assets[_assetId].pythId);
if (_requireFreshness) {
require(block.timestamp <= priceInfo.publishTime + assets[_assetId].allowedStaleness, "price stale");
}
uint256 price = uint256(uint64(priceInfo.price));
if (priceInfo.expo >= 0) {
uint256 exponent = uint256(uint32(priceInfo.expo));
return price * PRICE_PRECISION * (10 ** exponent);
} else {
uint256 exponent = uint256(uint32(-priceInfo.expo));
return (price * PRICE_PRECISION) / (10 ** exponent);
}
}
function getLastPrice(uint256 _assetId) public view override returns (uint256) {
uint256 price = assets[_assetId].price;
require(price > 0, "invalid price");
uint256 ts = assets[_assetId].timestamp;
uint256 allowedStaleness = assets[_assetId].allowedStaleness;
if (allowedStaleness == 0 || block.timestamp - ts <= allowedStaleness) {
// our price is fresh enough, return our answer
return price;
} else {
// our price is stale, try use on-chain price with freshness requirement
return getPythLastPrice(_assetId, true);
}
}
function setPrice(uint256 _assetId, uint256 _price, uint256 _ts) public onlyOperator(2) {
require(_ts > assets[_assetId].timestamp, "already updated");
bytes32 pythId = assets[_assetId].pythId;
if (pythId != bytes32(0)) {
//skip validation if pyth not enabled for this asset
uint256 priceOnChain = getPythLastPrice(_assetId, false);
uint256 deviation = _price > priceOnChain
? ((_price - priceOnChain) * BASIS_POINTS_DIVISOR) / priceOnChain
: ((priceOnChain - _price) * BASIS_POINTS_DIVISOR) / priceOnChain;
require(deviation <= assets[_assetId].allowedDeviation, "need update pyth price");
}
assets[_assetId].price = _price;
assets[_assetId].timestamp = _ts;
emit SetPrice(_assetId, _price, _ts);
}
function tokenToUsd(address _token, uint256 _tokenAmount) external view override returns (uint256) {
uint256 assetId = tokenAddressToAssetId[_token];
return (_tokenAmount * getLastPrice(assetId)) / (10 ** assets[assetId].tokenDecimals);
}
function usdToToken(address _token, uint256 _usdAmount) external view override returns (uint256) {
uint256 assetId = tokenAddressToAssetId[_token];
return (_usdAmount * (10 ** assets[assetId].tokenDecimals)) / getLastPrice(assetId);
}
function getCurrentTime() external view returns (uint256) {
return block.timestamp;
}
function maxLeverage(uint256 _assetId) external view override returns (uint256) {
return assets[_assetId].maxLeverage;
}
function getValidAssetIds() external view returns (uint256[] memory) {
return validAssetIds;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @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]
* ```solidity
* 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.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or 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 {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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);
}
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import "./PythStructs.sol";
import "./IPythEvents.sol";
/// @title Consume prices from the Pyth Network (https://pyth.network/).
/// @dev Please refer to the guidance at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how to consume prices safely.
/// @author Pyth Data Association
interface IPyth is IPythEvents {
/// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time
function getValidTimePeriod() external view returns (uint validTimePeriod);
/// @notice Returns the price and confidence interval.
/// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds.
/// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPrice(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price and confidence interval.
/// @dev Reverts if the EMA price is not available.
/// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPrice(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the price of a price feed without any sanity checks.
/// @dev This function returns the most recent price update in this contract without any recency checks.
/// This function is unsafe as the returned price update may be arbitrarily far in the past.
///
/// Users of this function should check the `publishTime` in the price to ensure that the returned price is
/// sufficiently recent for their application. If you are considering using this function, it may be
/// safer / easier to use either `getPrice` or `getPriceNoOlderThan`.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPriceUnsafe(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the price that is no older than `age` seconds of the current time.
/// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in
/// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
/// recently.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPriceNoOlderThan(
bytes32 id,
uint age
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.
/// @dev This function returns the same price as `getEmaPrice` in the case where the price is available.
/// However, if the price is not recent this function returns the latest available price.
///
/// The returned price can be from arbitrarily far in the past; this function makes no guarantees that
/// the returned price is recent or useful for any particular application.
///
/// Users of this function should check the `publishTime` in the price to ensure that the returned price is
/// sufficiently recent for their application. If you are considering using this function, it may be
/// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPriceUnsafe(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds
/// of the current time.
/// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in
/// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
/// recently.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPriceNoOlderThan(
bytes32 id,
uint age
) external view returns (PythStructs.Price memory price);
/// @notice Update price feeds with given update messages.
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
/// Prices will be updated if they are more recent than the current stored prices.
/// The call will succeed even if the update is not the most recent.
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid.
/// @param updateData Array of price update data.
function updatePriceFeeds(bytes[] calldata updateData) external payable;
/// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is
/// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the
/// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`.
///
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
///
/// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime
/// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have
/// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.
/// Otherwise, it calls updatePriceFeeds method to update the prices.
///
/// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`
function updatePriceFeedsIfNecessary(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64[] calldata publishTimes
) external payable;
/// @notice Returns the required fee to update an array of price updates.
/// @param updateData Array of price update data.
/// @return feeAmount The required fee in Wei.
function getUpdateFee(
bytes[] calldata updateData
) external view returns (uint feeAmount);
/// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published
/// within `minPublishTime` and `maxPublishTime`.
///
/// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price;
/// otherwise, please consider using `updatePriceFeeds`. This method may store the price updates on-chain, if they
/// are more recent than the current stored prices.
///
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
///
///
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is
/// no update for any of the given `priceIds` within the given time range.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.
/// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.
/// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).
function parsePriceFeedUpdates(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);
/// @notice Similar to `parsePriceFeedUpdates` but ensures the updates returned are
/// the first updates published in minPublishTime. That is, if there are multiple updates for a given timestamp,
/// this method will return the first update. This method may store the price updates on-chain, if they
/// are more recent than the current stored prices.
///
///
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is
/// no update for any of the given `priceIds` within the given time range and uniqueness condition.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.
/// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.
/// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).
function parsePriceFeedUpdatesUnique(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
/// @title IPythEvents contains the events that Pyth contract emits.
/// @dev This interface can be used for listening to the updates for off-chain and testing purposes.
interface IPythEvents {
/// @dev Emitted when the price feed with `id` has received a fresh update.
/// @param id The Pyth Price Feed ID.
/// @param publishTime Publish time of the given price update.
/// @param price Price of the given price update.
/// @param conf Confidence interval of the given price update.
event PriceFeedUpdate(
bytes32 indexed id,
uint64 publishTime,
int64 price,
uint64 conf
);
/// @dev Emitted when a batch price update is processed successfully.
/// @param chainId ID of the source chain that the batch price update comes from.
/// @param sequenceNumber Sequence number of the batch price update.
event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
contract PythStructs {
// A price with a degree of uncertainty, represented as a price +- a confidence interval.
//
// The confidence interval roughly corresponds to the standard error of a normal distribution.
// Both the price and confidence are stored in a fixed-point numeric representation,
// `x * (10^expo)`, where `expo` is the exponent.
//
// Please refer to the documentation at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how
// to how this price safely.
struct Price {
// Price
int64 price;
// Confidence interval around the price
uint64 conf;
// Price exponent
int32 expo;
// Unix timestamp describing when the price was published
uint publishTime;
}
// PriceFeed represents a current aggregate price from pyth publisher feeds.
struct PriceFeed {
// The price ID.
bytes32 id;
// Latest available price
Price price;
// Latest available exponentially-weighted moving average price
Price emaPrice;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
contract Constants {
uint8 internal constant STAKING_PID_FOR_CHARGE_FEE = 1;
uint256 internal constant BASIS_POINTS_DIVISOR = 100000;
uint256 internal constant LIQUIDATE_THRESHOLD_DIVISOR = 10 * BASIS_POINTS_DIVISOR;
uint256 internal constant DEFAULT_NSLP_PRICE = 100000;
uint256 internal constant FUNDING_RATE_PRECISION = BASIS_POINTS_DIVISOR ** 3; // 1e15
uint256 internal constant MAX_DEPOSIT_WITHDRAW_FEE = 10000; // 10%
uint256 internal constant MAX_DELTA_TIME = 24 hours;
uint256 internal constant MAX_COOLDOWN_DURATION = 30 days;
uint256 internal constant MAX_FEE_BASIS_POINTS = 5000; // 5%
uint256 internal constant MAX_PRICE_MOVEMENT_PERCENT = 10000; // 10%
uint256 internal constant MAX_BORROW_FEE_FACTOR = 500; // 0.5% per hour
uint256 internal constant MAX_FUNDING_RATE = FUNDING_RATE_PRECISION / 10; // 10% per hour
uint256 internal constant MAX_STAKING_UNSTAKING_FEE = 10000; // 10%
uint256 internal constant MAX_EXPIRY_DURATION = 60; // 60 seconds
uint256 internal constant MAX_SELF_EXECUTE_COOLDOWN = 300; // 5 minutes
uint256 internal constant MAX_TOKENFARM_COOLDOWN_DURATION = 4 weeks;
uint256 internal constant MAX_TRIGGER_GAS_FEE = 1e8 gwei;
uint256 internal constant MAX_MARKET_ORDER_GAS_FEE = 1e8 gwei;
uint256 internal constant MAX_VESTING_DURATION = 700 days;
uint256 internal constant MIN_LEVERAGE = 10000; // 1x
uint256 internal constant POSITION_MARKET = 0;
uint256 internal constant POSITION_LIMIT = 1;
uint256 internal constant POSITION_STOP_MARKET = 2;
uint256 internal constant POSITION_STOP_LIMIT = 3;
uint256 internal constant POSITION_TRAILING_STOP = 4;
uint256 internal constant PRICE_PRECISION = 10 ** 30;
uint256 internal constant TRAILING_STOP_TYPE_AMOUNT = 0;
uint256 internal constant TRAILING_STOP_TYPE_PERCENT = 1;
uint256 internal constant NSLP_DECIMALS = 18;
function uintToBytes(uint v) internal pure returns (bytes32 ret) {
if (v == 0) {
ret = "0";
} else {
while (v > 0) {
ret = bytes32(uint(ret) / (2 ** 8));
ret |= bytes32(((v % 10) + 48) * 2 ** (8 * 31));
v /= 10;
}
}
return ret;
}
function checkSlippage(bool isLong, uint256 allowedPrice, uint256 actualMarketPrice) internal pure {
if (isLong) {
require(
actualMarketPrice <= allowedPrice,
string(
abi.encodePacked(
"long: slippage exceeded ",
uintToBytes(actualMarketPrice),
" ",
uintToBytes(allowedPrice)
)
)
);
} else {
require(
actualMarketPrice >= allowedPrice,
string(
abi.encodePacked(
"short: slippage exceeded ",
uintToBytes(actualMarketPrice),
" ",
uintToBytes(allowedPrice)
)
)
);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IOperators {
function getOperatorLevel(address op) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
interface IPriceManager {
function assets(uint256 _assetId) external view returns (
string memory symbol,
bytes32 pythId,
uint256 price,
uint256 timestamp,
uint256 allowedStaleness,
uint256 allowedDeviation,
uint256 maxLeverage,
uint256 tokenDecimals
);
function getLastPrice(uint256 _tokenId) external view returns (uint256);
function getPythLastPrice(uint256 _assetId, bool _requireFreshness) external view returns (uint256);
function pyth() external view returns (IPyth);
function maxLeverage(uint256 _tokenId) external view returns (uint256);
function tokenToUsd(address _token, uint256 _tokenAmount) external view returns (uint256);
function usdToToken(address _token, uint256 _usdAmount) external view returns (uint256);
function setPrice(uint256 _assetId, uint256 _price, uint256 _ts) external;
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"bytes32","name":"pythId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowedStaleness","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowedDeviation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"name":"SetAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SetPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"bytes32","name":"pythId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowedStaleness","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowedDeviation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenDecimals","type":"uint256"}],"name":"SetUsdAsset","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"assets","outputs":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"bytes32","name":"pythId","type":"bytes32"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"allowedStaleness","type":"uint256"},{"internalType":"uint256","name":"allowedDeviation","type":"uint256"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"tokenDecimals","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_assetIds","type":"uint256[]"},{"internalType":"uint256","name":"_allowedDeviation","type":"uint256"}],"name":"batchSetAllowedDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_assetIds","type":"uint256[]"},{"internalType":"uint256","name":"_allowedStaleness","type":"uint256"}],"name":"batchSetAllowedStaleness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_assetIds","type":"uint256[]"},{"internalType":"uint256","name":"_maxLeverage","type":"uint256"}],"name":"batchSetMaxLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"getLastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"bool","name":"_requireFreshness","type":"bool"}],"name":"getPythLastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidAssetIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operators","type":"address"},{"internalType":"address","name":"_pyth","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"maxLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operators","outputs":[{"internalType":"contract IOperators","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pyth","outputs":[{"internalType":"contract IPyth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"bytes32","name":"_pythId","type":"bytes32"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_allowedStaleness","type":"uint256"},{"internalType":"uint256","name":"_allowedDeviation","type":"uint256"},{"internalType":"uint256","name":"_maxLeverage","type":"uint256"}],"name":"setAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_ts","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"bytes32","name":"_pythId","type":"bytes32"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_allowedStaleness","type":"uint256"},{"internalType":"uint256","name":"_allowedDeviation","type":"uint256"},{"internalType":"uint256","name":"_tokenDecimals","type":"uint256"}],"name":"setUsdAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenAddressToAssetId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"tokenToUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_usdAmount","type":"uint256"}],"name":"usdToToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061212f806100206000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80637a6a35a9116100a2578063cc9e713911610071578063cc9e713914610225578063cf35bdd014610248578063e41b61a51461026f578063e673df8a14610282578063f98d06f0146102b357600080fd5b80637a6a35a9146101cc578063804ddade146101df578063aa585d56146101ff578063bd1b12981461021257600080fd5b806365fa2f7f116100e957806365fa2f7f1461016d57806368ce13d6146101805780636f8a953a1461019357806376db60d0146101a65780637988116f146101b957600080fd5b806329cb924d1461011b57806336f20e11146101305780633c98e05014610145578063485cc9551461015a575b600080fd5b425b6040519081526020015b60405180910390f35b6101386102c6565b6040516101279190611883565b61015861015336600461192c565b61031e565b005b6101586101683660046119b3565b610564565b61011d61017b3660046119e6565b610741565b61011d61018e3660046119ff565b6107e1565b6101586101a1366004611a70565b61083e565b6101586101b4366004611b1c565b610b0a565b61011d6101c7366004611b93565b610d85565b6101586101da366004611a70565b610f23565b61011d6101ed366004611bc8565b60036020526000908152604090205481565b61015861020d366004611bea565b6111e9565b61011d6102203660046119ff565b61141e565b61011d6102333660046119e6565b60009081526002602052604090206006015490565b61025b6102563660046119e6565b61145c565b604051610127989796959493929190611c63565b61015861027d366004611a70565b611524565b60005461029b906201000090046001600160a01b031681565b6040516001600160a01b039091168152602001610127565b60015461029b906001600160a01b031681565b6060600480548060200260200160405190810160405280929190818152602001828054801561031457602002820191906000526020600020905b815481526020019060010190808311610300575b5050505050905090565b60005460405163df07560560e01b815233600480830191909152918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561036d57600080fd5b505afa158015610381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a59190611cae565b10156103cc5760405162461bcd60e51b81526004016103c390611cc7565b60405180910390fd5b60008981526002602052604090206007015461041857600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b018990555b6001600160a01b038a166000908152600360209081526040918290208b90558151610120601f8b0183900490920281018201909252610100820189815282918b908b9081908501838280828437600092018290525093855250505060208083018a905260408084018a90524260608501526080840189905260a0840188905260c0840183905260e09093018690528c8252600281529190208251805191926104c5928492909101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050507ff8be5fed6a4c5e7d5c4fc980d5ed0e95db2a0944fbb988cd32280300ba4857f48a8a8a8a8a8a428b8b8b6040516105509a99989796959493929190611d1a565b60405180910390a150505050505050505050565b600054610100900460ff16158080156105845750600054600160ff909116105b8061059e5750303b15801561059e575060005460ff166001145b6106015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103c3565b6000805460ff191660011790558015610624576000805461ff0019166101001790555b6001600160a01b0383163b61066f5760405162461bcd60e51b81526020600482015260116024820152701bdc195c985d1bdc9cc81a5b9d985b1a59607a1b60448201526064016103c3565b6001600160a01b0382163b6106b55760405162461bcd60e51b815260206004820152600c60248201526b1c1e5d1a081a5b9d985b1a5960a21b60448201526064016103c3565b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117909155600180546001600160a01b031916918416919091179055801561073c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600081815260026020819052604082200154806107905760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420707269636560981b60448201526064016103c3565b600083815260026020526040902060038101546004909101548015806107bf5750806107bc8342611d93565b11155b156107cd5750909392505050565b6107d8856001610d85565b95945050505050565b6001600160a01b03821660009081526003602052604081205461080381610741565b60008281526002602052604090206007015461082090600a611e8e565b61082a9085611e9a565b6108349190611eb9565b9150505b92915050565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561088b57600080fd5b505afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c39190611cae565b10156108e15760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b0457600084828151811061090157610901611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461093c90611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461096890611ef1565b80156109b55780601f1061098a576101008083540402835291602001916109b5565b820191906000526020600020905b81548152906001019060200180831161099857829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c0015111610a2a5760405162461bcd60e51b81526004016103c390611f2c565b60a081018590526000828152600260209081526040909120825180518493610a569284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c00151604051610ae7989796959493929190611f4f565b60405180910390a150508080610afc90611f9c565b9150506108e4565b50505050565b60005460405163df07560560e01b815233600480830191909152918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b158015610b5957600080fd5b505afa158015610b6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b919190611cae565b1015610baf5760405162461bcd60e51b81526004016103c390611cc7565b6127108211610c195760405162461bcd60e51b815260206004820152603060248201527f4d6178204c657665726167652073686f756c642062652067726561746572207460448201526f68616e204d696e204c6576657261676560801b60648201526084016103c3565b600089815260026020526040902060060154610c6557600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b018990555b60405180610100016040528089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060208083018a905260408084018a90524260608501526080840189905260a0840188905260c0840187905260e09093018290528c825260028152919020825180519192610cfb928492909101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da8339815191528989898989428a8a8a604051610d7299989796959493929190611fb7565b60405180910390a1505050505050505050565b600180546000848152600260205260408082209093015492516396834ad360e01b815260048101939093529182916001600160a01b0316906396834ad39060240160806040518083038186803b158015610dde57600080fd5b505afa158015610df2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e169190612006565b90508215610e7c576000848152600260205260409020600401546060820151610e3f919061209d565b421115610e7c5760405162461bcd60e51b815260206004820152600b60248201526a7072696365207374616c6560a81b60448201526064016103c3565b6000816000015167ffffffffffffffff1690506000826040015160030b12610edf57604082015163ffffffff16610eb481600a611e8e565b610ecb6c0c9f2c9cd04674edea4000000084611e9a565b610ed59190611e9a565b9350505050610838565b60008260400151610eef906120b5565b63ffffffff169050610f0281600a611e8e565b610f196c0c9f2c9cd04674edea4000000084611e9a565b610ed59190611eb9565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b158015610f7057600080fd5b505afa158015610f84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa89190611cae565b1015610fc65760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b04576000848281518110610fe657610fe6611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461102190611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461104d90611ef1565b801561109a5780601f1061106f5761010080835404028352916020019161109a565b820191906000526020600020905b81548152906001019060200180831161107d57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c001511161110f5760405162461bcd60e51b81526004016103c390611f2c565b60c08101859052600082815260026020908152604090912082518051849361113b9284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c001516040516111cc989796959493929190611f4f565b60405180910390a1505080806111e190611f9c565b915050610fc9565b60005460405163df07560560e01b81523360048201526002918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190611cae565b101561128c5760405162461bcd60e51b81526004016103c390611cc7565b60008481526002602052604090206003015482116112de5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e481d5c19185d1959608a1b60448201526064016103c3565b60008481526002602052604090206001015480156113b9576000611303866000610d85565b905060008186116113365781620186a061131d8883611d93565b6113279190611e9a565b6113319190611eb9565b611359565b81620186a06113458289611d93565b61134f9190611e9a565b6113599190611eb9565b6000888152600260205260409020600501549091508111156113b65760405162461bcd60e51b81526020600482015260166024820152756e65656420757064617465207079746820707269636560501b60448201526064016103c3565b50505b600085815260026020818152604092839020918201879055600390910185905581518781529081018690529081018490527f18e75bb8c091a6448c12a2023f055b2714c151b941a91df8b9938788769ffe139060600160405180910390a15050505050565b6001600160a01b038216600090815260036020908152604080832054808452600290925282206007015461145390600a611e8e565b61082082610741565b60026020526000908152604090208054819061147790611ef1565b80601f01602080910402602001604051908101604052809291908181526020018280546114a390611ef1565b80156114f05780601f106114c5576101008083540402835291602001916114f0565b820191906000526020600020905b8154815290600101906020018083116114d357829003601f168201915b5050505050908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561157157600080fd5b505afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a99190611cae565b10156115c75760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b045760008482815181106115e7576115e7611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461162290611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461164e90611ef1565b801561169b5780601f106116705761010080835404028352916020019161169b565b820191906000526020600020905b81548152906001019060200180831161167e57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c00151116117105760405162461bcd60e51b81526004016103c390611f2c565b60808101859052600082815260026020908152604090912082518051849361173c9284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c001516040516117cd989796959493929190611f4f565b60405180910390a1505080806117e290611f9c565b9150506115ca565b8280546117f690611ef1565b90600052602060002090601f016020900481019282611818576000855561185e565b82601f1061183157805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e578251825591602001919060010190611843565b5061186a92915061186e565b5090565b5b8082111561186a576000815560010161186f565b6020808252825182820181905260009190848201906040850190845b818110156118bb5783518352928401929184019160010161189f565b50909695505050505050565b80356001600160a01b03811681146118de57600080fd5b919050565b60008083601f8401126118f557600080fd5b50813567ffffffffffffffff81111561190d57600080fd5b60208301915083602082850101111561192557600080fd5b9250929050565b60008060008060008060008060006101008a8c03121561194b57600080fd5b6119548a6118c7565b985060208a0135975060408a013567ffffffffffffffff81111561197757600080fd5b6119838c828d016118e3565b9a9d999c509a6060810135996080820135995060a0820135985060c0820135975060e09091013595509350505050565b600080604083850312156119c657600080fd5b6119cf836118c7565b91506119dd602084016118c7565b90509250929050565b6000602082840312156119f857600080fd5b5035919050565b60008060408385031215611a1257600080fd5b611a1b836118c7565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611a6857611a68611a29565b604052919050565b60008060408385031215611a8357600080fd5b823567ffffffffffffffff80821115611a9b57600080fd5b818501915085601f830112611aaf57600080fd5b8135602082821115611ac357611ac3611a29565b8160051b9250611ad4818401611a3f565b8281529284018101928181019089851115611aee57600080fd5b948201945b84861015611b0c57853582529482019490820190611af3565b9997909101359750505050505050565b60008060008060008060008060e0898b031215611b3857600080fd5b88359750602089013567ffffffffffffffff811115611b5657600080fd5b611b628b828c016118e3565b999c909b509899604081013599606082013599506080820135985060a0820135975060c09091013595509350505050565b60008060408385031215611ba657600080fd5b8235915060208301358015158114611bbd57600080fd5b809150509250929050565b600060208284031215611bda57600080fd5b611be3826118c7565b9392505050565b600080600060608486031215611bff57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b81811015611c3c57602081850181015186830182015201611c20565b81811115611c4e576000602083870101525b50601f01601f19169290920160200192915050565b6000610100808352611c778184018c611c16565b602084019a909a52505060408101969096526060860194909452608085019290925260a084015260c083015260e090910152919050565b600060208284031215611cc057600080fd5b5051919050565b60208082526010908201526f34b73b30b634b21037b832b930ba37b960811b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038b168152602081018a905261012060408201819052600090611d478382018b8d611cf1565b60608401999099525050608081019590955260a085019390935260c084019190915260e083015261010090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600082821015611da557611da5611d7d565b500390565b600181815b80851115611de5578160001904821115611dcb57611dcb611d7d565b80851615611dd857918102915b93841c9390800290611daf565b509250929050565b600082611dfc57506001610838565b81611e0957506000610838565b8160018114611e1f5760028114611e2957611e45565b6001915050610838565b60ff841115611e3a57611e3a611d7d565b50506001821b610838565b5060208310610133831016604e8410600b8410161715611e68575081810a610838565b611e728383611daa565b8060001904821115611e8657611e86611d7d565b029392505050565b6000611be38383611ded565b6000816000190483118215151615611eb457611eb4611d7d565b500290565b600082611ed657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680611f0557607f821691505b60208210811415611f2657634e487b7160e01b600052602260045260246000fd5b50919050565b602080825260099082015268085b995dd05cdcd95d60ba1b604082015260600190565b60006101008a8352806020840152611f698184018b611c16565b604084019990995250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b6000600019821415611fb057611fb0611d7d565b5060010190565b60006101008b8352806020840152611fd28184018b8d611cf1565b604084019990995250506060810195909552608085019390935260a084019190915260c083015260e0909101529392505050565b60006080828403121561201857600080fd5b6040516080810167ffffffffffffffff828210818311171561203c5761203c611a29565b81604052845191508160070b821461205357600080fd5b908252602084015190808216821461206a57600080fd5b5060208201526040830151600381900b811461208557600080fd5b60408201526060928301519281019290925250919050565b600082198211156120b0576120b0611d7d565b500190565b60008160030b637fffffff198114156120d0576120d0611d7d565b6000039291505056fe1d1b9a3a4db1da165c247e2eb600745c405e9523a095f13270b904ff9d0ef4a8a2646970667358221220d7bb26b71f8bbc2b2bf395fc0b3d64a92de66a99a3cb5d7a40783d55cfd0403764736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c80637a6a35a9116100a2578063cc9e713911610071578063cc9e713914610225578063cf35bdd014610248578063e41b61a51461026f578063e673df8a14610282578063f98d06f0146102b357600080fd5b80637a6a35a9146101cc578063804ddade146101df578063aa585d56146101ff578063bd1b12981461021257600080fd5b806365fa2f7f116100e957806365fa2f7f1461016d57806368ce13d6146101805780636f8a953a1461019357806376db60d0146101a65780637988116f146101b957600080fd5b806329cb924d1461011b57806336f20e11146101305780633c98e05014610145578063485cc9551461015a575b600080fd5b425b6040519081526020015b60405180910390f35b6101386102c6565b6040516101279190611883565b61015861015336600461192c565b61031e565b005b6101586101683660046119b3565b610564565b61011d61017b3660046119e6565b610741565b61011d61018e3660046119ff565b6107e1565b6101586101a1366004611a70565b61083e565b6101586101b4366004611b1c565b610b0a565b61011d6101c7366004611b93565b610d85565b6101586101da366004611a70565b610f23565b61011d6101ed366004611bc8565b60036020526000908152604090205481565b61015861020d366004611bea565b6111e9565b61011d6102203660046119ff565b61141e565b61011d6102333660046119e6565b60009081526002602052604090206006015490565b61025b6102563660046119e6565b61145c565b604051610127989796959493929190611c63565b61015861027d366004611a70565b611524565b60005461029b906201000090046001600160a01b031681565b6040516001600160a01b039091168152602001610127565b60015461029b906001600160a01b031681565b6060600480548060200260200160405190810160405280929190818152602001828054801561031457602002820191906000526020600020905b815481526020019060010190808311610300575b5050505050905090565b60005460405163df07560560e01b815233600480830191909152918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561036d57600080fd5b505afa158015610381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a59190611cae565b10156103cc5760405162461bcd60e51b81526004016103c390611cc7565b60405180910390fd5b60008981526002602052604090206007015461041857600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b018990555b6001600160a01b038a166000908152600360209081526040918290208b90558151610120601f8b0183900490920281018201909252610100820189815282918b908b9081908501838280828437600092018290525093855250505060208083018a905260408084018a90524260608501526080840189905260a0840188905260c0840183905260e09093018690528c8252600281529190208251805191926104c5928492909101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050507ff8be5fed6a4c5e7d5c4fc980d5ed0e95db2a0944fbb988cd32280300ba4857f48a8a8a8a8a8a428b8b8b6040516105509a99989796959493929190611d1a565b60405180910390a150505050505050505050565b600054610100900460ff16158080156105845750600054600160ff909116105b8061059e5750303b15801561059e575060005460ff166001145b6106015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103c3565b6000805460ff191660011790558015610624576000805461ff0019166101001790555b6001600160a01b0383163b61066f5760405162461bcd60e51b81526020600482015260116024820152701bdc195c985d1bdc9cc81a5b9d985b1a59607a1b60448201526064016103c3565b6001600160a01b0382163b6106b55760405162461bcd60e51b815260206004820152600c60248201526b1c1e5d1a081a5b9d985b1a5960a21b60448201526064016103c3565b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117909155600180546001600160a01b031916918416919091179055801561073c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600081815260026020819052604082200154806107905760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420707269636560981b60448201526064016103c3565b600083815260026020526040902060038101546004909101548015806107bf5750806107bc8342611d93565b11155b156107cd5750909392505050565b6107d8856001610d85565b95945050505050565b6001600160a01b03821660009081526003602052604081205461080381610741565b60008281526002602052604090206007015461082090600a611e8e565b61082a9085611e9a565b6108349190611eb9565b9150505b92915050565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561088b57600080fd5b505afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c39190611cae565b10156108e15760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b0457600084828151811061090157610901611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461093c90611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461096890611ef1565b80156109b55780601f1061098a576101008083540402835291602001916109b5565b820191906000526020600020905b81548152906001019060200180831161099857829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c0015111610a2a5760405162461bcd60e51b81526004016103c390611f2c565b60a081018590526000828152600260209081526040909120825180518493610a569284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c00151604051610ae7989796959493929190611f4f565b60405180910390a150508080610afc90611f9c565b9150506108e4565b50505050565b60005460405163df07560560e01b815233600480830191909152918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b158015610b5957600080fd5b505afa158015610b6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b919190611cae565b1015610baf5760405162461bcd60e51b81526004016103c390611cc7565b6127108211610c195760405162461bcd60e51b815260206004820152603060248201527f4d6178204c657665726167652073686f756c642062652067726561746572207460448201526f68616e204d696e204c6576657261676560801b60648201526084016103c3565b600089815260026020526040902060060154610c6557600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b018990555b60405180610100016040528089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060208083018a905260408084018a90524260608501526080840189905260a0840188905260c0840187905260e09093018290528c825260028152919020825180519192610cfb928492909101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da8339815191528989898989428a8a8a604051610d7299989796959493929190611fb7565b60405180910390a1505050505050505050565b600180546000848152600260205260408082209093015492516396834ad360e01b815260048101939093529182916001600160a01b0316906396834ad39060240160806040518083038186803b158015610dde57600080fd5b505afa158015610df2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e169190612006565b90508215610e7c576000848152600260205260409020600401546060820151610e3f919061209d565b421115610e7c5760405162461bcd60e51b815260206004820152600b60248201526a7072696365207374616c6560a81b60448201526064016103c3565b6000816000015167ffffffffffffffff1690506000826040015160030b12610edf57604082015163ffffffff16610eb481600a611e8e565b610ecb6c0c9f2c9cd04674edea4000000084611e9a565b610ed59190611e9a565b9350505050610838565b60008260400151610eef906120b5565b63ffffffff169050610f0281600a611e8e565b610f196c0c9f2c9cd04674edea4000000084611e9a565b610ed59190611eb9565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b158015610f7057600080fd5b505afa158015610f84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa89190611cae565b1015610fc65760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b04576000848281518110610fe657610fe6611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461102190611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461104d90611ef1565b801561109a5780601f1061106f5761010080835404028352916020019161109a565b820191906000526020600020905b81548152906001019060200180831161107d57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c001511161110f5760405162461bcd60e51b81526004016103c390611f2c565b60c08101859052600082815260026020908152604090912082518051849361113b9284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c001516040516111cc989796959493929190611f4f565b60405180910390a1505080806111e190611f9c565b915050610fc9565b60005460405163df07560560e01b81523360048201526002918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190611cae565b101561128c5760405162461bcd60e51b81526004016103c390611cc7565b60008481526002602052604090206003015482116112de5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e481d5c19185d1959608a1b60448201526064016103c3565b60008481526002602052604090206001015480156113b9576000611303866000610d85565b905060008186116113365781620186a061131d8883611d93565b6113279190611e9a565b6113319190611eb9565b611359565b81620186a06113458289611d93565b61134f9190611e9a565b6113599190611eb9565b6000888152600260205260409020600501549091508111156113b65760405162461bcd60e51b81526020600482015260166024820152756e65656420757064617465207079746820707269636560501b60448201526064016103c3565b50505b600085815260026020818152604092839020918201879055600390910185905581518781529081018690529081018490527f18e75bb8c091a6448c12a2023f055b2714c151b941a91df8b9938788769ffe139060600160405180910390a15050505050565b6001600160a01b038216600090815260036020908152604080832054808452600290925282206007015461145390600a611e8e565b61082082610741565b60026020526000908152604090208054819061147790611ef1565b80601f01602080910402602001604051908101604052809291908181526020018280546114a390611ef1565b80156114f05780601f106114c5576101008083540402835291602001916114f0565b820191906000526020600020905b8154815290600101906020018083116114d357829003601f168201915b5050505050908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60005460405163df07560560e01b81523360048201526003918291620100009091046001600160a01b03169063df0756059060240160206040518083038186803b15801561157157600080fd5b505afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a99190611cae565b10156115c75760405162461bcd60e51b81526004016103c390611cc7565b60005b8351811015610b045760008482815181106115e7576115e7611edb565b602002602001015190506000600260008381526020019081526020016000206040518061010001604052908160008201805461162290611ef1565b80601f016020809104026020016040519081016040528092919081815260200182805461164e90611ef1565b801561169b5780601f106116705761010080835404028352916020019161169b565b820191906000526020600020905b81548152906001019060200180831161167e57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481525050905060008160c00151116117105760405162461bcd60e51b81526004016103c390611f2c565b60808101859052600082815260026020908152604090912082518051849361173c9284929101906117ea565b506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701559050506000805160206120da83398151915282826000015183602001518460400151856060015186608001518760a001518860c001516040516117cd989796959493929190611f4f565b60405180910390a1505080806117e290611f9c565b9150506115ca565b8280546117f690611ef1565b90600052602060002090601f016020900481019282611818576000855561185e565b82601f1061183157805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e578251825591602001919060010190611843565b5061186a92915061186e565b5090565b5b8082111561186a576000815560010161186f565b6020808252825182820181905260009190848201906040850190845b818110156118bb5783518352928401929184019160010161189f565b50909695505050505050565b80356001600160a01b03811681146118de57600080fd5b919050565b60008083601f8401126118f557600080fd5b50813567ffffffffffffffff81111561190d57600080fd5b60208301915083602082850101111561192557600080fd5b9250929050565b60008060008060008060008060006101008a8c03121561194b57600080fd5b6119548a6118c7565b985060208a0135975060408a013567ffffffffffffffff81111561197757600080fd5b6119838c828d016118e3565b9a9d999c509a6060810135996080820135995060a0820135985060c0820135975060e09091013595509350505050565b600080604083850312156119c657600080fd5b6119cf836118c7565b91506119dd602084016118c7565b90509250929050565b6000602082840312156119f857600080fd5b5035919050565b60008060408385031215611a1257600080fd5b611a1b836118c7565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611a6857611a68611a29565b604052919050565b60008060408385031215611a8357600080fd5b823567ffffffffffffffff80821115611a9b57600080fd5b818501915085601f830112611aaf57600080fd5b8135602082821115611ac357611ac3611a29565b8160051b9250611ad4818401611a3f565b8281529284018101928181019089851115611aee57600080fd5b948201945b84861015611b0c57853582529482019490820190611af3565b9997909101359750505050505050565b60008060008060008060008060e0898b031215611b3857600080fd5b88359750602089013567ffffffffffffffff811115611b5657600080fd5b611b628b828c016118e3565b999c909b509899604081013599606082013599506080820135985060a0820135975060c09091013595509350505050565b60008060408385031215611ba657600080fd5b8235915060208301358015158114611bbd57600080fd5b809150509250929050565b600060208284031215611bda57600080fd5b611be3826118c7565b9392505050565b600080600060608486031215611bff57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b81811015611c3c57602081850181015186830182015201611c20565b81811115611c4e576000602083870101525b50601f01601f19169290920160200192915050565b6000610100808352611c778184018c611c16565b602084019a909a52505060408101969096526060860194909452608085019290925260a084015260c083015260e090910152919050565b600060208284031215611cc057600080fd5b5051919050565b60208082526010908201526f34b73b30b634b21037b832b930ba37b960811b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038b168152602081018a905261012060408201819052600090611d478382018b8d611cf1565b60608401999099525050608081019590955260a085019390935260c084019190915260e083015261010090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b600082821015611da557611da5611d7d565b500390565b600181815b80851115611de5578160001904821115611dcb57611dcb611d7d565b80851615611dd857918102915b93841c9390800290611daf565b509250929050565b600082611dfc57506001610838565b81611e0957506000610838565b8160018114611e1f5760028114611e2957611e45565b6001915050610838565b60ff841115611e3a57611e3a611d7d565b50506001821b610838565b5060208310610133831016604e8410600b8410161715611e68575081810a610838565b611e728383611daa565b8060001904821115611e8657611e86611d7d565b029392505050565b6000611be38383611ded565b6000816000190483118215151615611eb457611eb4611d7d565b500290565b600082611ed657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680611f0557607f821691505b60208210811415611f2657634e487b7160e01b600052602260045260246000fd5b50919050565b602080825260099082015268085b995dd05cdcd95d60ba1b604082015260600190565b60006101008a8352806020840152611f698184018b611c16565b604084019990995250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b6000600019821415611fb057611fb0611d7d565b5060010190565b60006101008b8352806020840152611fd28184018b8d611cf1565b604084019990995250506060810195909552608085019390935260a084019190915260c083015260e0909101529392505050565b60006080828403121561201857600080fd5b6040516080810167ffffffffffffffff828210818311171561203c5761203c611a29565b81604052845191508160070b821461205357600080fd5b908252602084015190808216821461206a57600080fd5b5060208201526040830151600381900b811461208557600080fd5b60408201526060928301519281019290925250919050565b600082198211156120b0576120b0611d7d565b500190565b60008160030b637fffffff198114156120d0576120d0611d7d565b6000039291505056fe1d1b9a3a4db1da165c247e2eb600745c405e9523a095f13270b904ff9d0ef4a8a2646970667358221220d7bb26b71f8bbc2b2bf395fc0b3d64a92de66a99a3cb5d7a40783d55cfd0403764736f6c63430008090033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$7.11
Net Worth in S
Token Allocations
WETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ARB | 100.00% | $2,960.66 | 0.00240001 | $7.11 |
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.