Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
37f96e9
Merge remote-tracking branch 'origin/hotfix/internal_cancel_limit_ord…
DesertEaglePosition May 20, 2022
357007e
add limit when open market order and update deploy qc
DesertEaglePosition May 23, 2022
6aeac16
Merge branch 'hotfix/remove_claimbleAmount_and_debtProfit' into deplo…
DesertEaglePosition May 23, 2022
e790d58
upgrade qc contract update pending order after liquidated
DesertEaglePosition May 23, 2022
1b3f768
update calculate entryPrice when accumulateLimitOrderToPositionData
DesertEaglePosition May 24, 2022
8bc8050
update deploy contract qc
DesertEaglePosition May 24, 2022
54dfe39
deploy qc update close limit order no need to deposit
DesertEaglePosition May 25, 2022
ff7ca83
deploy qc make market order when liquidate
DesertEaglePosition May 25, 2022
dc71d99
deploy qc make market order when liquidate
DesertEaglePosition May 25, 2022
a317f90
deploy qc: not claim back fund when cancel a close limit order
DesertEaglePosition May 26, 2022
5a35693
update formula calculate liquidation price for long order
DesertEaglePosition May 26, 2022
784740e
update check if quantity = 0 when calculate liquidation price
DesertEaglePosition May 26, 2022
96e9d8a
remove function _removeUnfilledMargin in getClaimAmount
DesertEaglePosition May 26, 2022
cee4d32
update test case
DesertEaglePosition May 26, 2022
232d6f2
deploy qc
DesertEaglePosition May 26, 2022
32ef372
update test case
DesertEaglePosition May 26, 2022
d73a1d5
update getLiquidityInPipRange return current pip side
DesertEaglePosition May 27, 2022
9e2bef1
update return margin when close limit at current price and filled
DesertEaglePosition May 27, 2022
be3ccfd
separate error message
DesertEaglePosition May 27, 2022
dfcf881
update revert message
DesertEaglePosition May 27, 2022
fe84c91
add function instantlyClosePosition
DesertEaglePosition May 27, 2022
1364ecc
clear limit close order when partial liquidate
DesertEaglePosition May 27, 2022
c2fcd1a
deploy qc
DesertEaglePosition May 27, 2022
5375444
update calculate reverse notional in handleMarketPart
DesertEaglePosition May 27, 2022
4c809a3
upgrade final qc
DesertEaglePosition May 28, 2022
e1dcd3d
update deposit fund when open a limit close
DesertEaglePosition May 28, 2022
3983fda
update test case
DesertEaglePosition May 28, 2022
2d950b6
update open limit long/short higher/lower than current price
DesertEaglePosition May 28, 2022
1a2d2ef
update change current price when open a limit order long/short higher…
DesertEaglePosition May 28, 2022
ec53e9d
update change current price when open a limit order long/short higher…
DesertEaglePosition May 28, 2022
25e7bdf
update state.pip when remainingSize > liquidity
DesertEaglePosition May 28, 2022
596f56b
Add tests
LiamPosition Apr 27, 2022
ac5a9d6
Add test
DesertEaglePosition Jun 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/interfaces/IPositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ interface IPositionManager {
)
external
view
returns (PositionManagerStorage.PipLiquidity[] memory, uint128);
returns (PositionManagerStorage.PipLiquidity[] memory, uint128, uint8);

function openMarketPosition(uint256 size, bool isBuy)
external
Expand Down
6 changes: 3 additions & 3 deletions contracts/protocol/ChainLinkPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {IChainLinkPriceFeed} from "../interfaces/IChainLinkPriceFeed.sol";

contract ChainLinkPriceFeed is OwnableUpgradeable, IChainLinkPriceFeed {
abstract contract ChainLinkPriceFeed is OwnableUpgradeable, IChainLinkPriceFeed {
uint256 private constant TOKEN_DIGIT = 10**18;

// key by currency symbol, eg ETH
Expand Down Expand Up @@ -102,7 +102,7 @@ contract ChainLinkPriceFeed is OwnableUpgradeable, IChainLinkPriceFeed {
function getPrice(bytes32 _priceFeedKey)
external
view
override
virtual
returns (uint256)
{
AggregatorV3Interface aggregator = getAggregator(_priceFeedKey);
Expand All @@ -128,7 +128,7 @@ contract ChainLinkPriceFeed is OwnableUpgradeable, IChainLinkPriceFeed {
function getTwapPrice(bytes32 _priceFeedKey, uint256 _interval)
external
view
override
virtual
returns (uint256)
{
AggregatorV3Interface aggregator = getAggregator(_priceFeedKey);
Expand Down
6 changes: 6 additions & 0 deletions contracts/protocol/InsuranceFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ contract InsuranceFund is
paths[1] = token;
}

// TODO only use for qc test
function burnBalance(address token) onlyOwner public {
IERC20Upgradeable _token = IERC20Upgradeable(token);
_token.transfer(BURN_ADDRESS, _token.balanceOf(address(this)));
}

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
Expand Down
89 changes: 56 additions & 33 deletions contracts/protocol/PositionHouse.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,28 @@ contract PositionHouse is
IPositionManager positionManager
);

// event MarginAdded(
// address trader,
// uint256 marginAdded,
// IPositionManager positionManager
// );
//
// event MarginRemoved(
// address trader,
// uint256 marginRemoved,
// IPositionManager positionManager
// );
event MarginAdded(
address trader,
uint256 marginAdded,
IPositionManager positionManager
);

event MarginRemoved(
address trader,
uint256 marginRemoved,
IPositionManager positionManager
);

event FullyLiquidated(address pmAddress, address trader);
// event PartiallyLiquidated(address pmAddress, address trader);
event PartiallyLiquidated(address pmAddress, address trader);
// event WhitelistManagerUpdated(address positionManager, bool isWhitelite);

event FundClaimed(
address pmAddress,
address trader,
uint256 totalFund
);

function initialize(
address _insuranceFund,
IPositionHouseConfigurationProxy _positionHouseConfigurationProxy
Expand Down Expand Up @@ -171,6 +177,29 @@ contract PositionHouse is
);
}

function instantlyClosePosition(IPositionManager _positionManager, uint256 _quantity)
external
nonReentrant
{
address _pmAddress = address(_positionManager);
address _trader = _msgSender();
_emptyReduceLimitOrders(_pmAddress, _trader);
Position.Data memory _positionDataWithManualMargin = getPositionWithManualMargin(_pmAddress, _trader, getPosition(_pmAddress, _trader));
require(
_quantity > 0 && _quantity <= _positionDataWithManualMargin.quantity.abs(),
Errors.VL_INVALID_CLOSE_QUANTITY
);
_internalOpenMarketPosition(
_positionManager,
_positionDataWithManualMargin.quantity > 0
? Position.Side.SHORT
: Position.Side.LONG,
_quantity,
_positionDataWithManualMargin.leverage,
_positionDataWithManualMargin
);
}

/**
* @notice close position with close market
* @param _positionManager IPositionManager address
Expand Down Expand Up @@ -229,6 +258,7 @@ contract PositionHouse is
clearPosition(_pmAddress, _trader);
if (totalRealizedPnl > 0) {
_withdraw(_pmAddress, _trader, totalRealizedPnl.abs());
emit FundClaimed(_pmAddress, _trader, totalRealizedPnl.abs());
}
}

Expand Down Expand Up @@ -278,12 +308,15 @@ contract PositionHouse is
liquidationPenalty = uint256(positionResp.marginToVault);
feeToLiquidator = liquidationPenalty / 2;
uint256 feeToInsuranceFund = liquidationPenalty - feeToLiquidator;
// emit PartiallyLiquidated(_pmAddress, _trader);
emit PartiallyLiquidated(_pmAddress, _trader);
} else {
// fully liquidate trader's position
bool _liquidateOrderIsBuy = positionDataWithManualMargin.quantity > 0 ? false : true;
liquidationPenalty =
positionDataWithManualMargin.margin ;
clearPosition(_pmAddress, _trader);
// after clear position, create an opposite market order of old position
_positionManager.openMarketPosition(positionDataWithManualMargin.quantity.abs(), _liquidateOrderIsBuy);
feeToLiquidator =
(liquidationPenalty * _liquidationFeeRatio) /
2 /
Expand Down Expand Up @@ -315,7 +348,7 @@ contract PositionHouse is

_deposit(_pmAddress, _trader, _amount, 0);

// emit MarginAdded(_trader, _amount, _positionManager);
emit MarginAdded(_trader, _amount, _positionManager);
}

/**
Expand All @@ -338,7 +371,7 @@ contract PositionHouse is

_withdraw(_pmAddress, _trader, _amount);

// emit MarginRemoved(_trader, _amount, _positionManager);
emit MarginRemoved(_trader, _amount, _positionManager);
}

// OWNER UPDATE VARIABLE STORAGE
Expand Down Expand Up @@ -585,7 +618,7 @@ contract PositionHouse is
) internal {
address _trader = _msgSender();
address _pmAddress = address(_positionManager);
require(_requireOrderSideAndQuantity(_pmAddress, _trader, _side, _quantity, oldPosition.quantity),Errors.VL_MUST_SAME_SIDE);
_requireOrderSideAndQuantity(_pmAddress, _trader, _side, _quantity, oldPosition.quantity);
int256 pQuantity = _side == Position.Side.LONG
? int256(_quantity)
: -int256(_quantity);
Expand Down Expand Up @@ -688,16 +721,13 @@ contract PositionHouse is
.add(_getClaimAmount(_pmAddress, _trader, _oldPosition))
.kPositive();
positionResp.unrealizedPnl = 0;
ClaimableAmountManager._reset(_pmAddress, _trader);
clearPosition(_pmAddress, _trader);
}

function clearPosition(address _pmAddress, address _trader) internal {
positionMap[_pmAddress][_trader].clear();
debtPosition[_pmAddress][_trader].clearDebt();
manualMargin[_pmAddress][_trader] = 0;
debtProfit[_pmAddress][_trader] = 0;
ClaimableAmountManager._reset(_pmAddress, _trader);
(
PositionLimitOrder.Data[] memory subListLimitOrders,
PositionLimitOrder.Data[] memory subReduceLimitOrders
Expand All @@ -716,12 +746,6 @@ contract PositionHouse is
_pushLimit(_pmAddress, _trader, subListLimitOrders[i]);
}
_emptyReduceLimitOrders(_pmAddress, _trader);
for (uint256 i = 0; i < subReduceLimitOrders.length; i++) {
if (subReduceLimitOrders[i].pip == 0) {
break;
}
_pushReduceLimit(_pmAddress, _trader, subReduceLimitOrders[i]);
}
}

function openReversePosition(
Expand All @@ -736,8 +760,8 @@ contract PositionHouse is
if (_quantity.abs() < _oldPosition.quantity.abs()) {
int256 _manualAddedMargin = _getManualMargin(_pmAddress, _trader);
{
int256 debtMargin;
(positionResp, debtMargin) = PositionHouseFunction.openReversePosition(

positionResp = PositionHouseFunction.openReversePosition(
_pmAddress,
_side,
_quantity,
Expand All @@ -749,9 +773,6 @@ contract PositionHouse is
_manualAddedMargin
);
manualMargin[_pmAddress][_trader] = _manualAddedMargin * (_oldPosition.quantity.absInt() - _quantity.absInt()) / _oldPosition.quantity.absInt();
// if (_getPositionMap(_pmAddress, _trader).margin < debtMargin.abs()) {
debtProfit[_pmAddress][_trader] += debtMargin;
// }
return positionResp;
}
}
Expand Down Expand Up @@ -806,9 +827,11 @@ contract PositionHouse is
) internal returns (PositionResp memory positionResp) {
address _pmAddress = address(_positionManager);
int256 _manualMargin = _getManualMargin(_pmAddress, _trader);
Position.Side _side = _quantity > 0 ? Position.Side.SHORT : Position.Side.LONG;
(positionResp.exchangedPositionSize, ,, ) = PositionHouseFunction
.openMarketOrder(_pmAddress, _quantity.abs(), _side);
_emptyReduceLimitOrders(_pmAddress, _trader);
// if current position is long (_quantity >0) then liquidate order is short
bool _liquidateOrderIsBuy = _quantity > 0 ? false : true;
// call directly to position manager to skip check enough liquidity
_positionManager.openMarketPosition(_quantity.abs(), _liquidateOrderIsBuy);
positionResp.exchangedQuoteAssetAmount = _quantity
.getExchangedQuoteAssetAmount(
_oldPosition.openNotional,
Expand Down
16 changes: 14 additions & 2 deletions contracts/protocol/PositionHouseViewer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {Int256Math} from "./libraries/helpers/Int256Math.sol";

contract PositionHouseViewer is Initializable, OwnableUpgradeable {
using Int256Math for int256;
using Quantity for int256;
using Position for Position.Data;
IPositionHouse public positionHouse;
IPositionHouseConfigurationProxy public positionHouseConfigurationProxy;
function initialize(IPositionHouse _positionHouse, IPositionHouseConfigurationProxy _positionHouseConfigurationProxy) public initializer {
Expand Down Expand Up @@ -91,7 +93,7 @@ contract PositionHouseViewer is Initializable, OwnableUpgradeable {
(
uint256 maintenanceMargin,
int256 marginBalance,

,
) = getMaintenanceDetail(_positionManager, _trader, PositionHouseStorage.PnlCalcOption.TWAP);
int256 _remainingMargin = marginBalance - int256(maintenanceMargin);
return
Expand All @@ -112,7 +114,8 @@ contract PositionHouseViewer is Initializable, OwnableUpgradeable {
returns (
uint256 maintenanceMargin,
int256 marginBalance,
uint256 marginRatio
uint256 marginRatio,
uint256 liquidationPrice
)
{
address _pmAddress = address(_positionManager);
Expand Down Expand Up @@ -142,6 +145,15 @@ contract PositionHouseViewer is Initializable, OwnableUpgradeable {
if (_positionDataWithManualMargin.quantity == 0) {
marginRatio = 0;
}
if (_positionDataWithManualMargin.quantity != 0)
{
(uint64 baseBasisPoint, uint64 basisPoint) = _positionManager.getBasisPointFactors();
if (_positionDataWithManualMargin.side() == Position.Side.LONG) {
liquidationPrice = (maintenanceMargin + _positionDataWithManualMargin.openNotional - _positionDataWithManualMargin.margin) * basisPoint / _positionDataWithManualMargin.quantity.abs();
} else {
liquidationPrice = (_positionDataWithManualMargin.openNotional - maintenanceMargin + _positionDataWithManualMargin.margin) * basisPoint / _positionDataWithManualMargin.quantity.abs();
}
}
}

function getPositionNotionalAndUnrealizedPnl(
Expand Down
Loading