Contract 0x6196Ac4C950817D23918bB643f4d315Ebe0A09b1 18

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xc3178bdf3c0b6cd462b5e69460f593e926f52e8ae7b24e82f512571133faba64Execute Order1337245742023-09-23 4:33:093 hrs 15 mins ago0xa1bd49463fddbbdf81f2325738e40ffb6bbac727 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.002 ETH0.00010597 0.1
0x33b63d04315cce8edcd51ed5dda187477bd4ded733b1ee0d27604c973ad9caa0Execute Order1336891742023-09-23 1:41:466 hrs 6 mins ago0x20244f628e41321bc1b87e646a51b26837cf87a7 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.0002 ETH0.00010087 0.1
0xdb954eb834493d5f8427628b25c53d2c57db77c6eb5abb8f650a88c9852ab280Execute Order1336412232023-09-22 21:36:5110 hrs 11 mins ago0x46fdb3ccfd6ba22d8646f75e4291ad1b8bab7705 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00011740.1
0xbbbcf9d5829425f3ac3ed9258c20d4623de5540f513cc91bfe08eb20fe29273eExecute Order1335505082023-09-22 14:40:4817 hrs 7 mins ago0x3f5cd162a922583ec7581e7cbf608c1361c80f99 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.001 ETH0.00013526 0.1
0xc682786ff6838b2d3bcab36306aeb2b1c647b6d97098c79455a78e7decafa8edExecute Order1335000562023-09-22 11:06:0320 hrs 42 mins ago0x51d0eb116ecbfd3b82163f713887e62a78e1befa IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.000061060.1
0xddabc2ed9341cccf5af33e6fc1efed68651a3a87239d5f840ec5864519313a54Execute Order1334576862023-09-22 8:06:5923 hrs 41 mins ago0xc45006bd34aafb521f77a521e21ababe4d4b6020 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.000114090.1
0xf817b33310c37fb4abd1ed2a644f3a95ae11e2296347dd13b7a21e3bba760251Execute Order1333091452023-09-21 21:18:171 day 10 hrs ago0x8d157e01ed8dd9f732e5587faf6ab54dc1a9d4d4 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00011292 0.1
0x1ccd0c556833c4e5db0613229525b9812414a51a48c13b551892aba25887697dExecute Order1333060502023-09-21 21:04:561 day 10 hrs ago0x8d157e01ed8dd9f732e5587faf6ab54dc1a9d4d4 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00013587 0.1
0x24f2fcf41bafd9107bec8dc9b60a5a6f95affbaf6e5f734f3cb5ac87ce8fca24Execute Order1332963532023-09-21 20:22:471 day 11 hrs ago0x434eb950ef67470f1c255bdacd1b6a39e1c67a14 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00010685 0.1
0x0ea582276dedd22b928da6bdee9aa87197c24ac9e0c9ff95f7121758cc382889Execute Order1332760092023-09-21 18:56:381 day 12 hrs ago0xcbb932b45054647335e04bf370318e636df8b3f0 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.0068 ETH0.00014429 0.1
0xb80cb2ce2dc29bfcf5cc7d64ea8b552fae2971e19999760b6589cb8fd7f0b376Execute Order1331985872023-09-21 13:33:211 day 18 hrs ago0xc63b4b2632b00e2371c6213d115735151892571c IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.001 ETH0.00013161 0.1
0xbd8deb30c0585a91add41adb2cc6e38d5cdf89591d1c07236fc3f1d5ecb9b93dExecute Order1331412652023-09-21 9:32:221 day 22 hrs ago0x33030f4db80d06f4055ce9bb1e0d823a65b33f40 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.001 ETH0.00016972 0.1
0x3dd53330656dde1dbb5c6ec8752604b5534438734a380fba95ec449f223720b4Execute Order1331261892023-09-21 8:29:461 day 23 hrs ago0x3d322b32fbb27b6c2dfbe7906300781f425dc301 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00006727 0.1
0xf68496a9d90ccd84626c350d219e32c904d3b0fc52e064b1cdad3bb615b8de7cExecute Order1330756942023-09-21 4:57:012 days 2 hrs ago0x374d5221a4367fe746cc6c92d333c6ce15386fcd IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00006864 0.1
0xdc3d2aba04462b7991391f809c8dc7d4796a3dd0542c9f2d393dbf02442f3bb3Execute Order1329652512023-09-20 20:48:172 days 11 hrs ago0x934d96724147328d9b376d5d532c2455f31f089b IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.000101480.1
0x2c4f03f7be644b05d5ec5b279a6c25074e818f8fbc537cfff05a38656ae2218fExecute Order1329623172023-09-20 20:36:072 days 11 hrs ago0x934d96724147328d9b376d5d532c2455f31f089b IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00013340.1
0x4d42eb670b3ac8060c9477c7c20a00638ea1b78aaa55dea37f837c68f0714292Execute Order1329618152023-09-20 20:34:012 days 11 hrs ago0x6ee9209ef6e3624fc7f5829be6eb1b729d6f80ee IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00013713 0.1
0x11eaa6f5e33461ac5e8d40d27ec4fe86f37c659f68dcaae76eff9990f73007b3Execute Order1329354552023-09-20 18:39:442 days 13 hrs ago0xb67adf0c9284fe651330a6e04319a9508f69f1e9 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.000122350.1
0xd2942050ae9409457745641a3e1c99e4662c4f7e26faaafb1addf0dd5c878de5Execute Order1329351392023-09-20 18:38:232 days 13 hrs ago0xfbc1458c5bdc9db7dd903f26a02b7cf27bed4610 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.000069580.1
0xa31b2b69cba468f0b21fc4a74fae425c39b1931480b0496a591851f2d6f8f336Execute Order1328592882023-09-20 13:11:502 days 18 hrs ago0xab3454f4198940432f89872023ebbd64495293b0 IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.0000626 0.1
0xb489619b16ecc6c972d361b8ff04f9de27aef2906618b3ac6a6f610322c507edExecute Order1328231032023-09-20 10:38:272 days 21 hrs ago0x080e285cbe0b28b06b2f803c59d0cbe541201ade IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00012779 0.1
0xab0ecccdeba8f091368d0f0fa52278653854949eba399aecf8370d035b0dc4e6Execute Order1328229102023-09-20 10:37:352 days 21 hrs ago0x273122c3e71e3ae2d2021b6bb7b1652346f8ddee IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10.019 ETH0.00008142 0.1
0x2aa7ced3a984e96b0834f08eee0432da2adf99f04a59e3658a3385219237115bExecute Order1328227542023-09-20 10:36:552 days 21 hrs ago0x080e285cbe0b28b06b2f803c59d0cbe541201ade IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00011989 0.1
0xb192b147178d5642f74b4462544a5bbb8802472cdf86d909d64ee0c7d0a3eecbExecute Order1327958272023-09-20 8:43:212 days 23 hrs ago0xc66f4876a4bfb92ea6533c3ed404905e4f70e92d IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00011663 0.1
0x2141800a67e44909033b65cd071f5cbcb18b1378af987b48f458f3fd3e9831a9Execute Order1327955132023-09-20 8:41:582 days 23 hrs ago0xc66f4876a4bfb92ea6533c3ed404905e4f70e92d IN  0x6196ac4c950817d23918bb643f4d315ebe0a09b10 ETH0.00012956 0.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xc3178bdf3c0b6cd462b5e69460f593e926f52e8ae7b24e82f512571133faba641337245742023-09-23 4:33:093 hrs 15 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.001994 ETH
0xc3178bdf3c0b6cd462b5e69460f593e926f52e8ae7b24e82f512571133faba641337245742023-09-23 4:33:093 hrs 15 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x5ef7f250f74d4f11a68054ae4e150705474a6d4a0.000006 ETH
0x33b63d04315cce8edcd51ed5dda187477bd4ded733b1ee0d27604c973ad9caa01336891742023-09-23 1:41:466 hrs 6 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.0001994 ETH
0x33b63d04315cce8edcd51ed5dda187477bd4ded733b1ee0d27604c973ad9caa01336891742023-09-23 1:41:466 hrs 6 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x5ef7f250f74d4f11a68054ae4e150705474a6d4a0.0000006 ETH
0xbbbcf9d5829425f3ac3ed9258c20d4623de5540f513cc91bfe08eb20fe29273e1335505082023-09-22 14:40:4817 hrs 7 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.000997 ETH
0xbbbcf9d5829425f3ac3ed9258c20d4623de5540f513cc91bfe08eb20fe29273e1335505082023-09-22 14:40:4817 hrs 7 mins ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x5ef7f250f74d4f11a68054ae4e150705474a6d4a0.000003 ETH
0x0ea582276dedd22b928da6bdee9aa87197c24ac9e0c9ff95f7121758cc3828891332760092023-09-21 18:56:381 day 12 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.0067796 ETH
0x0ea582276dedd22b928da6bdee9aa87197c24ac9e0c9ff95f7121758cc3828891332760092023-09-21 18:56:381 day 12 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x5ef7f250f74d4f11a68054ae4e150705474a6d4a0.0000204 ETH
0x083cf0604b8da11ed652c47032cd1e6226b3ef41af844ef074a6a209c6fc4ef41332345282023-09-21 16:01:571 day 15 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10xdf1b6ff2c0a38e48952f35742d3961b854a563c70.001320983674527979 ETH
0x083cf0604b8da11ed652c47032cd1e6226b3ef41af844ef074a6a209c6fc4ef41332345282023-09-21 16:01:571 day 15 hrs ago Wrapped Ether 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.001320983674527979 ETH
0xb80cb2ce2dc29bfcf5cc7d64ea8b552fae2971e19999760b6589cb8fd7f0b3761331985872023-09-21 13:33:211 day 18 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.000997 ETH
0xb80cb2ce2dc29bfcf5cc7d64ea8b552fae2971e19999760b6589cb8fd7f0b3761331985872023-09-21 13:33:211 day 18 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x5ef7f250f74d4f11a68054ae4e150705474a6d4a0.000003 ETH
0x80c18610698e9b903fb93fdcb74ace403c3a8029fa2625871ba0e5d4f9e1b9f11331832322023-09-21 12:29:491 day 19 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.023425487842841025 ETH
0x80c18610698e9b903fb93fdcb74ace403c3a8029fa2625871ba0e5d4f9e1b9f11331832322023-09-21 12:29:491 day 19 hrs ago 0xb0a5068cad1e7909597c22cf459e82054f545c49 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.023425487842841025 ETH
0xbd8deb30c0585a91add41adb2cc6e38d5cdf89591d1c07236fc3f1d5ecb9b93d1331412652023-09-21 9:32:221 day 22 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.001 ETH
0x11eaa6f5e33461ac5e8d40d27ec4fe86f37c659f68dcaae76eff9990f73007b31329354552023-09-20 18:39:442 days 13 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10xb67adf0c9284fe651330a6e04319a9508f69f1e90.006144514960197873 ETH
0x11eaa6f5e33461ac5e8d40d27ec4fe86f37c659f68dcaae76eff9990f73007b31329354552023-09-20 18:39:442 days 13 hrs ago Wrapped Ether 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.006144514960197873 ETH
0xab0ecccdeba8f091368d0f0fa52278653854949eba399aecf8370d035b0dc4e61328229102023-09-20 10:37:352 days 21 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b1 Wrapped Ether0.019 ETH
0xb192b147178d5642f74b4462544a5bbb8802472cdf86d909d64ee0c7d0a3eecb1327958272023-09-20 8:43:212 days 23 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10xc66f4876a4bfb92ea6533c3ed404905e4f70e92d0.000751956720649352 ETH
0xb192b147178d5642f74b4462544a5bbb8802472cdf86d909d64ee0c7d0a3eecb1327958272023-09-20 8:43:212 days 23 hrs ago Wrapped Ether 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.000751956720649352 ETH
0x2141800a67e44909033b65cd071f5cbcb18b1378af987b48f458f3fd3e9831a91327955132023-09-20 8:41:582 days 23 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10xc66f4876a4bfb92ea6533c3ed404905e4f70e92d0.00120845575801254 ETH
0x2141800a67e44909033b65cd071f5cbcb18b1378af987b48f458f3fd3e9831a91327955132023-09-20 8:41:582 days 23 hrs ago Wrapped Ether 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.00120845575801254 ETH
0x5357981609142c52354487e35f76ed57b10e5314a21930146d55d0514e0843bd1327947352023-09-20 8:38:412 days 23 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x79df464d87ad1e15e254d791e3df0b08478b91860.000719021916129126 ETH
0x5357981609142c52354487e35f76ed57b10e5314a21930146d55d0514e0843bd1327947352023-09-20 8:38:412 days 23 hrs ago Wrapped Ether 0x6196ac4c950817d23918bb643f4d315ebe0a09b10.000719021916129126 ETH
0x5dd224f936335995f60c7651c14409af8bc62a7ded58f9f62891a140cfeb035a1327943402023-09-20 8:36:592 days 23 hrs ago 0x6196ac4c950817d23918bb643f4d315ebe0a09b10x79df464d87ad1e15e254d791e3df0b08478b91860.000589978631558626 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WidoRouter

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 11 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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 2 of 11 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 3 of 11 : 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;
    }
}

File 4 of 11 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 5 of 11 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 6 of 11 : IWidoRouter.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity 0.8.7;

interface IWidoRouter {
    /// @notice OrderInput object describing the desired token inputs
    /// @param tokenAddress Address of the input token
    /// @param fromTokenAmount Amount of the input token to spend on the user's behalf
    /// @dev amount must == msg.value when token == address(0)
    struct OrderInput {
        address tokenAddress;
        uint256 amount;
    }

    /// @notice OrderOutput object describing the desired token outputs
    /// @param tokenAddress Address of the output token
    /// @param minOutputAmount Minimum amount of the output token the user is willing to accept for this order
    struct OrderOutput {
        address tokenAddress;
        uint256 minOutputAmount;
    }

    /// @notice Order object describing the requirements of the zap
    /// @param inputs Array of input objects, see OrderInput
    /// @param outputs Array of output objects, see OrderOutput
    /// @param user Address of user placing the order
    /// @param nonce Number used once to ensure an order requested by a signature only executes once
    /// @param expiration Timestamp until which the order is valid to execute
    struct Order {
        OrderInput[] inputs;
        OrderOutput[] outputs;
        address user;
        uint32 nonce;
        uint32 expiration;
    }

    /// @notice Step object describing a single token transformation
    /// @param fromToken Address of the from token
    /// @param targetAddress Address of the contract performing the transformation
    /// @param data Data which the swap contract will be called with
    /// @param amountIndex Index for the from token amount that can be found in data and needs to be updated with the most recent value.
    struct Step {
        address fromToken;
        address targetAddress;
        bytes data;
        int32 amountIndex;
    }

    function verifyOrder(Order calldata order, uint8 v, bytes32 r, bytes32 s) external view returns (bool);

    function executeOrder(
        Order calldata order,
        Step[] calldata route,
        uint256 feeBps,
        address partner
    ) external payable;

    function executeOrder(
        Order calldata order,
        Step[] calldata route,
        address recipient,
        uint256 feeBps,
        address partner
    ) external payable;

    function executeOrderWithSignature(
        Order calldata order,
        Step[] calldata route,
        uint8 v,
        bytes32 r,
        bytes32 s,
        uint256 feeBps,
        address partner
    ) external;
}

File 7 of 11 : IWidoTokenManager.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity 0.8.7;
import "./IWidoRouter.sol";

interface IWidoTokenManager {
    function pullTokens(address user, IWidoRouter.OrderInput[] calldata inputs) external;
}

File 8 of 11 : WidoRouter.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity 0.8.7;

import "solmate/src/utils/SafeTransferLib.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./interfaces/IWidoRouter.sol";
import "./WidoTokenManager.sol";

error SlippageTooHigh(uint256 expectedAmount, uint256 actualAmount);

/// @title Wido Router
/// @notice Zap in or out of any ERC20 token, liquid or illiquid, in a single transaction.
/// @notice DO NOT APPROVE THIS CONTRACT FOR SPENDING YOUR TOKENS.
/// @author Wido
contract WidoRouter is IWidoRouter, Ownable, ReentrancyGuard {
    using SafeTransferLib for address;
    using SafeTransferLib for ERC20;

    bytes32 private constant EIP712_DOMAIN_TYPEHASH =
        keccak256(
            abi.encodePacked("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
        );

    bytes32 private constant ORDER_TYPEHASH =
        keccak256(
            abi.encodePacked(
                "Order(OrderInput[] inputs,OrderOutput[] outputs,address user,uint32 nonce,uint32 expiration)OrderInput(address tokenAddress,uint256 amount)OrderOutput(address tokenAddress,uint256 minOutputAmount)"
            )
        );

    bytes32 private constant ORDER_INPUT_TYPEHASH =
        keccak256(abi.encodePacked("OrderInput(address tokenAddress,uint256 amount)"));

    bytes32 private constant ORDER_OUTPUT_TYPEHASH =
        keccak256(abi.encodePacked("OrderOutput(address tokenAddress,uint256 minOutputAmount)"));

    // Nonce for executing order with EIP-712 signatures.
    mapping(address => uint256) public nonces;

    // Address of the wrapped native token
    address public immutable wrappedNativeToken;

    // Address of fee bank
    address public bank;

    WidoTokenManager public immutable widoTokenManager;

    /// @notice Event emitted when the order is fulfilled
    /// @param order The order that was fulfilled
    /// @param sender The msg.sender
    /// @param recipient Recipient of the final tokens of the order
    /// @param feeBps Fee in basis points (bps)
    /// @param partner Partner address
    event FulfilledOrder(
        Order order,
        address indexed sender,
        address recipient,
        uint256 feeBps,
        address indexed partner
    );

    /// @notice Event emitted when the bank address is updated
    /// @param bank The updated address of the bank
    event SetBank(
        address bank
    );

    constructor(
        address _wrappedNativeToken,
        address _bank // uint256 _feeBps
    ) {
        require(_wrappedNativeToken != address(0) && _bank != address(0), "Addresses cannot be zero address");

        wrappedNativeToken = _wrappedNativeToken;
        bank = _bank;
        widoTokenManager = new WidoTokenManager();
    }

    /// @notice Sets the bank address
    /// @param _bank The address of the new bank
    function setBank(address _bank) external onlyOwner {
        require(_bank != address(0) && _bank != address(this), "Bank address cannot be zero address or Wido Router address");
        bank = _bank;
        emit SetBank(_bank);
    }

    /// @notice Approve a token spending
    /// @param token The ERC20 token to approve
    /// @param spender The address of the spender
    /// @param amount The minimum allowance to grant to the spender
    function _approveToken(address token, address spender, uint256 amount) internal {
        ERC20 _token = ERC20(token);
        if (_token.allowance(address(this), spender) < amount) {
            _token.safeApprove(spender, type(uint256).max);
        }
    }

    /// @notice Executes steps in the route to transfer to token
    /// @param route Step data for token transformation
    /// @dev Updates the amount in the byte data with the current balance as to not leave any dust
    /// @dev Expects step data to be properly chained for the token transformation tokenA -> tokenB -> tokenC
    function _executeSteps(Step[] calldata route) private {
        for (uint256 i = 0; i < route.length; ) {
            Step calldata step = route[i];

            require(step.targetAddress != address(widoTokenManager), "Wido: forbidden call to WidoTokenManager");

            uint256 balance;
            uint256 value;
            if (step.fromToken == address(0)) {
                value = address(this).balance;
            } else {
                value = 0;
                balance = ERC20(step.fromToken).balanceOf(address(this));
                require(balance > 0, "Not enough balance for the step");
                _approveToken(step.fromToken, step.targetAddress, balance);
            }

            bytes memory editedSwapData;
            if (step.amountIndex >= 0) {
                uint256 idx = uint256(int256(step.amountIndex));
                editedSwapData = bytes.concat(step.data[:idx], abi.encode(balance), step.data[idx + 32:]);
            } else {
                editedSwapData = step.data;
            }

            (bool success, bytes memory result) = step.targetAddress.call{value: value}(editedSwapData);
            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string)));
            }

            unchecked {
                i++;
            }
        }
    }

    function hash(OrderInput[] memory orderInput) internal pure returns (bytes32) {
        bytes32[] memory result = new bytes32[](orderInput.length);
        for (uint256 i = 0; i < orderInput.length; ) {
            result[i] = keccak256(abi.encode(ORDER_INPUT_TYPEHASH, orderInput[i]));
            unchecked {
                i++;
            }
        }
        return keccak256(abi.encodePacked(result));
    }

    function hash(OrderOutput[] memory orderOutput) internal pure returns (bytes32) {
        bytes32[] memory result = new bytes32[](orderOutput.length);
        for (uint256 i = 0; i < orderOutput.length; ) {
            result[i] = keccak256(abi.encode(ORDER_OUTPUT_TYPEHASH, orderOutput[i]));
            unchecked {
                i++;
            }
        }
        return keccak256(abi.encodePacked(result));
    }

    function hash(Order memory order) internal pure returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    ORDER_TYPEHASH,
                    hash(order.inputs),
                    hash(order.outputs),
                    order.user,
                    order.nonce,
                    order.expiration
                )
            );
    }

    /// @notice Verifies if the order is valid
    /// @param order Order to be validated
    /// @param v v of the signature
    /// @param r r of the signature
    /// @param s s of the signature
    /// @return bool True if the order is valid
    function verifyOrder(Order calldata order, uint8 v, bytes32 r, bytes32 s) public view override returns (bool) {
        bytes32 DOMAIN_SEPARATOR = keccak256(
            abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256("WidoRouter"), keccak256("1"), block.chainid, address(this))
        );
        address recoveredAddress = ECDSA.recover(
            keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hash(order))),
            v,
            r,
            s
        );
        require(recoveredAddress != address(0) && order.user == recoveredAddress, "Invalid signature");
        require(order.nonce == nonces[order.user], "Invalid nonce");
        require(order.expiration == 0 || block.timestamp <= order.expiration, "Expired request");
        for (uint256 i = 0; i < order.inputs.length; ) {
            IWidoRouter.OrderInput calldata input = order.inputs[i];
            require(input.amount > 0, "Amount should be greater than 0");
            unchecked {
                i++;
            }
        }
        return true;
    }

    /// @notice Executes the validated order
    /// @param order Order to be executed
    /// @param route Route to execute for the token swap
    /// @param recipient The address of the final token receiver
    /// @param feeBps Fee in basis points (bps)
    /// @dev Expects the steps in the route to transform order.fromToken to order.toToken
    /// @dev Expects at least order.minToTokenAmount to be transferred to the recipient
    function _executeOrder(Order calldata order, Step[] calldata route, address recipient, uint256 feeBps) private {
        widoTokenManager.pullTokens(order.user, order.inputs);

        for (uint256 i = 0; i < order.inputs.length; ) {
            IWidoRouter.OrderInput calldata input = order.inputs[i];

            uint256 balance;
            if (input.tokenAddress == address(0)) {
                balance = address(this).balance;
            } else {
                balance = ERC20(input.tokenAddress).balanceOf(address(this));
            }
            require(balance >= input.amount, "Balance lower than order amount");
            _collectFees(input.tokenAddress, balance, feeBps);

            unchecked {
                i++;
            }
        }

        _executeSteps(route);

        for (uint256 i = 0; i < order.outputs.length; ) {
            IWidoRouter.OrderOutput calldata output = order.outputs[i];

            if (output.tokenAddress == address(0)) {
                uint256 balance = address(this).balance;
                if (balance < output.minOutputAmount) {
                    revert SlippageTooHigh(output.minOutputAmount, balance);
                }
                recipient.safeTransferETH(balance);
            } else {
                uint256 balance = ERC20(output.tokenAddress).balanceOf(address(this));
                if (balance < output.minOutputAmount) {
                    revert SlippageTooHigh(output.minOutputAmount, balance);
                }
                ERC20(output.tokenAddress).safeTransfer(recipient, balance);
            }

            unchecked {
                i++;
            }
        }
    }

    /// @notice Returns the amount of tokens or native tokens after accounting for fee
    /// @param fromToken Address of the token for the fee
    /// @param amount Amount of tokens to subtract the fee
    /// @param feeBps Fee in basis points (bps)
    /// @dev Sends the fee to the bank to not maintain any balance in the contract
    function _collectFees(address fromToken, uint256 amount, uint256 feeBps) private {
        require(feeBps <= 100, "Fee out of range");
        uint256 fee = (amount * feeBps) / 10000;
        if (fee > 0) {
            if (fromToken == address(0)) {
                bank.safeTransferETH(fee);
            } else {
                ERC20(fromToken).safeTransfer(bank, fee);
            }
        }
    }

    /// @notice Executes order to transform ERC20 token from order.fromToken to order.toToken
    /// @param order Order describing the expectation of the token transformation
    /// @param route Route describes the details of the token transformation
    /// @param feeBps Fee in basis points (bps)
    /// @param partner Partner address
    function executeOrder(
        Order calldata order,
        Step[] calldata route,
        uint256 feeBps,
        address partner
    ) external payable override nonReentrant {
        require(msg.sender == order.user, "Invalid order user");
        _executeOrder(order, route, order.user, feeBps);
        emit FulfilledOrder(order, msg.sender, order.user, feeBps, partner);
    }

    /// @notice Executes order to transform ERC20 token from order.fromToken to order.toToken
    /// @param order Order describing the expectation of the token transformation
    /// @param route Route describes the details of the token transformation
    /// @param recipient Destination address where the final tokens are sent
    /// @param feeBps Fee in basis points (bps)
    /// @param partner Partner address
    function executeOrder(
        Order calldata order,
        Step[] calldata route,
        address recipient,
        uint256 feeBps,
        address partner
    ) external payable override nonReentrant {
        require(msg.sender == order.user, "Invalid order user");
        _executeOrder(order, route, recipient, feeBps);
        emit FulfilledOrder(order, msg.sender, recipient, feeBps, partner);
    }

    /// @notice Executes the order with valid EIP-712 signature
    /// @param order Order describing the expectation of the token transformation
    /// @param route Expects a valid route to transform order.fromToken to order.toToken
    /// @param v v of the signature
    /// @param r r of the signature
    /// @param s s of the signation
    /// @param feeBps Fee in basis points (bps)
    /// @param partner Partner address
    function executeOrderWithSignature(
        Order calldata order,
        Step[] calldata route,
        uint8 v,
        bytes32 r,
        bytes32 s,
        uint256 feeBps,
        address partner
    ) external override nonReentrant {
        require(verifyOrder(order, v, r, s), "Invalid order");
        nonces[order.user]++;
        _executeOrder(order, route, order.user, feeBps);
        emit FulfilledOrder(order, msg.sender, order.user, feeBps, partner);
    }

    /// @notice Allow receiving of native tokens
    receive() external payable {}
}

File 9 of 11 : WidoTokenManager.sol
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity 0.8.7;

import "solmate/src/utils/SafeTransferLib.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IWidoTokenManager.sol";

contract WidoTokenManager is IWidoTokenManager, Ownable {
    using SafeTransferLib for ERC20;

    /// @notice Transfers tokens or native tokens from the user
    /// @param user The address of the order user
    /// @param inputs Array of input objects, see OrderInput and Order
    function pullTokens(address user, IWidoRouter.OrderInput[] calldata inputs) external override onlyOwner {
        for (uint256 i = 0; i < inputs.length; i++) {
            IWidoRouter.OrderInput calldata input = inputs[i];

            if (input.tokenAddress == address(0)) {
                continue;
            }

            ERC20(input.tokenAddress).safeTransferFrom(user, owner(), input.amount);
        }
    }
}

File 10 of 11 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 11 of 11 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_wrappedNativeToken","type":"address"},{"internalType":"address","name":"_bank","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"name":"SlippageTooHigh","type":"error"},{"anonymous":false,"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderInput[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderOutput[]","name":"outputs","type":"tuple[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"expiration","type":"uint32"}],"indexed":false,"internalType":"struct IWidoRouter.Order","name":"order","type":"tuple"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeBps","type":"uint256"},{"indexed":true,"internalType":"address","name":"partner","type":"address"}],"name":"FulfilledOrder","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":"bank","type":"address"}],"name":"SetBank","type":"event"},{"inputs":[],"name":"bank","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderInput[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderOutput[]","name":"outputs","type":"tuple[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"expiration","type":"uint32"}],"internalType":"struct IWidoRouter.Order","name":"order","type":"tuple"},{"components":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"int32","name":"amountIndex","type":"int32"}],"internalType":"struct IWidoRouter.Step[]","name":"route","type":"tuple[]"},{"internalType":"uint256","name":"feeBps","type":"uint256"},{"internalType":"address","name":"partner","type":"address"}],"name":"executeOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderInput[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderOutput[]","name":"outputs","type":"tuple[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"expiration","type":"uint32"}],"internalType":"struct IWidoRouter.Order","name":"order","type":"tuple"},{"components":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"int32","name":"amountIndex","type":"int32"}],"internalType":"struct IWidoRouter.Step[]","name":"route","type":"tuple[]"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"feeBps","type":"uint256"},{"internalType":"address","name":"partner","type":"address"}],"name":"executeOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderInput[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderOutput[]","name":"outputs","type":"tuple[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"expiration","type":"uint32"}],"internalType":"struct IWidoRouter.Order","name":"order","type":"tuple"},{"components":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"int32","name":"amountIndex","type":"int32"}],"internalType":"struct IWidoRouter.Step[]","name":"route","type":"tuple[]"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint256","name":"feeBps","type":"uint256"},{"internalType":"address","name":"partner","type":"address"}],"name":"executeOrderWithSignature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bank","type":"address"}],"name":"setBank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderInput[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"internalType":"struct IWidoRouter.OrderOutput[]","name":"outputs","type":"tuple[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"expiration","type":"uint32"}],"internalType":"struct IWidoRouter.Order","name":"order","type":"tuple"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"verifyOrder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"widoTokenManager","outputs":[{"internalType":"contract WidoTokenManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040523480156200001157600080fd5b5060405162003189380380620031898339810160408190526200003491620001a2565b6200003f3362000127565b600180556001600160a01b038216158015906200006457506001600160a01b03811615155b620000b55760405162461bcd60e51b815260206004820181905260248201527f4164647265737365732063616e6e6f74206265207a65726f2061646472657373604482015260640160405180910390fd5b606082901b6001600160601b031916608052600380546001600160a01b0319166001600160a01b038316179055604051620000f09062000177565b604051809103906000f0801580156200010d573d6000803e3d6000fd5b5060601b6001600160601b03191660a05250620001da9050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105cd8062002bbc83390190565b80516001600160a01b03811681146200019d57600080fd5b919050565b60008060408385031215620001b657600080fd5b620001c18362000185565b9150620001d16020840162000185565b90509250929050565b60805160601c60a05160601c6129a8620002146000396000818161015c01528181610e9e01526118c00152600061010b01526129a86000f3fe6080604052600436106100cb5760003560e01c80637ecebe0011610074578063e58610841161004e578063e58610841461024f578063f2fde38b1461026f578063fc171d911461028f57600080fd5b80637ecebe00146101e35780638da5cb5b1461021e578063916a3bd91461023c57600080fd5b80633967048b116100a55780633967048b1461017e578063715018a6146101ae57806376cdb03b146101c357600080fd5b8063090d23b9146100d757806317fcb39b146100f95780631802553e1461014a57600080fd5b366100d257005b600080fd5b3480156100e357600080fd5b506100f76100f2366004612025565b6102a2565b005b34801561010557600080fd5b5061012d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561015657600080fd5b5061012d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561018a57600080fd5b5061019e6101993660046122be565b6103ae565b6040519015158152602001610141565b3480156101ba57600080fd5b506100f761076b565b3480156101cf57600080fd5b5060035461012d906001600160a01b031681565b3480156101ef57600080fd5b506102106101fe366004612025565b60026020526000908152604090205481565b604051908152602001610141565b34801561022a57600080fd5b506000546001600160a01b031661012d565b6100f761024a366004612192565b61077f565b34801561025b57600080fd5b506100f761026a366004612216565b6108c3565b34801561027b57600080fd5b506100f761028a366004612025565b610a2d565b6100f761029d3660046120fe565b610abd565b6102aa610bed565b6001600160a01b038116158015906102cb57506001600160a01b0381163014155b6103425760405162461bcd60e51b815260206004820152603a60248201527f42616e6b20616464726573732063616e6e6f74206265207a65726f206164647260448201527f657373206f72205769646f20526f75746572206164647265737300000000000060648201526084015b60405180910390fd5b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f10f5824683d64a0712038f2244e046b174a1cc57fbb8556bfda5ffb2612440679060200160405180910390a150565b600080604051602001610430907f454950373132446f6d61696e28737472696e67206e616d652c737472696e672081527f76657273696f6e2c75696e7432353620636861696e49642c616464726573732060208201527f766572696679696e67436f6e7472616374290000000000000000000000000000604082015260520190565b60408051601f198184030181528282528051602091820120908301527fe18799aceb0d5c1134b671173b8112a3ebcbe15aaef1b5bf23f47082a09df0ec908201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c001604051602081830303815290604052805190602001209050600061052d826104d6896104d1906127cf565b610c47565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810192909252604282015260620160405160208183030381529060405280519060200120878787610e04565b90506001600160a01b0381161580159061056757506001600160a01b03811661055c6060890160408a01612025565b6001600160a01b0316145b6105b35760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610339565b600260006105c760608a0160408b01612025565b6001600160a01b031681526020810191909152604001600020546105f16080890160608a01612334565b63ffffffff16146106445760405162461bcd60e51b815260206004820152600d60248201527f496e76616c6964206e6f6e6365000000000000000000000000000000000000006044820152606401610339565b61065460a0880160808901612334565b63ffffffff16158061067b575061067160a0880160808901612334565b63ffffffff164211155b6106c75760405162461bcd60e51b815260206004820152600f60248201527f45787069726564207265717565737400000000000000000000000000000000006044820152606401610339565b60005b6106d488806125c0565b905081101561075d57366106e889806125c0565b838181106106f8576106f8612946565b905060400201905060008160200135116107545760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e742073686f756c642062652067726561746572207468616e2030006044820152606401610339565b506001016106ca565b506001979650505050505050565b610773610bed565b61077d6000610e2c565b565b600260015414156107d25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610339565b60026001556107e76060860160408701612025565b6001600160a01b0316336001600160a01b0316146108475760405162461bcd60e51b815260206004820152601260248201527f496e76616c6964206f72646572207573657200000000000000000000000000006044820152606401610339565b61086385858561085d6060840160408501612025565b86610e94565b6001600160a01b038116337f1ac24a2fc0a341cfcb02105ee08de6110d72cdf0d2b78fe9136f5da301eb9091876108a06060820160408301612025565b866040516108b0939291906124b8565b60405180910390a3505060018055505050565b600260015414156109165760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610339565b6002600155610927888686866103ae565b6109735760405162461bcd60e51b815260206004820152600d60248201527f496e76616c6964206f72646572000000000000000000000000000000000000006044820152606401610339565b6002600061098760608b0160408c01612025565b6001600160a01b03168152602081019190915260400160009081208054916109ae836128ff565b909155506109ca905088888861085d6060840160408501612025565b6001600160a01b038116337f1ac24a2fc0a341cfcb02105ee08de6110d72cdf0d2b78fe9136f5da301eb90918a610a076060820160408301612025565b86604051610a17939291906124b8565b60405180910390a3505060018055505050505050565b610a35610bed565b6001600160a01b038116610ab15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610339565b610aba81610e2c565b50565b60026001541415610b105760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610339565b6002600155610b256060870160408801612025565b6001600160a01b0316336001600160a01b031614610b855760405162461bcd60e51b815260206004820152601260248201527f496e76616c6964206f72646572207573657200000000000000000000000000006044820152606401610339565b610b928686868686610e94565b806001600160a01b0316336001600160a01b03167f1ac24a2fc0a341cfcb02105ee08de6110d72cdf0d2b78fe9136f5da301eb9091888686604051610bd9939291906124b8565b60405180910390a350506001805550505050565b6000546001600160a01b0316331461077d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610339565b6000604051602001610d60907f4f72646572284f72646572496e7075745b5d20696e707574732c4f726465724f81527f75747075745b5d206f7574707574732c6164647265737320757365722c75696e60208201527f743332206e6f6e63652c75696e7433322065787069726174696f6e294f72646560408201527f72496e707574286164647265737320746f6b656e416464726573732c75696e7460608201527f32353620616d6f756e74294f726465724f75747075742861646472657373207460808201527f6f6b656e416464726573732c75696e74323536206d696e4f7574707574416d6f60a08201527f756e74290000000000000000000000000000000000000000000000000000000060c082015260c40190565b60405160208183030381529060405280519060200120610d838360000151611267565b610d9084602001516113c1565b604080860151606087015160808801519251610de79695949390602001958652602086019490945260408501929092526001600160a01b0316606084015263ffffffff90811660808401521660a082015260c00190565b604051602081830303815290604052805190602001209050919050565b6000806000610e15878787876114eb565b91509150610e22816115d8565b5095945050505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166377fc3fa8610ed36060880160408901612025565b610edd88806125c0565b6040518463ffffffff1660e01b8152600401610efb93929190612432565b600060405180830381600087803b158015610f1557600080fd5b505af1158015610f29573d6000803e3d6000fd5b5050505060005b610f3a86806125c0565b905081101561108d5736610f4e87806125c0565b83818110610f5e57610f5e612946565b6040029190910191506000905080610f796020840184612025565b6001600160a01b03161415610f8f575047611018565b610f9c6020830183612025565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a082319060240160206040518083038186803b158015610fdd57600080fd5b505afa158015610ff1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611015919061231b565b90505b816020013581101561106c5760405162461bcd60e51b815260206004820152601f60248201527f42616c616e6365206c6f776572207468616e206f7264657220616d6f756e74006044820152606401610339565b61108361107c6020840184612025565b82866117c9565b5050600101610f30565b506110988484611884565b60005b6110a860208701876125c0565b905081101561125f57366110bf60208801886125c0565b838181106110cf576110cf612946565b604002919091019150600090506110e96020830183612025565b6001600160a01b0316141561115d57476020820135811015611144576040517f76baadda0000000000000000000000000000000000000000000000000000000081526020830135600482015260248101829052604401610339565b6111576001600160a01b03861682611c60565b50611256565b600061116c6020830183612025565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a082319060240160206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e5919061231b565b90508160200135811015611232576040517f76baadda0000000000000000000000000000000000000000000000000000000081526020830135600482015260248101829052604401610339565b61125485826112446020860186612025565b6001600160a01b03169190611cbb565b505b5060010161109b565b505050505050565b600080825167ffffffffffffffff8111156112845761128461295c565b6040519080825280602002602001820160405280156112ad578160200160208202803683370190505b50905060005b835181101561139157604051602001611315907f4f72646572496e707574286164647265737320746f6b656e416464726573732c81527f75696e7432353620616d6f756e742900000000000000000000000000000000006020820152602f0190565b6040516020818303038152906040528051906020012084828151811061133d5761133d612946565b602002602001015160405160200161135692919061245e565b6040516020818303038152906040528051906020012082828151811061137e5761137e612946565b60209081029190910101526001016112b3565b50806040516020016113a391906123ac565b60405160208183030381529060405280519060200120915050919050565b600080825167ffffffffffffffff8111156113de576113de61295c565b604051908082528060200260200182016040528015611407578160200160208202803683370190505b50905060005b83518110156113915760405160200161146f907f4f726465724f7574707574286164647265737320746f6b656e4164647265737381527f2c75696e74323536206d696e4f7574707574416d6f756e742900000000000000602082015260390190565b6040516020818303038152906040528051906020012084828151811061149757611497612946565b60200260200101516040516020016114b092919061245e565b604051602081830303815290604052805190602001208282815181106114d8576114d8612946565b602090810291909101015260010161140d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561152257506000905060036115cf565b8460ff16601b1415801561153a57508460ff16601c14155b1561154b57506000905060046115cf565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561159f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166115c8576000600192509250506115cf565b9150600090505b94509492505050565b60008160048111156115ec576115ec612930565b14156115f55750565b600181600481111561160957611609612930565b14156116575760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610339565b600281600481111561166b5761166b612930565b14156116b95760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610339565b60038160048111156116cd576116cd612930565b14156117415760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610339565b600481600481111561175557611755612930565b1415610aba5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610339565b606481111561181a5760405162461bcd60e51b815260206004820152601060248201527f466565206f7574206f662072616e6765000000000000000000000000000000006044820152606401610339565b600061271061182983856127b0565b611833919061278e565b9050801561187e576001600160a01b0384166118645760035461185f906001600160a01b031682611c60565b61187e565b60035461187e906001600160a01b03868116911683611cbb565b50505050565b60005b81811015611c5b57368383838181106118a2576118a2612946565b90506020028101906118b49190612651565b90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166118f06040830160208401612025565b6001600160a01b0316141561196d5760405162461bcd60e51b815260206004820152602860248201527f5769646f3a20666f7262696464656e2063616c6c20746f205769646f546f6b6560448201527f6e4d616e616765720000000000000000000000000000000000000000000000006064820152608401610339565b6000808061197e6020850185612025565b6001600160a01b03161415611994575047611a95565b5060006119a46020840184612025565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a082319060240160206040518083038186803b1580156119e557600080fd5b505afa1580156119f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1d919061231b565b915060008211611a6f5760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f7567682062616c616e636520666f72207468652073746570006044820152606401610339565b611a95611a7f6020850185612025565b611a8f6040860160208701612025565b84611d5a565b60606000611aa860808601868401612047565b60030b12611b4b576000611ac26080860160608701612047565b60030b9050611ad4604086018661260a565b611ae291839160009161274c565b60408051602081018890520160408051601f19818403018152918152611b0a9089018961260a565b611b15866020612776565b611b2092829061274c565b604051602001611b349594939291906123e2565b604051602081830303815290604052915050611b90565b611b58604085018561260a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b600080611ba36040870160208801612025565b6001600160a01b03168484604051611bbb9190612416565b60006040518083038185875af1925050503d8060008114611bf8576040519150601f19603f3d011682016040523d82523d6000602084013e611bfd565b606091505b509150915081611c4957604481511015611c1657600080fd5b60048101905080806020019051810190611c30919061206a565b60405162461bcd60e51b81526004016103399190612485565b50506001909401935061188792505050565b505050565b600080600080600085875af1905080611c5b5760405162461bcd60e51b815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152606401610339565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061187e5760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610339565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0383811660248301528491839183169063dd62ed3e9060440160206040518083038186803b158015611dbe57600080fd5b505afa158015611dd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df6919061231b565b101561187e5761187e6001600160a01b0382168460001960006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061187e5760405162461bcd60e51b815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610339565b80356001600160a01b0381168114611ec357600080fd5b919050565b600082601f830112611ed957600080fd5b81356020611eee611ee9836126df565b6126ae565b80838252828201915082860187848660061b8901011115611f0e57600080fd5b60005b85811015611f3857611f238983611f91565b84529284019260409190910190600101611f11565b5090979650505050505050565b60008083601f840112611f5757600080fd5b50813567ffffffffffffffff811115611f6f57600080fd5b6020830191508360208260051b8501011115611f8a57600080fd5b9250929050565b600060408284031215611fa357600080fd5b6040516040810181811067ffffffffffffffff82111715611fc657611fc661295c565b604052905080611fd583611eac565b8152602083013560208201525092915050565b600060a08284031215611ffa57600080fd5b50919050565b803563ffffffff81168114611ec357600080fd5b803560ff81168114611ec357600080fd5b60006020828403121561203757600080fd5b61204082611eac565b9392505050565b60006020828403121561205957600080fd5b81358060030b811461204057600080fd5b60006020828403121561207c57600080fd5b815167ffffffffffffffff8082111561209457600080fd5b818401915084601f8301126120a857600080fd5b8151818111156120ba576120ba61295c565b6120cd6020601f19601f840116016126ae565b91508082528560208285010111156120e457600080fd5b6120f58160208401602086016128d3565b50949350505050565b60008060008060008060a0878903121561211757600080fd5b863567ffffffffffffffff8082111561212f57600080fd5b61213b8a838b01611fe8565b9750602089013591508082111561215157600080fd5b5061215e89828a01611f45565b9096509450612171905060408801611eac565b92506060870135915061218660808801611eac565b90509295509295509295565b6000806000806000608086880312156121aa57600080fd5b853567ffffffffffffffff808211156121c257600080fd5b6121ce89838a01611fe8565b965060208801359150808211156121e457600080fd5b506121f188828901611f45565b9095509350506040860135915061220a60608701611eac565b90509295509295909350565b60008060008060008060008060e0898b03121561223257600080fd5b883567ffffffffffffffff8082111561224a57600080fd5b6122568c838d01611fe8565b995060208b013591508082111561226c57600080fd5b506122798b828c01611f45565b909850965061228c905060408a01612014565b9450606089013593506080890135925060a089013591506122af60c08a01611eac565b90509295985092959890939650565b600080600080608085870312156122d457600080fd5b843567ffffffffffffffff8111156122eb57600080fd5b6122f787828801611fe8565b94505061230660208601612014565b93969395505050506040820135916060013590565b60006020828403121561232d57600080fd5b5051919050565b60006020828403121561234657600080fd5b61204082612000565b81835260208301925060008160005b8481101561238357612370868361238d565b604095860195919091019060010161235e565b5093949350505050565b6001600160a01b0361239e82611eac565b168252602090810135910152565b815160009082906020808601845b838110156123d6578151855293820193908201906001016123ba565b50929695505050505050565b8486823760008582016000815285516123ff818360208a016128d3565b018385823760009301928352509095945050505050565b600082516124288184602087016128d3565b9190910192915050565b6001600160a01b038416815260406020820152600061245560408301848661234f565b95945050505050565b82815260608101612040602083018480516001600160a01b03168252602090810151910152565b60208152600082518060208401526124a48160408501602087016128d3565b601f01601f19169190910160400192915050565b6060815260006124c88586612703565b60a060608501526124de6101008501828461234f565b9150506124ee6020870187612703565b8483037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808601528083529091600091906020015b8183101561254a57612537818561238d565b6040938401936001939093019201612525565b61255660408a01611eac565b6001600160a01b03811660a0880152935061257360608a01612000565b63ffffffff811660c0880152935061258d60808a01612000565b63ffffffff1660e08701526001600160a01b038816602087015293506125b292505050565b826040830152949350505050565b6000808335601e198436030181126125d757600080fd5b83018035915067ffffffffffffffff8211156125f257600080fd5b6020019150600681901b3603821315611f8a57600080fd5b6000808335601e1984360301811261262157600080fd5b83018035915067ffffffffffffffff82111561263c57600080fd5b602001915036819003821315611f8a57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261242857600080fd5b60405160a0810167ffffffffffffffff811182821017156126a8576126a861295c565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156126d7576126d761295c565b604052919050565b600067ffffffffffffffff8211156126f9576126f961295c565b5060051b60200190565b6000808335601e1984360301811261271a57600080fd5b830160208101925035905067ffffffffffffffff81111561273a57600080fd5b8060061b3603831315611f8a57600080fd5b6000808585111561275c57600080fd5b8386111561276957600080fd5b5050820193919092039150565b600082198211156127895761278961291a565b500190565b6000826127ab57634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156127ca576127ca61291a565b500290565b600060a082360312156127e157600080fd5b6127e9612685565b823567ffffffffffffffff8082111561280157600080fd5b9084019036601f83011261281457600080fd5b81356020612824611ee9836126df565b8281528181019085830136600686901b88018501111561284357600080fd5b600096505b8487101561286f5761285a3682611f91565b83526001969096019591830191604001612848565b508652508681013593508284111561288657600080fd5b61289236858901611ec8565b81860152505050506128a660408401611eac565b60408201526128b760608401612000565b60608201526128c860808401612000565b608082015292915050565b60005b838110156128ee5781810151838201526020016128d6565b8381111561187e5750506000910152565b60006000198214156129135761291361291a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122050ff5cabe47edd9569ce89e0ba0f68eff813e85d665e712a723440f1d6f5cc4564736f6c63430008070033608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61054f8061007e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063715018a61461005157806377fc3fa81461005b5780638da5cb5b1461006e578063f2fde38b1461009a575b600080fd5b6100596100ad565b005b610059610069366004610404565b6100c1565b6000546040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100596100a83660046103e2565b61018f565b6100b5610231565b6100bf6000610298565b565b6100c9610231565b60005b8181101561018957368383838181106100e7576100e76104ea565b6040029190910191506000905061010160208301836103e2565b73ffffffffffffffffffffffffffffffffffffffff1614156101235750610177565b6101758561014660005473ffffffffffffffffffffffffffffffffffffffff1690565b6020840180359061015790866103e2565b73ffffffffffffffffffffffffffffffffffffffff1692919061030d565b505b806101818161048a565b9150506100cc565b50505050565b610197610231565b73ffffffffffffffffffffffffffffffffffffffff81166102255760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61022e81610298565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146100bf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161021c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806103b25760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640161021c565b5050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146103dd57600080fd5b919050565b6000602082840312156103f457600080fd5b6103fd826103b9565b9392505050565b60008060006040848603121561041957600080fd5b610422846103b9565b9250602084013567ffffffffffffffff8082111561043f57600080fd5b818601915086601f83011261045357600080fd5b81358181111561046257600080fd5b8760208260061b850101111561047757600080fd5b6020830194508093505050509250925092565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156104e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212204dd1f47161d778557eea8c911bac4fd310ad7cc96f57ff7b36fb2fe38010b82464736f6c6343000807003300000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000005ef7f250f74d4f11a68054ae4e150705474a6d4a

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

00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000005ef7f250f74d4f11a68054ae4e150705474a6d4a

-----Decoded View---------------
Arg [0] : _wrappedNativeToken (address): 0x82af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [1] : _bank (address): 0x5ef7f250f74d4f11a68054ae4e150705474a6d4a

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [1] : 0000000000000000000000005ef7f250f74d4f11a68054ae4e150705474a6d4a


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.