ETH Price: $3,266.16 (+4.88%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Buyback147978162022-05-18 8:31:52988 days ago1652862712IN
0xD302484D...74aBC6eBe
0 ETH0.0039315724.15209352
Buyback147978112022-05-18 8:30:53988 days ago1652862653IN
0xD302484D...74aBC6eBe
0 ETH0.0045657727.43657827
Buyback147098832022-05-04 8:32:501002 days ago1651653170IN
0xD302484D...74aBC6eBe
0 ETH0.0092332556.73519593
Buyback147098792022-05-04 8:31:191002 days ago1651653079IN
0xD302484D...74aBC6eBe
0 ETH0.0083040849.9088447
Buyback146654252022-04-27 8:32:161009 days ago1651048336IN
0xD302484D...74aBC6eBe
0 ETH0.0051945631.7204163
Buyback146654212022-04-27 8:31:171009 days ago1651048277IN
0xD302484D...74aBC6eBe
0 ETH0.0056858934.16818427
Buyback146208482022-04-20 8:32:071016 days ago1650443527IN
0xD302484D...74aBC6eBe
0 ETH0.0057474735.08729028
Buyback146208402022-04-20 8:30:591016 days ago1650443459IN
0xD302484D...74aBC6eBe
0 ETH0.0065773139.53067635
Buyback145761022022-04-13 8:32:041023 days ago1649838724IN
0xD302484D...74aBC6eBe
0 ETH0.0081816149.96495715
Buyback145760982022-04-13 8:30:381023 days ago1649838638IN
0xD302484D...74aBC6eBe
0 ETH0.0064382938.68959086
Buyback145313012022-04-06 8:33:031030 days ago1649233983IN
0xD302484D...74aBC6eBe
0 ETH0.009225456.33321542
Buyback145312972022-04-06 8:31:471030 days ago1649233907IN
0xD302484D...74aBC6eBe
0 ETH0.0081714349.10452704
Buyback144868402022-03-30 9:36:141037 days ago1648632974IN
0xD302484D...74aBC6eBe
0 ETH0.0051154931.23450878
Buyback144868372022-03-30 9:34:571037 days ago1648632897IN
0xD302484D...74aBC6eBe
0 ETH0.0043423926.09471976
Buyback144417372022-03-23 9:31:421044 days ago1648027902IN
0xD302484D...74aBC6eBe
0 ETH0.0058322933.81532828
Buyback144417342022-03-23 9:30:581044 days ago1648027858IN
0xD302484D...74aBC6eBe
0 ETH0.0053332532.04907292
Buyback143968532022-03-16 9:42:391051 days ago1647423759IN
0xD302484D...74aBC6eBe
0 ETH0.0038169123.44497818
Buyback143968082022-03-16 9:30:471051 days ago1647423047IN
0xD302484D...74aBC6eBe
0 ETH0.0033500620.12824035
Buyback143517852022-03-09 9:31:551058 days ago1646818315IN
0xD302484D...74aBC6eBe
0 ETH0.0049186230.03061899
Buyback143517812022-03-09 9:30:301058 days ago1646818230IN
0xD302484D...74aBC6eBe
0 ETH0.0046968928.22142174
Buyback143067852022-03-02 9:31:081065 days ago1646213468IN
0xD302484D...74aBC6eBe
0 ETH0.0042622426.02248783
Buyback143067812022-03-02 9:30:361065 days ago1646213436IN
0xD302484D...74aBC6eBe
0 ETH0.0041279724.80619213
Buyback142615582022-02-23 9:33:301072 days ago1645608810IN
0xD302484D...74aBC6eBe
0 ETH0.0094716961.26344507
Buyback142615552022-02-23 9:31:441072 days ago1645608704IN
0xD302484D...74aBC6eBe
0 ETH0.0074005545.18593571
Buyback142615512022-02-23 9:30:411072 days ago1645608641IN
0xD302484D...74aBC6eBe
0 ETH0.0064514238.76219157
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SurplusConverterUniV3

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 12 : SurplusConverterUniV3.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

import "../interfaces/external/uniswap/IUniswapRouter.sol";
import "./BaseSurplusConverter.sol";

/// @title SurplusConverterUniV3
/// @author Angle Core Team
/// @notice A contract to swap tokens from the surplus of the protocol to a reward token
/// (could be ANGLE tokens, or another type of token)
/// @dev This contract swaps tokens on UniV3
contract SurplusConverterUniV3 is BaseSurplusConverter {
    using SafeERC20 for IERC20;

    event PathUpdated(address indexed token, bytes newPath, bytes oldPath);
    event TokenRevoked(address indexed token);

    /// @notice Address of the uniswapV2Router for swaps
    IUniswapV3Router public immutable uniswapV3Router;

    /// @notice Maps a token to the related path on Uniswap to do the swap to the reward token
    mapping(address => bytes) public uniswapPaths;

    /// @notice Constructor of the `SurplusConverterUniV3`
    /// @param _rewardToken Reward token that this contract tries to buy
    /// @param _feeDistributor Reference to the contract handling fee distribution
    /// @param _uniswapV3Router Reference to the `UniswapV2Router`
    /// @param whitelisted Reference to the first whitelisted address that will have the right
    /// @param governor Governor of the protocol
    /// @param guardians List of guardians of the protocol
    constructor(
        address _rewardToken,
        address _feeDistributor,
        address _uniswapV3Router,
        address whitelisted,
        address governor,
        address[] memory guardians
    ) BaseSurplusConverter(_rewardToken, _feeDistributor, whitelisted, governor, guardians) {
        require(_uniswapV3Router != address(0), "0");
        uniswapV3Router = IUniswapV3Router(_uniswapV3Router);
    }

    /// @notice Adds a token to support with this contract
    /// @param token Token to add to this contract
    /// @param pathAddresses Addresses used (in order) for the swap
    /// @param pathFees Fees used (in order) to get the path for the pool to use for the swap
    /// @dev This function can be called to change the path for a token or to add a new supported
    /// token
    function addToken(
        address token,
        address[] memory pathAddresses,
        uint24[] memory pathFees
    ) external onlyRole(GUARDIAN_ROLE) {
        require(token != address(0), "0");
        require(pathAddresses.length >= 2, "5");
        require(pathAddresses.length == (pathFees.length + 1), "104");
        require(pathAddresses[0] == token && pathAddresses[pathAddresses.length - 1] == address(rewardToken), "111");

        bytes memory path;
        for (uint256 i = 0; i < pathFees.length; i++) {
            require(pathAddresses[i] != address(0) && pathAddresses[i + 1] != address(0), "0");
            path = abi.encodePacked(path, pathAddresses[i], pathFees[i]);
        }
        path = abi.encodePacked(path, pathAddresses[pathFees.length]);

        // As this function can be sued to change the path for an existing token,
        // we're checking if a path already exists for this token before giving it
        // approval
        bytes memory oldPath = uniswapPaths[token];
        if (oldPath.length == 0) {
            IERC20(token).safeApprove(address(uniswapV3Router), type(uint256).max);
        }
        uniswapPaths[token] = path;
        emit PathUpdated(token, path, oldPath);
    }

    /// @notice Revokes a token supported by this contract
    /// @param token Token to add to this contract
    function revokeToken(address token) external onlyRole(GUARDIAN_ROLE) {
        delete uniswapPaths[token];
        IERC20(token).safeApprove(address(uniswapV3Router), 0);
        emit TokenRevoked(token);
    }

    /// @notice Buys back `rewardToken` from UniswapV3 using the accumulated `token` and distributes
    /// the results of the swaps to the `FeeDistributor` or some other `SurplusConverter` contract
    /// @param token Token to use for buybacks of `rewardToken`
    /// @param amount Amount of tokens to use for the buyback
    /// @param minAmount Specify the minimum amount to receive out of the swap as a slippage protection
    /// @param transfer Whether the function should transfer the bought back `rewardToken` directly to the `FeeDistributor`
    /// contract or to the associated `SurplusConverter`
    /// @dev This function always chooses the same path
    function buyback(
        address token,
        uint256 amount,
        uint256 minAmount,
        bool transfer
    ) external override whenNotPaused onlyRole(WHITELISTED_ROLE) {
        bytes memory path = uniswapPaths[token];
        require(path.length != 0, "111");
        uniswapV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, minAmount));
        if (transfer) {
            // This call will automatically transfer all the `rewardToken` balance of this contract to the `FeeDistributor`
            feeDistributor.burn(address(rewardToken));
        }
    }
}

File 2 of 12 : Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 3 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 4 of 12 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 5 of 12 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 6 of 12 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 7 of 12 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 8 of 12 : AccessControl.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

import "../interfaces/IAccessControl.sol";

/**
 * @dev This contract is fully forked from OpenZeppelin `AccessControl`.
 * The only difference is the removal of the ERC165 implementation as it's not
 * needed in Angle.
 *
 * Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external override {
        require(account == _msgSender(), "71");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) internal {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) internal {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 9 of 12 : IAccessControl.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

/// @title IAccessControl
/// @author Forked from OpenZeppelin
/// @notice Interface for `AccessControl` contracts
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);

    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    function grantRole(bytes32 role, address account) external;

    function revokeRole(bytes32 role, address account) external;

    function renounceRole(bytes32 role, address account) external;
}

File 10 of 12 : IFeeDistributor.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

/// @title IFeeDistributor
/// @author Interface of the `FeeDistributor` contract
/// @dev This interface is used by the `SurplusConverter` contract to send funds to the `FeeDistributor`
interface IFeeDistributor {
    function burn(address token) external;
}

File 11 of 12 : IUniswapRouter.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

struct ExactInputParams {
    bytes path;
    address recipient;
    uint256 deadline;
    uint256 amountIn;
    uint256 amountOutMinimum;
}

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface IUniswapV3Router {
    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
}

/// @title Router for price estimation functionality
/// @notice Functions for getting the price of one token with respect to another using Uniswap V2
/// @dev This interface is only used for non critical elements of the protocol
interface IUniswapV2Router {
    /// @notice Given an input asset amount, returns the maximum output amount of the
    /// other asset (accounting for fees) given reserves.
    /// @param path Addresses of the pools used to get prices
    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);

    function swapExactTokensForTokens(
        uint256 swapAmount,
        uint256 minExpected,
        address[] calldata path,
        address receiver,
        uint256 swapDeadline
    ) external;
}

File 12 of 12 : BaseSurplusConverter.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

import "../interfaces/IFeeDistributor.sol";
import "../external/AccessControl.sol";

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";

/// @title BaseSurplusConverter
/// @author Angle Core Team
/// @notice A base contract for the swap tokens from the surplus of the protocol to a reward token
/// (could be ANGLE tokens, or another type of token like sanTokens)
/// @dev All contracts implementing such swap features in Angle should implement this base contract
abstract contract BaseSurplusConverter is AccessControl, Pausable, IFeeDistributor {
    using SafeERC20 for IERC20;

    event FeeDistributorUpdated(address indexed newFeeDistributor, address indexed oldFeeDistributor);
    event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);

    /// @notice Role for governor of this contract
    bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE");

    /// @notice Role for guardians of this contract
    bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");

    /// @notice Role for addresses allowed to redistribute the protocol's surplus
    bytes32 public constant WHITELISTED_ROLE = keccak256("WHITELISTED_ROLE");

    /// @notice Address responsible for distributing bought back reward tokens to veANGLE holders or for swapping
    /// the reward token of this contract to another token
    IFeeDistributor public feeDistributor;

    /// @notice Reward Token obtained by this contract
    IERC20 public immutable rewardToken;

    /// @notice Constructor of the `BaseSurplusConverter`
    /// @param _rewardToken Reward token that this contract tries to buy or otain
    /// @param _feeDistributor Reference to the contract handling fee distribution
    /// @param whitelisted Reference to the first whitelisted address that will have the right to perform buybacks
    /// @param governor Governor of the protocol
    /// @param guardians List of guardians of the protocol
    /// @dev Having a list of guardians as a parameter facilitates deployment of the contract
    constructor(
        address _rewardToken,
        address _feeDistributor,
        address whitelisted,
        address governor,
        address[] memory guardians
    ) {
        require(_feeDistributor != address(0) && whitelisted != address(0) && governor != address(0), "0");
        feeDistributor = IFeeDistributor(_feeDistributor);
        rewardToken = IERC20(_rewardToken);
        // The function is going to revert because of the following call if the `_rewardToken` parameter is the
        // zero address
        IERC20(_rewardToken).safeApprove(_feeDistributor, type(uint256).max);
        require(guardians.length > 0, "101");
        for (uint256 i = 0; i < guardians.length; i++) {
            require(guardians[i] != address(0), "0");
            _setupRole(GUARDIAN_ROLE, guardians[i]);
        }
        _setupRole(WHITELISTED_ROLE, whitelisted);
        _setupRole(GOVERNOR_ROLE, governor);
        _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);
        _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);
        _setRoleAdmin(WHITELISTED_ROLE, GUARDIAN_ROLE);
        // Contract is paused after deployment
        _pause();
    }

    /// @notice Changes the reference to the `FeeDistributor` allowed to distribute rewards to veANGLE holders
    /// or to swap the reward token to another token
    /// @param _feeDistributor Reference to the new `FeeDistributor`
    /// @dev This function is a governor only function as it could technically be used to withdraw funds from the protocol
    function setFeeDistributor(address _feeDistributor) external onlyRole(GOVERNOR_ROLE) {
        require(_feeDistributor != address(0), "0");
        address oldFeeDistributor = address(feeDistributor);
        feeDistributor = IFeeDistributor(_feeDistributor);
        IERC20 rewardTokenMem = rewardToken;
        rewardTokenMem.safeApprove(_feeDistributor, type(uint256).max);
        rewardTokenMem.safeApprove(oldFeeDistributor, 0);
        emit FeeDistributorUpdated(_feeDistributor, oldFeeDistributor);
    }

    /// @notice Withdraws ERC20 tokens that could accrue on this contract
    /// @param tokenAddress Address of the ERC20 token to withdraw
    /// @param to Address to transfer to
    /// @param amount Amount to transfer
    /// @dev Added to support recovering rewardToken in case of impossible buybacks
    /// and other tokens mistakenly sent to this contract
    function recoverERC20(
        address tokenAddress,
        address to,
        uint256 amount
    ) external onlyRole(GOVERNOR_ROLE) {
        IERC20(tokenAddress).safeTransfer(to, amount);
        emit Recovered(tokenAddress, to, amount);
    }

    /// @notice Pauses the `buyback`, `sendToFeeDistributor` and `burn` methods
    /// @dev After calling this function, it is going to be impossible for whitelisted addresses to buyback
    /// reward tokens or to send the bought back tokens to the `FeeDistributor`
    function pause() external onlyRole(GUARDIAN_ROLE) {
        _pause();
    }

    /// @notice Unpauses the `buyback` and `sendToFeeDistributor` methods
    function unpause() external onlyRole(GUARDIAN_ROLE) {
        _unpause();
    }

    /// @notice Buys back `rewardToken` using the accumulated `token` and distributes the results of the
    /// swaps to the `feeDistributor` contract (which can be another `SurplusConverter`)
    /// @param token Token to use for buybacks of `rewardToken`
    /// @param amount Amount of tokens to use for the buyback
    /// @param minAmount Specify the minimum amount to receive - slippage protection
    /// @param transfer Whether the function should transfer the bought back `rewardToken` directly to the `FeeDistributor`
    /// contract
    /// @dev This function should revert if `amount` is inferior to the amount of `token` owned by this contract
    /// @dev The reason for the variable `amount` instead of simply using the whole contract's balance for buybacks
    /// is that it gives more flexibility to the addresses handling buyback to optimize for the swap prices
    /// @dev This function should be whitelisted because arbitrageurs could take advantage of it to do sandwich attacks
    /// by just calling this function. Calls to this function could be sandwiched too but it's going harder for miners to
    /// setup sandwich attacks
    function buyback(
        address token,
        uint256 amount,
        uint256 minAmount,
        bool transfer
    ) external virtual;

    /// @notice Pulls tokens from another `SurplusConverter` contract
    /// @param token Address of the token to pull
    /// @dev This function is what allows for composability between different `SurplusConverter` contracts: a surplus converter
    /// having swapped tokens can send its output token to another surplus converter, responsible for doing another type
    /// of conversion, by calling this contract
    function burn(address token) external override whenNotPaused {
        IERC20(token).safeTransferFrom(msg.sender, address(this), IERC20(token).balanceOf(msg.sender));
    }

    /// @notice This function transfers all the accumulated `rewardToken` to the `FeeDistributor` contract
    /// @dev The reason for having this function rather than doing such transfers directly in the `buyback` function is that
    /// it can allow to batch transfers and thus optimizes for gas
    function sendToFeeDistributor() external whenNotPaused {
        feeDistributor.burn(address(rewardToken));
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_feeDistributor","type":"address"},{"internalType":"address","name":"_uniswapV3Router","type":"address"},{"internalType":"address","name":"whitelisted","type":"address"},{"internalType":"address","name":"governor","type":"address"},{"internalType":"address[]","name":"guardians","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFeeDistributor","type":"address"},{"indexed":true,"internalType":"address","name":"oldFeeDistributor","type":"address"}],"name":"FeeDistributorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bytes","name":"newPath","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"oldPath","type":"bytes"}],"name":"PathUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"TokenRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GUARDIAN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELISTED_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address[]","name":"pathAddresses","type":"address[]"},{"internalType":"uint24[]","name":"pathFees","type":"uint24[]"}],"name":"addToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"transfer","type":"bool"}],"name":"buyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeDistributor","outputs":[{"internalType":"contract IFeeDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"revokeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendToFeeDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDistributor","type":"address"}],"name":"setFeeDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"uniswapPaths","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV3Router","outputs":[{"internalType":"contract IUniswapV3Router","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b506040516200353b3803806200353b833981016040819052620000349162000883565b6001805460ff1916905585858484846001600160a01b038416158015906200006457506001600160a01b03831615155b80156200007957506001600160a01b03821615155b620000af5760405162461bcd60e51b81526020600482015260016024820152600360fc1b60448201526064015b60405180910390fd5b60018054610100600160a81b0319166101006001600160a01b038781169190910291909117909155606086901b6001600160601b031916608052620001069086168560001962000310602090811b6200153517901c565b60008151116200013f5760405162461bcd60e51b815260206004820152600360248201526231303160e81b6044820152606401620000a6565b60005b8151811015620002035760006001600160a01b03168282815181106200016c576200016c62000aa9565b60200260200101516001600160a01b03161415620001b15760405162461bcd60e51b81526020600482015260016024820152600360fc1b6044820152606401620000a6565b620001ee6000805160206200351b833981519152838381518110620001da57620001da62000aa9565b60200260200101516200046f60201b60201c565b80620001fa8162000a7f565b91505062000142565b506200021f600080516020620034fb833981519152846200046f565b6200023a600080516020620034db833981519152836200046f565b62000255600080516020620034db833981519152806200047f565b6200027f6000805160206200351b833981519152600080516020620034db8339815191526200047f565b620002a9600080516020620034fb8339815191526000805160206200351b8339815191526200047f565b620002b3620004d3565b50505050506001600160a01b038416620002f45760405162461bcd60e51b81526020600482015260016024820152600360fc1b6044820152606401620000a6565b50505060601b6001600160601b03191660a0525062000ad59050565b8015806200039e5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200036157600080fd5b505afa15801562000376573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039c9190620009df565b155b620004125760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401620000a6565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200046a9185916200055c16565b505050565b6200047b82826200063a565b5050565b600082815260208190526040902060010154819060405184907fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff90600090a460009182526020829052604090912060010155565b60015460ff16156200051b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401620000a6565b6001805460ff1916811790556040805133815290517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589181900360200190a1565b6000620005b8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620006da60201b62001744179092919060201c565b8051909150156200046a5780806020019051810190620005d99190620009bb565b6200046a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620000a6565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166200047b576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620006963390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6060620006eb8484600085620006f5565b90505b9392505050565b606082471015620007585760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620000a6565b843b620007a85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620000a6565b600080866001600160a01b03168587604051620007c69190620009f9565b60006040518083038185875af1925050503d806000811462000805576040519150601f19603f3d011682016040523d82523d6000602084013e6200080a565b606091505b5090925090506200081d82828662000828565b979650505050505050565b6060831562000839575081620006ee565b8251156200084a5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000a17565b80516001600160a01b03811681146200087e57600080fd5b919050565b60008060008060008060c087890312156200089d57600080fd5b620008a88762000866565b95506020620008b981890162000866565b9550620008c96040890162000866565b9450620008d96060890162000866565b9350620008e96080890162000866565b60a08901519093506001600160401b03808211156200090757600080fd5b818a0191508a601f8301126200091c57600080fd5b81518181111562000931576200093162000abf565b8060051b604051601f19603f8301168101818110858211171562000959576200095962000abf565b604052828152858101935084860182860187018f10156200097957600080fd5b600095505b83861015620009a757620009928162000866565b8552600195909501949386019386016200097e565b508096505050505050509295509295509295565b600060208284031215620009ce57600080fd5b81518015158114620006ee57600080fd5b600060208284031215620009f257600080fd5b5051919050565b6000825162000a0d81846020870162000a4c565b9190910192915050565b602081526000825180602084015262000a3881604085016020870162000a4c565b601f01601f19169190910160400192915050565b60005b8381101562000a6957818101518382015260200162000a4f565b8381111562000a79576000848401525b50505050565b600060001982141562000aa257634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60805160601c60a05160601c6129a962000b32600039600081816102530152818161095601528181610f1c01526112060152600081816103fb015281816105b301528181610b9d015281816112d3015261144001526129a96000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637d6d9c63116100e3578063a3745c681161008c578063ccfc2e8d11610066578063ccfc2e8d146103d0578063d547741f146103e3578063f7c618c1146103f657600080fd5b8063a3745c6814610383578063adce205814610396578063ccc57490146103a957600080fd5b806391d14854116100bd57806391d1485414610324578063933f4eef14610368578063a217fddf1461037b57600080fd5b80637d6d9c63146102e95780638456cb591461030957806389afcb441461031157600080fd5b80632f2ff15d116101455780633f4ba83a1161011f5780633f4ba83a146102a35780635c975abb146102ab5780637a3226ec146102c257600080fd5b80632f2ff15d1461027557806333baecb21461028857806336568abe1461029057600080fd5b8063248a9ca311610176578063248a9ca3146101f657806324ea54f4146102275780632c76d7a61461024e57600080fd5b80630d43e8ad146101925780631171bda9146101e1575b600080fd5b6001546101b790610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101f46101ef3660046122e4565b61041d565b005b61021961020436600461245e565b60009081526020819052604090206001015490565b6040519081526020016101d8565b6102197f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504181565b6101b77f000000000000000000000000000000000000000000000000000000000000000081565b6101f4610283366004612477565b6104d6565b6101f4610501565b6101f461029e366004612477565b610620565b6101f46106ad565b60015460ff165b60405190151581526020016101d8565b6102197f8429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b4981565b6102fc6102f73660046122c9565b6106e3565b6040516101d89190612664565b6101f461077d565b6101f461031f3660046122c9565b6107b0565b6102b2610332366004612477565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b6101f46103763660046122c9565b6108e1565b610219600081565b6101f4610391366004612320565b6109c1565b6101f46103a43660046123f9565b610ff0565b6102197f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f5581565b6101f46103de3660046122c9565b611347565b6101f46103f1366004612477565b61150f565b6101b77f000000000000000000000000000000000000000000000000000000000000000081565b7f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55610448813361175d565b61046973ffffffffffffffffffffffffffffffffffffffff8516848461182d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b648846040516104c891815260200190565b60405180910390a350505050565b6000828152602081905260409020600101546104f2813361175d565b6104fc8383611883565b505050565b60015460ff1615610573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6001546040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152610100909204909116906389afcb4490602401600060405180830381600087803b15801561060657600080fd5b505af115801561061a573d6000803e3d6000fd5b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461069f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f3731000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6106a98282611973565b5050565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416106d8813361175d565b6106e0611a2a565b50565b600260205260009081526040902080546106fc9061284b565b80601f01602080910402602001604051908101604052809291908181526020018280546107289061284b565b80156107755780601f1061074a57610100808354040283529160200191610775565b820191906000526020600020905b81548152906001019060200180831161075857829003601f168201915b505050505081565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416107a8813361175d565b6106e0611b0b565b60015460ff161561081d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482018190526106e091309073ffffffffffffffffffffffffffffffffffffffff8516906370a082319060240160206040518083038186803b15801561088a57600080fd5b505afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c291906124a3565b73ffffffffffffffffffffffffffffffffffffffff8516929190611bc9565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161090c813361175d565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040812061093a91612149565b61097c73ffffffffffffffffffffffffffffffffffffffff83167f00000000000000000000000000000000000000000000000000000000000000006000611535565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f45f62f30e7b8439e0da7d8e560fe39d01238091ce9e789e3d12b514edf98acea90600090a25050565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416109ec813361175d565b73ffffffffffffffffffffffffffffffffffffffff8416610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b600283511015610ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3500000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b8151610ae290600161277e565b835114610b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3130340000000000000000000000000000000000000000000000000000000000604482015260640161056a565b8373ffffffffffffffffffffffffffffffffffffffff1683600081518110610b7557610b75612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16148015610c1157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168360018551610be191906127d3565b81518110610bf157610bf1612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b610c77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3131310000000000000000000000000000000000000000000000000000000000604482015260640161056a565b606060005b8351811015610de657600073ffffffffffffffffffffffffffffffffffffffff16858281518110610caf57610caf612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614158015610d155750600085610ce483600161277e565b81518110610cf457610cf4612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b81858281518110610d8e57610d8e612907565b6020026020010151858381518110610da857610da8612907565b6020026020010151604051602001610dc29392919061256c565b60405160208183030381529060405291508080610dde9061289f565b915050610c7c565b508084845181518110610dfb57610dfb612907565b6020026020010151604051602001610e14929190612522565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815273ffffffffffffffffffffffffffffffffffffffff87166000908152600260205290812080549293509091610e769061284b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea29061284b565b8015610eef5780601f10610ec457610100808354040283529160200191610eef565b820191906000526020600020905b815481529060010190602001808311610ed257829003601f168201915b50505050509050805160001415610f6157610f6173ffffffffffffffffffffffffffffffffffffffff87167f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611535565b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602090815260409091208351610f9792850190612183565b508573ffffffffffffffffffffffffffffffffffffffff167f4864804c0e4f81ecffca2a07977e5ba7a7ed64a6dab9cdce258d2ec9ab9fabeb8383604051610fe0929190612677565b60405180910390a2505050505050565b60015460ff161561105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b7f8429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b49611088813361175d565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260026020526040812080546110b89061284b565b80601f01602080910402602001604051908101604052809291908181526020018280546110e49061284b565b80156111315780601f1061110657610100808354040283529160200191611131565b820191906000526020600020905b81548152906001019060200180831161111457829003601f168201915b505050505090508051600014156111a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3131310000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6040805160a0810182528281523060208201524281830152606081018790526080810186905290517fc04b8d5900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163c04b8d599161123a91906004016126a5565b602060405180830381600087803b15801561125457600080fd5b505af1158015611268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128c91906124a3565b50821561133f576001546040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152610100909204909116906389afcb4490602401600060405180830381600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050505b505050505050565b7f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55611372813361175d565b73ffffffffffffffffffffffffffffffffffffffff82166113ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6001805473ffffffffffffffffffffffffffffffffffffffff8481166101009081027fffffffffffffffffffffff0000000000000000000000000000000000000000ff8416179093559190048116907f00000000000000000000000000000000000000000000000000000000000000009061148d908216857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611535565b6114af73ffffffffffffffffffffffffffffffffffffffff8216836000611535565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fbb470d12faa974cbae56bc3c345446451b4d504aa13806836f3df6d032fa9a9160405160405180910390a350505050565b60008281526020819052604090206001015461152b813361175d565b6104fc8383611973565b8015806115e457506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156115aa57600080fd5b505afa1580156115be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e291906124a3565b155b611670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161056a565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104fc9084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c27565b60606117538484600085611d33565b90505b9392505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166106a9576117b38173ffffffffffffffffffffffffffffffffffffffff166014611eb3565b6117be836020611eb3565b6040516020016117cf9291906125e3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261056a91600401612664565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104fc9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016116c2565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166106a95760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556119153390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156106a95760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60015460ff16611a96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161056a565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60015460ff1615611b78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833611ae1565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261061a9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116c2565b6000611c89826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166117449092919063ffffffff16565b8051909150156104fc5780806020019051810190611ca79190612441565b6104fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056a565b606082471015611dc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056a565b843b611e2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056a565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e569190612506565b60006040518083038185875af1925050503d8060008114611e93576040519150601f19603f3d011682016040523d82523d6000602084013e611e98565b606091505b5091509150611ea88282866120f6565b979650505050505050565b60606000611ec2836002612796565b611ecd90600261277e565b67ffffffffffffffff811115611ee557611ee5612936565b6040519080825280601f01601f191660200182016040528015611f0f576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611f4657611f46612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611fa957611fa9612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611fe5846002612796565b611ff090600161277e565b90505b600181111561208d577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061203157612031612907565b1a60f81b82828151811061204757612047612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361208681612816565b9050611ff3565b508315611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056a565b60608315612105575081611756565b8251156121155782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056a9190612664565b5080546121559061284b565b6000825580601f10612165575050565b601f0160209004906000526020600020908101906106e09190612207565b82805461218f9061284b565b90600052602060002090601f0160209004810192826121b157600085556121f7565b82601f106121ca57805160ff19168380011785556121f7565b828001600101855582156121f7579182015b828111156121f75782518255916020019190600101906121dc565b50612203929150612207565b5090565b5b808211156122035760008155600101612208565b803573ffffffffffffffffffffffffffffffffffffffff8116811461224057600080fd5b919050565b600082601f83011261225657600080fd5b8135602061226b6122668361275a565b61270b565b80838252828201915082860187848660051b890101111561228b57600080fd5b6000805b868110156122bb57823562ffffff811681146122a9578283fd5b8552938501939185019160010161228f565b509198975050505050505050565b6000602082840312156122db57600080fd5b6117568261221c565b6000806000606084860312156122f957600080fd5b6123028461221c565b92506123106020850161221c565b9150604084013590509250925092565b60008060006060848603121561233557600080fd5b61233e8461221c565b925060208085013567ffffffffffffffff8082111561235c57600080fd5b818701915087601f83011261237057600080fd5b813561237e6122668261275a565b8082825285820191508585018b878560051b880101111561239e57600080fd5b600095505b838610156123c8576123b48161221c565b8352600195909501949186019186016123a3565b509650505060408701359250808311156123e157600080fd5b50506123ef86828701612245565b9150509250925092565b6000806000806080858703121561240f57600080fd5b6124188561221c565b93506020850135925060408501359150606085013561243681612965565b939692955090935050565b60006020828403121561245357600080fd5b815161175681612965565b60006020828403121561247057600080fd5b5035919050565b6000806040838503121561248a57600080fd5b8235915061249a6020840161221c565b90509250929050565b6000602082840312156124b557600080fd5b5051919050565b600081518084526124d48160208601602086016127ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516125188184602087016127ea565b9190910192915050565b600083516125348184602088016127ea565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b6000845161257e8184602089016127ea565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815260e89190911b7fffffff000000000000000000000000000000000000000000000000000000000016601482015260170192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161261b8160178501602088016127ea565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516126588160288401602088016127ea565b01602801949350505050565b60208152600061175660208301846124bc565b60408152600061268a60408301856124bc565b828103602084015261269c81856124bc565b95945050505050565b602081526000825160a060208401526126c160c08401826124bc565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561275257612752612936565b604052919050565b600067ffffffffffffffff82111561277457612774612936565b5060051b60200190565b60008219821115612791576127916128d8565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127ce576127ce6128d8565b500290565b6000828210156127e5576127e56128d8565b500390565b60005b838110156128055781810151838201526020016127ed565b8381111561061a5750506000910152565b600081612825576128256128d8565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600181811c9082168061285f57607f821691505b60208210811415612899577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156128d1576128d16128d8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80151581146106e057600080fdfea26469706673582212207c7507b036ed7f8e5440eefe55a0d1f4604b9cfe96e9b79dbe0391ec44d9cf2f64736f6c634300080700337935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f558429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b4955435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002e2063080a05ffdaa6d57f9358c2a5e1c65c70ec000000000000000000000000e592427a0aece92de3edee1f18e0157c058615640000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d000000000000000000000000dc4e6dfe07efca50a197df15d9200883ef4eb1c800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c2553e4b9dfa9f83b1a6d3eab96c4baab42d4300000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018d5760003560e01c80637d6d9c63116100e3578063a3745c681161008c578063ccfc2e8d11610066578063ccfc2e8d146103d0578063d547741f146103e3578063f7c618c1146103f657600080fd5b8063a3745c6814610383578063adce205814610396578063ccc57490146103a957600080fd5b806391d14854116100bd57806391d1485414610324578063933f4eef14610368578063a217fddf1461037b57600080fd5b80637d6d9c63146102e95780638456cb591461030957806389afcb441461031157600080fd5b80632f2ff15d116101455780633f4ba83a1161011f5780633f4ba83a146102a35780635c975abb146102ab5780637a3226ec146102c257600080fd5b80632f2ff15d1461027557806333baecb21461028857806336568abe1461029057600080fd5b8063248a9ca311610176578063248a9ca3146101f657806324ea54f4146102275780632c76d7a61461024e57600080fd5b80630d43e8ad146101925780631171bda9146101e1575b600080fd5b6001546101b790610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101f46101ef3660046122e4565b61041d565b005b61021961020436600461245e565b60009081526020819052604090206001015490565b6040519081526020016101d8565b6102197f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504181565b6101b77f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b6101f4610283366004612477565b6104d6565b6101f4610501565b6101f461029e366004612477565b610620565b6101f46106ad565b60015460ff165b60405190151581526020016101d8565b6102197f8429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b4981565b6102fc6102f73660046122c9565b6106e3565b6040516101d89190612664565b6101f461077d565b6101f461031f3660046122c9565b6107b0565b6102b2610332366004612477565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b6101f46103763660046122c9565b6108e1565b610219600081565b6101f4610391366004612320565b6109c1565b6101f46103a43660046123f9565b610ff0565b6102197f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f5581565b6101f46103de3660046122c9565b611347565b6101f46103f1366004612477565b61150f565b6101b77f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b7f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55610448813361175d565b61046973ffffffffffffffffffffffffffffffffffffffff8516848461182d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b648846040516104c891815260200190565b60405180910390a350505050565b6000828152602081905260409020600101546104f2813361175d565b6104fc8383611883565b505050565b60015460ff1615610573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6001546040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881166004830152610100909204909116906389afcb4490602401600060405180830381600087803b15801561060657600080fd5b505af115801561061a573d6000803e3d6000fd5b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461069f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f3731000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6106a98282611973565b5050565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416106d8813361175d565b6106e0611a2a565b50565b600260205260009081526040902080546106fc9061284b565b80601f01602080910402602001604051908101604052809291908181526020018280546107289061284b565b80156107755780601f1061074a57610100808354040283529160200191610775565b820191906000526020600020905b81548152906001019060200180831161075857829003601f168201915b505050505081565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416107a8813361175d565b6106e0611b0b565b60015460ff161561081d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482018190526106e091309073ffffffffffffffffffffffffffffffffffffffff8516906370a082319060240160206040518083038186803b15801561088a57600080fd5b505afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c291906124a3565b73ffffffffffffffffffffffffffffffffffffffff8516929190611bc9565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161090c813361175d565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040812061093a91612149565b61097c73ffffffffffffffffffffffffffffffffffffffff83167f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646000611535565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f45f62f30e7b8439e0da7d8e560fe39d01238091ce9e789e3d12b514edf98acea90600090a25050565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50416109ec813361175d565b73ffffffffffffffffffffffffffffffffffffffff8416610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b600283511015610ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3500000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b8151610ae290600161277e565b835114610b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3130340000000000000000000000000000000000000000000000000000000000604482015260640161056a565b8373ffffffffffffffffffffffffffffffffffffffff1683600081518110610b7557610b75612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16148015610c1157507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168360018551610be191906127d3565b81518110610bf157610bf1612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b610c77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3131310000000000000000000000000000000000000000000000000000000000604482015260640161056a565b606060005b8351811015610de657600073ffffffffffffffffffffffffffffffffffffffff16858281518110610caf57610caf612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614158015610d155750600085610ce483600161277e565b81518110610cf457610cf4612907565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b81858281518110610d8e57610d8e612907565b6020026020010151858381518110610da857610da8612907565b6020026020010151604051602001610dc29392919061256c565b60405160208183030381529060405291508080610dde9061289f565b915050610c7c565b508084845181518110610dfb57610dfb612907565b6020026020010151604051602001610e14929190612522565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815273ffffffffffffffffffffffffffffffffffffffff87166000908152600260205290812080549293509091610e769061284b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea29061284b565b8015610eef5780601f10610ec457610100808354040283529160200191610eef565b820191906000526020600020905b815481529060010190602001808311610ed257829003601f168201915b50505050509050805160001415610f6157610f6173ffffffffffffffffffffffffffffffffffffffff87167f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611535565b73ffffffffffffffffffffffffffffffffffffffff861660009081526002602090815260409091208351610f9792850190612183565b508573ffffffffffffffffffffffffffffffffffffffff167f4864804c0e4f81ecffca2a07977e5ba7a7ed64a6dab9cdce258d2ec9ab9fabeb8383604051610fe0929190612677565b60405180910390a2505050505050565b60015460ff161561105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b7f8429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b49611088813361175d565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260026020526040812080546110b89061284b565b80601f01602080910402602001604051908101604052809291908181526020018280546110e49061284b565b80156111315780601f1061110657610100808354040283529160200191611131565b820191906000526020600020905b81548152906001019060200180831161111457829003601f168201915b505050505090508051600014156111a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f3131310000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6040805160a0810182528281523060208201524281830152606081018790526080810186905290517fc04b8d5900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564169163c04b8d599161123a91906004016126a5565b602060405180830381600087803b15801561125457600080fd5b505af1158015611268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128c91906124a3565b50821561133f576001546040517f89afcb4400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881166004830152610100909204909116906389afcb4490602401600060405180830381600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050505b505050505050565b7f7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55611372813361175d565b73ffffffffffffffffffffffffffffffffffffffff82166113ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f3000000000000000000000000000000000000000000000000000000000000000604482015260640161056a565b6001805473ffffffffffffffffffffffffffffffffffffffff8481166101009081027fffffffffffffffffffffff0000000000000000000000000000000000000000ff8416179093559190048116907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489061148d908216857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611535565b6114af73ffffffffffffffffffffffffffffffffffffffff8216836000611535565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fbb470d12faa974cbae56bc3c345446451b4d504aa13806836f3df6d032fa9a9160405160405180910390a350505050565b60008281526020819052604090206001015461152b813361175d565b6104fc8383611973565b8015806115e457506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156115aa57600080fd5b505afa1580156115be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e291906124a3565b155b611670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161056a565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104fc9084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c27565b60606117538484600085611d33565b90505b9392505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166106a9576117b38173ffffffffffffffffffffffffffffffffffffffff166014611eb3565b6117be836020611eb3565b6040516020016117cf9291906125e3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261056a91600401612664565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104fc9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016116c2565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166106a95760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556119153390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156106a95760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60015460ff16611a96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161056a565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60015460ff1615611b78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161056a565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833611ae1565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261061a9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116c2565b6000611c89826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166117449092919063ffffffff16565b8051909150156104fc5780806020019051810190611ca79190612441565b6104fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056a565b606082471015611dc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056a565b843b611e2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056a565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e569190612506565b60006040518083038185875af1925050503d8060008114611e93576040519150601f19603f3d011682016040523d82523d6000602084013e611e98565b606091505b5091509150611ea88282866120f6565b979650505050505050565b60606000611ec2836002612796565b611ecd90600261277e565b67ffffffffffffffff811115611ee557611ee5612936565b6040519080825280601f01601f191660200182016040528015611f0f576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611f4657611f46612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611fa957611fa9612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611fe5846002612796565b611ff090600161277e565b90505b600181111561208d577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061203157612031612907565b1a60f81b82828151811061204757612047612907565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361208681612816565b9050611ff3565b508315611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056a565b60608315612105575081611756565b8251156121155782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056a9190612664565b5080546121559061284b565b6000825580601f10612165575050565b601f0160209004906000526020600020908101906106e09190612207565b82805461218f9061284b565b90600052602060002090601f0160209004810192826121b157600085556121f7565b82601f106121ca57805160ff19168380011785556121f7565b828001600101855582156121f7579182015b828111156121f75782518255916020019190600101906121dc565b50612203929150612207565b5090565b5b808211156122035760008155600101612208565b803573ffffffffffffffffffffffffffffffffffffffff8116811461224057600080fd5b919050565b600082601f83011261225657600080fd5b8135602061226b6122668361275a565b61270b565b80838252828201915082860187848660051b890101111561228b57600080fd5b6000805b868110156122bb57823562ffffff811681146122a9578283fd5b8552938501939185019160010161228f565b509198975050505050505050565b6000602082840312156122db57600080fd5b6117568261221c565b6000806000606084860312156122f957600080fd5b6123028461221c565b92506123106020850161221c565b9150604084013590509250925092565b60008060006060848603121561233557600080fd5b61233e8461221c565b925060208085013567ffffffffffffffff8082111561235c57600080fd5b818701915087601f83011261237057600080fd5b813561237e6122668261275a565b8082825285820191508585018b878560051b880101111561239e57600080fd5b600095505b838610156123c8576123b48161221c565b8352600195909501949186019186016123a3565b509650505060408701359250808311156123e157600080fd5b50506123ef86828701612245565b9150509250925092565b6000806000806080858703121561240f57600080fd5b6124188561221c565b93506020850135925060408501359150606085013561243681612965565b939692955090935050565b60006020828403121561245357600080fd5b815161175681612965565b60006020828403121561247057600080fd5b5035919050565b6000806040838503121561248a57600080fd5b8235915061249a6020840161221c565b90509250929050565b6000602082840312156124b557600080fd5b5051919050565b600081518084526124d48160208601602086016127ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516125188184602087016127ea565b9190910192915050565b600083516125348184602088016127ea565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b6000845161257e8184602089016127ea565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815260e89190911b7fffffff000000000000000000000000000000000000000000000000000000000016601482015260170192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161261b8160178501602088016127ea565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516126588160288401602088016127ea565b01602801949350505050565b60208152600061175660208301846124bc565b60408152600061268a60408301856124bc565b828103602084015261269c81856124bc565b95945050505050565b602081526000825160a060208401526126c160c08401826124bc565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561275257612752612936565b604052919050565b600067ffffffffffffffff82111561277457612774612936565b5060051b60200190565b60008219821115612791576127916128d8565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127ce576127ce6128d8565b500290565b6000828210156127e5576127e56128d8565b500390565b60005b838110156128055781810151838201526020016127ed565b8381111561061a5750506000910152565b600081612825576128256128d8565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600181811c9082168061285f57607f821691505b60208210811415612899577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156128d1576128d16128d8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80151581146106e057600080fdfea26469706673582212207c7507b036ed7f8e5440eefe55a0d1f4604b9cfe96e9b79dbe0391ec44d9cf2f64736f6c63430008070033

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

000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002e2063080a05ffdaa6d57f9358c2a5e1c65c70ec000000000000000000000000e592427a0aece92de3edee1f18e0157c058615640000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d000000000000000000000000dc4e6dfe07efca50a197df15d9200883ef4eb1c800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c2553e4b9dfa9f83b1a6d3eab96c4baab42d4300000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d

-----Decoded View---------------
Arg [0] : _rewardToken (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [1] : _feeDistributor (address): 0x2E2063080A05FfdaA6D57f9358C2a5e1C65c70EC
Arg [2] : _uniswapV3Router (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [3] : whitelisted (address): 0x2Acd062Cf718c87c9A58382f01C5b51a0f287C8D
Arg [4] : governor (address): 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8
Arg [5] : guardians (address[]): 0x0C2553e4B9dFA9f83b1A6D3EAB96c4bAaB42d430,0x2Acd062Cf718c87c9A58382f01C5b51a0f287C8D

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [1] : 0000000000000000000000002e2063080a05ffdaa6d57f9358c2a5e1c65c70ec
Arg [2] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [3] : 0000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d
Arg [4] : 000000000000000000000000dc4e6dfe07efca50a197df15d9200883ef4eb1c8
Arg [5] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [7] : 0000000000000000000000000c2553e4b9dfa9f83b1a6d3eab96c4baab42d430
Arg [8] : 0000000000000000000000002acd062cf718c87c9a58382f01c5b51a0f287c8d


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  ]

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.