ETH Price: $3,396.72 (+1.86%)

Contract

0x50daBB21895Ed7E11C9E7Cb6dAa98d4Bf9fb6929
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Call192870052024-02-23 1:25:23310 days ago1708651523IN
0x50daBB21...Bf9fb6929
0 ETH0.00711546.620604
Call192789332024-02-21 22:14:35311 days ago1708553675IN
0x50daBB21...Bf9fb6929
0 ETH0.0056130336.77904669
Call192780212024-02-21 19:10:11311 days ago1708542611IN
0x50daBB21...Bf9fb6929
0 ETH0.0063931137.6696837
Call192751202024-02-21 9:23:35312 days ago1708507415IN
0x50daBB21...Bf9fb6929
0 ETH0.0044949829.45308398
Call192747872024-02-21 8:15:59312 days ago1708503359IN
0x50daBB21...Bf9fb6929
0 ETH0.0047596631.18738289
Call192722432024-02-20 23:40:11312 days ago1708472411IN
0x50daBB21...Bf9fb6929
0 ETH0.0068524940.376502
Call192715632024-02-20 21:23:11312 days ago1708464191IN
0x50daBB21...Bf9fb6929
0 ETH0.0058807138.5329768
Call192668642024-02-20 5:34:23313 days ago1708407263IN
0x50daBB21...Bf9fb6929
0 ETH0.0028777518.85630309
Call192645142024-02-19 21:41:11313 days ago1708378871IN
0x50daBB21...Bf9fb6929
0 ETH0.0056177536.80998221
Call192514252024-02-18 1:26:35315 days ago1708219595IN
0x50daBB21...Bf9fb6929
0 ETH0.0027790118.20930479
Call192503882024-02-17 21:56:35315 days ago1708206995IN
0x50daBB21...Bf9fb6929
0 ETH0.0031369620.55474426
Call192497382024-02-17 19:45:47315 days ago1708199147IN
0x50daBB21...Bf9fb6929
0 ETH0.0032238921.12438802
Call192495712024-02-17 19:12:11315 days ago1708197131IN
0x50daBB21...Bf9fb6929
0 ETH0.0030208219.79378809
Call192397812024-02-16 10:11:11317 days ago1708078271IN
0x50daBB21...Bf9fb6929
0 ETH0.0040027326.22765956
Call192396562024-02-16 9:45:35317 days ago1708076735IN
0x50daBB21...Bf9fb6929
0 ETH0.0034230622.42940728
Call192394852024-02-16 9:10:59317 days ago1708074659IN
0x50daBB21...Bf9fb6929
0 ETH0.0045755729.98113292
Call192324932024-02-15 9:39:59318 days ago1707989999IN
0x50daBB21...Bf9fb6929
0 ETH0.0026054817.07226667
Call192323582024-02-15 9:12:35318 days ago1707988355IN
0x50daBB21...Bf9fb6929
0 ETH0.0030807720.18659898
Call192322042024-02-15 8:41:35318 days ago1707986495IN
0x50daBB21...Bf9fb6929
0 ETH0.0026770417.54113547
Call192234402024-02-14 3:10:11319 days ago1707880211IN
0x50daBB21...Bf9fb6929
0 ETH0.0025946917.00160519
Call192207902024-02-13 18:14:35319 days ago1707848075IN
0x50daBB21...Bf9fb6929
0 ETH0.0045849130.04235906
Call186562772023-11-26 13:54:59398 days ago1701006899IN
0x50daBB21...Bf9fb6929
0 ETH0.0045426329.76532725
Call186484852023-11-25 11:42:47399 days ago1700912567IN
0x50daBB21...Bf9fb6929
0 ETH0.0031608720.71143823
Call186407032023-11-24 9:34:47401 days ago1700818487IN
0x50daBB21...Bf9fb6929
0 ETH0.004897932.09320728
Call186334292023-11-23 9:06:59402 days ago1700730419IN
0x50daBB21...Bf9fb6929
0 ETH0.0041703127.32574731
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
161987592022-12-16 17:29:59743 days ago1671211799  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Withdrawer

Compiler Version
v0.8.3+commit.8d00100c

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-23
*/

// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// File @mimic-fi/v2-helpers/contracts/auth/[email protected]


pragma solidity >=0.8.0;

/**
 * @title IAuthorizer
 */
interface IAuthorizer {
    /**
     * @dev Emitted when an account is authorized to call a function
     */
    event Authorized(address indexed who, bytes4 what);

    /**
     * @dev Emitted when an account is unauthorized to call a function
     */
    event Unauthorized(address indexed who, bytes4 what);

    /**
     * @dev Authorizes someone to call a function. Sender must be authorize to do so.
     * @param who Address to be authorized
     * @param what Function selector to be granted
     */
    function authorize(address who, bytes4 what) external;

    /**
     * @dev Unauthorizes someone to call a function. Sender must be authorize to do so.
     * @param who Address to be unauthorized
     * @param what Function selector to be revoked
     */
    function unauthorize(address who, bytes4 what) external;

    /**
     * @dev Tells whether someone is allowed to call a function or not. It returns true if it's allowed to anyone.
     * @param who Address asking permission for
     * @param what Function selector asking permission for
     */
    function isAuthorized(address who, bytes4 what) external view returns (bool);
}


// File @mimic-fi/v2-registry/contracts/implementations/[email protected]


pragma solidity >=0.8.0;

// solhint-disable func-name-mixedcase

/**
 * @title IImplementation
 * @dev Implementation interface that must be followed for implementations to be registered in the Mimic Registry
 */
interface IImplementation {
    /**
     * @dev Tells the namespace under which the implementation is registered in the Mimic Registry
     */
    function NAMESPACE() external view returns (bytes32);

    /**
     * @dev Tells the address of the Mimic Registry
     */
    function registry() external view returns (address);
}


// File @mimic-fi/v2-price-oracle/contracts/feeds/[email protected]


pragma solidity >=0.8.0;

/**
 * @title IPriceFeedProvider
 * @dev Contract providing price feed references for (base, quote) token pairs
 */
interface IPriceFeedProvider {
    /**
     * @dev Emitted every time a price feed is set for (base, quote) pair
     */
    event PriceFeedSet(address indexed base, address indexed quote, address feed);

    /**
     * @dev Tells the price feed address for (base, quote) pair. It returns the zero address if there is no one set.
     * @param base Token to be rated
     * @param quote Token used for the price rate
     */
    function getPriceFeed(address base, address quote) external view returns (address);

    /**
     * @dev Sets a of price feed
     * @param base Token base to be set
     * @param quote Token quote to be set
     * @param feed Price feed to be set
     */
    function setPriceFeed(address base, address quote, address feed) external;

    /**
     * @dev Sets a list of price feeds
     * @param bases List of token bases to be set
     * @param quotes List of token quotes to be set
     * @param feeds List of price feeds to be set
     */
    function setPriceFeeds(address[] memory bases, address[] memory quotes, address[] memory feeds) external;
}


// File @mimic-fi/v2-smart-vault/contracts/[email protected]


pragma solidity ^0.8.0;



/**
 * @title ISmartVault
 * @dev Mimic Smart Vault interface to manage assets. It must support also `IImplementation` and `IAuthorizer`
 */
interface ISmartVault is IPriceFeedProvider, IImplementation, IAuthorizer {
    enum SwapLimit {
        Slippage,
        MinAmountOut
    }

    /**
     * @dev Emitted every time a new strategy is set for the Smart Vault
     */
    event StrategySet(address indexed strategy, bool allowed);

    /**
     * @dev Emitted every time a new price oracle is set for the Smart Vault
     */
    event PriceOracleSet(address indexed priceOracle);

    /**
     * @dev Emitted every time a new swap connector is set for the Smart Vault
     */
    event SwapConnectorSet(address indexed swapConnector);

    /**
     * @dev Emitted every time a new fee collector is set
     */
    event FeeCollectorSet(address indexed feeCollector);

    /**
     * @dev Emitted every time the withdraw fee percentage is set
     */
    event WithdrawFeeSet(uint256 pct, uint256 cap, address token, uint256 period);

    /**
     * @dev Emitted every time the performance fee percentage is set
     */
    event PerformanceFeeSet(uint256 pct, uint256 cap, address token, uint256 period);

    /**
     * @dev Emitted every time the swap fee percentage is set
     */
    event SwapFeeSet(uint256 pct, uint256 cap, address token, uint256 period);

    /**
     * @dev Emitted every time `call` is called
     */
    event Call(address indexed target, bytes callData, uint256 value, bytes result, bytes data);

    /**
     * @dev Emitted every time `collect` is called
     */
    event Collect(address indexed token, address indexed from, uint256 collected, bytes data);

    /**
     * @dev Emitted every time `withdraw` is called
     */
    event Withdraw(address indexed token, address indexed recipient, uint256 withdrawn, uint256 fee, bytes data);

    /**
     * @dev Emitted every time `wrap` is called
     */
    event Wrap(uint256 amount, uint256 wrapped, bytes data);

    /**
     * @dev Emitted every time `unwrap` is called
     */
    event Unwrap(uint256 amount, uint256 unwrapped, bytes data);

    /**
     * @dev Emitted every time `claim` is called
     */
    event Claim(address indexed strategy, address[] tokens, uint256[] amounts, bytes data);

    /**
     * @dev Emitted every time `join` is called
     */
    event Join(
        address indexed strategy,
        address[] tokensIn,
        uint256[] amountsIn,
        address[] tokensOut,
        uint256[] amountsOut,
        uint256 value,
        uint256 slippage,
        bytes data
    );

    /**
     * @dev Emitted every time `exit` is called
     */
    event Exit(
        address indexed strategy,
        address[] tokensIn,
        uint256[] amountsIn,
        address[] tokensOut,
        uint256[] amountsOut,
        uint256 value,
        uint256[] fees,
        uint256 slippage,
        bytes data
    );

    /**
     * @dev Emitted every time `swap` is called
     */
    event Swap(
        uint8 indexed source,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut,
        uint256 minAmountOut,
        uint256 fee,
        bytes data
    );

    /**
     * @dev Tells a strategy is allowed or not
     * @param strategy Address of the strategy being queried
     */
    function isStrategyAllowed(address strategy) external view returns (bool);

    /**
     * @dev Tells the invested value for a strategy
     * @param strategy Address of the strategy querying the invested value of
     */
    function investedValue(address strategy) external view returns (uint256);

    /**
     * @dev Tells the last value accrued for a strategy. Note this value can be outdated.
     * @param strategy Address of the strategy querying the last value of
     */
    function lastValue(address strategy) external view returns (uint256);

    /**
     * @dev Tells the price oracle associated to a Smart Vault
     */
    function priceOracle() external view returns (address);

    /**
     * @dev Tells the swap connector associated to a Smart Vault
     */
    function swapConnector() external view returns (address);

    /**
     * @dev Tells the address where fees will be deposited
     */
    function feeCollector() external view returns (address);

    /**
     * @dev Tells the withdraw fee configuration
     */
    function withdrawFee()
        external
        view
        returns (uint256 pct, uint256 cap, address token, uint256 period, uint256 totalCharged, uint256 nextResetTime);

    /**
     * @dev Tells the performance fee configuration
     */
    function performanceFee()
        external
        view
        returns (uint256 pct, uint256 cap, address token, uint256 period, uint256 totalCharged, uint256 nextResetTime);

    /**
     * @dev Tells the swap fee configuration
     */
    function swapFee()
        external
        view
        returns (uint256 pct, uint256 cap, address token, uint256 period, uint256 totalCharged, uint256 nextResetTime);

    /**
     * @dev Tells the address of the wrapped native token
     */
    function wrappedNativeToken() external view returns (address);

    /**
     * @dev Sets a new strategy as allowed or not for a Smart Vault
     * @param strategy Address of the strategy to be set
     * @param allowed Whether the strategy is allowed or not
     */
    function setStrategy(address strategy, bool allowed) external;

    /**
     * @dev Sets a new price oracle to a Smart Vault
     * @param newPriceOracle Address of the new price oracle to be set
     */
    function setPriceOracle(address newPriceOracle) external;

    /**
     * @dev Sets a new swap connector to a Smart Vault
     * @param newSwapConnector Address of the new swap connector to be set
     */
    function setSwapConnector(address newSwapConnector) external;

    /**
     * @dev Sets a new fee collector
     * @param newFeeCollector Address of the new fee collector to be set
     */
    function setFeeCollector(address newFeeCollector) external;

    /**
     * @dev Sets a new withdraw fee configuration
     * @param pct Withdraw fee percentage to be set
     * @param cap New maximum amount of withdraw fees to be charged per period
     * @param token Address of the token cap to be set
     * @param period New cap period length in seconds for the withdraw fee
     */
    function setWithdrawFee(uint256 pct, uint256 cap, address token, uint256 period) external;

    /**
     * @dev Sets a new performance fee configuration
     * @param pct Performance fee percentage to be set
     * @param cap New maximum amount of performance fees to be charged per period
     * @param token Address of the token cap to be set
     * @param period New cap period length in seconds for the performance fee
     */
    function setPerformanceFee(uint256 pct, uint256 cap, address token, uint256 period) external;

    /**
     * @dev Sets a new swap fee configuration
     * @param pct Swap fee percentage to be set
     * @param cap New maximum amount of swap fees to be charged per period
     * @param token Address of the token cap to be set
     * @param period New cap period length in seconds for the swap fee
     */
    function setSwapFee(uint256 pct, uint256 cap, address token, uint256 period) external;

    /**
     * @dev Tells the price of a token (base) in a given quote
     * @param base Token to rate
     * @param quote Token used for the price rate
     */
    function getPrice(address base, address quote) external view returns (uint256);

    /**
     * @dev Execute an arbitrary call from a Smart Vault
     * @param target Address where the call will be sent
     * @param callData Calldata to be used for the call
     * @param value Value in wei that will be attached to the call
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return result Call response if it was successful, otherwise it reverts
     */
    function call(address target, bytes memory callData, uint256 value, bytes memory data)
        external
        returns (bytes memory result);

    /**
     * @dev Collect tokens from a sender to a Smart Vault
     * @param token Address of the token to be collected
     * @param from Address where the tokens will be transfer from
     * @param amount Amount of tokens to be transferred
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return collected Amount of tokens assigned to the Smart Vault
     */
    function collect(address token, address from, uint256 amount, bytes memory data)
        external
        returns (uint256 collected);

    /**
     * @dev Withdraw tokens to an external account
     * @param token Address of the token to be withdrawn
     * @param amount Amount of tokens to withdraw
     * @param recipient Address where the tokens will be transferred to
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return withdrawn Amount of tokens transferred to the recipient address
     */
    function withdraw(address token, uint256 amount, address recipient, bytes memory data)
        external
        returns (uint256 withdrawn);

    /**
     * @dev Wrap an amount of native tokens to the wrapped ERC20 version of it
     * @param amount Amount of native tokens to be wrapped
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return wrapped Amount of tokens wrapped
     */
    function wrap(uint256 amount, bytes memory data) external returns (uint256 wrapped);

    /**
     * @dev Unwrap an amount of wrapped native tokens
     * @param amount Amount of wrapped native tokens to unwrapped
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return unwrapped Amount of tokens unwrapped
     */
    function unwrap(uint256 amount, bytes memory data) external returns (uint256 unwrapped);

    /**
     * @dev Claim strategy rewards
     * @param strategy Address of the strategy to claim rewards
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return tokens Addresses of the tokens received as rewards
     * @return amounts Amounts of the tokens received as rewards
     */
    function claim(address strategy, bytes memory data)
        external
        returns (address[] memory tokens, uint256[] memory amounts);

    /**
     * @dev Join a strategy with an amount of tokens
     * @param strategy Address of the strategy to join
     * @param tokensIn List of token addresses to join with
     * @param amountsIn List of token amounts to join with
     * @param slippage Slippage that will be used to compute the join
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return tokensOut List of token addresses received after the join
     * @return amountsOut List of token amounts received after the join
     */
    function join(
        address strategy,
        address[] memory tokensIn,
        uint256[] memory amountsIn,
        uint256 slippage,
        bytes memory data
    ) external returns (address[] memory tokensOut, uint256[] memory amountsOut);

    /**
     * @dev Exit a strategy
     * @param strategy Address of the strategy to exit
     * @param tokensIn List of token addresses to exit with
     * @param amountsIn List of token amounts to exit with
     * @param slippage Slippage that will be used to compute the exit
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return tokensOut List of token addresses received after the exit
     * @return amountsOut List of token amounts received after the exit
     */
    function exit(
        address strategy,
        address[] memory tokensIn,
        uint256[] memory amountsIn,
        uint256 slippage,
        bytes memory data
    ) external returns (address[] memory tokensOut, uint256[] memory amountsOut);

    /**
     * @dev Swaps two tokens
     * @param source Source to request the swap. It depends on the Swap Connector attached to a Smart Vault.
     * @param tokenIn Token being sent
     * @param tokenOut Token being received
     * @param amountIn Amount of tokenIn being swapped
     * @param limitType Swap limit to be applied: slippage or min amount out
     * @param limitAmount Amount of the swap limit to be applied depending on limitType
     * @param data Extra data that may enable or not different behaviors depending on the implementation
     * @return amountOut Received amount of tokens out
     */
    function swap(
        uint8 source,
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        SwapLimit limitType,
        uint256 limitAmount,
        bytes memory data
    ) external returns (uint256 amountOut);
}


// File @openzeppelin/contracts/token/ERC20/[email protected]


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}


// File @mimic-fi/v2-helpers/contracts/auth/[email protected]


pragma solidity ^0.8.0;

/**
 * @title Authorizer
 * @dev Authorization module to be used by contracts that need to implement permissions for their methods.
 * It provides a permissions model to list who is allowed to call what function in a contract. And only accounts
 * authorized to manage those permissions are the ones that are allowed to authorize or unauthorize accounts.
 */
contract Authorizer is IAuthorizer {
    // Constant used to denote that a permission is open to anyone
    address public constant ANY_ADDRESS = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF);

    // Internal mapping to tell who is allowed to do what indexed by (account, function selector)
    mapping (address => mapping (bytes4 => bool)) private authorized;

    /**
     * @dev Modifier that should be used to tag protected functions
     */
    modifier auth() {
        _authenticate(msg.sender, msg.sig);
        _;
    }

    /**
     * @dev Tells whether someone is allowed to call a function or not. It returns true if it's allowed to anyone.
     * @param who Address asking permission for
     * @param what Function selector asking permission for
     */
    function isAuthorized(address who, bytes4 what) public view override returns (bool) {
        return authorized[ANY_ADDRESS][what] || authorized[who][what];
    }

    /**
     * @dev Authorizes someone to call a function. Sender must be authorize to do so.
     * @param who Address to be authorized
     * @param what Function selector to be granted
     */
    function authorize(address who, bytes4 what) external override auth {
        _authorize(who, what);
    }

    /**
     * @dev Unauthorizes someone to call a function. Sender must be authorize to do so.
     * @param who Address to be unauthorized
     * @param what Function selector to be revoked
     */
    function unauthorize(address who, bytes4 what) external override auth {
        _unauthorize(who, what);
    }

    /**
     * @dev Internal function to authenticate someone over a function.
     * It reverts if the given account is not authorized to call the requested function.
     * @param who Address to be authenticated
     * @param what Function selector to be authenticated
     */
    function _authenticate(address who, bytes4 what) internal view {
        require(isAuthorized(who, what), 'AUTH_SENDER_NOT_ALLOWED');
    }

    /**
     * @dev Internal function to authorize someone to call a function
     * @param who Address to be authorized
     * @param what Function selector to be granted
     */
    function _authorize(address who, bytes4 what) internal {
        authorized[who][what] = true;
        emit Authorized(who, what);
    }

    /**
     * @dev Internal function to unauthorize someone to call a function
     * @param who Address to be unauthorized
     * @param what Function selector to be revoked
     */
    function _unauthorize(address who, bytes4 what) internal {
        authorized[who][what] = false;
        emit Unauthorized(who, what);
    }
}


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library 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
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


// File @openzeppelin/contracts/proxy/utils/[email protected]


// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original
     * initialization step. This is essential to configure modules that are added through upgrades and that require
     * initialization.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized < type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }
}


// File @mimic-fi/v2-registry/contracts/registry/[email protected]


pragma solidity >=0.8.0;

/**
 * @title IRegistry
 * @dev Registry interface, it must follow the IAuthorizer interface.
 */
interface IRegistry is IAuthorizer {
    /**
     * @dev Emitted every time a new implementation is registered
     */
    event Registered(bytes32 indexed namespace, address indexed implementation, bool stateless);

    /**
     * @dev Emitted every time an implementation is deprecated
     */
    event Deprecated(bytes32 indexed namespace, address indexed implementation);

    /**
     * @dev Emitted every time an implementation is cloned
     */
    event Cloned(bytes32 indexed namespace, address indexed implementation, address instance, bytes initResult);

    /**
     * @dev Tells the implementation associated to a contract instance
     * @param instance Address of the instance to request it's implementation
     */
    function implementationOf(address instance) external view returns (address);

    /**
     * @dev Tells the data of an implementation:
     * @param implementation Address of the implementation to request it's data
     */
    function implementationData(address implementation)
        external
        view
        returns (bool stateless, bool deprecated, bytes32 namespace);

    /**
     * @dev Tells if a specific implementation is registered under a certain namespace and it's not deprecated
     * @param namespace Namespace asking for
     * @param implementation Address of the implementation to be checked
     */
    function isActive(bytes32 namespace, address implementation) external view returns (bool);

    /**
     * @dev Registers a new implementation for a given namespace
     * @param namespace Namespace to be used for the implementation
     * @param implementation Address of the implementation to be registered
     * @param stateless Whether the implementation is stateless or not
     */
    function register(bytes32 namespace, address implementation, bool stateless) external;

    /**
     * @dev Deprecates a registered implementation
     * @param implementation Address of the implementation to be deprecated
     */
    function deprecate(address implementation) external;

    /**
     * @dev Clones a registered implementation
     * @param implementation Address of the implementation to be cloned
     * @param initializeData Arbitrary data to be sent after deployment
     * @return instance Address of the new instance created
     */
    function clone(address implementation, bytes memory initializeData) external returns (address);
}


// File @mimic-fi/v2-registry/contracts/implementations/[email protected]


pragma solidity ^0.8.0;


/**
 * @title BaseImplementation
 * @dev This implementation contract comes with an immutable reference to an implementations registry where it should
 * be registered as well (checked during initialization). It allows requesting new instances of other registered
 * implementations to as another safety check to make sure valid instances are referenced in case it's needed.
 */
abstract contract BaseImplementation is IImplementation {
    // Immutable implementations registry reference
    address public immutable override registry;

    /**
     * @dev Creates a new BaseImplementation
     * @param _registry Address of the Mimic Registry where dependencies will be validated against
     */
    constructor(address _registry) {
        registry = _registry;
    }

    /**
     * @dev Internal function to validate a new dependency that must be registered as stateless.
     * It checks the new dependency is registered, not deprecated, and stateless.
     * @param dependency New stateless dependency to be set
     */
    function _validateStatelessDependency(address dependency) internal view {
        require(_validateDependency(dependency), 'DEPENDENCY_NOT_STATELESS');
    }

    /**
     * @dev Internal function to validate a new dependency that cannot be registered as stateless.
     * It checks the new dependency is registered, not deprecated, and not stateful.
     * @param dependency New stateful dependency to be set
     */
    function _validateStatefulDependency(address dependency) internal view {
        require(!_validateDependency(dependency), 'DEPENDENCY_NOT_STATEFUL');
    }

    /**
     * @dev Internal function to validate a new dependency. It checks the dependency is registered and not deprecated.
     * @param dependency New dependency to be set
     * @return Whether the dependency is stateless or not
     */
    function _validateDependency(address dependency) private view returns (bool) {
        // If there is an implementation registered for the dependency, check the dependency as an instance.
        // Otherwise, treat the dependency as an implementation.
        address dependencyImplementation = IRegistry(registry).implementationOf(dependency);
        address implementation = dependencyImplementation != address(0) ? dependencyImplementation : dependency;

        (bool stateless, bool deprecated, bytes32 namespace) = IRegistry(registry).implementationData(implementation);
        require(namespace != bytes32(0), 'DEPENDENCY_NOT_REGISTERED');
        require(!deprecated, 'DEPENDENCY_DEPRECATED');
        return stateless;
    }
}


// File @mimic-fi/v2-registry/contracts/implementations/[email protected]


pragma solidity ^0.8.0;

/**
 * @title BaseAuthorizedImplementation
 * @dev BaseImplementation using the Authorizer mixin. Base implementations that want to use the Authorizer
 * permissions mechanism should inherit from this contract instead.
 */
abstract contract BaseAuthorizedImplementation is BaseImplementation, Authorizer {
    /**
     * @dev Creates a new BaseAuthorizedImplementation
     * @param admin Address to be granted authorize and unauthorize permissions
     * @param registry Address of the Mimic Registry
     */
    constructor(address admin, address registry) BaseImplementation(registry) {
        _authorize(admin, Authorizer.authorize.selector);
        _authorize(admin, Authorizer.unauthorize.selector);
    }
}


// File @mimic-fi/v2-smart-vaults-base/contracts/actions/[email protected]


pragma solidity >=0.8.0;


/**
 * @title IAction
 * @dev Action interface it must follow the IAuthorizer interface
 */
interface IAction is IAuthorizer {
    /**
     * @dev Emitted every time an action is executed
     */
    event Executed();

    /**
     * @dev Tells the address of the Smart Vault tied to it, it cannot be changed
     */
    function smartVault() external view returns (ISmartVault);
}


// File @mimic-fi/v2-helpers/contracts/utils/[email protected]


pragma solidity ^0.8.0;

/**
 * @title Denominations
 * @dev Provides a list of ground denominations for those tokens that cannot be represented by an ERC20.
 * For now, the only needed is the native token that could be ETH, MATIC, or other depending on the layer being operated.
 */
library Denominations {
    address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    function isNativeToken(address token) internal pure returns (bool) {
        return token == NATIVE_TOKEN;
    }
}


// File @mimic-fi/v2-smart-vaults-base/contracts/actions/[email protected]


pragma solidity ^0.8.0;




/**
 * @title BaseAction
 * @dev Simple action implementation with a Smart Vault reference and using the Authorizer mixin
 */
contract BaseAction is IAction, BaseAuthorizedImplementation {
    bytes32 public constant override NAMESPACE = keccak256('ACTION');

    // Smart Vault reference
    ISmartVault public override smartVault;

    /**
     * @dev Emitted every time a new smart vault is set
     */
    event SmartVaultSet(address indexed smartVault);

    /**
     * @dev Creates a new BaseAction
     * @param admin Address to be granted authorize and unauthorize permissions
     * @param registry Address of the Mimic Registry
     */
    constructor(address admin, address registry) BaseAuthorizedImplementation(admin, registry) {
        // solhint-disable-previous-line no-empty-blocks
    }

    /**
     * @dev Sets the Smart Vault tied to the Action. Sender must be authorized. It can be set only once.
     * @param newSmartVault Address of the smart vault to be set
     */
    function setSmartVault(address newSmartVault) external auth {
        require(address(smartVault) == address(0), 'SMART_VAULT_ALREADY_SET');
        _validateStatefulDependency(newSmartVault);
        smartVault = ISmartVault(newSmartVault);
        emit SmartVaultSet(newSmartVault);
    }

    function _balanceOf(address token) internal view returns (uint256) {
        bool isNative = Denominations.isNativeToken(token);
        return isNative ? address(smartVault).balance : IERC20(token).balanceOf(address(smartVault));
    }

    function _isWrappedOrNativeToken(address token) internal view returns (bool) {
        return Denominations.isNativeToken(token) || token == smartVault.wrappedNativeToken();
    }
}


// File @mimic-fi/v2-helpers/contracts/math/[email protected]


pragma solidity ^0.8.0;

/**
 * @title FixedPoint
 * @dev Math library to operate with fixed point values with 18 decimals
 */
library FixedPoint {
    // 1 in fixed point value: 18 decimal places
    uint256 internal constant ONE = 1e18;

    /**
     * @dev Multiplies two fixed point numbers rounding down
     */
    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            uint256 product = a * b;
            require(a == 0 || product / a == b, 'MUL_OVERFLOW');
            return product / ONE;
        }
    }

    /**
     * @dev Multiplies two fixed point numbers rounding up
     */
    function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            uint256 product = a * b;
            require(a == 0 || product / a == b, 'MUL_OVERFLOW');
            return product == 0 ? 0 : (((product - 1) / ONE) + 1);
        }
    }

    /**
     * @dev Divides two fixed point numbers rounding down
     */
    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            require(b != 0, 'ZERO_DIVISION');
            if (a == 0) return 0;
            uint256 aInflated = a * ONE;
            require(aInflated / a == ONE, 'DIV_INTERNAL');
            return aInflated / b;
        }
    }

    /**
     * @dev Divides two fixed point numbers rounding up
     */
    function divUp(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            require(b != 0, 'ZERO_DIVISION');
            if (a == 0) return 0;
            uint256 aInflated = a * ONE;
            require(aInflated / a == ONE, 'DIV_INTERNAL');
            return ((aInflated - 1) / b) + 1;
        }
    }
}


// File @mimic-fi/v2-smart-vaults-base/contracts/actions/[email protected]


pragma solidity ^0.8.0;

/**
 * @title TokenThresholdAction
 * @dev Action that offers a token threshold limit. It can be used for minimum swap amounts, or minimum withdrawal
 * amounts, etc. This type of action does not require any specific permission on the Smart Vault.
 */
abstract contract TokenThresholdAction is BaseAction {
    using FixedPoint for uint256;

    address public thresholdToken;
    uint256 public thresholdAmount;

    event ThresholdSet(address indexed token, uint256 amount);

    /**
     * @dev Sets a new threshold configuration. Sender must be authorized.
     * @param token New token threshold to be set
     * @param amount New amount threshold to be set
     */
    function setThreshold(address token, uint256 amount) external auth {
        thresholdToken = token;
        thresholdAmount = amount;
        emit ThresholdSet(token, amount);
    }

    /**
     * @dev Internal function to check the set threshold
     * @param token Token address of the given amount to evaluate the threshold
     * @param amount Amount of tokens to validate the threshold
     */
    function _passesThreshold(address token, uint256 amount) internal view returns (bool) {
        uint256 price = smartVault.getPrice(token, thresholdToken);
        // Result balance is rounded down to make sure we always match at least the threshold
        return amount.mulDown(price) >= thresholdAmount;
    }

    /**
     * @dev Internal function to validate the set threshold
     * @param token Token address of the given amount to evaluate the threshold
     * @param amount Amount of tokens to validate the threshold
     */
    function _validateThreshold(address token, uint256 amount) internal view {
        require(_passesThreshold(token, amount), 'MIN_THRESHOLD_NOT_MET');
    }
}


// File @mimic-fi/v2-smart-vaults-base/contracts/actions/[email protected]


pragma solidity ^0.8.0;


/**
 * @title RelayedAction
 * @dev Action that offers a relayed mechanism to allow reimbursing tx costs after execution in any ERC20 token.
 * This type of action at least require having withdraw permissions from the Smart Vault tied to it.
 */
abstract contract RelayedAction is BaseAction {
    using FixedPoint for uint256;

    // Base gas amount charged to cover default amounts
    // solhint-disable-next-line func-name-mixedcase
    function BASE_GAS() external view virtual returns (uint256);

    // Note to be used to mark tx cost payments
    bytes private constant REDEEM_GAS_NOTE = bytes('RELAYER');

    // Internal variable used to allow a better developer experience to reimburse tx gas cost
    uint256 internal _initialGas;

    // Allows relaying transactions even if there is not enough balance in the Smart Vault to pay for the tx gas cost
    bool public isPermissiveModeActive;

    // Gas price limit, if surpassed it wont relay the transaction
    uint256 public gasPriceLimit;

    // Total cost limit expressed in `payingGasToken`, if surpassed it wont relay the transaction
    uint256 public totalCostLimit;

    // Address of the ERC20 token that will be used to pay the total tx cost
    address public payingGasToken;

    // List of allowed relayers indexed by address
    mapping (address => bool) public isRelayer;

    /**
     * @dev Emitted every time the permissive mode is changed
     */
    event PermissiveModeSet(bool active);

    /**
     * @dev Emitted every time the relayers list is changed
     */
    event RelayerSet(address indexed relayer, bool allowed);

    /**
     * @dev Emitted every time the relayer limits are set
     */
    event LimitsSet(uint256 gasPriceLimit, uint256 totalCostLimit, address payingGasToken);

    /**
     * @dev Modifier that can be used to reimburse the gas cost of the tagged function
     */
    modifier redeemGas() {
        _beforeCall();
        _;
        _afterCall();
    }

    /**
     * @dev Sets the relayed action permissive mode. If active,  relayer address. Sender must be authorized.
     * @param active Whether the permissive mode should be active or not
     */
    function setPermissiveMode(bool active) external auth {
        isPermissiveModeActive = active;
        emit PermissiveModeSet(active);
    }

    /**
     * @dev Sets a relayer address. Sender must be authorized.
     * @param relayer Address of the relayer to be set
     * @param allowed Whether it should be allowed or not
     */
    function setRelayer(address relayer, bool allowed) external auth {
        isRelayer[relayer] = allowed;
        emit RelayerSet(relayer, allowed);
    }

    /**
     * @dev Sets the relayer limits. Sender must be authorized.
     * @param _gasPriceLimit New gas price limit to be set
     * @param _totalCostLimit New total cost limit to be set
     * @param _payingGasToken New paying gas token to be set
     */
    function setLimits(uint256 _gasPriceLimit, uint256 _totalCostLimit, address _payingGasToken) external auth {
        require(_payingGasToken != address(0), 'PAYING_GAS_TOKEN_ZERO');
        gasPriceLimit = _gasPriceLimit;
        totalCostLimit = _totalCostLimit;
        payingGasToken = _payingGasToken;
        emit LimitsSet(_gasPriceLimit, _totalCostLimit, _payingGasToken);
    }

    /**
     * @dev Internal before call hook where limit validations are checked
     */
    function _beforeCall() internal {
        _initialGas = gasleft();
        require(isRelayer[msg.sender], 'SENDER_NOT_RELAYER');
        uint256 limit = gasPriceLimit;
        require(limit == 0 || tx.gasprice <= limit, 'GAS_PRICE_ABOVE_LIMIT');
    }

    /**
     * @dev Internal after call hook where tx cost is reimburse
     */
    function _afterCall() internal {
        uint256 totalGas = _initialGas - gasleft();
        uint256 totalCostNative = (totalGas + RelayedAction(this).BASE_GAS()) * tx.gasprice;

        uint256 limit = totalCostLimit;
        address payingToken = payingGasToken;
        // Total cost is rounded down to make sure we always match at least the threshold
        uint256 totalCostToken = totalCostNative.mulDown(_getPayingGasTokenPrice(payingToken));
        require(limit == 0 || totalCostToken <= limit, 'TX_COST_ABOVE_LIMIT');

        if (_shouldTryRedeemFromSmartVault(payingToken, totalCostToken)) {
            smartVault.withdraw(payingToken, totalCostToken, smartVault.feeCollector(), REDEEM_GAS_NOTE);
        }

        delete _initialGas;
    }

    /**
     * @dev Internal function to fetch the paying gas token rate from the Smart Vault's price oracle
     */
    function _getPayingGasTokenPrice(address token) private view returns (uint256) {
        bool isUsingNativeToken = _isWrappedOrNativeToken(token);
        return isUsingNativeToken ? FixedPoint.ONE : smartVault.getPrice(smartVault.wrappedNativeToken(), token);
    }

    /**
     * @dev Internal function to tell if the relayed action should try to redeem the gas cost from the Smart Vault
     * @param token Address of the token to pay the relayed gas cost
     * @param amount Amount of tokens to pay for the relayed gas cost
     */
    function _shouldTryRedeemFromSmartVault(address token, uint256 amount) private view returns (bool) {
        if (!isPermissiveModeActive) return true;
        return _balanceOf(token) >= amount;
    }
}


// File @mimic-fi/v2-smart-vaults-base/contracts/actions/[email protected]


pragma solidity ^0.8.0;

/**
 * @title Withdrawal action
 * @dev Action that offers a recipient address where funds can be withdrawn. This type of action at least require
 * having withdraw permissions from the Smart Vault tied to it.
 */
abstract contract WithdrawalAction is BaseAction {
    // Address where tokens will be transferred to
    address public recipient;

    /**
     * @dev Emitted every time the recipient is set
     */
    event RecipientSet(address indexed recipient);

    /**
     * @dev Sets the recipient address. Sender must be authorized.
     * @param newRecipient Address of the new recipient to be set
     */
    function setRecipient(address newRecipient) external auth {
        require(newRecipient != address(0), 'RECIPIENT_ZERO');
        recipient = newRecipient;
        emit RecipientSet(newRecipient);
    }

    /**
     * @dev Internal function to withdraw all the available balance of a token from the Smart Vault to the recipient
     * @param token Address of the token to be withdrawn
     */
    function _withdraw(address token) internal {
        uint256 balance = _balanceOf(token);
        _withdraw(token, balance);
    }

    /**
     * @dev Internal function to withdraw a specific amount of a token from the Smart Vault to the recipient
     * @param token Address of the token to be withdrawn
     * @param amount Amount of tokens to be withdrawn
     */
    function _withdraw(address token, uint256 amount) internal {
        smartVault.withdraw(token, amount, recipient, new bytes(0));
    }
}


// File contracts/actions/Withdrawer.sol


pragma solidity ^0.8.0;




contract Withdrawer is BaseAction, RelayedAction, TokenThresholdAction, WithdrawalAction {
    // Base gas amount charged to cover gas payment
    uint256 public constant override BASE_GAS = 115e3;

    event TokenSet(address indexed token);

    address public token;

    constructor(address admin, address registry) BaseAction(admin, registry) {
        // solhint-disable-previous-line no-empty-blocks
    }

    function canExecute() external view returns (bool) {
        return _passesThreshold(token, _balanceOf(token));
    }

    function setToken(address newToken) external auth {
        token = newToken;
        emit TokenSet(newToken);
    }

    function call() external auth {
        isRelayer[msg.sender] ? _relayedCall() : _call();
        _withdraw(token);
    }

    function _relayedCall() internal redeemGas {
        _call();
    }

    function _call() internal {
        _validateThreshold(token, _balanceOf(token));
        emit Executed();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"Authorized","type":"event"},{"anonymous":false,"inputs":[],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"gasPriceLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalCostLimit","type":"uint256"},{"indexed":false,"internalType":"address","name":"payingGasToken","type":"address"}],"name":"LimitsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"PermissiveModeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"RecipientSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"RelayerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"smartVault","type":"address"}],"name":"SmartVaultSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"TokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"Unauthorized","type":"event"},{"inputs":[],"name":"ANY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAMESPACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"authorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"call","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canExecute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasPriceLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPermissiveModeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRelayer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payingGasToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasPriceLimit","type":"uint256"},{"internalType":"uint256","name":"_totalCostLimit","type":"uint256"},{"internalType":"address","name":"_payingGasToken","type":"address"}],"name":"setLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"active","type":"bool"}],"name":"setPermissiveMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRecipient","type":"address"}],"name":"setRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"relayer","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSmartVault","type":"address"}],"name":"setSmartVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newToken","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"smartVault","outputs":[{"internalType":"contract ISmartVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thresholdAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thresholdToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCostLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"unauthorize","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162001e9c38038062001e9c833981016040819052620000349162000105565b6001600160601b0319606082901b16608052818181816200005d826324cfc3cf60e21b6200007c565b6200007082633323521b60e11b6200007c565b5050505050506200013c565b6001600160a01b0382166000818152602081815260408083206001600160e01b0319861680855290835292819020805460ff19166001179055519182527f7f06c1c34ad47198873da9dcde2e40904035d41b23da3a9132df674a75022df7910160405180910390a25050565b80516001600160a01b03811681146200010057600080fd5b919050565b6000806040838503121562000118578182fd5b6200012383620000e8565b91506200013360208401620000e8565b90509250929050565b60805160601c611d3362000169600039600081816103450152818161106001526111500152611d336000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80636646a436116100ee5780639d87999011610097578063d9972b9611610071578063d9972b96146103c3578063ecd8dc3a146103d6578063f5aabb1a146103e9578063fc0c546a14610409576101ae565b80639d87999014610383578063b42953e714610396578063c66197bf146103b6576101ae565b80637b103999116100c85780637b10399914610340578063933f0f3c14610367578063961a929c1461037a576101ae565b80636646a4361461030557806366d003ac1461031857806378b9033714610338576101ae565b8063389aa3421161015b57806344ba1fca1161013557806344ba1fca146102785780634fd49efd1461029f5780635247c1ca146102bf578063541d5548146102d2576101ae565b8063389aa3421461021b5780633bbed4a0146102255780633f81a19214610238576101ae565b8063144fa6d71161018c578063144fa6d7146101f757806328b5e32b1461020a57806328f4dbb614610212576101ae565b806301cfdd29146101b35780630d0eda8b146101cf57806313e3b57c146101e4575b600080fd5b6101bc60055481565b6040519081526020015b60405180910390f35b6101e26101dd366004611ae2565b610429565b005b6101e26101f23660046119f6565b6104bc565b6101e26102053660046119f6565b6105cd565b6101e261066a565b6101bc60095481565b6101bc6201c13881565b6101e26102333660046119f6565b6106e8565b61025373ffffffffffffffffffffffffffffffffffffffff81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101bc7ff66b632ae3b479ef109dee46eb319414289a8426a08b64d81aad232941f9d22a81565b6001546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6101e26102cd366004611b58565b6107e8565b6102f56102e03660046119f6565b60076020526000908152604090205460ff1681565b60405190151581526020016101c6565b6101e2610313366004611a66565b61090d565b600a546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6102f5610949565b6102537f000000000000000000000000000000000000000000000000000000000000000081565b6101e2610375366004611a66565b61097c565b6101bc60045481565b6101e2610391366004611ab7565b6109b4565b6008546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6003546102f59060ff1681565b6102f56103d1366004611a66565b610a62565b6101e26103e4366004611a2e565b610b1a565b6006546102539073ffffffffffffffffffffffffffffffffffffffff1681565b600b546102539073ffffffffffffffffffffffffffffffffffffffff1681565b610457336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527fe8693871decef495d3ddb20b4c2fdc4734c37f8ed6f875fbe1e6a718adbf0fdd9060200160405180910390a150565b6104ea336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b60015473ffffffffffffffffffffffffffffffffffffffff16156105555760405162461bcd60e51b815260206004820152601760248201527f534d4152545f5641554c545f414c52454144595f53455400000000000000000060448201526064015b60405180910390fd5b61055e81610c21565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f6a7abc646862eeb16d8760c0c56dff37a2d2c6b012a3419910005e57e503a08790600090a250565b6105fb336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fa07c91c183e42229e705a9795a1c06d76528b673788b849597364528c96eefb790600090a250565b610698336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b3360009081526007602052604090205460ff166106bc576106b7610c7a565b6106c4565b6106c4610cd0565b600b546106e69073ffffffffffffffffffffffffffffffffffffffff16610ce8565b565b610716336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff81166107795760405162461bcd60e51b815260206004820152600e60248201527f524543495049454e545f5a45524f000000000000000000000000000000000000604482015260640161054c565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b610816336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff81166108795760405162461bcd60e51b815260206004820152601560248201527f504159494e475f4741535f544f4b454e5f5a45524f0000000000000000000000604482015260640161054c565b60048390556005829055600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040805185815260208101859052908101919091527f7bd6a5fc2b1371f48a3ea03997aebaa84a60fb8d4e4a970b9f98a1b4c3d4bb889060600160405180910390a1505050565b61093b336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b6109458282610cff565b5050565b600b546000906109779073ffffffffffffffffffffffffffffffffffffffff1661097281610da4565b610ea3565b905090565b6109aa336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b6109458282610f6e565b6109e2336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915560098290556040518281527ff7e18aa0532694077d6fc7df02e85d86b91ba964f958d1949d45c5776d36eb6e906020015b60405180910390a25050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f50c7a3d1a23c7ff4a61d37c3f2c4aeb36cf60b43ee893723db201d3eb941cbad602052604081205460ff1680610b11575073ffffffffffffffffffffffffffffffffffffffff83166000908152602081815260408083207fffffffff000000000000000000000000000000000000000000000000000000008616845290915290205460ff165b90505b92915050565b610b48336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff821660008181526007602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527fee42947bc760229eeff964017ac68eddb00ba98b0defcd90a1bc85a5afceb0579101610a56565b610bd58282610a62565b6109455760405162461bcd60e51b815260206004820152601760248201527f415554485f53454e4445525f4e4f545f414c4c4f574544000000000000000000604482015260640161054c565b610c2a81611016565b15610c775760405162461bcd60e51b815260206004820152601760248201527f444550454e44454e43595f4e4f545f535441544546554c000000000000000000604482015260640161054c565b50565b600b54610ca59073ffffffffffffffffffffffffffffffffffffffff16610ca081610da4565b611277565b6040517f68f46c45a243a0e9065a97649faf9a5afe1692f2679e650c2f853b9cd734cc0e90600090a1565b610cd86112cd565b610ce0610c7a565b6106e661138c565b6000610cf382610da4565b90506109458282611636565b73ffffffffffffffffffffffffffffffffffffffff82166000818152602081815260408083207fffffffff0000000000000000000000000000000000000000000000000000000086168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055519182527fa2e97b9eea8d1168700e334304edd057dff89c0384ca6f920c73cc3e48c8e5239101610a56565b600073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480610e81576001546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908416906370a08231906024015b60206040518083038186803b158015610e4457600080fd5b505afa158015610e58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7c9190611b40565b610e9c565b60015473ffffffffffffffffffffffffffffffffffffffff16315b9392505050565b6001546008546040517fac41865a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015291821660248201526000928392169063ac41865a9060440160206040518083038186803b158015610f1c57600080fd5b505afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f549190611b40565b600954909150610f6484836116f9565b1015949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166000818152602081815260408083207fffffffff0000000000000000000000000000000000000000000000000000000086168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055519182527f7f06c1c34ad47198873da9dcde2e40904035d41b23da3a9132df674a75022df79101610a56565b6040517f8b4872b800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015260009182917f00000000000000000000000000000000000000000000000000000000000000001690638b4872b89060240160206040518083038186803b1580156110a257600080fd5b505afa1580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190611a12565b9050600073ffffffffffffffffffffffffffffffffffffffff82166110ff5783611101565b815b6040517f9235dcf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8083166004830152919250600091829182917f00000000000000000000000000000000000000000000000000000000000000001690639235dcf89060240160606040518083038186803b15801561119257600080fd5b505afa1580156111a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ca9190611afe565b919450925090508061121e5760405162461bcd60e51b815260206004820152601960248201527f444550454e44454e43595f4e4f545f5245474953544552454400000000000000604482015260640161054c565b811561126c5760405162461bcd60e51b815260206004820152601560248201527f444550454e44454e43595f444550524543415445440000000000000000000000604482015260640161054c565b509095945050505050565b6112818282610ea3565b6109455760405162461bcd60e51b815260206004820152601560248201527f4d494e5f5448524553484f4c445f4e4f545f4d45540000000000000000000000604482015260640161054c565b5a6002553360009081526007602052604090205460ff166113305760405162461bcd60e51b815260206004820152601260248201527f53454e4445525f4e4f545f52454c415945520000000000000000000000000000604482015260640161054c565b6004548015806113405750803a11155b610c775760405162461bcd60e51b815260206004820152601560248201527f4741535f50524943455f41424f56455f4c494d49540000000000000000000000604482015260640161054c565b60005a60025461139c9190611c87565b905060003a3073ffffffffffffffffffffffffffffffffffffffff1663389aa3426040518163ffffffff1660e01b815260040160206040518083038186803b1580156113e757600080fd5b505afa1580156113fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141f9190611b40565b6114299084611c32565b6114339190611c4a565b6005546006549192509073ffffffffffffffffffffffffffffffffffffffff1660006114686114618361179e565b85906116f9565b90508215806114775750828111155b6114c35760405162461bcd60e51b815260206004820152601360248201527f54585f434f53545f41424f56455f4c494d495400000000000000000000000000604482015260640161054c565b6114cd82826118c5565b1561162a57600154604080517fc415b95c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691639003afee9185918591859163c415b95c91600480820192602092909190829003018186803b15801561154957600080fd5b505afa15801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190611a12565b6040518060400160405280600781526020017f52454c41594552000000000000000000000000000000000000000000000000008152506040518563ffffffff1660e01b81526004016115d69493929190611b90565b602060405180830381600087803b1580156115f057600080fd5b505af1158015611604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116289190611b40565b505b50506000600255505050565b600154600a54604080516000815260208101918290527f9003afee0000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff92831692639003afee926116a29287928792169060248101611b90565b602060405180830381600087803b1580156116bc57600080fd5b505af11580156116d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f49190611b40565b505050565b600082820283158061174057508284828161173d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b04145b61178c5760405162461bcd60e51b815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015260640161054c565b670de0b6b3a764000090049392505050565b6000806117aa836118ed565b9050806118b557600154604080517f17fcb39b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163ac41865a9183916317fcb39b91600480820192602092909190829003018186803b15801561182457600080fd5b505afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190611a12565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff91821660048201529086166024820152604401610e2c565b50670de0b6b3a764000092915050565b60035460009060ff166118da57506001610b14565b816118e484610da4565b10159392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff83161480610b145750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317fcb39b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561198a57600080fd5b505afa15801561199e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c29190611a12565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161492915050565b600060208284031215611a07578081fd5b8135610e9c81611ccd565b600060208284031215611a23578081fd5b8151610e9c81611ccd565b60008060408385031215611a40578081fd5b8235611a4b81611ccd565b91506020830135611a5b81611cef565b809150509250929050565b60008060408385031215611a78578182fd5b8235611a8381611ccd565b915060208301357fffffffff0000000000000000000000000000000000000000000000000000000081168114611a5b578182fd5b60008060408385031215611ac9578182fd5b8235611ad481611ccd565b946020939093013593505050565b600060208284031215611af3578081fd5b8135610e9c81611cef565b600080600060608486031215611b12578081fd5b8351611b1d81611cef565b6020850151909350611b2e81611cef565b80925050604084015190509250925092565b600060208284031215611b51578081fd5b5051919050565b600080600060608486031215611b6c578283fd5b83359250602084013591506040840135611b8581611ccd565b809150509250925092565b600073ffffffffffffffffffffffffffffffffffffffff80871683526020868185015281861660408501526080606085015284519150816080850152825b82811015611bea5785810182015185820160a001528101611bce565b82811115611bfb578360a084870101525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a00195945050505050565b60008219821115611c4557611c45611c9e565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c8257611c82611c9e565b500290565b600082821015611c9957611c99611c9e565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610c7757600080fd5b8015158114610c7757600080fdfea26469706673582212209e37c847ab4e248f2bf09bcade5f369d2b0b28118b6465c4ddb45fccfb0ee23264736f6c63430008030033000000000000000000000000f060ac1f9ee8fc5dfb0c24b67729e59ddcdb437300000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c80636646a436116100ee5780639d87999011610097578063d9972b9611610071578063d9972b96146103c3578063ecd8dc3a146103d6578063f5aabb1a146103e9578063fc0c546a14610409576101ae565b80639d87999014610383578063b42953e714610396578063c66197bf146103b6576101ae565b80637b103999116100c85780637b10399914610340578063933f0f3c14610367578063961a929c1461037a576101ae565b80636646a4361461030557806366d003ac1461031857806378b9033714610338576101ae565b8063389aa3421161015b57806344ba1fca1161013557806344ba1fca146102785780634fd49efd1461029f5780635247c1ca146102bf578063541d5548146102d2576101ae565b8063389aa3421461021b5780633bbed4a0146102255780633f81a19214610238576101ae565b8063144fa6d71161018c578063144fa6d7146101f757806328b5e32b1461020a57806328f4dbb614610212576101ae565b806301cfdd29146101b35780630d0eda8b146101cf57806313e3b57c146101e4575b600080fd5b6101bc60055481565b6040519081526020015b60405180910390f35b6101e26101dd366004611ae2565b610429565b005b6101e26101f23660046119f6565b6104bc565b6101e26102053660046119f6565b6105cd565b6101e261066a565b6101bc60095481565b6101bc6201c13881565b6101e26102333660046119f6565b6106e8565b61025373ffffffffffffffffffffffffffffffffffffffff81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101bc7ff66b632ae3b479ef109dee46eb319414289a8426a08b64d81aad232941f9d22a81565b6001546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6101e26102cd366004611b58565b6107e8565b6102f56102e03660046119f6565b60076020526000908152604090205460ff1681565b60405190151581526020016101c6565b6101e2610313366004611a66565b61090d565b600a546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6102f5610949565b6102537f00000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a81565b6101e2610375366004611a66565b61097c565b6101bc60045481565b6101e2610391366004611ab7565b6109b4565b6008546102539073ffffffffffffffffffffffffffffffffffffffff1681565b6003546102f59060ff1681565b6102f56103d1366004611a66565b610a62565b6101e26103e4366004611a2e565b610b1a565b6006546102539073ffffffffffffffffffffffffffffffffffffffff1681565b600b546102539073ffffffffffffffffffffffffffffffffffffffff1681565b610457336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527fe8693871decef495d3ddb20b4c2fdc4734c37f8ed6f875fbe1e6a718adbf0fdd9060200160405180910390a150565b6104ea336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b60015473ffffffffffffffffffffffffffffffffffffffff16156105555760405162461bcd60e51b815260206004820152601760248201527f534d4152545f5641554c545f414c52454144595f53455400000000000000000060448201526064015b60405180910390fd5b61055e81610c21565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f6a7abc646862eeb16d8760c0c56dff37a2d2c6b012a3419910005e57e503a08790600090a250565b6105fb336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fa07c91c183e42229e705a9795a1c06d76528b673788b849597364528c96eefb790600090a250565b610698336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b3360009081526007602052604090205460ff166106bc576106b7610c7a565b6106c4565b6106c4610cd0565b600b546106e69073ffffffffffffffffffffffffffffffffffffffff16610ce8565b565b610716336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff81166107795760405162461bcd60e51b815260206004820152600e60248201527f524543495049454e545f5a45524f000000000000000000000000000000000000604482015260640161054c565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b610816336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff81166108795760405162461bcd60e51b815260206004820152601560248201527f504159494e475f4741535f544f4b454e5f5a45524f0000000000000000000000604482015260640161054c565b60048390556005829055600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040805185815260208101859052908101919091527f7bd6a5fc2b1371f48a3ea03997aebaa84a60fb8d4e4a970b9f98a1b4c3d4bb889060600160405180910390a1505050565b61093b336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b6109458282610cff565b5050565b600b546000906109779073ffffffffffffffffffffffffffffffffffffffff1661097281610da4565b610ea3565b905090565b6109aa336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b6109458282610f6e565b6109e2336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915560098290556040518281527ff7e18aa0532694077d6fc7df02e85d86b91ba964f958d1949d45c5776d36eb6e906020015b60405180910390a25050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f50c7a3d1a23c7ff4a61d37c3f2c4aeb36cf60b43ee893723db201d3eb941cbad602052604081205460ff1680610b11575073ffffffffffffffffffffffffffffffffffffffff83166000908152602081815260408083207fffffffff000000000000000000000000000000000000000000000000000000008616845290915290205460ff165b90505b92915050565b610b48336000357fffffffff0000000000000000000000000000000000000000000000000000000016610bcb565b73ffffffffffffffffffffffffffffffffffffffff821660008181526007602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527fee42947bc760229eeff964017ac68eddb00ba98b0defcd90a1bc85a5afceb0579101610a56565b610bd58282610a62565b6109455760405162461bcd60e51b815260206004820152601760248201527f415554485f53454e4445525f4e4f545f414c4c4f574544000000000000000000604482015260640161054c565b610c2a81611016565b15610c775760405162461bcd60e51b815260206004820152601760248201527f444550454e44454e43595f4e4f545f535441544546554c000000000000000000604482015260640161054c565b50565b600b54610ca59073ffffffffffffffffffffffffffffffffffffffff16610ca081610da4565b611277565b6040517f68f46c45a243a0e9065a97649faf9a5afe1692f2679e650c2f853b9cd734cc0e90600090a1565b610cd86112cd565b610ce0610c7a565b6106e661138c565b6000610cf382610da4565b90506109458282611636565b73ffffffffffffffffffffffffffffffffffffffff82166000818152602081815260408083207fffffffff0000000000000000000000000000000000000000000000000000000086168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055519182527fa2e97b9eea8d1168700e334304edd057dff89c0384ca6f920c73cc3e48c8e5239101610a56565b600073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480610e81576001546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908416906370a08231906024015b60206040518083038186803b158015610e4457600080fd5b505afa158015610e58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7c9190611b40565b610e9c565b60015473ffffffffffffffffffffffffffffffffffffffff16315b9392505050565b6001546008546040517fac41865a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015291821660248201526000928392169063ac41865a9060440160206040518083038186803b158015610f1c57600080fd5b505afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f549190611b40565b600954909150610f6484836116f9565b1015949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166000818152602081815260408083207fffffffff0000000000000000000000000000000000000000000000000000000086168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055519182527f7f06c1c34ad47198873da9dcde2e40904035d41b23da3a9132df674a75022df79101610a56565b6040517f8b4872b800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015260009182917f00000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a1690638b4872b89060240160206040518083038186803b1580156110a257600080fd5b505afa1580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190611a12565b9050600073ffffffffffffffffffffffffffffffffffffffff82166110ff5783611101565b815b6040517f9235dcf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8083166004830152919250600091829182917f00000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a1690639235dcf89060240160606040518083038186803b15801561119257600080fd5b505afa1580156111a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ca9190611afe565b919450925090508061121e5760405162461bcd60e51b815260206004820152601960248201527f444550454e44454e43595f4e4f545f5245474953544552454400000000000000604482015260640161054c565b811561126c5760405162461bcd60e51b815260206004820152601560248201527f444550454e44454e43595f444550524543415445440000000000000000000000604482015260640161054c565b509095945050505050565b6112818282610ea3565b6109455760405162461bcd60e51b815260206004820152601560248201527f4d494e5f5448524553484f4c445f4e4f545f4d45540000000000000000000000604482015260640161054c565b5a6002553360009081526007602052604090205460ff166113305760405162461bcd60e51b815260206004820152601260248201527f53454e4445525f4e4f545f52454c415945520000000000000000000000000000604482015260640161054c565b6004548015806113405750803a11155b610c775760405162461bcd60e51b815260206004820152601560248201527f4741535f50524943455f41424f56455f4c494d49540000000000000000000000604482015260640161054c565b60005a60025461139c9190611c87565b905060003a3073ffffffffffffffffffffffffffffffffffffffff1663389aa3426040518163ffffffff1660e01b815260040160206040518083038186803b1580156113e757600080fd5b505afa1580156113fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141f9190611b40565b6114299084611c32565b6114339190611c4a565b6005546006549192509073ffffffffffffffffffffffffffffffffffffffff1660006114686114618361179e565b85906116f9565b90508215806114775750828111155b6114c35760405162461bcd60e51b815260206004820152601360248201527f54585f434f53545f41424f56455f4c494d495400000000000000000000000000604482015260640161054c565b6114cd82826118c5565b1561162a57600154604080517fc415b95c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691639003afee9185918591859163c415b95c91600480820192602092909190829003018186803b15801561154957600080fd5b505afa15801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190611a12565b6040518060400160405280600781526020017f52454c41594552000000000000000000000000000000000000000000000000008152506040518563ffffffff1660e01b81526004016115d69493929190611b90565b602060405180830381600087803b1580156115f057600080fd5b505af1158015611604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116289190611b40565b505b50506000600255505050565b600154600a54604080516000815260208101918290527f9003afee0000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff92831692639003afee926116a29287928792169060248101611b90565b602060405180830381600087803b1580156116bc57600080fd5b505af11580156116d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f49190611b40565b505050565b600082820283158061174057508284828161173d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b04145b61178c5760405162461bcd60e51b815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015260640161054c565b670de0b6b3a764000090049392505050565b6000806117aa836118ed565b9050806118b557600154604080517f17fcb39b000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163ac41865a9183916317fcb39b91600480820192602092909190829003018186803b15801561182457600080fd5b505afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190611a12565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff91821660048201529086166024820152604401610e2c565b50670de0b6b3a764000092915050565b60035460009060ff166118da57506001610b14565b816118e484610da4565b10159392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff83161480610b145750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317fcb39b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561198a57600080fd5b505afa15801561199e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c29190611a12565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161492915050565b600060208284031215611a07578081fd5b8135610e9c81611ccd565b600060208284031215611a23578081fd5b8151610e9c81611ccd565b60008060408385031215611a40578081fd5b8235611a4b81611ccd565b91506020830135611a5b81611cef565b809150509250929050565b60008060408385031215611a78578182fd5b8235611a8381611ccd565b915060208301357fffffffff0000000000000000000000000000000000000000000000000000000081168114611a5b578182fd5b60008060408385031215611ac9578182fd5b8235611ad481611ccd565b946020939093013593505050565b600060208284031215611af3578081fd5b8135610e9c81611cef565b600080600060608486031215611b12578081fd5b8351611b1d81611cef565b6020850151909350611b2e81611cef565b80925050604084015190509250925092565b600060208284031215611b51578081fd5b5051919050565b600080600060608486031215611b6c578283fd5b83359250602084013591506040840135611b8581611ccd565b809150509250925092565b600073ffffffffffffffffffffffffffffffffffffffff80871683526020868185015281861660408501526080606085015284519150816080850152825b82811015611bea5785810182015185820160a001528101611bce565b82811115611bfb578360a084870101525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160a00195945050505050565b60008219821115611c4557611c45611c9e565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c8257611c82611c9e565b500290565b600082821015611c9957611c99611c9e565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610c7757600080fd5b8015158114610c7757600080fdfea26469706673582212209e37c847ab4e248f2bf09bcade5f369d2b0b28118b6465c4ddb45fccfb0ee23264736f6c63430008030033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f060ac1f9ee8fc5dfb0c24b67729e59ddcdb437300000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a

-----Decoded View---------------
Arg [0] : admin (address): 0xF060ac1f9ee8FC5dfb0c24b67729E59ddcdB4373
Arg [1] : registry (address): 0x53D627B1a2993139b32d5dF209A94498d691f21A

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f060ac1f9ee8fc5dfb0c24b67729e59ddcdb4373
Arg [1] : 00000000000000000000000053d627b1a2993139b32d5df209a94498d691f21a


Deployed Bytecode Sourcemap

58542:1010:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52386:29;;;;;;;;;4934:25:1;;;4922:2;4907:18;52386:29:0;;;;;;;;53488:145;;;;;;:::i;:::-;;:::i;:::-;;46582:295;;;;;;:::i;:::-;;:::i;59098:119::-;;;;;;:::i;:::-;;:::i;59225:124::-;;;:::i;49703:30::-;;;;;;58691:49;;58735:5;58691:49;;57526:207;;;;;;:::i;:::-;;:::i;21029:89::-;;21075:42;21029:89;;;;;3247:42:1;3235:55;;;3217:74;;3205:2;3190:18;21029:89:0;3172:125:1;45755:64:0;;45800:19;45755:64;;45858:38;;;;;;;;;54269:391;;;;;;:::i;:::-;;:::i;52592:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4761:14:1;;4754:22;4736:41;;4724:2;4709:18;52592:42:0;4691:92:1;22412:112:0;;;;;;:::i;:::-;;:::i;57215:24::-;;;;;;;;;58971:119;;;:::i;41300:42::-;;;;;22091:108;;;;;;:::i;:::-;;:::i;52250:28::-;;;;;;50006:186;;;;;;:::i;:::-;;:::i;49667:29::-;;;;;;;;;52139:34;;;;;;;;;21718:164;;;;;;:::i;:::-;;:::i;53838:156::-;;;;;;:::i;:::-;;:::i;52502:29::-;;;;;;;;;58795:20;;;;;;;;;53488:145;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;53553:22:::1;:31:::0;;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;53600:25:::1;::::0;4736:41:1;;;53600:25:0::1;::::0;4724:2:1;4709:18;53600:25:0::1;;;;;;;53488:145:::0;:::o;46582:295::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;46669:10:::1;::::0;46661:33:::1;46669:10;46661:33:::0;46653:69:::1;;;::::0;-1:-1:-1;;;46653:69:0;;6370:2:1;46653:69:0::1;::::0;::::1;6352:21:1::0;6409:2;6389:18;;;6382:30;6448:25;6428:18;;;6421:53;6491:18;;46653:69:0::1;;;;;;;;;46733:42;46761:13;46733:27;:42::i;:::-;46786:10;:39:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;46841:28:::1;::::0;::::1;::::0;-1:-1:-1;;46841:28:0::1;46582:295:::0;:::o;59098:119::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;59159:5:::1;:16:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;59191:18:::1;::::0;::::1;::::0;-1:-1:-1;;59191:18:0::1;59098:119:::0;:::o;59225:124::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;59276:10:::1;59266:21;::::0;;;:9:::1;:21;::::0;;;;;::::1;;:48;;59307:7;:5;:7::i;:::-;59266:48;;;59290:14;:12;:14::i;:::-;59335:5;::::0;59325:16:::1;::::0;59335:5:::1;;59325:9;:16::i;:::-;59225:124::o:0;57526:207::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;57603:26:::1;::::0;::::1;57595:53;;;::::0;-1:-1:-1;;;57595:53:0;;7426:2:1;57595:53:0::1;::::0;::::1;7408:21:1::0;7465:2;7445:18;;;7438:30;7504:16;7484:18;;;7477:44;7538:18;;57595:53:0::1;7398:164:1::0;57595:53:0::1;57659:9;:24:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;57699:26:::1;::::0;::::1;::::0;-1:-1:-1;;57699:26:0::1;57526:207:::0;:::o;54269:391::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;54395:29:::1;::::0;::::1;54387:63;;;::::0;-1:-1:-1;;;54387:63:0;;9173:2:1;54387:63:0::1;::::0;::::1;9155:21:1::0;9212:2;9192:18;;;9185:30;9251:23;9231:18;;;9224:51;9292:18;;54387:63:0::1;9145:171:1::0;54387:63:0::1;54461:13;:30:::0;;;54502:14:::1;:32:::0;;;54545:14:::1;:32:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;54593:59:::1;::::0;;10046:25:1;;;10102:2;10087:18;;10080:34;;;10130:18;;;10123:83;;;;54593:59:0::1;::::0;10034:2:1;10019:18;54593:59:0::1;;;;;;;54269:391:::0;;;:::o;22412:112::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;22493:23:::1;22506:3;22511:4;22493:12;:23::i;:::-;22412:112:::0;;:::o;58971:119::-;59057:5;;59016:4;;59040:42;;59057:5;;59064:17;59057:5;59064:10;:17::i;:::-;59040:16;:42::i;:::-;59033:49;;58971:119;:::o;22091:108::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;22170:21:::1;22181:3;22186:4;22170:10;:21::i;50006:186::-:0;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;50084:14:::1;:22:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;50117:15:::1;:24:::0;;;50157:27:::1;::::0;4934:25:1;;;50157:27:0::1;::::0;4922:2:1;4907:18;50157:27:0::1;;;;;;;;50006:186:::0;;:::o;21718:164::-;21820:29;;;21796:4;21820:29;;;:23;;:29;:23;:29;;;;;;:54;;-1:-1:-1;21853:15:0;;;:10;:15;;;;;;;;;;;:21;;;;;;;;;;;;;21820:54;21813:61;;21718:164;;;;;:::o;53838:156::-;21413:34;21427:10;21439:7;;;;21413:13;:34::i;:::-;53914:18:::1;::::0;::::1;;::::0;;;:9:::1;:18;::::0;;;;;;;;:28;;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;53958;;4736:41:1;;;53958:28:0::1;::::0;4709:18:1;53958:28:0::1;4691:92:1::0;22817:141:0;22899:23;22912:3;22917:4;22899:12;:23::i;:::-;22891:59;;;;-1:-1:-1;;;22891:59:0;;8119:2:1;22891:59:0;;;8101:21:1;8158:2;8138:18;;;8131:30;8197:25;8177:18;;;8170:53;8240:18;;22891:59:0;8091:173:1;42284:158:0;42375:31;42395:10;42375:19;:31::i;:::-;42374:32;42366:68;;;;-1:-1:-1;;;42366:68:0;;8821:2:1;42366:68:0;;;8803:21:1;8860:2;8840:18;;;8833:30;8899:25;8879:18;;;8872:53;8942:18;;42366:68:0;8793:173:1;42366:68:0;42284:158;:::o;59434:115::-;59490:5;;59471:44;;59490:5;;59497:17;59490:5;59497:10;:17::i;:::-;59471:18;:44::i;:::-;59531:10;;;;;;;59434:115::o;59357:69::-;53222:13;:11;:13::i;:::-;59411:7:::1;:5;:7::i;:::-;53258:12:::0;:10;:12::i;57935:133::-;57989:15;58007:17;58018:5;58007:10;:17::i;:::-;57989:35;;58035:25;58045:5;58052:7;58035:9;:25::i;23487:144::-;23555:15;;;23579:5;23555:15;;;;;;;;;;;:21;;;;;;;;;;;;;:29;;;;;;23600:23;5114:98:1;;;23600:23:0;;5087:18:1;23600:23:0;5069:149:1;46885:239:0;46943:7;45402:21;;;45266:42;45402:21;;47031:85;;47104:10;;47072:44;;;;;:23;47104:10;;;47072:44;;;3217:74:1;47072:23:0;;;;;;3190:18:1;;47072:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47031:85;;;47050:10;;;;47042:27;47031:85;47024:92;46885:239;-1:-1:-1;;;46885:239:0:o;50422:316::-;50535:10;;50562:14;;50535:42;;;;;:10;3555:15:1;;;50535:42:0;;;3537:34:1;50562:14:0;;;3587:18:1;;;3580:43;50502:4:0;;;;50535:10;;:19;;3449:18:1;;50535:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50715:15;;50519:58;;-1:-1:-1;50690:21:0;:6;50519:58;50690:14;:21::i;:::-;:40;;;50422:316;-1:-1:-1;;;;50422:316:0:o;23151:139::-;23217:15;;;:10;:15;;;;;;;;;;;:21;;;;;;;;;;;;;:28;;;;23241:4;23217:28;;;23261:21;5114:98:1;;;23261:21:0;;5087:18:1;23261:21:0;5069:149:1;42698:746:0;42997:48;;;;;:36;3235:55:1;;;42997:48:0;;;3217:74:1;42769:4:0;;;;43007:8;42997:36;;;;3190:18:1;;42997:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42962:83;-1:-1:-1;43056:22:0;43081:38;;;:78;;43149:10;43081:78;;;43122:24;43081:78;43227:54;;;;;:38;3235:55:1;;;43227:54:0;;;3217:74:1;43056:103:0;;-1:-1:-1;43173:14:0;;;;;;43237:8;43227:38;;;;3190:18:1;;43227:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43172:109;;-1:-1:-1;43172:109:0;-1:-1:-1;43172:109:0;-1:-1:-1;43300:23:0;43292:61;;;;-1:-1:-1;;;43292:61:0;;7072:2:1;43292:61:0;;;7054:21:1;7111:2;7091:18;;;7084:30;7150:27;7130:18;;;7123:55;7195:18;;43292:61:0;7044:175:1;43292:61:0;43373:10;43372:11;43364:45;;;;-1:-1:-1;;;43364:45:0;;8471:2:1;43364:45:0;;;8453:21:1;8510:2;8490:18;;;8483:30;8549:23;8529:18;;;8522:51;8590:18;;43364:45:0;8443:171:1;43364:45:0;-1:-1:-1;43427:9:0;;42698:746;-1:-1:-1;;;;;42698:746:0:o;50971:157::-;51063:31;51080:5;51087:6;51063:16;:31::i;:::-;51055:65;;;;-1:-1:-1;;;51055:65:0;;7769:2:1;51055:65:0;;;7751:21:1;7808:2;7788:18;;;7781:30;7847:23;7827:18;;;7820:51;7888:18;;51055:65:0;7741:171:1;54761:256:0;54818:9;54804:11;:23;54856:10;54846:21;;;;:9;:21;;;;;;;;54838:52;;;;-1:-1:-1;;;54838:52:0;;5675:2:1;54838:52:0;;;5657:21:1;5714:2;5694:18;;;5687:30;5753:20;5733:18;;;5726:48;5791:18;;54838:52:0;5647:168:1;54838:52:0;54917:13;;54949:10;;;:34;;;54978:5;54963:11;:20;;54949:34;54941:68;;;;-1:-1:-1;;;54941:68:0;;6722:2:1;54941:68:0;;;6704:21:1;6761:2;6741:18;;;6734:30;6800:23;6780:18;;;6773:51;6841:18;;54941:68:0;6694:171:1;55108:771:0;55150:16;55183:9;55169:11;;:23;;;;:::i;:::-;55150:42;;55203:23;55275:11;55255:4;55241:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55230:41;;:8;:41;:::i;:::-;55229:57;;;;:::i;:::-;55315:14;;55362;;55203:83;;-1:-1:-1;55315:14:0;55362;;55299:13;55503:61;55527:36;55362:14;55527:23;:36::i;:::-;55503:15;;:23;:61::i;:::-;55478:86;-1:-1:-1;55583:10:0;;;:37;;;55615:5;55597:14;:23;;55583:37;55575:69;;;;-1:-1:-1;;;55575:69:0;;6022:2:1;55575:69:0;;;6004:21:1;6061:2;6041:18;;;6034:30;6100:21;6080:18;;;6073:49;6139:18;;55575:69:0;5994:169:1;55575:69:0;55661:59;55692:11;55705:14;55661:30;:59::i;:::-;55657:184;;;55737:10;;55786:25;;;;;;;;55737:10;;;;;:19;;55757:11;;55770:14;;55737:10;;55786:23;;:25;;;;;;;;;;;;;;;55737:10;55786:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51863:16;;;;;;;;;;;;;;;;;55737:92;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;55657:184;-1:-1:-1;;55853:18:0;55860:11;55853:18;-1:-1:-1;;;55108:771:0:o;58317:137::-;58387:10;;58422:9;;58433:12;;;58387:10;58433:12;;;;;;;;;58387:59;;;;:10;;;;;:19;;:59;;58407:5;;58414:6;;58422:9;;58387:59;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;58317:137;;:::o;47728:250::-;47790:7;47853:5;;;47881:6;;;:26;;;47906:1;47901;47891:7;:11;;;;;;;;;;;;;;:16;47881:26;47873:51;;;;-1:-1:-1;;;47873:51:0;;9523:2:1;47873:51:0;;;9505:21:1;9562:2;9542:18;;;9535:30;9601:14;9581:18;;;9574:42;9633:18;;47873:51:0;9495:162:1;47873:51:0;47635:4;47946:13;;;;-1:-1:-1;;;47728:250:0:o;56007:269::-;56077:7;56097:23;56123:30;56147:5;56123:23;:30::i;:::-;56097:56;;56171:18;:97;;56209:10;;56229:31;;;;;;;;56209:10;;;;;:19;;:10;;56229:29;;:31;;;;;;;;;;;;;;;56209:10;56229:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56209:59;;;;;;;;;;3486:42:1;3555:15;;;56209:59:0;;;3537:34:1;3607:15;;;3587:18;;;3580:43;3449:18;;56209:59:0;3431:198:1;56171:97:0;-1:-1:-1;47635:4:0;;56007:269;-1:-1:-1;;56007:269:0:o;56559:203::-;56674:22;;56652:4;;56674:22;;56669:40;;-1:-1:-1;56705:4:0;56698:11;;56669:40;56748:6;56727:17;56738:5;56727:10;:17::i;:::-;:27;;;56559:203;-1:-1:-1;;;56559:203:0:o;47132:181::-;47203:4;45266:42;45402:21;;;;47227:78;;;;47274:10;;;;;;;;;;;:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47265:40;;:5;:40;;;47220:85;47132:181;-1:-1:-1;;47132:181:0:o;14:257:1:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:392::-;;;668:2;656:9;647:7;643:23;639:32;636:2;;;689:6;681;674:22;636:2;733:9;720:23;752:31;777:5;752:31;:::i;:::-;802:5;-1:-1:-1;859:2:1;844:18;;831:32;872:30;831:32;872:30;:::i;:::-;921:7;911:17;;;626:308;;;;;:::o;939:495::-;;;1067:2;1055:9;1046:7;1042:23;1038:32;1035:2;;;1088:6;1080;1073:22;1035:2;1132:9;1119:23;1151:31;1176:5;1151:31;:::i;:::-;1201:5;-1:-1:-1;1258:2:1;1243:18;;1230:32;1306:66;1293:80;;1281:93;;1271:2;;1393:6;1385;1378:22;1439:325;;;1568:2;1556:9;1547:7;1543:23;1539:32;1536:2;;;1589:6;1581;1574:22;1536:2;1633:9;1620:23;1652:31;1677:5;1652:31;:::i;:::-;1702:5;1754:2;1739:18;;;;1726:32;;-1:-1:-1;;;1526:238:1:o;1769:251::-;;1878:2;1866:9;1857:7;1853:23;1849:32;1846:2;;;1899:6;1891;1884:22;1846:2;1943:9;1930:23;1962:28;1984:5;1962:28;:::i;2025:444::-;;;;2176:2;2164:9;2155:7;2151:23;2147:32;2144:2;;;2197:6;2189;2182:22;2144:2;2234:9;2228:16;2253:28;2275:5;2253:28;:::i;:::-;2350:2;2335:18;;2329:25;2300:5;;-1:-1:-1;2363:30:1;2329:25;2363:30;:::i;:::-;2412:7;2402:17;;;2459:2;2448:9;2444:18;2438:25;2428:35;;2134:335;;;;;:::o;2474:194::-;;2597:2;2585:9;2576:7;2572:23;2568:32;2565:2;;;2618:6;2610;2603:22;2565:2;-1:-1:-1;2646:16:1;;2555:113;-1:-1:-1;2555:113:1:o;2673:393::-;;;;2819:2;2807:9;2798:7;2794:23;2790:32;2787:2;;;2840:6;2832;2825:22;2787:2;2881:9;2868:23;2858:33;;2938:2;2927:9;2923:18;2910:32;2900:42;;2992:2;2981:9;2977:18;2964:32;3005:31;3030:5;3005:31;:::i;:::-;3055:5;3045:15;;;2777:289;;;;;:::o;3634:957::-;;3857:42;3938:2;3930:6;3926:15;3915:9;3908:34;3961:2;3999:6;3994:2;3983:9;3979:18;3972:34;4054:2;4046:6;4042:15;4037:2;4026:9;4022:18;4015:43;4094:3;4089:2;4078:9;4074:18;4067:31;4127:6;4121:13;4107:27;;4171:6;4165:3;4154:9;4150:19;4143:35;4196:4;4209:141;4223:6;4220:1;4217:13;4209:141;;;4319:14;;;4315:23;;4309:30;4284:17;;;4303:3;4280:27;4273:67;4238:10;;4209:141;;;4368:6;4365:1;4362:13;4359:2;;;4439:4;4433:3;4424:6;4413:9;4409:22;4405:32;4398:46;4359:2;-1:-1:-1;;4506:2:1;4494:15;4511:66;4490:88;4475:104;;;;4581:3;4471:114;;3837:754;-1:-1:-1;;;;;3837:754:1:o;10217:128::-;;10288:1;10284:6;10281:1;10278:13;10275:2;;;10294:18;;:::i;:::-;-1:-1:-1;10330:9:1;;10265:80::o;10350:228::-;;10516:1;10448:66;10444:74;10441:1;10438:81;10433:1;10426:9;10419:17;10415:105;10412:2;;;10523:18;;:::i;:::-;-1:-1:-1;10563:9:1;;10402:176::o;10583:125::-;;10651:1;10648;10645:8;10642:2;;;10656:18;;:::i;:::-;-1:-1:-1;10693:9:1;;10632:76::o;10713:184::-;10765:77;10762:1;10755:88;10862:4;10859:1;10852:15;10886:4;10883:1;10876:15;10902:154;10988:42;10981:5;10977:54;10970:5;10967:65;10957:2;;11046:1;11043;11036:12;11061:118;11147:5;11140:13;11133:21;11126:5;11123:32;11113:2;;11169:1;11166;11159:12

Swarm Source

ipfs://9e37c847ab4e248f2bf09bcade5f369d2b0b28118b6465c4ddb45fccfb0ee232

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.