{
  "address": "0xB6a4A36f7E918a084E5bB39475B30b06cB9CEd91",
  "abi": [],
  "transactionHash": "0xb87af63ca8e54b04da5a00e55d6de5290bcc5896595f411f9425e84ede08c06a",
  "receipt": {
    "to": null,
    "from": "0x4f071924D66BBC71A5254217893CC7D49938B1c4",
    "contractAddress": "0xB6a4A36f7E918a084E5bB39475B30b06cB9CEd91",
    "transactionIndex": 0,
    "gasUsed": "22108372",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x6e4ed6a43e06cd16cc6929f163b1ecf5bbcc85479e2981cfc56d526c3d2f0c03",
    "transactionHash": "0xb87af63ca8e54b04da5a00e55d6de5290bcc5896595f411f9425e84ede08c06a",
    "logs": [],
    "blockNumber": 14570788,
    "cumulativeGasUsed": "10197132",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "4053827aa146c622da7f45f0acacb57f",
  "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addUsdcPosition(TraderVaultLib.TraderVault storage,int256)\":{\"params\":{\"_traderVault\":\"trader vault object\",\"_usdcPositionToAdd\":\"amount to add. value is always positive.\"}},\"decreaseLiquidationReward(TraderVaultLib.TraderVault storage,int256,int256)\":{\"params\":{\"_liquidationFee\":\"liquidation fee rate\",\"_minCollateral\":\"min collateral\",\"_traderVault\":\"trader vault object\"}},\"updateUsdcPosition(TraderVaultLib.TraderVault storage,int256,IPerpetualMarketCore.TradePriceInfo)\":{\"params\":{\"_tradePriceInfo\":\"trade price info\",\"_traderVault\":\"trader vault object\",\"_usdcPositionToAdd\":\"amount to add. if positive then increase amount, if negative then decrease amount.\"},\"returns\":{\"finalUsdcPosition\":\"positive means amount of deposited margin and negative means amount of withdrawn margin.\"}},\"updateVault(TraderVaultLib.TraderVault storage,uint256,uint256,int128,uint256,int256)\":{\"params\":{\"_fundingFeePerPosition\":\"entry funding fee paid per position\",\"_positionPerpetual\":\"amount of position to increase or decrease\",\"_productId\":\"product id\",\"_subVaultIndex\":\"index of sub-vault\",\"_tradePrice\":\"trade price\",\"_traderVault\":\"trader vault object\"}}},\"stateVariables\":{\"MIN_MARGIN\":{\"details\":\"minimum margin is 200 USDC\"},\"RISK_PARAM_FOR_VAULT\":{\"details\":\"risk parameter for MinCollateral calculation is 5.0%\"}},\"title\":\"TraderVaultLib\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addUsdcPosition(TraderVaultLib.TraderVault storage,int256)\":{\"notice\":\"Add USDC position\"},\"decreaseLiquidationReward(TraderVaultLib.TraderVault storage,int256,int256)\":{\"notice\":\"Decreases liquidation reward from usdc position\"},\"updateUsdcPosition(TraderVaultLib.TraderVault storage,int256,IPerpetualMarketCore.TradePriceInfo)\":{\"notice\":\"Updates USDC position\"},\"updateVault(TraderVaultLib.TraderVault storage,uint256,uint256,int128,uint256,int256)\":{\"notice\":\"Updates positions in the vault\"}},\"notice\":\"TraderVaultLib has functions to calculate position value and minimum collateral for implementing cross margin wallet. Data Structure  Vault  - PositionUSDC  - SubVault0(PositionPerpetuals, EntryPrices, entryFundingFee)  - SubVault1(PositionPerpetuals, EntryPrices, entryFundingFee)  - ...  PositionPerpetuals = [PositionSqueeth, PositionFuture]  EntryPrices = [EntryPriceSqueeth, EntryPriceFuture]  entryFundingFee = [entryFundingFeeqeeth, FundingFeeEntryValueFuture] Error codes  T0: PositionValue must be greater than MinCollateral  T1: PositionValue must be less than MinCollateral  T2: Vault is insolvent  T3: subVaultIndex is too large  T4: position must not be 0  T5: usdc to add must be positive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/lib/TraderVaultLib.sol\":\"TraderVaultLib\"},\"evmVersion\":\"istanbul\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x0000000000000031363535313831393733373438\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n    /**\\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n        uint256 c = a + b;\\n        if (c < a) return (false, 0);\\n        return (true, c);\\n    }\\n\\n    /**\\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n        if (b > a) return (false, 0);\\n        return (true, a - b);\\n    }\\n\\n    /**\\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n        // benefit is lost if 'b' is also tested.\\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n        if (a == 0) return (true, 0);\\n        uint256 c = a * b;\\n        if (c / a != b) return (false, 0);\\n        return (true, c);\\n    }\\n\\n    /**\\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n        if (b == 0) return (false, 0);\\n        return (true, a / b);\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n        if (b == 0) return (false, 0);\\n        return (true, a % b);\\n    }\\n\\n    /**\\n     * @dev Returns the addition of two unsigned integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `+` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Addition cannot overflow.\\n     */\\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n        uint256 c = a + b;\\n        require(c >= a, \\\"SafeMath: addition overflow\\\");\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two unsigned integers, reverting on\\n     * overflow (when the result is negative).\\n     *\\n     * Counterpart to Solidity's `-` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Subtraction cannot overflow.\\n     */\\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n        require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n        return a - b;\\n    }\\n\\n    /**\\n     * @dev Returns the multiplication of two unsigned integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `*` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Multiplication cannot overflow.\\n     */\\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n        if (a == 0) return 0;\\n        uint256 c = a * b;\\n        require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the integer division of two unsigned integers, reverting on\\n     * division by zero. The result is rounded towards zero.\\n     *\\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n     * uses an invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n        require(b > 0, \\\"SafeMath: division by zero\\\");\\n        return a / b;\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n     * reverting when dividing by zero.\\n     *\\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\\n     * invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n        require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n        return a % b;\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n     * overflow (when the result is negative).\\n     *\\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\\n     * message unnecessarily. For custom revert reasons use {trySub}.\\n     *\\n     * Counterpart to Solidity's `-` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Subtraction cannot overflow.\\n     */\\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b <= a, errorMessage);\\n        return a - b;\\n    }\\n\\n    /**\\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n     * division by zero. The result is rounded towards zero.\\n     *\\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\\n     * message unnecessarily. For custom revert reasons use {tryDiv}.\\n     *\\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n     * uses an invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b > 0, errorMessage);\\n        return a / b;\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n     * reverting with custom message when dividing by zero.\\n     *\\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\\n     * message unnecessarily. For custom revert reasons use {tryMod}.\\n     *\\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\\n     * invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b > 0, errorMessage);\\n        return a % b;\\n    }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SignedSafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title SignedSafeMath\\n * @dev Signed math operations with safety checks that revert on error.\\n */\\nlibrary SignedSafeMath {\\n    int256 constant private _INT256_MIN = -2**255;\\n\\n    /**\\n     * @dev Returns the multiplication of two signed integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `*` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Multiplication cannot overflow.\\n     */\\n    function mul(int256 a, int256 b) internal pure returns (int256) {\\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n        // benefit is lost if 'b' is also tested.\\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        require(!(a == -1 && b == _INT256_MIN), \\\"SignedSafeMath: multiplication overflow\\\");\\n\\n        int256 c = a * b;\\n        require(c / a == b, \\\"SignedSafeMath: multiplication overflow\\\");\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the integer division of two signed integers. Reverts on\\n     * division by zero. The result is rounded towards zero.\\n     *\\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n     * uses an invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function div(int256 a, int256 b) internal pure returns (int256) {\\n        require(b != 0, \\\"SignedSafeMath: division by zero\\\");\\n        require(!(b == -1 && a == _INT256_MIN), \\\"SignedSafeMath: division overflow\\\");\\n\\n        int256 c = a / b;\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two signed integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `-` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Subtraction cannot overflow.\\n     */\\n    function sub(int256 a, int256 b) internal pure returns (int256) {\\n        int256 c = a - b;\\n        require((b >= 0 && c <= a) || (b < 0 && c > a), \\\"SignedSafeMath: subtraction overflow\\\");\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the addition of two signed integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `+` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Addition cannot overflow.\\n     */\\n    function add(int256 a, int256 b) internal pure returns (int256) {\\n        int256 c = a + b;\\n        require((b >= 0 && c >= a) || (b < 0 && c < a), \\\"SignedSafeMath: addition overflow\\\");\\n\\n        return c;\\n    }\\n}\\n\",\"keccak256\":\"0xba085261d44cf28d2583f7c8cdb2f0a6a495ff1a640f86d995ea9d36b42b0046\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n\\n    /**\\n     * @dev Returns the downcasted uint128 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint128).\\n     *\\n     * Counterpart to Solidity's `uint128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     */\\n    function toUint128(uint256 value) internal pure returns (uint128) {\\n        require(value < 2**128, \\\"SafeCast: value doesn\\\\'t fit in 128 bits\\\");\\n        return uint128(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint64 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint64).\\n     *\\n     * Counterpart to Solidity's `uint64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     */\\n    function toUint64(uint256 value) internal pure returns (uint64) {\\n        require(value < 2**64, \\\"SafeCast: value doesn\\\\'t fit in 64 bits\\\");\\n        return uint64(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint32 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint32).\\n     *\\n     * Counterpart to Solidity's `uint32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     */\\n    function toUint32(uint256 value) internal pure returns (uint32) {\\n        require(value < 2**32, \\\"SafeCast: value doesn\\\\'t fit in 32 bits\\\");\\n        return uint32(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint16 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint16).\\n     *\\n     * Counterpart to Solidity's `uint16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     */\\n    function toUint16(uint256 value) internal pure returns (uint16) {\\n        require(value < 2**16, \\\"SafeCast: value doesn\\\\'t fit in 16 bits\\\");\\n        return uint16(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint8 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint8).\\n     *\\n     * Counterpart to Solidity's `uint8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits.\\n     */\\n    function toUint8(uint256 value) internal pure returns (uint8) {\\n        require(value < 2**8, \\\"SafeCast: value doesn\\\\'t fit in 8 bits\\\");\\n        return uint8(value);\\n    }\\n\\n    /**\\n     * @dev Converts a signed int256 into an unsigned uint256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be greater than or equal to 0.\\n     */\\n    function toUint256(int256 value) internal pure returns (uint256) {\\n        require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n        return uint256(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int128 from int256, reverting on\\n     * overflow (when the input is less than smallest int128 or\\n     * greater than largest int128).\\n     *\\n     * Counterpart to Solidity's `int128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt128(int256 value) internal pure returns (int128) {\\n        require(value >= -2**127 && value < 2**127, \\\"SafeCast: value doesn\\\\'t fit in 128 bits\\\");\\n        return int128(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int64 from int256, reverting on\\n     * overflow (when the input is less than smallest int64 or\\n     * greater than largest int64).\\n     *\\n     * Counterpart to Solidity's `int64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt64(int256 value) internal pure returns (int64) {\\n        require(value >= -2**63 && value < 2**63, \\\"SafeCast: value doesn\\\\'t fit in 64 bits\\\");\\n        return int64(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int32 from int256, reverting on\\n     * overflow (when the input is less than smallest int32 or\\n     * greater than largest int32).\\n     *\\n     * Counterpart to Solidity's `int32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt32(int256 value) internal pure returns (int32) {\\n        require(value >= -2**31 && value < 2**31, \\\"SafeCast: value doesn\\\\'t fit in 32 bits\\\");\\n        return int32(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int16 from int256, reverting on\\n     * overflow (when the input is less than smallest int16 or\\n     * greater than largest int16).\\n     *\\n     * Counterpart to Solidity's `int16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt16(int256 value) internal pure returns (int16) {\\n        require(value >= -2**15 && value < 2**15, \\\"SafeCast: value doesn\\\\'t fit in 16 bits\\\");\\n        return int16(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int8 from int256, reverting on\\n     * overflow (when the input is less than smallest int8 or\\n     * greater than largest int8).\\n     *\\n     * Counterpart to Solidity's `int8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt8(int256 value) internal pure returns (int8) {\\n        require(value >= -2**7 && value < 2**7, \\\"SafeCast: value doesn\\\\'t fit in 8 bits\\\");\\n        return int8(value);\\n    }\\n\\n    /**\\n     * @dev Converts an unsigned uint256 into a signed int256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be less than or equal to maxInt256.\\n     */\\n    function toInt256(uint256 value) internal pure returns (int256) {\\n        require(value < 2**255, \\\"SafeCast: value doesn't fit in an int256\\\");\\n        return int256(value);\\n    }\\n}\\n\",\"keccak256\":\"0x79004a1d1471abe87e92c4497acba06d5dfa5b1f3e9894a0991a7c4669c5c02c\",\"license\":\"MIT\"},\"src/interfaces/IPerpetualMarketCore.sol\":{\"content\":\"// SPDX-License-Identifier: agpl-3.0\\npragma solidity =0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../lib/NettingLib.sol\\\";\\n\\ninterface IPerpetualMarketCore {\\n    struct TradePriceInfo {\\n        uint128 spotPrice;\\n        int256[2] tradePrices;\\n        int256[2] fundingRates;\\n        int256[2] amountsFundingPaidPerPosition;\\n    }\\n\\n    function initialize(\\n        address _depositor,\\n        uint256 _depositAmount,\\n        int256 _initialFundingRate\\n    ) external returns (uint256 mintAmount);\\n\\n    function deposit(address _depositor, uint256 _depositAmount) external returns (uint256 mintAmount);\\n\\n    function withdraw(address _withdrawer, uint256 _withdrawnAmount) external returns (uint256 burnAmount);\\n\\n    function addLiquidity(uint256 _amount) external;\\n\\n    function updatePoolPositions(int256[2] memory _tradeAmounts)\\n        external\\n        returns (\\n            uint256[2] memory tradePrice,\\n            int256[2] memory,\\n            uint256 protocolFee\\n        );\\n\\n    function completeHedgingProcedure(NettingLib.CompleteParams memory _completeParams) external;\\n\\n    function updatePoolSnapshot() external;\\n\\n    function executeFundingPayment() external;\\n\\n    function getTradePriceInfo(int256[2] memory _tradeAmounts) external view returns (TradePriceInfo memory);\\n\\n    function getTradePrice(uint256 _productId, int256[2] memory _tradeAmounts)\\n        external\\n        view\\n        returns (\\n            int256,\\n            int256,\\n            int256,\\n            int256,\\n            int256\\n        );\\n\\n    function rebalance() external;\\n\\n    function getTokenAmountForHedging() external view returns (NettingLib.CompleteParams memory completeParams);\\n\\n    function getLPTokenPrice(int256 _deltaLiquidityAmount) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x2544ccffc110ad49bbc7ab45491d032c5063ba68130eafa237c392c149eaf3a3\",\"license\":\"agpl-3.0\"},\"src/lib/EntryPriceMath.sol\":{\"content\":\"//SPDX-License-Identifier: agpl-3.0\\npragma solidity =0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/utils/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SignedSafeMath.sol\\\";\\nimport \\\"./Math.sol\\\";\\n\\n/**\\n * @title EntryPriceMath\\n * @notice Library contract which has functions to calculate new entry price and profit\\n * from previous entry price and trade price for implementing margin wallet.\\n */\\nlibrary EntryPriceMath {\\n    using SafeCast for uint256;\\n    using SafeMath for uint256;\\n    using SignedSafeMath for int256;\\n\\n    /**\\n     * @notice Calculates new entry price and return profit if position is closed\\n     *\\n     * Calculation Patterns\\n     *  |Position|PositionTrade|NewPosition|Pattern|\\n     *  |       +|            +|          +|      A|\\n     *  |       +|            -|          +|      B|\\n     *  |       +|            -|          -|      C|\\n     *  |       -|            -|          -|      A|\\n     *  |       -|            +|          -|      B|\\n     *  |       -|            +|          +|      C|\\n     *\\n     * Calculations\\n     *  Pattern A (open positions)\\n     *   NewEntryPrice = (EntryPrice * |Position| + TradePrce * |PositionTrade|) / (Position + PositionTrade)\\n     *\\n     *  Pattern B (close positions)\\n     *   NewEntryPrice = EntryPrice\\n     *   ProfitValue = -PositionTrade * (TradePrice - EntryPrice)\\n     *\\n     *  Pattern C (close all positions & open new)\\n     *   NewEntryPrice = TradePrice\\n     *   ProfitValue = Position * (TradePrice - EntryPrice)\\n     *\\n     * @param _entryPrice previous entry price\\n     * @param _position current position\\n     * @param _tradePrice trade price\\n     * @param _positionTrade position to trade\\n     * @return newEntryPrice new entry price\\n     * @return profitValue notional profit value when positions are closed\\n     */\\n    function updateEntryPrice(\\n        int256 _entryPrice,\\n        int256 _position,\\n        int256 _tradePrice,\\n        int256 _positionTrade\\n    ) internal pure returns (int256 newEntryPrice, int256 profitValue) {\\n        int256 newPosition = _position.add(_positionTrade);\\n        if (_position == 0 || (_position > 0 && _positionTrade > 0) || (_position < 0 && _positionTrade < 0)) {\\n            newEntryPrice = (\\n                _entryPrice.mul(int256(Math.abs(_position))).add(_tradePrice.mul(int256(Math.abs(_positionTrade))))\\n            ).div(int256(Math.abs(_position.add(_positionTrade))));\\n        } else if (\\n            (_position > 0 && _positionTrade < 0 && newPosition > 0) ||\\n            (_position < 0 && _positionTrade > 0 && newPosition < 0)\\n        ) {\\n            newEntryPrice = _entryPrice;\\n            profitValue = (-_positionTrade).mul(_tradePrice.sub(_entryPrice)) / 1e8;\\n        } else {\\n            if (newPosition != 0) {\\n                newEntryPrice = _tradePrice;\\n            }\\n\\n            profitValue = _position.mul(_tradePrice.sub(_entryPrice)) / 1e8;\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x76b69923c0d21ff5a04335743b0b4f64ff36a90df6154f030914231abf47c858\",\"license\":\"agpl-3.0\"},\"src/lib/Math.sol\":{\"content\":\"//SPDX-License-Identifier: agpl-3.0\\npragma solidity =0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/math/SignedSafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\n\\n/**\\n * Error codes\\n * M0: y is too small\\n * M1: y is too large\\n * M2: possible overflow\\n * M3: input should be positive number\\n * M4: cannot handle exponents greater than 100\\n */\\nlibrary Math {\\n    using SafeMath for uint256;\\n    using SignedSafeMath for int256;\\n\\n    /// @dev Min exp\\n    int256 private constant MIN_EXP = -63 * 1e8;\\n    /// @dev Max exp\\n    uint256 private constant MAX_EXP = 100 * 1e8;\\n    /// @dev ln(2) scaled by 1e8\\n    uint256 private constant LN_2_E8 = 69314718;\\n\\n    /**\\n     * @notice Return the addition of unsigned integer and sigined integer.\\n     * when y is negative reverting on negative result and when y is positive reverting on overflow.\\n     */\\n    function addDelta(uint256 x, int256 y) internal pure returns (uint256 z) {\\n        if (y < 0) {\\n            require((z = x - uint256(-y)) < x, \\\"M0\\\");\\n        } else {\\n            require((z = x + uint256(y)) >= x, \\\"M1\\\");\\n        }\\n    }\\n\\n    function abs(int256 x) internal pure returns (uint256) {\\n        return uint256(x >= 0 ? x : -x);\\n    }\\n\\n    function min(int256 a, int256 b) internal pure returns (int256) {\\n        return a > b ? b : a;\\n    }\\n\\n    function mulDiv(\\n        int256 _x,\\n        int256 _y,\\n        int256 _d,\\n        bool _roundUp\\n    ) internal pure returns (int256) {\\n        int256 tailing;\\n        if (_roundUp) {\\n            int256 remainer = (_x * _y) % _d;\\n            if (remainer > 0) {\\n                tailing = 1;\\n            } else if (remainer < 0) {\\n                tailing = -1;\\n            }\\n        }\\n\\n        int256 result = (_x * _y) / _d + tailing;\\n\\n        return result;\\n    }\\n\\n    /**\\n     * @notice Returns scaled number.\\n     * Reverts if the scaler is greater than 50.\\n     */\\n    function scale(\\n        uint256 _a,\\n        uint256 _from,\\n        uint256 _to\\n    ) internal pure returns (uint256) {\\n        if (_from > _to) {\\n            require(_from - _to < 70, \\\"M2\\\");\\n            // (_from - _to) is safe because _from > _to.\\n            // 10**(_from - _to) is safe because it's less than 10**70.\\n            return _a.div(10**(_from - _to));\\n        } else if (_from < _to) {\\n            require(_to - _from < 70, \\\"M2\\\");\\n            // (_to - _from) is safe because _to > _from.\\n            // 10**(_to - _from) is safe because it's less than 10**70.\\n            return _a.mul(10**(_to - _from));\\n        } else {\\n            return _a;\\n        }\\n    }\\n\\n    /**\\n     * @dev Calculates an approximate value of the logarithm of input value by Halley's method.\\n     */\\n    function log(uint256 x) internal pure returns (int256) {\\n        int256 res;\\n        int256 next;\\n\\n        for (uint256 i = 0; i < 8; i++) {\\n            int256 e = int256(exp(res));\\n            next = res.add((int256(x).sub(e).mul(2)).mul(1e8).div(int256(x).add(e)));\\n            if (next == res) {\\n                break;\\n            }\\n            res = next;\\n        }\\n\\n        return res;\\n    }\\n\\n    /**\\n     * @dev Returns the exponent of the value using Taylor expansion with support for negative numbers.\\n     */\\n    function exp(int256 x) internal pure returns (uint256) {\\n        if (0 <= x) {\\n            return exp(uint256(x));\\n        } else if (x < MIN_EXP) {\\n            // return 0 because `exp(-63) < 1e-27`\\n            return 0;\\n        } else {\\n            return uint256(1e8).mul(1e8).div(exp(uint256(-x)));\\n        }\\n    }\\n\\n    /**\\n     * @dev Calculates the exponent of the value using Taylor expansion.\\n     */\\n    function exp(uint256 x) internal pure returns (uint256) {\\n        if (x == 0) {\\n            return 1e8;\\n        }\\n        require(x <= MAX_EXP, \\\"M4\\\");\\n\\n        uint256 k = floor(x.mul(1e8).div(LN_2_E8)) / 1e8;\\n        uint256 p = 2**k;\\n        uint256 r = x.sub(k.mul(LN_2_E8));\\n\\n        uint256 multiplier = 1e8;\\n\\n        uint256 lastMultiplier;\\n        for (uint256 i = 16; i > 0; i--) {\\n            multiplier = multiplier.mul(r / i).div(1e8).add(1e8);\\n            if (multiplier == lastMultiplier) {\\n                break;\\n            }\\n            lastMultiplier = multiplier;\\n        }\\n\\n        return p.mul(multiplier);\\n    }\\n\\n    /**\\n     * @dev Returns the floor of a 1e8\\n     */\\n    function floor(uint256 x) internal pure returns (uint256) {\\n        return x - (x % 1e8);\\n    }\\n}\\n\",\"keccak256\":\"0xf737bf7a070dc7bb0b6f3179c81d70938421a3cc39ddec72a4ba9fc97b60ab7a\",\"license\":\"agpl-3.0\"},\"src/lib/NettingLib.sol\":{\"content\":\"//SPDX-License-Identifier: agpl-3.0\\npragma solidity =0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/utils/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SignedSafeMath.sol\\\";\\nimport \\\"./Math.sol\\\";\\n\\n/**\\n * @title NettingLib\\n *\\n * HedgePositionValue = ETH * S + AmountUSDC\\n *\\n * Normally, Amount Locked is equal to HedgePositionValue.\\n * AMM adjusts the HedgePositionValue to be equal to the RequiredMargin\\n * by adding or decreasing AmountUSDC.\\n *\\n *  --------------------------------------------------\\n * |              Total Liquidity Amount              |\\n * |     Amount Locked       |\\n * |    ETH     | AmountUSDC |\\n *  --------------------------------------------------\\n *\\n * If RequiredMargin becomes smaller than ETH value that AMM has, AmountUSDC becomes negative.\\n *\\n *  --------------------------------------------------\\n * |              Total Liquidity Amount              |\\n * |      Amount Locked(10)       |\\n * |            ETH(15)                          |\\n *                                |AmountUSDC(-5)|\\n *  --------------------------------------------------\\n *\\n * After hedge completed, AmountUSDC becomes positive.\\n *\\n *  --------------------------------------------------\\n * |              Total Liquidity Amount              |\\n * |      Amount Locked(10)       |\\n * |      ETH(6)    |\\n *                  |AmountUSDC(4)|\\n *  --------------------------------------------------\\n *\\n * Error codes\\n * N0: Unknown product id\\n * N1: Total delta must be greater than 0\\n * N2: No enough USDC\\n */\\nlibrary NettingLib {\\n    using SafeCast for int256;\\n    using SafeCast for uint128;\\n    using SafeCast for uint256;\\n    using SafeMath for uint256;\\n    using SafeMath for uint128;\\n    using SafeMath for int256;\\n    using SignedSafeMath for int256;\\n    using SignedSafeMath for int128;\\n\\n    struct AddMarginParams {\\n        int256 delta0;\\n        int256 delta1;\\n        int256 gamma1;\\n        int256 spotPrice;\\n        int256 poolMarginRiskParam;\\n    }\\n\\n    struct CompleteParams {\\n        uint256 amountUsdc;\\n        uint256 amountUnderlying;\\n        uint256 futureWeight;\\n        bool isLong;\\n    }\\n\\n    struct Info {\\n        int256[2] amountsUsdc;\\n        uint256 amountUnderlying;\\n    }\\n\\n    /**\\n     * @notice Adds required margin for delta hedging\\n     */\\n    function addMargin(\\n        Info storage _info,\\n        uint256 _productId,\\n        AddMarginParams memory _params\\n    ) internal returns (int256 requiredMargin, int256 hedgePositionValue) {\\n        int256 totalRequiredMargin = getRequiredMargin(_productId, _params);\\n\\n        hedgePositionValue = getHedgePositionValue(_info, _params, _productId);\\n\\n        requiredMargin = totalRequiredMargin.sub(hedgePositionValue);\\n\\n        _info.amountsUsdc[_productId] = _info.amountsUsdc[_productId].add(requiredMargin);\\n    }\\n\\n    function getRequiredTokenAmountsForHedge(\\n        uint256 _amountUnderlying,\\n        int256[2] memory _deltas,\\n        int256 _spotPrice\\n    ) internal pure returns (CompleteParams memory completeParams) {\\n        int256 totalUnderlyingPosition = _amountUnderlying.toInt256();\\n\\n        // 1. Calculate required amount of underlying token\\n        int256 requiredUnderlyingAmount;\\n        {\\n            // required amount is -(net delta)\\n            requiredUnderlyingAmount = -_deltas[0].add(_deltas[1]).add(totalUnderlyingPosition);\\n\\n            if (_deltas[0].add(_deltas[1]) > 0) {\\n                // if pool delta is positive\\n                requiredUnderlyingAmount = -totalUnderlyingPosition;\\n            }\\n\\n            completeParams.isLong = requiredUnderlyingAmount > 0;\\n        }\\n\\n        // 2. Calculate USDC and ETH amounts.\\n        completeParams.amountUnderlying = Math.abs(requiredUnderlyingAmount);\\n        completeParams.amountUsdc = (Math.abs(requiredUnderlyingAmount).mul(uint256(_spotPrice))) / 1e8;\\n\\n        completeParams.futureWeight = calculateWeight(0, _deltas[0], _deltas[1]);\\n\\n        return completeParams;\\n    }\\n\\n    /**\\n     * @notice Completes delta hedging procedure\\n     * Calculate holding amount of Underlying and USDC after a hedge.\\n     */\\n    function complete(Info storage _info, CompleteParams memory _params) internal {\\n        uint256 amountRequired0 = _params.amountUsdc.mul(_params.futureWeight).div(1e16);\\n        uint256 amountRequired1 = _params.amountUsdc.sub(amountRequired0);\\n\\n        require(_params.amountUnderlying > 0, \\\"N1\\\");\\n\\n        if (_params.isLong) {\\n            _info.amountUnderlying = _info.amountUnderlying.add(_params.amountUnderlying);\\n\\n            _info.amountsUsdc[0] = _info.amountsUsdc[0].sub(amountRequired0.toInt256());\\n            _info.amountsUsdc[1] = _info.amountsUsdc[1].sub(amountRequired1.toInt256());\\n        } else {\\n            _info.amountUnderlying = _info.amountUnderlying.sub(_params.amountUnderlying);\\n\\n            _info.amountsUsdc[0] = _info.amountsUsdc[0].add(amountRequired0.toInt256());\\n            _info.amountsUsdc[1] = _info.amountsUsdc[1].add(amountRequired1.toInt256());\\n        }\\n    }\\n\\n    /**\\n     * @notice Gets required margin\\n     * @param _productId Id of product to get required margin\\n     * @param _params parameters to calculate required margin\\n     * @return RequiredMargin scaled by 1e8\\n     */\\n    function getRequiredMargin(uint256 _productId, AddMarginParams memory _params) internal pure returns (int256) {\\n        int256 weightedDelta = calculateWeightedDelta(_productId, _params.delta0, _params.delta1);\\n        int256 deltaFromGamma = 0;\\n\\n        if (_productId == 1) {\\n            deltaFromGamma = _params.poolMarginRiskParam.mul(_params.spotPrice).mul(_params.gamma1).div(1e12);\\n        }\\n\\n        int256 requiredMargin = (\\n            _params.spotPrice.mul(Math.abs(weightedDelta).add(Math.abs(deltaFromGamma)).toInt256())\\n        ).div(1e8);\\n\\n        return ((1e4 + _params.poolMarginRiskParam).mul(requiredMargin)).div(1e4);\\n    }\\n\\n    /**\\n     * @notice Gets notional value of hedge positions\\n     * HedgePositionValue_i = AmountsUsdc_i+(|delta_i| / (\\u03a3|delta_i|))*AmountUnderlying*S\\n     * @return HedgePositionValue scaled by 1e8\\n     */\\n    function getHedgePositionValue(\\n        Info memory _info,\\n        AddMarginParams memory _params,\\n        uint256 _productId\\n    ) internal pure returns (int256) {\\n        int256 totalHedgeNotional = _params.spotPrice.mul(_info.amountUnderlying.toInt256()).div(1e8);\\n\\n        int256 productHedgeNotional = totalHedgeNotional\\n            .mul(calculateWeight(0, _params.delta0, _params.delta1).toInt256())\\n            .div(1e16);\\n\\n        if (_productId == 1) {\\n            productHedgeNotional = totalHedgeNotional.sub(productHedgeNotional);\\n        }\\n\\n        int256 hedgePositionValue = _info.amountsUsdc[_productId].add(productHedgeNotional);\\n\\n        return hedgePositionValue;\\n    }\\n\\n    /**\\n     * @notice Gets notional value of hedge positions\\n     * HedgePositionValue_i = AmountsUsdc_0+AmountsUsdc_1+AmountUnderlying*S\\n     * @return HedgePositionValue scaled by 1e8\\n     */\\n    function getTotalHedgePositionValue(Info memory _info, int256 _spotPrice) internal pure returns (int256) {\\n        int256 hedgeNotional = _spotPrice.mul(_info.amountUnderlying.toInt256()).div(1e8);\\n\\n        return (_info.amountsUsdc[0].add(_info.amountsUsdc[1])).add(hedgeNotional);\\n    }\\n\\n    /**\\n     * @notice Calculates weighted delta\\n     * WeightedDelta = |delta_i| * (\\u03a3delta_i) / (\\u03a3|delta_i|)\\n     * @return weighted delta scaled by 1e8\\n     */\\n    function calculateWeightedDelta(\\n        uint256 _productId,\\n        int256 _delta0,\\n        int256 _delta1\\n    ) internal pure returns (int256) {\\n        int256 netDelta = _delta0.add(_delta1);\\n\\n        return netDelta.mul(calculateWeight(_productId, _delta0, _delta1).toInt256()).div(1e16);\\n    }\\n\\n    /**\\n     * @notice Calculates delta weighted value\\n     * WeightedDelta = |delta_i| / (\\u03a3|delta_i|)\\n     * @return weighted delta scaled by 1e16\\n     */\\n    function calculateWeight(\\n        uint256 _productId,\\n        int256 _delta0,\\n        int256 _delta1\\n    ) internal pure returns (uint256) {\\n        uint256 totalDelta = (Math.abs(_delta0).add(Math.abs(_delta1)));\\n\\n        require(totalDelta >= 0, \\\"N1\\\");\\n\\n        if (totalDelta == 0) {\\n            return 0;\\n        }\\n\\n        if (_productId == 0) {\\n            return (Math.abs(_delta0).mul(1e16)).div(totalDelta);\\n        } else if (_productId == 1) {\\n            return (Math.abs(_delta1).mul(1e16)).div(totalDelta);\\n        } else {\\n            revert(\\\"N0\\\");\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x70cdf7f78fd57b080557956bb3c7bcf7da407c8c35528d488e1714047d42cc53\",\"license\":\"agpl-3.0\"},\"src/lib/TraderVaultLib.sol\":{\"content\":\"//SPDX-License-Identifier: agpl-3.0\\npragma solidity =0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/utils/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SignedSafeMath.sol\\\";\\nimport \\\"../interfaces/IPerpetualMarketCore.sol\\\";\\nimport \\\"./Math.sol\\\";\\nimport \\\"./EntryPriceMath.sol\\\";\\n\\n/**\\n * @title TraderVaultLib\\n * @notice TraderVaultLib has functions to calculate position value and minimum collateral for implementing cross margin wallet.\\n *\\n * Data Structure\\n *  Vault\\n *  - PositionUSDC\\n *  - SubVault0(PositionPerpetuals, EntryPrices, entryFundingFee)\\n *  - SubVault1(PositionPerpetuals, EntryPrices, entryFundingFee)\\n *  - ...\\n *\\n *  PositionPerpetuals = [PositionSqueeth, PositionFuture]\\n *  EntryPrices = [EntryPriceSqueeth, EntryPriceFuture]\\n *  entryFundingFee = [entryFundingFeeqeeth, FundingFeeEntryValueFuture]\\n *\\n *\\n * Error codes\\n *  T0: PositionValue must be greater than MinCollateral\\n *  T1: PositionValue must be less than MinCollateral\\n *  T2: Vault is insolvent\\n *  T3: subVaultIndex is too large\\n *  T4: position must not be 0\\n *  T5: usdc to add must be positive\\n */\\nlibrary TraderVaultLib {\\n    using SafeCast for int256;\\n    using SafeCast for uint256;\\n    using SafeCast for uint128;\\n    using SafeMath for uint256;\\n    using SignedSafeMath for int256;\\n    using SignedSafeMath for int128;\\n\\n    uint256 private constant MAX_PRODUCT_ID = 2;\\n\\n    /// @dev minimum margin is 200 USDC\\n    uint256 private constant MIN_MARGIN = 200 * 1e8;\\n\\n    /// @dev risk parameter for MinCollateral calculation is 5.0%\\n    uint256 private constant RISK_PARAM_FOR_VAULT = 500;\\n\\n    struct SubVault {\\n        int128[2] positionPerpetuals;\\n        uint128[2] entryPrices;\\n        int256[2] entryFundingFee;\\n    }\\n\\n    struct TraderVault {\\n        int128 positionUsdc;\\n        SubVault[] subVaults;\\n    }\\n\\n    /**\\n     * @notice Gets amount of min collateral to add Squees/Future\\n     * @param _traderVault trader vault object\\n     * @param _tradeAmounts amount to trade\\n     * @param _tradePriceInfo trade price info\\n     * @return minCollateral and positionValue\\n     */\\n    function getMinCollateralToAddPosition(\\n        TraderVault memory _traderVault,\\n        int128[2] memory _tradeAmounts,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256 minCollateral) {\\n        int128[2] memory positionPerpetuals = getPositionPerpetuals(_traderVault);\\n\\n        for (uint256 i = 0; i < MAX_PRODUCT_ID; i++) {\\n            positionPerpetuals[i] = positionPerpetuals[i].add(_tradeAmounts[i]).toInt128();\\n        }\\n\\n        minCollateral = calculateMinCollateral(positionPerpetuals, _tradePriceInfo);\\n    }\\n\\n    /**\\n     * @notice Updates USDC position\\n     * @param _traderVault trader vault object\\n     * @param _usdcPositionToAdd amount to add. if positive then increase amount, if negative then decrease amount.\\n     * @param _tradePriceInfo trade price info\\n     * @return finalUsdcPosition positive means amount of deposited margin\\n     * and negative means amount of withdrawn margin.\\n     */\\n    function updateUsdcPosition(\\n        TraderVault storage _traderVault,\\n        int256 _usdcPositionToAdd,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) external returns (int256 finalUsdcPosition) {\\n        finalUsdcPosition = _usdcPositionToAdd;\\n\\n        int256 positionValue = getPositionValue(_traderVault, _tradePriceInfo);\\n        int256 minCollateral = getMinCollateral(_traderVault, _tradePriceInfo);\\n        int256 maxWithdrawable = positionValue - minCollateral;\\n\\n        // If trader wants to withdraw all USDC, set maxWithdrawable.\\n        if (_usdcPositionToAdd < -maxWithdrawable && maxWithdrawable > 0 && _usdcPositionToAdd < 0) {\\n            finalUsdcPosition = -maxWithdrawable;\\n        }\\n\\n        _traderVault.positionUsdc = _traderVault.positionUsdc.add(finalUsdcPosition).toInt128();\\n\\n        require(!checkVaultIsDanger(_traderVault, _tradePriceInfo), \\\"T0\\\");\\n    }\\n\\n    /**\\n     * @notice Add USDC position\\n     * @param _traderVault trader vault object\\n     * @param _usdcPositionToAdd amount to add. value is always positive.\\n     */\\n    function addUsdcPosition(TraderVault storage _traderVault, int256 _usdcPositionToAdd) external {\\n        require(_usdcPositionToAdd > 0, \\\"T5\\\");\\n\\n        _traderVault.positionUsdc = _traderVault.positionUsdc.add(_usdcPositionToAdd).toInt128();\\n    }\\n\\n    /**\\n     * @notice Gets total position of perpetuals in the vault\\n     * @param _traderVault trader vault object\\n     * @return positionPerpetuals are total amount of perpetual scaled by 1e8\\n     */\\n    function getPositionPerpetuals(TraderVault memory _traderVault)\\n        internal\\n        pure\\n        returns (int128[2] memory positionPerpetuals)\\n    {\\n        for (uint256 i = 0; i < MAX_PRODUCT_ID; i++) {\\n            positionPerpetuals[i] = getPositionPerpetual(_traderVault, i);\\n        }\\n    }\\n\\n    /**\\n     * @notice Gets position of a perpetual in the vault\\n     * @param _traderVault trader vault object\\n     * @param _productId product id\\n     * @return positionPerpetual is amount of perpetual scaled by 1e8\\n     */\\n    function getPositionPerpetual(TraderVault memory _traderVault, uint256 _productId)\\n        internal\\n        pure\\n        returns (int128 positionPerpetual)\\n    {\\n        for (uint256 i = 0; i < _traderVault.subVaults.length; i++) {\\n            positionPerpetual = positionPerpetual\\n                .add(_traderVault.subVaults[i].positionPerpetuals[_productId])\\n                .toInt128();\\n        }\\n    }\\n\\n    /**\\n     * @notice Updates positions in the vault\\n     * @param _traderVault trader vault object\\n     * @param _subVaultIndex index of sub-vault\\n     * @param _productId product id\\n     * @param _positionPerpetual amount of position to increase or decrease\\n     * @param _tradePrice trade price\\n     * @param _fundingFeePerPosition entry funding fee paid per position\\n     */\\n    function updateVault(\\n        TraderVault storage _traderVault,\\n        uint256 _subVaultIndex,\\n        uint256 _productId,\\n        int128 _positionPerpetual,\\n        uint256 _tradePrice,\\n        int256 _fundingFeePerPosition\\n    ) external returns (int256 roundedDeltaUsdcPosition, uint256 lpProfit) {\\n        require(_positionPerpetual != 0, \\\"T4\\\");\\n\\n        if (_traderVault.subVaults.length == _subVaultIndex) {\\n            int128[2] memory positionPerpetuals;\\n            uint128[2] memory entryPrices;\\n            int256[2] memory entryFundingFee;\\n\\n            _traderVault.subVaults.push(SubVault(positionPerpetuals, entryPrices, entryFundingFee));\\n        } else {\\n            require(_traderVault.subVaults.length > _subVaultIndex, \\\"T3\\\");\\n        }\\n\\n        SubVault storage subVault = _traderVault.subVaults[_subVaultIndex];\\n        int256 deltaUsdcPosition;\\n\\n        {\\n            (int256 newEntryPrice, int256 profitValue) = EntryPriceMath.updateEntryPrice(\\n                int256(subVault.entryPrices[_productId]),\\n                subVault.positionPerpetuals[_productId],\\n                int256(_tradePrice),\\n                _positionPerpetual\\n            );\\n\\n            subVault.entryPrices[_productId] = newEntryPrice.toUint256().toUint128();\\n            deltaUsdcPosition = deltaUsdcPosition.add(profitValue);\\n        }\\n\\n        {\\n            (int256 newEntryFundingFee, int256 profitValue) = EntryPriceMath.updateEntryPrice(\\n                int256(subVault.entryFundingFee[_productId]),\\n                subVault.positionPerpetuals[_productId],\\n                _fundingFeePerPosition,\\n                _positionPerpetual\\n            );\\n\\n            subVault.entryFundingFee[_productId] = newEntryFundingFee;\\n            deltaUsdcPosition = deltaUsdcPosition.sub(profitValue.div(1e8));\\n        }\\n\\n        // if deltaUsdcPosition is positive, round down to the second decimal place, if negative round up.\\n        roundedDeltaUsdcPosition = Math.mulDiv(deltaUsdcPosition, 1, 1e6, deltaUsdcPosition < 0).mul(1e6);\\n\\n        if (deltaUsdcPosition > roundedDeltaUsdcPosition) {\\n            lpProfit = deltaUsdcPosition.sub(roundedDeltaUsdcPosition).toUint256();\\n        }\\n\\n        _traderVault.positionUsdc = _traderVault.positionUsdc.add(roundedDeltaUsdcPosition).toInt128();\\n\\n        subVault.positionPerpetuals[_productId] = subVault\\n            .positionPerpetuals[_productId]\\n            .add(_positionPerpetual)\\n            .toInt128();\\n    }\\n\\n    /**\\n     * @notice Checks the vault is danger or not\\n     * if PositionValue is less than MinCollateral return true\\n     * otherwise return false\\n     * @param _traderVault trader vault object\\n     */\\n    function checkVaultIsDanger(\\n        TraderVault memory _traderVault,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (bool) {\\n        int256 positionValue = getPositionValue(_traderVault, _tradePriceInfo);\\n\\n        return positionValue < getMinCollateral(_traderVault, _tradePriceInfo);\\n    }\\n\\n    /**\\n     * @notice Decreases liquidation reward from usdc position\\n     * @param _traderVault trader vault object\\n     * @param _minCollateral min collateral\\n     * @param _liquidationFee liquidation fee rate\\n     */\\n    function decreaseLiquidationReward(\\n        TraderVault storage _traderVault,\\n        int256 _minCollateral,\\n        int256 _liquidationFee\\n    ) external returns (uint256) {\\n        if (_traderVault.positionUsdc <= 0) {\\n            return 0;\\n        }\\n\\n        int256 reward = _minCollateral.mul(_liquidationFee).div(1e4);\\n\\n        // round down to the second decimal place.\\n        reward = reward.div(1e6).mul(1e6);\\n\\n        reward = Math.min(reward, _traderVault.positionUsdc);\\n\\n        // reduce margin\\n        // sub is safe because we know reward is less than positionUsdc\\n        _traderVault.positionUsdc -= reward.toInt128();\\n\\n        return reward.toUint256();\\n    }\\n\\n    /**\\n     * @notice Gets min collateral of the vault\\n     * @param _traderVault trader vault object\\n     * @param _tradePriceInfo trade price info\\n     * @return MinCollateral scaled by 1e8\\n     */\\n    function getMinCollateral(\\n        TraderVault memory _traderVault,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        int128[2] memory assetAmounts = getPositionPerpetuals(_traderVault);\\n\\n        return calculateMinCollateral(assetAmounts, _tradePriceInfo);\\n    }\\n\\n    /**\\n     * @notice Calculates min collateral\\n     * MinCollateral = alpha*S*(|2*S*(1+fundingSqueeth)*PositionSqueeth + (1+fundingFuture)*PositionFuture| + 2*alpha*S*(1+fundingSqueeth)*|PositionSqueeth|)\\n     * where alpha is 0.05\\n     * @param positionPerpetuals amount of perpetual positions\\n     * @param _tradePriceInfo trade price info\\n     * @return MinCollateral scaled by 1e8\\n     */\\n    function calculateMinCollateral(\\n        int128[2] memory positionPerpetuals,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        // priceWithFunding = S*(1+fundingSqueeth)\\n        int256 priceWithFunding = int256(_tradePriceInfo.spotPrice).mul(_tradePriceInfo.fundingRates[1].add(1e16)).div(\\n            1e8\\n        );\\n\\n        uint256 maxDelta = Math.abs(\\n            (priceWithFunding.mul(positionPerpetuals[1]).mul(2).div(1e20)).add(\\n                positionPerpetuals[0].mul(_tradePriceInfo.fundingRates[0].add(1e16)).div(1e16)\\n            )\\n        );\\n\\n        maxDelta = maxDelta.add(\\n            Math.abs(int256(RISK_PARAM_FOR_VAULT).mul(priceWithFunding).mul(2).mul(positionPerpetuals[1]).div(1e24))\\n        );\\n\\n        uint256 minCollateral = (RISK_PARAM_FOR_VAULT.mul(_tradePriceInfo.spotPrice).mul(maxDelta)) / 1e12;\\n\\n        if ((positionPerpetuals[0] != 0 || positionPerpetuals[1] != 0) && minCollateral < MIN_MARGIN) {\\n            minCollateral = MIN_MARGIN;\\n        }\\n\\n        return minCollateral.toInt256();\\n    }\\n\\n    /**\\n     * @notice Gets position value in the vault\\n     * PositionValue = USDC + \\u03a3(ValueOfSubVault_i)\\n     * @param _traderVault trader vault object\\n     * @param _tradePriceInfo trade price info\\n     * @return PositionValue scaled by 1e8\\n     */\\n    function getPositionValue(\\n        TraderVault memory _traderVault,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        int256 value = _traderVault.positionUsdc;\\n\\n        for (uint256 i = 0; i < _traderVault.subVaults.length; i++) {\\n            value = value.add(getSubVaultPositionValue(_traderVault.subVaults[i], _tradePriceInfo));\\n        }\\n\\n        return value;\\n    }\\n\\n    /**\\n     * @notice Gets position value in the sub-vault\\n     * ValueOfSubVault = TotalPerpetualValueOfSubVault + TotalFundingFeePaidOfSubVault\\n     * @param _subVault sub-vault object\\n     * @param _tradePriceInfo trade price info\\n     * @return ValueOfSubVault scaled by 1e8\\n     */\\n    function getSubVaultPositionValue(\\n        SubVault memory _subVault,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        return\\n            getTotalPerpetualValueOfSubVault(_subVault, _tradePriceInfo).add(\\n                getTotalFundingFeePaidOfSubVault(_subVault, _tradePriceInfo.amountsFundingPaidPerPosition)\\n            );\\n    }\\n\\n    /**\\n     * @notice Gets total perpetual value in the sub-vault\\n     * TotalPerpetualValueOfSubVault = \\u03a3(PerpetualValueOfSubVault_i)\\n     * @param _subVault sub-vault object\\n     * @param _tradePriceInfo trade price info\\n     * @return TotalPerpetualValueOfSubVault scaled by 1e8\\n     */\\n    function getTotalPerpetualValueOfSubVault(\\n        SubVault memory _subVault,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        int256 pnl;\\n\\n        for (uint256 i = 0; i < MAX_PRODUCT_ID; i++) {\\n            pnl = pnl.add(getPerpetualValueOfSubVault(_subVault, i, _tradePriceInfo));\\n        }\\n\\n        return pnl;\\n    }\\n\\n    /**\\n     * @notice Gets perpetual value in the sub-vault\\n     * PerpetualValueOfSubVault_i = (TradePrice_i - EntryPrice_i)*Position_i\\n     * @param _subVault sub-vault object\\n     * @param _productId product id\\n     * @param _tradePriceInfo trade price info\\n     * @return PerpetualValueOfSubVault_i scaled by 1e8\\n     */\\n    function getPerpetualValueOfSubVault(\\n        SubVault memory _subVault,\\n        uint256 _productId,\\n        IPerpetualMarketCore.TradePriceInfo memory _tradePriceInfo\\n    ) internal pure returns (int256) {\\n        int256 pnl = _tradePriceInfo.tradePrices[_productId].sub(_subVault.entryPrices[_productId].toInt256()).mul(\\n            _subVault.positionPerpetuals[_productId]\\n        );\\n\\n        return pnl / 1e8;\\n    }\\n\\n    /**\\n     * @notice Gets total funding fee in the sub-vault\\n     * TotalFundingFeePaidOfSubVault = \\u03a3(FundingFeePaidOfSubVault_i)\\n     * @param _subVault sub-vault object\\n     * @param _amountsFundingPaidPerPosition the cumulative funding fee paid by long per position\\n     * @return TotalFundingFeePaidOfSubVault scaled by 1e8\\n     */\\n    function getTotalFundingFeePaidOfSubVault(\\n        SubVault memory _subVault,\\n        int256[2] memory _amountsFundingPaidPerPosition\\n    ) internal pure returns (int256) {\\n        int256 fundingFee;\\n\\n        for (uint256 i = 0; i < MAX_PRODUCT_ID; i++) {\\n            fundingFee = fundingFee.add(getFundingFeePaidOfSubVault(_subVault, i, _amountsFundingPaidPerPosition));\\n        }\\n\\n        return fundingFee;\\n    }\\n\\n    /**\\n     * @notice Gets funding fee in the sub-vault\\n     * FundingFeePaidOfSubVault_i = Position_i*(EntryFundingFee_i - FundingFeeGlobal_i)\\n     * @param _subVault sub-vault object\\n     * @param _productId product id\\n     * @param _amountsFundingPaidPerPosition cumulative funding fee paid by long per position.\\n     * @return FundingFeePaidOfSubVault_i scaled by 1e8\\n     */\\n    function getFundingFeePaidOfSubVault(\\n        SubVault memory _subVault,\\n        uint256 _productId,\\n        int256[2] memory _amountsFundingPaidPerPosition\\n    ) internal pure returns (int256) {\\n        int256 fundingFee = _subVault.entryFundingFee[_productId].sub(_amountsFundingPaidPerPosition[_productId]).mul(\\n            _subVault.positionPerpetuals[_productId]\\n        );\\n\\n        return fundingFee.div(1e16);\\n    }\\n}\\n\",\"keccak256\":\"0x390c1efbddb42545060b7d9aede56187aa59b84b0dc82aa0dc65f09210879be5\",\"license\":\"agpl-3.0\"}},\"version\":1}",
  "bytecode": "0x6118eb610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c8063652aa4831461005b57806369e2bed014610091578063a8ffb3b9146100b3578063e69e266d146100e1575b600080fd5b81801561006757600080fd5b5061007b610076366004611600565b610101565b6040516100889190611731565b60405180910390f35b81801561009d57600080fd5b506100b16100ac3660046115df565b6101a8565b005b8180156100bf57600080fd5b506100d36100ce3660046116da565b610211565b60405161008892919061173a565b8180156100ed57600080fd5b5061007b6100fc36600461162b565b61056f565b8254600090600f90810b900b811261011b575060006101a1565b600061013361271061012d8686610a52565b90610b04565b905061014c620f42406101468382610b04565b90610a52565b8554909150610163908290600f90810b900b610bbc565b905061016e81610bd1565b8554600f81810b9290920390910b6001600160801b03166001600160801b031990911617855561019d81610c36565b9150505b9392505050565b600081136101d15760405162461bcd60e51b81526004016101c89061179c565b60405180910390fd5b81546101ed906101e890600f90810b900b83610c8d565b610bd1565b8254600f9190910b6001600160801b03166001600160801b03199091161790915550565b60008084600f0b600014156102385760405162461bcd60e51b81526004016101c890611748565b60018801548714156102d95761024c61140b565b61025461140b565b61025c61140b565b6040805160608101825284815260208082018590529181018390526001808e01805491820181556000908152929092208151919260040201906102a29082906002611429565b5060208201516102b890600183019060026114cd565b5060408201516102ce906002808401919061152d565b5050505050506102fc565b600188015487106102fc5760405162461bcd60e51b81526004016101c890611780565b600088600101888154811061030d57fe5b906000526020600020906004020190506000806000610391846001018b6002811061033457fe5b600291828204019190066010029054906101000a90046001600160801b03166001600160801b0316856000018c6002811061036b57fe5b600291828204019190066010029054906101000a9004600f0b600f0b8a8c600f0b610cf2565b915091506103a66103a183610c36565b610e2a565b846001018b600281106103b557fe5b600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506103f78184610c8d90919063ffffffff16565b92505050600080610444846002018b6002811061041057fe5b0154858c6002811061041e57fe5b600291828204019190066010029054906101000a9004600f0b600f0b898c600f0b610cf2565b9150915081846002018b6002811061045857fe5b015561047261046b826305f5e100610b04565b8490610e6e565b92505050610490620f4240610146836001620f424060008712610ed3565b9350838113156104af576104ac6104a78286610e6e565b610c36565b92505b89546104c6906101e890600f90810b900b86610c8d565b8a546001600160801b0319166001600160801b03600f92830b16178b55610524906101e89089900b848b600281106104fa57fe5b600291828204019190066010029054906101000a9004600f0b600f0b610c8d90919063ffffffff16565b82896002811061053057fe5b600291828204019190066010026101000a8154816001600160801b030219169083600f0b6001600160801b031602179055505050965096945050505050565b6040805180820182528454600f90810b810b900b8152600185018054835160208281028201810190955281815286946000946106e69490938a938386019390929190889084015b828210156106d8576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f010492830192600103820291508084116105ed575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f010492830192600103820291508084116106495750505092845250506040805180820191829052602090930192915060028481019182845b8154815260200190600101908083116106ad57505050505081525050815260200190600101906105b6565b505050508152505084610f2a565b6040805180820182528754600f90810b810b900b8152600188018054835160208281028201810190955281815294955060009461085a948b93818601939091889084015b8282101561084c576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610761575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f010492830192600103820291508084116107bd5750505092845250506040805180820191829052602090930192915060028481019182845b815481526020019060010190808311610821575050505050815250508152602001906001019061072a565b505050508152505085610f7e565b90508082036000819003861280156108725750600081135b801561087e5750600086125b1561088a578060000393505b86546108a1906101e890600f90810b900b86610c8d565b87546001600160801b0319166001600160801b03600f92830b161780895560408051808201825291830b830b90920b81526001890180548351602080830282018101909552818152610a2b948c9381860193909160009084015b82821015610a1d576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610932575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f0104928301926001038202915080841161098e5750505092845250506040805180820191829052602090930192915060028481019182845b8154815260200190600101908083116109f257505050505081525050815260200190600101906108fb565b505050508152505086610f9e565b15610a485760405162461bcd60e51b81526004016101c890611764565b5050509392505050565b600082610a6157506000610afe565b82600019148015610a755750600160ff1b82145b15610ab15760405162461bcd60e51b81526004018080602001828103825260278152602001806118436027913960400191505060405180910390fd5b82820282848281610abe57fe5b0514610afb5760405162461bcd60e51b81526004018080602001828103825260278152602001806118436027913960400191505060405180910390fd5b90505b92915050565b600081610b58576040805162461bcd60e51b815260206004820181905260248201527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604482015290519081900360640190fd5b81600019148015610b6c5750600160ff1b83145b15610ba85760405162461bcd60e51b81526004018080602001828103825260218152602001806118016021913960400191505060405180910390fd5b6000828481610bb357fe5b05949350505050565b6000818313610bcb5782610afb565b50919050565b60006f7fffffffffffffffffffffffffffffff198212158015610bf757506001607f1b82125b610c325760405162461bcd60e51b81526004018080602001828103825260278152602001806117b96027913960400191505060405180910390fd5b5090565b600080821215610c32576040805162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015290519081900360640190fd5b6000828201818312801590610ca25750838112155b80610cb75750600083128015610cb757508381125b610afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806117e06021913960400191505060405180910390fd5b60008080610d008685610c8d565b9050851580610d1a5750600086138015610d1a5750600084135b80610d305750600086128015610d305750600084125b15610d8057610d79610d4a610d458887610c8d565b610fbf565b61012d610d60610d5988610fbf565b8990610a52565b610d73610d6c8b610fbf565b8c90610a52565b90610c8d565b9250610e20565b600086138015610d905750600084125b8015610d9c5750600081135b80610dbe5750600086128015610db25750600084135b8015610dbe5750600081125b15610df2578692506305f5e100610de3610dd88786610e6e565b600087900390610a52565b81610dea57fe5b059150610e20565b8015610dfc578492505b6305f5e100610e15610e0e878a610e6e565b8890610a52565b81610e1c57fe5b0591505b5094509492505050565b6000600160801b8210610c325760405162461bcd60e51b81526004018080602001828103825260278152602001806117b96027913960400191505060405180910390fd5b6000818303818312801590610e835750838113155b80610e985750600083128015610e9857508381135b610afb5760405162461bcd60e51b81526004018080602001828103825260248152602001806118926024913960400191505060405180910390fd5b6000808215610f0f5760008486880281610ee957fe5b0790506000811315610efe5760019150610f0d565b6000811215610f0d5760001991505b505b6000818587890281610f1d57fe5b0501979650505050505050565b8151600090600f0b815b846020015151811015610f7657610f6c610f6586602001518381518110610f5757fe5b602002602001015186610fd0565b8390610c8d565b9150600101610f34565b509392505050565b600080610f8a84610fed565b9050610f96818461102e565b949350505050565b600080610fab8484610f2a565b9050610fb78484610f7e565b139392505050565b600080821215610c32575060000390565b6000610afb610fe384846060015161119e565b610d7385856111c5565b610ff561140b565b60005b6002811015610bcb5761100b83826111ec565b82826002811061101757fe5b600f92830b90920b60209092020152600101610ff8565b6000806110746305f5e10061012d611063662386f26fc10000876040015160016002811061105857fe5b602002015190610c8d565b86516001600160801b031690610a52565b905060006110da610d456110b3662386f26fc1000061012d6110a8662386f26fc100008a6040015160006002811061105857fe5b8a51600f0b90610a52565b610d7368056bc75e2d6310000061012d60026101468c600160200201518a90600f0b610a52565b905061111461110d610d4569d3c21bcecceda100000061012d8960016020020151600f0b6101466002816101f48b610a52565b829061124d565b9050600064e8d4a5100061114a8361114488600001516001600160801b03166101f46112a790919063ffffffff16565b906112a7565b8161115157fe5b87519190049150600f0b15158061116e57506020860151600f0b15155b801561117e57506404a817c80081105b1561118b57506404a817c8005b61119481611300565b9695505050505050565b60008060005b6002811015610f76576111bb610f65868387611344565b91506001016111a4565b60008060005b6002811015610f76576111e2610f658683876113a4565b91506001016111cb565b6000805b8360200151518110156112465761123c6101e88560200151838151811061121357fe5b602002602001015160000151856002811061122a57fe5b6020020151600f85810b91900b610c8d565b91506001016111f0565b5092915050565b600082820183811015610afb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000826112b657506000610afe565b828202828482816112c357fe5b0414610afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806118226021913960400191505060405180910390fd5b6000600160ff1b8210610c325760405162461bcd60e51b815260040180806020018281038252602881526020018061186a6028913960400191505060405180910390fd5b6000806113918560000151856002811061135a57fe5b6020020151600f0b61014685876002811061137157fe5b60200201518860400151886002811061138657fe5b602002015190610e6e565b905061019d81662386f26fc10000610b04565b6000806113fb856000015185600281106113ba57fe5b6020020151600f0b6101466113eb886020015188600281106113d857fe5b60200201516001600160801b0316611300565b8660200151886002811061138657fe5b6305f5e100900595945050505050565b60405180604001604052806002906020820280368337509192915050565b6001830191839082156114c15791602002820160005b8382111561148c57835183826101000a8154816001600160801b030219169083600f0b6001600160801b031602179055509260200192601001602081600f0104928301926001030261143f565b80156114bf5782816101000a8154906001600160801b030219169055601001602081600f0104928301926001030261148c565b505b50610c3292915061155b565b6001830191839082156114c15791602002820160005b8382111561148c57835183826101000a8154816001600160801b0302191690836001600160801b031602179055509260200192601001602081600f010492830192600103026114e3565b82600281019282156114c1579160200282015b828111156114c1578251825591602001919060010190611540565b5b80821115610c32576000815560010161155c565b600082601f830112611580578081fd5b6040516040810181811067ffffffffffffffff8211171561159d57fe5b80604052508083856040860111156115b3578384fd5b835b60028110156115d45781358352602092830192909101906001016115b5565b509195945050505050565b600080604083850312156115f1578182fd5b50508035926020909101359150565b600080600060608486031215611614578081fd5b505081359360208301359350604090920135919050565b6000806000838503610120811215611641578384fd5b843593506020850135925060e0603f198201121561165d578182fd5b506040516080810181811067ffffffffffffffff8211171561167b57fe5b60409081528501356001600160801b0381168114611697578283fd5b81526116a68660608701611570565b60208201526116b88660a08701611570565b60408201526116ca8660e08701611570565b6060820152809150509250925092565b60008060008060008060c087890312156116f2578182fd5b863595506020870135945060408701359350606087013580600f0b8114611717578283fd5b9598949750929560808101359460a0909101359350915050565b90815260200190565b918252602082015260400190565b602080825260029082015261150d60f21b604082015260600190565b602080825260029082015261054360f41b604082015260600190565b602080825260029082015261543360f01b604082015260600190565b602080825260029082015261543560f01b60408201526060019056fe53616665436173743a2076616c756520646f65736e27742066697420696e2031323820626974735369676e6564536166654d6174683a206164646974696f6e206f766572666c6f775369676e6564536166654d6174683a206469766973696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235365369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f77a2646970667358221220ad056b194ee08dd36d22d5b2527f24c69e1464697a835ae46cbc6a0d80e5df9064736f6c63430007060033",
  "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c8063652aa4831461005b57806369e2bed014610091578063a8ffb3b9146100b3578063e69e266d146100e1575b600080fd5b81801561006757600080fd5b5061007b610076366004611600565b610101565b6040516100889190611731565b60405180910390f35b81801561009d57600080fd5b506100b16100ac3660046115df565b6101a8565b005b8180156100bf57600080fd5b506100d36100ce3660046116da565b610211565b60405161008892919061173a565b8180156100ed57600080fd5b5061007b6100fc36600461162b565b61056f565b8254600090600f90810b900b811261011b575060006101a1565b600061013361271061012d8686610a52565b90610b04565b905061014c620f42406101468382610b04565b90610a52565b8554909150610163908290600f90810b900b610bbc565b905061016e81610bd1565b8554600f81810b9290920390910b6001600160801b03166001600160801b031990911617855561019d81610c36565b9150505b9392505050565b600081136101d15760405162461bcd60e51b81526004016101c89061179c565b60405180910390fd5b81546101ed906101e890600f90810b900b83610c8d565b610bd1565b8254600f9190910b6001600160801b03166001600160801b03199091161790915550565b60008084600f0b600014156102385760405162461bcd60e51b81526004016101c890611748565b60018801548714156102d95761024c61140b565b61025461140b565b61025c61140b565b6040805160608101825284815260208082018590529181018390526001808e01805491820181556000908152929092208151919260040201906102a29082906002611429565b5060208201516102b890600183019060026114cd565b5060408201516102ce906002808401919061152d565b5050505050506102fc565b600188015487106102fc5760405162461bcd60e51b81526004016101c890611780565b600088600101888154811061030d57fe5b906000526020600020906004020190506000806000610391846001018b6002811061033457fe5b600291828204019190066010029054906101000a90046001600160801b03166001600160801b0316856000018c6002811061036b57fe5b600291828204019190066010029054906101000a9004600f0b600f0b8a8c600f0b610cf2565b915091506103a66103a183610c36565b610e2a565b846001018b600281106103b557fe5b600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506103f78184610c8d90919063ffffffff16565b92505050600080610444846002018b6002811061041057fe5b0154858c6002811061041e57fe5b600291828204019190066010029054906101000a9004600f0b600f0b898c600f0b610cf2565b9150915081846002018b6002811061045857fe5b015561047261046b826305f5e100610b04565b8490610e6e565b92505050610490620f4240610146836001620f424060008712610ed3565b9350838113156104af576104ac6104a78286610e6e565b610c36565b92505b89546104c6906101e890600f90810b900b86610c8d565b8a546001600160801b0319166001600160801b03600f92830b16178b55610524906101e89089900b848b600281106104fa57fe5b600291828204019190066010029054906101000a9004600f0b600f0b610c8d90919063ffffffff16565b82896002811061053057fe5b600291828204019190066010026101000a8154816001600160801b030219169083600f0b6001600160801b031602179055505050965096945050505050565b6040805180820182528454600f90810b810b900b8152600185018054835160208281028201810190955281815286946000946106e69490938a938386019390929190889084015b828210156106d8576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f010492830192600103820291508084116105ed575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f010492830192600103820291508084116106495750505092845250506040805180820191829052602090930192915060028481019182845b8154815260200190600101908083116106ad57505050505081525050815260200190600101906105b6565b505050508152505084610f2a565b6040805180820182528754600f90810b810b900b8152600188018054835160208281028201810190955281815294955060009461085a948b93818601939091889084015b8282101561084c576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610761575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f010492830192600103820291508084116107bd5750505092845250506040805180820191829052602090930192915060028481019182845b815481526020019060010190808311610821575050505050815250508152602001906001019061072a565b505050508152505085610f7e565b90508082036000819003861280156108725750600081135b801561087e5750600086125b1561088a578060000393505b86546108a1906101e890600f90810b900b86610c8d565b87546001600160801b0319166001600160801b03600f92830b161780895560408051808201825291830b830b90920b81526001890180548351602080830282018101909552818152610a2b948c9381860193909160009084015b82821015610a1d576000848152602090206040805160a0810190915290600484020181606081018260028282826020028201916000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610932575050509284525050604080518082019182905260209093019291506001840190600290826000855b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f0104928301926001038202915080841161098e5750505092845250506040805180820191829052602090930192915060028481019182845b8154815260200190600101908083116109f257505050505081525050815260200190600101906108fb565b505050508152505086610f9e565b15610a485760405162461bcd60e51b81526004016101c890611764565b5050509392505050565b600082610a6157506000610afe565b82600019148015610a755750600160ff1b82145b15610ab15760405162461bcd60e51b81526004018080602001828103825260278152602001806118436027913960400191505060405180910390fd5b82820282848281610abe57fe5b0514610afb5760405162461bcd60e51b81526004018080602001828103825260278152602001806118436027913960400191505060405180910390fd5b90505b92915050565b600081610b58576040805162461bcd60e51b815260206004820181905260248201527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604482015290519081900360640190fd5b81600019148015610b6c5750600160ff1b83145b15610ba85760405162461bcd60e51b81526004018080602001828103825260218152602001806118016021913960400191505060405180910390fd5b6000828481610bb357fe5b05949350505050565b6000818313610bcb5782610afb565b50919050565b60006f7fffffffffffffffffffffffffffffff198212158015610bf757506001607f1b82125b610c325760405162461bcd60e51b81526004018080602001828103825260278152602001806117b96027913960400191505060405180910390fd5b5090565b600080821215610c32576040805162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015290519081900360640190fd5b6000828201818312801590610ca25750838112155b80610cb75750600083128015610cb757508381125b610afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806117e06021913960400191505060405180910390fd5b60008080610d008685610c8d565b9050851580610d1a5750600086138015610d1a5750600084135b80610d305750600086128015610d305750600084125b15610d8057610d79610d4a610d458887610c8d565b610fbf565b61012d610d60610d5988610fbf565b8990610a52565b610d73610d6c8b610fbf565b8c90610a52565b90610c8d565b9250610e20565b600086138015610d905750600084125b8015610d9c5750600081135b80610dbe5750600086128015610db25750600084135b8015610dbe5750600081125b15610df2578692506305f5e100610de3610dd88786610e6e565b600087900390610a52565b81610dea57fe5b059150610e20565b8015610dfc578492505b6305f5e100610e15610e0e878a610e6e565b8890610a52565b81610e1c57fe5b0591505b5094509492505050565b6000600160801b8210610c325760405162461bcd60e51b81526004018080602001828103825260278152602001806117b96027913960400191505060405180910390fd5b6000818303818312801590610e835750838113155b80610e985750600083128015610e9857508381135b610afb5760405162461bcd60e51b81526004018080602001828103825260248152602001806118926024913960400191505060405180910390fd5b6000808215610f0f5760008486880281610ee957fe5b0790506000811315610efe5760019150610f0d565b6000811215610f0d5760001991505b505b6000818587890281610f1d57fe5b0501979650505050505050565b8151600090600f0b815b846020015151811015610f7657610f6c610f6586602001518381518110610f5757fe5b602002602001015186610fd0565b8390610c8d565b9150600101610f34565b509392505050565b600080610f8a84610fed565b9050610f96818461102e565b949350505050565b600080610fab8484610f2a565b9050610fb78484610f7e565b139392505050565b600080821215610c32575060000390565b6000610afb610fe384846060015161119e565b610d7385856111c5565b610ff561140b565b60005b6002811015610bcb5761100b83826111ec565b82826002811061101757fe5b600f92830b90920b60209092020152600101610ff8565b6000806110746305f5e10061012d611063662386f26fc10000876040015160016002811061105857fe5b602002015190610c8d565b86516001600160801b031690610a52565b905060006110da610d456110b3662386f26fc1000061012d6110a8662386f26fc100008a6040015160006002811061105857fe5b8a51600f0b90610a52565b610d7368056bc75e2d6310000061012d60026101468c600160200201518a90600f0b610a52565b905061111461110d610d4569d3c21bcecceda100000061012d8960016020020151600f0b6101466002816101f48b610a52565b829061124d565b9050600064e8d4a5100061114a8361114488600001516001600160801b03166101f46112a790919063ffffffff16565b906112a7565b8161115157fe5b87519190049150600f0b15158061116e57506020860151600f0b15155b801561117e57506404a817c80081105b1561118b57506404a817c8005b61119481611300565b9695505050505050565b60008060005b6002811015610f76576111bb610f65868387611344565b91506001016111a4565b60008060005b6002811015610f76576111e2610f658683876113a4565b91506001016111cb565b6000805b8360200151518110156112465761123c6101e88560200151838151811061121357fe5b602002602001015160000151856002811061122a57fe5b6020020151600f85810b91900b610c8d565b91506001016111f0565b5092915050565b600082820183811015610afb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000826112b657506000610afe565b828202828482816112c357fe5b0414610afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806118226021913960400191505060405180910390fd5b6000600160ff1b8210610c325760405162461bcd60e51b815260040180806020018281038252602881526020018061186a6028913960400191505060405180910390fd5b6000806113918560000151856002811061135a57fe5b6020020151600f0b61014685876002811061137157fe5b60200201518860400151886002811061138657fe5b602002015190610e6e565b905061019d81662386f26fc10000610b04565b6000806113fb856000015185600281106113ba57fe5b6020020151600f0b6101466113eb886020015188600281106113d857fe5b60200201516001600160801b0316611300565b8660200151886002811061138657fe5b6305f5e100900595945050505050565b60405180604001604052806002906020820280368337509192915050565b6001830191839082156114c15791602002820160005b8382111561148c57835183826101000a8154816001600160801b030219169083600f0b6001600160801b031602179055509260200192601001602081600f0104928301926001030261143f565b80156114bf5782816101000a8154906001600160801b030219169055601001602081600f0104928301926001030261148c565b505b50610c3292915061155b565b6001830191839082156114c15791602002820160005b8382111561148c57835183826101000a8154816001600160801b0302191690836001600160801b031602179055509260200192601001602081600f010492830192600103026114e3565b82600281019282156114c1579160200282015b828111156114c1578251825591602001919060010190611540565b5b80821115610c32576000815560010161155c565b600082601f830112611580578081fd5b6040516040810181811067ffffffffffffffff8211171561159d57fe5b80604052508083856040860111156115b3578384fd5b835b60028110156115d45781358352602092830192909101906001016115b5565b509195945050505050565b600080604083850312156115f1578182fd5b50508035926020909101359150565b600080600060608486031215611614578081fd5b505081359360208301359350604090920135919050565b6000806000838503610120811215611641578384fd5b843593506020850135925060e0603f198201121561165d578182fd5b506040516080810181811067ffffffffffffffff8211171561167b57fe5b60409081528501356001600160801b0381168114611697578283fd5b81526116a68660608701611570565b60208201526116b88660a08701611570565b60408201526116ca8660e08701611570565b6060820152809150509250925092565b60008060008060008060c087890312156116f2578182fd5b863595506020870135945060408701359350606087013580600f0b8114611717578283fd5b9598949750929560808101359460a0909101359350915050565b90815260200190565b918252602082015260400190565b602080825260029082015261150d60f21b604082015260600190565b602080825260029082015261054360f41b604082015260600190565b602080825260029082015261543360f01b604082015260600190565b602080825260029082015261543560f01b60408201526060019056fe53616665436173743a2076616c756520646f65736e27742066697420696e2031323820626974735369676e6564536166654d6174683a206164646974696f6e206f766572666c6f775369676e6564536166654d6174683a206469766973696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235365369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f77a2646970667358221220ad056b194ee08dd36d22d5b2527f24c69e1464697a835ae46cbc6a0d80e5df9064736f6c63430007060033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "addUsdcPosition(TraderVaultLib.TraderVault storage,int256)": {
        "params": {
          "_traderVault": "trader vault object",
          "_usdcPositionToAdd": "amount to add. value is always positive."
        }
      },
      "decreaseLiquidationReward(TraderVaultLib.TraderVault storage,int256,int256)": {
        "params": {
          "_liquidationFee": "liquidation fee rate",
          "_minCollateral": "min collateral",
          "_traderVault": "trader vault object"
        }
      },
      "updateUsdcPosition(TraderVaultLib.TraderVault storage,int256,IPerpetualMarketCore.TradePriceInfo)": {
        "params": {
          "_tradePriceInfo": "trade price info",
          "_traderVault": "trader vault object",
          "_usdcPositionToAdd": "amount to add. if positive then increase amount, if negative then decrease amount."
        },
        "returns": {
          "finalUsdcPosition": "positive means amount of deposited margin and negative means amount of withdrawn margin."
        }
      },
      "updateVault(TraderVaultLib.TraderVault storage,uint256,uint256,int128,uint256,int256)": {
        "params": {
          "_fundingFeePerPosition": "entry funding fee paid per position",
          "_positionPerpetual": "amount of position to increase or decrease",
          "_productId": "product id",
          "_subVaultIndex": "index of sub-vault",
          "_tradePrice": "trade price",
          "_traderVault": "trader vault object"
        }
      }
    },
    "stateVariables": {
      "MIN_MARGIN": {
        "details": "minimum margin is 200 USDC"
      },
      "RISK_PARAM_FOR_VAULT": {
        "details": "risk parameter for MinCollateral calculation is 5.0%"
      }
    },
    "title": "TraderVaultLib",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "addUsdcPosition(TraderVaultLib.TraderVault storage,int256)": {
        "notice": "Add USDC position"
      },
      "decreaseLiquidationReward(TraderVaultLib.TraderVault storage,int256,int256)": {
        "notice": "Decreases liquidation reward from usdc position"
      },
      "updateUsdcPosition(TraderVaultLib.TraderVault storage,int256,IPerpetualMarketCore.TradePriceInfo)": {
        "notice": "Updates USDC position"
      },
      "updateVault(TraderVaultLib.TraderVault storage,uint256,uint256,int128,uint256,int256)": {
        "notice": "Updates positions in the vault"
      }
    },
    "notice": "TraderVaultLib has functions to calculate position value and minimum collateral for implementing cross margin wallet. Data Structure  Vault  - PositionUSDC  - SubVault0(PositionPerpetuals, EntryPrices, entryFundingFee)  - SubVault1(PositionPerpetuals, EntryPrices, entryFundingFee)  - ...  PositionPerpetuals = [PositionSqueeth, PositionFuture]  EntryPrices = [EntryPriceSqueeth, EntryPriceFuture]  entryFundingFee = [entryFundingFeeqeeth, FundingFeeEntryValueFuture] Error codes  T0: PositionValue must be greater than MinCollateral  T1: PositionValue must be less than MinCollateral  T2: Vault is insolvent  T3: subVaultIndex is too large  T4: position must not be 0  T5: usdc to add must be positive",
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}