Contract 0x53c1fa41e67eb4841006e0a3649a890825ca6e0e 8

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x8d0c032313fb3322a83315febca8aac0d8a3a1e784b4a356436f2899cbb621e0Multicall1563725052023-12-03 4:47:2848 secs ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016974 0.1
0xdf97ecae713e059b0232460733e0abbe801578eafa2e0096c0cbf0c86e9f5149Multicall1563721242023-12-03 4:45:372 mins ago0x3b75dd318dd0f3e1faa50128f1b3b0d67cf5ef50 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00017222 0.1
0x8f0195bfc0968aa13eb7d5c4c15ebf79680acfef061b6aa9579b77a35b650b8dMulticall1563712562023-12-03 4:41:326 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016496 0.1
0x0cb3ac6732069798ca9cd6fa7dbb7725baa812f91bc98c8aac79731e38f9b419Multicall1563711812023-12-03 4:41:107 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016847 0.1
0xf0a7a9a6dbf980dd268923057666abd5020609919e0ccbf7881b041cbeeb57dbMulticall1563706662023-12-03 4:38:479 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016467 0.1
0xfb8116bf1a679463ce9e01f6561b98f5a3b3a8a4b7346c1373c2813f6039976cMulticall1563694852023-12-03 4:33:0715 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.0001514 0.1
0xa5911074ca0d4c5a9951a44f9c44d03fcf975e93dcf24e494ce7466617b8feaaMulticall1563694072023-12-03 4:32:4615 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00014794 0.1
0x99982b5aa6264abd2c2ac0ff8099d68286b16fdef0d2ea37b0a2b5bba1e69f33Multicall1563693202023-12-03 4:32:2015 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015261 0.1
0x030e6865373ec81585f87fa733ba933306a346b2488c49819c7cdcb5c5fb9364Multicall1563692552023-12-03 4:32:0216 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.0001534 0.1
0x3b7668b377f73dce44ecd0bea692920a5532e8a558af5492b0b0bfba089dfd65Multicall1563686372023-12-03 4:29:0219 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015551 0.1
0x4f1f8199e1a4679a24ece554d8205cff69113a505bf21e32cc6ac231500f74b8Multicall1563685382023-12-03 4:28:3419 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015508 0.1
0x3663d31967038b7763f68b71a0a96229ffeb17b6f503e0e52f3716e98ed4389eMulticall1563684962023-12-03 4:28:2019 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015585 0.1
0x0ee246279c6adb3bb7448a839787d9bc3bea8cb2859220f7ac4bbd66db78ec2cMulticall1563684732023-12-03 4:28:1420 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016765 0.1
0x0baa766eccc7c32aed6081cc4e065f2deb54bb449450bacc9a692e64d6586f1cMulticall1563684532023-12-03 4:28:0820 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.0001552 0.1
0xc55b17be3141cde8af8d669742090658c6a4ee40137c364107e670dab2f3fbfcMulticall1563683862023-12-03 4:27:4920 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015385 0.1
0xf7a4df1666d4ddeef9028639cf6f37ad447add35290b6b25eb6f61a5735d4912Multicall1563682782023-12-03 4:27:1621 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015257 0.1
0xe40b7d631c2e09deb76f4948855a6bb6af5b89f1ffb323fb1df257dd8d591d24Multicall1563677432023-12-03 4:24:4023 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.0001506 0.1
0x5a72d7ad9f74fa9a515a90269853f49816c898bc33b17ee709a5186500d2037eMulticall1563676952023-12-03 4:24:2523 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015071 0.1
0x0a8dac06a24167acf5e55311173233d8ea2b3560e2701e2bb21be9fb7778bdf3Multicall1563672802023-12-03 4:22:3525 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00016064 0.1
0x5146b8938e5880260e79e34c98413cc651dfed02884dd24772ced36dd7b4c6f2Multicall1563654892023-12-03 4:14:2833 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015531 0.1
0xf90ce1baeda2a85bd2695bf54c9f22c59c3ca68c48f8190484bdd1575320430fMulticall1563653052023-12-03 4:13:3834 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015552 0.1
0x7d79459a7d5fc736d8fad73234630c6417ca7fd5a33cc8330bfe33d5d5defc24Multicall1563652712023-12-03 4:13:2834 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00015465 0.1
0x69de71654faa7e91fb4a0e141475c85b8a0a3d992d67acdbaad7637c1f793475Multicall1563652122023-12-03 4:13:1035 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00014817 0.1
0x231e5e5c5cb229d67191443c97009f276a80de27ae2a805c02d1d24269fccff1Multicall1563639432023-12-03 4:06:5241 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00017387 0.1
0xe54052619ecbfda84123f6c521169ffd677ac08e9a8920c4b7c2745830290045Multicall1563639012023-12-03 4:06:4141 mins ago0x50c66c2299964882bd0e81112d305a970eb08d02 IN  0x53c1fa41e67eb4841006e0a3649a890825ca6e0e0 ETH0.00017062 0.1
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
MixedExecutor

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 100000000 runs

Other Settings:
paris EvmVersion
File 1 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 2 of 15 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 3 of 15 : Multicall.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Multicall.sol)

pragma solidity ^0.8.0;

import "./Address.sol";

/**
 * @dev Provides a function to batch together multiple calls in a single external call.
 *
 * _Available since v4.1._
 */
abstract contract Multicall {
    /**
     * @dev Receives and executes a batch of function calls on this contract.
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */
    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            results[i] = Address.functionDelegateCall(address(this), data[i]);
        }
        return results;
    }
}

File 4 of 15 : IPool.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "./IPoolErrors.sol";
import "./IPoolPosition.sol";
import "./IPoolLiquidityPosition.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// @title Perpetual Pool Position Interface
/// @notice This interface defines the functions for managing positions and liquidity positions in a perpetual pool
interface IPool is IPoolLiquidityPosition, IPoolPosition, IPoolErrors {
    struct PriceVertex {
        uint128 size;
        uint128 premiumRateX96;
    }

    struct PriceState {
        uint128 maxPriceImpactLiquidity;
        uint128 premiumRateX96;
        PriceVertex[7] priceVertices;
        uint8 pendingVertexIndex;
        uint8 liquidationVertexIndex;
        uint8 currentVertexIndex;
        uint128[7] liquidationBufferNetSizes;
    }

    /// @notice Emitted when the price vertex is changed
    event PriceVertexChanged(uint8 index, uint128 sizeAfter, uint128 premiumRateAfterX96);

    /// @notice Emitted when the protocol fee is increased
    /// @param amount The increased protocol fee
    event ProtocolFeeIncreased(uint128 amount);

    /// @notice Emitted when the protocol fee is collected
    /// @param amount The collected protocol fee
    event ProtocolFeeCollected(uint128 amount);

    /// @notice Emitted when the referral fee is increased
    /// @param referee The address of the referee
    /// @param referralToken The id of the referral token
    /// @param referralFee The amount of referral fee
    /// @param referralParentToken The id of the referral parent token
    /// @param referralParentFee The amount of referral parent fee
    event ReferralFeeIncreased(
        address indexed referee,
        uint256 indexed referralToken,
        uint128 referralFee,
        uint256 indexed referralParentToken,
        uint128 referralParentFee
    );

    /// @notice Emitted when the referral fee is collected
    /// @param referralToken The id of the referral token
    /// @param receiver The address to receive the referral fee
    /// @param amount The collected referral fee
    event ReferralFeeCollected(uint256 indexed referralToken, address indexed receiver, uint256 amount);

    function token() external view returns (IERC20);

    /// @notice Change the token config
    /// @dev The call will fail if caller is not the pool factory
    function onChangeTokenConfig() external;

    /// @notice Sample and adjust the funding rate
    function sampleAndAdjustFundingRate() external;

    /// @notice Return the price state
    /// @return maxPriceImpactLiquidity The maximum LP liquidity value used to calculate
    /// premium rate when trader increase or decrease positions
    /// @return premiumRateX96 The premium rate during the last position adjustment by the trader, as a Q32.96
    /// @return priceVertices The price vertices used to determine the pricing function
    /// @return pendingVertexIndex The index used to track the pending update of the price vertex
    /// @return liquidationVertexIndex The index used to store the net position of the liquidation
    /// @return currentVertexIndex The index used to track the current used price vertex
    /// @return liquidationBufferNetSizes The net sizes of the liquidation buffer
    function priceState()
        external
        view
        returns (
            uint128 maxPriceImpactLiquidity,
            uint128 premiumRateX96,
            PriceVertex[7] memory priceVertices,
            uint8 pendingVertexIndex,
            uint8 liquidationVertexIndex,
            uint8 currentVertexIndex,
            uint128[7] memory liquidationBufferNetSizes
        );

    /// @notice Get the market price
    /// @param side The side of the position adjustment, 1 for opening long or closing short positions,
    /// 2 for opening short or closing long positions
    /// @return marketPriceX96 The market price, as a Q64.96
    function marketPriceX96(Side side) external view returns (uint160 marketPriceX96);

    /// @notice Change the price vertex
    /// @param startExclusive The start index of the price vertex to be changed, exclusive
    /// @param endInclusive The end index of the price vertex to be changed, inclusive
    function changePriceVertex(uint8 startExclusive, uint8 endInclusive) external;

    /// @notice Return the protocol fee
    function protocolFee() external view returns (uint128);

    /// @notice Collect the protocol fee
    /// @dev This function can be called without authorization
    function collectProtocolFee() external;

    /// @notice Return the referral fee
    /// @param referralToken The id of the referral token
    function referralFees(uint256 referralToken) external view returns (uint256);

    /// @notice Collect the referral fee
    /// @param referralToken The id of the referral token
    /// @param receiver The address to receive the referral fee
    /// @return The collected referral fee
    function collectReferralFee(uint256 referralToken, address receiver) external returns (uint256);
}

File 5 of 15 : IPoolErrors.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Side} from "../../types/Side.sol";

interface IPoolErrors {
    /// @notice Liquidity is not enough to open a liquidity position
    error InvalidLiquidityToOpen();
    /// @notice Invalid caller
    error InvalidCaller(address requiredCaller);
    /// @notice Insufficient size to decrease
    error InsufficientSizeToDecrease(uint128 size, uint128 requiredSize);
    /// @notice Insufficient margin
    error InsufficientMargin();
    /// @notice Position not found
    error PositionNotFound(address requiredAccount, Side requiredSide);
    /// @notice Liquidity position not found
    error LiquidityPositionNotFound(uint256 requiredPositionID);
    /// @notice Last liquidity position cannot be closed
    error LastLiquidityPositionCannotBeClosed();
    /// @notice Caller is not the liquidator
    error CallerNotLiquidator();
    /// @notice Insufficient balance
    error InsufficientBalance(uint128 balance, uint128 requiredAmount);
    /// @notice Leverage is too high
    error LeverageTooHigh(uint256 margin, uint128 liquidity, uint32 maxLeverage);
    /// @notice Insufficient global liquidity
    error InsufficientGlobalLiquidity();
    /// @notice Risk rate is too high
    error RiskRateTooHigh(uint256 margin, uint64 liquidationExecutionFee, uint128 positionUnrealizedLoss);
    /// @notice Risk rate is too low
    error RiskRateTooLow(uint256 margin, uint64 liquidationExecutionFee, uint128 positionUnrealizedLoss);
    /// @notice Position margin rate is too low
    error MarginRateTooLow(int256 margin, int256 unrealizedPnL, uint256 maintenanceMargin);
    /// @notice Position margin rate is too high
    error MarginRateTooHigh(int256 margin, int256 unrealizedPnL, uint256 maintenanceMargin);
}

File 6 of 15 : IPoolLiquidityPosition.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Side} from "../../types/Side.sol";

/// @title Perpetual Pool Liquidity Position Interface
/// @notice This interface defines the functions for managing liquidity positions in a perpetual pool
interface IPoolLiquidityPosition {
    /// @notice Emitted when the unrealized loss metrics of the global liquidity position are changed
    /// @param lastZeroLossTimeAfter The time when the LP's net position no longer has unrealized losses
    /// or the risk buffer fund has enough balance to cover the unrealized losses of all LPs
    /// @param liquidityAfter The total liquidity of all LPs whose entry time is
    /// after `lastZeroLossTime`
    /// @param liquidityTimesUnrealizedLossAfter The product of liquidity and unrealized loss for
    /// each LP whose entry time is after `lastZeroLossTime`
    event GlobalUnrealizedLossMetricsChanged(
        uint64 lastZeroLossTimeAfter,
        uint128 liquidityAfter,
        uint256 liquidityTimesUnrealizedLossAfter
    );

    /// @notice Emitted when an LP opens a liquidity position
    /// @param account The owner of the position
    /// @param positionID The position ID
    /// @param margin The margin of the position
    /// @param liquidity The liquidity of the position
    /// @param entryUnrealizedLoss The snapshot of the unrealized loss of LP at the time of opening the position
    /// @param realizedProfitGrowthX64 The snapshot of `GlobalLiquidityPosition.realizedProfitGrowthX64`
    /// at the time of opening the position, as a Q192.64
    event LiquidityPositionOpened(
        address indexed account,
        uint96 positionID,
        uint128 margin,
        uint128 liquidity,
        uint256 entryUnrealizedLoss,
        uint256 realizedProfitGrowthX64
    );

    /// @notice Emitted when an LP closes a liquidity position
    /// @param positionID The position ID
    /// @param margin The margin removed from the position after closing
    /// @param unrealizedLoss The unrealized loss incurred by the position at the time of closing,
    /// which will be transferred to `GlobalLiquidityPosition.riskBufferFund`
    /// @param realizedProfit The realized profit of the position at the time of closing
    /// @param receiver The address that receives the margin upon closing
    event LiquidityPositionClosed(
        uint96 indexed positionID,
        uint128 margin,
        uint128 unrealizedLoss,
        uint256 realizedProfit,
        address receiver
    );

    /// @notice Emitted when the margin of an LP's position is adjusted
    /// @param positionID The position ID
    /// @param marginDelta Change in margin, positive for increase and negative for decrease
    /// @param marginAfter Adjusted margin
    /// @param entryRealizedProfitGrowthAfterX64 The snapshot of `GlobalLiquidityPosition.realizedProfitGrowthX64`
    ///  after adjustment, as a Q192.64
    /// @param receiver The address that receives the margin when it is decreased
    event LiquidityPositionMarginAdjusted(
        uint96 indexed positionID,
        int128 marginDelta,
        uint128 marginAfter,
        uint256 entryRealizedProfitGrowthAfterX64,
        address receiver
    );

    /// @notice Emitted when an LP's position is liquidated
    /// @param liquidator The address that executes the liquidation of the position
    /// @param positionID The position ID to be liquidated
    /// @param realizedProfit The realized profit of the position at the time of liquidation
    /// @param riskBufferFundDelta The remaining margin of the position after liquidation,
    /// which will be transferred to `GlobalLiquidityPosition.riskBufferFund`
    /// @param liquidationExecutionFee The liquidation execution fee paid by the position
    /// @param feeReceiver The address that receives the liquidation execution fee
    event LiquidityPositionLiquidated(
        address indexed liquidator,
        uint96 indexed positionID,
        uint256 realizedProfit,
        uint256 riskBufferFundDelta,
        uint64 liquidationExecutionFee,
        address feeReceiver
    );

    /// @notice Emitted when the net position of all LP's is adjusted
    /// @param netSizeAfter The adjusted net position size
    /// @param liquidationBufferNetSizeAfter The adjusted net position size in the liquidation buffer
    /// @param entryPriceAfterX96 The adjusted entry price, as a Q64.96
    /// @param sideAfter The adjusted side of the net position
    event GlobalLiquidityPositionNetPositionAdjusted(
        uint128 netSizeAfter,
        uint128 liquidationBufferNetSizeAfter,
        uint160 entryPriceAfterX96,
        Side sideAfter
    );

    /// @notice Emitted when the `realizedProfitGrowthX64` of the global liquidity position is changed
    /// @param realizedProfitGrowthAfterX64 The adjusted `realizedProfitGrowthX64`, as a Q192.64
    event GlobalLiquidityPositionRealizedProfitGrowthChanged(uint256 realizedProfitGrowthAfterX64);

    /// @notice Emitted when the risk buffer fund is used by `Gov`
    /// @param receiver The address that receives the risk buffer fund
    /// @param riskBufferFundDelta The amount of risk buffer fund used
    event GlobalRiskBufferFundGovUsed(address indexed receiver, uint128 riskBufferFundDelta);

    /// @notice Emitted when the risk buffer fund is changed
    event GlobalRiskBufferFundChanged(int256 riskBufferFundAfter);

    /// @notice Emitted when the liquidity of the risk buffer fund is increased
    /// @param account The owner of the position
    /// @param liquidityAfter The total liquidity of the position after the increase
    /// @param unlockTimeAfter The unlock time of the position after the increase
    event RiskBufferFundPositionIncreased(address indexed account, uint128 liquidityAfter, uint64 unlockTimeAfter);

    /// @notice Emitted when the liquidity of the risk buffer fund is decreased
    /// @param account The owner of the position
    /// @param liquidityAfter The total liquidity of the position after the decrease
    /// @param receiver The address that receives the liquidity when it is decreased
    event RiskBufferFundPositionDecreased(address indexed account, uint128 liquidityAfter, address receiver);

    struct GlobalLiquidityPosition {
        uint128 netSize;
        uint128 liquidationBufferNetSize;
        uint160 entryPriceX96;
        Side side;
        uint128 liquidity;
        uint256 realizedProfitGrowthX64;
    }

    struct GlobalRiskBufferFund {
        int256 riskBufferFund;
        uint256 liquidity;
    }

    struct GlobalUnrealizedLossMetrics {
        uint64 lastZeroLossTime;
        uint128 liquidity;
        uint256 liquidityTimesUnrealizedLoss;
    }

    struct LiquidityPosition {
        uint128 margin;
        uint128 liquidity;
        uint256 entryUnrealizedLoss;
        uint256 entryRealizedProfitGrowthX64;
        uint64 entryTime;
        address account;
    }

    struct RiskBufferFundPosition {
        uint128 liquidity;
        uint64 unlockTime;
    }

    /// @notice Get the global liquidity position
    /// @return netSize The size of the net position held by all LPs
    /// @return liquidationBufferNetSize The size of the net position held by all LPs in the liquidation buffer
    /// @return entryPriceX96 The entry price of the net position held by all LPs, as a Q64.96
    /// @return side The side of the position (Long or Short)
    /// @return liquidity The total liquidity of all LPs
    /// @return realizedProfitGrowthX64 The accumulated realized profit growth per liquidity unit, as a Q192.64
    function globalLiquidityPosition()
        external
        view
        returns (
            uint128 netSize,
            uint128 liquidationBufferNetSize,
            uint160 entryPriceX96,
            Side side,
            uint128 liquidity,
            uint256 realizedProfitGrowthX64
        );

    /// @notice Get the global unrealized loss metrics
    /// @return lastZeroLossTime The time when the LP's net position no longer has unrealized losses
    /// or the risk buffer fund has enough balance to cover the unrealized losses of all LPs
    /// @return liquidity The total liquidity of all LPs whose entry time is
    /// after `lastZeroLossTime`
    /// @return liquidityTimesUnrealizedLoss The product of liquidity and unrealized loss for
    /// each LP whose entry time is after `lastZeroLossTime`
    function globalUnrealizedLossMetrics()
        external
        view
        returns (uint64 lastZeroLossTime, uint128 liquidity, uint256 liquidityTimesUnrealizedLoss);

    /// @notice Get the information of a liquidity position
    /// @param positionID The position ID
    /// @return margin The margin of the position
    /// @return liquidity The liquidity (value) of the position
    /// @return entryUnrealizedLoss The snapshot of unrealized loss of LP at the time of opening the position
    /// @return entryRealizedProfitGrowthX64 The snapshot of `GlobalLiquidityPosition.realizedProfitGrowthX64`
    /// at the time of opening the position, as a Q192.64
    /// @return entryTime The time when the position is opened
    /// @return account The owner of the position
    function liquidityPositions(
        uint96 positionID
    )
        external
        view
        returns (
            uint128 margin,
            uint128 liquidity,
            uint256 entryUnrealizedLoss,
            uint256 entryRealizedProfitGrowthX64,
            uint64 entryTime,
            address account
        );

    /// @notice Get the owner of a specific liquidity position
    /// @param positionID The position ID
    /// @return account The owner of the position, `address(0)` returned if the position does not exist
    function liquidityPositionAccount(uint96 positionID) external view returns (address account);

    /// @notice Open a new liquidity position
    /// @dev The call will fail if the caller is not the `IRouter`
    /// @param account The owner of the position
    /// @param margin The margin of the position
    /// @param liquidity The liquidity (value) of the position
    /// @return positionID The position ID
    function openLiquidityPosition(
        address account,
        uint128 margin,
        uint128 liquidity
    ) external returns (uint96 positionID);

    /// @notice Close a liquidity position
    /// @dev The call will fail if the caller is not the `IRouter` or the position does not exist
    /// @param positionID The position ID
    /// @param receiver The address to receive the margin at the time of closing
    function closeLiquidityPosition(uint96 positionID, address receiver) external;

    /// @notice Adjust the margin of a liquidity position
    /// @dev The call will fail if the caller is not the `IRouter` or the position does not exist
    /// @param positionID The position ID
    /// @param marginDelta The change in margin, positive for increasing margin and negative for decreasing margin
    /// @param receiver The address to receive the margin when the margin is decreased
    function adjustLiquidityPositionMargin(uint96 positionID, int128 marginDelta, address receiver) external;

    /// @notice Liquidate a liquidity position
    /// @dev The call will fail if the caller is not the liquidator or the position does not exist
    /// @param positionID The position ID
    /// @param feeReceiver The address to receive the liquidation execution fee
    function liquidateLiquidityPosition(uint96 positionID, address feeReceiver) external;

    /// @notice `Gov` uses the risk buffer fund
    /// @dev The call will fail if the caller is not the `Gov` or
    /// the adjusted remaining risk buffer fund cannot cover the unrealized loss
    /// @param receiver The address to receive the risk buffer fund
    /// @param riskBufferFundDelta The used risk buffer fund
    function govUseRiskBufferFund(address receiver, uint128 riskBufferFundDelta) external;

    /// @notice Get the global risk buffer fund
    /// @return riskBufferFund The risk buffer fund, which accumulated by unrealized losses and price impact fees
    /// paid by LPs when positions are closed or liquidated. It also accumulates the remaining margin of LPs
    /// after liquidation. Additionally, the net profit or loss from closing LP's net position is also accumulated
    /// in the risk buffer fund
    /// @return liquidity The total liquidity of the risk buffer fund
    function globalRiskBufferFund() external view returns (int256 riskBufferFund, uint256 liquidity);

    /// @notice Get the liquidity of the risk buffer fund
    /// @param account The owner of the position
    /// @return liquidity The liquidity of the risk buffer fund
    /// @return unlockTime The time when the liquidity can be withdrawn
    function riskBufferFundPositions(address account) external view returns (uint128 liquidity, uint64 unlockTime);

    /// @notice Increase the liquidity of a risk buffer fund position
    /// @dev The call will fail if the caller is not the `IRouter`
    /// @param account The owner of the position
    /// @param liquidityDelta The increase in liquidity
    function increaseRiskBufferFundPosition(address account, uint128 liquidityDelta) external;

    /// @notice Decrease the liquidity of a risk buffer fund position
    /// @dev The call will fail if the caller is not the `IRouter`
    /// @param account The owner of the position
    /// @param liquidityDelta The decrease in liquidity
    /// @param receiver The address to receive the liquidity when it is decreased
    function decreaseRiskBufferFundPosition(address account, uint128 liquidityDelta, address receiver) external;
}

File 7 of 15 : IPoolPosition.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Side} from "../../types/Side.sol";

/// @title Perpetual Pool Position Interface
/// @notice This interface defines the functions for managing positions in a perpetual pool
interface IPoolPosition {
    /// @notice Emitted when the funding rate growth is adjusted
    /// @param fundingRateDeltaX96 The change in funding rate, a positive value means longs pay shorts,
    /// when a negative value means shorts pay longs, as a Q160.96
    /// @param longFundingRateGrowthAfterX96 The adjusted `GlobalPosition.longFundingRateGrowthX96`, as a Q96.96
    /// @param shortFundingRateGrowthAfterX96 The adjusted `GlobalPosition.shortFundingRateGrowthX96`, as a Q96.96
    /// @param lastAdjustFundingRateTime The adjusted `GlobalFundingRateSample.lastAdjustFundingRateTime`
    event FundingRateGrowthAdjusted(
        int256 fundingRateDeltaX96,
        int192 longFundingRateGrowthAfterX96,
        int192 shortFundingRateGrowthAfterX96,
        uint64 lastAdjustFundingRateTime
    );

    /// @notice Emitted when the position margin/liquidity (value) is increased
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increased margin
    /// @param marginAfter The adjusted margin
    /// @param sizeAfter The adjusted position size
    /// @param tradePriceX96 The trade price at which the position is adjusted.
    /// If only adding margin, it returns 0, as a Q64.96
    /// @param entryPriceAfterX96 The adjusted entry price of the position, as a Q64.96
    /// @param fundingFee The funding fee, a positive value means the position receives funding fee,
    /// while a negative value means the position positive pays funding fee
    /// @param tradingFee The trading fee paid by the position
    event PositionIncreased(
        address indexed account,
        Side side,
        uint128 marginDelta,
        uint128 marginAfter,
        uint128 sizeAfter,
        uint160 tradePriceX96,
        uint160 entryPriceAfterX96,
        int256 fundingFee,
        uint128 tradingFee
    );

    /// @notice Emitted when the position margin/liquidity (value) is decreased
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decreased margin
    /// @param marginAfter The adjusted margin
    /// @param sizeAfter The adjusted position size
    /// @param tradePriceX96 The trade price at which the position is adjusted.
    /// If only reducing margin, it returns 0, as a Q64.96
    /// @param realizedPnLDelta The realized PnL
    /// @param fundingFee The funding fee, a positive value means the position receives a funding fee,
    /// while a negative value means the position pays funding fee
    /// @param tradingFee The trading fee paid by the position
    /// @param receiver The address that receives the margin
    event PositionDecreased(
        address indexed account,
        Side side,
        uint128 marginDelta,
        uint128 marginAfter,
        uint128 sizeAfter,
        uint160 tradePriceX96,
        int256 realizedPnLDelta,
        int256 fundingFee,
        uint128 tradingFee,
        address receiver
    );

    /// @notice Emitted when a position is liquidated
    /// @param liquidator The address that executes the liquidation of the position
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param indexPriceX96 The index price when liquidating the position, as a Q64.96
    /// @param liquidationPriceX96 The liquidation price of the position, as a Q64.96
    /// @param fundingFee The funding fee, a positive value means the position receives a funding fee,
    /// while a negative value means the position pays funding fee. If it's negative,
    /// it represents the actual funding fee paid during liquidation
    /// @param tradingFee The trading fee paid by the position
    /// @param liquidationFee The liquidation fee paid by the position
    /// @param liquidationExecutionFee The liquidation execution fee paid by the position
    /// @param feeReceiver The address that receives the liquidation execution fee
    event PositionLiquidated(
        address indexed liquidator,
        address indexed account,
        Side side,
        uint160 indexPriceX96,
        uint160 liquidationPriceX96,
        int256 fundingFee,
        uint128 tradingFee,
        uint128 liquidationFee,
        uint64 liquidationExecutionFee,
        address feeReceiver
    );

    struct GlobalPosition {
        uint128 longSize;
        uint128 shortSize;
        int192 longFundingRateGrowthX96;
        int192 shortFundingRateGrowthX96;
    }

    struct PreviousGlobalFundingRate {
        int192 longFundingRateGrowthX96;
        int192 shortFundingRateGrowthX96;
    }

    struct GlobalFundingRateSample {
        uint64 lastAdjustFundingRateTime;
        uint16 sampleCount;
        int176 cumulativePremiumRateX96;
    }

    struct Position {
        uint128 margin;
        uint128 size;
        uint160 entryPriceX96;
        int192 entryFundingRateGrowthX96;
    }

    /// @notice Get the global position
    /// @return longSize The sum of long position sizes
    /// @return shortSize The sum of short position sizes
    /// @return longFundingRateGrowthX96 The funding rate growth per unit of long position sizes, as a Q96.96
    /// @return shortFundingRateGrowthX96 The funding rate growth per unit of short position sizes, as a Q96.96
    function globalPosition()
        external
        view
        returns (
            uint128 longSize,
            uint128 shortSize,
            int192 longFundingRateGrowthX96,
            int192 shortFundingRateGrowthX96
        );

    /// @notice Get the previous global funding rate growth
    /// @return longFundingRateGrowthX96 The funding rate growth per unit of long position sizes, as a Q96.96
    /// @return shortFundingRateGrowthX96 The funding rate growth per unit of short position sizes, as a Q96.96
    function previousGlobalFundingRate()
        external
        view
        returns (int192 longFundingRateGrowthX96, int192 shortFundingRateGrowthX96);

    /// @notice Get the global funding rate sample
    /// @return lastAdjustFundingRateTime The timestamp of the last funding rate adjustment
    /// @return sampleCount The number of samples taken since the last funding rate adjustment
    /// @return cumulativePremiumRateX96 The cumulative premium rate of the samples taken
    /// since the last funding rate adjustment, as a Q80.96
    function globalFundingRateSample()
        external
        view
        returns (uint64 lastAdjustFundingRateTime, uint16 sampleCount, int176 cumulativePremiumRateX96);

    /// @notice Get the information of a position
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @return margin The margin of the position
    /// @return size The size of the position
    /// @return entryPriceX96 The entry price of the position, as a Q64.96
    /// @return entryFundingRateGrowthX96 The snapshot of the funding rate growth at the time the position was opened.
    /// For long positions it is `GlobalPosition.longFundingRateGrowthX96`,
    /// and for short positions it is `GlobalPosition.shortFundingRateGrowthX96`
    function positions(
        address account,
        Side side
    ) external view returns (uint128 margin, uint128 size, uint160 entryPriceX96, int192 entryFundingRateGrowthX96);

    /// @notice Increase the margin/liquidity (value) of a position
    /// @dev The call will fail if the caller is not the `IRouter`
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increase in margin, which can be 0
    /// @param sizeDelta The increase in size, which can be 0
    /// @return tradePriceX96 The trade price at which the position is adjusted.
    /// If only adding margin, it returns 0, as a Q64.96
    function increasePosition(
        address account,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta
    ) external returns (uint160 tradePriceX96);

    /// @notice Decrease the margin/liquidity (value) of a position
    /// @dev The call will fail if the caller is not the `IRouter` or the position does not exist
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decrease in margin, which can be 0
    /// @param sizeDelta The decrease in size, which can be 0
    /// @param receiver The address to receive the margin
    /// @return tradePriceX96 The trade price at which the position is adjusted.
    /// If only reducing margin, it returns 0, as a Q64.96
    function decreasePosition(
        address account,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        address receiver
    ) external returns (uint160 tradePriceX96);

    /// @notice Liquidate a position
    /// @dev The call will fail if the caller is not the liquidator or the position does not exist
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param feeReceiver The address that receives the liquidation execution fee
    function liquidatePosition(address account, Side side, address feeReceiver) external;
}

File 8 of 15 : Governable.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

abstract contract Governable {
    address private _gov;
    address private _pendingGov;

    event ChangeGovStarted(address indexed previousGov, address indexed newGov);
    event GovChanged(address indexed previousGov, address indexed newGov);

    error Forbidden();

    modifier onlyGov() {
        _onlyGov();
        _;
    }

    constructor() {
        _changeGov(msg.sender);
    }

    function gov() public view virtual returns (address) {
        return _gov;
    }

    function pendingGov() public view virtual returns (address) {
        return _pendingGov;
    }

    function changeGov(address _newGov) public virtual onlyGov {
        _pendingGov = _newGov;
        emit ChangeGovStarted(_gov, _newGov);
    }

    function acceptGov() public virtual {
        if (msg.sender != _pendingGov) revert Forbidden();

        delete _pendingGov;
        _changeGov(msg.sender);
    }

    function _changeGov(address _newGov) internal virtual {
        address previousGov = _gov;
        _gov = _newGov;
        emit GovChanged(previousGov, _newGov);
    }

    function _onlyGov() internal view {
        if (msg.sender != _gov) revert Forbidden();
    }
}

File 9 of 15 : MixedExecutor.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;

import "../governance/Governable.sol";
import "../oracle/interfaces/IPriceFeed.sol";
import "../plugins/interfaces/IOrderBook.sol";
import "../plugins/interfaces/ILiquidator.sol";
import "../plugins/interfaces/IPositionRouter.sol";
import "@openzeppelin/contracts/utils/Multicall.sol";

/// @notice MixedExecutor is a contract that executes multiple calls in a single transaction
contract MixedExecutor is Multicall, Governable {
    /// @notice Execution error
    error ExecutionError();

    struct Slot {
        /// @notice Fee receiver
        address payable feeReceiver;
        /// @notice Indicates whether to cancel the order when an execution error occurs
        bool cancelOrderIfFailedStatus;
    }

    struct SetPricesParams {
        uint160[] priceX96s;
        uint64 timestamp;
    }

    mapping(address => bool) public executors;
    ILiquidator public immutable liquidator;
    /// @notice The address of position router
    IPositionRouter public immutable positionRouter;
    /// @notice The address of price feed
    IPriceFeed public immutable priceFeed;
    /// @notice The address of order book
    IOrderBook public immutable orderBook;
    Slot public slot;
    /// @notice Cache of token addresses used on updating the price
    IERC20[] public tokens;

    modifier onlyExecutor() {
        if (!executors[msg.sender]) revert Forbidden();
        _;
    }

    constructor(ILiquidator _liquidator, IPositionRouter _router, IPriceFeed _priceFeed, IOrderBook _orderBook) {
        (liquidator, positionRouter, priceFeed, orderBook) = (_liquidator, _router, _priceFeed, _orderBook);
        slot.cancelOrderIfFailedStatus = true;
    }

    /// @notice Set executor status active or not
    /// @param _executor Executor address
    /// @param _active Status of executor permission to set
    function setExecutor(address _executor, bool _active) external onlyGov {
        executors[_executor] = _active;
    }

    /// @notice Set the cache of token addresses used on updating the price
    /// @param _tokens The token address list
    function setTokens(IERC20[] memory _tokens) external onlyGov {
        tokens = _tokens;
    }

    /// @notice Set fee receiver
    /// @param _receiver The address of new fee receiver
    function setFeeReceiver(address payable _receiver) external onlyGov {
        slot.feeReceiver = _receiver;
    }

    /// @notice Set whether to cancel the order when an execution error occurs
    /// @param _cancelOrderIfFailedStatus If the _cancelOrderIfFailedStatus is set to 1, the order is canceled
    /// when an error occurs
    function setCancelOrderIfFailedStatus(bool _cancelOrderIfFailedStatus) external onlyGov {
        slot.cancelOrderIfFailedStatus = _cancelOrderIfFailedStatus;
    }

    /// @notice Update prices
    /// @param _params The price message to update
    function setPriceX96s(SetPricesParams calldata _params) external onlyExecutor {
        uint256 priceX96sLen = _params.priceX96s.length;
        uint256 tokensLen = tokens.length;

        IPriceFeed.TokenPrice[] memory tokenPrices = new IPriceFeed.TokenPrice[](priceX96sLen);
        for (uint256 i; i < priceX96sLen; ) {
            if (i >= tokensLen) break;

            tokenPrices[i] = IPriceFeed.TokenPrice({token: tokens[i], priceX96: _params.priceX96s[i]});

            // prettier-ignore
            unchecked { ++i; }
        }
        priceFeed.setPriceX96s(tokenPrices, _params.timestamp);
    }

    /// @notice Update prices
    /// @dev This function is used to update the price of only a subset of tokens
    /// @param _tokenPrices Array of token addresses and prices to update for
    /// @param _timestamp The timestamp of price update
    function fastSetPriceX96s(IPriceFeed.TokenPrice[] calldata _tokenPrices, uint64 _timestamp) external onlyExecutor {
        priceFeed.setPriceX96s(_tokenPrices, _timestamp);
    }

    /// @notice Execute multiple liquidity position requests
    /// @param _endIndex The maximum request index to execute, excluded
    function executeOpenLiquidityPositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeOpenLiquidityPositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple close liquidity position requests
    /// @param _endIndex The maximum request index to execute, excluded
    function executeCloseLiquidityPositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeCloseLiquidityPositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple adjust liquidity position margin requests
    /// @param _endIndex The maximum request index to execute, excluded
    function executeAdjustLiquidityPositionMargins(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeAdjustLiquidityPositionMargins(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple increase risk buffer fund positions
    /// @param _endIndex The maximum request index to execute, excluded
    function executeIncreaseRiskBufferFundPositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeIncreaseRiskBufferFundPositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple decrease risk buffer fund positions
    /// @param _endIndex The maximum request index to execute, excluded
    function executeDecreaseRiskBufferFundPositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeDecreaseRiskBufferFundPositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple increase position requests
    /// @param _endIndex The maximum request index to execute, excluded
    function executeIncreasePositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeIncreasePositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Execute multiple decrease position requests
    /// @param _endIndex The maximum request index to execute, excluded
    function executeDecreasePositions(uint128 _endIndex) external onlyExecutor {
        positionRouter.executeDecreasePositions(_endIndex, _getFeeReceiver());
    }

    /// @notice Sample and adjust funding rate
    /// @param _pool The pool address
    function sampleAndAdjustFundingRate(IPool _pool) external {
        _pool.sampleAndAdjustFundingRate();
    }

    /// @notice Collect protocol fee
    /// @param _pool The pool address
    function collectProtocolFee(IPool _pool) external {
        _pool.collectProtocolFee();
    }

    /// @notice Execute an existing increase order
    /// @param _orderIndex The index of order to execute
    /// @param _requireSuccess True if the execution error is ignored, false otherwise.
    function executeIncreaseOrder(uint256 _orderIndex, bool _requireSuccess) external onlyExecutor {
        try orderBook.executeIncreaseOrder(_orderIndex, _getFeeReceiver()) {} catch {
            if (_requireSuccess) revert ExecutionError();

            if (slot.cancelOrderIfFailedStatus)
                try orderBook.cancelIncreaseOrder(_orderIndex, _getFeeReceiver()) {} catch {}
        }
    }

    /// @notice Execute an existing decrease order
    /// @param _orderIndex The index of order to execute
    /// @param _requireSuccess True if the execution error is ignored, false otherwise.
    function executeDecreaseOrder(uint256 _orderIndex, bool _requireSuccess) external onlyExecutor {
        address payable feeReceiver = slot.feeReceiver == address(0) ? payable(msg.sender) : slot.feeReceiver;
        try orderBook.executeDecreaseOrder(_orderIndex, feeReceiver) {} catch {
            if (_requireSuccess) revert ExecutionError();

            if (slot.cancelOrderIfFailedStatus)
                try orderBook.cancelDecreaseOrder(_orderIndex, _getFeeReceiver()) {} catch {}
        }
    }

    /// @notice Liquidate a liquidity position
    /// @param _pool The pool address
    /// @param _positionID The position ID
    /// @param _requireSuccess True if the execution error is ignored, false otherwise.
    function liquidateLiquidityPosition(IPool _pool, uint96 _positionID, bool _requireSuccess) external onlyExecutor {
        try liquidator.liquidateLiquidityPosition(_pool, _positionID, _getFeeReceiver()) {} catch {
            if (_requireSuccess) revert ExecutionError();
        }
    }

    /// @notice Liquidate a position
    /// @param _pool The pool address
    /// @param _account The owner of the position
    /// @param _side The side of the position (Long or Short)
    /// @param _requireSuccess True if the execution error is ignored, false otherwise.
    function liquidatePosition(IPool _pool, address _account, Side _side, bool _requireSuccess) external onlyExecutor {
        try liquidator.liquidatePosition(_pool, _account, _side, _getFeeReceiver()) {} catch {
            if (_requireSuccess) revert ExecutionError();
        }
    }

    function _getFeeReceiver() private view returns (address payable) {
        return slot.feeReceiver == address(0) ? payable(msg.sender) : slot.feeReceiver;
    }
}

File 10 of 15 : IChainLinkAggregator.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

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

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

    function version() external view returns (uint256);

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

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

File 11 of 15 : IPriceFeed.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "./IChainLinkAggregator.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IPriceFeed {
    /// @notice Emitted when token price updated
    /// @param token Token address
    /// @param priceX96 The price passed in by updater, as a Q64.96
    /// @param maxPriceX96 Calculated maximum price, as a Q64.96
    /// @param minPriceX96 Calculated minimum price, as a Q64.96
    event PriceUpdated(IERC20 indexed token, uint160 priceX96, uint160 minPriceX96, uint160 maxPriceX96);

    /// @notice Emitted when maxCumulativeDeltaDiff exceeded
    /// @param token Token address
    /// @param priceX96 The price passed in by updater, as a Q64.96
    /// @param refPriceX96 The price provided by ChainLink, as a Q64.96
    /// @param cumulativeDelta The cumulative value of the price change ratio
    /// @param cumulativeRefDelta The cumulative value of the ChainLink price change ratio
    event MaxCumulativeDeltaDiffExceeded(
        IERC20 token,
        uint160 priceX96,
        uint160 refPriceX96,
        uint64 cumulativeDelta,
        uint64 cumulativeRefDelta
    );

    /// @notice Price not be initialized
    error NotInitialized();

    /// @notice Reference price feed not set
    error ReferencePriceFeedNotSet();

    /// @notice Invalid reference price
    /// @param referencePrice Reference price
    error InvalidReferencePrice(int256 referencePrice);

    /// @notice Reference price timeout
    /// @param elapsed The time elapsed since the last price update.
    error ReferencePriceTimeout(uint256 elapsed);

    /// @notice Stable token price timeout
    /// @param elapsed The time elapsed since the last price update.
    error StableTokenPriceTimeout(uint256 elapsed);

    /// @notice Invalid stable token price
    /// @param stableTokenPrice Stable token price
    error InvalidStableTokenPrice(int256 stableTokenPrice);

    /// @notice Invalid update timestamp
    /// @param timestamp Update timestamp
    error InvalidUpdateTimestamp(uint64 timestamp);
    /// @notice L2 sequencer is down
    error SequencerDown();
    /// @notice Grace period is not over
    /// @param sequencerUptime Sequencer uptime
    error GracePeriodNotOver(uint256 sequencerUptime);

    struct Slot {
        uint32 maxDeviationRatio;
        uint32 cumulativeRoundDuration;
        uint32 refPriceExtraSample;
        uint32 updateTxTimeout;
    }

    struct TokenConfig {
        IChainLinkAggregator refPriceFeed;
        uint32 refHeartbeatDuration;
        uint64 maxCumulativeDeltaDiff;
    }

    struct PriceDataItem {
        uint32 prevRound;
        uint160 prevRefPriceX96;
        uint64 cumulativeRefPriceDelta;
        uint160 prevPriceX96;
        uint64 cumulativePriceDelta;
    }

    struct PricePack {
        uint64 updateTimestamp;
        uint160 maxPriceX96;
        uint160 minPriceX96;
        uint64 updateBlockTimestamp;
    }

    struct TokenPrice {
        IERC20 token;
        uint160 priceX96;
    }

    /// @notice Get the address of stable token price feed
    /// @return priceFeed The address of stable token price feed
    function stableTokenPriceFeed() external view returns (IChainLinkAggregator priceFeed);

    /// @notice Get the expected update interval of stable token price
    /// @return duration The expected update interval of stable token price
    function stableTokenPriceFeedHeartBeatDuration() external view returns (uint32 duration);

    /// @notice The 0th storage slot in the price feed stores many values, which helps reduce gas
    /// costs when interacting with the price feed.
    /// @return maxDeviationRatio Maximum deviation ratio between price and ChainLink price.
    /// @return cumulativeRoundDuration Period for calculating cumulative deviation ratio.
    /// @return refPriceExtraSample The number of additional rounds for ChainLink prices to participate in price
    /// update calculation.
    /// @return updateTxTimeout The timeout for price update transactions.
    function slot()
        external
        view
        returns (
            uint32 maxDeviationRatio,
            uint32 cumulativeRoundDuration,
            uint32 refPriceExtraSample,
            uint32 updateTxTimeout
        );

    /// @notice Get token configuration for updating price
    /// @param token The token address to query the configuration
    /// @return refPriceFeed ChainLink contract address for corresponding token
    /// @return refHeartbeatDuration Expected update interval of chain link price feed
    /// @return maxCumulativeDeltaDiff Maximum cumulative change ratio difference between prices and ChainLink prices
    /// within a period of time.
    function tokenConfigs(
        IERC20 token
    )
        external
        view
        returns (IChainLinkAggregator refPriceFeed, uint32 refHeartbeatDuration, uint64 maxCumulativeDeltaDiff);

    /// @notice Get latest price data for corresponding token.
    /// @param token The token address to query the price data
    /// @return updateTimestamp The timestamp when updater uploads the price
    /// @return maxPriceX96 Calculated maximum price, as a Q64.96
    /// @return minPriceX96 Calculated minimum price, as a Q64.96
    /// @return updateBlockTimestamp The block timestamp when price is committed
    function latestPrices(
        IERC20 token
    )
        external
        view
        returns (uint64 updateTimestamp, uint160 maxPriceX96, uint160 minPriceX96, uint64 updateBlockTimestamp);

    /// @notice Update prices
    /// @dev Updater calls this method to update prices for multiple tokens. The contract calculation requires
    /// higher precision prices, so the passed-in prices need to be adjusted.
    ///
    /// ## Example
    ///
    /// The price of ETH is $2000, and ETH has 18 decimals, so the price of one unit of ETH is $`2000 / (10 ^ 18)`.
    ///
    /// The price of USD is $1, and USD has 6 decimals, so the price of one unit of USD is $`1 / (10 ^ 6)`.
    ///
    /// Then the price of ETH/USD pair is 2000 / (10 ^ 18) * (10 ^ 6)
    ///
    /// Finally convert the price to Q64.96, ETH/USD priceX96 = 2000 / (10 ^ 18) * (10 ^ 6) * (2 ^ 96)
    /// @param tokenPrices Array of token addresses and prices to update for
    /// @param timestamp The timestamp of price update
    function setPriceX96s(TokenPrice[] calldata tokenPrices, uint64 timestamp) external;

    /// @notice calculate min and max price if passed a specific price value
    /// @param tokenPrices Array of token addresses and prices to update for
    function calculatePriceX96s(
        TokenPrice[] calldata tokenPrices
    ) external view returns (uint160[] memory minPriceX96s, uint160[] memory maxPriceX96s);

    /// @notice Get minimum token price
    /// @param token The token address to query the price
    /// @return priceX96 Minimum token price
    function getMinPriceX96(IERC20 token) external view returns (uint160 priceX96);

    /// @notice Get maximum token price
    /// @param token The token address to query the price
    /// @return priceX96 Maximum token price
    function getMaxPriceX96(IERC20 token) external view returns (uint160 priceX96);

    /// @notice Set updater status active or not
    /// @param account Updater address
    /// @param active Status of updater permission to set
    function setUpdater(address account, bool active) external;

    /// @notice Check if is updater
    /// @param account The address to query the status
    /// @return active Status of updater
    function isUpdater(address account) external returns (bool active);

    /// @notice Set ChainLink contract address for corresponding token.
    /// @param token The token address to set
    /// @param priceFeed ChainLink contract address
    function setRefPriceFeed(IERC20 token, IChainLinkAggregator priceFeed) external;

    /// @notice Set SequencerUptimeFeed contract address.
    /// @param sequencerUptimeFeed SequencerUptimeFeed contract address
    function setSequencerUptimeFeed(IChainLinkAggregator sequencerUptimeFeed) external;

    /// @notice Get SequencerUptimeFeed contract address.
    /// @return sequencerUptimeFeed SequencerUptimeFeed contract address
    function sequencerUptimeFeed() external returns (IChainLinkAggregator sequencerUptimeFeed);

    /// @notice Set the expected update interval for the ChainLink oracle price of the corresponding token.
    /// If ChainLink does not update the price within this period, it is considered that ChainLink has broken down.
    /// @param token The token address to set
    /// @param duration Expected update interval
    function setRefHeartbeatDuration(IERC20 token, uint32 duration) external;

    /// @notice Set maximum deviation ratio between price and ChainLink price.
    /// If exceeded, the updated price will refer to ChainLink price.
    /// @param maxDeviationRatio Maximum deviation ratio
    function setMaxDeviationRatio(uint32 maxDeviationRatio) external;

    /// @notice Set period for calculating cumulative deviation ratio.
    /// @param cumulativeRoundDuration Period in seconds to set.
    function setCumulativeRoundDuration(uint32 cumulativeRoundDuration) external;

    /// @notice Set the maximum acceptable cumulative change ratio difference between prices and ChainLink prices
    /// within a period of time. If exceeded, the updated price will refer to ChainLink price.
    /// @param token The token address to set
    /// @param maxCumulativeDeltaDiff Maximum cumulative change ratio difference
    function setMaxCumulativeDeltaDiffs(IERC20 token, uint64 maxCumulativeDeltaDiff) external;

    /// @notice Set number of additional rounds for ChainLink prices to participate in price update calculation.
    /// @param refPriceExtraSample The number of additional sampling rounds.
    function setRefPriceExtraSample(uint32 refPriceExtraSample) external;

    /// @notice Set the timeout for price update transactions.
    /// @param updateTxTimeout The timeout for price update transactions
    function setUpdateTxTimeout(uint32 updateTxTimeout) external;

    /// @notice Set ChainLink contract address and heart beat duration config for stable token.
    /// @param stableTokenPriceFeed The stable token address to set
    /// @param stableTokenPriceFeedHeartBeatDuration The expected update interval of stable token price
    function setStableTokenPriceFeed(
        IChainLinkAggregator stableTokenPriceFeed,
        uint32 stableTokenPriceFeedHeartBeatDuration
    ) external;
}

File 12 of 15 : ILiquidator.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "../../core/interfaces/IPool.sol";
import "../../oracle/interfaces/IPriceFeed.sol";

interface ILiquidator {
    /// @notice Emitted when executor updated
    /// @param account The account to update
    /// @param active Updated status
    event ExecutorUpdated(address account, bool active);

    /// @notice Emitted when a position is closed by the liquidator
    /// @param pool The pool in which the position is closed
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param liquidationExecutionFee The liquidation execution fee paid to the liquidator
    event PositionClosedByLiquidator(
        IPool indexed pool,
        address indexed account,
        Side side,
        uint64 liquidationExecutionFee
    );

    /// @notice Update price feed contract through `IPoolFactory`
    function updatePriceFeed() external;

    /// @notice Update executor
    /// @param account Account to update
    /// @param active Updated status
    function updateExecutor(address account, bool active) external;

    /// @notice Liquidate a liquidity position
    /// @dev See `IPoolLiquidityPosition#liquidateLiquidityPosition` for more information
    /// @param pool The pool in which to liquidate the position
    /// @param positionID The position ID to liquidate
    /// @param feeReceiver The address to receive the liquidation execution fee
    function liquidateLiquidityPosition(IPool pool, uint96 positionID, address feeReceiver) external;

    /// @notice Liquidate a position
    /// @dev See `IPool#liquidatePosition` for more information
    /// @param pool The pool in which to liquidate the position
    /// @param account The owner of the position
    /// @param side The side of the position (Long or Short)
    /// @param feeReceiver The address to receive the liquidation execution fee
    function liquidatePosition(IPool pool, address account, Side side, address feeReceiver) external;
}

File 13 of 15 : IOrderBook.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "../../core/interfaces/IPool.sol";

interface IOrderBook {
    /// @notice Emitted when min execution fee updated
    /// @param minExecutionFee The new min execution fee after the update
    event MinExecutionFeeUpdated(uint256 minExecutionFee);

    /// @notice Emitted when order executor updated
    /// @param account The account to update
    /// @param active Updated status
    event OrderExecutorUpdated(address indexed account, bool active);

    /// @notice Emitted when increase order created
    /// @param account Owner of the increase order
    /// @param pool The address of the pool to increase position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increase in margin
    /// @param sizeDelta The increase in size
    /// @param triggerMarketPriceX96 Market price to trigger the order, as a Q64.96
    /// @param triggerAbove Execute the order when current price is greater than or
    /// equal to trigger price if `true` and vice versa
    /// @param acceptableTradePriceX96 Acceptable worst trade price of the order, as a Q64.96
    /// @param executionFee Amount of fee for the executor to carry out the order
    /// @param orderIndex Index of the order
    event IncreaseOrderCreated(
        address indexed account,
        IPool indexed pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 triggerMarketPriceX96,
        bool triggerAbove,
        uint160 acceptableTradePriceX96,
        uint256 executionFee,
        uint256 indexed orderIndex
    );

    /// @notice Emitted when increase order updated
    /// @param orderIndex Index of the updated order
    /// @param triggerMarketPriceX96 The new market price to trigger the order, as a Q64.96
    /// @param acceptableTradePriceX96 The new acceptable worst trade price of the order, as a Q64.96
    event IncreaseOrderUpdated(
        uint256 indexed orderIndex,
        uint160 triggerMarketPriceX96,
        uint160 acceptableTradePriceX96
    );

    /// @notice Emitted when increase order cancelled
    /// @param orderIndex Index of the cancelled order
    /// @param feeReceiver Receiver of the order execution fee
    event IncreaseOrderCancelled(uint256 indexed orderIndex, address payable feeReceiver);

    /// @notice Emitted when order executed
    /// @param orderIndex Index of the executed order
    /// @param marketPriceX96 Actual execution price, as a Q64.96
    /// @param feeReceiver Receiver of the order execution fee
    event IncreaseOrderExecuted(uint256 indexed orderIndex, uint160 marketPriceX96, address payable feeReceiver);

    /// @notice Emitted when decrease order created
    /// @param account Owner of the decrease order
    /// @param pool The address of the pool to decrease position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decrease in margin
    /// @param sizeDelta The decrease in size
    /// Note if zero, we treat it as a close position request, which will close the position,
    /// ignoring the `marginDelta` and `acceptableTradePriceX96`
    /// @param triggerMarketPriceX96 Market price to trigger the order, as a Q64.96
    /// @param triggerAbove Execute the order when current price is greater than or
    /// equal to trigger price if `true` and vice versa
    /// @param acceptableTradePriceX96 Acceptable worst trade price of the order, as a Q64.96
    /// @param receiver Margin recipient address
    /// @param executionFee Amount of fee for the executor to carry out the order
    /// @param orderIndex Index of the order
    event DecreaseOrderCreated(
        address indexed account,
        IPool indexed pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 triggerMarketPriceX96,
        bool triggerAbove,
        uint160 acceptableTradePriceX96,
        address receiver,
        uint256 executionFee,
        uint256 indexed orderIndex
    );

    /// @notice Emitted when decrease order updated
    /// @param orderIndex Index of the decrease order
    /// @param triggerMarketPriceX96 The new market price to trigger the order, as a Q64.96
    /// @param acceptableTradePriceX96 The new acceptable worst trade price of the order, as a Q64.96
    event DecreaseOrderUpdated(
        uint256 indexed orderIndex,
        uint160 triggerMarketPriceX96,
        uint160 acceptableTradePriceX96
    );

    /// @notice Emitted when decrease order cancelled
    /// @param orderIndex Index of the cancelled order
    /// @param feeReceiver Receiver of the order execution fee
    event DecreaseOrderCancelled(uint256 indexed orderIndex, address feeReceiver);

    /// @notice Emitted when decrease order executed
    /// @param orderIndex Index of the executed order
    /// @param marketPriceX96 The market price when execution, as a Q64.96
    /// @param feeReceiver Receiver of the order execution fee
    event DecreaseOrderExecuted(uint256 indexed orderIndex, uint160 marketPriceX96, address payable feeReceiver);

    /// @notice Execution fee is insufficient
    /// @param available The available execution fee amount
    /// @param required The required minimum execution fee amount
    error InsufficientExecutionFee(uint256 available, uint256 required);

    /// @notice Order not exists
    /// @param orderIndex The order index
    error OrderNotExists(uint256 orderIndex);

    /// @notice Current market price is invalid to trigger the order
    /// @param marketPriceX96 The current market price, as a Q64.96
    /// @param triggerMarketPriceX96 The trigger market price, as a Q64.96
    error InvalidMarketPriceToTrigger(uint160 marketPriceX96, uint160 triggerMarketPriceX96);

    /// @notice Trade price exceeds limit
    /// @param tradePriceX96 The trade price, as a Q64.96
    /// @param acceptableTradePriceX96 The acceptable trade price, as a Q64.96
    error InvalidTradePrice(uint160 tradePriceX96, uint160 acceptableTradePriceX96);

    struct IncreaseOrder {
        address account;
        IPool pool;
        Side side;
        uint128 marginDelta;
        uint128 sizeDelta;
        uint160 triggerMarketPriceX96;
        bool triggerAbove;
        uint160 acceptableTradePriceX96;
        uint256 executionFee;
    }

    struct DecreaseOrder {
        address account;
        IPool pool;
        Side side;
        uint128 marginDelta;
        uint128 sizeDelta;
        uint160 triggerMarketPriceX96;
        bool triggerAbove;
        uint160 acceptableTradePriceX96;
        address receiver;
        uint256 executionFee;
    }

    /// @notice Update minimum execution fee
    /// @param minExecutionFee New min execution fee
    function updateMinExecutionFee(uint256 minExecutionFee) external;

    /// @notice Update order executor
    /// @param account Account to update
    /// @param active Updated status
    function updateOrderExecutor(address account, bool active) external;

    /// @notice Update the gas limit for executing requests
    /// @param executionGasLimit New execution gas limit
    function updateExecutionGasLimit(uint256 executionGasLimit) external;

    /// @notice Create an order to open or increase the size of an existing position
    /// @param pool The pool address of position to create increase order
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increase in margin
    /// @param sizeDelta The increase in size
    /// @param triggerMarketPriceX96 Market price to trigger the order, as a Q64.96
    /// @param triggerAbove Execute the order when current price is greater than or
    /// equal to trigger price if `true` and vice versa
    /// @param acceptableTradePriceX96 Acceptable worst trade price of the order, as a Q64.96
    /// @return orderIndex Index of the order
    function createIncreaseOrder(
        IPool pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 triggerMarketPriceX96,
        bool triggerAbove,
        uint160 acceptableTradePriceX96
    ) external payable returns (uint256 orderIndex);

    /// @notice Update an existing increase order
    /// @param orderIndex The index of order to update
    /// @param triggerMarketPriceX96 The new market price to trigger the order, as a Q64.96
    /// @param acceptableTradePriceX96 The new acceptable worst trade price of the order, as a Q64.96
    function updateIncreaseOrder(
        uint256 orderIndex,
        uint160 triggerMarketPriceX96,
        uint160 acceptableTradePriceX96
    ) external;

    /// @notice Cancel an existing increase order
    /// @param orderIndex The index of order to cancel
    /// @param feeReceiver Receiver of the order execution fee
    function cancelIncreaseOrder(uint256 orderIndex, address payable feeReceiver) external;

    /// @notice Execute an existing increase order
    /// @param orderIndex The index of order to execute
    /// @param feeReceiver Receiver of the order execution fee
    function executeIncreaseOrder(uint256 orderIndex, address payable feeReceiver) external;

    /// @notice Create an order to close or decrease the size of an existing position
    /// @param pool The address of the pool to create decrease order
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decrease in margin
    /// @param sizeDelta The decrease in size
    /// Note if zero, we treat it as a close position request, which will close the position,
    /// ignoring the `marginDelta` and `acceptableTradePriceX96`
    /// @param triggerMarketPriceX96 Market price to trigger the order, as a Q64.96
    /// @param triggerAbove Execute the order when current price is greater than or
    /// equal to trigger price if `true` and vice versa
    /// @param acceptableTradePriceX96 Acceptable worst trade price of the order, as a Q64.96
    /// @param receiver Margin recipient address
    /// @return orderIndex Index of the order
    function createDecreaseOrder(
        IPool pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 triggerMarketPriceX96,
        bool triggerAbove,
        uint160 acceptableTradePriceX96,
        address receiver
    ) external payable returns (uint256 orderIndex);

    /// @notice Update an existing decrease order
    /// @param orderIndex The index of order to update
    /// @param triggerMarketPriceX96 The new market price to trigger the order, as a Q64.96
    /// @param acceptableTradePriceX96 The new acceptable worst trade price of the order, as a Q64.96
    function updateDecreaseOrder(
        uint256 orderIndex,
        uint160 triggerMarketPriceX96,
        uint160 acceptableTradePriceX96
    ) external;

    /// @notice Cancel an existing decrease order
    /// @param orderIndex The index of order to cancel
    /// @param feeReceiver Receiver of the order execution fee
    function cancelDecreaseOrder(uint256 orderIndex, address payable feeReceiver) external;

    /// @notice Execute an existing decrease order
    /// @param orderIndex The index of order to execute
    /// @param feeReceiver Receiver of the order execution fee
    function executeDecreaseOrder(uint256 orderIndex, address payable feeReceiver) external;

    /// @notice Create take-profit and stop-loss orders in a single call
    /// @param pool The pool address of position to create orders
    /// @param side The side of the position (Long or Short)
    /// @param marginDeltas The decreases in margin
    /// @param sizeDeltas The decreases in size
    /// @param triggerMarketPriceX96s Market prices to trigger the order, as Q64.96s
    /// @param acceptableTradePriceX96s Acceptable worst trade prices of the orders, as Q64.96s
    /// @param receiver Margin recipient address
    function createTakeProfitAndStopLossOrders(
        IPool pool,
        Side side,
        uint128[2] calldata marginDeltas,
        uint128[2] calldata sizeDeltas,
        uint160[2] calldata triggerMarketPriceX96s,
        uint160[2] calldata acceptableTradePriceX96s,
        address receiver
    ) external payable;
}

File 14 of 15 : IPositionRouter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "../../core/interfaces/IPool.sol";

interface IPositionRouter {
    /// @notice Emitted when min execution fee updated
    /// @param minExecutionFee New min execution fee after the update
    event MinExecutionFeeUpdated(uint256 minExecutionFee);

    /// @notice Emitted when position executor updated
    /// @param account Account to update
    /// @param active Whether active after the update
    event PositionExecutorUpdated(address indexed account, bool active);

    /// @notice Emitted when delay parameter updated
    /// @param minBlockDelayExecutor The new min block delay for executor to execute requests
    /// @param minTimeDelayPublic The new min time delay for public to execute requests
    /// @param maxTimeDelay The new max time delay until request expires
    event DelayValuesUpdated(uint32 minBlockDelayExecutor, uint32 minTimeDelayPublic, uint32 maxTimeDelay);

    /// @notice Emitted when open liquidity position request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to open liquidity position
    /// @param margin Margin of the position
    /// @param liquidity Liquidity of the position
    /// @param executionFee Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event OpenLiquidityPositionCreated(
        address indexed account,
        IPool indexed pool,
        uint128 margin,
        uint256 liquidity,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when open liquidity position request cancelled
    /// @param index Index of the cancelled request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event OpenLiquidityPositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when open liquidity position request executed
    /// @param index Index of the order to execute
    /// @param executionFeeReceiver Receiver of the order execution fee
    event OpenLiquidityPositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when close liquidity position request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to close liquidity position
    /// @param positionID ID of the position
    /// @param receiver Address of the margin receiver
    /// @param executionFee  Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event CloseLiquidityPositionCreated(
        address indexed account,
        IPool indexed pool,
        uint96 positionID,
        address receiver,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when close liquidity position request cancelled
    /// @param index Index of cancelled request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event CloseLiquidityPositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when close liquidity position request executed
    /// @param index Index of the executed request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event CloseLiquidityPositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when adjust liquidity position margin request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to adjust liquidity position margin
    /// @param positionID ID of the position
    /// @param marginDelta Delta of margin of the adjustment
    /// @param receiver Address of the margin receiver
    /// @param executionFee Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event AdjustLiquidityPositionMarginCreated(
        address indexed account,
        IPool indexed pool,
        uint96 positionID,
        int128 marginDelta,
        address receiver,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when adjust liquidity position margin request cancelled
    /// @param index Index of cancelled request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event AdjustLiquidityPositionMarginCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when adjust liquidity position margin request executed
    /// @param index Index of executed request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event AdjustLiquidityPositionMarginExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when increase risk buffer fund position request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to increase risk buffer fund position
    /// @param liquidityDelta The increase in liquidity
    /// @param executionFee Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event IncreaseRiskBufferFundPositionCreated(
        address indexed account,
        IPool indexed pool,
        uint128 liquidityDelta,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when increase risk buffer fund position request cancelled
    /// @param index Index of the cancelled request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event IncreaseRiskBufferFundPositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when increase risk buffer fund position request executed
    /// @param index Index of the executed request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event IncreaseRiskBufferFundPositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when decrease risk buffer fund position request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to decrease risk buffer fund position
    /// @param liquidityDelta The decrease in liquidity
    /// @param receiver Address of the margin receiver
    /// @param executionFee Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event DecreaseRiskBufferFundPositionCreated(
        address indexed account,
        IPool indexed pool,
        uint128 liquidityDelta,
        address receiver,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when decrease risk buffer fund position request cancelled
    /// @param index Index of the cancelled request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event DecreaseRiskBufferFundPositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when decrease risk buffer fund position request executed
    /// @param index Index of the executed request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event DecreaseRiskBufferFundPositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when open or increase an existing position size request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to increase position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increase in position margin
    /// @param sizeDelta The increase in position size
    /// @param acceptableTradePriceX96 The worst trade price of the request
    /// @param executionFee Amount of fee for the executor to carry out the request
    /// @param index Index of the request
    event IncreasePositionCreated(
        address indexed account,
        IPool indexed pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 acceptableTradePriceX96,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when increase position request cancelled
    /// @param index Index of the cancelled request
    /// @param executionFeeReceiver Receiver of the cancelled request execution fee
    event IncreasePositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when increase position request executed
    /// @param index Index of the executed request
    /// @param executionFeeReceiver Receiver of the executed request execution fee
    event IncreasePositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when close or decrease existing position size request created
    /// @param account Owner of the request
    /// @param pool The address of the pool to decrease position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decrease in position margin
    /// @param sizeDelta The decrease in position size
    /// @param acceptableTradePriceX96 The worst trade price of the request
    /// @param receiver Address of the margin receiver
    /// @param executionFee Amount of fee for the executor to carry out the order
    /// @param index Index of the request
    event DecreasePositionCreated(
        address indexed account,
        IPool indexed pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 acceptableTradePriceX96,
        address receiver,
        uint256 executionFee,
        uint128 indexed index
    );

    /// @notice Emitted when decrease position request cancelled
    /// @param index Index of the cancelled decrease position request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event DecreasePositionCancelled(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Emitted when decrease position request executed
    /// @param index Index of the executed decrease position request
    /// @param executionFeeReceiver Receiver of the request execution fee
    event DecreasePositionExecuted(uint128 indexed index, address payable executionFeeReceiver);

    /// @notice Execution fee is insufficient
    /// @param available The available execution fee amount
    /// @param required The required minimum execution fee amount
    error InsufficientExecutionFee(uint256 available, uint256 required);

    /// @notice Request expired
    /// @param expiredAt When the request is expired
    error Expired(uint256 expiredAt);

    /// @notice Too early to execute request
    /// @param earliest The earliest time to execute the request
    error TooEarly(uint256 earliest);

    /// @notice Trade price exceeds limit
    error InvalidTradePrice(uint160 tradePriceX96, uint160 acceptableTradePriceX96);

    struct OpenLiquidityPositionRequest {
        address account;
        uint96 blockNumber;
        IPool pool;
        uint64 blockTime;
        uint128 margin;
        uint128 liquidity;
        uint256 executionFee;
    }

    struct CloseLiquidityPositionRequest {
        address account;
        uint96 positionID;
        IPool pool;
        uint96 blockNumber;
        uint256 executionFee;
        address receiver;
        uint64 blockTime;
    }

    struct AdjustLiquidityPositionMarginRequest {
        address account;
        uint96 positionID;
        IPool pool;
        uint96 blockNumber;
        int128 marginDelta;
        uint64 blockTime;
        address receiver;
        uint256 executionFee;
    }

    struct IncreaseRiskBufferFundPositionRequest {
        address account;
        uint96 blockNumber;
        IPool pool;
        uint64 blockTime;
        uint128 liquidityDelta;
        uint256 executionFee;
    }

    struct DecreaseRiskBufferFundPositionRequest {
        address account;
        uint96 blockNumber;
        IPool pool;
        uint64 blockTime;
        uint128 liquidityDelta;
        address receiver;
        uint256 executionFee;
    }

    struct IncreasePositionRequest {
        address account;
        uint96 blockNumber;
        IPool pool;
        uint128 marginDelta;
        uint128 sizeDelta;
        uint160 acceptableTradePriceX96;
        uint64 blockTime;
        Side side;
        uint256 executionFee;
    }

    struct DecreasePositionRequest {
        address account;
        uint96 blockNumber;
        IPool pool;
        uint128 marginDelta;
        uint128 sizeDelta;
        uint160 acceptableTradePriceX96;
        uint64 blockTime;
        Side side;
        address receiver;
        uint256 executionFee;
    }

    /// @notice Update position executor
    /// @param account Account to update
    /// @param active Updated status
    function updatePositionExecutor(address account, bool active) external;

    /// @notice Update delay parameters
    /// @param minBlockDelayExecutor New min block delay for executor to execute requests
    /// @param minTimeDelayPublic New min time delay for public to execute requests
    /// @param maxTimeDelay New max time delay until request expires
    function updateDelayValues(uint32 minBlockDelayExecutor, uint32 minTimeDelayPublic, uint32 maxTimeDelay) external;

    /// @notice Update minimum execution fee
    /// @param minExecutionFee New min execution fee
    function updateMinExecutionFee(uint256 minExecutionFee) external;

    /// @notice Update the gas limit for executing requests
    /// @param executionGasLimit New execution gas limit
    function updateExecutionGasLimit(uint160 executionGasLimit) external;

    /// @notice Create open liquidity position request
    /// @param pool The address of the pool to open liquidity position
    /// @param margin Margin of the position
    /// @param liquidity Liquidity of the position
    /// @return index Index of the request
    function createOpenLiquidityPosition(
        IPool pool,
        uint128 margin,
        uint128 liquidity
    ) external payable returns (uint128 index);

    /// @notice Cancel open liquidity position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelOpenLiquidityPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute open liquidity position request
    /// @param index Index of request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeOpenLiquidityPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple liquidity position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fees
    function executeOpenLiquidityPositions(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create close liquidity position request
    /// @param pool The address of the pool to close liquidity position
    /// @param positionID ID of the position
    /// @param receiver Address of the margin receiver
    /// @return index The request index
    function createCloseLiquidityPosition(
        IPool pool,
        uint96 positionID,
        address receiver
    ) external payable returns (uint128 index);

    /// @notice Cancel close liquidity position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelCloseLiquidityPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute close liquidity position request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeCloseLiquidityPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple close liquidity position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeCloseLiquidityPositions(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create adjust liquidity position margin request
    /// @param pool The address of the pool to adjust liquidity position margin
    /// @param positionID ID of the position
    /// @param marginDelta Delta of margin of the adjustment
    /// @param receiver Address of the margin receiver
    /// @return index Index of the request
    function createAdjustLiquidityPositionMargin(
        IPool pool,
        uint96 positionID,
        int128 marginDelta,
        address receiver
    ) external payable returns (uint128 index);

    /// @notice Cancel adjust liquidity position margin request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelAdjustLiquidityPositionMargin(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute adjust liquidity position margin request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeAdjustLiquidityPositionMargin(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple adjust liquidity position margin requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeAdjustLiquidityPositionMargins(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create increase risk buffer fund position request
    /// @param pool The address of the pool to increase risk buffer fund position
    /// @param liquidityDelta The increase in liquidity
    /// @return index Index of the request
    function createIncreaseRiskBufferFundPosition(
        IPool pool,
        uint128 liquidityDelta
    ) external payable returns (uint128 index);

    /// @notice Cancel increase risk buffer fund position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelIncreaseRiskBufferFundPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute increase risk buffer fund position request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeIncreaseRiskBufferFundPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple increase risk buffer fund position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeIncreaseRiskBufferFundPositions(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create decrease risk buffer fund position request
    /// @param pool The address of the pool to decrease risk buffer fund position
    /// @param liquidityDelta The decrease in liquidity
    /// @param receiver Address of the margin receiver
    /// @return index Index of the request
    function createDecreaseRiskBufferFundPosition(
        IPool pool,
        uint128 liquidityDelta,
        address receiver
    ) external payable returns (uint128 index);

    /// @notice Cancel decrease risk buffer fund position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelDecreaseRiskBufferFundPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute decrease risk buffer fund position request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeDecreaseRiskBufferFundPosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple decrease risk buffer fund position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeDecreaseRiskBufferFundPositions(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create open or increase the size of existing position request
    /// @param pool The address of the pool to increase position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The increase in position margin
    /// @param sizeDelta The increase in position size
    /// @param acceptableTradePriceX96 The worst trade price of the request, as a Q64.96
    /// @return index Index of the request
    function createIncreasePosition(
        IPool pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 acceptableTradePriceX96
    ) external payable returns (uint128 index);

    /// @notice Cancel increase position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelIncreasePosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute increase position request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeIncreasePosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple increase position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeIncreasePositions(uint128 endIndex, address payable executionFeeReceiver) external;

    /// @notice Create decrease position request
    /// @param pool The address of the pool to decrease position
    /// @param side The side of the position (Long or Short)
    /// @param marginDelta The decrease in position margin
    /// @param sizeDelta The decrease in position size
    /// @param acceptableTradePriceX96 The worst trade price of the request, as a Q64.96
    /// @param receiver Margin recipient address
    /// @return index The request index
    function createDecreasePosition(
        IPool pool,
        Side side,
        uint128 marginDelta,
        uint128 sizeDelta,
        uint160 acceptableTradePriceX96,
        address receiver
    ) external payable returns (uint128 index);

    /// @notice Cancel decrease position request
    /// @param index Index of the request to cancel
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return cancelled True if the cancellation succeeds or request not exists
    function cancelDecreasePosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool cancelled);

    /// @notice Execute decrease position request
    /// @param index Index of the request to execute
    /// @param executionFeeReceiver Receiver of the request execution fee
    /// @return executed True if the execution succeeds or request not exists
    function executeDecreasePosition(
        uint128 index,
        address payable executionFeeReceiver
    ) external returns (bool executed);

    /// @notice Execute multiple decrease position requests
    /// @param endIndex The maximum request index to execute, excluded
    /// @param executionFeeReceiver Receiver of the request execution fee
    function executeDecreasePositions(uint128 endIndex, address payable executionFeeReceiver) external;
}

File 15 of 15 : Side.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

Side constant LONG = Side.wrap(1);
Side constant SHORT = Side.wrap(2);

type Side is uint8;

error InvalidSide(Side side);

using {requireValid, isLong, isShort, flip, eq as ==} for Side global;

function requireValid(Side self) pure {
    if (!isLong(self) && !isShort(self)) revert InvalidSide(self);
}

function isLong(Side self) pure returns (bool) {
    return Side.unwrap(self) == Side.unwrap(LONG);
}

function isShort(Side self) pure returns (bool) {
    return Side.unwrap(self) == Side.unwrap(SHORT);
}

function eq(Side self, Side other) pure returns (bool) {
    return Side.unwrap(self) == Side.unwrap(other);
}

function flip(Side self) pure returns (Side) {
    return isLong(self) ? SHORT : LONG;
}

Settings
{
  "evmVersion": "paris",
  "viaIR": true,
  "optimizer": {
    "enabled": true,
    "runs": 100000000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"contract ILiquidator","name":"_liquidator","type":"address"},{"internalType":"contract IPositionRouter","name":"_router","type":"address"},{"internalType":"contract IPriceFeed","name":"_priceFeed","type":"address"},{"internalType":"contract IOrderBook","name":"_orderBook","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExecutionError","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGov","type":"address"},{"indexed":true,"internalType":"address","name":"newGov","type":"address"}],"name":"ChangeGovStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGov","type":"address"},{"indexed":true,"internalType":"address","name":"newGov","type":"address"}],"name":"GovChanged","type":"event"},{"inputs":[],"name":"acceptGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGov","type":"address"}],"name":"changeGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"_pool","type":"address"}],"name":"collectProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeAdjustLiquidityPositionMargins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeCloseLiquidityPositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"bool","name":"_requireSuccess","type":"bool"}],"name":"executeDecreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeDecreasePositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeDecreaseRiskBufferFundPositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"bool","name":"_requireSuccess","type":"bool"}],"name":"executeIncreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeIncreasePositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeIncreaseRiskBufferFundPositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_endIndex","type":"uint128"}],"name":"executeOpenLiquidityPositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"executors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint160","name":"priceX96","type":"uint160"}],"internalType":"struct IPriceFeed.TokenPrice[]","name":"_tokenPrices","type":"tuple[]"},{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"fastSetPriceX96s","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"_pool","type":"address"},{"internalType":"uint96","name":"_positionID","type":"uint96"},{"internalType":"bool","name":"_requireSuccess","type":"bool"}],"name":"liquidateLiquidityPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"_pool","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"Side","name":"_side","type":"uint8"},{"internalType":"bool","name":"_requireSuccess","type":"bool"}],"name":"liquidatePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidator","outputs":[{"internalType":"contract ILiquidator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"orderBook","outputs":[{"internalType":"contract IOrderBook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionRouter","outputs":[{"internalType":"contract IPositionRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"_pool","type":"address"}],"name":"sampleAndAdjustFundingRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_cancelOrderIfFailedStatus","type":"bool"}],"name":"setCancelOrderIfFailedStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bool","name":"_active","type":"bool"}],"name":"setExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"setFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint160[]","name":"priceX96s","type":"uint160[]"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"internalType":"struct MixedExecutor.SetPricesParams","name":"_params","type":"tuple"}],"name":"setPriceX96s","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"_tokens","type":"address[]"}],"name":"setTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slot","outputs":[{"internalType":"address payable","name":"feeReceiver","type":"address"},{"internalType":"bool","name":"cancelOrderIfFailedStatus","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

610100346200016f57601f620026d438819003918201601f19168301916001600160401b0383118484101762000174578084926080946040528339810103126200016f5780516001600160a01b039182821682036200016f5760208101519083821682036200016f5760408101519084821682036200016f576060015184811681036200016f576000543360018060a01b0319821617600055604051953391167f3d1e4c3a68fed9f4f8315582b7297cf8fa264bc8e6704287603ba8c72bf05ac2600080a360e05260c05260a0526080526003805460ff60a01b1916600160a01b17905561254990816200018b823960805181818161160801528181611b230152611d2a015260a0518181816104d1015281816108e0015281816109f80152818161122a0152818161134201528181611a6a01528181611dc7015261207d015260c051818181610269015281816107690152611863015260e0518181816110020152818161144701526117f50152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe60806040908082526004918236101561001757600080fd5b600091823560e01c9081630f707f61146120005750806312d43a5114611fb05780631a88bc6614611f515780631e1bff3f14611eb85780632524081014611e665780633f6516a814611d4e5780634046ebae14611ce057806343f59a8214611c495780634f64b2be14611bdd5780635f6494ea14611a8e57806361ef161f14611a20578063625adaf214611887578063741bef1a14611819578063776af5ba146117ab5780637bc6729b146116d45780638afe848f146115795780638e2e3679146113e157806390a54594146112c9578063941bb2ff146111b157806397d9de2214610f895780639ac2a01114610f23578063a440fef914610e83578063a962ef1e14610dd6578063ac9650d814610a97578063bcf7788c1461097f578063be93738614610867578063d4e06a20146106c4578063efdcd97414610640578063f6116bbe146105af578063f65d21d5146104585763fe5e07b51461017a57600080fd5b34610454576020907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82813601126104505784359067ffffffffffffffff80831161044c578383880192843603011261044c573386526002855260ff848720541615610424576101ea8280612499565b90508754926101f882612299565b9361020587519586612258565b8285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061023284612299565b01888a5b82811061040357505050885b838110610348575b5050505073ffffffffffffffffffffffffffffffffffffffff966024887f00000000000000000000000000000000000000000000000000000000000000001694013591821680920361034457833b1561034457948451957f4c6f0df600000000000000000000000000000000000000000000000000000000875285604488019188015283518091528160648801940191885b8281106103235789808a8a82828c8183818f8f602483015203925af190811561031a57506103075750f35b610310906121f9565b6103175780f35b80fd5b513d84823e3d90fd5b835180518c1687528201518b168683015294870194928101926001016102dc565b8680fd5b818110156103fe5761035981612193565b905473ffffffffffffffffffffffffffffffffffffffff61037a8680612499565b8510156103d0578460051b0135918183168093036103cc57906001949392918c51936103a58561223c565b60031b1c1682528b8201526103ba828961236a565b526103c5818861236a565b5001610242565b8d80fd5b505060248c60328f7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b61024a565b895161040e8161223c565b8c81528c8382015282828a010152018990610236565b8684517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b8580fd5b8380fd5b5080fd5b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166104f96124ed565b90803b1561044c57610570948680948651978895869485937fe03d62ae000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b03925af190811561031a57506103075750f35b8390517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b8284346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454573580151580910361063b576105f361244e565b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000006003549260a01b1691161760035580f35b600080fd5b8284346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454573573ffffffffffffffffffffffffffffffffffffffff81168091036104545761069861244e565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600354161760035580f35b50913461045457827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104545767ffffffffffffffff9281358481116104505736602382011215610450578083013594808611610863573660248760061b8401011161086357602435908116809103610863573385526020956002875260ff84872054161561083a5773ffffffffffffffffffffffffffffffffffffffff96877f00000000000000000000000000000000000000000000000000000000000000001697883b15610836579190818651977f4c6f0df60000000000000000000000000000000000000000000000000000000089528760448a01918a01525260246064880195019288915b8383106107fd575050505050849584868181958195602483015203925af190811561031a57506103075750f35b90919293958261080c886122b1565b1681528187013583811680910361083257828201528701958701939260010191906107d0565b8a80fd5b8780fd5b505050517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b8480fd5b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166109086124ed565b90803b1561044c57610570948680948651978895869485937f890143c5000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016610a206124ed565b90803b1561044c57610570948680948651978895869485937f784050e1000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b503461045457602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105ab5783359167ffffffffffffffff94858411610863573660238501121561086357838101359386851161044c576024916005973684888b1b8501011161083657610b1687939798969598612299565b96610b2386519889612258565b8388527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610b5085612299565b01875b818110610dc757505086907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbd81360301915b858110610c0857505050505050508051938080860192818752855180945283818801981b870101940192955b828710610bbe5785850386f35b909192938280610bf8837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a6001960301865288516122d2565b9601920196019592919092610bb1565b86818d9c999a9c1b8301013583811215610dc357820187810135858111610dbf57604491828101908236038213610dbb57908291610c52610c498f95612330565b94519485612258565b8284528c840194833692010111610dbb57818f928d928637830101528a519160609182840184811089821117610d8e578f80938f938f857f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c7f206661696c656400000000000000000000000000000000000000000000000000928697610d139c9b995260278b528a01528801525190305af4903d15610d8757508c3d610d03610cfa82612330565b92519283612258565b815280928d3d92013e5b3061237e565b610d1d828c61236a565b52610d28818b61236a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d5c5760010199979699610b85565b868b6011877f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b9150610d0d565b8b60418b7f4e487b7100000000000000000000000000000000000000000000000000000000600052526000fd5b8e80fd5b8c80fd5b8b80fd5b60608a82018c01528a01610b53565b82346103175760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261031757610e0e612161565b610e1661244e565b73ffffffffffffffffffffffffffffffffffffffff80911690817fffffffffffffffffffffffff000000000000000000000000000000000000000060015416176001558254167fb9911e2099e372c216862258dc462bb65da46a2c854536c8b1acae619d0d62ed8380a380f35b5091819234610f1f5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610f1f5773ffffffffffffffffffffffffffffffffffffffff610ed3612161565b1691823b15610f1a57839283918351809581937fcaa4b46a0000000000000000000000000000000000000000000000000000000083525af190811561031a57506103075750f35b505050fd5b5050fd5b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104545760ff8160209373ffffffffffffffffffffffffffffffffffffffff610f76612161565b1681526002855220541690519015158152f35b503461045457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261045457823592610fc3612184565b93338452600260205260ff8385205416156111895773ffffffffffffffffffffffffffffffffffffffff9485600354168015600014611183575033955b7f00000000000000000000000000000000000000000000000000000000000000001695863b1561044c5784517fe6467b6900000000000000000000000000000000000000000000000000000000815284810184815273ffffffffffffffffffffffffffffffffffffffff90921660208301529086908190839081906040010381838c5af1918261116f575b50506111665761113e57839460ff60035460a01c166110ad575b505050505080f35b6110b56124ed565b91813b1561044c578580946111199651968795869485937f8ec4ad8b000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916040840195845216910152565b03925af161112a575b8080806110a5565b611133906121f9565b610317578038611122565b5090517f2532cf45000000000000000000000000000000000000000000000000000000008152fd5b50505050905080f35b611178906121f9565b61044c57853861108b565b95611000565b5090517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166112526124ed565b90803b1561044c57610570948680948651978895869485937f7b5402c6000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001661136a6124ed565b90803b1561044c57610570948680948651978895869485937f83011cb6000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b503461045457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104545782359261141b612184565b93338452600260205260ff8385205416156111895773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016946114706124ed565b863b1561044c5784517f71b40c9f00000000000000000000000000000000000000000000000000000000815284810184815273ffffffffffffffffffffffffffffffffffffffff90921660208301529086908190839081906040010381838c5af19182611565575b50506111665761113e57839460ff60035460a01c166114f957505050505080f35b6115016124ed565b91813b1561044c578580946111199651968795869485937f7bae8c5a000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916040840195845216910152565b61156e906121f9565b61044c5785386114d8565b508290346105ab5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105ab576115b3612161565b602435906bffffffffffffffffffffffff82168092036108635760443591821515830361063b57338652600260205260ff84872054161561083a57859073ffffffffffffffffffffffffffffffffffffffff807f000000000000000000000000000000000000000000000000000000000000000016916116316124ed565b94833b1561086357848094848b986064958c519a8b9889977f735625e8000000000000000000000000000000000000000000000000000000008952169087015260248601521660448401525af191826116c0575b50506116ba5761169457505080f35b517f2532cf45000000000000000000000000000000000000000000000000000000008152fd5b50505080f35b6116c9906121f9565b610863578486611685565b508290346105ab57827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105ab576001549173ffffffffffffffffffffffffffffffffffffffff9182841633036117855750507fffffffffffffffffffffffff0000000000000000000000000000000000000000809216600155825491339083161783553391167f3d1e4c3a68fed9f4f8315582b7297cf8fa264bc8e6704287603ba8c72bf05ac28380a380f35b517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5082346105ab576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261045057813567ffffffffffffffff9384821161044c573660238301121561044c5781840135916118e8610cfa84612299565b8282528382016024819460051b83010191368311611a1c576024869101915b838310611a04575050505061191a61244e565b519384116119d8576801000000000000000084116119d8578254848455808510611998575b50918452835b838110611950578480f35b825173ffffffffffffffffffffffffffffffffffffffff167f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b82015591810191600101611945565b847f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b91820191015b8181106119cd575061193f565b8681556001016119c0565b6024856041857f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8190611a0f846122b1565b8152019101908590611907565b8880fd5b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b508290346105ab5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105ab57611ac8612161565b6024359073ffffffffffffffffffffffffffffffffffffffff9182811680910361063b576044359260ff84168094036103445760643593841515850361063b57338852600260205260ff868920541615611bb55790879291817f00000000000000000000000000000000000000000000000000000000000000001694611b4c6124ed565b91863b1561044c5789968460849488979388948d519b8c998a987fb9e89222000000000000000000000000000000000000000000000000000000008a521690880152602487015260448601521660648401525af191826116c05750506116ba5761169457505080f35b8686517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b5090346103175760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103175782359254831015610317575073ffffffffffffffffffffffffffffffffffffffff611c3a602093612193565b92905490519260031b1c168152f35b5091819234610f1f5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610f1f5773ffffffffffffffffffffffffffffffffffffffff611c99612161565b1691823b15610f1a57839283918351809581937fd634b8330000000000000000000000000000000000000000000000000000000083525af190811561031a57506103075750f35b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346104545760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610454578235906fffffffffffffffffffffffffffffffff821682036105ab57338352600260205260ff81842054161561058357829373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016611def6124ed565b90803b1561044c57610570948680948651978895869485937f6f707c75000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104545760209073ffffffffffffffffffffffffffffffffffffffff600154169051908152f35b503461045457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261045457611eef612161565b9073ffffffffffffffffffffffffffffffffffffffff611f0d612184565b92611f1661244e565b168352600260205282209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008354169115151617905580f35b50903461031757807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610317575060035460ff82519173ffffffffffffffffffffffffffffffffffffffff8116835260a01c1615156020820152f35b503461045457817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104545773ffffffffffffffffffffffffffffffffffffffff60209254169051908152f35b84929150346104505760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610450578235906fffffffffffffffffffffffffffffffff8216820361086357338552600260205260ff83862054161561213a5750839073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166120a56124ed565b91813b15610450578361211a968651978895869485937f6c525501000000000000000000000000000000000000000000000000000000008552840190929173ffffffffffffffffffffffffffffffffffffffff6020916fffffffffffffffffffffffffffffffff604085019616845216910152565b03925af190811561031a575061212e575080f35b612137906121f9565b80f35b807fee90c46800000000000000000000000000000000000000000000000000000000859252fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361063b57565b60243590811515820361063b57565b6004548110156121ca5760046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff811161220d57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff82111761220d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761220d57604052565b67ffffffffffffffff811161220d5760051b60200190565b359073ffffffffffffffffffffffffffffffffffffffff8216820361063b57565b919082519283825260005b84811061231c5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b6020818301810151848301820152016122dd565b67ffffffffffffffff811161220d57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b80518210156121ca5760209160051b010190565b919290156123f95750815115612392575090565b3b1561239b5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561240c5750805190602001fd5b61244a906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906122d2565b0390fd5b73ffffffffffffffffffffffffffffffffffffffff60005416330361246f57565b60046040517fee90c468000000000000000000000000000000000000000000000000000000008152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561063b570180359067ffffffffffffffff821161063b57602001918160051b3603831361063b57565b60035473ffffffffffffffffffffffffffffffffffffffff168061251057503390565b9056fea264697066735822122084ad4582d9fa1172fd48e8acf3ddf97f05090e1404848f81cc640127f975c4fd64736f6c634300081500330000000000000000000000002d6b52a7dbfd653b23e27f713552790855f4d8c4000000000000000000000000c3b609357539a35673cc50e5ca4fa57da1bfec7b0000000000000000000000005f63167e3a1f03bb2485ea2d1df4ea889ccc2a2e0000000000000000000000000a41c964781312413ac51d1a11efff1d0cff2832

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

0000000000000000000000002d6b52a7dbfd653b23e27f713552790855f4d8c4000000000000000000000000c3b609357539a35673cc50e5ca4fa57da1bfec7b0000000000000000000000005f63167e3a1f03bb2485ea2d1df4ea889ccc2a2e0000000000000000000000000a41c964781312413ac51d1a11efff1d0cff2832

-----Decoded View---------------
Arg [0] : _liquidator (address): 0x2D6B52a7dbFD653B23E27F713552790855f4D8C4
Arg [1] : _router (address): 0xc3B609357539A35673cc50e5Ca4fA57da1BFeC7b
Arg [2] : _priceFeed (address): 0x5F63167E3a1f03bb2485Ea2D1Df4ea889CcC2A2E
Arg [3] : _orderBook (address): 0x0A41c964781312413Ac51d1A11efff1D0cfF2832

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000002d6b52a7dbfd653b23e27f713552790855f4d8c4
Arg [1] : 000000000000000000000000c3b609357539a35673cc50e5ca4fa57da1bfec7b
Arg [2] : 0000000000000000000000005f63167e3a1f03bb2485ea2d1df4ea889ccc2a2e
Arg [3] : 0000000000000000000000000a41c964781312413ac51d1a11efff1d0cff2832


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.