diff --git a/core/execution/common/errors.go b/core/execution/common/errors.go index 7e869e67eec..e202782614e 100644 --- a/core/execution/common/errors.go +++ b/core/execution/common/errors.go @@ -86,4 +86,6 @@ var ( ErrAMMCannotRebase = errors.New("not enough liquidity for AMM to rebase") // ErrInvalidOrderPrice is returned when an order is submitted to a capped future with a price > max price. ErrInvalidOrderPrice = errors.New("invalid order price") + // ErrIsolatedMarginFullyCollateralised is returned when a party tries to switch margin modes on a fully collateralised market. + ErrIsolatedMarginFullyCollateralised = errors.New("isolated margin not permitted on fully collateralised markets") ) diff --git a/core/execution/future/market.go b/core/execution/future/market.go index 6dee05e69fe..d8cc5321171 100644 --- a/core/execution/future/market.go +++ b/core/execution/future/market.go @@ -4990,6 +4990,9 @@ func (m *Market) GetRiskFactors() *types.RiskFactor { } func (m *Market) UpdateMarginMode(ctx context.Context, party string, marginMode types.MarginMode, marginFactor num.Decimal) error { + if m.fCap != nil && m.fCap.FullyCollateralised { + return common.ErrIsolatedMarginFullyCollateralised + } if err := m.switchMarginMode(ctx, party, marginMode, marginFactor); err != nil { return err } diff --git a/core/integration/features/capped-futures/0016-PFUT-021.feature b/core/integration/features/capped-futures/0016-PFUT-021.feature index c04ce58fd0c..268cf8d1893 100644 --- a/core/integration/features/capped-futures/0016-PFUT-021.feature +++ b/core/integration/features/capped-futures/0016-PFUT-021.feature @@ -93,9 +93,13 @@ Feature: When `max_price` is specified and the market is ran in a fully-collater # aux1: position * 1100 + 999*2 = 1100 + 1998 = 3098 # aux2: then placing the order (max price - average order price) * 3 = (1500 - (1301 + 1301 + 1100)/3) * 3 = (1500 - 1234) * 3 = 266 * 3 = 798 # aux2's short position and potential margins are calculated separately as 2 * (1500-1301) + 1 * (1500 - 1100) = 398 + 400 = 798 - Then the parties should have the following account balances: + And the parties should have the following account balances: | party | asset | market id | margin | general | | party1 | USD | ETH/DEC21 | 5000 | 5500 | | party2 | USD | ETH/DEC21 | 2500 | 7000 | | aux1 | USD | ETH/DEC21 | 3098 | 96908 | | aux2 | USD | ETH/DEC21 | 798 | 99174 | + # The market is fully collateralised, switching to isolated margin is not supported + When the parties submit update margin mode: + | party | market | margin_mode | margin_factor | error | + | party1 | ETH/DEC21 | isolated margin | 0.5 | isolated margin not permitted on fully collateralised markets |