diff --git a/protocol/x/subaccounts/keeper/isolated_subaccount.go b/protocol/x/subaccounts/keeper/isolated_subaccount.go index 50798a3805..9dd3006a1c 100644 --- a/protocol/x/subaccounts/keeper/isolated_subaccount.go +++ b/protocol/x/subaccounts/keeper/isolated_subaccount.go @@ -12,6 +12,8 @@ import ( // checkIsolatedSubaccountConstaints will validate all `updates` to the relevant subaccounts against // isolated subaccount constraints. +// This function checks each update in isolation, so if multiple updates for the same subaccount id +// are passed in, they are evaluated together // The input subaccounts must be settled. // // Returns a `success` value of `true` if all updates are valid. @@ -22,7 +24,6 @@ func (k Keeper) checkIsolatedSubaccountConstraints( ctx sdk.Context, settledUpdates []settledUpdate, perpetuals []perptypes.Perpetual, - uniqueSubaccounts bool, ) ( success bool, successPerUpdate []types.UpdateResult, @@ -30,7 +31,6 @@ func (k Keeper) checkIsolatedSubaccountConstraints( ) { success = true successPerUpdate = make([]types.UpdateResult, len(settledUpdates)) - var idOfSettledUpdates = make(map[types.SubaccountId]struct{}) var perpIdToMarketType = make(map[uint32]perptypes.PerpetualMarketType) for _, perpetual := range perpetuals { @@ -38,12 +38,6 @@ func (k Keeper) checkIsolatedSubaccountConstraints( } for i, u := range settledUpdates { - if uniqueSubaccounts { - if _, exists := idOfSettledUpdates[*u.SettledSubaccount.Id]; exists { - return false, nil, types.ErrNonUniqueUpdatesSubaccount - } - } - result, err := isValidIsolatedPerpetualUpdates(u, perpIdToMarketType) if err != nil { return false, nil, err @@ -53,7 +47,6 @@ func (k Keeper) checkIsolatedSubaccountConstraints( } successPerUpdate[i] = result - idOfSettledUpdates[*u.SettledSubaccount.Id] = struct{}{} } return success, successPerUpdate, nil diff --git a/protocol/x/subaccounts/keeper/subaccount.go b/protocol/x/subaccounts/keeper/subaccount.go index 8df5cb0388..6a2e56b2c6 100644 --- a/protocol/x/subaccounts/keeper/subaccount.go +++ b/protocol/x/subaccounts/keeper/subaccount.go @@ -280,23 +280,17 @@ func (k Keeper) UpdateSubaccounts( return false, nil, err } - // Check if the updates satisfy the isolated perpetual constraints. allPerps := k.perpetualsKeeper.GetAllPerpetuals(ctx) - success, successPerUpdate, err = k.checkIsolatedSubaccountConstraints( + success, successPerUpdate, err = k.internalCanUpdateSubaccounts( ctx, settledUpdates, + updateType, allPerps, - true, // uniqueSubaccounts ) if !success || err != nil { return success, successPerUpdate, err } - success, successPerUpdate, err = k.internalCanUpdateSubaccounts(ctx, settledUpdates, updateType) - if !success || err != nil { - return success, successPerUpdate, err - } - // Get a mapping from perpetual Id to current perpetual funding index. perpIdToFundingIndex := make(map[uint32]dtypes.SerializableInt) for _, perp := range allPerps { @@ -389,19 +383,8 @@ func (k Keeper) CanUpdateSubaccounts( return false, nil, err } - // Check if the updates satisfy the isolated perpetual constraints. allPerps := k.perpetualsKeeper.GetAllPerpetuals(ctx) - success, successPerUpdate, err = k.checkIsolatedSubaccountConstraints( - ctx, - settledUpdates, - allPerps, - false, // uniqueSubaccounts - ) - if !success || err != nil { - return success, successPerUpdate, err - } - - return k.internalCanUpdateSubaccounts(ctx, settledUpdates, updateType) + return k.internalCanUpdateSubaccounts(ctx, settledUpdates, updateType, allPerps) } // getSettledSubaccount returns 1. a new settled subaccount given an unsettled subaccount, @@ -534,6 +517,7 @@ func checkPositionUpdatable( // internalCanUpdateSubaccounts will validate all `updates` to the relevant subaccounts. // The `updates` do not have to contain `Subaccounts` with unique `SubaccountIds`. +// The `updates` do not have to contain `Subaccounts` with unique `SubaccountIds`. // Each update is considered in isolation. Thus if two updates are provided // with the same `Subaccount`, they are validated without respect to each // other. @@ -547,6 +531,7 @@ func (k Keeper) internalCanUpdateSubaccounts( ctx sdk.Context, settledUpdates []settledUpdate, updateType types.UpdateType, + perpetuals []perptypes.Perpetual, ) ( success bool, successPerUpdate []types.UpdateResult, @@ -555,6 +540,19 @@ func (k Keeper) internalCanUpdateSubaccounts( success = true successPerUpdate = make([]types.UpdateResult, len(settledUpdates)) + // Check if the updates satisfy the isolated perpetual constraints. + success, successPerUpdate, err = k.checkIsolatedSubaccountConstraints( + ctx, + settledUpdates, + perpetuals, + ) + if err != nil { + return false, nil, err + } + if !success { + return success, successPerUpdate, nil + } + // Block all withdrawals and transfers if either of the following is true within the last // `WITHDRAWAL_AND_TRANSFERS_BLOCKED_AFTER_NEGATIVE_TNC_SUBACCOUNT_SEEN_BLOCKS`: // - There was a negative TNC subaccount seen.