Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions contracts/interfaces/IInsuranceFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ interface IInsuranceFund {
address trader,
uint256 amountFee
) external;

function clearBonus(address _positionManager, address _trader) external;
}
37 changes: 17 additions & 20 deletions contracts/protocol/InsuranceFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ contract InsuranceFund is
}

if (depositedBonusAmount > 0) {
busdBonusBalances[_trader][_positionManager] += depositedBonusAmount;
busdBonusBalances[_positionManager][_trader] += depositedBonusAmount;
}

busdAmount = collectableBUSDAmount;
Expand All @@ -133,10 +133,11 @@ contract InsuranceFund is
IPositionManager(_positionManager).getQuoteAsset()
);

if (acceptBonus) {
uint256 bonusBalance = busdBonusBalances[_trader][_positionManager];
if (acceptBonus && _oldMargin > 0) {
uint256 bonusBalance = busdBonusBalances[_positionManager][_trader];
if (bonusBalance > 0) {
uint256 oldBUSDBalance = _oldMargin - bonusBalance;
uint256 withdrawMargin = uint256(int256(_amount) - _pnl);

(
uint256 withdrawBUSDAmount,
Expand All @@ -152,14 +153,16 @@ contract InsuranceFund is
: calcAmountWhenMarginOnlyHaveBonus(
_amount,
bonusBalance,
_pnl
_pnl,
withdrawMargin
);

if (withdrawBonusAmount > 0) {
busdBonus.safeTransfer(_trader, withdrawBonusAmount);
}

busdBonusBalances[_trader][_positionManager] = remainingBonusAmount;
// If withdraw all margin, clear bonus
busdBonusBalances[_positionManager][_trader] = withdrawMargin == _oldMargin ? 0 : remainingBonusAmount;

_amount = withdrawBUSDAmount;
if (_amount == 0) {
Expand Down Expand Up @@ -194,16 +197,9 @@ contract InsuranceFund is

function clearBonus(
address _positionManager,
address _trader,
uint256 _amount
) public onlyCounterParty {
// Use when liquidated
if (busdBonusBalances[_trader][_positionManager] > _amount) {
busdBonusBalances[_trader][_positionManager] -= _amount;
return;
}

busdBonusBalances[_trader][_positionManager] = 0;
address _trader
) external onlyCounterParty {
busdBonusBalances[_positionManager][_trader] = 0;
emit BonusBalanceCleared(_positionManager, _trader);
}

Expand Down Expand Up @@ -350,7 +346,8 @@ contract InsuranceFund is
function calcAmountWhenMarginOnlyHaveBonus(
uint256 _withdrawAmount,
uint256 _bonusBalance,
int256 _pnl
int256 _pnl,
uint256 _withdrawMargin
)
private
view
Expand All @@ -364,11 +361,10 @@ contract InsuranceFund is
* If PnL >= 0, return PnL in BUSD and requested withdraw margin in bonus
* If Pnl < 0, only return requested withdraw amount in bonus
*/
uint256 withdrawMargin = uint256(int256(_withdrawAmount) - _pnl);
return
_pnl >= 0
? (uint256(_pnl), withdrawMargin, _bonusBalance - withdrawMargin)
: (0, _withdrawAmount, _bonusBalance - withdrawMargin);
? (uint256(_pnl), _withdrawMargin, _bonusBalance - _withdrawMargin)
: (0, _withdrawAmount, _bonusBalance - _withdrawMargin);
}

function calcAmountWhenMarginHaveBUSD(
Expand Down Expand Up @@ -427,7 +423,8 @@ contract InsuranceFund is
*/
uint256[49] private __gap;
IERC20Upgradeable public busdBonus;
// Trader => (PositionManager => (BonusBalance))
// PositionManager => (Trader => (BonusBalance))
mapping(address => mapping(address => uint256)) public busdBonusBalances;
bool public acceptBonus;
mapping(address => mapping(address => uint256)) public busdBalances;
}
63 changes: 42 additions & 21 deletions contracts/protocol/bases/PositionHouseBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,20 @@ contract PositionHouseBase is
nonReentrant
onlyPositionStrategyOrder
{
address _pmAddress = address(_positionManager);
Position.Data memory _positionDataWithManualMargin = getPositionWithManualMargin(_pmAddress, _trader, getPosition(_pmAddress, _trader));
_internalCancelAllPendingOrder(_positionManager, _trader);
// must reuse this code instead of using function _internalCloseMarketPosition
_internalOpenMarketPosition(
_positionManager,
_positionDataWithManualMargin.quantity > 0
? Position.Side.SHORT
: Position.Side.LONG,
_positionDataWithManualMargin.quantity.abs(),
_positionDataWithManualMargin.leverage,
_positionDataWithManualMargin,
_trader
);
// address _pmAddress = address(_positionManager);
// Position.Data memory _positionDataWithManualMargin = getPositionWithManualMargin(_pmAddress, _trader, getPosition(_pmAddress, _trader));
// _internalCancelAllPendingOrder(_positionManager, _trader);
//// must reuse this code instead of using function _internalCloseMarketPosition
// _internalOpenMarketPosition(
// _positionManager,
// _positionDataWithManualMargin.quantity > 0
// ? Position.Side.SHORT
// : Position.Side.LONG,
// _positionDataWithManualMargin.quantity.abs(),
// _positionDataWithManualMargin.leverage,
// _positionDataWithManualMargin,
// _trader
// );
}

function _internalCloseMarketPosition(address _pmAddress, address _trader, uint256 _quantity) internal {
Expand Down Expand Up @@ -263,10 +263,11 @@ contract PositionHouseBase is
_positionData
);
}
uint256 oldMargin = _positionData.margin;
clearPosition(_pmAddress, _trader);
int256 totalClaimableAmount = _claimableMargin + _claimablePnl;
if (_claimableMargin + _claimablePnl > 0) {
_withdraw(_pmAddress, _trader, totalClaimableAmount.abs(), _claimableMargin.abs(), _claimablePnl);
_withdraw(_pmAddress, _trader, totalClaimableAmount.abs(), uint256(_claimableMargin), _claimablePnl);
// emit FundClaimed(_pmAddress, _trader, totalRealizedPnl.abs());
}
}
Expand Down Expand Up @@ -326,6 +327,7 @@ contract PositionHouseBase is
bool _liquidateOrderIsBuy = positionDataWithManualMargin.quantity > 0 ? false : true;
liquidationPenalty = positionDataWithManualMargin.margin ;
clearPosition(_pmAddress, _trader);
_clearBonus(_pmAddress, _trader);
// after clear position, create an opposite market order of old position
_positionManager.openMarketPosition(positionDataWithManualMargin.quantity.abs(), _liquidateOrderIsBuy);
feeToLiquidator =
Expand Down Expand Up @@ -360,7 +362,7 @@ contract PositionHouseBase is

_deposit(_pmAddress, _trader, _amount, 0);

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

/**
Expand All @@ -376,14 +378,14 @@ contract PositionHouseBase is
address _pmAddress = address(_positionManager);
address _trader = _msgSender();

uint256 removableMargin = getRemovableMargin(_positionManager, _trader);
require(_amount <= removableMargin, Errors.VL_INVALID_REMOVE_MARGIN);
uint256 _oldMargin = getTotalMargin(_pmAddress, _trader);
require(_amount <= getRemovableMargin(_positionManager, _trader), Errors.VL_INVALID_REMOVE_MARGIN);

manualMargin[_pmAddress][_trader] -= int256(_amount);

_withdraw(_pmAddress, _trader, _amount, _amount, 0);
_withdraw(_pmAddress, _trader, _amount, _oldMargin, 0);

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

// OWNER UPDATE VARIABLE STORAGE
Expand Down Expand Up @@ -476,6 +478,16 @@ contract PositionHouseBase is
}
}

function getTotalMargin(address _pmAddress, address _trader)
public
override
returns (uint256) {
uint256 pendingMargin = PositionHouseFunction.getTotalPendingLimitOrderMargin(IPositionManager(_pmAddress), _getLimitOrders(_pmAddress, _trader), false);
uint256 margin = getPositionWithManualMargin(_pmAddress, _trader, getPosition(_pmAddress, _trader)).margin;

return pendingMargin + margin;
}

function getPositionWithManualMargin(
address _pmAddress,
address _trader,
Expand Down Expand Up @@ -618,7 +630,8 @@ contract PositionHouseBase is
_deposit(_pmAddress, _trader, pResp.marginToVault.abs(), pResp.fee);
} else if (pResp.marginToVault < 0) {
// withdraw from vault to user
_withdraw(_pmAddress, _trader, pResp.marginToVault.abs(), oldPosition.margin, pResp.realizedPnl);
uint256 pendingMargin = PositionHouseFunction.getTotalPendingLimitOrderMargin(_positionManager, _getLimitOrders(_pmAddress, _trader), false);
_withdraw(_pmAddress, _trader, pResp.marginToVault.abs(), oldPosition.margin + pendingMargin, pResp.realizedPnl);
}
emit OpenMarket(
_trader,
Expand Down Expand Up @@ -854,6 +867,14 @@ contract PositionHouseBase is
insuranceFund.withdraw(_positionManager, _trader, _amount, _margin, _pnl);
}

function _clearBonus(
address _positionManager,
address _trader
) internal
{
insuranceFund.clearBonus(_positionManager, _trader);
}

modifier onlyPositionStrategyOrder() {
require(msg.sender == address(positionStrategyOrder), Errors.VL_ONLY_POSITION_STRATEGY_ORDER);
_;
Expand Down
17 changes: 12 additions & 5 deletions contracts/protocol/libraries/position/PositionHouseFunction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,28 @@ library PositionHouseFunction {

function getTotalPendingLimitOrderMargin(
IPositionManager _positionManager,
PositionLimitOrder.Data[] memory _limitOrder
PositionLimitOrder.Data[] memory _limitOrder,
bool shouldCancel
) external returns (uint256 totalMargin) {
for (uint i = 0; i < _limitOrder.length; i++) {
(
bool isFilled,
,
,
uint256 size,
uint256 partialFilled
) = _positionManager.getPendingOrderDetail(
_limitOrder[i].pip,
_limitOrder[i].orderId
);
if (!isFilled) {
(uint256 refundQuantity, ) = _positionManager.cancelLimitOrder(_limitOrder[i].pip, _limitOrder[i].orderId);
(, uint256 refundMargin, ) = _positionManager.getNotionalMarginAndFee(refundQuantity, _limitOrder[i].pip, _limitOrder[i].leverage);
totalMargin += refundMargin;
if (shouldCancel) {
(uint256 refundQuantity, ) = _positionManager.cancelLimitOrder(_limitOrder[i].pip, _limitOrder[i].orderId);
(, uint256 refundMargin, ) = _positionManager.getNotionalMarginAndFee(refundQuantity, _limitOrder[i].pip, _limitOrder[i].leverage);
totalMargin += refundMargin;
} else {
(, uint256 pendingMargin,) = _positionManager.getNotionalMarginAndFee(size - partialFilled, _limitOrder[i].pip, _limitOrder[i].leverage);
totalMargin += pendingMargin;
}
}
}
return totalMargin;
Expand Down
16 changes: 12 additions & 4 deletions contracts/protocol/modules/LimitOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ abstract contract LimitOrderManager is ClaimableAmountManager, PositionHouseStor
) internal {
address _trader = msg.sender;
address _pmAddress = address(_positionManager);
uint256 _oldMargin = getTotalMargin(_pmAddress, _trader);
// declare a pointer to reduceLimitOrders or limitOrders
PositionLimitOrder.Data[] storage _orders = _getLimitOrderPointer(
_pmAddress,
Expand All @@ -75,7 +76,7 @@ abstract contract LimitOrderManager is ClaimableAmountManager, PositionHouseStor
_order.pip,
_order.leverage
);
_withdraw(_pmAddress, _trader, _refundMargin, _refundMargin, 0);
_withdraw(_pmAddress, _trader, _refundMargin, _oldMargin, 0);
}
emit CancelLimitOrder(_trader, _pmAddress, _order.pip, _order.orderId);
}
Expand All @@ -86,14 +87,15 @@ abstract contract LimitOrderManager is ClaimableAmountManager, PositionHouseStor
) internal {
address _pmAddress = address(_positionManager);
PositionLimitOrder.Data[] memory _increaseOrders = limitOrders[_pmAddress][_trader];
uint256 _oldMargin = getTotalMargin(_pmAddress, _trader);
uint256 totalRefundMargin;
if (_increaseOrders.length != 0) {
totalRefundMargin = PositionHouseFunction.getTotalPendingLimitOrderMargin(_positionManager, _increaseOrders);
totalRefundMargin = PositionHouseFunction.getTotalPendingLimitOrderMargin(_positionManager, _increaseOrders, true);
}
_emptyLimitOrders(_pmAddress, _trader);
_emptyReduceLimitOrders(_pmAddress, _trader);
if (totalRefundMargin != 0) {
_withdraw(_pmAddress, _trader, totalRefundMargin, totalRefundMargin, 0);
_withdraw(_pmAddress, _trader, totalRefundMargin, _oldMargin, 0);
}
}

Expand Down Expand Up @@ -227,8 +229,9 @@ abstract contract LimitOrderManager is ClaimableAmountManager, PositionHouseStor
// if new limit order is not same side with old position, sizeOut == oldPosition.quantity
// => close all position and clear position, return sizeOut + 1 mean closed position
{
uint256 pendingMargin = PositionHouseFunction.getTotalPendingLimitOrderMargin(_positionManager, _getLimitOrders(_pmAddress, _trader), false);
(int256 totalReturn, int256 realizedPnl) = PositionHouseFunction.calcReturnWhenOpenReverse(_pmAddress, _trader, sizeOut, openNotional, oldPosition);
_withdraw(_pmAddress, _trader, totalReturn.abs(), oldPosition.margin, realizedPnl);
_withdraw(_pmAddress, _trader, totalReturn.abs(), oldPosition.margin + pendingMargin, realizedPnl);
}
if (sizeOut == oldPosition.quantity.abs()) {
clearPosition(_pmAddress, _trader);
Expand Down Expand Up @@ -415,6 +418,11 @@ abstract contract LimitOrderManager is ClaimableAmountManager, PositionHouseStor
virtual
returns (Position.Data memory);

function getTotalMargin(address _pmAddress, address _trader)
public
virtual
returns (uint256);

// function _internalClosePosition(
// IPositionManager _positionManager,
// address _trader,
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/InsurranceFundMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ contract InsuranceFundTest is InsuranceFund {
}

function setBonusBalance(address _pm, address _trader, uint256 _amount) public {
busdBonusBalances[_trader][_pm] = _amount;
busdBonusBalances[_pm][_trader] = _amount;
}
}
3 changes: 2 additions & 1 deletion deploy/ContractWrapperFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export class ContractWrapperFactory {

async createPositionManager(args: CreatePositionManagerInput) {
const PositionMathAddress = await this.db.findAddressByKey('PositionMath');
const symbol = `${args.priceFeedKey}_${args.quote}`;
// const symbol = `${args.priceFeedKey}_${args.quote}`;
const symbol = args.symbol;
const saveKey = `PositionManager:${symbol}`

const PositionManager = await this.hre.ethers.getContractFactory("PositionManager", {
Expand Down
1 change: 1 addition & 0 deletions deploy/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface CreatePositionManagerInput {
counterParty : string
leverage?: number
isCoinM?: boolean
symbol?: string
}


Expand Down
Loading