Source Code
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 19062943 | 793 days ago | 0.0000023 ETH | ||||
| Transfer | 19062943 | 793 days ago | 0.0000023 ETH | ||||
| Transfer | 19012213 | 800 days ago | 0.00000371 ETH | ||||
| Transfer | 19012213 | 800 days ago | 0.00000371 ETH | ||||
| Transfer | 18912512 | 814 days ago | 0.00000475 ETH | ||||
| Transfer | 18912512 | 814 days ago | 0.00000475 ETH | ||||
| Transfer | 18812805 | 828 days ago | 0.00000448 ETH | ||||
| Transfer | 18812805 | 828 days ago | 0.00000448 ETH | ||||
| Transfer | 18712930 | 842 days ago | 0.00000542 ETH | ||||
| Transfer | 18712930 | 842 days ago | 0.00000542 ETH | ||||
| Transfer | 18612929 | 856 days ago | 0.00000492 ETH | ||||
| Transfer | 18612929 | 856 days ago | 0.00000492 ETH | ||||
| Transfer | 18512870 | 870 days ago | 0.00000555 ETH | ||||
| Transfer | 18512870 | 870 days ago | 0.00000555 ETH | ||||
| Transfer | 18412898 | 884 days ago | 0.00001323 ETH | ||||
| Transfer | 18412898 | 884 days ago | 0.00001323 ETH | ||||
| Transfer | 18312845 | 898 days ago | 0.00002256 ETH | ||||
| Transfer | 18312845 | 898 days ago | 0.00002256 ETH | ||||
| Transfer | 18212731 | 912 days ago | 0.00003691 ETH | ||||
| Transfer | 18212731 | 912 days ago | 0.00003691 ETH | ||||
| Transfer | 18113042 | 926 days ago | 0.00000601 ETH | ||||
| Transfer | 18113042 | 926 days ago | 0.00000601 ETH | ||||
| Transfer | 18063045 | 933 days ago | 0.00000492 ETH | ||||
| Transfer | 18063045 | 933 days ago | 0.00000492 ETH | ||||
| Transfer | 18013074 | 940 days ago | 0.0000084 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SwapperRouter
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2022-08-12
*/
// SPDX-License-Identifier: GPL-3.0-or-later
// Sources flattened with hardhat v2.6.1 https://hardhat.org
// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `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);
/**
* @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);
}
// File @openzeppelin/contracts/utils/Address.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @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
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File interfaces/IRoleManager.sol
pragma solidity 0.8.10;
interface IRoleManager {
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function initialize() external;
function grantRole(bytes32 role, address account) external;
function addGovernor(address newGovernor) external;
function renounceGovernance() external;
function addGaugeZap(address zap) external;
function removeGaugeZap(address zap) external;
function revokeRole(bytes32 role, address account) external;
function hasRole(bytes32 role, address account) external view returns (bool);
function hasAnyRole(bytes32[] memory roles, address account) external view returns (bool);
function hasAnyRole(
bytes32 role1,
bytes32 role2,
address account
) external view returns (bool);
function hasAnyRole(
bytes32 role1,
bytes32 role2,
bytes32 role3,
address account
) external view returns (bool);
function getRoleMemberCount(bytes32 role) external view returns (uint256);
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
}
// File libraries/Errors.sol
pragma solidity 0.8.10;
// solhint-disable private-vars-leading-underscore
library Error {
string internal constant ADDRESS_WHITELISTED = "address already whitelisted";
string internal constant ADMIN_ALREADY_SET = "admin has already been set once";
string internal constant ADDRESS_NOT_WHITELISTED = "address not whitelisted";
string internal constant ADDRESS_NOT_FOUND = "address not found";
string internal constant CONTRACT_INITIALIZED = "contract can only be initialized once";
string internal constant CONTRACT_PAUSED = "contract is paused";
string internal constant UNAUTHORIZED_PAUSE = "not authorized to pause";
string internal constant INVALID_AMOUNT = "invalid amount";
string internal constant INVALID_INDEX = "invalid index";
string internal constant INVALID_VALUE = "invalid msg.value";
string internal constant INVALID_SENDER = "invalid msg.sender";
string internal constant INVALID_TOKEN = "token address does not match pool's LP token address";
string internal constant INVALID_DECIMALS = "incorrect number of decimals";
string internal constant INVALID_ARGUMENT = "invalid argument";
string internal constant INVALID_PARAMETER_VALUE = "invalid parameter value attempted";
string internal constant INVALID_IMPLEMENTATION = "invalid pool implementation for given coin";
string internal constant INVALID_POOL_IMPLEMENTATION =
"invalid pool implementation for given coin";
string internal constant INVALID_LP_TOKEN_IMPLEMENTATION =
"invalid LP Token implementation for given coin";
string internal constant INVALID_VAULT_IMPLEMENTATION =
"invalid vault implementation for given coin";
string internal constant INVALID_STAKER_VAULT_IMPLEMENTATION =
"invalid stakerVault implementation for given coin";
string internal constant INSUFFICIENT_ALLOWANCE = "insufficient allowance";
string internal constant INSUFFICIENT_BALANCE = "insufficient balance";
string internal constant INSUFFICIENT_AMOUNT_OUT = "Amount received less than min amount";
string internal constant PROXY_CALL_FAILED = "proxy call failed";
string internal constant INSUFFICIENT_AMOUNT_IN = "Amount spent more than max amount";
string internal constant ADDRESS_ALREADY_SET = "Address is already set";
string internal constant INSUFFICIENT_STRATEGY_BALANCE = "insufficient strategy balance";
string internal constant INSUFFICIENT_FUNDS_RECEIVED = "insufficient funds received";
string internal constant ADDRESS_DOES_NOT_EXIST = "address does not exist";
string internal constant ADDRESS_FROZEN = "address is frozen";
string internal constant ROLE_EXISTS = "role already exists";
string internal constant CANNOT_REVOKE_ROLE = "cannot revoke role";
string internal constant UNAUTHORIZED_ACCESS = "unauthorized access";
string internal constant SAME_ADDRESS_NOT_ALLOWED = "same address not allowed";
string internal constant SELF_TRANSFER_NOT_ALLOWED = "self-transfer not allowed";
string internal constant ZERO_ADDRESS_NOT_ALLOWED = "zero address not allowed";
string internal constant ZERO_TRANSFER_NOT_ALLOWED = "zero transfer not allowed";
string internal constant THRESHOLD_TOO_HIGH = "threshold is too high, must be under 10";
string internal constant INSUFFICIENT_THRESHOLD = "insufficient threshold";
string internal constant NO_POSITION_EXISTS = "no position exists";
string internal constant POSITION_ALREADY_EXISTS = "position already exists";
string internal constant CANNOT_EXECUTE_IN_SAME_BLOCK = "cannot execute action in same block";
string internal constant PROTOCOL_NOT_FOUND = "protocol not found";
string internal constant TOP_UP_FAILED = "top up failed";
string internal constant SWAP_PATH_NOT_FOUND = "swap path not found";
string internal constant UNDERLYING_NOT_SUPPORTED = "underlying token not supported";
string internal constant NOT_ENOUGH_FUNDS_WITHDRAWN =
"not enough funds were withdrawn from the pool";
string internal constant FAILED_TRANSFER = "transfer failed";
string internal constant FAILED_MINT = "mint failed";
string internal constant FAILED_REPAY_BORROW = "repay borrow failed";
string internal constant FAILED_METHOD_CALL = "method call failed";
string internal constant NOTHING_TO_CLAIM = "there is no claimable balance";
string internal constant ERC20_BALANCE_EXCEEDED = "ERC20: transfer amount exceeds balance";
string internal constant INVALID_MINTER =
"the minter address of the LP token and the pool address do not match";
string internal constant STAKER_VAULT_EXISTS = "a staker vault already exists for the token";
string internal constant DEADLINE_NOT_ZERO = "deadline must be 0";
string internal constant NOTHING_PENDING = "no pending change to reset";
string internal constant DEADLINE_NOT_SET = "deadline is 0";
string internal constant DEADLINE_NOT_REACHED = "deadline has not been reached yet";
string internal constant DELAY_TOO_SHORT = "delay must be at least 3 days";
string internal constant INSUFFICIENT_UPDATE_BALANCE =
"insufficient funds for updating the position";
string internal constant SAME_AS_CURRENT = "value must be different to existing value";
string internal constant NOT_CAPPED = "the pool is not currently capped";
string internal constant ALREADY_CAPPED = "the pool is already capped";
string internal constant ALREADY_SHUTDOWN = "already shutdown";
string internal constant EXCEEDS_DEPOSIT_CAP = "deposit exceeds deposit cap";
string internal constant VALUE_TOO_LOW_FOR_GAS = "value too low to cover gas";
string internal constant NOT_ENOUGH_FUNDS = "not enough funds to withdraw";
string internal constant ESTIMATED_GAS_TOO_HIGH = "too much ETH will be used for gas";
string internal constant GAUGE_KILLED = "gauge killed";
string internal constant INVALID_TARGET = "Invalid Target";
string internal constant DEPOSIT_FAILED = "deposit failed";
string internal constant GAS_TOO_HIGH = "too much ETH used for gas";
string internal constant GAS_BANK_BALANCE_TOO_LOW = "not enough ETH in gas bank to cover gas";
string internal constant INVALID_TOKEN_TO_ADD = "Invalid token to add";
string internal constant INVALID_TOKEN_TO_REMOVE = "token can not be removed";
string internal constant TIME_DELAY_NOT_EXPIRED = "time delay not expired yet";
string internal constant UNDERLYING_NOT_WITHDRAWABLE =
"pool does not support additional underlying coins to be withdrawn";
string internal constant STRATEGY_SHUTDOWN = "Strategy is shutdown";
string internal constant POOL_SHUTDOWN = "Pool is shutdown";
string internal constant ACTION_SHUTDOWN = "Action is shutdown";
string internal constant ACTION_PAUSED = "Action is paused";
string internal constant STRATEGY_DOES_NOT_EXIST = "Strategy does not exist";
string internal constant GAUGE_STILL_ACTIVE = "Gauge still active";
string internal constant UNSUPPORTED_UNDERLYING = "Underlying not supported";
string internal constant NO_DEX_SET = "no dex has been set for token";
string internal constant INVALID_TOKEN_PAIR = "invalid token pair";
string internal constant TOKEN_NOT_USABLE = "token not usable for the specific action";
string internal constant ADDRESS_NOT_ACTION = "address is not registered action";
string internal constant ACTION_NOT_ACTIVE = "address is not active action";
string internal constant INVALID_SLIPPAGE_TOLERANCE = "Invalid slippage tolerance";
string internal constant INVALID_MAX_FEE = "invalid max fee";
string internal constant POOL_NOT_PAUSED = "Pool must be paused to withdraw from reserve";
string internal constant INTERACTION_LIMIT = "Max of one deposit and withdraw per block";
string internal constant GAUGE_EXISTS = "Gauge already exists";
string internal constant GAUGE_DOES_NOT_EXIST = "Gauge does not exist";
string internal constant EXCEEDS_MAX_BOOST = "Not allowed to exceed maximum boost on Convex";
string internal constant PREPARED_WITHDRAWAL =
"Cannot relock funds when withdrawal is being prepared";
string internal constant ASSET_NOT_SUPPORTED = "Asset not supported";
string internal constant STALE_PRICE = "Price is stale";
string internal constant NEGATIVE_PRICE = "Price is negative";
string internal constant ROUND_NOT_COMPLETE = "Round not complete";
string internal constant NOT_ENOUGH_MERO_STAKED = "Not enough MERO tokens staked";
string internal constant RESERVE_ACCESS_EXCEEDED = "Reserve access exceeded";
}
// File libraries/Roles.sol
pragma solidity 0.8.10;
// solhint-disable private-vars-leading-underscore
library Roles {
bytes32 internal constant GOVERNANCE = "governance";
bytes32 internal constant ADDRESS_PROVIDER = "address_provider";
bytes32 internal constant POOL_FACTORY = "pool_factory";
bytes32 internal constant CONTROLLER = "controller";
bytes32 internal constant GAUGE_ZAP = "gauge_zap";
bytes32 internal constant MAINTENANCE = "maintenance";
bytes32 internal constant INFLATION_ADMIN = "inflation_admin";
bytes32 internal constant INFLATION_MANAGER = "inflation_manager";
bytes32 internal constant POOL = "pool";
bytes32 internal constant VAULT = "vault";
bytes32 internal constant ACTION = "action";
}
// File contracts/access/AuthorizationBase.sol
pragma solidity 0.8.10;
/**
* @notice Provides modifiers for authorization
*/
abstract contract AuthorizationBase {
/**
* @notice Only allows a sender with `role` to perform the given action
*/
modifier onlyRole(bytes32 role) {
require(_roleManager().hasRole(role, msg.sender), Error.UNAUTHORIZED_ACCESS);
_;
}
/**
* @notice Only allows a sender with GOVERNANCE role to perform the given action
*/
modifier onlyGovernance() {
require(_roleManager().hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS);
_;
}
/**
* @notice Only allows a sender with any of `roles` to perform the given action
*/
modifier onlyRoles2(bytes32 role1, bytes32 role2) {
require(_roleManager().hasAnyRole(role1, role2, msg.sender), Error.UNAUTHORIZED_ACCESS);
_;
}
/**
* @notice Only allows a sender with any of `roles` to perform the given action
*/
modifier onlyRoles3(
bytes32 role1,
bytes32 role2,
bytes32 role3
) {
require(
_roleManager().hasAnyRole(role1, role2, role3, msg.sender),
Error.UNAUTHORIZED_ACCESS
);
_;
}
function roleManager() external view virtual returns (IRoleManager) {
return _roleManager();
}
function _roleManager() internal view virtual returns (IRoleManager);
}
// File contracts/access/Authorization.sol
pragma solidity 0.8.10;
contract Authorization is AuthorizationBase {
IRoleManager internal immutable __roleManager;
constructor(IRoleManager roleManager) {
__roleManager = roleManager;
}
function _roleManager() internal view override returns (IRoleManager) {
return __roleManager;
}
}
// File interfaces/IGasBank.sol
pragma solidity 0.8.10;
interface IGasBank {
event Deposit(address indexed account, uint256 value);
event Withdraw(address indexed account, address indexed receiver, uint256 value);
function depositFor(address account) external payable;
function withdrawUnused(address account) external;
function withdrawFrom(address account, uint256 amount) external;
function withdrawFrom(
address account,
address payable to,
uint256 amount
) external;
function balanceOf(address account) external view returns (uint256);
}
// File interfaces/IVaultReserve.sol
pragma solidity 0.8.10;
interface IVaultReserve {
event Deposit(address indexed vault, address indexed token, uint256 amount);
event Withdraw(address indexed vault, address indexed token, uint256 amount);
event VaultListed(address indexed vault);
function deposit(address token, uint256 amount) external payable;
function withdraw(address token, uint256 amount) external;
function getBalance(address vault, address token) external view returns (uint256);
function canWithdraw(address vault) external view returns (bool);
}
// File interfaces/oracles/IOracleProvider.sol
pragma solidity 0.8.10;
interface IOracleProvider {
/// @notice Checks whether the asset is supported
/// @param baseAsset the asset of which the price is to be quoted
/// @return true if the asset is supported
function isAssetSupported(address baseAsset) external view returns (bool);
/// @notice Quotes the USD price of `baseAsset`
/// @param baseAsset the asset of which the price is to be quoted
/// @return the USD price of the asset
function getPriceUSD(address baseAsset) external view returns (uint256);
/// @notice Quotes the ETH price of `baseAsset`
/// @param baseAsset the asset of which the price is to be quoted
/// @return the ETH price of the asset
function getPriceETH(address baseAsset) external view returns (uint256);
}
// File interfaces/strategies/IStrategy.sol
pragma solidity 0.8.10;
interface IStrategy {
function deposit() external payable returns (bool);
function withdraw(uint256 amount) external returns (bool);
function withdrawAll() external returns (uint256);
function harvest() external returns (uint256);
function shutdown() external;
function setCommunityReserve(address _communityReserve) external;
function setStrategist(address strategist_) external;
function name() external view returns (string memory);
function balance() external view returns (uint256);
function harvestable() external view returns (uint256);
function strategist() external view returns (address);
function hasPendingFunds() external view returns (bool);
}
// File interfaces/IVault.sol
pragma solidity 0.8.10;
/**
* @title Interface for a Vault
*/
interface IVault {
event StrategyActivated(address indexed strategy);
event StrategyDeactivated(address indexed strategy);
/**
* @dev 'netProfit' is the profit after all fees have been deducted
*/
event Harvest(uint256 indexed netProfit, uint256 indexed loss);
function initialize(
address _pool,
uint256 _debtLimit,
uint256 _targetAllocation,
uint256 _bound
) external;
function withdrawFromStrategyWaitingForRemoval(address strategy) external returns (uint256);
function deposit() external payable;
function withdraw(uint256 amount) external returns (bool);
function withdrawAvailableToPool() external;
function initializeStrategy(address strategy_) external;
function shutdownStrategy() external;
function withdrawFromReserve(uint256 amount) external;
function updateStrategy(address newStrategy) external;
function activateStrategy() external returns (bool);
function deactivateStrategy() external returns (bool);
function updatePerformanceFee(uint256 newPerformanceFee) external;
function updateStrategistFee(uint256 newStrategistFee) external;
function updateDebtLimit(uint256 newDebtLimit) external;
function updateTargetAllocation(uint256 newTargetAllocation) external;
function updateReserveFee(uint256 newReserveFee) external;
function updateBound(uint256 newBound) external;
function withdrawFromStrategy(uint256 amount) external returns (bool);
function withdrawAllFromStrategy() external returns (bool);
function harvest() external returns (bool);
function getStrategiesWaitingForRemoval() external view returns (address[] memory);
function getAllocatedToStrategyWaitingForRemoval(address strategy)
external
view
returns (uint256);
function getTotalUnderlying() external view returns (uint256);
function getUnderlying() external view returns (address);
function strategy() external view returns (IStrategy);
}
// File interfaces/IStakerVault.sol
pragma solidity 0.8.10;
interface IStakerVault {
event Staked(address indexed account, uint256 amount);
event Unstaked(address indexed account, uint256 amount);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function initialize(address _token) external;
function initializeLpGauge(address _lpGauge) external;
function stake(uint256 amount) external;
function stakeFor(address account, uint256 amount) external;
function unstake(uint256 amount) external;
function unstakeFor(
address src,
address dst,
uint256 amount
) external;
function approve(address spender, uint256 amount) external;
function transfer(address account, uint256 amount) external;
function transferFrom(
address src,
address dst,
uint256 amount
) external;
function increaseActionLockedBalance(address account, uint256 amount) external;
function decreaseActionLockedBalance(address account, uint256 amount) external;
function updateLpGauge(address _lpGauge) external;
function poolCheckpoint() external returns (bool);
function poolCheckpoint(uint256 updateEndTime) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function getToken() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function stakedAndActionLockedBalanceOf(address account) external view returns (uint256);
function actionLockedBalanceOf(address account) external view returns (uint256);
function getStakedByActions() external view returns (uint256);
function getPoolTotalStaked() external view returns (uint256);
function decimals() external view returns (uint8);
function lpGauge() external view returns (address);
}
// File interfaces/pool/ILiquidityPool.sol
pragma solidity 0.8.10;
interface ILiquidityPool {
event Deposit(address indexed minter, uint256 depositAmount, uint256 mintedLpTokens);
event DepositFor(
address indexed minter,
address indexed mintee,
uint256 depositAmount,
uint256 mintedLpTokens
);
event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens);
event LpTokenSet(address indexed lpToken);
event StakerVaultSet(address indexed stakerVault);
event Shutdown();
function redeem(uint256 redeemTokens) external returns (uint256);
function redeem(uint256 redeemTokens, uint256 minRedeemAmount) external returns (uint256);
function calcRedeem(address account, uint256 underlyingAmount) external returns (uint256);
function deposit(uint256 mintAmount) external payable returns (uint256);
function deposit(uint256 mintAmount, uint256 minTokenAmount) external payable returns (uint256);
function depositAndStake(uint256 depositAmount, uint256 minTokenAmount)
external
payable
returns (uint256);
function depositFor(address account, uint256 depositAmount) external payable returns (uint256);
function depositFor(
address account,
uint256 depositAmount,
uint256 minTokenAmount
) external payable returns (uint256);
function unstakeAndRedeem(uint256 redeemLpTokens, uint256 minRedeemAmount)
external
returns (uint256);
function handleLpTokenTransfer(
address from,
address to,
uint256 amount
) external;
function updateVault(address _vault) external;
function setLpToken(address _lpToken) external;
function setStaker() external;
function shutdownPool(bool shutdownStrategy) external;
function shutdownStrategy() external;
function updateRequiredReserves(uint256 _newRatio) external;
function updateReserveDeviation(uint256 newRatio) external;
function updateMinWithdrawalFee(uint256 newFee) external;
function updateMaxWithdrawalFee(uint256 newFee) external;
function updateWithdrawalFeeDecreasePeriod(uint256 newPeriod) external;
function rebalanceVault() external;
function getNewCurrentFees(
uint256 timeToWait,
uint256 lastActionTimestamp,
uint256 feeRatio
) external view returns (uint256);
function vault() external view returns (IVault);
function staker() external view returns (IStakerVault);
function getUnderlying() external view returns (address);
function getLpToken() external view returns (address);
function getWithdrawalFee(address account, uint256 amount) external view returns (uint256);
function exchangeRate() external view returns (uint256);
function totalUnderlying() external view returns (uint256);
function name() external view returns (string memory);
function isShutdown() external view returns (bool);
}
// File libraries/AddressProviderMeta.sol
pragma solidity 0.8.10;
library AddressProviderMeta {
struct Meta {
bool freezable;
bool frozen;
}
function fromUInt(uint256 value) internal pure returns (Meta memory) {
Meta memory meta;
meta.freezable = (value & 1) == 1;
meta.frozen = ((value >> 1) & 1) == 1;
return meta;
}
function toUInt(Meta memory meta) internal pure returns (uint256) {
uint256 value;
value |= meta.freezable ? 1 : 0;
value |= meta.frozen ? 1 << 1 : 0;
return value;
}
}
// File interfaces/IAddressProvider.sol
pragma solidity 0.8.10;
// solhint-disable ordering
interface IAddressProvider {
event KnownAddressKeyAdded(bytes32 indexed key);
event StakerVaultListed(address indexed stakerVault);
event StakerVaultDelisted(address indexed stakerVault);
event ActionListed(address indexed action);
event ActionShutdown(address indexed action);
event PoolListed(address indexed pool);
event VaultUpdated(address indexed previousVault, address indexed newVault);
event FeeHandlerAdded(address feeHandler);
event FeeHandlerRemoved(address feeHandler);
/** Key functions */
function getKnownAddressKeys() external view returns (bytes32[] memory);
function freezeAddress(bytes32 key) external;
/** Pool functions */
function allPools() external view returns (address[] memory);
function addPool(address pool) external;
function poolsCount() external view returns (uint256);
function getPoolAtIndex(uint256 index) external view returns (address);
function isPool(address pool) external view returns (bool);
function getPoolForToken(address token) external view returns (ILiquidityPool);
function safeGetPoolForToken(address token) external view returns (address);
/** Vault functions */
function updateVault(address previousVault, address newVault) external;
function allVaults() external view returns (address[] memory);
function vaultsCount() external view returns (uint256);
function getVaultAtIndex(uint256 index) external view returns (address);
function isVault(address vault) external view returns (bool);
/** Action functions */
function allActions() external view returns (address[] memory);
function actionsCount() external view returns (uint256);
function getActionAtIndex(uint256 index) external view returns (address);
function allActiveActions() external view returns (address[] memory);
function addAction(address action) external returns (bool);
function shutdownAction(address action) external;
function isAction(address action) external view returns (bool);
function isActiveAction(address action) external view returns (bool);
/** Address functions */
function initialize(address roleManager_, address treasury_) external;
function initializeAddress(bytes32 key, address initialAddress) external;
function initializeAddress(
bytes32 key,
address initialAddress,
bool frezable
) external;
function initializeAndFreezeAddress(bytes32 key, address initialAddress) external;
function getAddress(bytes32 key) external view returns (address);
function getAddress(bytes32 key, bool checkExists) external view returns (address);
function getAddressMeta(bytes32 key) external view returns (AddressProviderMeta.Meta memory);
function updateAddress(bytes32 key, address newAddress) external;
function initializeInflationManager(address initialAddress) external;
/** Staker vault functions */
function allStakerVaults() external view returns (address[] memory);
function tryGetStakerVault(address token) external view returns (bool, address);
function getStakerVault(address token) external view returns (address);
function addStakerVault(address stakerVault) external;
function isStakerVault(address stakerVault, address token) external view returns (bool);
function isStakerVaultRegistered(address stakerVault) external view returns (bool);
function isWhiteListedFeeHandler(address feeHandler) external view returns (bool);
/** Fee Handler function */
function addFeeHandler(address feeHandler) external;
function removeFeeHandler(address feeHandler) external;
}
// File interfaces/IFeeBurner.sol
pragma solidity 0.8.10;
interface IFeeBurner {
function burnToTarget(address[] memory tokens, address targetLpToken)
external
payable
returns (uint256);
}
// File interfaces/tokenomics/IMeroToken.sol
pragma solidity 0.8.10;
interface IMeroToken is IERC20 {
function mint(address account, uint256 amount) external;
function cap() external view returns (uint256);
}
// File interfaces/actions/IAction.sol
pragma solidity 0.8.10;
interface IAction {
event UsableTokenAdded(address token);
event UsableTokenRemoved(address token);
event Paused();
event Unpaused();
event Shutdown();
function addUsableToken(address token) external;
function removeUsableToken(address token) external;
function updateActionFee(uint256 actionFee) external;
function updateFeeHandler(address feeHandler) external;
function shutdownAction() external;
function pause() external;
function unpause() external;
function getEthRequiredForGas(address payer) external view returns (uint256);
function getUsableTokens() external view returns (address[] memory);
function isUsable(address token) external view returns (bool);
function feeHandler() external view returns (address);
function isShutdown() external view returns (bool);
function isPaused() external view returns (bool);
}
// File interfaces/tokenomics/IInflationManager.sol
pragma solidity 0.8.10;
interface IInflationManager {
event KeeperGaugeListed(address indexed pool, address indexed keeperGauge);
event AmmGaugeListed(address indexed token, address indexed ammGauge);
event KeeperGaugeDelisted(address indexed pool, address indexed keeperGauge);
event AmmGaugeDelisted(address indexed token, address indexed ammGauge);
/** Pool functions */
function setKeeperGauge(address pool, address _keeperGauge) external returns (bool);
function setAmmGauge(address token, address _ammGauge) external returns (bool);
function setMinter(address _minter) external;
function advanceKeeperGaugeEpoch(address pool) external;
function whitelistGauge(address gauge) external;
function removeStakerVaultFromInflation(address lpToken) external;
function removeAmmGauge(address token) external returns (bool);
function addGaugeForVault(address lpToken) external;
function checkpointAllGauges(uint256 updateEndTime) external;
function mintRewards(address beneficiary, uint256 amount) external;
function checkPointInflation() external;
function removeKeeperGauge(address pool) external;
function getAllAmmGauges() external view returns (address[] memory);
function getLpRateForStakerVault(address stakerVault) external view returns (uint256);
function getKeeperRateForPool(address pool) external view returns (uint256);
function getAmmRateForToken(address token) external view returns (uint256);
function getLpPoolWeight(address pool) external view returns (uint256);
function getKeeperGaugeForPool(address pool) external view returns (address);
function getAmmGaugeForToken(address token) external view returns (address);
function gauges(address lpToken) external view returns (bool);
function ammWeights(address gauge) external view returns (uint256);
function lpPoolWeights(address gauge) external view returns (uint256);
function keeperPoolWeights(address gauge) external view returns (uint256);
function minter() external view returns (address);
function weightBasedKeeperDistributionDeactivated() external view returns (bool);
function totalKeeperPoolWeight() external view returns (uint256);
function totalLpPoolWeight() external view returns (uint256);
function totalAmmTokenWeight() external view returns (uint256);
/** Weight setter functions **/
function updateLpPoolWeight(address lpToken, uint256 newPoolWeight) external;
function updateAmmTokenWeight(address token, uint256 newTokenWeight) external;
function updateKeeperPoolWeight(address pool, uint256 newPoolWeight) external;
function batchUpdateLpPoolWeights(address[] calldata lpTokens, uint256[] calldata weights)
external;
function batchUpdateAmmTokenWeights(address[] calldata tokens, uint256[] calldata weights)
external;
function batchUpdateKeeperPoolWeights(address[] calldata pools, uint256[] calldata weights)
external;
function deactivateWeightBasedKeeperDistribution() external;
}
// File interfaces/IController.sol
pragma solidity 0.8.10;
// solhint-disable ordering
interface IController {
function addressProvider() external view returns (IAddressProvider);
function addStakerVault(address stakerVault) external;
function shutdownPool(ILiquidityPool pool, bool shutdownStrategy) external returns (bool);
function shutdownAction(IAction action) external;
/** Keeper functions */
function updateKeeperRequiredStakedMERO(uint256 amount) external;
function canKeeperExecuteAction(address keeper) external view returns (bool);
function keeperRequireStakedMero() external view returns (uint256);
/** Miscellaneous functions */
function getTotalEthRequiredForGas(address payer) external view returns (uint256);
}
// File interfaces/ISwapperRouter.sol
pragma solidity 0.8.10;
interface ISwapperRouter {
function swapAll(address fromToken, address toToken) external payable returns (uint256);
function setSlippageTolerance(uint256 slippageTolerance_) external;
function setCurvePool(address token_, address curvePool_) external;
function swap(
address fromToken,
address toToken,
uint256 amountIn
) external payable returns (uint256);
function getAmountOut(
address fromToken,
address toToken,
uint256 amountIn
) external view returns (uint256 amountOut);
}
// File libraries/AddressProviderKeys.sol
pragma solidity 0.8.10;
library AddressProviderKeys {
bytes32 internal constant _TREASURY_KEY = "treasury";
bytes32 internal constant _REWARD_HANDLER_KEY = "rewardHandler";
bytes32 internal constant _GAS_BANK_KEY = "gasBank";
bytes32 internal constant _VAULT_RESERVE_KEY = "vaultReserve";
bytes32 internal constant _ORACLE_PROVIDER_KEY = "oracleProvider";
bytes32 internal constant _POOL_FACTORY_KEY = "poolFactory";
bytes32 internal constant _CONTROLLER_KEY = "controller";
bytes32 internal constant _MERO_LOCKER_KEY = "meroLocker";
bytes32 internal constant _INFLATION_MANAGER_KEY = "inflationManager";
bytes32 internal constant _FEE_BURNER_KEY = "feeBurner";
bytes32 internal constant _ROLE_MANAGER_KEY = "roleManager";
bytes32 internal constant _SWAPPER_ROUTER_KEY = "swapperRouter";
}
// File libraries/AddressProviderHelpers.sol
pragma solidity 0.8.10;
library AddressProviderHelpers {
/**
* @return The address of the treasury.
*/
function getTreasury(IAddressProvider provider) internal view returns (address) {
return provider.getAddress(AddressProviderKeys._TREASURY_KEY);
}
/**
* @return The address of the reward handler.
*/
function getRewardHandler(IAddressProvider provider) internal view returns (address) {
return provider.getAddress(AddressProviderKeys._REWARD_HANDLER_KEY);
}
/**
* @dev Returns zero address if no reward handler is set.
* @return The address of the reward handler.
*/
function getSafeRewardHandler(IAddressProvider provider) internal view returns (address) {
return provider.getAddress(AddressProviderKeys._REWARD_HANDLER_KEY, false);
}
/**
* @return The address of the fee burner.
*/
function getFeeBurner(IAddressProvider provider) internal view returns (IFeeBurner) {
return IFeeBurner(provider.getAddress(AddressProviderKeys._FEE_BURNER_KEY));
}
/**
* @return The gas bank.
*/
function getGasBank(IAddressProvider provider) internal view returns (IGasBank) {
return IGasBank(provider.getAddress(AddressProviderKeys._GAS_BANK_KEY));
}
/**
* @return The address of the vault reserve.
*/
function getVaultReserve(IAddressProvider provider) internal view returns (IVaultReserve) {
return IVaultReserve(provider.getAddress(AddressProviderKeys._VAULT_RESERVE_KEY));
}
/**
* @return The oracleProvider.
*/
function getOracleProvider(IAddressProvider provider) internal view returns (IOracleProvider) {
return IOracleProvider(provider.getAddress(AddressProviderKeys._ORACLE_PROVIDER_KEY));
}
/**
* @return the address of the MERO locker
*/
function getMEROLocker(IAddressProvider provider) internal view returns (address) {
return provider.getAddress(AddressProviderKeys._MERO_LOCKER_KEY);
}
/**
* @return the address of the MERO locker
*/
function getRoleManager(IAddressProvider provider) internal view returns (IRoleManager) {
return IRoleManager(provider.getAddress(AddressProviderKeys._ROLE_MANAGER_KEY));
}
/**
* @return the controller
*/
function getController(IAddressProvider provider) internal view returns (IController) {
return IController(provider.getAddress(AddressProviderKeys._CONTROLLER_KEY));
}
/**
* @return the inflation manager
*/
function getInflationManager(IAddressProvider provider)
internal
view
returns (IInflationManager)
{
return IInflationManager(provider.getAddress(AddressProviderKeys._INFLATION_MANAGER_KEY));
}
/**
* @return the inflation manager or `address(0)` if it does not exist
*/
function safeGetInflationManager(IAddressProvider provider)
internal
view
returns (IInflationManager)
{
return
IInflationManager(
provider.getAddress(AddressProviderKeys._INFLATION_MANAGER_KEY, false)
);
}
/**
* @return the swapper router
*/
function getSwapperRouter(IAddressProvider provider) internal view returns (ISwapperRouter) {
return ISwapperRouter(provider.getAddress(AddressProviderKeys._SWAPPER_ROUTER_KEY));
}
}
// File libraries/DecimalScale.sol
pragma solidity ^0.8.4;
library DecimalScale {
uint8 internal constant _DECIMALS = 18; // 18 decimal places
function scaleFrom(uint256 value, uint8 decimals) internal pure returns (uint256) {
if (decimals == _DECIMALS) {
return value;
} else if (decimals > _DECIMALS) {
return value / 10**(decimals - _DECIMALS);
} else {
return value * 10**(_DECIMALS - decimals);
}
}
function scaleTo(uint256 value, uint8 decimals) internal pure returns (uint256) {
if (decimals == _DECIMALS) {
return value;
} else if (decimals > _DECIMALS) {
return value * 10**(decimals - _DECIMALS);
} else {
return value / 10**(_DECIMALS - decimals);
}
}
}
// File libraries/ScaledMath.sol
pragma solidity 0.8.10;
/*
* @dev To use functions of this contract, at least one of the numbers must
* be scaled to `DECIMAL_SCALE`. The result will scaled to `DECIMAL_SCALE`
* if both numbers are scaled to `DECIMAL_SCALE`, otherwise to the scale
* of the number not scaled by `DECIMAL_SCALE`
*/
library ScaledMath {
// solhint-disable-next-line private-vars-leading-underscore
uint256 internal constant DECIMAL_SCALE = 1e18;
// solhint-disable-next-line private-vars-leading-underscore
uint256 internal constant ONE = 1e18;
/**
* @notice Performs a multiplication between two scaled numbers
*/
function scaledMul(uint256 a, uint256 b) internal pure returns (uint256) {
return (a * b) / DECIMAL_SCALE;
}
/**
* @notice Performs a division between two scaled numbers
*/
function scaledDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return (a * DECIMAL_SCALE) / b;
}
/**
* @notice Performs a division between two numbers, rounding up the result
*/
function scaledDivRoundUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (a * DECIMAL_SCALE + b - 1) / b;
}
/**
* @notice Performs a division between two numbers, ignoring any scaling and rounding up the result
*/
function divRoundUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (a + b - 1) / b;
}
}
// File interfaces/vendor/UniswapRouter02.sol
pragma solidity 0.8.10;
interface UniswapRouter02 {
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) external view returns (uint256 amountIn);
function getAmountsIn(uint256 amountOut) external view returns (uint256[] memory amounts);
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) external view returns (uint256 amountOut);
function getAmountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function getAmountsOut(uint256 amountIn, address[] memory path)
external
view
returns (uint256[] memory amounts);
function getReserves(
address factory,
address tokenA,
address tokenB
) external view returns (uint256 reserveA, uint256 reserveB);
function WETH() external pure returns (address);
}
interface UniswapV2Pair {
function getReserves()
external
view
returns (
uint112 _reserve0,
uint112 _reserve1,
uint32 _blockTimestampLast
);
}
interface UniswapV2Factory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
// File interfaces/vendor/IWETH.sol
pragma solidity 0.8.10;
/**
* @notice Interface for WETH9
* @dev https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code
*/
interface IWETH is IERC20 {
function deposit() external payable;
function withdraw(uint256 wad) external;
}
// File interfaces/IERC20Full.sol
pragma solidity 0.8.10;
/// @notice This is the ERC20 interface including optional getter functions
/// The interface is used in the frontend through the generated typechain wrapper
interface IERC20Full is IERC20 {
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function decimals() external view returns (uint8);
}
// File interfaces/vendor/ICurveSwapEth.sol
pragma solidity 0.8.10;
interface ICurveSwapEth {
function get_virtual_price() external view returns (uint256);
function add_liquidity(uint256[2] calldata amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[3] calldata amounts, uint256 min_mint_amount) external payable;
function remove_liquidity_imbalance(uint256[3] calldata amounts, uint256 max_burn_amount)
external;
function remove_liquidity_imbalance(uint256[2] calldata amounts, uint256 max_burn_amount)
external;
function remove_liquidity(uint256 _amount, uint256[3] calldata min_amounts) external;
function exchange(
uint256 i,
uint256 j,
uint256 dx,
uint256 min_dy
) external payable;
function coins(uint256 i) external view returns (address);
function get_dy(
uint256 i,
uint256 j,
uint256 dx
) external view returns (uint256);
function calc_token_amount(uint256[3] calldata amounts, bool deposit)
external
view
returns (uint256);
function calc_token_amount(uint256[2] calldata amounts, bool deposit)
external
view
returns (uint256);
function calc_withdraw_one_coin(uint256 _token_amount, int128 i)
external
view
returns (uint256);
function remove_liquidity_one_coin(
uint256 _token_amount,
int128 i,
uint256 min_amount
) external;
}
// File contracts/swappers/SwapperRouter.sol
pragma solidity 0.8.10;
/**
* The swapper router handles the swapping from one token to another.
* By default it does all swaps through WETH, in two steps checking which DEX is better for each stage of the swap.
* It also supports ETH in or out and handles it by converting to WETH and back.
*/
contract SwapperRouter is ISwapperRouter, Authorization {
using SafeERC20 for IERC20;
using DecimalScale for uint256;
using ScaledMath for uint256;
using AddressProviderHelpers for IAddressProvider;
// Dex contracts
address private constant _UNISWAP = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); // Uniswap Router, used for swapping tokens on Uniswap
address private constant _SUSHISWAP = address(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); // Sushiswap Router, used for swapping tokens on Sushiswap
IWETH private constant _WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); // WETH, used for wrapping and unwrapping ETH for swaps
IAddressProvider private immutable _addressProvider; // Address provider used for getting oracle provider
uint256 public slippageTolerance; // The amount of slippage to allow from the oracle price of an asset
mapping(address => ICurveSwapEth) public curvePools; // Curve Pool to use for swapping with WETH
event Swapped(
address indexed fromToken,
address indexed toToken,
uint256 amountIn,
uint256 amountOut
); // Emitted after a successfull swap
event SetSlippageTolerance(uint256 value); // Emitted after a successful setting of slippage tolerance
event SetCurvePool(address token, address curvePool); // Emitted after a successful setting of a Curve Pool
constructor(address addressProvider_)
Authorization(IAddressProvider(addressProvider_).getRoleManager())
{
_addressProvider = IAddressProvider(addressProvider_);
slippageTolerance = 0.97e18;
}
receive() external payable {} // Used for receiving ETH when unwrapping WETH
/**
* @notice Swaps all of the users balance of fromToken for toToken.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @return amountOut The amount of toToken received.
*/
function swapAll(address fromToken_, address toToken_)
external
payable
override
returns (uint256 amountOut)
{
// Swapping if from token is ETH
if (fromToken_ == address(0)) {
return swap(fromToken_, toToken_, address(this).balance);
}
// Swapping if from token is ERC20
return swap(fromToken_, toToken_, IERC20(fromToken_).balanceOf(address(msg.sender)));
}
/**
* @notice Set slippage tolerance for swaps.
* @dev Stored as a multiplier, e.g. 2% would be set as 0.98.
* @param slippageTolerance_ New slippage tolerance.
*/
function setSlippageTolerance(uint256 slippageTolerance_) external override onlyGovernance {
require(slippageTolerance_ <= ScaledMath.ONE, Error.INVALID_SLIPPAGE_TOLERANCE);
slippageTolerance = slippageTolerance_;
emit SetSlippageTolerance(slippageTolerance_);
}
/**
* @notice Sets the Curve Pool to use for swapping a token with WETH.
* @dev To use Uniswap or Sushiswap instead, set the Curve Pool to the zero address.
* @param token_ The token to set the Curve Pool for.
* @param curvePool_ The address of the Curve Pool.
*/
function setCurvePool(address token_, address curvePool_) external override onlyGovernance {
require(token_ != address(0), Error.ZERO_ADDRESS_NOT_ALLOWED);
require(curvePool_ != address(curvePools[token_]), Error.SAME_ADDRESS_NOT_ALLOWED);
curvePools[token_] = ICurveSwapEth(curvePool_);
emit SetCurvePool(token_, curvePool_);
}
/**
* @notice Gets the amount of toToken received by swapping amountIn of fromToken.
* @dev In the case where a custom swapper is used, return value may not be precise.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @param amountIn_ The amount of fromToken being swapped.
* @return amountOut The amount of toToken received by swapping amountIn of fromToken.
*/
function getAmountOut(
address fromToken_,
address toToken_,
uint256 amountIn_
) external view override returns (uint256 amountOut) {
if (fromToken_ == toToken_ || amountIn_ == 0) return amountIn_;
return _getTokenOut(toToken_, _getWethOut(fromToken_, amountIn_));
}
/**
* @notice Swaps an amount of fromToken to toToken.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @param amountIn_ The amount of fromToken to swap for toToken.
* @return amountOut The amount of toToken received.
*/
function swap(
address fromToken_,
address toToken_,
uint256 amountIn_
) public payable override returns (uint256 amountOut) {
// Validating ETH value sent
require(msg.value == (fromToken_ == address(0) ? amountIn_ : 0), Error.INVALID_AMOUNT);
if (amountIn_ == 0) {
emit Swapped(fromToken_, toToken_, 0, 0);
return 0;
}
// Handling swap between the same token
if (fromToken_ == toToken_) {
if (fromToken_ == address(0)) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = payable(msg.sender).call{value: amountIn_}("");
require(success, Error.FAILED_TRANSFER);
}
emit Swapped(fromToken_, toToken_, amountIn_, amountIn_);
return amountIn_;
}
// Transferring to contract if ERC20
if (fromToken_ != address(0)) {
IERC20(fromToken_).safeTransferFrom(msg.sender, address(this), amountIn_);
}
// Swapping token via WETH
uint256 amountOut_ = _swapWethForToken(toToken_, _swapForWeth(fromToken_));
emit Swapped(fromToken_, toToken_, amountIn_, amountOut_);
return _returnTokens(toToken_, amountOut_);
}
/**
* @dev Swaps the full contract balance of token to WETH.
* @param token_ The token to swap to WETH.
* @return amountOut The amount of WETH received from the swap.
*/
function _swapForWeth(address token_) internal returns (uint256 amountOut) {
if (token_ == address(_WETH)) return _WETH.balanceOf(address(this));
// Handling ETH -> WETH
if (token_ == address(0)) {
uint256 ethBalance_ = address(this).balance;
if (ethBalance_ == 0) return 0;
_WETH.deposit{value: ethBalance_}();
return ethBalance_;
}
// Handling Curve Pool swaps
ICurveSwapEth curvePool_ = curvePools[token_];
if (address(curvePool_) != address(0)) {
uint256 amount_ = IERC20(token_).balanceOf(address(this));
if (amount_ == 0) return 0;
_approve(token_, address(curvePool_));
(uint256 wethIndex_, uint256 tokenIndex_) = _getIndices(curvePool_, token_);
curvePool_.exchange(
tokenIndex_,
wethIndex_,
amount_,
_minWethAmountOut(amount_, token_)
);
return _WETH.balanceOf(address(this));
}
// Handling ERC20 -> WETH
return _swap(token_, address(_WETH), IERC20(token_).balanceOf(address(this)));
}
/**
* @dev Swaps the full contract balance of WETH to token.
* @param token_ The token to swap WETH to.
* @return amountOut The amount of token received from the swap.
*/
function _swapWethForToken(address token_, uint256 amount_)
internal
returns (uint256 amountOut)
{
if (amount_ == 0) return 0;
if (token_ == address(_WETH)) return amount_;
// Handling WETH -> ETH
if (token_ == address(0)) {
_WETH.withdraw(amount_);
return amount_;
}
// Handling Curve Pool swaps
ICurveSwapEth curvePool_ = curvePools[token_];
if (address(curvePool_) != address(0)) {
_approve(address(_WETH), address(curvePool_));
(uint256 wethIndex_, uint256 tokenIndex_) = _getIndices(curvePool_, token_);
curvePool_.exchange(
wethIndex_,
tokenIndex_,
amount_,
_minTokenAmountOut(amount_, token_)
);
return IERC20(token_).balanceOf(address(this));
}
// Handling WETH -> ERC20
return _swap(address(_WETH), token_, amount_);
}
/**
* @dev Swaps an amount of fromToken to toToken.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @param amount_ The amount of fromToken to swap.
* @return amountOut The amount of toToken received from the swap.
*/
function _swap(
address fromToken_,
address toToken_,
uint256 amount_
) internal returns (uint256 amountOut) {
if (amount_ == 0) return 0;
if (fromToken_ == toToken_) return amount_;
address dex_ = _getBestDex(fromToken_, toToken_, amount_);
_approve(fromToken_, dex_);
address[] memory path_ = new address[](2);
path_[0] = fromToken_;
path_[1] = toToken_;
return
UniswapRouter02(dex_).swapExactTokensForTokens(
amount_,
_getAmountOutMin(amount_, fromToken_, toToken_),
path_,
address(this),
block.timestamp
)[1];
}
/**
* @dev Approves infinite spending for the given spender.
* @param token_ The token to approve for.
* @param spender_ The spender to approve.
*/
function _approve(address token_, address spender_) internal {
if (IERC20(token_).allowance(address(this), spender_) > 0) return;
IERC20(token_).safeApprove(spender_, type(uint256).max);
}
/**
* @dev Returns an amount of tokens to the sender.
* @param token_ The token to return to sender.
* @param amount_ The amount of tokens to return to sender.
* @return amountReturned The amount of tokens returned to sender.
*/
function _returnTokens(address token_, uint256 amount_)
internal
returns (uint256 amountReturned)
{
// Returning if ETH
if (token_ == address(0)) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = payable(msg.sender).call{value: amount_}("");
require(success, Error.FAILED_TRANSFER);
return amount_;
}
// Returning if ERC20
IERC20(token_).safeTransfer(msg.sender, amount_);
return amount_;
}
/**
* @dev Gets the amount of WETH received by swapping amount of token
* In the case where a custom swapper is used, return value may not be precise.
* @param token_ The token to swap from.
* @param amount_ The mount of token being swapped.
* @return amountOut The amount of WETH received by swapping amount of token.
*/
function _getWethOut(address token_, uint256 amount_)
internal
view
returns (uint256 amountOut)
{
if (token_ == address(_WETH) || token_ == address(0)) return amount_;
// Handling Curve Pool swaps
ICurveSwapEth curvePool_ = curvePools[token_];
if (address(curvePool_) != address(0)) {
(uint256 wethIndex_, uint256 tokenIndex_) = _getIndices(curvePool_, token_);
return curvePool_.get_dy(tokenIndex_, wethIndex_, amount_);
}
return
_tokenAmountOut(
token_,
address(_WETH),
amount_,
_getBestDex(token_, address(_WETH), amount_)
);
}
/**
* @dev Gets the amount of token received by swapping amount of WETH
* In the case where a custom swapper is used, return value may not be precise.
* @param token_ The token to swap to.
* @param amount_ The amount of WETH being swapped.
* @return amountOut The amount of token received by swapping amount of WETH.
*/
function _getTokenOut(address token_, uint256 amount_)
internal
view
returns (uint256 amountOut)
{
if (token_ == address(_WETH) || token_ == address(0)) return amount_;
// Handling Curve Pool swaps
ICurveSwapEth curvePool_ = curvePools[token_];
if (address(curvePool_) != address(0)) {
(uint256 wethIndex_, uint256 tokenIndex_) = _getIndices(curvePool_, token_);
return curvePool_.get_dy(wethIndex_, tokenIndex_, amount_);
}
return
_tokenAmountOut(
address(_WETH),
token_,
amount_,
_getBestDex(address(_WETH), token_, amount_)
);
}
/**
* @dev Gets the best dex to use for swapping tokens based on which gives the highest amount out.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @param amount_ The amount of fromToken to swap.
* @return bestDex The best dex to use for swapping tokens based on which gives the highest amount out
*/
function _getBestDex(
address fromToken_,
address toToken_,
uint256 amount_
) internal view returns (address bestDex) {
address uniswap_ = _UNISWAP;
address sushiswap_ = _SUSHISWAP;
return
_tokenAmountOut(fromToken_, toToken_, amount_, uniswap_) >=
_tokenAmountOut(fromToken_, toToken_, amount_, sushiswap_)
? uniswap_
: sushiswap_;
}
/**
* @notice Gets the amount of toToken received by swapping amountIn of fromToken.
* @param fromToken_ The token to swap from.
* @param toToken_ The token to swap to.
* @param amountIn_ The amount of fromToken being swapped.
* @param dex_ The DEX to use for the swap.
* @return amountOut The amount of toToken received by swapping amountIn of fromToken.
*/
function _tokenAmountOut(
address fromToken_,
address toToken_,
uint256 amountIn_,
address dex_
) internal view returns (uint256 amountOut) {
address[] memory path_ = new address[](2);
path_[0] = fromToken_;
path_[1] = toToken_;
return UniswapRouter02(dex_).getAmountsOut(amountIn_, path_)[1];
}
/**
* @dev Returns the minimum amount of toToken_ to receive from swap.
* @param amount_ The amount of fromToken_ being swapped.
* @param fromToken_ The Token being swapped from.
* @param toToken_ The Token being swapped to.
* @return amountOutMin The minimum amount of toToken_ to receive from swap.
*/
function _getAmountOutMin(
uint256 amount_,
address fromToken_,
address toToken_
) internal view returns (uint256 amountOutMin) {
return
fromToken_ == address(_WETH)
? _minTokenAmountOut(amount_, toToken_)
: _minWethAmountOut(amount_, fromToken_);
}
/**
* @dev Returns the minimum amount of Token to receive from swap.
* @param wethAmount_ The amount of WETH being swapped.
* @param token_ The Token the WETH is being swapped to.
* @return minAmountOut The minimum amount of Token to receive from swap.
*/
function _minTokenAmountOut(uint256 wethAmount_, address token_)
internal
view
returns (uint256 minAmountOut)
{
uint256 priceInEth_ = _getPriceInEth(token_);
if (priceInEth_ == 0) return 0;
return
wethAmount_.scaledDiv(priceInEth_).scaledMul(slippageTolerance).scaleTo(
IERC20Full(token_).decimals()
);
}
/**
* @dev Returns the minimum amount of WETH to receive from swap.
* @param tokenAmount_ The amount of Token being swapped.
* @param token_ The Token that is being swapped for WETH.
* @return minAmountOut The minimum amount of WETH to receive from swap.
*/
function _minWethAmountOut(uint256 tokenAmount_, address token_)
internal
view
returns (uint256 minAmountOut)
{
uint256 priceInEth_ = _getPriceInEth(token_);
if (priceInEth_ == 0) return 0;
return
tokenAmount_.scaledMul(priceInEth_).scaledMul(slippageTolerance).scaleFrom(
IERC20Full(token_).decimals()
);
}
/**
* @dev Returns the price in ETH of the given token.
* If no oracle exists for the token, returns 0.
* Only very minor assets should only ever return 0, which is why we choose
* to accept the risk of not having proper slippage in place later
* @param token_ The token to get the price for.
* @return tokenPriceInEth The price of the token in ETH.
*/
function _getPriceInEth(address token_) internal view returns (uint256 tokenPriceInEth) {
IOracleProvider oracleProvider = _addressProvider.getOracleProvider();
if (oracleProvider.isAssetSupported(token_)) {
return oracleProvider.getPriceETH(token_);
}
return 0;
}
/**
* @dev Returns the Curve Pool coin indices for a given Token.
* @param curvePool_ The Curve Pool to return the indices for.
* @param token_ The Token to get the indices for.
* @return wethIndex_ The coin index for WETH.
* @return tokenIndex_ The coin index for the Token.
*/
function _getIndices(ICurveSwapEth curvePool_, address token_)
internal
view
returns (uint256 wethIndex_, uint256 tokenIndex_)
{
return curvePool_.coins(1) == token_ ? (0, 1) : (1, 0);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"addressProvider_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"curvePool","type":"address"}],"name":"SetCurvePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetSlippageTolerance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromToken","type":"address"},{"indexed":true,"internalType":"address","name":"toToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swapped","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"curvePools","outputs":[{"internalType":"contract ICurveSwapEth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken_","type":"address"},{"internalType":"address","name":"toToken_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roleManager","outputs":[{"internalType":"contract IRoleManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"curvePool_","type":"address"}],"name":"setCurvePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slippageTolerance_","type":"uint256"}],"name":"setSlippageTolerance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slippageTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken_","type":"address"},{"internalType":"address","name":"toToken_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken_","type":"address"},{"internalType":"address","name":"toToken_","type":"address"}],"name":"swapAll","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002318380380620023188339810160408190526200003491620000f9565b62000053816001600160a01b03166200007760201b620008c51760201c565b6001600160a01b039081166080521660a052670d7621dc582100006000556200012b565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a72190602401602060405180830381865afa158015620000cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f39190620000f9565b92915050565b6000602082840312156200010c57600080fd5b81516001600160a01b03811681146200012457600080fd5b9392505050565b60805160a0516121ba6200015e60003960006118f40152600081816099015281816101ba015261042901526121ba6000f3fe60806040526004361061007e5760003560e01c806358fd9be01161004e57806358fd9be014610139578063a788871814610159578063d03153aa1461018f578063df791e50146101a557600080fd5b8062435da51461008a578063117da1ee146100d65780633ff37e8f146100f85780634aa066521461011957600080fd5b3661008557005b600080fd5b34801561009657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e257600080fd5b506100f66100f1366004611cb6565b6101b8565b005b61010b610106366004611ce7565b610343565b6040519081526020016100cd565b34801561012557600080fd5b5061010b610134366004611d20565b6103de565b34801561014557600080fd5b506100f6610154366004611ce7565b610427565b34801561016557600080fd5b506100b9610174366004611d61565b6001602052600090815260409020546001600160a01b031681565b34801561019b57600080fd5b5061010b60005481565b61010b6101b3366004611d20565b610650565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102569190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b815250906102a95760405162461bcd60e51b81526004016102a09190611dcc565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a76400008211156103075760405162461bcd60e51b81526004016102a09190611dcc565b5060008190556040518181527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a799060200160405180910390a150565b60006001600160a01b0383166103655761035e838347610650565b90506103d8565b6040516370a0823160e01b81523360048201526103d590849084906001600160a01b038316906370a0823190602401602060405180830381865afa1580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b39190611dff565b90505b92915050565b6000826001600160a01b0316846001600160a01b031614806103fe575081155b1561040a575080610420565b61041d83610418868561093f565b610a68565b90505b9392505050565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c59190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b8152509061050f5760405162461bcd60e51b81526004016102a09190611dcc565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b03831661056b5760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b03808316600090815260016020908152604091829020548251808401909352601883527f73616d652061646472657373206e6f7420616c6c6f7765640000000000000000918301919091529091838116911614156105e45760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc99581e03a01bc0e74719af7085e6d62b1a853b511cb673db6c840eb4ec648ca910160405180910390a15050565b60006001600160a01b0384161561066857600061066a565b815b34146040518060400160405280600e81526020016d1a5b9d985b1a5908185b5bdd5b9d60921b815250906106b15760405162461bcd60e51b81526004016102a09190611dcc565b50816107085760408051600080825260208201526001600160a01b0380861692908716917fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb910160405180910390a3506000610420565b826001600160a01b0316846001600160a01b03161415610822576001600160a01b0384166107c557604051600090339084908381818185875af1925050503d8060008114610772576040519150601f19603f3d011682016040523d82523d6000602084013e610777565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b815250906107c25760405162461bcd60e51b81526004016102a09190611dcc565b50505b826001600160a01b0316846001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb8485604051610813929190918252602082015260400190565b60405180910390a35080610420565b6001600160a01b03841615610846576108466001600160a01b038516333085610b3d565b600061085a8461085587610bae565b610ef3565b9050836001600160a01b0316856001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb85846040516108aa929190918252602082015260400190565b60405180910390a36108bc84826110ab565b95945050505050565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611e18565b60006001600160a01b038316600080516020612165833981519152148061096d57506001600160a01b038316155b156109795750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610a2e576000806109a78387611171565b60405163556d6e9f60e01b815260048101829052602481018390526044810188905291935091506001600160a01b0384169063556d6e9f906064015b602060405180830381865afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190611dff565b93505050506103d8565b610a608460008051602061216583398151915285610a5b886000805160206121658339815191528961121a565b611273565b949350505050565b60006001600160a01b0383166000805160206121658339815191521480610a9657506001600160a01b038316155b15610aa25750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610b1057600080610ad08387611171565b60405163556d6e9f60e01b815260048101839052602481018290526044810188905291935091506001600160a01b0384169063556d6e9f906064016109e3565b610a606000805160206121658339815191528585610a5b600080516020612165833981519152898961121a565b6040516001600160a01b0380851660248301528316604482015260648101829052610ba89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611387565b50505050565b60006001600160a01b0382166000805160206121658339815191521415610c3c576040516370a0823160e01b8152306004820152600080516020612165833981519152906370a0823190602401602060405180830381865afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611dff565b6001600160a01b038216610cc2574780610c595750600092915050565b6000805160206121658339815191526001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b50939695505050505050565b6001600160a01b03808316600090815260016020526040902054168015610e70576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4e9190611dff565b905080610d5f575060009392505050565b610d69848361145e565b600080610d768487611171565b91509150836001600160a01b0316635b41b908828486610d96888c6114f6565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260008051602061216583398151915292506370a082319150602401602060405180830381865afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e669190611dff565b9695505050505050565b6040516370a0823160e01b8152306004820152610420908490600080516020612165833981519152906001600160a01b038316906370a0823190602401602060405180830381865afa158015610eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee9190611dff565b611595565b600081610f02575060006103d8565b6001600160a01b0383166000805160206121658339815191521415610f285750806103d8565b6001600160a01b038316610f9d57604051632e1a7d4d60e01b81526004810183905260008051602061216583398151915290632e1a7d4d90602401600060405180830381600087803b158015610f7d57600080fd5b505af1158015610f91573d6000803e3d6000fd5b505050508190506103d8565b6001600160a01b0380841660009081526001602052604090205416801561109257610fd66000805160206121658339815191528261145e565b600080610fe38387611171565b91509150826001600160a01b0316635b41b9088383886110038a8c6116ff565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561104e57600080fd5b505af1158015611062573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201526001600160a01b03891692506370a0823191506024016109e3565b610a606000805160206121658339815191528585611595565b60006001600160a01b03831661115757604051600090339084908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061114d5760405162461bcd60e51b81526004016102a09190611dcc565b50829150506103d8565b61116b6001600160a01b0384163384611798565b50919050565b600080826001600160a01b0316846001600160a01b031663c661065760016040518263ffffffff1660e01b81526004016111ad91815260200190565b602060405180830381865afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190611e18565b6001600160a01b031614611205576001600061120a565b600060015b60ff918216969116945092505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f61125286868684611273565b61125e87878786611273565b101561126a5780610e66565b50949350505050565b6040805160028082526060820183526000928392919060208301908036833701905050905085816000815181106112ac576112ac611e4b565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106112e0576112e0611e4b565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81529084169063d06ca61f9061131d9087908590600401611ea5565b600060405180830381865afa15801561133a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113629190810190611ebe565b60018151811061137457611374611e4b565b6020026020010151915050949350505050565b60006113dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117c89092919063ffffffff16565b80519091501561145957808060200190518101906113fa9190611d7e565b6114595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a0565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301526000919084169063dd62ed3e90604401602060405180830381865afa1580156114ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d29190611dff565b11156114dc575050565b6114f26001600160a01b038316826000196117d7565b5050565b600080611502836118ec565b9050806115135760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115789190611f7c565b60005461158f906115898886611a07565b90611a07565b90611a26565b6000816115a457506000610420565b826001600160a01b0316846001600160a01b031614156115c5575080610420565b60006115d285858561121a565b90506115de858261145e565b604080516002808252606082018352600092602083019080368337019050509050858160008151811061161357611613611e4b565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018151811061164757611647611e4b565b6001600160a01b03928316602091820292909201015282166338ed173985611670818a8a611a87565b8430426040518663ffffffff1660e01b8152600401611693959493929190611f9f565b6000604051808303816000875af11580156116b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116da9190810190611ebe565b6001815181106116ec576116ec611e4b565b6020026020010151925050509392505050565b60008061170b836118ec565b90508061171c5760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190611f7c565b600054611792906115898886611ac0565b90611ad5565b6040516001600160a01b03831660248201526044810182905261145990849063a9059cbb60e01b90606401610b71565b606061041d8484600085611b0c565b8015806118515750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190611dff565b155b6118bc5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016102a0565b6040516001600160a01b03831660248201526044810182905261145990849063095ea7b360e01b90606401610b71565b6000806119217f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611c3d565b6040516308c9682b60e31b81526001600160a01b0385811660048301529192509082169063464b415890602401602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190611d7e565b156119fe5760405163e5ec9db960e01b81526001600160a01b03848116600483015282169063e5ec9db990602401602060405180830381865afa1580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104209190611dff565b50600092915050565b6000670de0b6b3a7640000611a1c8385611ff1565b6103d59190612010565b600060ff821660121415611a3b5750816103d8565b601260ff83161115611a6757611a52601283612032565b611a5d90600a612139565b61035e9084612010565b611a72826012612032565b611a7d90600a612139565b61035e9084611ff1565b60006001600160a01b03831660008051602061216583398151915214611ab657611ab184846114f6565b61041d565b61041d84836116ff565b600081611a1c670de0b6b3a764000085611ff1565b600060ff821660121415611aea5750816103d8565b601260ff83161115611b0157611a72601283612032565b611a52826012612032565b606082471015611b6d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016102a0565b6001600160a01b0385163b611bc45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a0565b600080866001600160a01b03168587604051611be09190612148565b60006040518083038185875af1925050503d8060008114611c1d576040519150601f19603f3d011682016040523d82523d6000602084013e611c22565b606091505b5091509150611c32828286611c7d565b979650505050505050565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a721906024016108fe565b60608315611c8c575081610420565b825115611c9c5782518084602001fd5b8160405162461bcd60e51b81526004016102a09190611dcc565b600060208284031215611cc857600080fd5b5035919050565b6001600160a01b0381168114611ce457600080fd5b50565b60008060408385031215611cfa57600080fd5b8235611d0581611ccf565b91506020830135611d1581611ccf565b809150509250929050565b600080600060608486031215611d3557600080fd5b8335611d4081611ccf565b92506020840135611d5081611ccf565b929592945050506040919091013590565b600060208284031215611d7357600080fd5b813561042081611ccf565b600060208284031215611d9057600080fd5b8151801515811461042057600080fd5b60005b83811015611dbb578181015183820152602001611da3565b83811115610ba85750506000910152565b6020815260008251806020840152611deb816040850160208701611da0565b601f01601f19169190910160400192915050565b600060208284031215611e1157600080fd5b5051919050565b600060208284031215611e2a57600080fd5b815161042081611ccf565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015611e9a5781516001600160a01b031687529582019590820190600101611e75565b509495945050505050565b82815260406020820152600061041d6040830184611e61565b60006020808385031215611ed157600080fd5b825167ffffffffffffffff80821115611ee957600080fd5b818501915085601f830112611efd57600080fd5b815181811115611f0f57611f0f611e35565b8060051b604051601f19603f83011681018181108582111715611f3457611f34611e35565b604052918252848201925083810185019188831115611f5257600080fd5b938501935b82851015611f7057845184529385019392850192611f57565b98975050505050505050565b600060208284031215611f8e57600080fd5b815160ff8116811461042057600080fd5b85815284602082015260a060408201526000611fbe60a0830186611e61565b6001600160a01b0394909416606083015250608001529392505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561200b5761200b611fdb565b500290565b60008261202d57634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168082101561204c5761204c611fdb565b90039392505050565b600181815b8085111561209057816000190482111561207657612076611fdb565b8085161561208357918102915b93841c939080029061205a565b509250929050565b6000826120a7575060016103d8565b816120b4575060006103d8565b81600181146120ca57600281146120d4576120f0565b60019150506103d8565b60ff8411156120e5576120e5611fdb565b50506001821b6103d8565b5060208310610133831016604e8410600b8410161715612113575081810a6103d8565b61211d8383612055565b806000190482111561213157612131611fdb565b029392505050565b60006103d560ff841683612098565b6000825161215a818460208701611da0565b919091019291505056fe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a2646970667358221220ea55d794c7e8966c0055b4eb6dc983848c98aa09208190462fa13b6c86f223fc64736f6c634300080a0033000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
Deployed Bytecode
0x60806040526004361061007e5760003560e01c806358fd9be01161004e57806358fd9be014610139578063a788871814610159578063d03153aa1461018f578063df791e50146101a557600080fd5b8062435da51461008a578063117da1ee146100d65780633ff37e8f146100f85780634aa066521461011957600080fd5b3661008557005b600080fd5b34801561009657600080fd5b507f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e235b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e257600080fd5b506100f66100f1366004611cb6565b6101b8565b005b61010b610106366004611ce7565b610343565b6040519081526020016100cd565b34801561012557600080fd5b5061010b610134366004611d20565b6103de565b34801561014557600080fd5b506100f6610154366004611ce7565b610427565b34801561016557600080fd5b506100b9610174366004611d61565b6001602052600090815260409020546001600160a01b031681565b34801561019b57600080fd5b5061010b60005481565b61010b6101b3366004611d20565b610650565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102569190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b815250906102a95760405162461bcd60e51b81526004016102a09190611dcc565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a76400008211156103075760405162461bcd60e51b81526004016102a09190611dcc565b5060008190556040518181527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a799060200160405180910390a150565b60006001600160a01b0383166103655761035e838347610650565b90506103d8565b6040516370a0823160e01b81523360048201526103d590849084906001600160a01b038316906370a0823190602401602060405180830381865afa1580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b39190611dff565b90505b92915050565b6000826001600160a01b0316846001600160a01b031614806103fe575081155b1561040a575080610420565b61041d83610418868561093f565b610a68565b90505b9392505050565b7f00000000000000000000000046dcde86b25a3f3b61eadd6b7225f4e2721c0e23604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c59190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b8152509061050f5760405162461bcd60e51b81526004016102a09190611dcc565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b03831661056b5760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b03808316600090815260016020908152604091829020548251808401909352601883527f73616d652061646472657373206e6f7420616c6c6f7765640000000000000000918301919091529091838116911614156105e45760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc99581e03a01bc0e74719af7085e6d62b1a853b511cb673db6c840eb4ec648ca910160405180910390a15050565b60006001600160a01b0384161561066857600061066a565b815b34146040518060400160405280600e81526020016d1a5b9d985b1a5908185b5bdd5b9d60921b815250906106b15760405162461bcd60e51b81526004016102a09190611dcc565b50816107085760408051600080825260208201526001600160a01b0380861692908716917fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb910160405180910390a3506000610420565b826001600160a01b0316846001600160a01b03161415610822576001600160a01b0384166107c557604051600090339084908381818185875af1925050503d8060008114610772576040519150601f19603f3d011682016040523d82523d6000602084013e610777565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b815250906107c25760405162461bcd60e51b81526004016102a09190611dcc565b50505b826001600160a01b0316846001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb8485604051610813929190918252602082015260400190565b60405180910390a35080610420565b6001600160a01b03841615610846576108466001600160a01b038516333085610b3d565b600061085a8461085587610bae565b610ef3565b9050836001600160a01b0316856001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb85846040516108aa929190918252602082015260400190565b60405180910390a36108bc84826110ab565b95945050505050565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611e18565b60006001600160a01b038316600080516020612165833981519152148061096d57506001600160a01b038316155b156109795750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610a2e576000806109a78387611171565b60405163556d6e9f60e01b815260048101829052602481018390526044810188905291935091506001600160a01b0384169063556d6e9f906064015b602060405180830381865afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190611dff565b93505050506103d8565b610a608460008051602061216583398151915285610a5b886000805160206121658339815191528961121a565b611273565b949350505050565b60006001600160a01b0383166000805160206121658339815191521480610a9657506001600160a01b038316155b15610aa25750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610b1057600080610ad08387611171565b60405163556d6e9f60e01b815260048101839052602481018290526044810188905291935091506001600160a01b0384169063556d6e9f906064016109e3565b610a606000805160206121658339815191528585610a5b600080516020612165833981519152898961121a565b6040516001600160a01b0380851660248301528316604482015260648101829052610ba89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611387565b50505050565b60006001600160a01b0382166000805160206121658339815191521415610c3c576040516370a0823160e01b8152306004820152600080516020612165833981519152906370a0823190602401602060405180830381865afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611dff565b6001600160a01b038216610cc2574780610c595750600092915050565b6000805160206121658339815191526001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b50939695505050505050565b6001600160a01b03808316600090815260016020526040902054168015610e70576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4e9190611dff565b905080610d5f575060009392505050565b610d69848361145e565b600080610d768487611171565b91509150836001600160a01b0316635b41b908828486610d96888c6114f6565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260008051602061216583398151915292506370a082319150602401602060405180830381865afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e669190611dff565b9695505050505050565b6040516370a0823160e01b8152306004820152610420908490600080516020612165833981519152906001600160a01b038316906370a0823190602401602060405180830381865afa158015610eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee9190611dff565b611595565b600081610f02575060006103d8565b6001600160a01b0383166000805160206121658339815191521415610f285750806103d8565b6001600160a01b038316610f9d57604051632e1a7d4d60e01b81526004810183905260008051602061216583398151915290632e1a7d4d90602401600060405180830381600087803b158015610f7d57600080fd5b505af1158015610f91573d6000803e3d6000fd5b505050508190506103d8565b6001600160a01b0380841660009081526001602052604090205416801561109257610fd66000805160206121658339815191528261145e565b600080610fe38387611171565b91509150826001600160a01b0316635b41b9088383886110038a8c6116ff565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561104e57600080fd5b505af1158015611062573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201526001600160a01b03891692506370a0823191506024016109e3565b610a606000805160206121658339815191528585611595565b60006001600160a01b03831661115757604051600090339084908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061114d5760405162461bcd60e51b81526004016102a09190611dcc565b50829150506103d8565b61116b6001600160a01b0384163384611798565b50919050565b600080826001600160a01b0316846001600160a01b031663c661065760016040518263ffffffff1660e01b81526004016111ad91815260200190565b602060405180830381865afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190611e18565b6001600160a01b031614611205576001600061120a565b600060015b60ff918216969116945092505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f61125286868684611273565b61125e87878786611273565b101561126a5780610e66565b50949350505050565b6040805160028082526060820183526000928392919060208301908036833701905050905085816000815181106112ac576112ac611e4b565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106112e0576112e0611e4b565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81529084169063d06ca61f9061131d9087908590600401611ea5565b600060405180830381865afa15801561133a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113629190810190611ebe565b60018151811061137457611374611e4b565b6020026020010151915050949350505050565b60006113dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117c89092919063ffffffff16565b80519091501561145957808060200190518101906113fa9190611d7e565b6114595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a0565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301526000919084169063dd62ed3e90604401602060405180830381865afa1580156114ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d29190611dff565b11156114dc575050565b6114f26001600160a01b038316826000196117d7565b5050565b600080611502836118ec565b9050806115135760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115789190611f7c565b60005461158f906115898886611a07565b90611a07565b90611a26565b6000816115a457506000610420565b826001600160a01b0316846001600160a01b031614156115c5575080610420565b60006115d285858561121a565b90506115de858261145e565b604080516002808252606082018352600092602083019080368337019050509050858160008151811061161357611613611e4b565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018151811061164757611647611e4b565b6001600160a01b03928316602091820292909201015282166338ed173985611670818a8a611a87565b8430426040518663ffffffff1660e01b8152600401611693959493929190611f9f565b6000604051808303816000875af11580156116b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116da9190810190611ebe565b6001815181106116ec576116ec611e4b565b6020026020010151925050509392505050565b60008061170b836118ec565b90508061171c5760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190611f7c565b600054611792906115898886611ac0565b90611ad5565b6040516001600160a01b03831660248201526044810182905261145990849063a9059cbb60e01b90606401610b71565b606061041d8484600085611b0c565b8015806118515750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190611dff565b155b6118bc5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016102a0565b6040516001600160a01b03831660248201526044810182905261145990849063095ea7b360e01b90606401610b71565b6000806119217f000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d76001600160a01b0316611c3d565b6040516308c9682b60e31b81526001600160a01b0385811660048301529192509082169063464b415890602401602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190611d7e565b156119fe5760405163e5ec9db960e01b81526001600160a01b03848116600483015282169063e5ec9db990602401602060405180830381865afa1580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104209190611dff565b50600092915050565b6000670de0b6b3a7640000611a1c8385611ff1565b6103d59190612010565b600060ff821660121415611a3b5750816103d8565b601260ff83161115611a6757611a52601283612032565b611a5d90600a612139565b61035e9084612010565b611a72826012612032565b611a7d90600a612139565b61035e9084611ff1565b60006001600160a01b03831660008051602061216583398151915214611ab657611ab184846114f6565b61041d565b61041d84836116ff565b600081611a1c670de0b6b3a764000085611ff1565b600060ff821660121415611aea5750816103d8565b601260ff83161115611b0157611a72601283612032565b611a52826012612032565b606082471015611b6d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016102a0565b6001600160a01b0385163b611bc45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a0565b600080866001600160a01b03168587604051611be09190612148565b60006040518083038185875af1925050503d8060008114611c1d576040519150601f19603f3d011682016040523d82523d6000602084013e611c22565b606091505b5091509150611c32828286611c7d565b979650505050505050565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a721906024016108fe565b60608315611c8c575081610420565b825115611c9c5782518084602001fd5b8160405162461bcd60e51b81526004016102a09190611dcc565b600060208284031215611cc857600080fd5b5035919050565b6001600160a01b0381168114611ce457600080fd5b50565b60008060408385031215611cfa57600080fd5b8235611d0581611ccf565b91506020830135611d1581611ccf565b809150509250929050565b600080600060608486031215611d3557600080fd5b8335611d4081611ccf565b92506020840135611d5081611ccf565b929592945050506040919091013590565b600060208284031215611d7357600080fd5b813561042081611ccf565b600060208284031215611d9057600080fd5b8151801515811461042057600080fd5b60005b83811015611dbb578181015183820152602001611da3565b83811115610ba85750506000910152565b6020815260008251806020840152611deb816040850160208701611da0565b601f01601f19169190910160400192915050565b600060208284031215611e1157600080fd5b5051919050565b600060208284031215611e2a57600080fd5b815161042081611ccf565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015611e9a5781516001600160a01b031687529582019590820190600101611e75565b509495945050505050565b82815260406020820152600061041d6040830184611e61565b60006020808385031215611ed157600080fd5b825167ffffffffffffffff80821115611ee957600080fd5b818501915085601f830112611efd57600080fd5b815181811115611f0f57611f0f611e35565b8060051b604051601f19603f83011681018181108582111715611f3457611f34611e35565b604052918252848201925083810185019188831115611f5257600080fd5b938501935b82851015611f7057845184529385019392850192611f57565b98975050505050505050565b600060208284031215611f8e57600080fd5b815160ff8116811461042057600080fd5b85815284602082015260a060408201526000611fbe60a0830186611e61565b6001600160a01b0394909416606083015250608001529392505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561200b5761200b611fdb565b500290565b60008261202d57634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168082101561204c5761204c611fdb565b90039392505050565b600181815b8085111561209057816000190482111561207657612076611fdb565b8085161561208357918102915b93841c939080029061205a565b509250929050565b6000826120a7575060016103d8565b816120b4575060006103d8565b81600181146120ca57600281146120d4576120f0565b60019150506103d8565b60ff8411156120e5576120e5611fdb565b50506001821b6103d8565b5060208310610133831016604e8410600b8410161715612113575081810a6103d8565b61211d8383612055565b806000190482111561213157612131611fdb565b029392505050565b60006103d560ff841683612098565b6000825161215a818460208701611da0565b919091019291505056fe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a2646970667358221220ea55d794c7e8966c0055b4eb6dc983848c98aa09208190462fa13b6c86f223fc64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
-----Decoded View---------------
Arg [0] : addressProvider_ (address): 0xa298d39715AE492e4CAF3Ccb33cBF57abC5238d7
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a298d39715ae492e4caf3ccb33cbf57abc5238d7
Deployed Bytecode Sourcemap
61316:18233:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27760:108;;;;;;;;;;-1:-1:-1;28312:13:0;27760:108;;;-1:-1:-1;;;;;198:32:1;;;180:51;;168:2;153:18;27760:108:0;;;;;;;;63980:294;;;;;;;;;;-1:-1:-1;63980:294:0;;;;;:::i;:::-;;:::i;:::-;;63315:464;;;;;;:::i;:::-;;:::i;:::-;;;1102:25:1;;;1090:2;1075:18;63315:464:0;956:177:1;65405:323:0;;;;;;;;;;-1:-1:-1;65405:323:0;;;;;:::i;:::-;;:::i;64581:369::-;;;;;;;;;;-1:-1:-1;64581:369:0;;;;;:::i;:::-;;:::i;62234:51::-;;;;;;;;;;-1:-1:-1;62234:51:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;62234:51:0;;;62126:32;;;;;;;;;;;;;;;;66035:1325;;;;;;:::i;:::-;;:::i;63980:294::-;28312:13;27001:52;;-1:-1:-1;;;27001:52:0;;-1:-1:-1;;;27001:52:0;;;2255:25:1;27042:10:0;2296:18:1;;;2289:60;-1:-1:-1;;;;;27001:22:0;;;;;;;2228:18:1;;27001:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27055:25;;;;;;;;;;;;;-1:-1:-1;;;27055:25:0;;;26993:88;;;;;-1:-1:-1;;;26993:88:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;64128:32:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;55354:4:::1;64090:36:::0;::::1;;64082:79;;;;-1:-1:-1::0;;;64082:79:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;64172:17:0::1;:38:::0;;;64226:40:::1;::::0;1102:25:1;;;64226:40:0::1;::::0;1090:2:1;1075:18;64226:40:0::1;;;;;;;63980:294:::0;:::o;63315:464::-;63441:17;-1:-1:-1;;;;;63522:24:0;;63518:113;;63570:49;63575:10;63587:8;63597:21;63570:4;:49::i;:::-;63563:56;;;;63518:113;63721:49;;-1:-1:-1;;;63721:49:0;;63758:10;63721:49;;;180:51:1;63694:77:0;;63699:10;;63711:8;;-1:-1:-1;;;;;63721:28:0;;;;;153:18:1;;63721:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;63694:77::-;63687:84;;63315:464;;;;;:::o;65405:323::-;65550:17;65598:8;-1:-1:-1;;;;;65584:22:0;:10;-1:-1:-1;;;;;65584:22:0;;:40;;;-1:-1:-1;65610:14:0;;65584:40;65580:62;;;-1:-1:-1;65633:9:0;65626:16;;65580:62;65662:58;65675:8;65685:34;65697:10;65709:9;65685:11;:34::i;:::-;65662:12;:58::i;:::-;65655:65;;65405:323;;;;;;:::o;64581:369::-;28312:13;27001:52;;-1:-1:-1;;;27001:52:0;;-1:-1:-1;;;27001:52:0;;;2255:25:1;27042:10:0;2296:18:1;;;2289:60;-1:-1:-1;;;;;27001:22:0;;;;;;;2228:18:1;;27001:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27055:25;;;;;;;;;;;;;-1:-1:-1;;;27055:25:0;;;26993:88;;;;;-1:-1:-1;;;26993:88:0;;;;;;;;:::i;:::-;-1:-1:-1;64713:30:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;-1:-1:-1;;;;;64691:20:0;::::1;64683:61;;;;-1:-1:-1::0;;;64683:61:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;64785:18:0;;::::1;;::::0;;;:10:::1;:18;::::0;;;;;;;;;64806:30;;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;64763:41;;::::1;64785:18:::0;::::1;64763:41;;64755:82;;;;-1:-1:-1::0;;;64755:82:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;64848:18:0;;::::1;;::::0;;;:10:::1;:18;::::0;;;;;;;;:46;;-1:-1:-1;;;;;;64848:46:0::1;::::0;;::::1;::::0;;::::1;::::0;;64910:32;;3902:34:1;;;3952:18;;3945:43;;;;64910:32:0::1;::::0;3837:18:1;64910:32:0::1;;;;;;;64581:369:::0;;:::o;66035:1325::-;66173:17;-1:-1:-1;;;;;66263:24:0;;;:40;;66302:1;66263:40;;;66290:9;66263:40;66249:9;:55;66306:20;;;;;;;;;;;;;-1:-1:-1;;;66306:20:0;;;66241:86;;;;;-1:-1:-1;;;66241:86:0;;;;;;;;:::i;:::-;-1:-1:-1;66342:14:0;66338:110;;66378:35;;;66408:1;4189:25:1;;;4245:2;4230:18;;4223:34;-1:-1:-1;;;;;66378:35:0;;;;;;;;;;4162:18:1;66378:35:0;;;;;;;-1:-1:-1;66435:1:0;66428:8;;66338:110;66527:8;-1:-1:-1;;;;;66513:22:0;:10;-1:-1:-1;;;;;66513:22:0;;66509:412;;;-1:-1:-1;;;;;66556:24:0;;66552:256;;66688:46;;66670:12;;66696:10;;66720:9;;66670:12;66688:46;66670:12;66688:46;66720:9;66696:10;66688:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66669:65;;;66761:7;66770:21;;;;;;;;;;;;;-1:-1:-1;;;66770:21:0;;;66753:39;;;;;-1:-1:-1;;;66753:39:0;;;;;;;;:::i;:::-;;66582:226;66552:256;66847:8;-1:-1:-1;;;;;66827:51:0;66835:10;-1:-1:-1;;;;;66827:51:0;;66857:9;66868;66827:51;;;;;;4189:25:1;;;4245:2;4230:18;;4223:34;4177:2;4162:18;;3999:264;66827:51:0;;;;;;;;-1:-1:-1;66900:9:0;66893:16;;66509:412;-1:-1:-1;;;;;66983:24:0;;;66979:130;;67024:73;-1:-1:-1;;;;;67024:35:0;;67060:10;67080:4;67087:9;67024:35;:73::i;:::-;67157:18;67178:53;67196:8;67206:24;67219:10;67206:12;:24::i;:::-;67178:17;:53::i;:::-;67157:74;;67267:8;-1:-1:-1;;;;;67247:52:0;67255:10;-1:-1:-1;;;;;67247:52:0;;67277:9;67288:10;67247:52;;;;;;4189:25:1;;;4245:2;4230:18;;4223:34;4177:2;4162:18;;3999:264;67247:52:0;;;;;;;;67317:35;67331:8;67341:10;67317:13;:35::i;:::-;67310:42;66035:1325;-1:-1:-1;;;;;66035:1325:0:o;52523:186::-;52642:58;;-1:-1:-1;;;52642:58:0;;-1:-1:-1;;;52642:58:0;;;1102:25:1;52597:12:0;;-1:-1:-1;;;;;52642:19:0;;;;;1075:18:1;;52642:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72631:745::-;72735:17;-1:-1:-1;;;;;72774:24:0;;-1:-1:-1;;;;;;;;;;;72774:24:0;;:48;;-1:-1:-1;;;;;;72802:20:0;;;72774:48;72770:68;;;-1:-1:-1;72831:7:0;72824:14;;72770:68;-1:-1:-1;;;;;72916:18:0;;;72889:24;72916:18;;;:10;:18;;;;;;;72949:33;;72945:214;;73000:18;73020:19;73043:31;73055:10;73067:6;73043:11;:31::i;:::-;73096:51;;-1:-1:-1;;;73096:51:0;;;;;5371:25:1;;;5412:18;;;5405:34;;;5455:18;;;5448:34;;;72999:75:0;;-1:-1:-1;72999:75:0;-1:-1:-1;;;;;;73096:17:0;;;;;5344:18:1;;73096:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73089:58;;;;;;;72945:214;73191:177;73225:6;-1:-1:-1;;;;;;;;;;;73283:7:0;73309:44;73321:6;-1:-1:-1;;;;;;;;;;;73345:7:0;73309:11;:44::i;:::-;73191:15;:177::i;:::-;73171:197;72631:745;-1:-1:-1;;;;72631:745:0:o;73750:746::-;73855:17;-1:-1:-1;;;;;73894:24:0;;-1:-1:-1;;;;;;;;;;;73894:24:0;;:48;;-1:-1:-1;;;;;;73922:20:0;;;73894:48;73890:68;;;-1:-1:-1;73951:7:0;73944:14;;73890:68;-1:-1:-1;;;;;74036:18:0;;;74009:24;74036:18;;;:10;:18;;;;;;;74069:33;;74065:214;;74120:18;74140:19;74163:31;74175:10;74187:6;74163:11;:31::i;:::-;74216:51;;-1:-1:-1;;;74216:51:0;;;;;5371:25:1;;;5412:18;;;5405:34;;;5455:18;;;5448:34;;;74119:75:0;;-1:-1:-1;74119:75:0;-1:-1:-1;;;;;;74216:17:0;;;;;5344:18:1;;74216:51:0;5169:319:1;74065:214:0;74311:177;-1:-1:-1;;;;;;;;;;;74378:6:0;74403:7;74429:44;-1:-1:-1;;;;;;;;;;;74457:6:0;74465:7;74429:11;:44::i;12422:248::-;12593:68;;-1:-1:-1;;;;;5751:15:1;;;12593:68:0;;;5733:34:1;5803:15;;5783:18;;;5776:43;5835:18;;;5828:34;;;12566:96:0;;12586:5;;-1:-1:-1;;;12616:27:0;5668:18:1;;12593:68:0;;;;-1:-1:-1;;12593:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;12593:68:0;-1:-1:-1;;;;;;12593:68:0;;;;;;;;;;12566:19;:96::i;:::-;12422:248;;;;:::o;67567:1206::-;67623:17;-1:-1:-1;;;;;67657:24:0;;-1:-1:-1;;;;;;;;;;;67657:24:0;67653:67;;;67690:30;;-1:-1:-1;;;67690:30:0;;67714:4;67690:30;;;180:51:1;-1:-1:-1;;;;;;;;;;;61905:42:0;67690:15;;153:18:1;;67690:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;67653:67::-;-1:-1:-1;;;;;67770:20:0;;67766:224;;67829:21;67869:16;67865:30;;-1:-1:-1;67894:1:0;;67567:1206;-1:-1:-1;;67567:1206:0:o;67865:30::-;-1:-1:-1;;;;;;;;;;;;;;;;67910:13:0;;67931:11;67910:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67967:11:0;;67567:1206;-1:-1:-1;;;;;;67567:1206:0:o;67766:224::-;-1:-1:-1;;;;;68067:18:0;;;68040:24;68067:18;;;:10;:18;;;;;;;68100:33;;68096:545;;68168:39;;-1:-1:-1;;;68168:39:0;;68201:4;68168:39;;;180:51:1;68150:15:0;;-1:-1:-1;;;;;68168:24:0;;;;;153:18:1;;68168:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68150:57;-1:-1:-1;68226:12:0;68222:26;;-1:-1:-1;68247:1:0;;67567:1206;-1:-1:-1;;;67567:1206:0:o;68222:26::-;68263:37;68272:6;68288:10;68263:8;:37::i;:::-;68316:18;68336:19;68359:31;68371:10;68383:6;68359:11;:31::i;:::-;68315:75;;;;68405:10;-1:-1:-1;;;;;68405:19:0;;68443:11;68473:10;68502:7;68528:34;68546:7;68555:6;68528:17;:34::i;:::-;68405:172;;-1:-1:-1;;;;;;68405:172:0;;;;;;;;;;6104:25:1;;;;6145:18;;;6138:34;;;;6188:18;;;6181:34;6231:18;;;6224:34;6076:19;;68405:172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68599:30:0;;-1:-1:-1;;;68599:30:0;;68623:4;68599:30;;;180:51:1;-1:-1:-1;;;;;;;;;;;61905:42:0;-1:-1:-1;68599:15:0;;-1:-1:-1;153:18:1;;68599:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68592:37;67567:1206;-1:-1:-1;;;;;;67567:1206:0:o;68096:545::-;68725:39;;-1:-1:-1;;;68725:39:0;;68758:4;68725:39;;;180:51:1;68695:70:0;;68701:6;;-1:-1:-1;;;;;;;;;;;61905:42:0;-1:-1:-1;;;;;68725:24:0;;;;;153:18:1;;68725:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68695:5;:70::i;68981:1019::-;69077:17;69116:12;69112:26;;-1:-1:-1;69137:1:0;69130:8;;69112:26;-1:-1:-1;;;;;69153:24:0;;-1:-1:-1;;;;;;;;;;;69153:24:0;69149:44;;;-1:-1:-1;69186:7:0;69179:14;;69149:44;-1:-1:-1;;;;;69243:20:0;;69239:105;;69280:23;;-1:-1:-1;;;69280:23:0;;;;;1102:25:1;;;-1:-1:-1;;;;;;;;;;;61905:42:0;69280:14;;1075:18:1;;69280:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69325:7;69318:14;;;;69239:105;-1:-1:-1;;;;;69421:18:0;;;69394:24;69421:18;;;:10;:18;;;;;;;69454:33;;69450:450;;69504:45;-1:-1:-1;;;;;;;;;;;69537:10:0;69504:8;:45::i;:::-;69565:18;69585:19;69608:31;69620:10;69632:6;69608:11;:31::i;:::-;69564:75;;;;69654:10;-1:-1:-1;;;;;69654:19:0;;69692:10;69721:11;69751:7;69777:35;69796:7;69805:6;69777:18;:35::i;:::-;69654:173;;-1:-1:-1;;;;;;69654:173:0;;;;;;;;;;6104:25:1;;;;6145:18;;;6138:34;;;;6188:18;;;6181:34;6231:18;;;6224:34;6076:19;;69654:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69849:39:0;;-1:-1:-1;;;69849:39:0;;69882:4;69849:39;;;180:51:1;-1:-1:-1;;;;;69849:24:0;;;-1:-1:-1;69849:24:0;;-1:-1:-1;153:18:1;;69849:39:0;14:223:1;69450:450:0;69954:38;-1:-1:-1;;;;;;;;;;;69976:6:0;69984:7;69954:5;:38::i;71707:548::-;71799:22;-1:-1:-1;;;;;71872:20:0;;71868:263;;71992:44;;71974:12;;72000:10;;72024:7;;71974:12;71992:44;71974:12;71992:44;72024:7;72000:10;71992:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71973:63;;;72059:7;72068:21;;;;;;;;;;;;;-1:-1:-1;;;72068:21:0;;;72051:39;;;;;-1:-1:-1;;;72051:39:0;;;;;;;;:::i;:::-;;72112:7;72105:14;;;;;71868:263;72174:48;-1:-1:-1;;;;;72174:27:0;;72202:10;72214:7;72174:27;:48::i;:::-;-1:-1:-1;72240:7:0;71707:548;-1:-1:-1;71707:548:0:o;79314:232::-;79427:18;79447:19;79514:6;-1:-1:-1;;;;;79491:29:0;:10;-1:-1:-1;;;;;79491:16:0;;79508:1;79491:19;;;;;;;;;;;;;1102:25:1;;1090:2;1075:18;;956:177;79491:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;79491:29:0;;:47;;79533:1;79536;79491:47;;;79524:1;79527;79491:47;79484:54;;;;;;;;-1:-1:-1;79314:232:0;-1:-1:-1;;;79314:232:0:o;74885:462::-;75018:15;61608:42;61759;75223:58;75239:10;75251:8;75261:7;61759:42;75223:15;:58::i;:::-;75146:56;75162:10;75174:8;75184:7;75193:8;75146:15;:56::i;:::-;:135;;:193;;75329:10;75146:193;;;-1:-1:-1;75301:8:0;75126:213;-1:-1:-1;;;;74885:462:0:o;75761:377::-;75978:16;;;75992:1;75978:16;;;;;;;;75923:17;;;;75978:16;75992:1;75978:16;;;;;;;;;;-1:-1:-1;75978:16:0;75953:41;;76016:10;76005:5;76011:1;76005:8;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;76005:21:0;;;-1:-1:-1;;;;;76005:21:0;;;;;76048:8;76037:5;76043:1;76037:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;76037:19:0;;;:8;;;;;;;;;:19;76074:53;;-1:-1:-1;;;76074:53:0;;:35;;;;;;:53;;76110:9;;76121:5;;76074:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;76074:53:0;;;;;;;;;;;;:::i;:::-;76128:1;76074:56;;;;;;;;:::i;:::-;;;;;;;76067:63;;;75761:377;;;;;;:::o;14776:716::-;15200:23;15226:69;15254:4;15226:69;;;;;;;;;;;;;;;;;15234:5;-1:-1:-1;;;;;15226:27:0;;;:69;;;;;:::i;:::-;15310:17;;15200:95;;-1:-1:-1;15310:21:0;15306:179;;15407:10;15396:30;;;;;;;;;;;;:::i;:::-;15388:85;;;;-1:-1:-1;;;15388:85:0;;8838:2:1;15388:85:0;;;8820:21:1;8877:2;8857:18;;;8850:30;8916:34;8896:18;;;8889:62;-1:-1:-1;;;8967:18:1;;;8960:40;9017:19;;15388:85:0;8636:406:1;15388:85:0;14846:646;14776:716;;:::o;71224:211::-;71300:49;;-1:-1:-1;;;71300:49:0;;71333:4;71300:49;;;3902:34:1;-1:-1:-1;;;;;3972:15:1;;;3952:18;;;3945:43;71352:1:0;;71300:24;;;;;;3837:18:1;;71300:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;71296:66;;;71224:211;;:::o;71296:66::-;71372:55;-1:-1:-1;;;;;71372:26:0;;71399:8;-1:-1:-1;;71372:26:0;:55::i;:::-;71224:211;;:::o;77844:414::-;77959:20;77997:19;78019:22;78034:6;78019:14;:22::i;:::-;77997:44;-1:-1:-1;78056:16:0;78052:30;;78081:1;78074:8;;;;;78052:30;78113:137;78217:6;-1:-1:-1;;;;;78206:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78159:17;;78113:64;;:35;:12;78136:11;78113:22;:35::i;:::-;:45;;:64::i;:::-;:74;;:137::i;70304:735::-;70426:17;70460:12;70456:26;;-1:-1:-1;70481:1:0;70474:8;;70456:26;70511:8;-1:-1:-1;;;;;70497:22:0;:10;-1:-1:-1;;;;;70497:22:0;;70493:42;;;-1:-1:-1;70528:7:0;70521:14;;70493:42;70546:12;70561:42;70573:10;70585:8;70595:7;70561:11;:42::i;:::-;70546:57;;70614:26;70623:10;70635:4;70614:8;:26::i;:::-;70676:16;;;70690:1;70676:16;;;;;;;;70651:22;;70676:16;;;;;;;;;;-1:-1:-1;70676:16:0;70651:41;;70714:10;70703:5;70709:1;70703:8;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;70703:21:0;;;-1:-1:-1;;;;;70703:21:0;;;;;70746:8;70735:5;70741:1;70735:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;70735:19:0;;;:8;;;;;;;;;:19;70785:46;;;70850:7;70876:47;70850:7;70902:10;70914:8;70876:16;:47::i;:::-;70942:5;70974:4;70998:15;70785:243;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70785:243:0;;;;;;;;;;;;:::i;:::-;71029:1;70785:246;;;;;;;;:::i;:::-;;;;;;;70765:266;;;;70304:735;;;;;:::o;77132:411::-;77247:20;77285:19;77307:22;77322:6;77307:14;:22::i;:::-;77285:44;-1:-1:-1;77344:16:0;77340:30;;77369:1;77362:8;;;;;77340:30;77401:134;77502:6;-1:-1:-1;;;;;77491:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77446:17;;77401:63;;:34;:11;77423;77401:21;:34::i;:63::-;:71;;:134::i;12203:211::-;12347:58;;-1:-1:-1;;;;;10096:32:1;;12347:58:0;;;10078:51:1;10145:18;;;10138:34;;;12320:86:0;;12340:5;;-1:-1:-1;;;12370:23:0;10051:18:1;;12347:58:0;9904:274:1;6977:229:0;7114:12;7146:52;7168:6;7176:4;7182:1;7185:12;7146:21;:52::i;12939:616::-;13303:10;;;13302:62;;-1:-1:-1;13319:39:0;;-1:-1:-1;;;13319:39:0;;13343:4;13319:39;;;3902:34:1;-1:-1:-1;;;;;3972:15:1;;;3952:18;;;3945:43;13319:15:0;;;;;3837:18:1;;13319:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;13302:62;13280:166;;;;-1:-1:-1;;;13280:166:0;;10385:2:1;13280:166:0;;;10367:21:1;10424:2;10404:18;;;10397:30;10463:34;10443:18;;;10436:62;-1:-1:-1;;;10514:18:1;;;10507:52;10576:19;;13280:166:0;10183:418:1;13280:166:0;13484:62;;-1:-1:-1;;;;;10096:32:1;;13484:62:0;;;10078:51:1;10145:18;;;10138:34;;;13457:90:0;;13477:5;;-1:-1:-1;;;13507:22:0;10051:18:1;;13484:62:0;9904:274:1;78666:320:0;78729:23;78765:30;78798:36;:16;-1:-1:-1;;;;;78798:34:0;;:36::i;:::-;78849:39;;-1:-1:-1;;;78849:39:0;;-1:-1:-1;;;;;198:32:1;;;78849:39:0;;;180:51:1;78765:69:0;;-1:-1:-1;78849:31:0;;;;;;153:18:1;;78849:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78845:113;;;78912:34;;-1:-1:-1;;;78912:34:0;;-1:-1:-1;;;;;198:32:1;;;78912:34:0;;;180:51:1;78912:26:0;;;;;153:18:1;;78912:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;78845:113::-;-1:-1:-1;78977:1:0;;78666:320;-1:-1:-1;;78666:320:0:o;55454:122::-;55518:7;55245:4;55546:5;55550:1;55546;:5;:::i;:::-;55545:23;;;;:::i;54069:340::-;54142:7;54166:21;;;54037:2;54166:21;54162:240;;;-1:-1:-1;54211:5:0;54204:12;;54162:240;54037:2;54238:20;;;;54234:168;;;54295:20;54037:2;54295:8;:20;:::i;:::-;54290:26;;:2;:26;:::i;:::-;54282:34;;:5;:34;:::i;54234:168::-;54369:20;54381:8;54037:2;54369:20;:::i;:::-;54364:26;;:2;:26;:::i;:::-;54356:34;;:5;:34;:::i;76491:342::-;76629:20;-1:-1:-1;;;;;76682:28:0;;-1:-1:-1;;;;;;;;;;;76682:28:0;:143;;76787:38;76805:7;76814:10;76787:17;:38::i;:::-;76682:143;;;76730:37;76749:7;76758:8;76730:18;:37::i;55665:122::-;55729:7;55778:1;55757:17;55245:4;55757:1;:17;:::i;54417:338::-;54488:7;54512:21;;;54037:2;54512:21;54508:240;;;-1:-1:-1;54557:5:0;54550:12;;54508:240;54037:2;54584:20;;;;54580:168;;;54641:20;54037:2;54641:8;:20;:::i;54580:168::-;54715:20;54727:8;54037:2;54715:20;:::i;8097:510::-;8267:12;8325:5;8300:21;:30;;8292:81;;;;-1:-1:-1;;;8292:81:0;;12918:2:1;8292:81:0;;;12900:21:1;12957:2;12937:18;;;12930:30;12996:34;12976:18;;;12969:62;-1:-1:-1;;;13047:18:1;;;13040:36;13093:19;;8292:81:0;12716:402:1;8292:81:0;-1:-1:-1;;;;;4527:19:0;;;8384:60;;;;-1:-1:-1;;;8384:60:0;;13325:2:1;8384:60:0;;;13307:21:1;13364:2;13344:18;;;13337:30;13403:31;13383:18;;;13376:59;13452:18;;8384:60:0;13123:353:1;8384:60:0;8458:12;8472:23;8499:6;-1:-1:-1;;;;;8499:11:0;8518:5;8525:4;8499:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8457:73;;;;8548:51;8565:7;8574:10;8586:12;8548:16;:51::i;:::-;8541:58;8097:510;-1:-1:-1;;;;;;;8097:510:0:o;52014:198::-;52142:61;;-1:-1:-1;;;52142:61:0;;-1:-1:-1;;;52142:61:0;;;1102:25:1;52091:15:0;;-1:-1:-1;;;;;52142:19:0;;;;;1075:18:1;;52142:61:0;956:177:1;10783:712:0;10933:12;10962:7;10958:530;;;-1:-1:-1;10993:10:0;10986:17;;10958:530;11107:17;;:21;11103:374;;11305:10;11299:17;11366:15;11353:10;11349:2;11345:19;11338:44;11103:374;11448:12;11441:20;;-1:-1:-1;;;11441:20:0;;;;;;;;:::i;242:180:1:-;301:6;354:2;342:9;333:7;329:23;325:32;322:52;;;370:1;367;360:12;322:52;-1:-1:-1;393:23:1;;242:180;-1:-1:-1;242:180:1:o;427:131::-;-1:-1:-1;;;;;502:31:1;;492:42;;482:70;;548:1;545;538:12;482:70;427:131;:::o;563:388::-;631:6;639;692:2;680:9;671:7;667:23;663:32;660:52;;;708:1;705;698:12;660:52;747:9;734:23;766:31;791:5;766:31;:::i;:::-;816:5;-1:-1:-1;873:2:1;858:18;;845:32;886:33;845:32;886:33;:::i;:::-;938:7;928:17;;;563:388;;;;;:::o;1138:456::-;1215:6;1223;1231;1284:2;1272:9;1263:7;1259:23;1255:32;1252:52;;;1300:1;1297;1290:12;1252:52;1339:9;1326:23;1358:31;1383:5;1358:31;:::i;:::-;1408:5;-1:-1:-1;1465:2:1;1450:18;;1437:32;1478:33;1437:32;1478:33;:::i;:::-;1138:456;;1530:7;;-1:-1:-1;;;1584:2:1;1569:18;;;;1556:32;;1138:456::o;1599:247::-;1658:6;1711:2;1699:9;1690:7;1686:23;1682:32;1679:52;;;1727:1;1724;1717:12;1679:52;1766:9;1753:23;1785:31;1810:5;1785:31;:::i;2360:277::-;2427:6;2480:2;2468:9;2459:7;2455:23;2451:32;2448:52;;;2496:1;2493;2486:12;2448:52;2528:9;2522:16;2581:5;2574:13;2567:21;2560:5;2557:32;2547:60;;2603:1;2600;2593:12;2642:258;2714:1;2724:113;2738:6;2735:1;2732:13;2724:113;;;2814:11;;;2808:18;2795:11;;;2788:39;2760:2;2753:10;2724:113;;;2855:6;2852:1;2849:13;2846:48;;;-1:-1:-1;;2890:1:1;2872:16;;2865:27;2642:258::o;2905:383::-;3054:2;3043:9;3036:21;3017:4;3086:6;3080:13;3129:6;3124:2;3113:9;3109:18;3102:34;3145:66;3204:6;3199:2;3188:9;3184:18;3179:2;3171:6;3167:15;3145:66;:::i;:::-;3272:2;3251:15;-1:-1:-1;;3247:29:1;3232:45;;;;3279:2;3228:54;;2905:383;-1:-1:-1;;2905:383:1:o;3501:184::-;3571:6;3624:2;3612:9;3603:7;3599:23;3595:32;3592:52;;;3640:1;3637;3630:12;3592:52;-1:-1:-1;3663:16:1;;3501:184;-1:-1:-1;3501:184:1:o;4913:251::-;4983:6;5036:2;5024:9;5015:7;5011:23;5007:32;5004:52;;;5052:1;5049;5042:12;5004:52;5084:9;5078:16;5103:31;5128:5;5103:31;:::i;6459:127::-;6520:10;6515:3;6511:20;6508:1;6501:31;6551:4;6548:1;6541:15;6575:4;6572:1;6565:15;6591:127;6652:10;6647:3;6643:20;6640:1;6633:31;6683:4;6680:1;6673:15;6707:4;6704:1;6697:15;6723:461;6776:3;6814:5;6808:12;6841:6;6836:3;6829:19;6867:4;6896:2;6891:3;6887:12;6880:19;;6933:2;6926:5;6922:14;6954:1;6964:195;6978:6;6975:1;6972:13;6964:195;;;7043:13;;-1:-1:-1;;;;;7039:39:1;7027:52;;7099:12;;;;7134:15;;;;7075:1;6993:9;6964:195;;;-1:-1:-1;7175:3:1;;6723:461;-1:-1:-1;;;;;6723:461:1:o;7189:332::-;7396:6;7385:9;7378:25;7439:2;7434;7423:9;7419:18;7412:30;7359:4;7459:56;7511:2;7500:9;7496:18;7488:6;7459:56;:::i;7526:1105::-;7621:6;7652:2;7695;7683:9;7674:7;7670:23;7666:32;7663:52;;;7711:1;7708;7701:12;7663:52;7744:9;7738:16;7773:18;7814:2;7806:6;7803:14;7800:34;;;7830:1;7827;7820:12;7800:34;7868:6;7857:9;7853:22;7843:32;;7913:7;7906:4;7902:2;7898:13;7894:27;7884:55;;7935:1;7932;7925:12;7884:55;7964:2;7958:9;7986:2;7982;7979:10;7976:36;;;7992:18;;:::i;:::-;8038:2;8035:1;8031:10;8070:2;8064:9;8133:2;8129:7;8124:2;8120;8116:11;8112:25;8104:6;8100:38;8188:6;8176:10;8173:22;8168:2;8156:10;8153:18;8150:46;8147:72;;;8199:18;;:::i;:::-;8235:2;8228:22;8285:18;;;8319:15;;;;-1:-1:-1;8361:11:1;;;8357:20;;;8389:19;;;8386:39;;;8421:1;8418;8411:12;8386:39;8445:11;;;;8465:135;8481:6;8476:3;8473:15;8465:135;;;8547:10;;8535:23;;8498:12;;;;8578;;;;8465:135;;;8619:6;7526:1105;-1:-1:-1;;;;;;;;7526:1105:1:o;9047:273::-;9115:6;9168:2;9156:9;9147:7;9143:23;9139:32;9136:52;;;9184:1;9181;9174:12;9136:52;9216:9;9210:16;9266:4;9259:5;9255:16;9248:5;9245:27;9235:55;;9286:1;9283;9276:12;9325:574;9616:6;9605:9;9598:25;9659:6;9654:2;9643:9;9639:18;9632:34;9702:3;9697:2;9686:9;9682:18;9675:31;9579:4;9723:57;9775:3;9764:9;9760:19;9752:6;9723:57;:::i;:::-;-1:-1:-1;;;;;9816:32:1;;;;9811:2;9796:18;;9789:60;-1:-1:-1;9880:3:1;9865:19;9858:35;9715:65;9325:574;-1:-1:-1;;;9325:574:1:o;10606:127::-;10667:10;10662:3;10658:20;10655:1;10648:31;10698:4;10695:1;10688:15;10722:4;10719:1;10712:15;10738:168;10778:7;10844:1;10840;10836:6;10832:14;10829:1;10826:21;10821:1;10814:9;10807:17;10803:45;10800:71;;;10851:18;;:::i;:::-;-1:-1:-1;10891:9:1;;10738:168::o;10911:217::-;10951:1;10977;10967:132;;11021:10;11016:3;11012:20;11009:1;11002:31;11056:4;11053:1;11046:15;11084:4;11081:1;11074:15;10967:132;-1:-1:-1;11113:9:1;;10911:217::o;11133:195::-;11171:4;11208;11205:1;11201:12;11240:4;11237:1;11233:12;11265:3;11260;11257:12;11254:38;;;11272:18;;:::i;:::-;11309:13;;;11133:195;-1:-1:-1;;;11133:195:1:o;11333:422::-;11422:1;11465:5;11422:1;11479:270;11500:7;11490:8;11487:21;11479:270;;;11559:4;11555:1;11551:6;11547:17;11541:4;11538:27;11535:53;;;11568:18;;:::i;:::-;11618:7;11608:8;11604:22;11601:55;;;11638:16;;;;11601:55;11717:22;;;;11677:15;;;;11479:270;;;11483:3;11333:422;;;;;:::o;11760:806::-;11809:5;11839:8;11829:80;;-1:-1:-1;11880:1:1;11894:5;;11829:80;11928:4;11918:76;;-1:-1:-1;11965:1:1;11979:5;;11918:76;12010:4;12028:1;12023:59;;;;12096:1;12091:130;;;;12003:218;;12023:59;12053:1;12044:10;;12067:5;;;12091:130;12128:3;12118:8;12115:17;12112:43;;;12135:18;;:::i;:::-;-1:-1:-1;;12191:1:1;12177:16;;12206:5;;12003:218;;12305:2;12295:8;12292:16;12286:3;12280:4;12277:13;12273:36;12267:2;12257:8;12254:16;12249:2;12243:4;12240:12;12236:35;12233:77;12230:159;;;-1:-1:-1;12342:19:1;;;12374:5;;12230:159;12421:34;12446:8;12440:4;12421:34;:::i;:::-;12491:6;12487:1;12483:6;12479:19;12470:7;12467:32;12464:58;;;12502:18;;:::i;:::-;12540:20;;11760:806;-1:-1:-1;;;11760:806:1:o;12571:140::-;12629:5;12658:47;12699:4;12689:8;12685:19;12679:4;12658:47;:::i;13481:274::-;13610:3;13648:6;13642:13;13664:53;13710:6;13705:3;13698:4;13690:6;13686:17;13664:53;:::i;:::-;13733:16;;;;;13481:274;-1:-1:-1;;13481:274:1:o
Swarm Source
ipfs://ea55d794c7e8966c0055b4eb6dc983848c98aa09208190462fa13b6c86f223fc
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.