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

Clean up open-interest liquidity tier calculations #1592

Merged
merged 3 commits into from
May 29, 2024

Conversation

BrendanChou
Copy link
Contributor

@BrendanChou BrendanChou commented May 28, 2024

Changelist

Since IMF due to open-interest is calculated a lot, simplify the code paths, make them more testable, benchmark them, and improve performance by not using big.Rat.

Note, this is a (slightly) breaking change as the adjusted IMF is now calculated as a ppm before applying. This is generally fine to round the initial margin requirement to the nearest ppm value (as the base IMF is already in ppm). When multiplying the value by the notional value of the position, the margin requirement is already rounded up.

Test Plan

Added benchmarks and additional tests.

Summary by CodeRabbit

  • New Features

    • Introduced benchmark testing for margin requirement calculations to ensure performance under various scenarios.
  • Refactor

    • Updated margin requirement calculations to improve accuracy and alignment with open interest caps.
  • Bug Fixes

    • Enhanced test cases for margin requirements to ensure correct variable usage and values.
  • Chores

    • Improved naming conventions for better code clarity and maintainability.

Copy link
Contributor

coderabbitai bot commented May 28, 2024

Walkthrough

The updates primarily focus on refining margin requirements calculations and enhancing test coverage in the perpetuals module. Key changes include variable name updates, refactoring margin calculation logic, adding benchmarks, and improving subaccount management tests.

Changes

File Path Change Summary
protocol/x/perpetuals/keeper/perpetual_test.go Updated variable names and values in test cases related to margin requirements calculations.
protocol/x/perpetuals/types/liquidity_tier.go Refactored GetInitialMarginQuoteQuantums function and added GetAdjustedInitialMarginPpm function.
protocol/x/perpetuals/types/liquidity_tier_test.go Added benchmark function BenchmarkGetInitialMarginQuoteQuantums to test margin calculation logic.
protocol/x/subaccounts/keeper/subaccount_test.go Updated tests for isolated subaccounts, position management, and conditions for withdrawals and transfers.

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 your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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 an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @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.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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.

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 50919ec and 315515e.
Files selected for processing (1)
  • protocol/x/perpetuals/types/liquidity_tier_test.go (1 hunks)
Additional Context Used
Path-based Instructions (1)
protocol/x/perpetuals/types/liquidity_tier_test.go (1)

Pattern **/**: Do not include a walkthrough. For all comments on line changes that are longer than 15 lines, add a prefix to the comment of what lines you are commenting on (for example: "The changes from lines 100 to 200...". Add your comment to be on the last 15 lines of the chunk rather than adding your comment to the entire chunk.

Additional comments not posted (1)
protocol/x/perpetuals/types/liquidity_tier_test.go (1)

222-242: The benchmark function BenchmarkGetInitialMarginQuoteQuantums is well-structured and effectively tests the performance of GetInitialMarginQuoteQuantums under various open interest values.

Comment on lines +693 to +694
bigExpectedInitialMargin *big.Int
bigExpectedMaintenanceMargin *big.Int
Copy link
Contributor Author

Choose a reason for hiding this comment

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

these are not ppm values, they are in quantums, so I renamed them

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.

Actionable comments posted: 0

Outside diff range and nitpick comments (5)
protocol/x/perpetuals/types/liquidity_tier.go (1)

Line range hint 89-140: Consider replacing the panic with a more graceful error handling mechanism to improve robustness.

- panic(fmt.Sprintf("invalid open interest values for liquidity tier %d", liquidityTier.Id))
+ return nil, fmt.Errorf("invalid open interest values for liquidity tier %d", liquidityTier.Id)

Other than that, the implementation of GetAdjustedInitialMarginPpm is robust and aligns with the PR objectives.

protocol/x/perpetuals/keeper/perpetual_test.go (4)

Line range hint 10-100: Ensure proper cleanup and teardown in tests to prevent state leakage between tests.

Consider adding t.Cleanup() to ensure that any setup done in your tests is properly cleaned up afterwards. This is especially important in a testing environment where multiple tests are run in sequence and may share the same context or resources.


Line range hint 101-200: Consider parameterizing tests for better coverage and maintainability.

Using table-driven tests can help make your tests more organized and easier to extend. For example, you can define a struct for test cases that includes inputs and the expected output, and then range over a slice of these test cases.


Line range hint 201-300: Enhance error messages for better debugging and user feedback.

When checking for errors in your tests, consider including more descriptive messages that explain what the test was checking for. This can help quickly identify what went wrong without needing to dig through the test code.


Line range hint 401-500: Optimize data retrieval and sorting mechanisms for efficiency.

Consider optimizing the retrieval and sorting of liquidity tiers, especially if the number of tiers can be large. Efficient sorting algorithms or database queries can significantly improve the performance of this functionality.

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 315515e and 6ce712e.
Files selected for processing (3)
  • protocol/x/perpetuals/keeper/perpetual_test.go (13 hunks)
  • protocol/x/perpetuals/types/liquidity_tier.go (2 hunks)
  • protocol/x/perpetuals/types/liquidity_tier_test.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • protocol/x/perpetuals/types/liquidity_tier_test.go
Additional Context Used
Path-based Instructions (2)
protocol/x/perpetuals/types/liquidity_tier.go (1)

Pattern **/**: Do not include a walkthrough. For all comments on line changes that are longer than 15 lines, add a prefix to the comment of what lines you are commenting on (for example: "The changes from lines 100 to 200...". Add your comment to be on the last 15 lines of the chunk rather than adding your comment to the entire chunk.

protocol/x/perpetuals/keeper/perpetual_test.go (1)

Pattern **/**: Do not include a walkthrough. For all comments on line changes that are longer than 15 lines, add a prefix to the comment of what lines you are commenting on (for example: "The changes from lines 100 to 200...". Add your comment to be on the last 15 lines of the chunk rather than adding your comment to the entire chunk.

Additional comments not posted (2)
protocol/x/perpetuals/types/liquidity_tier.go (1)

76-87: LGTM! The refactoring of GetInitialMarginQuoteQuantums enhances clarity and testability by using GetAdjustedInitialMarginPpm.

protocol/x/perpetuals/keeper/perpetual_test.go (1)

Line range hint 301-400: Verify the use of mocks to ensure they are correctly simulating the external dependencies.

Ensure that the mocks used in your tests accurately represent the behavior of the external dependencies they are meant to simulate. This is crucial for ensuring that your tests are valid and that they accurately reflect the behavior of your system under test.

),
)
// If `open_interest` >= `open_interest_upper_cap` where `upper_cap` is non-zero, OIMF is 1.
if oiCapUpper.Sign() > 0 && oiQuoteQuantums.Cmp(oiCapUpper) >= 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: oiCapUpper.Sign() > 0 is an invariant here since we know oiCapUpper is non-negative (from uint64) and not equal to 0 from above.

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 I agree and was considering removing it, but I explicitly added it here in case code gets moved around later, or the check above gets removed or something

protocol/x/perpetuals/types/liquidity_tier.go Outdated Show resolved Hide resolved
@@ -219,6 +219,28 @@ func TestLiquidityTierGetMaxAbsFundingClampPpm(t *testing.T) {
}
}

func BenchmarkGetInitialMarginQuoteQuantums(b *testing.B) {
Copy link
Contributor

Choose a reason for hiding this comment

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

On darwin/arm64 for reference:
Before

BenchmarkGetInitialMarginQuoteQuantums-10    	 1322443	       907.5 ns/op	     832 B/op	      44 allocs/op

After

BenchmarkGetInitialMarginQuoteQuantums-10    	 2147283	       573.7 ns/op	     600 B/op	      28 allocs/op

Perhaps in the future we can add some workflow that compare these benchmarks on linux/amd64?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a workflow to run on amd64 that runs in CI. I added it, but currently only runs on changes to protocol/lib/. I can change it to run on any changes to protocol/. I'm not very worried about negative impact on performance in this PR given that it's significantly better on arm64 but will be good to keep and eye on in the future

// Total IMF.
capScalePpm := lib.BigU(lib.OneMillion - liquidityTier.InitialMarginPpm)
result := new(big.Int).Mul(capScalePpm, capNum)
result.Div(result, capDen)
Copy link
Contributor

Choose a reason for hiding this comment

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

This rounds towards zero right? Should we always round more conservatively (towards positive infinity) when calculating margin requirements? Think this is why (OIMF) match collateralized at base IMF and just failed collateralization at OIMF unit test is failing

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 should always round conservatively when doing the final calculation (imfPpm to quoteQuantums), but rounding conservatively in the case of increased ppm from OI doesn't seem entirely necessary to me.

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.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
protocol/x/perpetuals/types/liquidity_tier.go (1)

Line range hint 89-140: The GetAdjustedInitialMarginPpm function is well-implemented with comprehensive checks for different scenarios of open interest. Consider enhancing the comments to clarify the calculation steps for better maintainability.

// - Define
//   - `Open Notional = Open Interest * Oracle Price`
//   - `Scaling Factor = (Open Notional - Lower Cap) / (Upper Cap - Lower Cap)`
//   - `IMF Increase = Scaling Factor * (1 - Base IMF)`
//   - Then a market’s `Effective IMF = Min(Base IMF + Max(IMF Increase, 0), 1.0)`
+ // These steps calculate the effective IMF based on the scaling factor and the base IMF, adjusting as the open interest moves between the defined caps.
Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 6ce712e and 62fdc9d.
Files selected for processing (3)
  • .github/workflows/protocol-benchmark.yml (1 hunks)
  • protocol/x/perpetuals/types/liquidity_tier.go (2 hunks)
  • protocol/x/subaccounts/keeper/subaccount_test.go (23 hunks)
Files skipped from review due to trivial changes (2)
  • .github/workflows/protocol-benchmark.yml
  • protocol/x/subaccounts/keeper/subaccount_test.go
Additional Context Used
Path-based Instructions (1)
protocol/x/perpetuals/types/liquidity_tier.go (1)

Pattern **/**: Do not include a walkthrough. For all comments on line changes that are longer than 15 lines, add a prefix to the comment of what lines you are commenting on (for example: "The changes from lines 100 to 200...". Add your comment to be on the last 15 lines of the chunk rather than adding your comment to the entire chunk.

Additional comments not posted (2)
protocol/x/perpetuals/types/liquidity_tier.go (2)

76-87: The implementation of GetInitialMarginQuoteQuantums correctly calculates the initial margin requirement using the adjusted PPM value and rounds up the result, aligning with conservative financial practices.


Line range hint 9-34: The Validate function effectively ensures that all properties of a LiquidityTier are within defined limits, using clear and specific error messages for each type of validation failure.

@BrendanChou BrendanChou merged commit df00d84 into main May 29, 2024
17 of 18 checks passed
@BrendanChou BrendanChou deleted the bc/clean/liquidity-tier branch May 29, 2024 18:37
mergify bot pushed a commit that referenced this pull request Jun 27, 2024
(cherry picked from commit df00d84)

# Conflicts:
#	.github/workflows/protocol-benchmark.yml
teddyding pushed a commit that referenced this pull request Jun 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants