Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
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-07-27 */ // SPDX-License-Identifier: GPL-3.0-or-later // Sources flattened with hardhat v2.6.1 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // 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/[email protected] // 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/[email protected] // 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 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 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 = "the pool is 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 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 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_MANAGER = "inflation_manager"; bytes32 internal constant POOL = "pool"; bytes32 internal constant VAULT = "vault"; } // 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/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 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 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 addAction(address action) external returns (bool); function isAction(address action) external view returns (bool); /** Address functions */ 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; /** 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/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() external; function mintRewards(address beneficiary, uint256 amount) 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); /** 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 inflationManager() external view returns (IInflationManager); function addStakerVault(address stakerVault) external; function shutdownPool(ILiquidityPool pool, bool shutdownStrategy) external returns (bool); /** Keeper functions */ function updateKeeperRequiredStakedMERO(uint256 amount) external; function canKeeperExecuteAction(address keeper) external view returns (bool); /** 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 _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 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
60c06040523480156200001157600080fd5b5060405162002318380380620023188339810160408190526200003491620000f9565b62000053816001600160a01b03166200007760201b620008c51760201c565b6001600160a01b039081166080521660a052670d7621dc582100006000556200012b565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a72190602401602060405180830381865afa158015620000cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f39190620000f9565b92915050565b6000602082840312156200010c57600080fd5b81516001600160a01b03811681146200012457600080fd5b9392505050565b60805160a0516121ba6200015e60003960006118f40152600081816099015281816101ba015261042901526121ba6000f3fe60806040526004361061007e5760003560e01c806358fd9be01161004e57806358fd9be014610139578063a788871814610159578063d03153aa1461018f578063df791e50146101a557600080fd5b8062435da51461008a578063117da1ee146100d65780633ff37e8f146100f85780634aa066521461011957600080fd5b3661008557005b600080fd5b34801561009657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e257600080fd5b506100f66100f1366004611cb6565b6101b8565b005b61010b610106366004611ce7565b610343565b6040519081526020016100cd565b34801561012557600080fd5b5061010b610134366004611d20565b6103de565b34801561014557600080fd5b506100f6610154366004611ce7565b610427565b34801561016557600080fd5b506100b9610174366004611d61565b6001602052600090815260409020546001600160a01b031681565b34801561019b57600080fd5b5061010b60005481565b61010b6101b3366004611d20565b610650565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102569190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b815250906102a95760405162461bcd60e51b81526004016102a09190611dcc565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a76400008211156103075760405162461bcd60e51b81526004016102a09190611dcc565b5060008190556040518181527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a799060200160405180910390a150565b60006001600160a01b0383166103655761035e838347610650565b90506103d8565b6040516370a0823160e01b81523360048201526103d590849084906001600160a01b038316906370a0823190602401602060405180830381865afa1580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b39190611dff565b90505b92915050565b6000826001600160a01b0316846001600160a01b031614806103fe575081155b1561040a575080610420565b61041d83610418868561093f565b610a68565b90505b9392505050565b7f0000000000000000000000000000000000000000000000000000000000000000604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c59190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b8152509061050f5760405162461bcd60e51b81526004016102a09190611dcc565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b03831661056b5760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b03808316600090815260016020908152604091829020548251808401909352601883527f73616d652061646472657373206e6f7420616c6c6f7765640000000000000000918301919091529091838116911614156105e45760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc99581e03a01bc0e74719af7085e6d62b1a853b511cb673db6c840eb4ec648ca910160405180910390a15050565b60006001600160a01b0384161561066857600061066a565b815b34146040518060400160405280600e81526020016d1a5b9d985b1a5908185b5bdd5b9d60921b815250906106b15760405162461bcd60e51b81526004016102a09190611dcc565b50816107085760408051600080825260208201526001600160a01b0380861692908716917fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb910160405180910390a3506000610420565b826001600160a01b0316846001600160a01b03161415610822576001600160a01b0384166107c557604051600090339084908381818185875af1925050503d8060008114610772576040519150601f19603f3d011682016040523d82523d6000602084013e610777565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b815250906107c25760405162461bcd60e51b81526004016102a09190611dcc565b50505b826001600160a01b0316846001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb8485604051610813929190918252602082015260400190565b60405180910390a35080610420565b6001600160a01b03841615610846576108466001600160a01b038516333085610b3d565b600061085a8461085587610bae565b610ef3565b9050836001600160a01b0316856001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb85846040516108aa929190918252602082015260400190565b60405180910390a36108bc84826110ab565b95945050505050565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611e18565b60006001600160a01b038316600080516020612165833981519152148061096d57506001600160a01b038316155b156109795750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610a2e576000806109a78387611171565b60405163556d6e9f60e01b815260048101829052602481018390526044810188905291935091506001600160a01b0384169063556d6e9f906064015b602060405180830381865afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190611dff565b93505050506103d8565b610a608460008051602061216583398151915285610a5b886000805160206121658339815191528961121a565b611273565b949350505050565b60006001600160a01b0383166000805160206121658339815191521480610a9657506001600160a01b038316155b15610aa25750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610b1057600080610ad08387611171565b60405163556d6e9f60e01b815260048101839052602481018290526044810188905291935091506001600160a01b0384169063556d6e9f906064016109e3565b610a606000805160206121658339815191528585610a5b600080516020612165833981519152898961121a565b6040516001600160a01b0380851660248301528316604482015260648101829052610ba89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611387565b50505050565b60006001600160a01b0382166000805160206121658339815191521415610c3c576040516370a0823160e01b8152306004820152600080516020612165833981519152906370a0823190602401602060405180830381865afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611dff565b6001600160a01b038216610cc2574780610c595750600092915050565b6000805160206121658339815191526001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b50939695505050505050565b6001600160a01b03808316600090815260016020526040902054168015610e70576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4e9190611dff565b905080610d5f575060009392505050565b610d69848361145e565b600080610d768487611171565b91509150836001600160a01b0316635b41b908828486610d96888c6114f6565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260008051602061216583398151915292506370a082319150602401602060405180830381865afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e669190611dff565b9695505050505050565b6040516370a0823160e01b8152306004820152610420908490600080516020612165833981519152906001600160a01b038316906370a0823190602401602060405180830381865afa158015610eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee9190611dff565b611595565b600081610f02575060006103d8565b6001600160a01b0383166000805160206121658339815191521415610f285750806103d8565b6001600160a01b038316610f9d57604051632e1a7d4d60e01b81526004810183905260008051602061216583398151915290632e1a7d4d90602401600060405180830381600087803b158015610f7d57600080fd5b505af1158015610f91573d6000803e3d6000fd5b505050508190506103d8565b6001600160a01b0380841660009081526001602052604090205416801561109257610fd66000805160206121658339815191528261145e565b600080610fe38387611171565b91509150826001600160a01b0316635b41b9088383886110038a8c6116ff565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561104e57600080fd5b505af1158015611062573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201526001600160a01b03891692506370a0823191506024016109e3565b610a606000805160206121658339815191528585611595565b60006001600160a01b03831661115757604051600090339084908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061114d5760405162461bcd60e51b81526004016102a09190611dcc565b50829150506103d8565b61116b6001600160a01b0384163384611798565b50919050565b600080826001600160a01b0316846001600160a01b031663c661065760016040518263ffffffff1660e01b81526004016111ad91815260200190565b602060405180830381865afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190611e18565b6001600160a01b031614611205576001600061120a565b600060015b60ff918216969116945092505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f61125286868684611273565b61125e87878786611273565b101561126a5780610e66565b50949350505050565b6040805160028082526060820183526000928392919060208301908036833701905050905085816000815181106112ac576112ac611e4b565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106112e0576112e0611e4b565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81529084169063d06ca61f9061131d9087908590600401611ea5565b600060405180830381865afa15801561133a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113629190810190611ebe565b60018151811061137457611374611e4b565b6020026020010151915050949350505050565b60006113dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117c89092919063ffffffff16565b80519091501561145957808060200190518101906113fa9190611d7e565b6114595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a0565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301526000919084169063dd62ed3e90604401602060405180830381865afa1580156114ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d29190611dff565b11156114dc575050565b6114f26001600160a01b038316826000196117d7565b5050565b600080611502836118ec565b9050806115135760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115789190611f7c565b60005461158f906115898886611a07565b90611a07565b90611a26565b6000816115a457506000610420565b826001600160a01b0316846001600160a01b031614156115c5575080610420565b60006115d285858561121a565b90506115de858261145e565b604080516002808252606082018352600092602083019080368337019050509050858160008151811061161357611613611e4b565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018151811061164757611647611e4b565b6001600160a01b03928316602091820292909201015282166338ed173985611670818a8a611a87565b8430426040518663ffffffff1660e01b8152600401611693959493929190611f9f565b6000604051808303816000875af11580156116b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116da9190810190611ebe565b6001815181106116ec576116ec611e4b565b6020026020010151925050509392505050565b60008061170b836118ec565b90508061171c5760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190611f7c565b600054611792906115898886611ac0565b90611ad5565b6040516001600160a01b03831660248201526044810182905261145990849063a9059cbb60e01b90606401610b71565b606061041d8484600085611b0c565b8015806118515750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190611dff565b155b6118bc5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016102a0565b6040516001600160a01b03831660248201526044810182905261145990849063095ea7b360e01b90606401610b71565b6000806119217f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611c3d565b6040516308c9682b60e31b81526001600160a01b0385811660048301529192509082169063464b415890602401602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190611d7e565b156119fe5760405163e5ec9db960e01b81526001600160a01b03848116600483015282169063e5ec9db990602401602060405180830381865afa1580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104209190611dff565b50600092915050565b6000670de0b6b3a7640000611a1c8385611ff1565b6103d59190612010565b600060ff821660121415611a3b5750816103d8565b601260ff83161115611a6757611a52601283612032565b611a5d90600a612139565b61035e9084612010565b611a72826012612032565b611a7d90600a612139565b61035e9084611ff1565b60006001600160a01b03831660008051602061216583398151915214611ab657611ab184846114f6565b61041d565b61041d84836116ff565b600081611a1c670de0b6b3a764000085611ff1565b600060ff821660121415611aea5750816103d8565b601260ff83161115611b0157611a72601283612032565b611a52826012612032565b606082471015611b6d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016102a0565b6001600160a01b0385163b611bc45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a0565b600080866001600160a01b03168587604051611be09190612148565b60006040518083038185875af1925050503d8060008114611c1d576040519150601f19603f3d011682016040523d82523d6000602084013e611c22565b606091505b5091509150611c32828286611c7d565b979650505050505050565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a721906024016108fe565b60608315611c8c575081610420565b825115611c9c5782518084602001fd5b8160405162461bcd60e51b81526004016102a09190611dcc565b600060208284031215611cc857600080fd5b5035919050565b6001600160a01b0381168114611ce457600080fd5b50565b60008060408385031215611cfa57600080fd5b8235611d0581611ccf565b91506020830135611d1581611ccf565b809150509250929050565b600080600060608486031215611d3557600080fd5b8335611d4081611ccf565b92506020840135611d5081611ccf565b929592945050506040919091013590565b600060208284031215611d7357600080fd5b813561042081611ccf565b600060208284031215611d9057600080fd5b8151801515811461042057600080fd5b60005b83811015611dbb578181015183820152602001611da3565b83811115610ba85750506000910152565b6020815260008251806020840152611deb816040850160208701611da0565b601f01601f19169190910160400192915050565b600060208284031215611e1157600080fd5b5051919050565b600060208284031215611e2a57600080fd5b815161042081611ccf565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015611e9a5781516001600160a01b031687529582019590820190600101611e75565b509495945050505050565b82815260406020820152600061041d6040830184611e61565b60006020808385031215611ed157600080fd5b825167ffffffffffffffff80821115611ee957600080fd5b818501915085601f830112611efd57600080fd5b815181811115611f0f57611f0f611e35565b8060051b604051601f19603f83011681018181108582111715611f3457611f34611e35565b604052918252848201925083810185019188831115611f5257600080fd5b938501935b82851015611f7057845184529385019392850192611f57565b98975050505050505050565b600060208284031215611f8e57600080fd5b815160ff8116811461042057600080fd5b85815284602082015260a060408201526000611fbe60a0830186611e61565b6001600160a01b0394909416606083015250608001529392505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561200b5761200b611fdb565b500290565b60008261202d57634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168082101561204c5761204c611fdb565b90039392505050565b600181815b8085111561209057816000190482111561207657612076611fdb565b8085161561208357918102915b93841c939080029061205a565b509250929050565b6000826120a7575060016103d8565b816120b4575060006103d8565b81600181146120ca57600281146120d4576120f0565b60019150506103d8565b60ff8411156120e5576120e5611fdb565b50506001821b6103d8565b5060208310610133831016604e8410600b8410161715612113575081810a6103d8565b61211d8383612055565b806000190482111561213157612131611fdb565b029392505050565b60006103d560ff841683612098565b6000825161215a818460208701611da0565b919091019291505056fe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a2646970667358221220fbeb5a96ecfeca936ae80a6aa1394adfa61cde8ef4986d6fac920d1dd142740d64736f6c634300080a0033000000000000000000000000ac61fd84c5b20828c666ab1fdca0329aeaa8c8ee
Deployed Bytecode
0x60806040526004361061007e5760003560e01c806358fd9be01161004e57806358fd9be014610139578063a788871814610159578063d03153aa1461018f578063df791e50146101a557600080fd5b8062435da51461008a578063117da1ee146100d65780633ff37e8f146100f85780634aa066521461011957600080fd5b3661008557005b600080fd5b34801561009657600080fd5b507f000000000000000000000000f42420f505205b0771e631b5ef40cf3a563f21085b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e257600080fd5b506100f66100f1366004611cb6565b6101b8565b005b61010b610106366004611ce7565b610343565b6040519081526020016100cd565b34801561012557600080fd5b5061010b610134366004611d20565b6103de565b34801561014557600080fd5b506100f6610154366004611ce7565b610427565b34801561016557600080fd5b506100b9610174366004611d61565b6001602052600090815260409020546001600160a01b031681565b34801561019b57600080fd5b5061010b60005481565b61010b6101b3366004611d20565b610650565b7f000000000000000000000000f42420f505205b0771e631b5ef40cf3a563f2108604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015610232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102569190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b815250906102a95760405162461bcd60e51b81526004016102a09190611dcc565b60405180910390fd5b5060408051808201909152601a81527f496e76616c696420736c69707061676520746f6c6572616e63650000000000006020820152670de0b6b3a76400008211156103075760405162461bcd60e51b81526004016102a09190611dcc565b5060008190556040518181527fe4a7fd2711237e77309a9a16ff636a748dbf956fd91f6e6da800d9302f441a799060200160405180910390a150565b60006001600160a01b0383166103655761035e838347610650565b90506103d8565b6040516370a0823160e01b81523360048201526103d590849084906001600160a01b038316906370a0823190602401602060405180830381865afa1580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b39190611dff565b90505b92915050565b6000826001600160a01b0316846001600160a01b031614806103fe575081155b1561040a575080610420565b61041d83610418868561093f565b610a68565b90505b9392505050565b7f000000000000000000000000f42420f505205b0771e631b5ef40cf3a563f2108604051632474521560e21b815269676f7665726e616e636560b01b60048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa1580156104a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c59190611d7e565b60405180604001604052806013815260200172756e617574686f72697a65642061636365737360681b8152509061050f5760405162461bcd60e51b81526004016102a09190611dcc565b5060408051808201909152601881527f7a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060208201526001600160a01b03831661056b5760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b03808316600090815260016020908152604091829020548251808401909352601883527f73616d652061646472657373206e6f7420616c6c6f7765640000000000000000918301919091529091838116911614156105e45760405162461bcd60e51b81526004016102a09190611dcc565b506001600160a01b0382811660008181526001602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc99581e03a01bc0e74719af7085e6d62b1a853b511cb673db6c840eb4ec648ca910160405180910390a15050565b60006001600160a01b0384161561066857600061066a565b815b34146040518060400160405280600e81526020016d1a5b9d985b1a5908185b5bdd5b9d60921b815250906106b15760405162461bcd60e51b81526004016102a09190611dcc565b50816107085760408051600080825260208201526001600160a01b0380861692908716917fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb910160405180910390a3506000610420565b826001600160a01b0316846001600160a01b03161415610822576001600160a01b0384166107c557604051600090339084908381818185875af1925050503d8060008114610772576040519150601f19603f3d011682016040523d82523d6000602084013e610777565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b815250906107c25760405162461bcd60e51b81526004016102a09190611dcc565b50505b826001600160a01b0316846001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb8485604051610813929190918252602082015260400190565b60405180910390a35080610420565b6001600160a01b03841615610846576108466001600160a01b038516333085610b3d565b600061085a8461085587610bae565b610ef3565b9050836001600160a01b0316856001600160a01b03167fa078c4190abe07940190effc1846be0ccf03ad6007bc9e93f9697d0b460befbb85846040516108aa929190918252602082015260400190565b60405180910390a36108bc84826110ab565b95945050505050565b6040516321f8a72160e01b81526a3937b632a6b0b730b3b2b960a91b60048201526000906001600160a01b038316906321f8a721906024015b602060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611e18565b60006001600160a01b038316600080516020612165833981519152148061096d57506001600160a01b038316155b156109795750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610a2e576000806109a78387611171565b60405163556d6e9f60e01b815260048101829052602481018390526044810188905291935091506001600160a01b0384169063556d6e9f906064015b602060405180830381865afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190611dff565b93505050506103d8565b610a608460008051602061216583398151915285610a5b886000805160206121658339815191528961121a565b611273565b949350505050565b60006001600160a01b0383166000805160206121658339815191521480610a9657506001600160a01b038316155b15610aa25750806103d8565b6001600160a01b03808416600090815260016020526040902054168015610b1057600080610ad08387611171565b60405163556d6e9f60e01b815260048101839052602481018290526044810188905291935091506001600160a01b0384169063556d6e9f906064016109e3565b610a606000805160206121658339815191528585610a5b600080516020612165833981519152898961121a565b6040516001600160a01b0380851660248301528316604482015260648101829052610ba89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611387565b50505050565b60006001600160a01b0382166000805160206121658339815191521415610c3c576040516370a0823160e01b8152306004820152600080516020612165833981519152906370a0823190602401602060405180830381865afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d89190611dff565b6001600160a01b038216610cc2574780610c595750600092915050565b6000805160206121658339815191526001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b50939695505050505050565b6001600160a01b03808316600090815260016020526040902054168015610e70576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4e9190611dff565b905080610d5f575060009392505050565b610d69848361145e565b600080610d768487611171565b91509150836001600160a01b0316635b41b908828486610d96888c6114f6565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260008051602061216583398151915292506370a082319150602401602060405180830381865afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e669190611dff565b9695505050505050565b6040516370a0823160e01b8152306004820152610420908490600080516020612165833981519152906001600160a01b038316906370a0823190602401602060405180830381865afa158015610eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee9190611dff565b611595565b600081610f02575060006103d8565b6001600160a01b0383166000805160206121658339815191521415610f285750806103d8565b6001600160a01b038316610f9d57604051632e1a7d4d60e01b81526004810183905260008051602061216583398151915290632e1a7d4d90602401600060405180830381600087803b158015610f7d57600080fd5b505af1158015610f91573d6000803e3d6000fd5b505050508190506103d8565b6001600160a01b0380841660009081526001602052604090205416801561109257610fd66000805160206121658339815191528261145e565b600080610fe38387611171565b91509150826001600160a01b0316635b41b9088383886110038a8c6116ff565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401600060405180830381600087803b15801561104e57600080fd5b505af1158015611062573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201526001600160a01b03891692506370a0823191506024016109e3565b610a606000805160206121658339815191528585611595565b60006001600160a01b03831661115757604051600090339084908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b50509050806040518060400160405280600f81526020016e1d1c985b9cd9995c8819985a5b1959608a1b8152509061114d5760405162461bcd60e51b81526004016102a09190611dcc565b50829150506103d8565b61116b6001600160a01b0384163384611798565b50919050565b600080826001600160a01b0316846001600160a01b031663c661065760016040518263ffffffff1660e01b81526004016111ad91815260200190565b602060405180830381865afa1580156111ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ee9190611e18565b6001600160a01b031614611205576001600061120a565b600060015b60ff918216969116945092505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f61125286868684611273565b61125e87878786611273565b101561126a5780610e66565b50949350505050565b6040805160028082526060820183526000928392919060208301908036833701905050905085816000815181106112ac576112ac611e4b565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106112e0576112e0611e4b565b6001600160a01b03928316602091820292909201015260405163d06ca61f60e01b81529084169063d06ca61f9061131d9087908590600401611ea5565b600060405180830381865afa15801561133a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113629190810190611ebe565b60018151811061137457611374611e4b565b6020026020010151915050949350505050565b60006113dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117c89092919063ffffffff16565b80519091501561145957808060200190518101906113fa9190611d7e565b6114595760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a0565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0382811660248301526000919084169063dd62ed3e90604401602060405180830381865afa1580156114ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d29190611dff565b11156114dc575050565b6114f26001600160a01b038316826000196117d7565b5050565b600080611502836118ec565b9050806115135760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115789190611f7c565b60005461158f906115898886611a07565b90611a07565b90611a26565b6000816115a457506000610420565b826001600160a01b0316846001600160a01b031614156115c5575080610420565b60006115d285858561121a565b90506115de858261145e565b604080516002808252606082018352600092602083019080368337019050509050858160008151811061161357611613611e4b565b60200260200101906001600160a01b031690816001600160a01b031681525050848160018151811061164757611647611e4b565b6001600160a01b03928316602091820292909201015282166338ed173985611670818a8a611a87565b8430426040518663ffffffff1660e01b8152600401611693959493929190611f9f565b6000604051808303816000875af11580156116b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116da9190810190611ebe565b6001815181106116ec576116ec611e4b565b6020026020010151925050509392505050565b60008061170b836118ec565b90508061171c5760009150506103d8565b610a60836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190611f7c565b600054611792906115898886611ac0565b90611ad5565b6040516001600160a01b03831660248201526044810182905261145990849063a9059cbb60e01b90606401610b71565b606061041d8484600085611b0c565b8015806118515750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190611dff565b155b6118bc5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016102a0565b6040516001600160a01b03831660248201526044810182905261145990849063095ea7b360e01b90606401610b71565b6000806119217f000000000000000000000000ac61fd84c5b20828c666ab1fdca0329aeaa8c8ee6001600160a01b0316611c3d565b6040516308c9682b60e31b81526001600160a01b0385811660048301529192509082169063464b415890602401602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190611d7e565b156119fe5760405163e5ec9db960e01b81526001600160a01b03848116600483015282169063e5ec9db990602401602060405180830381865afa1580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104209190611dff565b50600092915050565b6000670de0b6b3a7640000611a1c8385611ff1565b6103d59190612010565b600060ff821660121415611a3b5750816103d8565b601260ff83161115611a6757611a52601283612032565b611a5d90600a612139565b61035e9084612010565b611a72826012612032565b611a7d90600a612139565b61035e9084611ff1565b60006001600160a01b03831660008051602061216583398151915214611ab657611ab184846114f6565b61041d565b61041d84836116ff565b600081611a1c670de0b6b3a764000085611ff1565b600060ff821660121415611aea5750816103d8565b601260ff83161115611b0157611a72601283612032565b611a52826012612032565b606082471015611b6d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016102a0565b6001600160a01b0385163b611bc45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a0565b600080866001600160a01b03168587604051611be09190612148565b60006040518083038185875af1925050503d8060008114611c1d576040519150601f19603f3d011682016040523d82523d6000602084013e611c22565b606091505b5091509150611c32828286611c7d565b979650505050505050565b6040516321f8a72160e01b81526d37b930b1b632a83937bb34b232b960911b60048201526000906001600160a01b038316906321f8a721906024016108fe565b60608315611c8c575081610420565b825115611c9c5782518084602001fd5b8160405162461bcd60e51b81526004016102a09190611dcc565b600060208284031215611cc857600080fd5b5035919050565b6001600160a01b0381168114611ce457600080fd5b50565b60008060408385031215611cfa57600080fd5b8235611d0581611ccf565b91506020830135611d1581611ccf565b809150509250929050565b600080600060608486031215611d3557600080fd5b8335611d4081611ccf565b92506020840135611d5081611ccf565b929592945050506040919091013590565b600060208284031215611d7357600080fd5b813561042081611ccf565b600060208284031215611d9057600080fd5b8151801515811461042057600080fd5b60005b83811015611dbb578181015183820152602001611da3565b83811115610ba85750506000910152565b6020815260008251806020840152611deb816040850160208701611da0565b601f01601f19169190910160400192915050565b600060208284031215611e1157600080fd5b5051919050565b600060208284031215611e2a57600080fd5b815161042081611ccf565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015611e9a5781516001600160a01b031687529582019590820190600101611e75565b509495945050505050565b82815260406020820152600061041d6040830184611e61565b60006020808385031215611ed157600080fd5b825167ffffffffffffffff80821115611ee957600080fd5b818501915085601f830112611efd57600080fd5b815181811115611f0f57611f0f611e35565b8060051b604051601f19603f83011681018181108582111715611f3457611f34611e35565b604052918252848201925083810185019188831115611f5257600080fd5b938501935b82851015611f7057845184529385019392850192611f57565b98975050505050505050565b600060208284031215611f8e57600080fd5b815160ff8116811461042057600080fd5b85815284602082015260a060408201526000611fbe60a0830186611e61565b6001600160a01b0394909416606083015250608001529392505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561200b5761200b611fdb565b500290565b60008261202d57634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168082101561204c5761204c611fdb565b90039392505050565b600181815b8085111561209057816000190482111561207657612076611fdb565b8085161561208357918102915b93841c939080029061205a565b509250929050565b6000826120a7575060016103d8565b816120b4575060006103d8565b81600181146120ca57600281146120d4576120f0565b60019150506103d8565b60ff8411156120e5576120e5611fdb565b50506001821b6103d8565b5060208310610133831016604e8410600b8410161715612113575081810a6103d8565b61211d8383612055565b806000190482111561213157612131611fdb565b029392505050565b60006103d560ff841683612098565b6000825161215a818460208701611da0565b919091019291505056fe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a2646970667358221220fbeb5a96ecfeca936ae80a6aa1394adfa61cde8ef4986d6fac920d1dd142740d64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ac61fd84c5b20828c666ab1fdca0329aeaa8c8ee
-----Decoded View---------------
Arg [0] : addressProvider_ (address): 0xAc61Fd84c5B20828c666aB1FdCa0329AEaA8C8eE
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ac61fd84c5b20828c666ab1fdca0329aeaa8c8ee
Deployed Bytecode Sourcemap
55552:18233:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27326:108;;;;;;;;;;-1:-1:-1;27878:13:0;27326:108;;;-1:-1:-1;;;;;198:32:1;;;180:51;;168:2;153:18;27326:108:0;;;;;;;;58216:294;;;;;;;;;;-1:-1:-1;58216:294:0;;;;;:::i;:::-;;:::i;:::-;;57551:464;;;;;;:::i;:::-;;:::i;:::-;;;1102:25:1;;;1090:2;1075:18;57551:464:0;956:177:1;59641:323:0;;;;;;;;;;-1:-1:-1;59641:323:0;;;;;:::i;:::-;;:::i;58817:369::-;;;;;;;;;;-1:-1:-1;58817:369:0;;;;;:::i;:::-;;:::i;56470:51::-;;;;;;;;;;-1:-1:-1;56470:51:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;56470:51:0;;;56362:32;;;;;;;;;;;;;;;;60271:1325;;;;;;:::i;:::-;;:::i;58216:294::-;27878:13;26567:52;;-1:-1:-1;;;26567:52:0;;-1:-1:-1;;;26567:52:0;;;2255:25:1;26608:10:0;2296:18:1;;;2289:60;-1:-1:-1;;;;;26567:22:0;;;;;;;2228:18:1;;26567:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26621:25;;;;;;;;;;;;;-1:-1:-1;;;26621:25:0;;;26559:88;;;;;-1:-1:-1;;;26559:88:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;58364:32:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;49590:4:::1;58326:36:::0;::::1;;58318:79;;;;-1:-1:-1::0;;;58318:79:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;58408:17:0::1;:38:::0;;;58462:40:::1;::::0;1102:25:1;;;58462:40:0::1;::::0;1090:2:1;1075:18;58462:40:0::1;;;;;;;58216:294:::0;:::o;57551:464::-;57677:17;-1:-1:-1;;;;;57758:24:0;;57754:113;;57806:49;57811:10;57823:8;57833:21;57806:4;:49::i;:::-;57799:56;;;;57754:113;57957:49;;-1:-1:-1;;;57957:49:0;;57994:10;57957:49;;;180:51:1;57930:77:0;;57935:10;;57947:8;;-1:-1:-1;;;;;57957:28:0;;;;;153:18:1;;57957:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;57930:77::-;57923:84;;57551:464;;;;;:::o;59641:323::-;59786:17;59834:8;-1:-1:-1;;;;;59820:22:0;:10;-1:-1:-1;;;;;59820:22:0;;:40;;;-1:-1:-1;59846:14:0;;59820:40;59816:62;;;-1:-1:-1;59869:9:0;59862:16;;59816:62;59898:58;59911:8;59921:34;59933:10;59945:9;59921:11;:34::i;:::-;59898:12;:58::i;:::-;59891:65;;59641:323;;;;;;:::o;58817:369::-;27878:13;26567:52;;-1:-1:-1;;;26567:52:0;;-1:-1:-1;;;26567:52:0;;;2255:25:1;26608:10:0;2296:18:1;;;2289:60;-1:-1:-1;;;;;26567:22:0;;;;;;;2228:18:1;;26567:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26621:25;;;;;;;;;;;;;-1:-1:-1;;;26621:25:0;;;26559:88;;;;;-1:-1:-1;;;26559:88:0;;;;;;;;:::i;:::-;-1:-1:-1;58949:30:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;-1:-1:-1;;;;;58927:20:0;::::1;58919:61;;;;-1:-1:-1::0;;;58919:61:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;59021:18:0;;::::1;;::::0;;;:10:::1;:18;::::0;;;;;;;;;59042:30;;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;58999:41;;::::1;59021:18:::0;::::1;58999:41;;58991:82;;;;-1:-1:-1::0;;;58991:82:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;59084:18:0;;::::1;;::::0;;;:10:::1;:18;::::0;;;;;;;;:46;;-1:-1:-1;;;;;;59084:46:0::1;::::0;;::::1;::::0;;::::1;::::0;;59146:32;;3902:34:1;;;3952:18;;3945:43;;;;59146:32:0::1;::::0;3837:18:1;59146:32:0::1;;;;;;;58817:369:::0;;:::o;60271:1325::-;60409:17;-1:-1:-1;;;;;60499:24:0;;;:40;;60538:1;60499:40;;;60526:9;60499:40;60485:9;:55;60542:20;;;;;;;;;;;;;-1:-1:-1;;;60542:20:0;;;60477:86;;;;;-1:-1:-1;;;60477:86:0;;;;;;;;:::i;:::-;-1:-1:-1;60578:14:0;60574:110;;60614:35;;;60644:1;4189:25:1;;;4245:2;4230:18;;4223:34;-1:-1:-1;;;;;60614:35:0;;;;;;;;;;4162:18:1;60614:35:0;;;;;;;-1:-1:-1;60671:1:0;60664:8;;60574:110;60763:8;-1:-1:-1;;;;;60749:22:0;:10;-1:-1:-1;;;;;60749:22:0;;60745:412;;;-1:-1:-1;;;;;60792:24:0;;60788:256;;60924:46;;60906:12;;60932:10;;60956:9;;60906:12;60924:46;60906:12;60924:46;60956:9;60932:10;60924:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60905:65;;;60997:7;61006:21;;;;;;;;;;;;;-1:-1:-1;;;61006:21:0;;;60989:39;;;;;-1:-1:-1;;;60989:39:0;;;;;;;;:::i;:::-;;60818:226;60788:256;61083:8;-1:-1:-1;;;;;61063:51:0;61071:10;-1:-1:-1;;;;;61063:51:0;;61093:9;61104;61063:51;;;;;;4189:25:1;;;4245:2;4230:18;;4223:34;4177:2;4162:18;;3999:264;61063:51:0;;;;;;;;-1:-1:-1;61136:9:0;61129:16;;60745:412;-1:-1:-1;;;;;61219:24:0;;;61215:130;;61260:73;-1:-1:-1;;;;;61260:35:0;;61296:10;61316:4;61323:9;61260:35;:73::i;:::-;61393:18;61414:53;61432:8;61442:24;61455:10;61442:12;:24::i;:::-;61414:17;:53::i;:::-;61393:74;;61503:8;-1:-1:-1;;;;;61483:52:0;61491:10;-1:-1:-1;;;;;61483:52:0;;61513:9;61524:10;61483:52;;;;;;4189:25:1;;;4245:2;4230:18;;4223:34;4177:2;4162:18;;3999:264;61483:52:0;;;;;;;;61553:35;61567:8;61577:10;61553:13;:35::i;:::-;61546:42;60271:1325;-1:-1:-1;;;;;60271:1325:0:o;47456:186::-;47575:58;;-1:-1:-1;;;47575:58:0;;-1:-1:-1;;;47575:58:0;;;1102:25:1;47530:12:0;;-1:-1:-1;;;;;47575:19:0;;;;;1075:18:1;;47575:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;66867:745::-;66971:17;-1:-1:-1;;;;;67010:24:0;;-1:-1:-1;;;;;;;;;;;67010:24:0;;:48;;-1:-1:-1;;;;;;67038:20:0;;;67010:48;67006:68;;;-1:-1:-1;67067:7:0;67060:14;;67006:68;-1:-1:-1;;;;;67152:18:0;;;67125:24;67152:18;;;:10;:18;;;;;;;67185:33;;67181:214;;67236:18;67256:19;67279:31;67291:10;67303:6;67279:11;:31::i;:::-;67332:51;;-1:-1:-1;;;67332:51:0;;;;;5371:25:1;;;5412:18;;;5405:34;;;5455:18;;;5448:34;;;67235:75:0;;-1:-1:-1;67235:75:0;-1:-1:-1;;;;;;67332:17:0;;;;;5344:18:1;;67332:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67325:58;;;;;;;67181:214;67427:177;67461:6;-1:-1:-1;;;;;;;;;;;67519:7:0;67545:44;67557:6;-1:-1:-1;;;;;;;;;;;67581:7:0;67545:11;:44::i;:::-;67427:15;:177::i;:::-;67407:197;66867:745;-1:-1:-1;;;;66867:745:0:o;67986:746::-;68091:17;-1:-1:-1;;;;;68130:24:0;;-1:-1:-1;;;;;;;;;;;68130:24:0;;:48;;-1:-1:-1;;;;;;68158:20:0;;;68130:48;68126:68;;;-1:-1:-1;68187:7:0;68180:14;;68126:68;-1:-1:-1;;;;;68272:18:0;;;68245:24;68272:18;;;:10;:18;;;;;;;68305:33;;68301:214;;68356:18;68376:19;68399:31;68411:10;68423:6;68399:11;:31::i;:::-;68452:51;;-1:-1:-1;;;68452:51:0;;;;;5371:25:1;;;5412:18;;;5405:34;;;5455:18;;;5448:34;;;68355:75:0;;-1:-1:-1;68355:75:0;-1:-1:-1;;;;;;68452:17:0;;;;;5344:18:1;;68452:51:0;5169:319:1;68301:214:0;68547:177;-1:-1:-1;;;;;;;;;;;68614:6:0;68639:7;68665:44;-1:-1:-1;;;;;;;;;;;68693:6:0;68701:7;68665: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;61803:1206::-;61859:17;-1:-1:-1;;;;;61893:24:0;;-1:-1:-1;;;;;;;;;;;61893:24:0;61889:67;;;61926:30;;-1:-1:-1;;;61926:30:0;;61950:4;61926:30;;;180:51:1;-1:-1:-1;;;;;;;;;;;56141:42:0;61926:15;;153:18:1;;61926:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61889:67::-;-1:-1:-1;;;;;62006:20:0;;62002:224;;62065:21;62105:16;62101:30;;-1:-1:-1;62130:1:0;;61803:1206;-1:-1:-1;;61803:1206:0:o;62101:30::-;-1:-1:-1;;;;;;;;;;;;;;;;62146:13:0;;62167:11;62146:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62203:11:0;;61803:1206;-1:-1:-1;;;;;;61803:1206:0:o;62002:224::-;-1:-1:-1;;;;;62303:18:0;;;62276:24;62303:18;;;:10;:18;;;;;;;62336:33;;62332:545;;62404:39;;-1:-1:-1;;;62404:39:0;;62437:4;62404:39;;;180:51:1;62386:15:0;;-1:-1:-1;;;;;62404:24:0;;;;;153:18:1;;62404:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62386:57;-1:-1:-1;62462:12:0;62458:26;;-1:-1:-1;62483:1:0;;61803:1206;-1:-1:-1;;;61803:1206:0:o;62458:26::-;62499:37;62508:6;62524:10;62499:8;:37::i;:::-;62552:18;62572:19;62595:31;62607:10;62619:6;62595:11;:31::i;:::-;62551:75;;;;62641:10;-1:-1:-1;;;;;62641:19:0;;62679:11;62709:10;62738:7;62764:34;62782:7;62791:6;62764:17;:34::i;:::-;62641:172;;-1:-1:-1;;;;;;62641:172:0;;;;;;;;;;6104:25:1;;;;6145:18;;;6138:34;;;;6188:18;;;6181:34;6231:18;;;6224:34;6076:19;;62641:172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;62835:30:0;;-1:-1:-1;;;62835:30:0;;62859:4;62835:30;;;180:51:1;-1:-1:-1;;;;;;;;;;;56141:42:0;-1:-1:-1;62835:15:0;;-1:-1:-1;153:18:1;;62835:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62828:37;61803:1206;-1:-1:-1;;;;;;61803:1206:0:o;62332:545::-;62961:39;;-1:-1:-1;;;62961:39:0;;62994:4;62961:39;;;180:51:1;62931:70:0;;62937:6;;-1:-1:-1;;;;;;;;;;;56141:42:0;-1:-1:-1;;;;;62961:24:0;;;;;153:18:1;;62961:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62931:5;:70::i;63217:1019::-;63313:17;63352:12;63348:26;;-1:-1:-1;63373:1:0;63366:8;;63348:26;-1:-1:-1;;;;;63389:24:0;;-1:-1:-1;;;;;;;;;;;63389:24:0;63385:44;;;-1:-1:-1;63422:7:0;63415:14;;63385:44;-1:-1:-1;;;;;63479:20:0;;63475:105;;63516:23;;-1:-1:-1;;;63516:23:0;;;;;1102:25:1;;;-1:-1:-1;;;;;;;;;;;56141:42:0;63516:14;;1075:18:1;;63516:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63561:7;63554:14;;;;63475:105;-1:-1:-1;;;;;63657:18:0;;;63630:24;63657:18;;;:10;:18;;;;;;;63690:33;;63686:450;;63740:45;-1:-1:-1;;;;;;;;;;;63773:10:0;63740:8;:45::i;:::-;63801:18;63821:19;63844:31;63856:10;63868:6;63844:11;:31::i;:::-;63800:75;;;;63890:10;-1:-1:-1;;;;;63890:19:0;;63928:10;63957:11;63987:7;64013:35;64032:7;64041:6;64013:18;:35::i;:::-;63890:173;;-1:-1:-1;;;;;;63890:173:0;;;;;;;;;;6104:25:1;;;;6145:18;;;6138:34;;;;6188:18;;;6181:34;6231:18;;;6224:34;6076:19;;63890:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64085:39:0;;-1:-1:-1;;;64085:39:0;;64118:4;64085:39;;;180:51:1;-1:-1:-1;;;;;64085:24:0;;;-1:-1:-1;64085:24:0;;-1:-1:-1;153:18:1;;64085:39:0;14:223:1;63686:450:0;64190:38;-1:-1:-1;;;;;;;;;;;64212:6:0;64220:7;64190:5;:38::i;65943:548::-;66035:22;-1:-1:-1;;;;;66108:20:0;;66104:263;;66228:44;;66210:12;;66236:10;;66260:7;;66210:12;66228:44;66210:12;66228:44;66260:7;66236:10;66228:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66209:63;;;66295:7;66304:21;;;;;;;;;;;;;-1:-1:-1;;;66304:21:0;;;66287:39;;;;;-1:-1:-1;;;66287:39:0;;;;;;;;:::i;:::-;;66348:7;66341:14;;;;;66104:263;66410:48;-1:-1:-1;;;;;66410:27:0;;66438:10;66450:7;66410:27;:48::i;:::-;-1:-1:-1;66476:7:0;65943:548;-1:-1:-1;65943:548:0:o;73550:232::-;73663:18;73683:19;73750:6;-1:-1:-1;;;;;73727:29:0;:10;-1:-1:-1;;;;;73727:16:0;;73744:1;73727:19;;;;;;;;;;;;;1102:25:1;;1090:2;1075:18;;956:177;73727:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;73727:29:0;;:47;;73769:1;73772;73727:47;;;73760:1;73763;73727:47;73720:54;;;;;;;;-1:-1:-1;73550:232:0;-1:-1:-1;;;73550:232:0:o;69121:462::-;69254:15;55844:42;55995;69459:58;69475:10;69487:8;69497:7;55995:42;69459:15;:58::i;:::-;69382:56;69398:10;69410:8;69420:7;69429:8;69382:15;:56::i;:::-;:135;;:193;;69565:10;69382:193;;;-1:-1:-1;69537:8:0;69362:213;-1:-1:-1;;;;69121:462:0:o;69997:377::-;70214:16;;;70228:1;70214:16;;;;;;;;70159:17;;;;70214:16;70228:1;70214:16;;;;;;;;;;-1:-1:-1;70214:16:0;70189:41;;70252:10;70241:5;70247:1;70241:8;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;70241:21:0;;;-1:-1:-1;;;;;70241:21:0;;;;;70284:8;70273:5;70279:1;70273:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;70273:19:0;;;:8;;;;;;;;;:19;70310:53;;-1:-1:-1;;;70310:53:0;;:35;;;;;;:53;;70346:9;;70357:5;;70310:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70310:53:0;;;;;;;;;;;;:::i;:::-;70364:1;70310:56;;;;;;;;:::i;:::-;;;;;;;70303:63;;;69997: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;65460:211::-;65536:49;;-1:-1:-1;;;65536:49:0;;65569:4;65536:49;;;3902:34:1;-1:-1:-1;;;;;3972:15:1;;;3952:18;;;3945:43;65588:1:0;;65536:24;;;;;;3837:18:1;;65536:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;65532:66;;;65460:211;;:::o;65532:66::-;65608:55;-1:-1:-1;;;;;65608:26:0;;65635:8;-1:-1:-1;;65608:26:0;:55::i;:::-;65460:211;;:::o;72080:414::-;72195:20;72233:19;72255:22;72270:6;72255:14;:22::i;:::-;72233:44;-1:-1:-1;72292:16:0;72288:30;;72317:1;72310:8;;;;;72288:30;72349:137;72453:6;-1:-1:-1;;;;;72442:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72395:17;;72349:64;;:35;:12;72372:11;72349:22;:35::i;:::-;:45;;:64::i;:::-;:74;;:137::i;64540:735::-;64662:17;64696:12;64692:26;;-1:-1:-1;64717:1:0;64710:8;;64692:26;64747:8;-1:-1:-1;;;;;64733:22:0;:10;-1:-1:-1;;;;;64733:22:0;;64729:42;;;-1:-1:-1;64764:7:0;64757:14;;64729:42;64782:12;64797:42;64809:10;64821:8;64831:7;64797:11;:42::i;:::-;64782:57;;64850:26;64859:10;64871:4;64850:8;:26::i;:::-;64912:16;;;64926:1;64912:16;;;;;;;;64887:22;;64912:16;;;;;;;;;;-1:-1:-1;64912:16:0;64887:41;;64950:10;64939:5;64945:1;64939:8;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;64939:21:0;;;-1:-1:-1;;;;;64939:21:0;;;;;64982:8;64971:5;64977:1;64971:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;64971:19:0;;;:8;;;;;;;;;:19;65021:46;;;65086:7;65112:47;65086:7;65138:10;65150:8;65112:16;:47::i;:::-;65178:5;65210:4;65234:15;65021:243;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65021:243:0;;;;;;;;;;;;:::i;:::-;65265:1;65021:246;;;;;;;;:::i;:::-;;;;;;;65001:266;;;;64540:735;;;;;:::o;71368:411::-;71483:20;71521:19;71543:22;71558:6;71543:14;:22::i;:::-;71521:44;-1:-1:-1;71580:16:0;71576:30;;71605:1;71598:8;;;;;71576:30;71637:134;71738:6;-1:-1:-1;;;;;71727:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71682:17;;71637:63;;:34;:11;71659;71637: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;72902:320:0;72965:23;73001:30;73034:36;:16;-1:-1:-1;;;;;73034:34:0;;:36::i;:::-;73085:39;;-1:-1:-1;;;73085:39:0;;-1:-1:-1;;;;;198:32:1;;;73085:39:0;;;180:51:1;73001:69:0;;-1:-1:-1;73085:31:0;;;;;;153:18:1;;73085:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73081:113;;;73148:34;;-1:-1:-1;;;73148:34:0;;-1:-1:-1;;;;;198:32:1;;;73148:34:0;;;180:51:1;73148:26:0;;;;;153:18:1;;73148:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;73081:113::-;-1:-1:-1;73213:1:0;;72902:320;-1:-1:-1;;72902:320:0:o;49690:122::-;49754:7;49481:4;49782:5;49786:1;49782;:5;:::i;:::-;49781:23;;;;:::i;48305:340::-;48378:7;48402:21;;;48273:2;48402:21;48398:240;;;-1:-1:-1;48447:5:0;48440:12;;48398:240;48273:2;48474:20;;;;48470:168;;;48531:20;48273:2;48531:8;:20;:::i;:::-;48526:26;;:2;:26;:::i;:::-;48518:34;;:5;:34;:::i;48470:168::-;48605:20;48617:8;48273:2;48605:20;:::i;:::-;48600:26;;:2;:26;:::i;:::-;48592:34;;:5;:34;:::i;70727:342::-;70865:20;-1:-1:-1;;;;;70918:28:0;;-1:-1:-1;;;;;;;;;;;70918:28:0;:143;;71023:38;71041:7;71050:10;71023:17;:38::i;:::-;70918:143;;;70966:37;70985:7;70994:8;70966:18;:37::i;49901:122::-;49965:7;50014:1;49993:17;49481:4;49993:1;:17;:::i;48653:338::-;48724:7;48748:21;;;48273:2;48748:21;48744:240;;;-1:-1:-1;48793:5:0;48786:12;;48744:240;48273:2;48820:20;;;;48816:168;;;48877:20;48273:2;48877:8;:20;:::i;48816:168::-;48951:20;48963:8;48273:2;48951: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;46947:198::-;47075:61;;-1:-1:-1;;;47075:61:0;;-1:-1:-1;;;47075:61:0;;;1102:25:1;47024:15:0;;-1:-1:-1;;;;;47075:19:0;;;;;1075:18:1;;47075: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://fbeb5a96ecfeca936ae80a6aa1394adfa61cde8ef4986d6fac920d1dd142740d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 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.