Contract 0x6680ed0b92bd226f50ab704a0226391add943e55 1

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xcb9e9672b201571e9cf0216eb9f4133392f9a5cf48da4c5a7a1b6fd7824bbab2Approve287162072022-05-24 15:08:009 hrs 35 mins ago0xc38b21934a152f4331ff2752611c681078f34841 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.003583195 77
0x6cc684b2b67fe3077f343f49d5b76b8a5c26d789900f891b781d43308f184401Approve286378172022-05-22 17:21:232 days 7 hrs ago0x36a477382219adca9584b4cacbcbd19f162196e7 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001721795 37
0x3bccf0162a014093518aa3f8eb3a092a224681df4f2d40ce5585cbba7df7d8acApprove285814032022-05-21 8:19:323 days 16 hrs ago0x4a536f3994dc28122ce366dc1d8241785e751361 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001444446382 31.039999614
0x029706debc1ac1f0b69763bdba6273cac6bd594411d91f25111021838f90dc9bApprove285691652022-05-21 1:10:193 days 23 hrs ago0xa1ecd0b02df00f88635c1a588c2bb8c09d6c7603 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001468746465 31.562189017
0x6a8162cdeeede4f940eb31ec216f91ad6edc01303bcfb152c277df5107009b4dApprove285179822022-05-19 18:27:135 days 6 hrs ago0x8de12037d8dbece9bcf6b574bebcaf1c770b1ea2 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001399302529 30.069894258
0x3507360083be47323c30a3d022243f4f804f670cbb2c0528868006e55b67a267Approve284898372022-05-19 1:32:575 days 23 hrs ago0x6940a135dd473e1f08454f5bc311f82ded797e94 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001399307492 30.070000917
0x9e28259c0480b2b881111708e515efc716ff344e1b1dcc2c88587ce4f6af6534Approve284440212022-05-17 21:40:027 days 3 hrs ago0x41723746b9559f6de953414d1844f64d7f092e3a IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.00139972992330.079078625
0x72a5303cf1521440025fd7689962b61a380c76db1d2ba8abf64ee6e9cb78dd91Approve284417582022-05-17 20:16:547 days 4 hrs ago0xa8ea5ed5b7b99b7351f4c1357e913d20b49746ba IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001404605595 30.183852922
0xa4942904b1fd97864ee9ee9bc07e2ceb8b7be8f7256c51b3b53ec317375cc20cApprove284289772022-05-17 12:23:377 days 12 hrs ago0x36a477382219adca9584b4cacbcbd19f162196e7 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.00139766257 30.034652856
0x5680242d50bb8712f4281a2490e4ae0f122420a79662ae150bb7255e43b8ba40Approve284265362022-05-17 10:57:197 days 13 hrs ago0x06cecfbac34101ae41c88ebc2450f8602b3d164b IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.00139766257230.034652904
0x4ebf8c53b6ccbeb9201e9b53b152745db22470b356f12977fd4cfb72a3fc4217Approve283815152022-05-16 8:12:528 days 16 hrs ago0xe795b3c6a5691d50dcb155f4f49a7b7a9e030b31 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.0018614 40
0x8557e71f2d4d32f09f0f6db2b94f74a76aaf8ba1f97d7a325acde395301ba8a5Approve283769172022-05-16 5:34:378 days 19 hrs ago0x21f38bcb0e0ce291fb0536c41aad36586750bd02 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001407811997 30.252755943
0xd827ec010dd5a4d8400a06446b650d5ad8630073933efade234f52058d855d44Approve283680162022-05-16 0:21:549 days 21 mins ago0xc38b21934a152f4331ff2752611c681078f34841 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.001398641576 30.05569091
0xce8b5c170ea92af5e5f53753523aa4cdedb63babd29424c14f2869c4e1a7d8fdApprove283674032022-05-16 0:00:479 days 42 mins ago0x20ddbdde0e39351281bf05921aa311f0128c9edc IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.00139930745 30.070000014
0x12cd681e5f1916f079975fdd71d5e3c9ece9400edaa67004aff98b5feca9040eApprove282807812022-05-13 20:33:0711 days 4 hrs ago0x71327867a0dea69a0f1b07d8a9eba3ba0c99b5c7 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.00232675 50
0x0ed7eeda9fd4ba234aa072420e876dc58350b8209973f292e40187a5a9dfe24aApprove282699312022-05-13 13:55:5211 days 10 hrs ago0x62025a6b9cebaa7f27d1cfb69061b8c5622dc1a5 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.008368727831 179.837280154
0x765706e2b3d9dfba935cd74a9732044ee29bbc4450e1efe0e2e932670b4f7973Approve282645632022-05-13 10:44:3211 days 13 hrs ago0x18023d0662aa015b1db89b6436138c3efb6cb6b1 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.002305394215 49.541081249
0x9979071c275ed71c24ed285621125495efbe98d3ed3bd7e321bc93577a1c680eApprove282301972022-05-12 13:03:5412 days 11 hrs ago0x144a3cfc685ced2e4901478929fd952df82aab42 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.022459041124 482.626864177
0x8959fd00a2fce0fa2ef5c1af1a5aeea1f94251719f307da4efc33a59e7c17134Approve282244852022-05-12 9:26:3112 days 15 hrs ago0xf7bde049c8cf1f2428fb2610c5185042f26a2993 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.01265752 272
0x484ab5662df742476b946c6d34072832f5d19743b6a4fd6ec5739e619ce4f531Approve282244442022-05-12 9:25:0512 days 15 hrs ago0xd351b8cf884a38db68a700483b1cea9940e49a69 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.020697509323 444.772952039
0x67e0dbffb717a43dd174b98855be80348be8259f4dfb305bb0d113b8bbb03983Approve282193902022-05-12 6:21:2812 days 18 hrs ago0x144a3cfc685ced2e4901478929fd952df82aab42 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.014046649442 301.851282746
0x3334da7887c8f4e07f42b90fd078317c4b6447d64137309d0cc29396b725fb25Approve282190632022-05-12 6:10:1412 days 18 hrs ago0xe4e8301296bd883515d539490105b1c797c52fec IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.093082594484 2,000.270645416
0x316baa6b645668d3d31ff1903387481251cd136f0648c5769d652c546fe1b5c3Approve282038022022-05-11 21:00:2513 days 3 hrs ago0xd98014be6e16ecdcd52a5fd8d6ac0c2f4cc8b95d IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.550159656503 11,822.491812689
0x42c2267282ad661f3e32b4fb6f0b3ff0ec032116dfc581e3707c3be8d0f7e21aApprove281920362022-05-11 13:26:0213 days 11 hrs ago0xf6a1641eb1cccc0a5e86b045b04830c68b3d2c18 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.08878878 1,908
0x47bc6ed9a84cc238a806568f38dedcb79a221dcad01e660eafb1a0c08ebfd799Approve281920132022-05-11 13:25:1613 days 11 hrs ago0x5f3050c874fba05ca1b18a3684c818c24dc87e62 IN  0x6680ed0b92bd226f50ab704a0226391add943e550 MATIC0.076565528036 1,645.332073408
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x0fff4aa92e06451895d43d77070b01c602993f3acc907cb3643a00e2e813c7aa217183342021-11-23 19:49:35182 days 4 hrs ago 0xab6912a6574af207a6b68276c204d39b97b9be69  Contract Creation0 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LiquidityProviderToken

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion, GNU LGPLv3 license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 2 of 10 : Constants.sol
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.8.4;

/**
 * @dev See GOVERNANCE.md for descriptions of fixed parameters and fees
 */

library Constants {
  // 100 basis points/percent * 100 percent/total
  uint64 public constant basisPointsInTotal = 100 * 100;

  uint64 public constant depositIndexNotSet = 2**64 - 1;

  uint8 public constant liquidityProviderTokenDecimals = 18;

  // 1 week at 3s/block
  uint256 public constant maxChainPropagationPeriod = (7 * 24 * 60 * 60) / 3;

  // 20%
  uint64 public constant maxFeeBasisPoints = 20 * 100;

  // Pool reserve balance ratio above which price dips below 1 pip and can no longer be represented
  uint64 public constant maxLiquidityPoolReserveRatio = 10**8;

  // Pool reserve balance below which prices can no longer be represented with full pip precision
  uint64 public constant minLiquidityPoolReserveInPips = 10**8;

  // 2%
  uint64 public constant maxPoolInputFeeBasisPoints = 2 * 100;

  // 5%
  uint64 public constant maxPoolOutputAdjustmentBasisPoints = 5 * 100;

  // 1%
  uint64 public constant maxPoolPriceCorrectionBasisPoints = 1 * 100;

  // To convert integer pips to a fractional price shift decimal left by the pip precision of 8
  // decimals places
  uint64 public constant pipPriceMultiplier = 10**8;

  uint8 public constant signatureHashVersion = 3;
}

File 3 of 10 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 4 of 10 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The defaut value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);

        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;

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

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

File 5 of 10 : Enums.sol
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.8.4;

/**
 * @notice Enums definitions
 */

// Liquidity pools //

enum LiquidityChangeOrigination { OnChain, OffChain }

enum LiquidityChangeType { Addition, Removal }

enum LiquidityChangeState { NotInitiated, Initiated, Executed }

// Order book //

enum OrderSelfTradePrevention {
  // Decrement and cancel
  dc,
  // Cancel oldest
  co,
  // Cancel newest
  cn,
  // Cancel both
  cb
}

enum OrderSide { Buy, Sell }

enum OrderTimeInForce {
  // Good until cancelled
  gtc,
  // Good until time
  gtt,
  // Immediate or cancel
  ioc,
  // Fill or kill
  fok
}

enum OrderType {
  Market,
  Limit,
  LimitMaker,
  StopLoss,
  StopLossLimit,
  TakeProfit,
  TakeProfitLimit
}

// Withdrawals //

enum WithdrawalType { BySymbol, ByAddress }

File 6 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 7 of 10 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 8 of 10 : Interfaces.sol
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.8.4;

import { Order, OrderBookTrade, Withdrawal } from './Structs.sol';

/**
 * @notice Interface of the ERC20 standard as defined in the EIP, but with no return values for
 * transfer and transferFrom. By asserting expected balance changes when calling these two methods
 * we can safely ignore their return values. This allows support of non-compliant tokens that do not
 * return a boolean. See https://github.com/ethereum/solidity/issues/4116
 */
interface IERC20 {
  /**
   * @notice Returns the amount of tokens in existence.
   */
  function totalSupply() external view returns (uint256);

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

  /**
   * @notice Moves `amount` tokens from the caller's account to `recipient`.
   *
   * Most implementing contracts return a boolean value indicating whether the operation succeeded, but
   * we ignore this and rely on asserting balance changes instead
   *
   * Emits a {Transfer} event.
   */
  function transfer(address recipient, uint256 amount) external;

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

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

  /**
   * @notice Moves `amount` tokens from `sender` to `recipient` using the
   * allowance mechanism. `amount` is then deducted from the caller's
   * allowance.
   *
   * Most implementing contracts return a boolean value indicating whether the operation succeeded, but
   * we ignore this and rely on asserting balance changes instead
   *
   * Emits a {Transfer} event.
   */
  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) external;

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

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

/**
 * @notice Interface to Custodian contract. Used by Exchange and Governance contracts for internal
 * delegate calls
 */
interface ICustodian {
  /**
   * @notice ETH can only be sent by the Exchange
   */
  receive() external payable;

  /**
   * @notice Withdraw any asset and amount to a target wallet
   *
   * @dev No balance checking performed
   *
   * @param wallet The wallet to which assets will be returned
   * @param asset The address of the asset to withdraw (native asset or ERC-20 contract)
   * @param quantityInAssetUnits The quantity in asset units to withdraw
   */
  function withdraw(
    address payable wallet,
    address asset,
    uint256 quantityInAssetUnits
  ) external;

  /**
   * @notice Load address of the currently whitelisted Exchange contract
   *
   * @return The address of the currently whitelisted Exchange contract
   */
  function loadExchange() external view returns (address);

  /**
   * @notice Sets a new Exchange contract address
   *
   * @param newExchange The address of the new whitelisted Exchange contract
   */
  function setExchange(address newExchange) external;

  /**
   * @notice Load address of the currently whitelisted Governance contract
   *
   * @return The address of the currently whitelisted Governance contract
   */
  function loadGovernance() external view returns (address);

  /**
   * @notice Sets a new Governance contract address
   *
   * @param newGovernance The address of the new whitelisted Governance contract
   */
  function setGovernance(address newGovernance) external;
}

/**
 * @notice Interface to Whistler Exchange contract
 *
 * @dev Used for lazy balance migrations from old to new Exchange after upgrade
 */
interface IExchange {
  /**
   * @notice Load a wallet's balance by asset address, in pips
   *
   * @param wallet The wallet address to load the balance for. Can be different from `msg.sender`
   * @param assetAddress The asset address to load the wallet's balance for
   *
   * @return The quantity denominated in pips of asset at `assetAddress` currently deposited by `wallet`
   */
  function loadBalanceInPipsByAddress(address wallet, address assetAddress)
    external
    view
    returns (uint64);

  /**
   * @notice Load the address of the Custodian contract
   *
   * @return The address of the Custodian contract
   */
  function loadCustodian() external view returns (ICustodian);
}

interface ILiquidityProviderToken {
  function custodian() external returns (ICustodian);

  function baseAssetAddress() external returns (address);

  function quoteAssetAddress() external returns (address);

  function baseAssetSymbol() external returns (string memory);

  function quoteAssetSymbol() external returns (string memory);

  function token0() external returns (address);

  function token1() external returns (address);

  function burn(
    address wallet,
    uint256 liquidity,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits,
    address to
  ) external;

  function mint(
    address wallet,
    uint256 liquidity,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits,
    address to
  ) external;

  function reverseAssets() external;
}

interface IWETH9 is IERC20 {
  receive() external payable;

  function deposit() external payable;

  function withdraw(uint256 wad) external;
}

File 9 of 10 : LiquidityProviderToken.sol
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.8.4;

import { Address } from './Address.sol';
import { ERC20 } from './ERC20.sol';

import { Constants } from './Constants.sol';
import {
  ICustodian,
  IExchange,
  IERC20,
  ILiquidityProviderToken
} from './Interfaces.sol';

/**
 * @notice Liquidity Provider ERC-20 token contract
 *
 * @dev Reference OpenZeppelin implementation with whitelisted minting and burning
 */
contract LiquidityProviderToken is ERC20, ILiquidityProviderToken {
  // Used to whitelist Exchange-only functions by loading address of current Exchange from Custodian
  ICustodian public override custodian;

  // Base and quote asset addresses provided only for informational purposes
  address public override baseAssetAddress;
  address public override quoteAssetAddress;
  string public override baseAssetSymbol;
  string public override quoteAssetSymbol;

  /**
   * @notice Emitted when the Exchange mints new LP tokens to a wallet via `mint`
   */
  event Mint(
    address indexed sender,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits
  );
  /**
   * @notice Emitted when the Exchange burns a wallet's LP tokens via `burn`
   */
  event Burn(
    address indexed sender,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits,
    address indexed to
  );

  modifier onlyExchange() {
    require(msg.sender == custodian.loadExchange(), 'Caller is not Exchange');
    _;
  }

  /**
   * @notice Instantiate a new `LiquidityProviderToken` contract
   *
   * @dev Should be called by the Exchange via a CREATE2 op to generate stable deterministic
   * addresses and setup whitelist for `onlyExchange`-restricted functions. Asset addresses and
   * symbols are stored for informational purposes
   *
   * @param _baseAssetAddress The base asset address
   * @param _quoteAssetAddress The quote asset address
   * @param _baseAssetSymbol The base asset symbol
   * @param _quoteAssetSymbol The quote asset symbol
   */

  constructor(
    address _baseAssetAddress,
    address _quoteAssetAddress,
    string memory _baseAssetSymbol,
    string memory _quoteAssetSymbol
  ) ERC20('', 'IDEX-LP') {
    custodian = IExchange(msg.sender).loadCustodian();
    require(address(custodian) != address(0x0), 'Invalid Custodian address');

    // Assets cannot be equal
    require(
      _baseAssetAddress != _quoteAssetAddress,
      'Assets must be different'
    );

    // Each asset must be the native asset or contract
    require(
      _baseAssetAddress == address(0x0) ||
        Address.isContract(_baseAssetAddress),
      'Invalid base asset'
    );
    require(
      _quoteAssetAddress == address(0x0) ||
        Address.isContract(_quoteAssetAddress),
      'Invalid quote asset'
    );

    baseAssetAddress = _baseAssetAddress;
    quoteAssetAddress = _quoteAssetAddress;
    baseAssetSymbol = _baseAssetSymbol;
    quoteAssetSymbol = _quoteAssetSymbol;
  }

  /**
   * @notice Returns the name of the token
   */
  function name() public view override returns (string memory) {
    return
      string(
        abi.encodePacked('IDEX LP: ', baseAssetSymbol, '-', quoteAssetSymbol)
      );
  }

  /**
   * @notice Returns the address of the base-quote pair asset with the lower sort order
   */
  function token0() external view override returns (address) {
    return
      baseAssetAddress < quoteAssetAddress
        ? baseAssetAddress
        : quoteAssetAddress;
  }

  /**
   * @notice Returns the address of the base-quote pair asset with the higher sort order
   */
  function token1() external view override returns (address) {
    return
      baseAssetAddress < quoteAssetAddress
        ? quoteAssetAddress
        : baseAssetAddress;
  }

  /**
   * @notice Burns LP tokens by removing them from `wallet`'s balance and total supply
   */
  function burn(
    address wallet,
    uint256 liquidity,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits,
    address to
  ) external override onlyExchange {
    _burn(address(custodian), liquidity);

    emit Burn(
      wallet,
      baseAssetQuantityInAssetUnits,
      quoteAssetQuantityInAssetUnits,
      to
    );
  }

  /**
   * @notice Mints LP tokens by adding them to `wallet`'s balance and total supply
   */
  function mint(
    address wallet,
    uint256 liquidity,
    uint256 baseAssetQuantityInAssetUnits,
    uint256 quoteAssetQuantityInAssetUnits,
    address to
  ) external override onlyExchange {
    _mint(to, liquidity);

    emit Mint(
      wallet,
      baseAssetQuantityInAssetUnits,
      quoteAssetQuantityInAssetUnits
    );
  }

  /**
   * @notice Reverses the asset pair represented by this token by swapping `baseAssetAddress` with
   * `quoteAssetAddress` and `baseAssetSymbol` with `quoteAssetSymbol`
   */
  function reverseAssets() external override onlyExchange {
    // Assign swapped values to intermediate values first as Solidity won't allow multiple storage
    // writes in a single statement
    (
      address _baseAssetAddress,
      address _quoteAssetAddress,
      string memory _baseAssetSymbol,
      string memory _quoteAssetSymbol
    ) =
      (quoteAssetAddress, baseAssetAddress, quoteAssetSymbol, baseAssetSymbol);
    (baseAssetAddress, quoteAssetAddress, baseAssetSymbol, quoteAssetSymbol) = (
      _baseAssetAddress,
      _quoteAssetAddress,
      _baseAssetSymbol,
      _quoteAssetSymbol
    );
  }
}

File 10 of 10 : Structs.sol
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.8.4;

import { ILiquidityProviderToken, IWETH9 } from './Interfaces.sol';
import {
  LiquidityChangeOrigination,
  OrderSelfTradePrevention,
  OrderSide,
  OrderTimeInForce,
  OrderType,
  WithdrawalType
} from './Enums.sol';

/**
 * @notice Struct definitions
 */

/**
 * @notice State tracking for a hybrid liquidity pool
 *
 * @dev Base and quote asset decimals are denormalized here to avoid extra loads from
 * `AssetRegistry.Storage`
 */
struct LiquidityPool {
  // Flag to distinguish from empty struct
  bool exists;
  uint64 baseAssetReserveInPips;
  uint8 baseAssetDecimals;
  uint64 quoteAssetReserveInPips;
  uint8 quoteAssetDecimals;
  ILiquidityProviderToken liquidityProviderToken;
}

/**
 * @dev Internal struct capturing user-initiated liquidity addition request parameters
 */
struct LiquidityAddition {
  // Must equal `Constants.signatureHashVersion`
  uint8 signatureHashVersion;
  // Distinguishes between liquidity additions initated on- or off- chain
  LiquidityChangeOrigination origination;
  // UUIDv1 unique to wallet
  uint128 nonce;
  address wallet;
  address assetA;
  address assetB;
  uint256 amountADesired;
  uint256 amountBDesired;
  uint256 amountAMin;
  uint256 amountBMin;
  address to;
  uint256 deadline;
  bytes signature;
}

/**
 * @notice Internally used struct, return type from `LiquidityPools.addLiquidity`
 */
struct LiquidityAdditionDepositResult {
  string assetASymbol;
  uint64 assetAQuantityInPips;
  uint64 assetANewExchangeBalanceInPips;
  uint256 assetANewExchangeBalanceInAssetUnits;
  string assetBSymbol;
  uint64 assetBQuantityInPips;
  uint64 assetBNewExchangeBalanceInPips;
  uint256 assetBNewExchangeBalanceInAssetUnits;
}

/**
 * @notice Internally used struct, return type from `LiquidityPools.removeLiquidity`
 */
struct LiquidityRemovalDepositResult {
  address assetAddress;
  string assetSymbol;
  uint64 assetQuantityInPips;
  uint64 assetNewExchangeBalanceInPips;
  uint256 assetNewExchangeBalanceInAssetUnits;
}

/**
 * @dev Internal struct capturing user-initiated liquidity removal request parameters
 */
struct LiquidityRemoval {
  // Must equal `Constants.signatureHashVersion`
  uint8 signatureHashVersion;
  // Distinguishes between liquidity additions initated on- or off- chain
  LiquidityChangeOrigination origination;
  uint128 nonce;
  address wallet;
  address assetA;
  address assetB;
  uint256 liquidity;
  uint256 amountAMin;
  uint256 amountBMin;
  address payable to;
  uint256 deadline;
  bytes signature;
}

/**
 * @notice Argument type to `Exchange.executeAddLiquidity` and `Exchange.executeRemoveLiquidity`
 */
struct LiquidityChangeExecution {
  address baseAssetAddress;
  address quoteAssetAddress;
  uint64 liquidityInPips;
  // Gross amount including fees of base asset executed
  uint64 grossBaseQuantityInPips;
  // Gross amount including fees of quote asset executed
  uint64 grossQuoteQuantityInPips;
  // Net amount of base asset sent to pool for additions or received by wallet for removals
  uint64 netBaseQuantityInPips;
  // Net amount of quote asset sent to pool for additions or received by wallet for removals
  uint64 netQuoteQuantityInPips;
}

/**
 * @notice Internally used struct, argument type to `LiquidityPoolAdmin.migrateLiquidityPool`
 */
struct LiquidityMigration {
  address token0;
  address token1;
  bool isToken1Quote;
  uint256 desiredLiquidity;
  address to;
  IWETH9 WETH;
}

/**
 * @notice Internally used struct capturing wallet order nonce invalidations created via `invalidateOrderNonce`
 */
struct NonceInvalidation {
  bool exists;
  uint64 timestampInMs;
  uint256 effectiveBlockNumber;
}

/**
 * @notice Return type for `Exchange.loadAssetBySymbol`, and `Exchange.loadAssetByAddress`; also
 * used internally by `AssetRegistry`
 */
struct Asset {
  // Flag to distinguish from empty struct
  bool exists;
  // The asset's address
  address assetAddress;
  // The asset's symbol
  string symbol;
  // The asset's decimal precision
  uint8 decimals;
  // Flag set when asset registration confirmed. Asset deposits, trades, or withdrawals only
  // allowed if true
  bool isConfirmed;
  // Timestamp as ms since Unix epoch when isConfirmed was asserted
  uint64 confirmedTimestampInMs;
}

/**
 * @notice Argument type for `Exchange.executeOrderBookTrade` and `Hashing.getOrderWalletHash`
 */
struct Order {
  // Must equal `Constants.signatureHashVersion`
  uint8 signatureHashVersion;
  // UUIDv1 unique to wallet
  uint128 nonce;
  // Wallet address that placed order and signed hash
  address walletAddress;
  // Type of order
  OrderType orderType;
  // Order side wallet is on
  OrderSide side;
  // Order quantity in base or quote asset terms depending on isQuantityInQuote flag
  uint64 quantityInPips;
  // Is quantityInPips in quote terms
  bool isQuantityInQuote;
  // For limit orders, price in decimal pips * 10^8 in quote terms
  uint64 limitPriceInPips;
  // For stop orders, stop loss or take profit price in decimal pips * 10^8 in quote terms
  uint64 stopPriceInPips;
  // Optional custom client order ID
  string clientOrderId;
  // TIF option specified by wallet for order
  OrderTimeInForce timeInForce;
  // STP behavior specified by wallet for order
  OrderSelfTradePrevention selfTradePrevention;
  // Cancellation time specified by wallet for GTT TIF order
  uint64 cancelAfter;
  // The ECDSA signature of the order hash as produced by Hashing.getOrderWalletHash
  bytes walletSignature;
}

/**
 * @notice Argument type for `Exchange.executeOrderBookTrade` specifying execution parameters for matching orders
 */
struct OrderBookTrade {
  // Base asset symbol
  string baseAssetSymbol;
  // Quote asset symbol
  string quoteAssetSymbol;
  // Base asset address
  address baseAssetAddress;
  // Quote asset address
  address quoteAssetAddress;
  // Gross amount including fees of base asset executed
  uint64 grossBaseQuantityInPips;
  // Gross amount including fees of quote asset executed
  uint64 grossQuoteQuantityInPips;
  // Net amount of base asset received by buy side wallet after fees
  uint64 netBaseQuantityInPips;
  // Net amount of quote asset received by sell side wallet after fees
  uint64 netQuoteQuantityInPips;
  // Asset address for liquidity maker's fee
  address makerFeeAssetAddress;
  // Asset address for liquidity taker's fee
  address takerFeeAssetAddress;
  // Fee paid by liquidity maker
  uint64 makerFeeQuantityInPips;
  // Fee paid by liquidity taker, inclusive of gas fees
  uint64 takerFeeQuantityInPips;
  // Execution price of trade in decimal pips * 10^8 in quote terms
  uint64 priceInPips;
  // Which side of the order (buy or sell) the liquidity maker was on
  OrderSide makerSide;
}

/**
 * @notice Argument type for `Exchange.executePoolTrade` specifying execution parameters for an
 * order against pool liquidity
 */
struct PoolTrade {
  // Base asset symbol
  string baseAssetSymbol;
  // Quote asset symbol
  string quoteAssetSymbol;
  // Base asset address
  address baseAssetAddress;
  // Quote asset address
  address quoteAssetAddress;
  // Gross amount including fees of base asset executed
  uint64 grossBaseQuantityInPips;
  // Gross amount including fees of quote asset executed
  uint64 grossQuoteQuantityInPips;
  // If wallet is buy side, net amount of quote input to pool used to calculate output; otherwise,
  // net amount of base asset leaving pool
  uint64 netBaseQuantityInPips;
  // If wallet is buy side, net amount of base input to pool used to calculate output; otherwise,
  // net amount of quote asset leaving pool
  uint64 netQuoteQuantityInPips;
  // Fee paid by liquidity taker to pool from sent asset
  uint64 takerPoolFeeQuantityInPips;
  // Fee paid by liquidity taker to fee wallet from sent asset
  uint64 takerProtocolFeeQuantityInPips;
  // Fee paid by liquidity taker to fee wallet from received asset
  uint64 takerGasFeeQuantityInPips;
  // Fee paid by liquidity taker sell to pool taken from pool's quote asset output
  uint64 takerPriceCorrectionFeeQuantityInPips;
}

struct HybridTrade {
  OrderBookTrade orderBookTrade;
  PoolTrade poolTrade;
  // Fee paid by liquidity taker to fee wallet from received asset
  uint64 takerGasFeeQuantityInPips;
}

/**
 * @notice Argument type for `Exchange.withdraw` and `Hashing.getWithdrawalWalletHash`
 */
struct Withdrawal {
  // Distinguishes between withdrawals by asset symbol or address
  WithdrawalType withdrawalType;
  // UUIDv1 unique to wallet
  uint128 nonce;
  // Address of wallet to which funds will be returned
  address payable walletAddress;
  // Asset symbol
  string assetSymbol;
  // Asset address
  address assetAddress; // Used when assetSymbol not specified
  // Withdrawal quantity
  uint64 grossQuantityInPips;
  // Gas fee deducted from withdrawn quantity to cover dispatcher tx costs
  uint64 gasFeeInPips;
  // Not currently used but reserved for future use. Must be true
  bool autoDispatchEnabled;
  // The ECDSA signature of the withdrawal hash as produced by Hashing.getWithdrawalWalletHash
  bytes walletSignature;
}

Settings
{
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "optimizer": {
    "enabled": true,
    "runs": 1
  },
  "evmVersion": "berlin",
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "libraries": {
    "Exchange.sol": {
      "AssetRegistry": "0xc2f05d03915E7c2D9038830F7888c97e351dd3dB",
      "Depositing": "0x116310b243dd287d4285d0e8a34ce3d4adb63dac",
      "LiquidityPoolAdmin": "0x7a246e4434dd31df784bb88d3443e309e3143adc",
      "LiquidityPools": "0x0f2c07f4ecc6c9d74d16e735d2a59d00985b1962",
      "NonceInvalidations": "0x6c539e6143f70408076f35d19e7e549850c021ad",
      "Trading": "0x4d3250014ea4ecddd857fad48c3d64d2e4f037e1",
      "Withdrawing": "0xb3af24eeac0ee8b6f5798f8a75e3ecd51b18deb2"
    },
    "AssetRegistry.sol": {
      "AssetRegistry": "0xc2f05d03915E7c2D9038830F7888c97e351dd3dB"
    },
    "Depositing.sol": {
      "Depositing": "0x116310b243dd287d4285d0e8a34ce3d4adb63dac"
    },
    "LiquidityPoolAdmin.sol": {
      "LiquidityPoolAdmin": "0x7a246e4434dd31df784bb88d3443e309e3143adc"
    },
    "LiquidityPools.sol": {
      "LiquidityPools": "0x0f2c07f4ecc6c9d74d16e735d2a59d00985b1962"
    },
    "NonceInvalidations.sol": {
      "NonceInvalidations": "0x6c539e6143f70408076f35d19e7e549850c021ad"
    },
    "Trading.sol": {
      "Trading": "0x4d3250014ea4ecddd857fad48c3d64d2e4f037e1"
    },
    "Withdrawing.sol": {
      "Withdrawing": "0xb3af24eeac0ee8b6f5798f8a75e3ecd51b18deb2"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_baseAssetAddress","type":"address"},{"internalType":"address","name":"_quoteAssetAddress","type":"address"},{"internalType":"string","name":"_baseAssetSymbol","type":"string"},{"internalType":"string","name":"_quoteAssetSymbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseAssetQuantityInAssetUnits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quoteAssetQuantityInAssetUnits","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseAssetQuantityInAssetUnits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quoteAssetQuantityInAssetUnits","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseAssetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseAssetSymbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"baseAssetQuantityInAssetUnits","type":"uint256"},{"internalType":"uint256","name":"quoteAssetQuantityInAssetUnits","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"custodian","outputs":[{"internalType":"contract ICustodian","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"baseAssetQuantityInAssetUnits","type":"uint256"},{"internalType":"uint256","name":"quoteAssetQuantityInAssetUnits","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteAssetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteAssetSymbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reverseAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620019bb380380620019bb83398101604081905262000034916200047e565b60408051602080820180845260008352835180850190945260078452660494445582d4c560cc1b918401919091528151919291620000759160039162000325565b5080516200008b90600490602084019062000325565b505050336001600160a01b031663ed04a7076040518163ffffffff1660e01b815260040160206040518083038186803b158015620000c857600080fd5b505afa158015620000dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000103919062000510565b600580546001600160a01b0319166001600160a01b03929092169182179055620001745760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420437573746f6469616e20616464726573730000000000000060448201526064015b60405180910390fd5b826001600160a01b0316846001600160a01b03161415620001d85760405162461bcd60e51b815260206004820152601860248201527f417373657473206d75737420626520646966666572656e74000000000000000060448201526064016200016b565b6001600160a01b038416158062000200575062000200846200031f60201b62000afa1760201c565b620002435760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a590818985cd948185cdcd95d60721b60448201526064016200016b565b6001600160a01b03831615806200026b57506200026b836200031f60201b62000afa1760201c565b620002b95760405162461bcd60e51b815260206004820152601360248201527f496e76616c69642071756f74652061737365740000000000000000000000000060448201526064016200016b565b600680546001600160a01b038087166001600160a01b03199283161790925560078054928616929091169190911790558151620002fe90600890602085019062000325565b5080516200031490600990602084019062000325565b5050505050620005a2565b3b151590565b828054620003339062000536565b90600052602060002090601f016020900481019282620003575760008555620003a2565b82601f106200037257805160ff1916838001178555620003a2565b82800160010185558215620003a2579182015b82811115620003a257825182559160200191906001019062000385565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b600082601f830112620003dc578081fd5b81516001600160401b0380821115620003f957620003f962000573565b604051601f8301601f19908116603f0116810190828211818310171562000424576200042462000573565b8160405283815260209250868385880101111562000440578485fd5b8491505b8382101562000463578582018301518183018401529082019062000444565b838211156200047457848385830101525b9695505050505050565b6000806000806080858703121562000494578384fd5b8451620004a18162000589565b6020860151909450620004b48162000589565b60408601519093506001600160401b0380821115620004d1578384fd5b620004df88838901620003cb565b93506060870151915080821115620004f5578283fd5b506200050487828801620003cb565b91505092959194509250565b60006020828403121562000522578081fd5b81516200052f8162000589565b9392505050565b600181811c908216806200054b57607f821691505b602082108114156200056d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200059f57600080fd5b50565b61140980620005b26000396000f3fe608060405234801561001057600080fd5b50600436106101075760003560e01c806306fdde031461010c578063095ea7b31461012a5780630dfe16811461014d57806318160ddd1461016d57806323b872dd1461017f5780632ff6302c14610192578063313ce567146101a557806337209efe146101b4578063375b74c3146101c957806339509351146101dc5780636111bdaa146101ef57806370a08231146101f75780637c43c6bb146102205780638cb75cad1461022857806395d89b411461023b5780639b56916814610243578063a457c2d714610256578063a52f0b4314610269578063a9059cbb14610271578063d21220a714610284578063dd62ed3e1461028c575b600080fd5b6101146102c5565b6040516101219190611298565b60405180910390f35b61013d610138366004611145565b6102f0565b6040519015158152602001610121565b610155610306565b6040516001600160a01b039091168152602001610121565b6002545b604051908152602001610121565b61013d61018d366004611105565b610341565b600654610155906001600160a01b031681565b60405160128152602001610121565b6101c76101c2366004611170565b6103f7565b005b600554610155906001600160a01b031681565b61013d6101ea366004611145565b610520565b6101c7610557565b61017161020536600461108e565b6001600160a01b031660009081526020819052604090205490565b6101146107df565b6101c7610236366004611170565b61086d565b610114610978565b600754610155906001600160a01b031681565b61013d610264366004611145565b610a0a565b610114610aa5565b61013d61027f366004611145565b610ab2565b610155610abf565b61017161029a3660046110cd565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600860096040516020016102dc92919061125d565b604051602081830303815290604052905090565b60006102fd338484610b00565b50600192915050565b6007546006546000916001600160a01b0390811691161061033157506007546001600160a01b031690565b506006546001600160a01b031690565b600061034e848484610c25565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156103d85760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6103ec85336103e78685611333565b610b00565b506001949350505050565b600560009054906101000a90046001600160a01b03166001600160a01b0316633bffd49d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561044557600080fd5b505afa158015610459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047d91906110b1565b6001600160a01b0316336001600160a01b0316146104ad5760405162461bcd60e51b81526004016103cf906112eb565b6005546104c3906001600160a01b031685610deb565b806001600160a01b0316856001600160a01b03167fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d819364968585604051610511929190918252602082015260400190565b60405180910390a35050505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916102fd9185906103e790869061131b565b600560009054906101000a90046001600160a01b03166001600160a01b0316633bffd49d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a557600080fd5b505afa1580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd91906110b1565b6001600160a01b0316336001600160a01b03161461060d5760405162461bcd60e51b81526004016103cf906112eb565b600754600654600880546000938493849384936001600160a01b0393841693909216916009919061063d9061134a565b80601f01602080910402602001604051908101604052809291908181526020018280546106699061134a565b80156106b65780601f1061068b576101008083540402835291602001916106b6565b820191906000526020600020905b81548152906001019060200180831161069957829003601f168201915b5050505050935080546106c89061134a565b80601f01602080910402602001604051908101604052809291908181526020018280546106f49061134a565b80156107415780601f1061071657610100808354040283529160200191610741565b820191906000526020600020905b81548152906001019060200180831161072457829003601f168201915b50505050509350935093508383838360066000600760006008600060096000889190509080519060200190610777929190610ff5565b5050865161078a91906020890190610ff5565b508691906101000a8154816001600160a01b0302191690836001600160a01b031602179055508591906101000a8154816001600160a01b0302191690836001600160a01b031602179055505050505050505050565b600980546107ec9061134a565b80601f01602080910402602001604051908101604052809291908181526020018280546108189061134a565b80156108655780601f1061083a57610100808354040283529160200191610865565b820191906000526020600020905b81548152906001019060200180831161084857829003601f168201915b505050505081565b600560009054906101000a90046001600160a01b03166001600160a01b0316633bffd49d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156108bb57600080fd5b505afa1580156108cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f391906110b1565b6001600160a01b0316336001600160a01b0316146109235760405162461bcd60e51b81526004016103cf906112eb565b61092d8185610f28565b60408051848152602081018490526001600160a01b038716917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25050505050565b6060600480546109879061134a565b80601f01602080910402602001604051908101604052809291908181526020018280546109b39061134a565b8015610a005780601f106109d557610100808354040283529160200191610a00565b820191906000526020600020905b8154815290600101906020018083116109e357829003601f168201915b5050505050905090565b3360009081526001602090815260408083206001600160a01b038616845290915281205482811015610a8c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016103cf565b610a9b33856103e78685611333565b5060019392505050565b600880546107ec9061134a565b60006102fd338484610c25565b6007546006546000916001600160a01b03908116911610610aea57506006546001600160a01b031690565b506007546001600160a01b031690565b3b151590565b6001600160a01b038316610b625760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103cf565b6001600160a01b038216610bc35760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103cf565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316610c895760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103cf565b6001600160a01b038216610ceb5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103cf565b6001600160a01b03831660009081526020819052604090205481811015610d635760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103cf565b610d6d8282611333565b6001600160a01b038086166000908152602081905260408082209390935590851681529081208054849290610da390849061131b565b92505081905550826001600160a01b0316846001600160a01b03166000805160206113b483398151915284604051610ddd91815260200190565b60405180910390a350505050565b6001600160a01b038216610e4b5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103cf565b6001600160a01b03821660009081526020819052604090205481811015610ebf5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103cf565b610ec98282611333565b6001600160a01b03841660009081526020819052604081209190915560028054849290610ef7908490611333565b90915550506040518281526000906001600160a01b038516906000805160206113b483398151915290602001610c18565b6001600160a01b038216610f7e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103cf565b8060026000828254610f90919061131b565b90915550506001600160a01b03821660009081526020819052604081208054839290610fbd90849061131b565b90915550506040518181526001600160a01b038316906000906000805160206113b48339815191529060200160405180910390a35050565b8280546110019061134a565b90600052602060002090601f0160209004810192826110235760008555611069565b82601f1061103c57805160ff1916838001178555611069565b82800160010185558215611069579182015b8281111561106957825182559160200191906001019061104e565b50611075929150611079565b5090565b5b80821115611075576000815560010161107a565b60006020828403121561109f578081fd5b81356110aa8161139b565b9392505050565b6000602082840312156110c2578081fd5b81516110aa8161139b565b600080604083850312156110df578081fd5b82356110ea8161139b565b915060208301356110fa8161139b565b809150509250929050565b600080600060608486031215611119578081fd5b83356111248161139b565b925060208401356111348161139b565b929592945050506040919091013590565b60008060408385031215611157578182fd5b82356111628161139b565b946020939093013593505050565b600080600080600060a08688031215611187578081fd5b85356111928161139b565b945060208601359350604086013592506060860135915060808601356111b78161139b565b809150509295509295909350565b8054600090600181811c90808316806111df57607f831692505b60208084108214156111ff57634e487b7160e01b86526022600452602486fd5b818015611213576001811461122457611251565b60ff19861689528489019650611251565b60008881526020902060005b868110156112495781548b820152908501908301611230565b505084890196505b50505050505092915050565b68024a222ac1026281d160bd1b8152600061127b60098301856111c5565b602d60f81b815261128f60018201856111c5565b95945050505050565b6000602080835283518082850152825b818110156112c4578581018301518582016040015282016112a8565b818111156112d55783604083870101525b50601f01601f1916929092016040019392505050565b60208082526016908201527543616c6c6572206973206e6f742045786368616e676560501b604082015260600190565b6000821982111561132e5761132e611385565b500190565b60008282101561134557611345611385565b500390565b600181811c9082168061135e57607f821691505b6020821081141561137f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146113b057600080fd5b5056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220e2f34b0302d85fe79c347e6e92720d5490e0344999118c2a4d470fe48aa3071f64736f6c634300080400330000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f6190000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000

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

0000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f6190000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _baseAssetAddress (address): 0x7ceb23fd6bc0add59e62ac25578270cff1b9f619
Arg [1] : _quoteAssetAddress (address): 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [2] : _baseAssetSymbol (string): ETH
Arg [3] : _quoteAssetSymbol (string): USDC

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f619
Arg [1] : 0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [5] : 4554480000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 5553444300000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

437:5045:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3037:178;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4153:166:3;;;;;;:::i;:::-;;:::i;:::-;;;4290:14:10;;4283:22;4265:41;;4253:2;4238:18;4153:166:3;4220:92:10;3319:174:8;;;:::i;:::-;;;-1:-1:-1;;;;;4081:32:10;;;4063:51;;4051:2;4036:18;3319:174:8;4018:102:10;3144:106:3;3231:12;;3144:106;;;9662:25:10;;;9650:2;9635:18;3144:106:3;9617:76:10;4786:414:3;;;;;;:::i;:::-;;:::i;726:40:8:-;;;;;-1:-1:-1;;;;;726:40:8;;;2993:91:3;;;3075:2;10093:36:10;;10081:2;10066:18;2993:91:3;10048:87:10;3875:363:8;;;;;;:::i;:::-;;:::i;:::-;;608:36;;;;;-1:-1:-1;;;;;608:36:8;;;5595:212:3;;;;;;:::i;:::-;;:::i;4860:620:8:-;;;:::i;3308:125:3:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3408:18:3;3382:7;3408:18;;;;;;;;;;;;3308:125;857:39:8;;;:::i;4337:337::-;;;;;;:::i;:::-;;:::i;2267:102:3:-;;;:::i;770:41:8:-;;;;;-1:-1:-1;;;;;770:41:8;;;6294:371:3;;;;;;:::i;:::-;;:::i;815:38:8:-;;;:::i;3636:172:3:-;;;;;;:::i;:::-;;:::i;3598:174:8:-;;;:::i;3866:149:3:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3981:18:3;;;3955:7;3981:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3866:149;3037:178:8;3083:13;3163:15;3185:16;3133:69;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3104:106;;3037:178;:::o;4153:166:3:-;4236:4;4252:39;665:10:2;4275:7:3;4284:6;4252:8;:39::i;:::-;-1:-1:-1;4308:4:3;4153:166;;;;:::o;3319:174:8:-;3416:17;;3397:16;;3369:7;;-1:-1:-1;;;;;3416:17:8;;;3397:16;;:36;:91;;-1:-1:-1;3471:17:8;;-1:-1:-1;;;;;3471:17:8;;3319:174::o;3397:91::-;-1:-1:-1;3444:16:8;;-1:-1:-1;;;;;3444:16:8;;3319:174::o;4786:414:3:-;4892:4;4908:36;4918:6;4926:9;4937:6;4908:9;:36::i;:::-;-1:-1:-1;;;;;4982:19:3;;4955:24;4982:19;;;:11;:19;;;;;;;;665:10:2;4982:33:3;;;;;;;;5033:26;;;;5025:79;;;;-1:-1:-1;;;5025:79:3;;6979:2:10;5025:79:3;;;6961:21:10;7018:2;6998:18;;;6991:30;7057:34;7037:18;;;7030:62;-1:-1:-1;;;7108:18:10;;;7101:38;7156:19;;5025:79:3;;;;;;;;;5114:57;5123:6;665:10:2;5145:25:3;5164:6;5145:16;:25;:::i;:::-;5114:8;:57::i;:::-;-1:-1:-1;5189:4:3;;4786:414;-1:-1:-1;;;;4786:414:3:o;3875:363:8:-;1427:9;;;;;;;;;-1:-1:-1;;;;;1427:9:8;-1:-1:-1;;;;;1427:22:8;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1413:38:8;:10;-1:-1:-1;;;;;1413:38:8;;1405:73;;;;-1:-1:-1;;;1405:73:8;;;;;;;:::i;:::-;4090:9:::1;::::0;4076:36:::1;::::0;-1:-1:-1;;;;;4090:9:8::1;4102::::0;4076:5:::1;:36::i;:::-;4225:2;-1:-1:-1::0;;;;;4124:109:8::1;4136:6;-1:-1:-1::0;;;;;4124:109:8::1;;4150:29;4187:30;4124:109;;;;;;9872:25:10::0;;;9928:2;9913:18;;9906:34;9860:2;9845:18;;9827:119;4124:109:8::1;;;;;;;;3875:363:::0;;;;;:::o;5595:212:3:-;665:10:2;5683:4:3;5731:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;5731:34:3;;;;;;;;;;5683:4;;5699:80;;5722:7;;5731:47;;5768:10;;5731:47;:::i;4860:620:8:-;1427:9;;;;;;;;;-1:-1:-1;;;;;1427:9:8;-1:-1:-1;;;;;1427:22:8;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1413:38:8;:10;-1:-1:-1;;;;;1413:38:8;;1405:73;;;;-1:-1:-1;;;1405:73:8;;;;;;;:::i;:::-;5217:17:::1;::::0;5236:16:::1;::::0;5272:15:::1;5057:231:::0;;5065:25:::1;::::0;;;;;;;-1:-1:-1;;;;;5217:17:8;;::::1;::::0;5236:16;;::::1;::::0;5254::::1;::::0;5272:15;5057:231:::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5377:17;5402:18;5428:16;5452:17;5295:16;;5313:17;;5332:15;;5349:16;;5294:181;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;5294:181:8;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;-1:-1:-1::0;;;;;5294:181:8::1;;;;;-1:-1:-1::0;;;;;5294:181:8::1;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5294:181:8::1;;;;;-1:-1:-1::0;;;;;5294:181:8::1;;;;;;;;;;1484:1;;;;4860:620::o:0;857:39::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4337:337::-;1427:9;;;;;;;;;-1:-1:-1;;;;;1427:9:8;-1:-1:-1;;;;;1427:22:8;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1413:38:8;:10;-1:-1:-1;;;;;1413:38:8;;1405:73;;;;-1:-1:-1;;;1405:73:8;;;;;;;:::i;:::-;4538:20:::1;4544:2;4548:9;4538:5;:20::i;:::-;4570:99;::::0;;9872:25:10;;;9928:2;9913:18;;9906:34;;;-1:-1:-1;;;;;4570:99:8;::::1;::::0;::::1;::::0;9845:18:10;4570:99:8::1;;;;;;;4337:337:::0;;;;;:::o;2267:102:3:-;2323:13;2355:7;2348:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2267:102;:::o;6294:371::-;665:10:2;6387:4:3;6430:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6430:34:3;;;;;;;;;;6482:35;;;;6474:85;;;;-1:-1:-1;;;6474:85:3;;8952:2:10;6474:85:3;;;8934:21:10;8991:2;8971:18;;;8964:30;9030:34;9010:18;;;9003:62;-1:-1:-1;;;9081:18:10;;;9074:35;9126:19;;6474:85:3;8924:227:10;6474:85:3;6569:67;665:10:2;6592:7:3;6601:34;6620:15;6601:16;:34;:::i;6569:67::-;-1:-1:-1;6654:4:3;;6294:371;-1:-1:-1;;;6294:371:3:o;815:38:8:-;;;;;;;:::i;3636:172:3:-;3722:4;3738:42;665:10:2;3762:9:3;3773:6;3738:9;:42::i;3598:174:8:-;3695:17;;3676:16;;3648:7;;-1:-1:-1;;;;;3695:17:8;;;3676:16;;:36;:91;;-1:-1:-1;3751:16:8;;-1:-1:-1;;;;;3751:16:8;;3319:174::o;3676:91::-;-1:-1:-1;3723:17:8;;-1:-1:-1;;;;;3723:17:8;;3598:174::o;718:413:0:-;1078:20;1116:8;;;718:413::o;9558:340:3:-;-1:-1:-1;;;;;9659:19:3;;9651:68;;;;-1:-1:-1;;;9651:68:3;;8196:2:10;9651:68:3;;;8178:21:10;8235:2;8215:18;;;8208:30;8274:34;8254:18;;;8247:62;-1:-1:-1;;;8325:18:10;;;8318:34;8369:19;;9651:68:3;8168:226:10;9651:68:3;-1:-1:-1;;;;;9737:21:3;;9729:68;;;;-1:-1:-1;;;9729:68:3;;6169:2:10;9729:68:3;;;6151:21:10;6208:2;6188:18;;;6181:30;6247:34;6227:18;;;6220:62;-1:-1:-1;;;6298:18:10;;;6291:32;6340:19;;9729:68:3;6141:224:10;9729:68:3;-1:-1:-1;;;;;9808:18:3;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;9859:32;;9662:25:10;;;9859:32:3;;9635:18:10;9859:32:3;;;;;;;;9558:340;;;:::o;7139:592::-;-1:-1:-1;;;;;7244:20:3;;7236:70;;;;-1:-1:-1;;;7236:70:3;;7790:2:10;7236:70:3;;;7772:21:10;7829:2;7809:18;;;7802:30;7868:34;7848:18;;;7841:62;-1:-1:-1;;;7919:18:10;;;7912:35;7964:19;;7236:70:3;7762:227:10;7236:70:3;-1:-1:-1;;;;;7324:23:3;;7316:71;;;;-1:-1:-1;;;7316:71:3;;5362:2:10;7316:71:3;;;5344:21:10;5401:2;5381:18;;;5374:30;5440:34;5420:18;;;5413:62;-1:-1:-1;;;5491:18:10;;;5484:33;5534:19;;7316:71:3;5334:225:10;7316:71:3;-1:-1:-1;;;;;7480:17:3;;7456:21;7480:17;;;;;;;;;;;7515:23;;;;7507:74;;;;-1:-1:-1;;;7507:74:3;;6572:2:10;7507:74:3;;;6554:21:10;6611:2;6591:18;;;6584:30;6650:34;6630:18;;;6623:62;-1:-1:-1;;;6701:18:10;;;6694:36;6747:19;;7507:74:3;6544:228:10;7507:74:3;7611:22;7627:6;7611:13;:22;:::i;:::-;-1:-1:-1;;;;;7591:17:3;;;:9;:17;;;;;;;;;;;:42;;;;7643:20;;;;;;;;:30;;7667:6;;7591:9;7643:30;;7667:6;;7643:30;:::i;:::-;;;;;;;;7706:9;-1:-1:-1;;;;;7689:35:3;7698:6;-1:-1:-1;;;;;7689:35:3;-1:-1:-1;;;;;;;;;;;7717:6:3;7689:35;;;;9662:25:10;;9650:2;9635:18;;9617:76;7689:35:3;;;;;;;;7139:592;;;;:::o;8652:483::-;-1:-1:-1;;;;;8735:21:3;;8727:67;;;;-1:-1:-1;;;8727:67:3;;7388:2:10;8727:67:3;;;7370:21:10;7427:2;7407:18;;;7400:30;7466:34;7446:18;;;7439:62;-1:-1:-1;;;7517:18:10;;;7510:31;7558:19;;8727:67:3;7360:223:10;8727:67:3;-1:-1:-1;;;;;8890:18:3;;8865:22;8890:18;;;;;;;;;;;8926:24;;;;8918:71;;;;-1:-1:-1;;;8918:71:3;;5766:2:10;8918:71:3;;;5748:21:10;5805:2;5785:18;;;5778:30;5844:34;5824:18;;;5817:62;-1:-1:-1;;;5895:18:10;;;5888:32;5937:19;;8918:71:3;5738:224:10;8918:71:3;9020:23;9037:6;9020:14;:23;:::i;:::-;-1:-1:-1;;;;;8999:18:3;;:9;:18;;;;;;;;;;:44;;;;9053:12;:22;;9069:6;;8999:9;9053:22;;9069:6;;9053:22;:::i;:::-;;;;-1:-1:-1;;9091:37:3;;9662:25:10;;;9117:1:3;;-1:-1:-1;;;;;9091:37:3;;;-1:-1:-1;;;;;;;;;;;9091:37:3;9650:2:10;9635:18;9091:37:3;9617:76:10;8002:330:3;-1:-1:-1;;;;;8085:21:3;;8077:65;;;;-1:-1:-1;;;8077:65:3;;9358:2:10;8077:65:3;;;9340:21:10;9397:2;9377:18;;;9370:30;9436:33;9416:18;;;9409:61;9487:18;;8077:65:3;9330:181:10;8077:65:3;8229:6;8213:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8245:18:3;;:9;:18;;;;;;;;;;:28;;8267:6;;8245:9;:28;;8267:6;;8245:28;:::i;:::-;;;;-1:-1:-1;;8288:37:3;;9662:25:10;;;-1:-1:-1;;;;;8288:37:3;;;8305:1;;-1:-1:-1;;;;;;;;;;;8288:37:3;9650:2:10;9635:18;8288:37:3;;;;;;;8002:330;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:257:10;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;:::-;260:5;84:187;-1:-1:-1;;;84:187:10:o;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:398::-;610:6;618;671:2;659:9;650:7;646:23;642:32;639:2;;;692:6;684;677:22;639:2;736:9;723:23;755:31;780:5;755:31;:::i;:::-;805:5;-1:-1:-1;862:2:10;847:18;;834:32;875:33;834:32;875:33;:::i;:::-;927:7;917:17;;;629:311;;;;;:::o;945:466::-;1022:6;1030;1038;1091:2;1079:9;1070:7;1066:23;1062:32;1059:2;;;1112:6;1104;1097:22;1059:2;1156:9;1143:23;1175:31;1200:5;1175:31;:::i;:::-;1225:5;-1:-1:-1;1282:2:10;1267:18;;1254:32;1295:33;1254:32;1295:33;:::i;:::-;1049:362;;1347:7;;-1:-1:-1;;;1401:2:10;1386:18;;;;1373:32;;1049:362::o;1416:325::-;1484:6;1492;1545:2;1533:9;1524:7;1520:23;1516:32;1513:2;;;1566:6;1558;1551:22;1513:2;1610:9;1597:23;1629:31;1654:5;1629:31;:::i;:::-;1679:5;1731:2;1716:18;;;;1703:32;;-1:-1:-1;;;1503:238:10:o;1746:604::-;1841:6;1849;1857;1865;1873;1926:3;1914:9;1905:7;1901:23;1897:33;1894:2;;;1948:6;1940;1933:22;1894:2;1992:9;1979:23;2011:31;2036:5;2011:31;:::i;:::-;2061:5;-1:-1:-1;2113:2:10;2098:18;;2085:32;;-1:-1:-1;2164:2:10;2149:18;;2136:32;;-1:-1:-1;2215:2:10;2200:18;;2187:32;;-1:-1:-1;2271:3:10;2256:19;;2243:33;2285;2243;2285;:::i;:::-;2337:7;2327:17;;;1884:466;;;;;;;;:::o;2355:979::-;2440:12;;2405:3;;2497:1;2517:18;;;;2570;;;;2597:2;;2651:4;2643:6;2639:17;2629:27;;2597:2;2677;2725;2717:6;2714:14;2694:18;2691:38;2688:2;;;-1:-1:-1;;;2752:33:10;;2808:4;2805:1;2798:15;2838:4;2759:3;2826:17;2688:2;2869:18;2896:104;;;;3014:1;3009:319;;;;2862:466;;2896:104;-1:-1:-1;;2929:24:10;;2917:37;;2974:16;;;;-1:-1:-1;2896:104:10;;3009:319;10187:4;10206:17;;;10256:4;10240:21;;3103:1;3117:165;3131:6;3128:1;3125:13;3117:165;;;3209:14;;3196:11;;;3189:35;3252:16;;;;3146:10;;3117:165;;;3121:3;;3311:6;3306:3;3302:16;3295:23;;2862:466;;;;;;;2413:921;;;;:::o;3339:573::-;-1:-1:-1;;;3739:3:10;3732:24;3714:3;3775:46;3818:1;3813:3;3809:11;3801:6;3775:46;:::i;:::-;-1:-1:-1;;;3837:2:10;3830:15;3861:45;3903:1;3899:2;3895:10;3887:6;3861:45;:::i;:::-;3854:52;3722:190;-1:-1:-1;;;;;3722:190:10:o;4552:603::-;4664:4;4693:2;4722;4711:9;4704:21;4754:6;4748:13;4797:6;4792:2;4781:9;4777:18;4770:34;4822:4;4835:140;4849:6;4846:1;4843:13;4835:140;;;4944:14;;;4940:23;;4934:30;4910:17;;;4929:2;4906:26;4899:66;4864:10;;4835:140;;;4993:6;4990:1;4987:13;4984:2;;;5063:4;5058:2;5049:6;5038:9;5034:22;5030:31;5023:45;4984:2;-1:-1:-1;5139:2:10;5118:15;-1:-1:-1;;5114:29:10;5099:45;;;;5146:2;5095:54;;4673:482;-1:-1:-1;;;4673:482:10:o;8399:346::-;8601:2;8583:21;;;8640:2;8620:18;;;8613:30;-1:-1:-1;;;8674:2:10;8659:18;;8652:52;8736:2;8721:18;;8573:172::o;10272:128::-;10312:3;10343:1;10339:6;10336:1;10333:13;10330:2;;;10349:18;;:::i;:::-;-1:-1:-1;10385:9:10;;10320:80::o;10405:125::-;10445:4;10473:1;10470;10467:8;10464:2;;;10478:18;;:::i;:::-;-1:-1:-1;10515:9:10;;10454:76::o;10535:380::-;10614:1;10610:12;;;;10657;;;10678:2;;10732:4;10724:6;10720:17;10710:27;;10678:2;10785;10777:6;10774:14;10754:18;10751:38;10748:2;;;10831:10;10826:3;10822:20;10819:1;10812:31;10866:4;10863:1;10856:15;10894:4;10891:1;10884:15;10748:2;;10590:325;;;:::o;10920:127::-;10981:10;10976:3;10972:20;10969:1;10962:31;11012:4;11009:1;11002:15;11036:4;11033:1;11026:15;11052:131;-1:-1:-1;;;;;11127:31:10;;11117:42;;11107:2;;11173:1;11170;11163:12;11107:2;11097:86;:::o

Swarm Source

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