Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLOB-1017] final settlement deleveraging step in PrepareCheckState #848

Conversation

jakob-dydx
Copy link
Contributor

This PR adds a new step in PrepareCheckState to deleverage subaccounts with open positions in final settlement markets. It does this by leveraging the new field from the liquidations daemon which contains a mapping of perpetual -> position side -> subaccount id which allows us to know which subaccounts have open positions in specific markets. We re-use the MaxDeleveragingAttemptsPerBlock clob flag to limit the number of attempts. The regular liquidations/deleveraging flow now returns a total number of deleveraging attempts so we don't go over the limit.

Note: this PR needs to be updated once the liquidations daemon actually outputs this information. Right now a placeholder variable of the expected type has been used and initialized to be empty.

Copy link

linear bot commented Dec 6, 2023

Copy link
Contributor

coderabbitai bot commented Dec 6, 2023

Important

Auto Review Skipped

Auto reviews are disabled on base/target branches other than the default branch. Please add the base/target branch pattern to the list of additional branches to be reviewed in the settings.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository.

To trigger a single review, invoke the @coderabbitai review command.

Walkthrough

The changes across various files in the protocol primarily involve the introduction and handling of final settlement for clob pairs. This includes updates to function signatures to accommodate a new isFinalSettlement parameter, logic to handle deleveraging and liquidation in the context of final settlement, and updates to error handling and event management. Additionally, there are updates to test cases to reflect these changes and ensure correct behavior during final settlement scenarios.

Changes

File(s) Summary
protocol/x/clob/abci.go Added import for subaccounttypes, updated PrepareCheckState function to handle LiquidateSubaccountsAgainstOrderbook results, and added final settlement handling.
protocol/x/clob/keeper/deleveraging.go, protocol/x/clob/keeper/deleveraging_test.go Added error handling, early return conditions, new functions for deleveraging in final settlement markets, and updated tests.
protocol/x/clob/keeper/liquidations.go Modified LiquidateSubaccountsAgainstOrderbook function signature and introduced clobPairStatuses map.
protocol/x/clob/keeper/process_operations.go Added final settlement verification and adjustments to deleveraging fills processing.
protocol/x/clob/types/errors.go Introduced new error ErrFinalSettlementDeleveragingMatchForActiveMarket.
protocol/indexer/events/deleveraging.go, protocol/indexer/events/deleveraging_test.go Added isFinalSettlement parameter to NewDeleveragingEvent function and updated tests.
protocol/testutil/constants/clob_pair.go Added new variable ClobPair_Btc_Final_Settlement.
proto/dydxprotocol/indexer/protocol/v1/clob.proto Updated CLOB_PAIR_STATUS_FINAL_SETTLEMENT enum behavior.
protocol/mocks/MemClob.go, protocol/mocks/MemClobKeeper.go Altered method signatures and return types, indicating logic and control flow modifications.
protocol/testutil/memclob/keeper.go Added isFinalSettlement parameter to OffsetSubaccountPerpetualPosition function.
protocol/x/clob/keeper/clob_pair.go, protocol/x/clob/keeper/clob_pair_test.go Modified logic for ClobPair status transitions and added tests for final settlement.
protocol/x/clob/keeper/final_settlement.go Added logic to forcefully cancel stateful orders and delete untriggered conditional orders for final settlement.
protocol/x/clob/memclob/memclob.go, protocol/x/clob/types/memclob.go Added isFinalSettlement parameter to method signatures.
protocol/x/clob/types/clob_pair.go, protocol/x/clob/types/clob_pair_test.go Modified state transition logic for ClobPair_Status and updated tests.
protocol/x/clob/types/internal_operation.go Added isFinalSettlement parameter to NewMatchPerpetualDeleveragingInternalOperation function.
protocol/x/clob/types/mem_clob_keeper.go Added isFinalSettlement parameter to MatchPerpetualDeleveraging method in MemClobKeeper interface.
protocol/x/clob/types/operations_to_propose.go, protocol/x/clob/types/operations_to_propose_test.go Added isFinalSettlement parameter to MustAddDeleveragingToOperationsQueue method and updated tests.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on X ?


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • You can reply to a review comment made by CodeRabbit.
  • You can tag CodeRabbit on specific lines of code or files in the PR by tagging @coderabbitai in a comment.
  • You can tag @coderabbitai in a PR comment and ask one-off questions about the PR and the codebase. Use quoted replies to pass the context for follow-up questions.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

…nt flag instead of calculating implicitly based off of clob pair status, and update indexer deleveraging event so we can send isFinalSettlement flag
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 073f8f6 and e37c37f.
Files selected for processing (5)
  • protocol/indexer/events/deleveraging.go (1 hunks)
  • protocol/indexer/events/deleveraging_test.go (2 hunks)
  • protocol/x/clob/keeper/deleveraging.go (8 hunks)
  • protocol/x/clob/keeper/deleveraging_test.go (4 hunks)
  • protocol/x/clob/keeper/process_operations.go (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • protocol/x/clob/keeper/process_operations.go
Additional comments: 11
protocol/indexer/events/deleveraging.go (1)
  • 14-29: The addition of the isFinalSettlement parameter to the NewDeleveragingEvent function is consistent with the PR objectives and the AI-generated summaries. This parameter will allow the function to handle events related to final settlement markets, which is a new feature being introduced.
protocol/indexer/events/deleveraging_test.go (2)
  • 3-10: The order of import statements has been altered. Ensure this change aligns with the project's import ordering conventions.

  • 27-33: The addition of the false argument to the NewDeleveragingEvent function call aligns with the PR's objective to handle subaccounts in final settlement markets. Confirm that this value is appropriate for the test scenario.

protocol/x/clob/keeper/deleveraging.go (4)
  • 35-52: The logic to allow deleveraging for markets in final settlement even for subaccounts with non-negative TNC is consistent with the PR objectives. This change ensures that subaccounts can be deleveraged in a specific scenario, which is an important aspect of the new feature being introduced.

  • 272-308: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [238-305]

The updated logic in OffsetSubaccountPerpetualPosition to handle final settlement deleveraging by fetching delta quote quantums at the oracle price for final settlement markets is consistent with the PR objectives. The addition of the isFinalSettlement flag to the NewDeleveragingEvent function call ensures that the correct price is used for the deleveraging operation.

  • 366-393: The changes to getDeleveragingQuoteQuantumsDelta to return an additional boolean indicating if the deleveraging is for a final settlement market are crucial for the correct calculation of the quote quantums delta. This allows the system to use the oracle price for final settlement deleveraging, aligning with the PR objectives.

  • 535-577: The addition of DeleverageSubaccountsInFinalSettlementMarkets is a significant change that directly addresses the PR's objective to deleverage subaccounts in final settlement markets. This function ensures that the deleveraging process is correctly applied to both negative and non-negative TNC subaccounts, using the appropriate price based on the market's status.

protocol/x/clob/keeper/deleveraging_test.go (4)
  • 711-717: The changes from lines 711 to 717 add a new parameter false to the NewDeleveragingEvent function calls. This aligns with the PR objectives to handle new conditions for deleveraging subaccounts in final settlement markets. Ensure that the false parameter correctly represents the expected behavior in the context of these tests.

  • 1127-1133: The changes from lines 1127 to 1133 also add the false parameter to the NewDeleveragingEvent function calls. Similar to the previous comment, verify that this parameter is correctly representing the expected behavior in the context of the test cases.

  • 1336-1342: The changes from lines 1336 to 1342 follow the same pattern as the previous comments, adding the false parameter to the NewDeleveragingEvent function calls. Confirm that this parameter accurately reflects the intended test conditions.

  • 1496-1502: The changes from lines 1496 to 1502 again introduce the false parameter to the NewDeleveragingEvent function calls within the test cases. As with the other instances, ensure that this parameter is appropriate for the test scenarios being executed.

return 0, err
}

// Skip liquidation if the ClobPair for the liquidation order is in final settlement. There is a separate flow
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We skip attempting to place the liquidation if the market is in final settlement, as liquidation matches are not allowed in closed markets. We do append the order to unfilledLiquidations so that the deleveraging flow may naturally pick up negative TNC subaccounts in the market and deleverage them as part of the standard deleveraging flow

Copy link
Contributor

@lucas-dydx lucas-dydx Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not pick another perpetual ID to liquidate?

What if the subaccount is liquidatable but has multiple positions? Closing their open but final settled position at the oracle price won't change their collateralization, so IMO could make sense to just liquidate another position

However I could see us leaning towards the simplest approach and just waiting another block since I think it picks a random position to liquidate. Also I guess this logic is necessary to trigger the deleveraging flow

Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah admittedly was going for simplicity here. Picking a new position to liquidate would mean introducing a new flow here where we selectively re-generate liquidation orders depending on clob pair status and I just don't think that is worth it for now. If you feel strongly, we could implement this later but for now I think this is fine

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 1b9d06b and 22328c7.
Files selected for processing (2)
  • protocol/x/clob/keeper/liquidations.go (8 hunks)
  • protocol/x/clob/keeper/process_operations.go (3 hunks)
Additional comments: 8
protocol/x/clob/keeper/liquidations.go (6)
  • 24-30: The changes to the function signature and the introduction of numDeleveragingAttempts are consistent with the PR objectives to track the number of deleveraging attempts within a block.

  • 35-39: The early return when there are no subaccounts to liquidate is a good practice for performance optimization.

  • 68-74: Proper error handling is implemented for the case where a subaccount is not liquidatable, and unexpected errors are correctly returned, halting the process.

  • 106-123: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [94-117]

The introduction of clobPairStatuses to track the status of ClobPair and skip liquidation for pairs in final settlement status aligns with the PR objectives to handle subaccounts in final settlement markets.

  • 127-133: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [123-130]

The error handling and logging for failed liquidation attempts are correctly implemented, ensuring that issues are logged and the function returns early in case of an error.

  • 158-175: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [145-171]

The loop correctly implements the logic to attempt deleveraging for unfilled liquidations, respecting the MaxDeleveragingAttemptsPerBlock limit, which is consistent with the PR objectives.

protocol/x/clob/keeper/process_operations.go (2)
  • 678-692: The changes from lines 678 to 692 handle the calculation of deltaQuoteQuantums differently depending on whether the match is a final settlement. This is consistent with the PR objectives and ensures that the correct calculation method is used based on the match type.

  • 715-732: The changes from lines 715 to 732 correctly emit an on-chain update for the deleveraging event. The use of TransientStore ensures that the events are rolled back if the branched state is discarded, which is a good practice for blockchain state management.

protocol/x/clob/keeper/process_operations.go Outdated Show resolved Hide resolved
@@ -499,23 +529,50 @@ func (k Keeper) ProcessDeleveraging(
),
)

// Send on-chain update for the deleveraging. The events are stored in a TransientStore which should be rolled-back
// if the branched state is discarded, so batching is not necessary.
k.GetIndexerEventManager().AddTxnEvent(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled this onchain event out of ProcessDeleveraging so that we can easily set the isFinalSettlement flag on the event. This information is not known to the ProcessDeleveraging function.

This is similar to how ProcessSingleMatch works, the caller of the function is responsible for emitting the event instead of the event being in ProcessSingleMatch. This allows us to treat these "Process" functions solely as state-updating functions. Their callers are responsible for generating events.

protocol/x/clob/abci.go Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0418a25 and 9bde41c.
Files selected for processing (3)
  • protocol/x/clob/abci.go (2 hunks)
  • protocol/x/clob/keeper/process_operations.go (3 hunks)
  • protocol/x/clob/types/errors.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • protocol/x/clob/keeper/process_operations.go
Additional comments: 3
protocol/x/clob/abci.go (2)
  • 14-17: The addition of the satypes import aligns with the changes made in the PrepareCheckState function.

  • 199-211: The changes to PrepareCheckState function correctly implement the new step for deleveraging subaccounts with open positions in final settlement markets, as described in the PR objectives and the summary.

protocol/x/clob/types/errors.go (1)
  • 311-314: The addition of ErrInvalidFinalSettlementDeleveragingMatch with code 1021 correctly implements the new error handling logic as described in the PR objectives and the AI-generated summaries.

protocol/x/clob/abci.go Show resolved Hide resolved
@@ -25,6 +26,15 @@ func (server *Server) WithDaemonLiquidationInfo(
return server
}

// SetSubaccountOpenPositions stores the list of subaccount open positions in a go-routine safe map.
// Placeholder to allow for testing.
func (s *Server) SetSubaccountOpenPositions(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jayy04 I've added this as a placeholder so I can modify this datastructure for testing. I imagine there will be a new function created for this in one of your PRs

Comment on lines 125 to 128
subaccountsToDeleverage = append(subaccountsToDeleverage, subaccountToDeleverage{
SubaccountId: liquidationOrder.GetSubaccountId(),
PerpetualId: liquidationOrder.MustGetLiquidatedPerpetualId(),
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to append here, right? since this is going to get picked up by GetSubaccountsWithOpenPositionsInFinalSettlementMarkets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my motivation in still appending here is that this negative TNC deleveraging attempt will occur earlier if I append it here rather than wait for the other function to pick it up. It's more important that we deleverage negative TNC subaccounts than it is that we do the final settlement deleveraging for non-negative TNC subaccounts

subaccountIds := daemonLiquidationInfo.GetLiquidatableSubaccountIds()
if err := keeper.LiquidateSubaccountsAgainstOrderbook(ctx, subaccountIds); err != nil {
liquidatableSubaccountIds := daemonLiquidationInfo.GetLiquidatableSubaccountIds()
subaccountsToDeleverage, err := keeper.LiquidateSubaccountsAgainstOrderbook(ctx, liquidatableSubaccountIds)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking about this more - subaccountsToDeleverage here should mostly contain subaccounts with unfilled liquidations and need to be deleveraged at bankruptcy price (-ve TNC), right?

we do have DaemonLiquidationInfo.NegativeTncSubaccounts, maybe we can just use that? this will de-couple step 6&7 completely. wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it does contain -ve TNC subaccounts, paired with a perpetual id that we tried to liquidate with. I think it probably makes sense to use DaemonLiquidationInfo.NegativeTncSubaccounts as you suggested. Unsure if we want to deleverage using the same perpetual we tried to liquidate with though, if so we would need to add some extra logic for that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe we can do this in a separate PR. no need to block on this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe create a ticket and add a TODO?

Comment on lines 167 to 168
// Can deleverage subaccount if net collateral is negative or if the market is in final settlement.
canDeleverageSubaccount = bigNetCollateral.Sign() == -1 || clobPair.Status == types.ClobPair_STATUS_FINAL_SETTLEMENT
Copy link
Contributor

@jayy04 jayy04 Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe move this to above k.GetClobPairIdForPerpetual. this save us 1 state read if TNC < 0.

also curious to get your thoughts on making these two bools mutually exclusive. something like shouldDeleverageAtBankruptcyPrice and shouldDeleverageAtOraclePrice. I think it improves code readability slightly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, not a bad idea

protocol/x/clob/keeper/deleveraging.go Outdated Show resolved Hide resolved
protocol/x/clob/keeper/deleveraging.go Outdated Show resolved Hide resolved
protocol/x/clob/keeper/deleveraging.go Outdated Show resolved Hide resolved
protocol/x/clob/keeper/liquidations.go Show resolved Hide resolved
protocol/x/clob/keeper/liquidations.go Outdated Show resolved Hide resolved
protocol/x/clob/keeper/deleveraging.go Show resolved Hide resolved
protocol/x/clob/keeper/liquidations.go Show resolved Hide resolved
protocol/x/clob/keeper/process_operations.go Outdated Show resolved Hide resolved
protocol/x/clob/keeper/process_operations.go Show resolved Hide resolved
protocol/x/clob/types/errors.go Outdated Show resolved Hide resolved
@jakob-dydx jakob-dydx changed the title [CLOB-1017][WIP] - final settlement deleveraging step in PrepareCheckState [CLOB-1017] final settlement deleveraging step in PrepareCheckState Dec 19, 2023
jakob-dydx and others added 2 commits December 19, 2023 15:55
)

* add missing indexer constants

* update proto formatting

* fix indexer test

* set up ground work for allowing only deleveraging events for final settlement markets

* test trading is blocked in process proposer operations for final settlement

* update comments

* add DeliverTx tests for process operations final settlement deleveraging operations

* pr nits

* nit
@jakob-dydx jakob-dydx merged commit 5dd3bae into jakob-dydx/final-settlement-endblocker Dec 20, 2023
14 of 16 checks passed
@jakob-dydx jakob-dydx deleted the jakob-dydx/final-settlement-pcs branch December 20, 2023 20:28
jakob-dydx added a commit that referenced this pull request Dec 22, 2023
…#829)

* add protos for final settlement clob pair status and final settlement removal reason

* implement cancellation of open stateful orders for final settlement clob pairs upon acceptance of gov proposal

* format

* pr nits

* pr nits

* [CLOB-1010] final settlement checktx validation (#842)

* checktx logic to reject order placements for final settlement markets

* fix test with incorrect order

* [CLOB-1017]  final settlement deleveraging step in PrepareCheckState (#848)

* add functionality in ProcessDeleveraging to allow settlement at oracle price instead of bankruptcy price

* pull deltaQuoteQuantums out of ProcessDeleveraging

* fix lint

* fix issue with test

* pr nits

* update getDeleveragingQuoteQuantumsDelta helper

* initial implementation of final settlement deleveraging

* add delivertx logic for deleveraging match

* update to have DeliverTx calculate price based off of IsFinalSettlement flag instead of calculating implicitly based off of clob pair status, and update indexer deleveraging event so we can send isFinalSettlement flag

* update delivertx validation

* allow final settlement subaccounts to be deleveraged by regular deleveraging flow

* remove superfluous comment

* update err name

* fix import formatting

* lint

* begin adding tests

* update logic so that isFinalSettlement flag on operation is used

* re-use helper function

* pr nits, redefine CanDeleverageSubaccount

* update tests for CanDeleverageSubaccount

* split up PCS steps 6 and 7 to be for liquidations and then for deleveraging

* update to use new subaccountOpenPositionInfo type

* update tests

* pr nits

* lint

* formatting

* nits and tests

* more nits and comment updates

* [CLOB-1021] final settlement DeliverTx validation to block trading (#834)

* add missing indexer constants

* update proto formatting

* fix indexer test

* set up ground work for allowing only deleveraging events for final settlement markets

* test trading is blocked in process proposer operations for final settlement

* update comments

* add DeliverTx tests for process operations final settlement deleveraging operations

* pr nits

* nit

* merge from upstream

* format

* update test to verify transitions from a status to itself is accepted

* fix defer statement with latency metric

* pr nits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

3 participants