ETH Price: $3,251.04 (-0.09%)
Gas: 1 Gwei

Contract

0xbB55b164b641cD0eC89E901884d79f920f310605
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Pay And Notify196640292024-04-15 22:57:35102 days ago1713221855IN
0xbB55b164...20f310605
0 ETH0.0012702310.75143582
Pay And Notify196614082024-04-15 14:09:11102 days ago1713190151IN
0xbB55b164...20f310605
0 ETH0.0031602826.74627666
Pay And Notify196547672024-04-14 15:48:11103 days ago1713109691IN
0xbB55b164...20f310605
0 ETH0.0014553512.41548199
Pay And Notify196464292024-04-13 11:43:47104 days ago1713008627IN
0xbB55b164...20f310605
0 ETH0.0015868213.86961353
Pay And Notify196441402024-04-13 4:01:11105 days ago1712980871IN
0xbB55b164...20f310605
0 ETH0.0018229715.06824003
Pay From Ether A...196427642024-04-12 23:22:11105 days ago1712964131IN
0xbB55b164...20f310605
0.00445962 ETH0.0024336717.50275233
Pay From Ether A...196363892024-04-12 1:56:35106 days ago1712886995IN
0xbB55b164...20f310605
0.04907563 ETH0.0019821613.94565901
Pay And Notify195975962024-04-06 15:31:11111 days ago1712417471IN
0xbB55b164...20f310605
0 ETH0.0023751818.06087115
Pay From Ether A...195819592024-04-04 10:58:47113 days ago1712228327IN
0xbB55b164...20f310605
0.22039218 ETH0.0041834919.03814687
Pay From Ether A...195818792024-04-04 10:42:35113 days ago1712227355IN
0xbB55b164...20f310605
0.21679112 ETH0.0032411122.60948561
Pay From Ether A...195764732024-04-03 16:35:47114 days ago1712162147IN
0xbB55b164...20f310605
0.01740213 ETH0.0064684746.02553803
Pay From Ether A...195756932024-04-03 13:58:47114 days ago1712152727IN
0xbB55b164...20f310605
0.01747804 ETH0.0056854840.45427292
Pay And Notify195640682024-04-01 22:51:59116 days ago1712011919IN
0xbB55b164...20f310605
0 ETH0.0033113924.48207274
Pay From Ether A...195351482024-03-28 21:18:23120 days ago1711660703IN
0xbB55b164...20f310605
0.20488392 ETH0.0098011741.55806529
Pay From Ether A...195314692024-03-28 8:38:11120 days ago1711615091IN
0xbB55b164...20f310605
0.16225433 ETH0.0032707525.90655306
Pay From Ether A...195314222024-03-28 8:28:47120 days ago1711614527IN
0xbB55b164...20f310605
0.12155966 ETH0.0031554922.15702686
Pay From Ether A...195239172024-03-27 6:31:59121 days ago1711521119IN
0xbB55b164...20f310605
0.00803066 ETH0.0033804524.21462365
Pay And Notify193253092024-02-28 10:02:47149 days ago1709114567IN
0xbB55b164...20f310605
0 ETH0.0053555145.69673254
Pay From Ether A...192129822024-02-12 15:57:35165 days ago1707753455IN
0xbB55b164...20f310605
0.09913261 ETH0.0064454345.25812687
Pay From Ether A...191414552024-02-02 14:59:11175 days ago1706885951IN
0xbB55b164...20f310605
0.22746774 ETH0.0054850324.24786628
Pay From Ether A...191211942024-01-30 18:45:11178 days ago1706640311IN
0xbB55b164...20f310605
0.16771315 ETH0.0040057228.12711037
Pay From Ether A...190780782024-01-24 17:46:47184 days ago1706118407IN
0xbB55b164...20f310605
0.00652775 ETH0.0018262513.13427096
Pay And Notify190189472024-01-16 10:47:35192 days ago1705402055IN
0xbB55b164...20f310605
0 ETH0.0042421635.43165217
Pay And Notify190187372024-01-16 10:04:59192 days ago1705399499IN
0xbB55b164...20f310605
0 ETH0.0041199734.68601597
Pay From Ether A...190051562024-01-14 12:34:11194 days ago1705235651IN
0xbB55b164...20f310605
1.21627213 ETH0.0079355454.64274793
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
196427642024-04-12 23:22:11105 days ago1712964131
0xbB55b164...20f310605
0.00004459 ETH
196427642024-04-12 23:22:11105 days ago1712964131
0xbB55b164...20f310605
0.00441503 ETH
196363892024-04-12 1:56:35106 days ago1712886995
0xbB55b164...20f310605
0.00034129 ETH
196363892024-04-12 1:56:35106 days ago1712886995
0xbB55b164...20f310605
0.04873434 ETH
195819592024-04-04 10:58:47113 days ago1712228327
0xbB55b164...20f310605
0.0022037 ETH
195819592024-04-04 10:58:47113 days ago1712228327
0xbB55b164...20f310605
0.0022037 ETH
195819592024-04-04 10:58:47113 days ago1712228327
0xbB55b164...20f310605
0.22039218 ETH
195818792024-04-04 10:42:35113 days ago1712227355
0xbB55b164...20f310605
0.00216769 ETH
195818792024-04-04 10:42:35113 days ago1712227355
0xbB55b164...20f310605
0.21462343 ETH
195764732024-04-03 16:35:47114 days ago1712162147
0xbB55b164...20f310605
0.00026133 ETH
195764732024-04-03 16:35:47114 days ago1712162147
0xbB55b164...20f310605
0.01714079 ETH
195756932024-04-03 13:58:47114 days ago1712152727
0xbB55b164...20f310605
0.00017476 ETH
195756932024-04-03 13:58:47114 days ago1712152727
0xbB55b164...20f310605
0.01730328 ETH
195351482024-03-28 21:18:23120 days ago1711660703
0xbB55b164...20f310605
0.00204863 ETH
195351482024-03-28 21:18:23120 days ago1711660703
0xbB55b164...20f310605
0.00204863 ETH
195351482024-03-28 21:18:23120 days ago1711660703
0xbB55b164...20f310605
0.20488392 ETH
195314692024-03-28 8:38:11120 days ago1711615091
0xbB55b164...20f310605
0.00162238 ETH
195314692024-03-28 8:38:11120 days ago1711615091
0xbB55b164...20f310605
0.16063194 ETH
195314222024-03-28 8:28:47120 days ago1711614527
0xbB55b164...20f310605
0.00121547 ETH
195314222024-03-28 8:28:47120 days ago1711614527
0xbB55b164...20f310605
0.12034418 ETH
195239172024-03-27 6:31:59121 days ago1711521119
0xbB55b164...20f310605
0.00008029 ETH
195239172024-03-27 6:31:59121 days ago1711521119
0xbB55b164...20f310605
0.00795036 ETH
192129822024-02-12 15:57:35165 days ago1707753455
0xbB55b164...20f310605
0.00099122 ETH
192129822024-02-12 15:57:35165 days ago1707753455
0xbB55b164...20f310605
0.09814138 ETH
191414552024-02-02 14:59:11175 days ago1706885951
0xbB55b164...20f310605
0.00227445 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PaymentHub

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
File 1 of 8 : PaymentHub.sol
/**
* SPDX-License-Identifier: LicenseRef-Aktionariat
*
* MIT License with Automated License Fee Payments
*
* Copyright (c) 2021 Aktionariat AG (aktionariat.com)
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* - The above copyright notice and this permission notice shall be included in
*   all copies or substantial portions of the Software.
* - All automated license fee payments integrated into this and related Software
*   are preserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.0;

import "../utils/Address.sol";
import "../ERC20/IERC20.sol";
import "../ERC20/IERC20Permit.sol";
import "./IUniswapV3.sol";
import "../utils/Ownable.sol";
import "./IBrokerbot.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

/**
 * A hub for payments. This allows tokens that do not support ERC 677 to enjoy similar functionality,
 * namely interacting with a token-handling smart contract in one transaction, without having to set an allowance first.
 * Instead, an allowance needs to be set only once, namely for this contract.
 * Further, it supports automatic conversion from Ether to the payment currency through Uniswap or the reception of Ether
 * using the current exchange rate as found in the chainlink oracle.
 */
contract PaymentHub {

    address public trustedForwarder;

    uint24 private constant DEFAULT_FEE = 3000;
    uint256 private constant DENOMINATOR = 1e8;
    address private constant CHF_TOKEN = 0xB4272071eCAdd69d933AdcD19cA99fe80664fc08;

    uint8 private constant KEEP_ETHER = 0x4; // copied from brokerbot
    
    IQuoter private immutable uniswapQuoter;
    ISwapRouter private immutable uniswapRouter;
    AggregatorV3Interface internal immutable priceFeedCHFUSD;
    AggregatorV3Interface internal immutable priceFeedETHUSD;

    event ForwarderChanged(address _oldForwarder, address _newForwarder);

    constructor(address _trustedForwarder, IQuoter _quoter, ISwapRouter swapRouter, AggregatorV3Interface _aggregatorCHFUSD, AggregatorV3Interface _aggregatorETHUSD) {
        trustedForwarder = _trustedForwarder;
        uniswapQuoter = _quoter;
        uniswapRouter = swapRouter;
        priceFeedCHFUSD = _aggregatorCHFUSD;
        priceFeedETHUSD = _aggregatorETHUSD;
    }

    function changeForwarder(address newForwarder) external {
        require(msg.sender == trustedForwarder, "not forwarder");
        trustedForwarder = newForwarder;
        emit ForwarderChanged(msg.sender, newForwarder);
    }

    /*  
     * Get price in ERC20
     * This is the method that the Brokerbot widget should use to quote the price to the user.
     * @param amountInBase The amount of the base currency for the exact output.
     * @param path The encoded path of the swap from erc20 to base.
     * @return amount quoted to pay
     */
    function getPriceInERC20(uint256 amountInBase, bytes memory path) public returns (uint256) {
        return uniswapQuoter.quoteExactOutput(
            path,
            amountInBase
        );
    }

    /**
     * Get price in Ether depding on brokerbot setting.
     * If keep ETH is set price is from oracle.
     * This is the method that the Brokerbot widget should use to quote the price to the user.
     * @return The price in wei.
     */
    function getPriceInEther(uint256 amountInBase, IBrokerbot brokerBot) public returns (uint256) {
        if ((address(brokerBot) != address(0)) && hasSettingKeepEther(brokerBot)) {
            return getPriceInEtherFromOracle(amountInBase, IBrokerbot(brokerBot).base());
        } else {
            return uniswapQuoter.quoteExactOutputSingle(uniswapQuoter.WETH9(), address(brokerBot.base()), DEFAULT_FEE, amountInBase, 0);
        }
    }

    /**
     * Price in ETH with 18 decimals
     */
    function getPriceInEtherFromOracle(uint256 amountInBase, IERC20 base) public view returns (uint256) {
        if(address(base) == CHF_TOKEN) {
            return getLatestPriceCHFUSD() * amountInBase / getLatestPriceETHUSD();
        } else {
            return amountInBase * DENOMINATOR / getLatestPriceETHUSD();
        }
    }

    /**
     * Returns the latest price of eth/usd pair from chainlink with 8 decimals
     */
    function getLatestPriceETHUSD() public view returns (uint256) {
        (, int256 price, , , ) = priceFeedETHUSD.latestRoundData();
        return uint256(price);
    }

    /**
     * Returns the latest price of chf/usd pair from chainlink with 8 decimals
     */
    function getLatestPriceCHFUSD() public view returns (uint256) {
        (, int256 price, , , ) = priceFeedCHFUSD.latestRoundData();
        return uint256(price);
    }

    /**
     * Convenience method to swap ether into base and pay a target address
     */
    function payFromEther(address recipient, uint256 amountInBase, IERC20 base) public payable {
        ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
            // rely on time stamp is ok, no exact time stamp needed
            // solhint-disable-next-line not-rely-on-time
            uniswapQuoter.WETH9(), address(base), DEFAULT_FEE, recipient, block.timestamp, amountInBase, msg.value, 0);

        ISwapRouter swapRouter = uniswapRouter;
        // Executes the swap returning the amountIn needed to spend to receive the desired amountOut.
        uint256 amountIn = swapRouter.exactOutputSingle{value: msg.value}(params);

        // For exact output swaps, the amountInMaximum may not have all been spent.
        // If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0.
        if (amountIn < msg.value) {
            swapRouter.refundETH();
            (bool success, ) = msg.sender.call{value:msg.value - amountIn}(""); // return change
            require(success, "Transfer failed.");
        }
    }

    /// @dev The calling address must approve this contract to spend its ERC20 for this function to succeed. As the amount of input ERC20 is variable,
    /// the calling address will need to approve for a slightly higher or infinit amount, anticipating some variance.
    /// @param amountOut The desired amount of baseCurrency.
    /// @param amountInMaximum The maximum amount of ERC20 willing to be swapped for the specified amountOut of baseCurrency.
    /// @param erc20In The address of the erc20 token to pay with.
    /// @param path The encoded path of the swap from erc20 to base.
    /// @param recipient The reciving address - brokerbot.
    /// @return amountIn The amountIn of ERC20 actually spent to receive the desired amountOut.
    function payFromERC20(uint256 amountOut, uint256 amountInMaximum, address erc20In, bytes memory path, address recipient) public returns (uint256 amountIn) {
        ISwapRouter swapRouter = uniswapRouter;
        // Transfer the specified `amountInMaximum` to this contract.
        IERC20(erc20In).transferFrom(msg.sender, address(this), amountInMaximum);

        // The parameter path is encoded as (tokenOut, fee, tokenIn/tokenOut, fee, tokenIn)
        ISwapRouter.ExactOutputParams memory params =
            ISwapRouter.ExactOutputParams({
                path: path,
                recipient: recipient,
                // solhint-disable-next-line not-rely-on-time
                deadline: block.timestamp,
                amountOut: amountOut,
                amountInMaximum: amountInMaximum
            });

        // Executes the swap, returning the amountIn actually spent.
        amountIn = swapRouter.exactOutput(params);

        // If the swap did not require the full amountInMaximum to achieve the exact amountOut then we refund msg.sender and approve the router to spend 0.
        if (amountIn < amountInMaximum) {
            IERC20(erc20In).transfer(msg.sender, amountInMaximum - amountIn);
        }
    }

    ///This function appoves infinite allowance for Uniswap, this is safe as the paymenthub should never hold any token (see also recover() ).
    ///@dev This function needs to be called before using the PaymentHub the first time with a new ERC20 token.
    ///@param erc20In The erc20 addresse to approve.
    function approveERC20(address erc20In) external {
        IERC20(erc20In).approve(address(uniswapRouter), 0x8000000000000000000000000000000000000000000000000000000000000000);
    }

    function multiPay(IERC20 token, address[] calldata recipients, uint256[] calldata amounts) public {
        for (uint i=0; i<recipients.length; i++) {
            require(IERC20(token).transferFrom(msg.sender, recipients[i], amounts[i]));
        }
    }

    /**
     * Can (at least in theory) save some gas as the sender balance only is touched in one transaction.
     */
    function multiPayAndNotify(IERC20 token, address[] calldata recipients, uint256[] calldata amounts, bytes calldata ref) external {
        for (uint i=0; i<recipients.length; i++) {
            payAndNotify(token, recipients[i], amounts[i], ref);
        }
    }

    // Allows to make a payment from the sender to an address given an allowance to this contract
    // Equivalent to xchf.transferAndCall(recipient, amountInBase)
    function payAndNotify(address recipient, uint256 amountInBase, bytes calldata ref) external {
        payAndNotify(IBrokerbot(recipient).base(), recipient, amountInBase, ref);
    }

    function payAndNotify(IERC20 token, address recipient, uint256 amount, bytes calldata ref) public {
        require(IERC20(token).transferFrom(msg.sender, recipient, amount));
        IBrokerbot(recipient).processIncoming(token, msg.sender, amount, ref);
    }

    function payFromEtherAndNotify(IBrokerbot recipient, uint256 amountInBase, bytes calldata ref) external payable {
        IERC20 base = recipient.base();
        // Check if the brokerbot has setting to keep ETH
        if (hasSettingKeepEther(recipient)) {
            uint256 priceInEther = getPriceInEtherFromOracle(amountInBase, base);
            recipient.processIncoming{value: priceInEther}(base, msg.sender, amountInBase, ref);

            // Pay back ETH that was overpaid
            if (priceInEther < msg.value) {
                (bool success, ) = msg.sender.call{value:msg.value - priceInEther}(""); // return change
                require(success, "Transfer failed.");
            }

        } else {
            payFromEther(address(recipient), amountInBase, base);
            recipient.processIncoming(base, msg.sender, amountInBase, ref);
        }
    }

    /***
     * Pay from any ERC20 token (which has Uniswapv3 ERC20-ETH pool) and send swapped base currency to brokerbot.
     * The needed amount needs to be approved at the ERC20 contract beforehand
     */
    function payFromERC20AndNotify(address recipient, uint256 amountBase, address erc20, uint256 amountInMaximum, bytes memory path, bytes calldata ref) external {
        IERC20 base = IBrokerbot(recipient).base();
        uint256 balanceBefore = IERC20(base).balanceOf(recipient);
        payFromERC20(amountBase, amountInMaximum, erc20, path, recipient);
        uint256 balanceAfter = IERC20(base).balanceOf(recipient);
        require(amountBase == (balanceAfter - balanceBefore), "swap error");
        IBrokerbot(recipient).processIncoming(base, msg.sender, balanceAfter - balanceBefore, ref);
    }

    /**
     * @notice Sell shares with permit
     * 
     * @param recipient The brokerbot to recive the shares.
     * @param seller The address of the seller.
     * @param amountToSell The amount the seller wants to sell.
     * @param deadline The deadline of the permit.
     * @param ref Reference of the insider declaration and the type of sell.
     * @param v Part of the permit signature.
     * @param r Part of the permit signature.
     * @param s Part of the permit signature.
     */
    function sellSharesWithPermit(address recipient, address seller, uint256 amountToSell, uint256 exFee, uint256 deadline, bytes calldata ref, uint8 v, bytes32 r, bytes32 s) external {
        require(msg.sender == trustedForwarder || msg.sender == seller, "not trusted");
        IERC20Permit token = IBrokerbot(recipient).token();
        // Call permit 
        token.permit(seller, address(this), amountToSell, deadline, v, r,s);
        // send token to brokerbot
        token.transferFrom(seller, recipient, amountToSell);
        // process sell
        if (exFee > 0){
            uint256 proceeds = IBrokerbot(recipient).processIncoming(IERC20(token), address(this), amountToSell, ref);
            IERC20 currency = IBrokerbot(recipient).base();
            currency.transfer(msg.sender, exFee);
            currency.transfer(seller, proceeds - exFee);
        } else {
            IBrokerbot(recipient).processIncoming(IERC20(token), seller, amountToSell, ref);
        }
    }
    
    /**
     * Checks if the recipient(brokerbot) has setting enabled to keep ether
     */
    function hasSettingKeepEther(IBrokerbot recipient) public view returns (bool) {
        return recipient.settings() & KEEP_ETHER == KEEP_ETHER;
    }

    /**
     * In case tokens have been accidentally sent directly to this contract.
     * Make sure to be fast as anyone can call this!
     */
    function recover(IERC20 ercAddress, address to, uint256 amount) external {
        require(ercAddress.transfer(to, amount));
    }

    // solhint-disable-next-line no-empty-blocks
    receive() external payable {
        // Important to receive ETH refund from Uniswap
    }
}

File 2 of 8 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}

File 3 of 8 : IERC20.sol
/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2016-2019 zOS Global Limited
*
*/
pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */

interface IERC20 {

    // Optional functions
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    /**
     * @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.
     *
     * > 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 8 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
// Copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/draft-IERC20Permit.sol

pragma solidity ^0.8.0;

import "./IERC20.sol";

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit is IERC20 {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 5 of 8 : IBrokerbot.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../ERC20/IERC20.sol";
import "../ERC20/IERC20Permit.sol";

interface IBrokerbot {

  function base() external view returns (IERC20);

  function token() external view returns (IERC20Permit);
  
  function settings() external view returns (uint256);

  // @return The amount of shares bought on buying or how much in the base currency is transfered on selling
  function processIncoming(IERC20 token_, address from, uint256 amount, bytes calldata ref) external payable returns (uint256);

}

File 6 of 8 : IUniswapV3.sol
// SPDX-License-Identifier: MIT
// https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/IQuoter.sol
pragma solidity ^0.8.0;

interface IQuoter {
    function quoteExactOutputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountOut,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountIn);

    /// @notice Returns the amount in required for a given exact output swap without executing the swap
    /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order
    /// @param amountOut The amount of the last token to receive
    /// @return amountIn The amount of first token required to be paid
    function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn);
    
    // solhint-disable-next-line func-name-mixedcase
    function WETH9() external view returns (address);
}

interface ISwapRouter {
    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
    
    function refundETH() external payable;
}

File 7 of 8 : Address.sol
// SPDX-License-Identifier: MIT
// Copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol
// and modified it.

pragma solidity ^0.8.0;

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/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.
        return account.code.length > 0;
    }

    function functionCallWithValue(address target, bytes memory data, uint256 weiValue) internal returns (bytes memory) {
        require(data.length == 0 || isContract(target), "transfer or contract");
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else if (returndata.length > 0) {
            assembly{
                revert (add (returndata, 0x20), mload (returndata))
            }
        } else {
           revert("failed");
        }
    }
}

File 8 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
//
// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
//
// Modifications:
// - Replaced Context._msgSender() with msg.sender
// - Made leaner
// - Extracted interface

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable {

    address public owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor (address initialOwner) {
        owner = initialOwner;
        emit OwnershipTransferred(address(0), owner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) external onlyOwner {
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }

    modifier onlyOwner() {
        require(owner == msg.sender, "not owner");
        _;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"contract IQuoter","name":"_quoter","type":"address"},{"internalType":"contract ISwapRouter","name":"swapRouter","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"_aggregatorCHFUSD","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"_aggregatorETHUSD","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oldForwarder","type":"address"},{"indexed":false,"internalType":"address","name":"_newForwarder","type":"address"}],"name":"ForwarderChanged","type":"event"},{"inputs":[{"internalType":"address","name":"erc20In","type":"address"}],"name":"approveERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newForwarder","type":"address"}],"name":"changeForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLatestPriceCHFUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestPriceETHUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"bytes","name":"path","type":"bytes"}],"name":"getPriceInERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"contract IBrokerbot","name":"brokerBot","type":"address"}],"name":"getPriceInEther","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"contract IERC20","name":"base","type":"address"}],"name":"getPriceInEtherFromOracle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBrokerbot","name":"recipient","type":"address"}],"name":"hasSettingKeepEther","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"multiPay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"ref","type":"bytes"}],"name":"multiPayAndNotify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"bytes","name":"ref","type":"bytes"}],"name":"payAndNotify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"ref","type":"bytes"}],"name":"payAndNotify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"},{"internalType":"address","name":"erc20In","type":"address"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"}],"name":"payFromERC20","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountBase","type":"uint256"},{"internalType":"address","name":"erc20","type":"address"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"ref","type":"bytes"}],"name":"payFromERC20AndNotify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"contract IERC20","name":"base","type":"address"}],"name":"payFromEther","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IBrokerbot","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountInBase","type":"uint256"},{"internalType":"bytes","name":"ref","type":"bytes"}],"name":"payFromEtherAndNotify","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"ercAddress","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"amountToSell","type":"uint256"},{"internalType":"uint256","name":"exFee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"ref","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"sellSharesWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"trustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b50604051620025b3380380620025b3833981016040819052620000359162000086565b600080546001600160a01b039096166001600160a01b0319909616959095179094556001600160601b0319606093841b811660805291831b821660a052821b811660c05291901b1660e0526200011f565b600080600080600060a086880312156200009f57600080fd5b8551620000ac8162000106565b6020870151909550620000bf8162000106565b6040870151909450620000d28162000106565b6060870151909350620000e58162000106565b6080870151909250620000f88162000106565b809150509295509295909350565b6001600160a01b03811681146200011c57600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c61242b6200018860003960006110bd0152600061039501526000818161074c01528181610eb7015261126a0152600081816106a301528181610dc9015281816114f0015261151f015261242b6000f3fe6080604052600436106101175760003560e01c8063568f3254116100a0578063c1d8e08a11610064578063c1d8e08a146102e0578063d3b3ca7714610310578063d64d4ba514610330578063e25b37c614610350578063e347bb601461037057600080fd5b8063568f3254146102405780635daf206a146102605780636fb0c7dc146102805780637da0a8771461029357806395fe863c146102cb57600080fd5b806317f565d2116100e757806317f565d2146101a05780631945b784146101c05780631c9af2e3146101e05780631ec82cb814610200578063415a21871461022057600080fd5b8062124e3d14610123578063040c037a1461014b578063078aa9641461016057806311e8701c1461018057600080fd5b3661011e57005b600080fd5b34801561012f57600080fd5b50610138610390565b6040519081526020015b60405180910390f35b61015e610159366004611e1e565b61042f565b005b34801561016c57600080fd5b5061013861017b3660046120aa565b610689565b34801561018c57600080fd5b5061015e61019b366004611c86565b610735565b3480156101ac57600080fd5b5061015e6101bb366004611e1e565b6107de565b3480156101cc57600080fd5b506101386101db3660046120f1565b610861565b3480156101ec57600080fd5b5061015e6101fb366004611f92565b6108ca565b34801561020c57600080fd5b5061015e61021b366004611ede565b6109b0565b34801561022c57600080fd5b5061015e61023b366004611c86565b610a40565b34801561024c57600080fd5b5061015e61025b366004612004565b610ae5565b34801561026c57600080fd5b5061015e61027b366004611d7b565b610b57565b61015e61028e366004611e7a565b610db9565b34801561029f57600080fd5b506000546102b3906001600160a01b031681565b6040516001600160a01b039091168152602001610142565b3480156102d757600080fd5b506101386110b8565b3480156102ec57600080fd5b506103006102fb366004611c86565b611114565b6040519015158152602001610142565b34801561031c57600080fd5b5061015e61032b366004611f1f565b611199565b34801561033c57600080fd5b5061013861034b366004612121565b611258565b34801561035c57600080fd5b5061013861036b3660046120f1565b611456565b34801561037c57600080fd5b5061015e61038b366004611cc7565b6116b5565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156103ec57600080fd5b505afa158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190612199565b509195945050505050565b6000846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561046a57600080fd5b505afa15801561047e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611caa565b90506104ad85611114565b156105ef5760006104be8583610861565b9050856001600160a01b03166369365c528284338989896040518763ffffffff1660e01b81526004016104f595949392919061227c565b6020604051808303818588803b15801561050e57600080fd5b505af1158015610522573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105479190612091565b50348110156105e95760003361055d8334612369565b604051600081818185875af1925050503d8060008114610599576040519150601f19603f3d011682016040523d82523d6000602084013e61059e565b606091505b50509050806105e75760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064015b60405180910390fd5b505b50610682565b6105fa858583610db9565b60405163349b2e2960e11b81526001600160a01b038616906369365c529061062e908490339089908990899060040161227c565b602060405180830381600087803b15801561064857600080fd5b505af115801561065c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106809190612091565b505b5050505050565b604051632f80bb1d60e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632f80bb1d906106da908590879060040161225a565b602060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072c9190612091565b90505b92915050565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600160ff1b602483015282169063095ea7b390604401602060405180830381600087803b1580156107a257600080fd5b505af11580156107b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107da9190611ebc565b5050565b61085b846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561081a57600080fd5b505afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190611caa565b85858585611199565b50505050565b60006001600160a01b03821673b4272071ecadd69d933adcd19ca99fe80664fc0814156108b4576108906110b8565b83610899610390565b6108a3919061234a565b6108ad9190612328565b905061072f565b6108bc6110b8565b6108a36305f5e1008561234a565b60005b8381101561068057856001600160a01b03166323b872dd338787858181106108f7576108f76123b1565b905060200201602081019061090c9190611c86565b86868681811061091e5761091e6123b1565b905060200201356040518463ffffffff1660e01b815260040161094393929190612236565b602060405180830381600087803b15801561095d57600080fd5b505af1158015610971573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109959190611ebc565b61099e57600080fd5b806109a881612380565b9150506108cd565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156109fa57600080fd5b505af1158015610a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a329190611ebc565b610a3b57600080fd5b505050565b6000546001600160a01b03163314610a8a5760405162461bcd60e51b815260206004820152600d60248201526c3737ba103337b93bb0b93232b960991b60448201526064016105de565b600080546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527f6b1afd5bf12dcac0f44e8afd235c6681297d3124624a7a7a0d34abd84b798625910160405180910390a150565b60005b85811015610b4d57610b3b88888884818110610b0657610b066123b1565b9050602002016020810190610b1b9190611c86565b878785818110610b2d57610b2d6123b1565b905060200201358686611199565b80610b4581612380565b915050610ae8565b5050505050505050565b6000876001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190611caa565b6040516370a0823160e01b81526001600160a01b038a811660048301529192506000918316906370a082319060240160206040518083038186803b158015610c1157600080fd5b505afa158015610c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c499190612091565b9050610c58888789888d611258565b506040516370a0823160e01b81526001600160a01b038a81166004830152600091908416906370a082319060240160206040518083038186803b158015610c9e57600080fd5b505afa158015610cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd69190612091565b9050610ce28282612369565b8914610d1d5760405162461bcd60e51b815260206004820152600a60248201526939bbb0b81032b93937b960b11b60448201526064016105de565b6001600160a01b038a166369365c528433610d388686612369565b89896040518663ffffffff1660e01b8152600401610d5a95949392919061227c565b602060405180830381600087803b158015610d7457600080fd5b505af1158015610d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dac9190612091565b5050505050505050505050565b60006040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2057600080fd5b505afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e589190611caa565b6001600160a01b03168152602001836001600160a01b03168152602001610bb862ffffff168152602001856001600160a01b0316815260200142815260200184815260200134815260200160006001600160a01b0316815250905060007f000000000000000000000000000000000000000000000000000000000000000090506000816001600160a01b031663db3e219834856040518363ffffffff1660e01b8152600401610f6b919081516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b6020604051808303818588803b158015610f8457600080fd5b505af1158015610f98573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fbd9190612091565b90503481101561068057816001600160a01b03166312210e8a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561100257600080fd5b505af1158015611016573d6000803e3d6000fd5b506000925033915061102a90508334612369565b604051600081818185875af1925050503d8060008114611066576040519150601f19603f3d011682016040523d82523d6000602084013e61106b565b606091505b50509050806110af5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016105de565b50505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156103ec57600080fd5b6000600460ff16600460ff16836001600160a01b031663e06174e46040518163ffffffff1660e01b815260040160206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111919190612091565b161492915050565b6040516323b872dd60e01b81526001600160a01b038616906323b872dd906111c990339088908890600401612236565b602060405180830381600087803b1580156111e357600080fd5b505af11580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190611ebc565b61122457600080fd5b60405163349b2e2960e11b81526001600160a01b038516906369365c529061062e908890339088908890889060040161227c565b6040516323b872dd60e01b81526000907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b038616906323b872dd906112ad90339030908b90600401612236565b602060405180830381600087803b1580156112c757600080fd5b505af11580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ff9190611ebc565b506040805160a0810182528581526001600160a01b0380861660208301524282840152606082018a9052608082018990529151631e51809360e31b8152909183169063f28c0498906113559084906004016122d0565b602060405180830381600087803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190612091565b92508683101561144b576001600160a01b03861663a9059cbb336113cb868b612369565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561141157600080fd5b505af1158015611425573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114499190611ebc565b505b505095945050505050565b60006001600160a01b03821615801590611474575061147482611114565b156114ee576108ad83836001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101db9190611caa565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166330d07f217f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561157657600080fd5b505afa15801561158a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ae9190611caa565b846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156115e757600080fd5b505afa1580156115fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161f9190611caa565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152610bb86044820152606481018690526000608482015260a401602060405180830381600087803b15801561167d57600080fd5b505af1158015611691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ad9190612091565b6000546001600160a01b03163314806116d65750336001600160a01b038a16145b6117105760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd081d1c9d5cdd195960aa1b60448201526064016105de565b60008a6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561174b57600080fd5b505afa15801561175f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117839190611caa565b60405163d505accf60e01b81526001600160a01b038c81166004830152306024830152604482018c9052606482018a905260ff8716608483015260a4820186905260c482018590529192509082169063d505accf9060e401600060405180830381600087803b1580156117f557600080fd5b505af1158015611809573d6000803e3d6000fd5b50506040516323b872dd60e01b81526001600160a01b03841692506323b872dd915061183d908d908f908e90600401612236565b602060405180830381600087803b15801561185757600080fd5b505af115801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190611ebc565b508715611ab85760405163349b2e2960e11b81526000906001600160a01b038d16906369365c52906118cd90859030908f908d908d9060040161227c565b602060405180830381600087803b1580156118e757600080fd5b505af11580156118fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191f9190612091565b905060008c6001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561195c57600080fd5b505afa158015611970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119949190611caa565b60405163a9059cbb60e01b8152336004820152602481018c90529091506001600160a01b0382169063a9059cbb90604401602060405180830381600087803b1580156119df57600080fd5b505af11580156119f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a179190611ebc565b506001600160a01b03811663a9059cbb8d611a328d86612369565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611a7857600080fd5b505af1158015611a8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab09190611ebc565b505050610dac565b60405163349b2e2960e11b81526001600160a01b038c16906369365c5290611aec9084908e908e908c908c9060040161227c565b602060405180830381600087803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3e9190612091565b505050505050505050505050565b60008083601f840112611b5e57600080fd5b50813567ffffffffffffffff811115611b7657600080fd5b6020830191508360208260051b8501011115611b9157600080fd5b9250929050565b60008083601f840112611baa57600080fd5b50813567ffffffffffffffff811115611bc257600080fd5b602083019150836020828501011115611b9157600080fd5b600082601f830112611beb57600080fd5b813567ffffffffffffffff80821115611c0657611c066123c7565b604051601f8301601f19908116603f01168101908282118183101715611c2e57611c2e6123c7565b81604052838152866020858801011115611c4757600080fd5b836020870160208301376000602085830101528094505050505092915050565b805169ffffffffffffffffffff81168114611c8157600080fd5b919050565b600060208284031215611c9857600080fd5b8135611ca3816123dd565b9392505050565b600060208284031215611cbc57600080fd5b8151611ca3816123dd565b6000806000806000806000806000806101208b8d031215611ce757600080fd5b8a35611cf2816123dd565b995060208b0135611d02816123dd565b985060408b0135975060608b0135965060808b0135955060a08b013567ffffffffffffffff811115611d3357600080fd5b611d3f8d828e01611b98565b90965094505060c08b013560ff81168114611d5957600080fd5b8093505060e08b013591506101008b013590509295989b9194979a5092959850565b600080600080600080600060c0888a031215611d9657600080fd5b8735611da1816123dd565b9650602088013595506040880135611db8816123dd565b945060608801359350608088013567ffffffffffffffff80821115611ddc57600080fd5b611de88b838c01611bda565b945060a08a0135915080821115611dfe57600080fd5b50611e0b8a828b01611b98565b989b979a50959850939692959293505050565b60008060008060608587031215611e3457600080fd5b8435611e3f816123dd565b935060208501359250604085013567ffffffffffffffff811115611e6257600080fd5b611e6e87828801611b98565b95989497509550505050565b600080600060608486031215611e8f57600080fd5b8335611e9a816123dd565b9250602084013591506040840135611eb1816123dd565b809150509250925092565b600060208284031215611ece57600080fd5b81518015158114611ca357600080fd5b600080600060608486031215611ef357600080fd5b8335611efe816123dd565b92506020840135611f0e816123dd565b929592945050506040919091013590565b600080600080600060808688031215611f3757600080fd5b8535611f42816123dd565b94506020860135611f52816123dd565b935060408601359250606086013567ffffffffffffffff811115611f7557600080fd5b611f8188828901611b98565b969995985093965092949392505050565b600080600080600060608688031215611faa57600080fd5b8535611fb5816123dd565b9450602086013567ffffffffffffffff80821115611fd257600080fd5b611fde89838a01611b4c565b90965094506040880135915080821115611ff757600080fd5b50611f8188828901611b4c565b60008060008060008060006080888a03121561201f57600080fd5b873561202a816123dd565b9650602088013567ffffffffffffffff8082111561204757600080fd5b6120538b838c01611b4c565b909850965060408a013591508082111561206c57600080fd5b6120788b838c01611b4c565b909650945060608a0135915080821115611dfe57600080fd5b6000602082840312156120a357600080fd5b5051919050565b600080604083850312156120bd57600080fd5b82359150602083013567ffffffffffffffff8111156120db57600080fd5b6120e785828601611bda565b9150509250929050565b6000806040838503121561210457600080fd5b823591506020830135612116816123dd565b809150509250929050565b600080600080600060a0868803121561213957600080fd5b85359450602086013593506040860135612152816123dd565b9250606086013567ffffffffffffffff81111561216e57600080fd5b61217a88828901611bda565b925050608086013561218b816123dd565b809150509295509295909350565b600080600080600060a086880312156121b157600080fd5b6121ba86611c67565b94506020860151935060408601519250606086015191506121dd60808701611c67565b90509295509295909350565b6000815180845260005b8181101561220f576020818501810151868301820152016121f3565b81811115612221576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60408152600061226d60408301856121e9565b90508260208301529392505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b602081526000825160a060208401526122ec60c08401826121e9565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008261234557634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156123645761236461239b565b500290565b60008282101561237b5761237b61239b565b500390565b60006000198214156123945761239461239b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146123f257600080fd5b5056fea26469706673582212209c528e1856ffc4b54506d4b37f7a24c86dd955cc58161186376783ac371b306164736f6c6343000807003300000000000000000000000059f0941e75f2f77ca4577e48c3c5333a3f8d277b000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000449d117117838ffa61263b61da6301aa2a88b13a0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419

Deployed Bytecode

0x6080604052600436106101175760003560e01c8063568f3254116100a0578063c1d8e08a11610064578063c1d8e08a146102e0578063d3b3ca7714610310578063d64d4ba514610330578063e25b37c614610350578063e347bb601461037057600080fd5b8063568f3254146102405780635daf206a146102605780636fb0c7dc146102805780637da0a8771461029357806395fe863c146102cb57600080fd5b806317f565d2116100e757806317f565d2146101a05780631945b784146101c05780631c9af2e3146101e05780631ec82cb814610200578063415a21871461022057600080fd5b8062124e3d14610123578063040c037a1461014b578063078aa9641461016057806311e8701c1461018057600080fd5b3661011e57005b600080fd5b34801561012f57600080fd5b50610138610390565b6040519081526020015b60405180910390f35b61015e610159366004611e1e565b61042f565b005b34801561016c57600080fd5b5061013861017b3660046120aa565b610689565b34801561018c57600080fd5b5061015e61019b366004611c86565b610735565b3480156101ac57600080fd5b5061015e6101bb366004611e1e565b6107de565b3480156101cc57600080fd5b506101386101db3660046120f1565b610861565b3480156101ec57600080fd5b5061015e6101fb366004611f92565b6108ca565b34801561020c57600080fd5b5061015e61021b366004611ede565b6109b0565b34801561022c57600080fd5b5061015e61023b366004611c86565b610a40565b34801561024c57600080fd5b5061015e61025b366004612004565b610ae5565b34801561026c57600080fd5b5061015e61027b366004611d7b565b610b57565b61015e61028e366004611e7a565b610db9565b34801561029f57600080fd5b506000546102b3906001600160a01b031681565b6040516001600160a01b039091168152602001610142565b3480156102d757600080fd5b506101386110b8565b3480156102ec57600080fd5b506103006102fb366004611c86565b611114565b6040519015158152602001610142565b34801561031c57600080fd5b5061015e61032b366004611f1f565b611199565b34801561033c57600080fd5b5061013861034b366004612121565b611258565b34801561035c57600080fd5b5061013861036b3660046120f1565b611456565b34801561037c57600080fd5b5061015e61038b366004611cc7565b6116b5565b6000807f000000000000000000000000449d117117838ffa61263b61da6301aa2a88b13a6001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156103ec57600080fd5b505afa158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190612199565b509195945050505050565b6000846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561046a57600080fd5b505afa15801561047e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611caa565b90506104ad85611114565b156105ef5760006104be8583610861565b9050856001600160a01b03166369365c528284338989896040518763ffffffff1660e01b81526004016104f595949392919061227c565b6020604051808303818588803b15801561050e57600080fd5b505af1158015610522573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105479190612091565b50348110156105e95760003361055d8334612369565b604051600081818185875af1925050503d8060008114610599576040519150601f19603f3d011682016040523d82523d6000602084013e61059e565b606091505b50509050806105e75760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064015b60405180910390fd5b505b50610682565b6105fa858583610db9565b60405163349b2e2960e11b81526001600160a01b038616906369365c529061062e908490339089908990899060040161227c565b602060405180830381600087803b15801561064857600080fd5b505af115801561065c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106809190612091565b505b5050505050565b604051632f80bb1d60e01b81526000906001600160a01b037f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab61690632f80bb1d906106da908590879060040161225a565b602060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072c9190612091565b90505b92915050565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481166004830152600160ff1b602483015282169063095ea7b390604401602060405180830381600087803b1580156107a257600080fd5b505af11580156107b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107da9190611ebc565b5050565b61085b846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561081a57600080fd5b505afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190611caa565b85858585611199565b50505050565b60006001600160a01b03821673b4272071ecadd69d933adcd19ca99fe80664fc0814156108b4576108906110b8565b83610899610390565b6108a3919061234a565b6108ad9190612328565b905061072f565b6108bc6110b8565b6108a36305f5e1008561234a565b60005b8381101561068057856001600160a01b03166323b872dd338787858181106108f7576108f76123b1565b905060200201602081019061090c9190611c86565b86868681811061091e5761091e6123b1565b905060200201356040518463ffffffff1660e01b815260040161094393929190612236565b602060405180830381600087803b15801561095d57600080fd5b505af1158015610971573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109959190611ebc565b61099e57600080fd5b806109a881612380565b9150506108cd565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156109fa57600080fd5b505af1158015610a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a329190611ebc565b610a3b57600080fd5b505050565b6000546001600160a01b03163314610a8a5760405162461bcd60e51b815260206004820152600d60248201526c3737ba103337b93bb0b93232b960991b60448201526064016105de565b600080546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527f6b1afd5bf12dcac0f44e8afd235c6681297d3124624a7a7a0d34abd84b798625910160405180910390a150565b60005b85811015610b4d57610b3b88888884818110610b0657610b066123b1565b9050602002016020810190610b1b9190611c86565b878785818110610b2d57610b2d6123b1565b905060200201358686611199565b80610b4581612380565b915050610ae8565b5050505050505050565b6000876001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190611caa565b6040516370a0823160e01b81526001600160a01b038a811660048301529192506000918316906370a082319060240160206040518083038186803b158015610c1157600080fd5b505afa158015610c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c499190612091565b9050610c58888789888d611258565b506040516370a0823160e01b81526001600160a01b038a81166004830152600091908416906370a082319060240160206040518083038186803b158015610c9e57600080fd5b505afa158015610cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd69190612091565b9050610ce28282612369565b8914610d1d5760405162461bcd60e51b815260206004820152600a60248201526939bbb0b81032b93937b960b11b60448201526064016105de565b6001600160a01b038a166369365c528433610d388686612369565b89896040518663ffffffff1660e01b8152600401610d5a95949392919061227c565b602060405180830381600087803b158015610d7457600080fd5b505af1158015610d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dac9190612091565b5050505050505050505050565b60006040518061010001604052807f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab66001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2057600080fd5b505afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e589190611caa565b6001600160a01b03168152602001836001600160a01b03168152602001610bb862ffffff168152602001856001600160a01b0316815260200142815260200184815260200134815260200160006001600160a01b0316815250905060007f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156490506000816001600160a01b031663db3e219834856040518363ffffffff1660e01b8152600401610f6b919081516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b6020604051808303818588803b158015610f8457600080fd5b505af1158015610f98573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610fbd9190612091565b90503481101561068057816001600160a01b03166312210e8a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561100257600080fd5b505af1158015611016573d6000803e3d6000fd5b506000925033915061102a90508334612369565b604051600081818185875af1925050503d8060008114611066576040519150601f19603f3d011682016040523d82523d6000602084013e61106b565b606091505b50509050806110af5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016105de565b50505050505050565b6000807f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84196001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156103ec57600080fd5b6000600460ff16600460ff16836001600160a01b031663e06174e46040518163ffffffff1660e01b815260040160206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111919190612091565b161492915050565b6040516323b872dd60e01b81526001600160a01b038616906323b872dd906111c990339088908890600401612236565b602060405180830381600087803b1580156111e357600080fd5b505af11580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190611ebc565b61122457600080fd5b60405163349b2e2960e11b81526001600160a01b038516906369365c529061062e908890339088908890889060040161227c565b6040516323b872dd60e01b81526000907f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564906001600160a01b038616906323b872dd906112ad90339030908b90600401612236565b602060405180830381600087803b1580156112c757600080fd5b505af11580156112db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ff9190611ebc565b506040805160a0810182528581526001600160a01b0380861660208301524282840152606082018a9052608082018990529151631e51809360e31b8152909183169063f28c0498906113559084906004016122d0565b602060405180830381600087803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190612091565b92508683101561144b576001600160a01b03861663a9059cbb336113cb868b612369565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561141157600080fd5b505af1158015611425573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114499190611ebc565b505b505095945050505050565b60006001600160a01b03821615801590611474575061147482611114565b156114ee576108ad83836001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101db9190611caa565b7f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab66001600160a01b03166330d07f217f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab66001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561157657600080fd5b505afa15801561158a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ae9190611caa565b846001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156115e757600080fd5b505afa1580156115fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161f9190611caa565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152610bb86044820152606481018690526000608482015260a401602060405180830381600087803b15801561167d57600080fd5b505af1158015611691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ad9190612091565b6000546001600160a01b03163314806116d65750336001600160a01b038a16145b6117105760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd081d1c9d5cdd195960aa1b60448201526064016105de565b60008a6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561174b57600080fd5b505afa15801561175f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117839190611caa565b60405163d505accf60e01b81526001600160a01b038c81166004830152306024830152604482018c9052606482018a905260ff8716608483015260a4820186905260c482018590529192509082169063d505accf9060e401600060405180830381600087803b1580156117f557600080fd5b505af1158015611809573d6000803e3d6000fd5b50506040516323b872dd60e01b81526001600160a01b03841692506323b872dd915061183d908d908f908e90600401612236565b602060405180830381600087803b15801561185757600080fd5b505af115801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190611ebc565b508715611ab85760405163349b2e2960e11b81526000906001600160a01b038d16906369365c52906118cd90859030908f908d908d9060040161227c565b602060405180830381600087803b1580156118e757600080fd5b505af11580156118fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191f9190612091565b905060008c6001600160a01b0316635001f3b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561195c57600080fd5b505afa158015611970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119949190611caa565b60405163a9059cbb60e01b8152336004820152602481018c90529091506001600160a01b0382169063a9059cbb90604401602060405180830381600087803b1580156119df57600080fd5b505af11580156119f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a179190611ebc565b506001600160a01b03811663a9059cbb8d611a328d86612369565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611a7857600080fd5b505af1158015611a8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab09190611ebc565b505050610dac565b60405163349b2e2960e11b81526001600160a01b038c16906369365c5290611aec9084908e908e908c908c9060040161227c565b602060405180830381600087803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3e9190612091565b505050505050505050505050565b60008083601f840112611b5e57600080fd5b50813567ffffffffffffffff811115611b7657600080fd5b6020830191508360208260051b8501011115611b9157600080fd5b9250929050565b60008083601f840112611baa57600080fd5b50813567ffffffffffffffff811115611bc257600080fd5b602083019150836020828501011115611b9157600080fd5b600082601f830112611beb57600080fd5b813567ffffffffffffffff80821115611c0657611c066123c7565b604051601f8301601f19908116603f01168101908282118183101715611c2e57611c2e6123c7565b81604052838152866020858801011115611c4757600080fd5b836020870160208301376000602085830101528094505050505092915050565b805169ffffffffffffffffffff81168114611c8157600080fd5b919050565b600060208284031215611c9857600080fd5b8135611ca3816123dd565b9392505050565b600060208284031215611cbc57600080fd5b8151611ca3816123dd565b6000806000806000806000806000806101208b8d031215611ce757600080fd5b8a35611cf2816123dd565b995060208b0135611d02816123dd565b985060408b0135975060608b0135965060808b0135955060a08b013567ffffffffffffffff811115611d3357600080fd5b611d3f8d828e01611b98565b90965094505060c08b013560ff81168114611d5957600080fd5b8093505060e08b013591506101008b013590509295989b9194979a5092959850565b600080600080600080600060c0888a031215611d9657600080fd5b8735611da1816123dd565b9650602088013595506040880135611db8816123dd565b945060608801359350608088013567ffffffffffffffff80821115611ddc57600080fd5b611de88b838c01611bda565b945060a08a0135915080821115611dfe57600080fd5b50611e0b8a828b01611b98565b989b979a50959850939692959293505050565b60008060008060608587031215611e3457600080fd5b8435611e3f816123dd565b935060208501359250604085013567ffffffffffffffff811115611e6257600080fd5b611e6e87828801611b98565b95989497509550505050565b600080600060608486031215611e8f57600080fd5b8335611e9a816123dd565b9250602084013591506040840135611eb1816123dd565b809150509250925092565b600060208284031215611ece57600080fd5b81518015158114611ca357600080fd5b600080600060608486031215611ef357600080fd5b8335611efe816123dd565b92506020840135611f0e816123dd565b929592945050506040919091013590565b600080600080600060808688031215611f3757600080fd5b8535611f42816123dd565b94506020860135611f52816123dd565b935060408601359250606086013567ffffffffffffffff811115611f7557600080fd5b611f8188828901611b98565b969995985093965092949392505050565b600080600080600060608688031215611faa57600080fd5b8535611fb5816123dd565b9450602086013567ffffffffffffffff80821115611fd257600080fd5b611fde89838a01611b4c565b90965094506040880135915080821115611ff757600080fd5b50611f8188828901611b4c565b60008060008060008060006080888a03121561201f57600080fd5b873561202a816123dd565b9650602088013567ffffffffffffffff8082111561204757600080fd5b6120538b838c01611b4c565b909850965060408a013591508082111561206c57600080fd5b6120788b838c01611b4c565b909650945060608a0135915080821115611dfe57600080fd5b6000602082840312156120a357600080fd5b5051919050565b600080604083850312156120bd57600080fd5b82359150602083013567ffffffffffffffff8111156120db57600080fd5b6120e785828601611bda565b9150509250929050565b6000806040838503121561210457600080fd5b823591506020830135612116816123dd565b809150509250929050565b600080600080600060a0868803121561213957600080fd5b85359450602086013593506040860135612152816123dd565b9250606086013567ffffffffffffffff81111561216e57600080fd5b61217a88828901611bda565b925050608086013561218b816123dd565b809150509295509295909350565b600080600080600060a086880312156121b157600080fd5b6121ba86611c67565b94506020860151935060408601519250606086015191506121dd60808701611c67565b90509295509295909350565b6000815180845260005b8181101561220f576020818501810151868301820152016121f3565b81811115612221576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60408152600061226d60408301856121e9565b90508260208301529392505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b602081526000825160a060208401526122ec60c08401826121e9565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008261234557634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156123645761236461239b565b500290565b60008282101561237b5761237b61239b565b500390565b60006000198214156123945761239461239b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146123f257600080fd5b5056fea26469706673582212209c528e1856ffc4b54506d4b37f7a24c86dd955cc58161186376783ac371b306164736f6c63430008070033

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

00000000000000000000000059f0941e75f2f77ca4577e48c3c5333a3f8d277b000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000449d117117838ffa61263b61da6301aa2a88b13a0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419

-----Decoded View---------------
Arg [0] : _trustedForwarder (address): 0x59f0941e75f2F77cA4577E48c3c5333a3F8D277b
Arg [1] : _quoter (address): 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6
Arg [2] : swapRouter (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [3] : _aggregatorCHFUSD (address): 0x449d117117838fFA61263B61dA6301AA2a88B13A
Arg [4] : _aggregatorETHUSD (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000059f0941e75f2f77ca4577e48c3c5333a3f8d277b
Arg [1] : 000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6
Arg [2] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [3] : 000000000000000000000000449d117117838ffa61263b61da6301aa2a88b13a
Arg [4] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.