Contract 0xaf28cb0d9e045170e1642321b964740784e7dc64 10

Contract Overview

Balance:
0 MATIC
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x0184400e7751c41549ede0b8485e23ed2f01e86b25b0cdb593240de52c6e2106Swap Tokens For ...283383902022-09-28 10:38:401 min ago0x11ccc88363a75f75285e1dbaf12b993a8cb2d181 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.00027773462 2.529920024
0x26456f2d76dcadd45232b46d2fbfe8e7d5af1b3639b2bed198ad7e23d1125bf4Swap Tokens For ...283383892022-09-28 10:38:351 min ago0x9dbf11ba76b3c941968ae49d28786102c986a27c IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000278115521 2.533389701
0x81e694608e06bb2e9a5084f7c2b7c9ce67c6542bdd1a36314f52b8b1dddec8c8Swap Tokens For ...283383872022-09-28 10:38:251 min ago0x24082bdccdca1c9450c2c3e7c70e1ea9928027ed IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000278663247 2.542107186
0xbbd8f9325480fbeca296322dbe66a4283bbd1494c6e63a6ca5d9277b1cbb7108Swap Tokens For ...283383602022-09-28 10:36:093 mins ago0x4bc40616d00a041c9408da235e14d96110b78376 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000273775744 2.493426579
0x75f780089881bde92b4bd5af38db229c146e387b64eb0e938292fa299d8a2afeSwap Tokens For ...283383502022-09-28 10:35:194 mins ago0x972a6feb13309f056622e22cb6a22ba38edef28c IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000270250463 2.465361515
0xd7ddc7c852901579b97fb4eef1046e2fe9ceabcd9ee33a5edc7cb7d6b53dafb9Swap Tokens For ...283383432022-09-28 10:34:445 mins ago0x96cc8f637cca47c22bf91e960c96d718b3694fb5 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000269243374 2.456174339
0x580461b07fe77f625ac5f2f7b43daf073b9c3f8e04c95a85bfa246fcc1885855Swap Tokens For ...283383402022-09-28 10:34:295 mins ago0x50d00e0f7d0e56fc52d53b90d585b4c85d2f9c23 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000264245017 2.40662499
0x5c73f9c473a5406bed088c346f3b6fdebd2201329148aec4823598bf90d4bbe9Swap Tokens For ...283383372022-09-28 10:34:145 mins ago0x445e8d74bace06b88fdf24325e2ca3507d50fa63 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000263658816 2.400870685
0x35c14265fe7a26de6dee0222544661dd229b56c8603efceeff714fc3c041a2a5Swap Tokens For ...283383342022-09-28 10:33:596 mins ago0xd5152b333706145a1fea244c39ae010a297d9d27 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.00026841003 2.448572147
0xd9c2191804dc6585646fe1a0fd8d86e579ef69d52eb861028dc9053c4c385687Swap ETH For Tok...283383232022-09-28 10:33:047 mins ago0x3a1beec016b22767f78af398ccaeed8b69442233 IN  0xaf28cb0d9e045170e1642321b964740784e7dc641.007791067077643 MATIC0.000454720066 2.443457263
0x957104b78d2ee5e4c8993803ba769ac9a46bc5c016674477103477f6167bd361Swap Tokens For ...283383162022-09-28 10:32:297 mins ago0x353d47afed0d576abac71f8aafa770801f14da55 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000268236685 2.442979314
0xa77993280dbd9bcedf85ec96930f9d84c36a4f60dd9135723ecd74cbd19f4e3aSwap Tokens For ...283382822022-09-28 10:29:3810 mins ago0xa750399c9b7843bf495d9711987a33dcf0110d83 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267988001 2.441359223
0x8d7fd99e52ae541e45f3e9fccf8af7e536c30ddb19e69337927de1c4d1cff134Swap Tokens For ...283382702022-09-28 10:28:3811 mins ago0xd62c368ce6433b87e18fd97a79ee9eb131b715d6 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267755629 2.442602369
0xf7676e4f832e1ec9bbb5fe8173385b65f9980d21964bcc1531b9e8c3bd3f6c61Swap Tokens For ...283382642022-09-28 10:28:0811 mins ago0xcb155e496311315effde79e6ddb601e9ca8c1ddb IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267622472 2.441387647
0xa4111caf531dcb71a2c14b765da77a24096c367fc27c08c931ea53ca1d854c58Swap Tokens For ...283382442022-09-28 10:26:2813 mins ago0xc831f86b9dfa3023c55a14eb91f24a342a68ef17 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267761203 2.439293097
0xb1eb41ca6f93ae3584756b2b3aee53e79255933f400d453431474ecd70392e8fSwap Tokens For ...283382372022-09-28 10:25:5214 mins ago0x94881c16467335f67f80cd8237cd4f10f60d080b IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267649551 2.437631961
0xb303d1ff22151713283bb2d3656bdada169462c6e2b7e8078117538f7feec1ddSwap ETH For Tok...283382312022-09-28 10:25:2214 mins ago0xf7e7a61437b294315f3a1c949ab6619b2c9044df IN  0xaf28cb0d9e045170e1642321b964740784e7dc641 MATIC0.000445062358 2.389250192
0xaa87edb51481f8e7d917d65d0f5705fcca6dab09365713b746f0c0c0b1c060fdSwap Tokens For ...283382252022-09-28 10:24:5215 mins ago0x8530b061212141ed62ea53c38f9ba529394abcfe IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000259808871 2.36622257
0x5d9b41100dfbbf39f4688d62a7f254cb09d4586fc89f31a1d20ac71e5f9bca93Swap Tokens For ...283382162022-09-28 10:24:0715 mins ago0xbb7f86dc7451214313f9b1b57204bf31be01be3d IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267912628 2.440027948
0xb16339e94077f9bfa0b148ebeb2abf2eb9226606a84549da28719a6c61a5cdeeSwap Tokens For ...283382012022-09-28 10:22:5217 mins ago0xd4e19d923f7af5c01a3b9f46e57e34d9f1791592 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.0002672561 2.438045412
0xd909e8c20fc8d03fcc156e55038b306415e6d2ad7c1979ad6e86c8065a67bc29Swap Tokens For ...283381922022-09-28 10:22:0717 mins ago0x7f056d1e379a99425904de3cd427968b0ed8ea79 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267685885 2.43860696
0x27dc71dd2e73df044cc96a24ccc0f51a61da5626976baaa9ea7a34a0856a3783Swap Tokens For ...283381832022-09-28 10:21:2218 mins ago0xfe1cf4b8ae48467711f81930a5fa042f8dc7bd43 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000267788614 2.438898486
0xbaec2be2c89ba90b5f76e98588ce5d51585be021a597e05b1420fe7d3192a436Swap Tokens For ...283381822022-09-28 10:21:1718 mins ago0xcda48340d5df2d174c01220f3a4ca3d35a553eae IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.00016621749 1.513834284
0x523daa7fea858dc56e61110eb24b6004a8e1f9ed96ea82dce9bfa26993af08e3Swap Tokens For ...283381822022-09-28 10:21:1718 mins ago0x1d568834759fdaff19ada52b015ed5019aea808c IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.00016621749 1.513834284
0x050c676f8dcaa884aa1298e3a6f4200db5d350b3155343a9ac5ed6d9b220fb72Swap Tokens For ...283381792022-09-28 10:21:0219 mins ago0x56bb1365af07c56f7609fa7a6142f3d87c6fdf82 IN  0xaf28cb0d9e045170e1642321b964740784e7dc640 MATIC0.000263898669 2.403470607
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe2996f8da6d2732d21a3dfcef424a6c676a92b41f5213fbf0ba0e9f592dc9f9f283383522022-09-28 10:35:294 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x60a1cf5d0901a3add975399829e158cd444e88400.485449905109848333 MATIC
0xe2996f8da6d2732d21a3dfcef424a6c676a92b41f5213fbf0ba0e9f592dc9f9f283383522022-09-28 10:35:294 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.485449905109848333 MATIC
0xd9c2191804dc6585646fe1a0fd8d86e579ef69d52eb861028dc9053c4c385687283383232022-09-28 10:33:047 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc64 0xe592427a0aece92de3edee1f18e0157c058615641.007791067077643377 MATIC
0xd9c2191804dc6585646fe1a0fd8d86e579ef69d52eb861028dc9053c4c385687283383232022-09-28 10:33:047 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc64 0xaf28cb0d9e045170e1642321b964740784e7dc641.007791067077643377 MATIC
0x12afcd9003b918e6dc1dfa4e563f7259a4f6adb39023ba2832b76bd64ab64cc3283383212022-09-28 10:32:547 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x15d47eed1c14e0957f8ea2b0cf1246be0581897f0.516915000803286949 MATIC
0x12afcd9003b918e6dc1dfa4e563f7259a4f6adb39023ba2832b76bd64ab64cc3283383212022-09-28 10:32:547 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.516915000803286949 MATIC
0xf4aea32f214e7e9f8c89d79dd33ac9ab97b87cb31a797c8177a2bb0b42a9a7b4283382832022-09-28 10:29:4310 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x227ee48f81f4fd7595182546b057e82d86356ccd0.517071301885472868 MATIC
0xf4aea32f214e7e9f8c89d79dd33ac9ab97b87cb31a797c8177a2bb0b42a9a7b4283382832022-09-28 10:29:4310 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.517071301885472868 MATIC
0xb303d1ff22151713283bb2d3656bdada169462c6e2b7e8078117538f7feec1dd283382312022-09-28 10:25:2214 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc64 0xe592427a0aece92de3edee1f18e0157c058615641 MATIC
0xb303d1ff22151713283bb2d3656bdada169462c6e2b7e8078117538f7feec1dd283382312022-09-28 10:25:2214 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc64 0xaf28cb0d9e045170e1642321b964740784e7dc641 MATIC
0x36a990f7f509d90c41318446531478fe2dce167a2aec556b090d76c38406d987283382192022-09-28 10:24:2215 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x49f7c97c40c058a3cc7f76b8908b20132bf7cc080.683636703562583725 MATIC
0x36a990f7f509d90c41318446531478fe2dce167a2aec556b090d76c38406d987283382192022-09-28 10:24:2215 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.683636703562583725 MATIC
0x0f17a50d20e092ab4ea482c4f94a53f7fe6af67174571c9c017c54296512f40b283382192022-09-28 10:24:2215 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640xec57b52e2096bfc0330a8932e5cd0a42599612e45.237865550568874718 MATIC
0x0f17a50d20e092ab4ea482c4f94a53f7fe6af67174571c9c017c54296512f40b283382192022-09-28 10:24:2215 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc645.237865550568874718 MATIC
0xebdc0fe8258489f8d36e70f96583d6f27c7bca84ab817eab9c48d3cd7ec535c3283381832022-09-28 10:21:2218 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x06c4bb82d8dd291e9a642fe5cfa92408a4a7ad200.516480352942865661 MATIC
0xebdc0fe8258489f8d36e70f96583d6f27c7bca84ab817eab9c48d3cd7ec535c3283381832022-09-28 10:21:2218 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.516480352942865661 MATIC
0x574bf47e1777757563296c92adf90c86afd44e5297999211f4f2c65d21bef48c283381532022-09-28 10:18:5121 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x03c073544531f9e97205303e5046abc6ba11f2470.683880159783982163 MATIC
0x574bf47e1777757563296c92adf90c86afd44e5297999211f4f2c65d21bef48c283381532022-09-28 10:18:5121 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.683880159783982163 MATIC
0x2e896a3877a08077f0f3cbfb4c4af232b9a14d48d28b243528b71925edf04b22283381442022-09-28 10:18:0621 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x98942bbff33ccf8f87eed92b582c1daf5a40c70c0.683906028225382771 MATIC
0x2e896a3877a08077f0f3cbfb4c4af232b9a14d48d28b243528b71925edf04b22283381442022-09-28 10:18:0621 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.683906028225382771 MATIC
0x9efa1af28cd750b9d631e77fce87d65010d70a6f13789a9a939def7a2184c6c1283381352022-09-28 10:17:2122 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x6aee778b15b922bb1591b428c1f1ec0671ae95120.341696625276682483 MATIC
0x9efa1af28cd750b9d631e77fce87d65010d70a6f13789a9a939def7a2184c6c1283381352022-09-28 10:17:2122 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc640.341696625276682483 MATIC
0x7d7056bd5716ccf93178889a24f4bc949c2dce4ce4267496aee2db48ea57f418283381092022-09-28 10:15:1024 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x3578db872e9899d8bf0ff1198fdf8dba74ec37331.368441478707464047 MATIC
0x7d7056bd5716ccf93178889a24f4bc949c2dce4ce4267496aee2db48ea57f418283381092022-09-28 10:15:1024 mins ago 0x9c3c9283d3e44854697cd22d3faa240cfb032889 0xaf28cb0d9e045170e1642321b964740784e7dc641.368441478707464047 MATIC
0x4601d50913dc8a2d19b80b06fb291e173005d4eb338891d0508ff65b6d5834ab283380782022-09-28 10:12:3527 mins ago 0xaf28cb0d9e045170e1642321b964740784e7dc640x54936a49a7b00ae94d6f4b7c8357485804051bd60.518154792830952202 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiChainSwapUniV3

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 16 : MultiChainSwapUniV3.strategy.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@zetachain/protocol-contracts/contracts/ZetaTokenConsumerUniV3.strategy.sol";

import "./MultiChainSwapErrors.sol";
import "./MultiChainSwap.sol";

contract MultiChainSwapUniV3 is MultiChainSwap, ZetaInteractor, MultiChainSwapErrors, ZetaTokenConsumerUniV3 {
    using SafeERC20 for IERC20;
    bytes32 public constant CROSS_CHAIN_SWAP_MESSAGE = keccak256("CROSS_CHAIN_SWAP");

    constructor(
        address zetaConnector_,
        address zetaToken_,
        address uniswapV3Router_,
        address quoter_,
        address WETH9Address_,
        uint24 zetaPoolFee_,
        uint24 tokenPoolFee_
    )
        ZetaTokenConsumerUniV3(zetaToken_, uniswapV3Router_, quoter_, WETH9Address_, zetaPoolFee_, tokenPoolFee_)
        ZetaInteractor(zetaConnector_)
    {}

    function swapETHForTokensCrossChain(
        bytes calldata receiverAddress,
        address destinationOutToken,
        bool isDestinationOutETH,
        /**
         * @dev The minimum amount of tokens that receiverAddress should get,
         * if it's not reached, the transaction will revert on the destination chain
         */
        uint256 outTokenMinAmount,
        uint256 destinationChainId,
        uint256 crossChaindestinationGasLimit
    ) external payable override {
        if (!_isValidChainId(destinationChainId)) revert InvalidDestinationChainId();

        if (msg.value == 0) revert ValueShouldBeGreaterThanZero();
        if (
            (destinationOutToken != address(0) && isDestinationOutETH) ||
            (destinationOutToken == address(0) && !isDestinationOutETH)
        ) revert OutTokenInvariant();

        uint256 zetaValueAndGas = this.getZetaFromEth{value: msg.value}(
            address(this),
            0 /// @todo Add min amount
        );
        if (zetaValueAndGas == 0) revert ErrorSwappingTokens();

        IERC20(zetaToken).safeApprove(address(connector), zetaValueAndGas);

        connector.send(
            ZetaInterfaces.SendInput({
                destinationChainId: destinationChainId,
                destinationAddress: interactorsByChainId[destinationChainId],
                destinationGasLimit: crossChaindestinationGasLimit,
                message: abi.encode(
                    CROSS_CHAIN_SWAP_MESSAGE,
                    msg.sender,
                    WETH9Address,
                    msg.value,
                    receiverAddress,
                    destinationOutToken,
                    isDestinationOutETH,
                    outTokenMinAmount,
                    true // inputTokenIsETH
                ),
                zetaValueAndGas: zetaValueAndGas,
                zetaParams: abi.encode("")
            })
        );
    }

    function swapTokensForTokensCrossChain(
        address sourceInputToken,
        uint256 inputTokenAmount,
        bytes calldata receiverAddress,
        address destinationOutToken,
        bool isDestinationOutETH,
        /**
         * @dev The minimum amount of tokens that receiverAddress should get,
         * if it's not reached, the transaction will revert on the destination chain
         */
        uint256 outTokenMinAmount,
        uint256 destinationChainId,
        uint256 crossChaindestinationGasLimit
    ) external override {
        if (!_isValidChainId(destinationChainId)) revert InvalidDestinationChainId();

        if (sourceInputToken == address(0)) revert MissingSourceInputTokenAddress();
        if (
            (destinationOutToken != address(0) && isDestinationOutETH) ||
            (destinationOutToken == address(0) && !isDestinationOutETH)
        ) revert OutTokenInvariant();

        uint256 zetaValueAndGas;

        IERC20(sourceInputToken).safeTransferFrom(msg.sender, address(this), inputTokenAmount);

        if (sourceInputToken == zetaToken) {
            zetaValueAndGas = inputTokenAmount;
        } else {
            IERC20(sourceInputToken).safeApprove(address(this), inputTokenAmount);
            zetaValueAndGas = this.getZetaFromToken(
                address(this),
                0, /// @todo Add min amount
                sourceInputToken,
                inputTokenAmount
            );

            if (zetaValueAndGas == 0) revert ErrorSwappingTokens();
        }

        IERC20(zetaToken).safeApprove(address(connector), zetaValueAndGas);

        connector.send(
            ZetaInterfaces.SendInput({
                destinationChainId: destinationChainId,
                destinationAddress: interactorsByChainId[destinationChainId],
                destinationGasLimit: crossChaindestinationGasLimit,
                message: abi.encode(
                    CROSS_CHAIN_SWAP_MESSAGE,
                    msg.sender,
                    sourceInputToken,
                    inputTokenAmount,
                    receiverAddress,
                    destinationOutToken,
                    isDestinationOutETH,
                    outTokenMinAmount,
                    false // inputTokenIsETH
                ),
                zetaValueAndGas: zetaValueAndGas,
                zetaParams: abi.encode("")
            })
        );
    }

    function onZetaMessage(ZetaInterfaces.ZetaMessage calldata zetaMessage)
        external
        override
        isValidMessageCall(zetaMessage)
    {
        (
            bytes32 messageType,
            address sourceTxOrigin,
            address sourceInputToken,
            uint256 inputTokenAmount,
            bytes memory receiverAddressEncoded,
            address destinationOutToken,
            bool isDestinationOutETH,
            uint256 outTokenMinAmount,

        ) = abi.decode(zetaMessage.message, (bytes32, address, address, uint256, bytes, address, bool, uint256, bool));
        if (messageType != CROSS_CHAIN_SWAP_MESSAGE) revert InvalidMessageType();

        uint256 outTokenFinalAmount;
        if (destinationOutToken == zetaToken) {
            if (zetaMessage.zetaValue < outTokenMinAmount) revert InsufficientOutToken();

            IERC20(zetaToken).safeTransfer(address(uint160(bytes20(receiverAddressEncoded))), zetaMessage.zetaValue);

            outTokenFinalAmount = zetaMessage.zetaValue;
        } else {
            /**
             * @dev If the out token is not Zeta, get it using Uniswap
             */
            IERC20(zetaToken).safeApprove(address(this), zetaMessage.zetaValue);

            if (isDestinationOutETH) {
                outTokenFinalAmount = this.getEthFromZeta(
                    address(uint160(bytes20(receiverAddressEncoded))),
                    outTokenMinAmount,
                    zetaMessage.zetaValue
                );
            } else {
                outTokenFinalAmount = this.getTokenFromZeta(
                    address(uint160(bytes20(receiverAddressEncoded))),
                    outTokenMinAmount,
                    destinationOutToken,
                    zetaMessage.zetaValue
                );
            }

            if (outTokenFinalAmount == 0) revert ErrorSwappingTokens();
            if (outTokenFinalAmount < outTokenMinAmount) revert InsufficientOutToken();
        }

        emit Swapped(
            sourceTxOrigin,
            sourceInputToken,
            inputTokenAmount,
            destinationOutToken,
            outTokenFinalAmount,
            address(uint160(bytes20(receiverAddressEncoded)))
        );
    }

    function onZetaRevert(ZetaInterfaces.ZetaRevert calldata zetaRevert)
        external
        override
        isValidRevertCall(zetaRevert)
    {
        /**
         * @dev: If something goes wrong we must swap to the source input token
         */
        (
            ,
            address sourceTxOrigin,
            address sourceInputToken,
            uint256 inputTokenAmount,
            ,
            ,
            ,
            ,
            bool inputTokenIsETH
        ) = abi.decode(zetaRevert.message, (bytes32, address, address, uint256, bytes, address, bool, uint256, bool));

        uint256 inputTokenReturnedAmount;
        if (sourceInputToken == zetaToken) {
            IERC20(zetaToken).safeApprove(address(this), zetaRevert.remainingZetaValue);
            IERC20(zetaToken).safeTransferFrom(address(this), sourceTxOrigin, zetaRevert.remainingZetaValue);
            inputTokenReturnedAmount = zetaRevert.remainingZetaValue;
        } else {
            /**
             * @dev If the source input token is not Zeta, trade it using Uniswap
             */
            IERC20(zetaToken).safeApprove(address(this), zetaRevert.remainingZetaValue);

            if (inputTokenIsETH) {
                inputTokenReturnedAmount = this.getEthFromZeta(
                    sourceTxOrigin,
                    0, /// @todo Add min amount
                    zetaRevert.remainingZetaValue
                );
            } else {
                inputTokenReturnedAmount = this.getTokenFromZeta(
                    sourceTxOrigin,
                    0, /// @todo Add min amount
                    sourceInputToken,
                    zetaRevert.remainingZetaValue
                );
            }
        }

        emit RevertedSwap(sourceTxOrigin, sourceInputToken, inputTokenAmount, inputTokenReturnedAmount);
    }
}

File 2 of 16 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

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

File 3 of 16 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

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 4 of 16 : ZetaTokenConsumerUniV3.strategy.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol";

import "./interfaces/ZetaInterfaces.sol";

interface ZetaTokenConsumerUniV3Errors {
    error InvalidAddress();

    error InputCantBeZero();

    error ErrorSendingETH();

    error ReentrancyError();
}

interface WETH9 {
    function withdraw(uint256 wad) external;
}

/**
 * @dev Uniswap V3 strategy for ZetaTokenConsumer
 */
contract ZetaTokenConsumerUniV3 is ZetaTokenConsumer, ZetaTokenConsumerUniV3Errors {
    using SafeERC20 for IERC20;
    uint256 internal constant MAX_DEADLINE = 200;

    uint24 public immutable zetaPoolFee;
    uint24 public immutable tokenPoolFee;

    address internal immutable WETH9Address;
    address public immutable zetaToken;

    ISwapRouter public immutable uniswapV3Router;
    IQuoter public immutable quoter;

    bool internal _locked;

    constructor(
        address zetaToken_,
        address uniswapV3Router_,
        address quoter_,
        address WETH9Address_,
        uint24 zetaPoolFee_,
        uint24 tokenPoolFee_
    ) {
        if (
            zetaToken_ == address(0) ||
            uniswapV3Router_ == address(0) ||
            quoter_ == address(0) ||
            WETH9Address_ == address(0)
        ) revert InvalidAddress();

        zetaToken = zetaToken_;
        uniswapV3Router = ISwapRouter(uniswapV3Router_);
        quoter = IQuoter(quoter_);
        WETH9Address = WETH9Address_;
        zetaPoolFee = zetaPoolFee_;
        tokenPoolFee = tokenPoolFee_;
    }

    modifier nonReentrant() {
        if (_locked) revert ReentrancyError();
        _locked = true;
        _;
        _locked = false;
    }

    receive() external payable {}

    function getZetaFromEth(address destinationAddress, uint256 minAmountOut)
        external
        payable
        override
        returns (uint256)
    {
        if (destinationAddress == address(0)) revert InvalidAddress();
        if (msg.value == 0) revert InputCantBeZero();

        ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
            deadline: block.timestamp + MAX_DEADLINE,
            tokenIn: WETH9Address,
            tokenOut: zetaToken,
            fee: zetaPoolFee,
            recipient: destinationAddress,
            amountIn: msg.value,
            amountOutMinimum: minAmountOut,
            sqrtPriceLimitX96: 0
        });

        uint256 amountOut = uniswapV3Router.exactInputSingle{value: msg.value}(params);

        emit EthExchangedForZeta(msg.value, amountOut);
        return amountOut;
    }

    function getZetaFromToken(
        address destinationAddress,
        uint256 minAmountOut,
        address inputToken,
        uint256 inputTokenAmount
    ) external override returns (uint256) {
        if (destinationAddress == address(0) || inputToken == address(0)) revert InvalidAddress();
        if (inputTokenAmount == 0) revert InputCantBeZero();

        IERC20(inputToken).safeTransferFrom(msg.sender, address(this), inputTokenAmount);
        IERC20(inputToken).safeApprove(address(uniswapV3Router), inputTokenAmount);

        ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
            deadline: block.timestamp + MAX_DEADLINE,
            path: abi.encodePacked(inputToken, tokenPoolFee, WETH9Address, zetaPoolFee, zetaToken),
            recipient: destinationAddress,
            amountIn: inputTokenAmount,
            amountOutMinimum: minAmountOut
        });

        uint256 amountOut = uniswapV3Router.exactInput(params);

        emit TokenExchangedForZeta(inputToken, inputTokenAmount, amountOut);
        return amountOut;
    }

    function getEthFromZeta(
        address destinationAddress,
        uint256 minAmountOut,
        uint256 zetaTokenAmount
    ) external override returns (uint256) {
        if (destinationAddress == address(0)) revert InvalidAddress();
        if (zetaTokenAmount == 0) revert InputCantBeZero();

        IERC20(zetaToken).safeTransferFrom(msg.sender, address(this), zetaTokenAmount);
        IERC20(zetaToken).safeApprove(address(uniswapV3Router), zetaTokenAmount);

        ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
            deadline: block.timestamp + MAX_DEADLINE,
            tokenIn: zetaToken,
            tokenOut: WETH9Address,
            fee: zetaPoolFee,
            recipient: address(this),
            amountIn: zetaTokenAmount,
            amountOutMinimum: minAmountOut,
            sqrtPriceLimitX96: 0
        });

        uint256 amountOut = uniswapV3Router.exactInputSingle(params);

        WETH9(WETH9Address).withdraw(amountOut);

        emit ZetaExchangedForEth(zetaTokenAmount, amountOut);

        (bool sent, ) = destinationAddress.call{value: amountOut}("");
        if (!sent) revert ErrorSendingETH();

        return amountOut;
    }

    function getTokenFromZeta(
        address destinationAddress,
        uint256 minAmountOut,
        address outputToken,
        uint256 zetaTokenAmount
    ) external override nonReentrant returns (uint256) {
        if (destinationAddress == address(0) || outputToken == address(0)) revert InvalidAddress();
        if (zetaTokenAmount == 0) revert InputCantBeZero();

        IERC20(zetaToken).safeTransferFrom(msg.sender, address(this), zetaTokenAmount);
        IERC20(zetaToken).safeApprove(address(uniswapV3Router), zetaTokenAmount);

        ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
            deadline: block.timestamp + MAX_DEADLINE,
            path: abi.encodePacked(zetaToken, zetaPoolFee, WETH9Address, tokenPoolFee, outputToken),
            recipient: destinationAddress,
            amountIn: zetaTokenAmount,
            amountOutMinimum: minAmountOut
        });

        uint256 amountOut = uniswapV3Router.exactInput(params);

        emit ZetaExchangedForToken(outputToken, zetaTokenAmount, amountOut);
        return amountOut;
    }
}

File 5 of 16 : MultiChainSwapErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

interface MultiChainSwapErrors {
    error ErrorTransferringTokens(address token);

    error ErrorApprovingTokens(address token);

    error ErrorSwappingTokens();

    error ValueShouldBeGreaterThanZero();

    error OutTokenInvariant();

    error InsufficientOutToken();

    error MissingSourceInputTokenAddress();

    error InvalidMessageType();
}

File 6 of 16 : MultiChainSwap.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@zetachain/protocol-contracts/contracts/ZetaInteractor.sol";

interface MultiChainSwap is ZetaReceiver {
    event SentTokenSwap(
        address sourceTxOrigin,
        address sourceInputToken,
        uint256 inputTokenAmount,
        address destinationOutToken,
        uint256 outTokenMinAmount,
        address receiverAddress
    );

    event SentEthSwap(
        address sourceTxOrigin,
        uint256 inputEthAmount,
        address destinationOutToken,
        uint256 outTokenMinAmount,
        address receiverAddress
    );

    event Swapped(
        address sourceTxOrigin,
        address sourceInputToken,
        uint256 inputTokenAmount,
        address destinationOutToken,
        uint256 outTokenFinalAmount,
        address receiverAddress
    );

    event RevertedSwap(
        address sourceTxOrigin,
        address sourceInputToken,
        uint256 inputTokenAmount,
        uint256 inputTokenReturnedAmount
    );

    function swapETHForTokensCrossChain(
        bytes calldata receiverAddress,
        address destinationOutToken,
        bool isDestinationOutETH,
        /**
         * @dev The minimum amount of tokens that receiverAddress should get,
         * if it's not reached, the transaction will revert on the destination chain
         */
        uint256 outTokenMinAmount,
        uint256 destinationChainId,
        uint256 crossChaindestinationGasLimit
    ) external payable;

    function swapTokensForTokensCrossChain(
        address sourceInputToken,
        uint256 inputTokenAmount,
        bytes calldata receiverAddress,
        address destinationOutToken,
        bool isDestinationOutETH,
        /**
         * @dev The minimum amount of tokens that receiverAddress should get,
         * if it's not reached, the transaction will revert on the destination chain
         */
        uint256 outTokenMinAmount,
        uint256 destinationChainId,
        uint256 crossChaindestinationGasLimit
    ) external;
}

File 7 of 16 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 8 of 16 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 16 : ISwapRouter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

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

    /// @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);

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

    /// @notice Swaps as little as possible of one token for `amountOut` of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    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);
}

File 10 of 16 : IQuoter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

/// @title Quoter Interface
/// @notice Supports quoting the calculated amounts from exact input or exact output swaps
/// @dev These functions are not marked view because they rely on calling non-view functions and reverting
/// to compute the result. They are also not gas efficient and should not be called on-chain.
interface IQuoter {
    /// @notice Returns the amount out received for a given exact input swap without executing the swap
    /// @param path The path of the swap, i.e. each token pair and the pool fee
    /// @param amountIn The amount of the first token to swap
    /// @return amountOut The amount of the last token that would be received
    function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut);

    /// @notice Returns the amount out received for a given exact input but for a swap of a single pool
    /// @param tokenIn The token being swapped in
    /// @param tokenOut The token being swapped out
    /// @param fee The fee of the token pool to consider for the pair
    /// @param amountIn The desired input amount
    /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
    /// @return amountOut The amount of `tokenOut` that would be received
    function quoteExactInputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountIn,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountOut);

    /// @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);

    /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool
    /// @param tokenIn The token being swapped in
    /// @param tokenOut The token being swapped out
    /// @param fee The fee of the token pool to consider for the pair
    /// @param amountOut The desired output amount
    /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
    /// @return amountIn The amount required as the input for the swap in order to receive `amountOut`
    function quoteExactOutputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        uint256 amountOut,
        uint160 sqrtPriceLimitX96
    ) external returns (uint256 amountIn);
}

File 11 of 16 : ZetaInterfaces.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

interface ZetaInterfaces {
    /**
     * @dev Use SendInput to interact with the Connector: connector.send(SendInput)
     */
    struct SendInput {
        /// @dev Chain id of the destination chain. More about chain ids https://docs.zetachain.com/learn/glossary#chain-id
        uint256 destinationChainId;
        /// @dev Address receiving the message on the destination chain (expressed in bytes since it can be non-EVM)
        bytes destinationAddress;
        /// @dev Gas limit for the destination chain's transaction
        uint256 destinationGasLimit;
        /// @dev An encoded, arbitrary message to be parsed by the destination contract
        bytes message;
        /// @dev ZETA to be sent cross-chain + ZetaChain gas fees + destination chain gas fees (expressed in ZETA)
        uint256 zetaValueAndGas;
        /// @dev Optional parameters for the ZetaChain protocol
        bytes zetaParams;
    }

    /**
     * @dev Our Connector calls onZetaMessage with this struct as argument
     */
    struct ZetaMessage {
        bytes zetaTxSenderAddress;
        uint256 sourceChainId;
        address destinationAddress;
        /// @dev Remaining ZETA from zetaValueAndGas after subtracting ZetaChain gas fees and destination gas fees
        uint256 zetaValue;
        bytes message;
    }

    /**
     * @dev Our Connector calls onZetaRevert with this struct as argument
     */
    struct ZetaRevert {
        address zetaTxSenderAddress;
        uint256 sourceChainId;
        bytes destinationAddress;
        uint256 destinationChainId;
        /// @dev Equals to: zetaValueAndGas - ZetaChain gas fees - destination chain gas fees - source chain revert tx gas fees
        uint256 remainingZetaValue;
        bytes message;
    }
}

interface ZetaConnector {
    /**
     * @dev Sending value and data cross-chain is as easy as calling connector.send(SendInput)
     */
    function send(ZetaInterfaces.SendInput calldata input) external;
}

interface ZetaReceiver {
    /**
     * @dev onZetaMessage is called when a cross-chain message reaches a contract
     */
    function onZetaMessage(ZetaInterfaces.ZetaMessage calldata zetaMessage) external;

    /**
     * @dev onZetaRevert is called when a cross-chain message reverts.
     * It's useful to rollback to the original state
     */
    function onZetaRevert(ZetaInterfaces.ZetaRevert calldata zetaRevert) external;
}

/**
 * @dev ZetaTokenConsumer makes it easier to handle the following situations:
 *   - Getting Zeta using native coin (to pay for destination gas while using `connector.send`)
 *   - Getting Zeta using a token (to pay for destination gas while using `connector.send`)
 *   - Getting native coin using Zeta (to return unused destination gas when `onZetaRevert` is executed)
 *   - Getting a token using Zeta (to return unused destination gas when `onZetaRevert` is executed)
 * @dev The interface can be implemented using different strategies, like UniswapV2, UniswapV3, etc
 */
interface ZetaTokenConsumer {
    event EthExchangedForZeta(uint256 amountIn, uint256 amountOut);
    event TokenExchangedForZeta(address token, uint256 amountIn, uint256 amountOut);
    event ZetaExchangedForEth(uint256 amountIn, uint256 amountOut);
    event ZetaExchangedForToken(address token, uint256 amountIn, uint256 amountOut);

    function getZetaFromEth(address destinationAddress, uint256 minAmountOut) external payable returns (uint256);

    function getZetaFromToken(
        address destinationAddress,
        uint256 minAmountOut,
        address inputToken,
        uint256 inputTokenAmount
    ) external returns (uint256);

    function getEthFromZeta(
        address destinationAddress,
        uint256 minAmountOut,
        uint256 zetaTokenAmount
    ) external returns (uint256);

    function getTokenFromZeta(
        address destinationAddress,
        uint256 minAmountOut,
        address outputToken,
        uint256 zetaTokenAmount
    ) external returns (uint256);
}

File 12 of 16 : IUniswapV3SwapCallback.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata data
    ) external;
}

File 13 of 16 : ZetaInteractor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/access/Ownable.sol";

import "./interfaces/ZetaInterfaces.sol";
import "./interfaces/ZetaInteractorErrors.sol";

abstract contract ZetaInteractor is Ownable, ZetaInteractorErrors {
    bytes32 constant ZERO_BYTES = keccak256(new bytes(0));
    uint256 internal immutable currentChainId;
    ZetaConnector public immutable connector;

    /**
     * @dev Maps a chain id to its corresponding address of the MultiChainSwap contract
     * The address is expressed in bytes to allow non-EVM chains
     * This mapping is useful, mainly, for two reasons:
     *  - Given a chain id, the contract is able to route a transaction to its corresponding address
     *  - To check that the messages (onZetaMessage, onZetaRevert) come from a trusted source
     */
    mapping(uint256 => bytes) public interactorsByChainId;

    modifier isValidMessageCall(ZetaInterfaces.ZetaMessage calldata zetaMessage) {
        _isValidCaller();
        if (keccak256(zetaMessage.zetaTxSenderAddress) != keccak256(interactorsByChainId[zetaMessage.sourceChainId]))
            revert InvalidZetaMessageCall();
        _;
    }

    modifier isValidRevertCall(ZetaInterfaces.ZetaRevert calldata zetaRevert) {
        _isValidCaller();
        if (zetaRevert.zetaTxSenderAddress != address(this)) revert InvalidZetaRevertCall();
        if (zetaRevert.sourceChainId != currentChainId) revert InvalidZetaRevertCall();
        _;
    }

    constructor(address zetaConnectorAddress) {
        currentChainId = block.chainid;
        connector = ZetaConnector(zetaConnectorAddress);
    }

    function _isValidCaller() private view {
        if (msg.sender != address(connector)) revert InvalidCaller(msg.sender);
    }

    /**
     * @dev Useful for contracts that inherit from this one
     */
    function _isValidChainId(uint256 chainId) internal view returns (bool) {
        return (keccak256(interactorsByChainId[chainId]) != ZERO_BYTES);
    }

    function setInteractorByChainId(uint256 destinationChainId, bytes calldata contractAddress) external onlyOwner {
        interactorsByChainId[destinationChainId] = contractAddress;
    }
}

File 14 of 16 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

/**
 * @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.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 15 of 16 : ZetaInteractorErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

interface ZetaInteractorErrors {
    error InvalidDestinationChainId();

    error InvalidCaller(address caller);

    error InvalidZetaMessageCall();

    error InvalidZetaRevertCall();
}

File 16 of 16 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

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;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"zetaConnector_","type":"address"},{"internalType":"address","name":"zetaToken_","type":"address"},{"internalType":"address","name":"uniswapV3Router_","type":"address"},{"internalType":"address","name":"quoter_","type":"address"},{"internalType":"address","name":"WETH9Address_","type":"address"},{"internalType":"uint24","name":"zetaPoolFee_","type":"uint24"},{"internalType":"uint24","name":"tokenPoolFee_","type":"uint24"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"ErrorApprovingTokens","type":"error"},{"inputs":[],"name":"ErrorSendingETH","type":"error"},{"inputs":[],"name":"ErrorSwappingTokens","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"ErrorTransferringTokens","type":"error"},{"inputs":[],"name":"InputCantBeZero","type":"error"},{"inputs":[],"name":"InsufficientOutToken","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidDestinationChainId","type":"error"},{"inputs":[],"name":"InvalidMessageType","type":"error"},{"inputs":[],"name":"InvalidZetaMessageCall","type":"error"},{"inputs":[],"name":"InvalidZetaRevertCall","type":"error"},{"inputs":[],"name":"MissingSourceInputTokenAddress","type":"error"},{"inputs":[],"name":"OutTokenInvariant","type":"error"},{"inputs":[],"name":"ReentrancyError","type":"error"},{"inputs":[],"name":"ValueShouldBeGreaterThanZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"EthExchangedForZeta","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sourceTxOrigin","type":"address"},{"indexed":false,"internalType":"address","name":"sourceInputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"inputTokenReturnedAmount","type":"uint256"}],"name":"RevertedSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sourceTxOrigin","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputEthAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"destinationOutToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outTokenMinAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiverAddress","type":"address"}],"name":"SentEthSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sourceTxOrigin","type":"address"},{"indexed":false,"internalType":"address","name":"sourceInputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"destinationOutToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outTokenMinAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiverAddress","type":"address"}],"name":"SentTokenSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sourceTxOrigin","type":"address"},{"indexed":false,"internalType":"address","name":"sourceInputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"destinationOutToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outTokenFinalAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiverAddress","type":"address"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"TokenExchangedForZeta","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"ZetaExchangedForEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"ZetaExchangedForToken","type":"event"},{"inputs":[],"name":"CROSS_CHAIN_SWAP_MESSAGE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"connector","outputs":[{"internalType":"contract ZetaConnector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"zetaTokenAmount","type":"uint256"}],"name":"getEthFromZeta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"zetaTokenAmount","type":"uint256"}],"name":"getTokenFromZeta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"getZetaFromEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputTokenAmount","type":"uint256"}],"name":"getZetaFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"interactorsByChainId","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"zetaTxSenderAddress","type":"bytes"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"zetaValue","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct ZetaInterfaces.ZetaMessage","name":"zetaMessage","type":"tuple"}],"name":"onZetaMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"zetaTxSenderAddress","type":"address"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"remainingZetaValue","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct ZetaInterfaces.ZetaRevert","name":"zetaRevert","type":"tuple"}],"name":"onZetaRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoter","outputs":[{"internalType":"contract IQuoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes","name":"contractAddress","type":"bytes"}],"name":"setInteractorByChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"receiverAddress","type":"bytes"},{"internalType":"address","name":"destinationOutToken","type":"address"},{"internalType":"bool","name":"isDestinationOutETH","type":"bool"},{"internalType":"uint256","name":"outTokenMinAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"crossChaindestinationGasLimit","type":"uint256"}],"name":"swapETHForTokensCrossChain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sourceInputToken","type":"address"},{"internalType":"uint256","name":"inputTokenAmount","type":"uint256"},{"internalType":"bytes","name":"receiverAddress","type":"bytes"},{"internalType":"address","name":"destinationOutToken","type":"address"},{"internalType":"bool","name":"isDestinationOutETH","type":"bool"},{"internalType":"uint256","name":"outTokenMinAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"crossChaindestinationGasLimit","type":"uint256"}],"name":"swapTokensForTokensCrossChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenPoolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV3Router","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zetaPoolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zetaToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101806040523480156200001257600080fd5b5060405162004ff338038062004ff38339818101604052810190620000389190620003c6565b8585858585858c6200005f62000053620002cc60201b60201c565b620002d460201b60201c565b46608081815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161480620001075750600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b806200013f5750600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b80620001775750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15620001af576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff166101208173ffffffffffffffffffffffffffffffffffffffff1660601b815250508473ffffffffffffffffffffffffffffffffffffffff166101408173ffffffffffffffffffffffffffffffffffffffff1660601b815250508373ffffffffffffffffffffffffffffffffffffffff166101608173ffffffffffffffffffffffffffffffffffffffff1660601b815250508273ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff1660601b815250508162ffffff1660c08162ffffff1660e81b815250508062ffffff1660e08162ffffff1660e81b8152505050505050505050505050505050620004f5565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050620003a981620004c1565b92915050565b600081519050620003c081620004db565b92915050565b600080600080600080600060e0888a031215620003e857620003e7620004bc565b5b6000620003f88a828b0162000398565b97505060206200040b8a828b0162000398565b96505060406200041e8a828b0162000398565b9550506060620004318a828b0162000398565b9450506080620004448a828b0162000398565b93505060a0620004578a828b01620003af565b92505060c06200046a8a828b01620003af565b91505092959891949750929550565b600062000486826200048d565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b600080fd5b620004cc8162000479565b8114620004d857600080fd5b50565b620004e681620004ad565b8114620004f257600080fd5b50565b60805160a05160601c60c05160e81c60e05160e81c6101005160601c6101205160601c6101405160601c6101605160601c6149646200068f60003960006127ab01526000818161065a0152818161087a015281816109b801528181610b4d015281816115be015281816117300152818161253d015261269b01526000818161059a0152818161074c0152818161093301528181610c9801528181610d3f01528181610d9a0152818161113301528181611190015281816111e00152818161123c01528181611574015281816115e00152818161163401528181611c40015281816120210152818161219d015281816124f30152818161255f01526125b201526000818161055e015281816108f101528181611670015281816117dd01528181611d9c01526125f40152600081816108d00152818161195101526126150152600081816105d60152818161091201528181611000015281816116ac01526125d30152600081816119fd01528181611c1e01528181611c860152818161217b015281816121e30152612aae015260006110a401526149646000f3fe6080604052600436106101235760003560e01c806354c49a2a116100a05780638da5cb5b116100645780638da5cb5b146103c65780639848a6b3146103f1578063a53fb10b1461041a578063c6bbd5a714610457578063f2fde38b146104825761012a565b806354c49a2a146103005780635d9dfdde1461033d578063715018a61461036857806383f3084f1461037f57806385ff842c146103aa5761012a565b80633749c51a116100e75780633749c51a1461022f5780633cbd7005146102585780633ff0693c1461028357806340bfddf0146102ac5780634fd3f7d7146102d75761012a565b8063013b2ff81461012f57806321e093b11461015f5780632405620a1461018a5780632618143f146101c75780632c76d7a6146102045761012a565b3661012a57005b600080fd5b610149600480360381019061014491906131fb565b6104ab565b6040516101569190614205565b60405180910390f35b34801561016b57600080fd5b5061017461074a565b6040516101819190613cf9565b60405180910390f35b34801561019657600080fd5b506101b160048036038101906101ac919061323b565b61076e565b6040516101be9190614205565b60405180910390f35b3480156101d357600080fd5b506101ee60048036038101906101e9919061361f565b610aab565b6040516101fb9190614015565b60405180910390f35b34801561021057600080fd5b50610219610b4b565b6040516102269190614052565b60405180910390f35b34801561023b57600080fd5b506102566004803603810190610251919061358d565b610b6f565b005b34801561026457600080fd5b5061026d610ffe565b60405161027a91906141ea565b60405180910390f35b34801561028f57600080fd5b506102aa60048036038101906102a591906135d6565b611022565b005b3480156102b857600080fd5b506102c1611401565b6040516102ce9190613f64565b60405180910390f35b3480156102e357600080fd5b506102fe60048036038101906102f99190613679565b611425565b005b34801561030c57600080fd5b5061032760048036038101906103229190613378565b6114c9565b6040516103349190614205565b60405180910390f35b34801561034957600080fd5b5061035261194f565b60405161035f91906141ea565b60405180910390f35b34801561037457600080fd5b5061037d611973565b005b34801561038b57600080fd5b506103946119fb565b6040516103a1919061406d565b60405180910390f35b6103c460048036038101906103bf91906134de565b611a1f565b005b3480156103d257600080fd5b506103db611e6f565b6040516103e89190613cf9565b60405180910390f35b3480156103fd57600080fd5b50610418600480360381019061041391906132a2565b611e98565b005b34801561042657600080fd5b50610441600480360381019061043c919061323b565b6123ae565b60405161044e9190614205565b60405180910390f35b34801561046357600080fd5b5061046c6127a9565b6040516104799190614037565b60405180910390f35b34801561048e57600080fd5b506104a960048036038101906104a491906131ce565b6127cd565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610513576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600034141561054e576040517fb813f54900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061010001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000062ffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200160c842610628919061437b565b8152602001348152602001848152602001600073ffffffffffffffffffffffffffffffffffffffff16815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663414bf38934846040518363ffffffff1660e01b81526004016106b291906141ac565b6020604051808303818588803b1580156106cb57600080fd5b505af11580156106df573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610704919061364c565b90507f87890b0a30955b1db16cc894fbe24779ae05d9f337bfe8b6dfc0809b5bf9da113482604051610737929190614220565b60405180910390a1809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806107d65750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b1561080d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000821415610848576040517fb813f54900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108753330848673ffffffffffffffffffffffffffffffffffffffff166128c5909392919063ffffffff16565b6108c07f0000000000000000000000000000000000000000000000000000000000000000838573ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b60006040518060a00160405280857f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000604051602001610966959493929190613c3e565b60405160208183030381529060405281526020018773ffffffffffffffffffffffffffffffffffffffff16815260200160c8426109a3919061437b565b815260200184815260200186815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c04b8d59836040518263ffffffff1660e01b8152600401610a0f919061418a565b602060405180830381600087803b158015610a2957600080fd5b505af1158015610a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a61919061364c565b90507f017190d3d99ee6d8dd0604ef1e71ff9802810c6485f57c9b2ed6169848dd119f858583604051610a9693929190613f2d565b60405180910390a18092505050949350505050565b60016020528060005260406000206000915090508054610aca90614585565b80601f0160208091040260200160405190810160405280929190818152602001828054610af690614585565b8015610b435780601f10610b1857610100808354040283529160200191610b43565b820191906000526020600020905b815481529060010190602001808311610b2657829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000081565b80610b78612aac565b6001600082602001358152602001908152602001600020604051610b9c9190613ccd565b6040518091039020818060000190610bb49190614249565b604051610bc2929190613c9d565b604051809103902014610c01576040517fb473eb0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080600080600080898060800190610c1d9190614249565b810190610c2a91906133f8565b50975097509750975097509750975097507f65f49bd49de252a7f0d9100776c70f0da398368ef9866f8e21fbb0e3e630e74f8814610c94576040517f5b60892f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610d8f57818b606001351015610d28576040517f82995e3600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d8385610d3590614470565b60601c8c606001357f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612b3e9092919063ffffffff16565b8a606001359050610fa4565b610dde308c606001357f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b8215610e8a573073ffffffffffffffffffffffffffffffffffffffff166354c49a2a86610e0a90614470565b60601c848e606001356040518463ffffffff1660e01b8152600401610e3193929190613f2d565b602060405180830381600087803b158015610e4b57600080fd5b505af1158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e83919061364c565b9050610f2e565b3073ffffffffffffffffffffffffffffffffffffffff1663a53fb10b86610eb090614470565b60601c84878f606001356040518563ffffffff1660e01b8152600401610ed99493929190613ee8565b602060405180830381600087803b158015610ef357600080fd5b505af1158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b919061364c565b90505b6000811415610f69576040517fbdfc233800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811015610fa3576040517f82995e3600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b7f6135b536e33070976edb6dc1ecd6f9235b0d3a24970b028cd9dc6994bd0d5ec088888887858a610fd490614470565b60601c604051610fe996959493929190613d74565b60405180910390a15050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b8061102b612aac565b3073ffffffffffffffffffffffffffffffffffffffff1681600001602081019061105591906131ce565b73ffffffffffffffffffffffffffffffffffffffff16146110a2576040517fc03e9c3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008160200135146110ff576040517fc03e9c3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080858060a001906111159190614249565b81019061112291906133f8565b9850505050509450945094505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611231576111d43088608001357f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b611225308689608001357f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166128c5909392919063ffffffff16565b866080013590506113bb565b6112803088608001357f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b8115611321573073ffffffffffffffffffffffffffffffffffffffff166354c49a2a8660008a608001356040518463ffffffff1660e01b81526004016112c893929190613e88565b602060405180830381600087803b1580156112e257600080fd5b505af11580156112f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131a919061364c565b90506113ba565b3073ffffffffffffffffffffffffffffffffffffffff1663a53fb10b866000878b608001356040518563ffffffff1660e01b81526004016113659493929190613e43565b602060405180830381600087803b15801561137f57600080fd5b505af1158015611393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b7919061364c565b90505b5b7f038c50564f7d16a801ecb85a9eb58cc10af6400fadc80b0e8b8a9b082b32a1ba858585846040516113f09493929190613dd5565b60405180910390a150505050505050565b7f65f49bd49de252a7f0d9100776c70f0da398368ef9866f8e21fbb0e3e630e74f81565b61142d612bc4565b73ffffffffffffffffffffffffffffffffffffffff1661144b611e6f565b73ffffffffffffffffffffffffffffffffffffffff16146114a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611498906140ea565b60405180910390fd5b81816001600086815260200190815260200160002091906114c3929190612f94565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611531576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082141561156c576040517fb813f54900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115b93330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166128c5909392919063ffffffff16565b6116247f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b60006040518061010001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000062ffffff1681526020013073ffffffffffffffffffffffffffffffffffffffff16815260200160c8426116fe919061437b565b8152602001848152602001858152602001600073ffffffffffffffffffffffffffffffffffffffff16815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663414bf389836040518263ffffffff1660e01b815260040161178791906141ac565b602060405180830381600087803b1580156117a157600080fd5b505af11580156117b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d9919061364c565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b81526004016118349190614205565b600060405180830381600087803b15801561184e57600080fd5b505af1158015611862573d6000803e3d6000fd5b505050507f74e171117e91660f493740924d8bad0caf48dc4fbccb767fb05935397a2c17ae8482604051611897929190614220565b60405180910390a160008673ffffffffffffffffffffffffffffffffffffffff16826040516118c590613ce4565b60006040518083038185875af1925050503d8060008114611902576040519150601f19603f3d011682016040523d82523d6000602084013e611907565b606091505b5050905080611942576040517f3794aeaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8193505050509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b61197b612bc4565b73ffffffffffffffffffffffffffffffffffffffff16611999611e6f565b73ffffffffffffffffffffffffffffffffffffffff16146119ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e6906140ea565b60405180910390fd5b6119f96000612bcc565b565b7f000000000000000000000000000000000000000000000000000000000000000081565b611a2882612c90565b611a5e576040517f90eaaa7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000341415611a99576040517feae2ddad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614158015611ad35750835b80611b145750600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148015611b13575083155b5b15611b4b576040517fac901eb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff1663013b2ff8343060006040518463ffffffff1660e01b8152600401611b8a929190613e1a565b6020604051808303818588803b158015611ba357600080fd5b505af1158015611bb7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611bdc919061364c565b90506000811415611c19576040517fbdfc233800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c847f0000000000000000000000000000000000000000000000000000000000000000827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ec0269016040518060c00160405280868152602001600160008881526020019081526020016000208054611cef90614585565b80601f0160208091040260200160405190810160405280929190818152602001828054611d1b90614585565b8015611d685780601f10611d3d57610100808354040283529160200191611d68565b820191906000526020600020905b815481529060010190602001808311611d4b57829003601f168201915b505050505081526020018581526020017f65f49bd49de252a7f0d9100776c70f0da398368ef9866f8e21fbb0e3e630e74f337f0000000000000000000000000000000000000000000000000000000000000000348f8f8f8f8f6001604051602001611ddc9a99989796959493929190613f7f565b6040516020818303038152906040528152602001848152602001604051602001611e059061410a565b6040516020818303038152906040528152506040518263ffffffff1660e01b8152600401611e3391906141c8565b600060405180830381600087803b158015611e4d57600080fd5b505af1158015611e61573d6000803e3d6000fd5b505050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611ea182612c90565b611ed7576040517f90eaaa7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415611f3e576040517fd257189e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614158015611f785750835b80611fb95750600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148015611fb8575083155b5b15611ff0576040517fac901eb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061201f33308b8d73ffffffffffffffffffffffffffffffffffffffff166128c5909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16141561207b57889050612176565b6120a6308a8c73ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b3073ffffffffffffffffffffffffffffffffffffffff16632405620a3060008d8d6040518563ffffffff1660e01b81526004016120e69493929190613e43565b602060405180830381600087803b15801561210057600080fd5b505af1158015612114573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612138919061364c565b90506000811415612175576040517fbdfc233800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6121e17f0000000000000000000000000000000000000000000000000000000000000000827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ec0269016040518060c0016040528086815260200160016000888152602001908152602001600020805461224c90614585565b80601f016020809104026020016040519081016040528092919081815260200182805461227890614585565b80156122c55780601f1061229a576101008083540402835291602001916122c5565b820191906000526020600020905b8154815290600101906020018083116122a857829003601f168201915b505050505081526020018581526020017f65f49bd49de252a7f0d9100776c70f0da398368ef9866f8e21fbb0e3e630e74f338f8f8f8f8f8f8f60006040516020016123199a99989796959493929190613f7f565b60405160208183030381529060405281526020018481526020016040516020016123429061410a565b6040516020818303038152906040528152506040518263ffffffff1660e01b815260040161237091906141c8565b600060405180830381600087803b15801561238a57600080fd5b505af115801561239e573d6000803e3d6000fd5b5050505050505050505050505050565b6000600260009054906101000a900460ff16156123f7576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600260006101000a81548160ff021916908315150217905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806124795750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b156124b0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008214156124eb576040517fb813f54900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125383330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166128c5909392919063ffffffff16565b6125a37f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661294e9092919063ffffffff16565b60006040518060a001604052807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000089604051602001612649959493929190613c3e565b60405160208183030381529060405281526020018773ffffffffffffffffffffffffffffffffffffffff16815260200160c842612686919061437b565b815260200184815260200186815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c04b8d59836040518263ffffffff1660e01b81526004016126f2919061418a565b602060405180830381600087803b15801561270c57600080fd5b505af1158015612720573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612744919061364c565b90507f0a7cb8f6e1d29e616c1209a3f418c17b3a9137005377f6dd072217b1ede2573b85858360405161277993929190613f2d565b60405180910390a180925050506000600260006101000a81548160ff021916908315150217905550949350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6127d5612bc4565b73ffffffffffffffffffffffffffffffffffffffff166127f3611e6f565b73ffffffffffffffffffffffffffffffffffffffff1614612849576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612840906140ea565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b0906140aa565b60405180910390fd5b6128c281612bcc565b50565b612948846323b872dd60e01b8585856040516024016128e693929190613d3d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612d17565b50505050565b60008114806129e7575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401612995929190613d14565b60206040518083038186803b1580156129ad57600080fd5b505afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e5919061364c565b145b612a26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a1d9061416a565b60405180910390fd5b612aa78363095ea7b360e01b8484604051602401612a45929190613ebf565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612d17565b505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b3c57336040517fcbd9d2e0000000000000000000000000000000000000000000000000000000008152600401612b339190613cf9565b60405180910390fd5b565b612bbf8363a9059cbb60e01b8484604051602401612b5d929190613ebf565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612d17565b505050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008067ffffffffffffffff811115612cac57612cab61467c565b5b6040519080825280601f01601f191660200182016040528015612cde5781602001600182028036833780820191505090505b508051906020012060016000848152602001908152602001600020604051612d069190613ccd565b604051809103902014159050919050565b6000612d79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612dde9092919063ffffffff16565b9050600081511115612dd95780806020019051810190612d9991906133cb565b612dd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dcf9061414a565b60405180910390fd5b5b505050565b6060612ded8484600085612df6565b90509392505050565b606082471015612e3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e32906140ca565b60405180910390fd5b612e4485612f0a565b612e83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7a9061412a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612eac9190613cb6565b60006040518083038185875af1925050503d8060008114612ee9576040519150601f19603f3d011682016040523d82523d6000602084013e612eee565b606091505b5091509150612efe828286612f2d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315612f3d57829050612f8d565b600083511115612f505782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f849190614088565b60405180910390fd5b9392505050565b828054612fa090614585565b90600052602060002090601f016020900481019282612fc25760008555613009565b82601f10612fdb57803560ff1916838001178555613009565b82800160010185558215613009579182015b82811115613008578235825591602001919060010190612fed565b5b509050613016919061301a565b5090565b5b8082111561303357600081600090555060010161301b565b5090565b600061304a613045846142d1565b6142ac565b905082815260208101848484011115613066576130656146e3565b5b613071848285614543565b509392505050565b600081359050613088816148bb565b92915050565b60008135905061309d816148d2565b92915050565b6000813590506130b2816148e9565b92915050565b6000815190506130c7816148e9565b92915050565b6000813590506130dc81614900565b92915050565b60008083601f8401126130f8576130f76146c5565b5b8235905067ffffffffffffffff811115613115576131146146c0565b5b602083019150836001820283011115613131576131306146d9565b5b9250929050565b600082601f83011261314d5761314c6146c5565b5b813561315d848260208601613037565b91505092915050565b600060a0828403121561317c5761317b6146cf565b5b81905092915050565b600060c0828403121561319b5761319a6146cf565b5b81905092915050565b6000813590506131b381614917565b92915050565b6000815190506131c881614917565b92915050565b6000602082840312156131e4576131e36146ed565b5b60006131f284828501613079565b91505092915050565b60008060408385031215613212576132116146ed565b5b600061322085828601613079565b9250506020613231858286016131a4565b9150509250929050565b60008060008060808587031215613255576132546146ed565b5b600061326387828801613079565b9450506020613274878288016131a4565b935050604061328587828801613079565b9250506060613296878288016131a4565b91505092959194509250565b60008060008060008060008060006101008a8c0312156132c5576132c46146ed565b5b60006132d38c828d01613079565b99505060206132e48c828d016131a4565b98505060408a013567ffffffffffffffff811115613305576133046146e8565b5b6133118c828d016130e2565b975097505060606133248c828d01613079565b95505060806133358c828d016130a3565b94505060a06133468c828d016131a4565b93505060c06133578c828d016131a4565b92505060e06133688c828d016131a4565b9150509295985092959850929598565b600080600060608486031215613391576133906146ed565b5b600061339f86828701613079565b93505060206133b0868287016131a4565b92505060406133c1868287016131a4565b9150509250925092565b6000602082840312156133e1576133e06146ed565b5b60006133ef848285016130b8565b91505092915050565b60008060008060008060008060006101208a8c03121561341b5761341a6146ed565b5b60006134298c828d016130cd565b995050602061343a8c828d0161308e565b985050604061344b8c828d0161308e565b975050606061345c8c828d016131a4565b96505060808a013567ffffffffffffffff81111561347d5761347c6146e8565b5b6134898c828d01613138565b95505060a061349a8c828d0161308e565b94505060c06134ab8c828d016130a3565b93505060e06134bc8c828d016131a4565b9250506101006134ce8c828d016130a3565b9150509295985092959850929598565b600080600080600080600060c0888a0312156134fd576134fc6146ed565b5b600088013567ffffffffffffffff81111561351b5761351a6146e8565b5b6135278a828b016130e2565b9750975050602061353a8a828b01613079565b955050604061354b8a828b016130a3565b945050606061355c8a828b016131a4565b935050608061356d8a828b016131a4565b92505060a061357e8a828b016131a4565b91505092959891949750929550565b6000602082840312156135a3576135a26146ed565b5b600082013567ffffffffffffffff8111156135c1576135c06146e8565b5b6135cd84828501613166565b91505092915050565b6000602082840312156135ec576135eb6146ed565b5b600082013567ffffffffffffffff81111561360a576136096146e8565b5b61361684828501613185565b91505092915050565b600060208284031215613635576136346146ed565b5b6000613643848285016131a4565b91505092915050565b600060208284031215613662576136616146ed565b5b6000613670848285016131b9565b91505092915050565b600080600060408486031215613692576136916146ed565b5b60006136a0868287016131a4565b935050602084013567ffffffffffffffff8111156136c1576136c06146e8565b5b6136cd868287016130e2565b92509250509250925092565b6136e2816143d1565b82525050565b6136f1816143d1565b82525050565b613708613703826143d1565b6145e8565b82525050565b613717816143f5565b82525050565b6137268161442d565b82525050565b6000613738838561434e565b9350613745838584614543565b61374e836146f2565b840190509392505050565b6000613765838561435f565b9350613772838584614543565b82840190509392505050565b600061378982614327565b613793818561433d565b93506137a3818560208601614552565b6137ac816146f2565b840191505092915050565b60006137c282614327565b6137cc818561434e565b93506137dc818560208601614552565b6137e5816146f2565b840191505092915050565b60006137fb82614327565b613805818561435f565b9350613815818560208601614552565b80840191505092915050565b6000815461382e81614585565b613838818661435f565b94506001821660008114613853576001811461386457613897565b60ff19831686528186019350613897565b61386d85614312565b60005b8381101561388f57815481890152600182019150602081019050613870565b838801955050505b50505092915050565b6138a9816144d7565b82525050565b6138b8816144e9565b82525050565b6138c7816144fb565b82525050565b6138d68161450d565b82525050565b60006138e782614332565b6138f1818561436a565b9350613901818560208601614552565b61390a816146f2565b840191505092915050565b600061392260268361436a565b915061392d8261472a565b604082019050919050565b600061394560268361436a565b915061395082614779565b604082019050919050565b600061396860208361436a565b9150613973826147c8565b602082019050919050565b600061398b60008361435f565b9150613996826147f1565b600082019050919050565b60006139ae60008361436a565b91506139b9826147f1565b600082019050919050565b60006139d1601d8361436a565b91506139dc826147f4565b602082019050919050565b60006139f4602a8361436a565b91506139ff8261481d565b604082019050919050565b6000613a1760368361436a565b9150613a228261486c565b604082019050919050565b600060a0830160008301518482036000860152613a4a828261377e565b9150506020830151613a5f60208601826136d9565b506040830151613a726040860182613c20565b506060830151613a856060860182613c20565b506080830151613a986080860182613c20565b508091505092915050565b61010082016000820151613aba60008501826136d9565b506020820151613acd60208501826136d9565b506040820151613ae06040850182613beb565b506060820151613af360608501826136d9565b506080820151613b066080850182613c20565b5060a0820151613b1960a0850182613c20565b5060c0820151613b2c60c0850182613c20565b5060e0820151613b3f60e0850182613bdc565b50505050565b600060c083016000830151613b5d6000860182613c20565b5060208301518482036020860152613b75828261377e565b9150506040830151613b8a6040860182613c20565b5060608301518482036060860152613ba2828261377e565b9150506080830151613bb76080860182613c20565b5060a083015184820360a0860152613bcf828261377e565b9150508091505092915050565b613be581614437565b82525050565b613bf481614457565b82525050565b613c0381614457565b82525050565b613c1a613c1582614457565b61460c565b82525050565b613c2981614466565b82525050565b613c3881614466565b82525050565b6000613c4a82886136f7565b601482019150613c5a8287613c09565b600382019150613c6a82866136f7565b601482019150613c7a8285613c09565b600382019150613c8a82846136f7565b6014820191508190509695505050505050565b6000613caa828486613759565b91508190509392505050565b6000613cc282846137f0565b915081905092915050565b6000613cd98284613821565b915081905092915050565b6000613cef8261397e565b9150819050919050565b6000602082019050613d0e60008301846136e8565b92915050565b6000604082019050613d2960008301856136e8565b613d3660208301846136e8565b9392505050565b6000606082019050613d5260008301866136e8565b613d5f60208301856136e8565b613d6c6040830184613c2f565b949350505050565b600060c082019050613d8960008301896136e8565b613d9660208301886136e8565b613da36040830187613c2f565b613db060608301866136e8565b613dbd6080830185613c2f565b613dca60a08301846136e8565b979650505050505050565b6000608082019050613dea60008301876136e8565b613df760208301866136e8565b613e046040830185613c2f565b613e116060830184613c2f565b95945050505050565b6000604082019050613e2f60008301856136e8565b613e3c60208301846138cd565b9392505050565b6000608082019050613e5860008301876136e8565b613e6560208301866138cd565b613e7260408301856136e8565b613e7f6060830184613c2f565b95945050505050565b6000606082019050613e9d60008301866136e8565b613eaa60208301856138cd565b613eb76040830184613c2f565b949350505050565b6000604082019050613ed460008301856136e8565b613ee16020830184613c2f565b9392505050565b6000608082019050613efd60008301876136e8565b613f0a6020830186613c2f565b613f1760408301856136e8565b613f246060830184613c2f565b95945050505050565b6000606082019050613f4260008301866136e8565b613f4f6020830185613c2f565b613f5c6040830184613c2f565b949350505050565b6000602082019050613f79600083018461371d565b92915050565b600061012082019050613f95600083018d61371d565b613fa2602083018c6136e8565b613faf604083018b6136e8565b613fbc606083018a613c2f565b8181036080830152613fcf81888a61372c565b9050613fde60a08301876136e8565b613feb60c083018661370e565b613ff860e0830185613c2f565b61400661010083018461370e565b9b9a5050505050505050505050565b6000602082019050818103600083015261402f81846137b7565b905092915050565b600060208201905061404c60008301846138a0565b92915050565b600060208201905061406760008301846138af565b92915050565b600060208201905061408260008301846138be565b92915050565b600060208201905081810360008301526140a281846138dc565b905092915050565b600060208201905081810360008301526140c381613915565b9050919050565b600060208201905081810360008301526140e381613938565b9050919050565b600060208201905081810360008301526141038161395b565b9050919050565b60006020820190508181036000830152614123816139a1565b9050919050565b60006020820190508181036000830152614143816139c4565b9050919050565b60006020820190508181036000830152614163816139e7565b9050919050565b6000602082019050818103600083015261418381613a0a565b9050919050565b600060208201905081810360008301526141a48184613a2d565b905092915050565b6000610100820190506141c26000830184613aa3565b92915050565b600060208201905081810360008301526141e28184613b45565b905092915050565b60006020820190506141ff6000830184613bfa565b92915050565b600060208201905061421a6000830184613c2f565b92915050565b60006040820190506142356000830185613c2f565b6142426020830184613c2f565b9392505050565b60008083356001602003843603038112614266576142656146d4565b5b80840192508235915067ffffffffffffffff821115614288576142876146ca565b5b6020830192506001820236038313156142a4576142a36146de565b5b509250929050565b60006142b66142c7565b90506142c282826145b7565b919050565b6000604051905090565b600067ffffffffffffffff8211156142ec576142eb61467c565b5b6142f5826146f2565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600061438682614466565b915061439183614466565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156143c6576143c561461e565b5b828201905092915050565b60006143dc82614437565b9050919050565b60006143ee82614437565b9050919050565b60008115159050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600061447b82614327565b8261448584614302565b9050614490816146ab565b925060148210156144d0576144cb7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008360140360080261471d565b831692505b5050919050565b60006144e28261451f565b9050919050565b60006144f48261451f565b9050919050565b60006145068261451f565b9050919050565b600061451882614466565b9050919050565b600061452a82614531565b9050919050565b600061453c82614437565b9050919050565b82818337600083830152505050565b60005b83811015614570578082015181840152602081019050614555565b8381111561457f576000848401525b50505050565b6000600282049050600182168061459d57607f821691505b602082108114156145b1576145b061464d565b5b50919050565b6145c0826146f2565b810181811067ffffffffffffffff821117156145df576145de61467c565b5b80604052505050565b60006145f3826145fa565b9050919050565b600061460582614710565b9050919050565b600061461782614703565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006146b78251614401565b80915050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160e81b9050919050565b60008160601b9050919050565b600082821b905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b50565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b6148c4816143d1565b81146148cf57600080fd5b50565b6148db816143e3565b81146148e657600080fd5b50565b6148f2816143f5565b81146148fd57600080fd5b50565b6149098161442d565b811461491457600080fd5b50565b61492081614466565b811461492b57600080fd5b5056fea26469706673582212204512f7e957b45af8349554e6bd851369d18bc5c029c8227c189768516af0ca1064736f6c63430008070033000000000000000000000000000054d3a0bc83ec7808f52fcdc28a96c89f6c5c000000000000000000000000000080383847bd75f91c168269aa74004877592f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab60000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb03288900000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000000000000000bb8

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

000000000000000000000000000054d3a0bc83ec7808f52fcdc28a96c89f6c5c000000000000000000000000000080383847bd75f91c168269aa74004877592f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab60000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb03288900000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000000000000000bb8

-----Decoded View---------------
Arg [0] : zetaConnector_ (address): 0x000054d3a0bc83ec7808f52fcdc28a96c89f6c5c
Arg [1] : zetaToken_ (address): 0x000080383847bd75f91c168269aa74004877592f
Arg [2] : uniswapV3Router_ (address): 0xe592427a0aece92de3edee1f18e0157c05861564
Arg [3] : quoter_ (address): 0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6
Arg [4] : WETH9Address_ (address): 0x9c3c9283d3e44854697cd22d3faa240cfb032889
Arg [5] : zetaPoolFee_ (uint24): 500
Arg [6] : tokenPoolFee_ (uint24): 3000

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000000054d3a0bc83ec7808f52fcdc28a96c89f6c5c
Arg [1] : 000000000000000000000000000080383847bd75f91c168269aa74004877592f
Arg [2] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [3] : 000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6
Arg [4] : 0000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb032889
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000bb8


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading