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

[TRA-507] Add tests for UpgradeIsolatedPerpetualToCross #2583

Closed

Conversation

hwray
Copy link
Contributor

@hwray hwray commented Nov 19, 2024

Changelist

  • Add tests for UpgradeIsolatedPerpetualToCross

Test Plan

  • unit tests

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced the ability to upgrade isolated perpetual markets to cross-margin markets, enhancing market flexibility.
    • Added new message types and methods for handling insurance fund balances and transfers between isolated and cross-margin accounts.
    • Enhanced the SubaccountsKeeper interface with methods for managing insurance fund balances.
  • Bug Fixes

    • Improved error handling for authority verification and perpetual ID validation during upgrades.
  • Tests

    • Expanded test coverage for the new upgrade functionality and insurance fund balance retrieval, ensuring robust validation of edge cases.
  • Documentation

    • Updated error messages for clarity regarding market type changes and authority validations.

@hwray hwray requested a review from a team as a code owner November 19, 2024 20:17
Copy link

linear bot commented Nov 19, 2024

Copy link
Contributor

coderabbitai bot commented Nov 19, 2024

Walkthrough

The changes introduce a new method upgradeIsolatedPerpetualToCross to the Msg interface and MsgClientImpl class, allowing the upgrade of a perpetual market from isolated to cross margin. This includes new message types and response handling. Additionally, the SubaccountsKeeper field is added to various structs, enhancing functionality related to insurance fund management. Several new methods for fund transfers and balance retrieval are introduced across different keeper implementations, and corresponding tests are added to ensure functionality and error handling.

Changes

File Change Summary
indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.rpc.msg.ts Added method upgradeIsolatedPerpetualToCross and new message types MsgUpgradeIsolatedPerpetualToCross and MsgUpgradeIsolatedPerpetualToCrossResponse.
indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.ts Introduced MsgUpgradeIsolatedPerpetualToCross, MsgUpgradeIsolatedPerpetualToCrossResponse, and their SDK types.
proto/dydxprotocol/listing/tx.proto Added RPC method UpgradeIsolatedPerpetualToCross and new message types for upgrade operations.
protocol/app/app.go Added SubaccountsKeeper field to ListingKeeper struct.
protocol/app/msgs/all_msgs.go Added new message entries for MsgUpgradeIsolatedPerpetualToCross and its response.
protocol/app/msgs/internal_msgs.go Added new message types to InternalMsgSamplesDydxCustom.
protocol/app/msgs/internal_msgs_test.go No alterations to exported entities; added new message types to tests.
protocol/lib/ante/internal_msg.go Updated IsInternalMsg function to recognize new message type.
protocol/mocks/ClobKeeper.go Removed GetInsuranceFundBalance method from ClobKeeper mock.
protocol/testutil/keeper/listing.go Updated ListingKeepers and createListingKeeper functions to include new parameters.
protocol/x/clob/keeper/deleveraging.go Removed GetInsuranceFundBalance and GetCrossInsuranceFundBalance; updated balance retrieval logic.
protocol/x/clob/keeper/deleveraging_test.go Removed TestGetInsuranceFundBalance test function.
protocol/x/clob/keeper/keeper.go Added GetCrossInsuranceFundBalance method to Keeper.
protocol/x/clob/types/expected_keepers.go Added methods to SubaccountsKeeper for insurance fund balance retrieval.
protocol/x/clob/types/liquidations_keeper.go Removed GetInsuranceFundBalance method from LiquidationsKeeper interface.
protocol/x/listing/keeper/keeper.go Added SubaccountsKeeper field to Keeper.
protocol/x/listing/keeper/listing.go Introduced UpgradeIsolatedPerpetualToCross method in Keeper.
protocol/x/listing/keeper/listing_test.go Added TestUpgradeIsolatedPerpetualToCross test function and updated existing test cases.
protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross.go Added UpgradeIsolatedPerpetualToCross method for handling upgrade requests.
protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross_test.go New test function for validating MsgUpgradeIsolatedPerpetualToCross.
protocol/x/listing/types/errors.go Added new error variables for invalid authority and perpetual ID.
protocol/x/listing/types/expected_keepers.go Added new methods to SubaccountsKeeper and updated PerpetualsKeeper interface.
protocol/x/listing/types/msg_upgrade_isolated_perpetual_to_cross.go Defined MsgUpgradeIsolatedPerpetualToCross message type with validation methods.
protocol/x/perpetuals/keeper/perpetual.go Updated SetPerpetualMarketType method for improved validation logic.
protocol/x/perpetuals/keeper/perpetual_test.go Enhanced test coverage and error handling for perpetual market type modifications.
protocol/x/subaccounts/keeper/subaccount.go Added methods for retrieving insurance fund balances.
protocol/x/subaccounts/keeper/subaccount_test.go Added TestGetInsuranceFundBalance function for testing balance retrieval.
protocol/x/subaccounts/keeper/transfer.go Introduced methods for transferring funds from isolated to cross-perpetuals.
protocol/x/subaccounts/types/expected_keepers.go Added methods for asset management and balance retrieval in AssetsKeeper and BankKeeper.

Possibly related PRs

Suggested labels

pml

Suggested reviewers

  • vincentwschau
  • chenyaoy

🐰 In the meadow, changes bloom bright,
New methods and messages take flight.
From isolated to cross, we now can go,
With funds transferring, watch our markets grow!
A hop, a skip, in code we play,
Enhancing our protocol, hip-hip-hooray! 🌼


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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration 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: 1

🧹 Outside diff range and nitpick comments (24)
protocol/x/listing/types/msg_upgrade_isolated_perpetual_to_cross.go (2)

13-16: Consider adding panic recovery for better robustness.

While discarding the error is a common pattern here (as ValidateBasic handles validation), consider adding panic recovery for extra safety.

 func (msg *MsgUpgradeIsolatedPerpetualToCross) GetSigners() []sdk.AccAddress {
+    defer func() {
+        if r := recover(); r != nil {
+            // Return empty slice on panic, as this is better than crashing
+            return []sdk.AccAddress{}
+        }
+    }()
     addr, _ := sdk.AccAddressFromBech32(msg.Authority)
     return []sdk.AccAddress{addr}
 }

18-33: Consider additional validations for PerpetualId.

While the current validations are good, consider adding an upper bound check for PerpetualId to prevent unreasonably large values.

 func (msg *MsgUpgradeIsolatedPerpetualToCross) ValidateBasic() error {
     if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil {
         return errorsmod.Wrap(
             ErrInvalidAuthority,
             fmt.Sprintf(
                 "authority '%s' must be a valid bech32 address, but got error '%v'",
                 msg.Authority,
                 err.Error(),
             ),
         )
     }
     if msg.PerpetualId == 0 {
         return ErrInvalidPerpetualId
     }
+    // Add an upper bound check to prevent unreasonable values
+    if msg.PerpetualId > MaxPerpetualId {
+        return errorsmod.Wrapf(
+            ErrInvalidPerpetualId,
+            "perpetual id %d exceeds maximum allowed value %d",
+            msg.PerpetualId,
+            MaxPerpetualId,
+        )
+    }
     return nil
 }
protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross.go (1)

24-35: Consider adding logging and events

While the implementation is correct, consider enhancing observability by:

  1. Adding logging for successful upgrades
  2. Emitting events to track these administrative actions on-chain

Here's a suggested implementation:

 	if err != nil {
 		return nil, err
 	}
+
+	// Log successful upgrade
+	k.Logger(ctx).Info("Successfully upgraded isolated perpetual to cross",
+		"perpetual_id", msg.PerpetualId,
+		"authority", msg.Authority,
+	)
+
+	// Emit event
+	if err := ctx.EventManager().EmitTypedEvent(
+		&types.EventPerpetualUpgradeToIsolated{
+			PerpetualId: msg.PerpetualId,
+			Authority:   msg.Authority,
+		}); err != nil {
+		return nil, err
+	}

 	return &types.MsgUpgradeIsolatedPerpetualToCrossResponse{}, nil
protocol/x/listing/types/errors.go (2)

43-47: Consider simplifying the error message.

The error message "Authority is invalid" can be simplified to "invalid authority" to be more concise and consistent with other error messages in the module.

 	ErrInvalidAuthority = errorsmod.Register(
 		ModuleName,
 		7,
-		"Authority is invalid",
+		"invalid authority",
 	)

49-53: Fix capitalization in error message.

The error message should use consistent capitalization. "ID" should be in uppercase as it's an acronym.

 	ErrInvalidPerpetualId = errorsmod.Register(
 		ModuleName,
 		8,
-		"Invalid perpetual ID",
+		"invalid perpetual ID",
 	)
protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross_test.go (2)

34-34: Fix typos in test case names

There are typos in the test case names:

  • "Invaid authority" should be "Invalid authority"
  • "Invaid perpetual ID" should be "Invalid perpetual ID"
-		"Failure: Invaid authority": {
+		"Failure: Invalid authority": {
-		"Failure: Invaid perpetual ID": {
+		"Failure: Invalid perpetual ID": {

Also applies to: 41-41


16-60: Consider adding more test cases for comprehensive validation

While the current test cases cover basic validation, consider adding:

  1. Test case for maximum allowed perpetual ID value
  2. Test case for malformed bech32 address (currently only testing empty and invalid format)
  3. Consider grouping test cases by the field being tested (authority vs perpetual ID) for better organization

Example structure:

tests := map[string]struct {
    msg         types.MsgUpgradeIsolatedPerpetualToCross
    expectedErr string
}{
    "Authority Validation": {
        "Success: Valid authority": {...},
        "Failure: Empty authority": {...},
        "Failure: Invalid authority format": {...},
        "Failure: Malformed bech32 address": {...},
    },
    "Perpetual ID Validation": {
        "Success: Valid perpetual ID": {...},
        "Failure: Zero perpetual ID": {...},
        "Failure: Exceeds maximum value": {...},
    },
}
indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.rpc.msg.ts (2)

15-20: Enhance JSDoc documentation for better clarity.

While the JSDoc comment is clear, it could be more informative by including:

  • Parameters description
  • Return value description
  • Any authorization requirements
  • Potential error cases

Consider expanding the JSDoc like this:

 /**
  * UpgradeIsolatedPerpetualToCross upgrades a perpetual from isolated to cross
  * margin
+ * @param request - Contains perpetualId and authority for the upgrade
+ * @returns Response indicating the success of the upgrade operation
+ * @throws If the caller lacks necessary permissions or if the perpetual is invalid
  */

51-55: Consider adding explicit error handling.

While the implementation follows the established pattern, consider adding explicit error handling to provide more detailed error information to callers.

Consider wrapping the implementation like this:

 upgradeIsolatedPerpetualToCross(request: MsgUpgradeIsolatedPerpetualToCross): Promise<MsgUpgradeIsolatedPerpetualToCrossResponse> {
+  try {
     const data = MsgUpgradeIsolatedPerpetualToCross.encode(request).finish();
     const promise = this.rpc.request("dydxprotocol.listing.Msg", "UpgradeIsolatedPerpetualToCross", data);
     return promise.then(data => MsgUpgradeIsolatedPerpetualToCrossResponse.decode(new _m0.Reader(data)));
+  } catch (error) {
+    throw new Error(`Failed to upgrade perpetual: ${error.message}`);
+  }
 }
proto/dydxprotocol/listing/tx.proto (2)

26-29: Consider enhancing the RPC method documentation.

While the current comment describes the basic purpose, it would be helpful to add more details about:

  • The requirements and preconditions for upgrading
  • The implications of upgrading from isolated to cross margin
  • Any side effects or important considerations
-  // UpgradeIsolatedPerpetualToCross upgrades a perpetual from isolated to cross
-  // margin
+  // UpgradeIsolatedPerpetualToCross upgrades a perpetual from isolated to cross margin.
+  // Requirements:
+  //  - The perpetual must exist and be in isolated margin mode
+  //  - Only the authority can perform this upgrade
+  // Effects:
+  //  - Changes the perpetual's margin type from isolated to cross
+  //  - Affects how margin requirements are calculated for positions

81-89: Consider adding field validation for perpetual_id.

While the field type is correct, consider adding validation constraints to ensure the perpetual_id is within valid bounds.

   // ID of the perpetual to be upgraded to CROSS
-  uint32 perpetual_id = 2;
+  uint32 perpetual_id = 2 [(gogoproto.moretags) = "validate:\"required,min=0\""];
protocol/testutil/keeper/listing.go (1)

42-44: Consider renaming bankKeeper_out for consistency.

The suffix _out in bankKeeper_out doesn't follow typical Go naming conventions. Consider using a more descriptive name without the underscore, such as bankKeeperBase or simply bankKeeper.

protocol/x/listing/keeper/listing.go (2)

156-191: Consider wrapping errors for better context

The error handling could be improved by wrapping errors with additional context about the operation being performed.

Consider applying this change:

 func (k Keeper) UpgradeIsolatedPerpetualToCross(
     ctx sdk.Context,
     perpetualId uint32,
 ) error {
     perpetual, err := k.PerpetualsKeeper.GetPerpetual(ctx, perpetualId)
     if err != nil {
-        return err
+        return fmt.Errorf("failed to get perpetual %d: %w", perpetualId, err)
     }
     if perpetual.Params.GetMarketType() != perpetualtypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_ISOLATED {
         return fmt.Errorf("perpetual %d is not an isolated perpetual and cannot be upgraded to cross", perpetualId)
     }

     err = k.SubaccountsKeeper.TransferIsolatedInsuranceFundToCross(ctx, perpetualId)
     if err != nil {
-        return err
+        return fmt.Errorf("failed to transfer isolated insurance fund for perpetual %d: %w", perpetualId, err)
     }

     err = k.SubaccountsKeeper.TransferIsolatedCollateralToCross(ctx, perpetualId)
     if err != nil {
-        return err
+        return fmt.Errorf("failed to transfer isolated collateral for perpetual %d: %w", perpetualId, err)
     }

     _, err = k.PerpetualsKeeper.SetPerpetualMarketType(
         ctx,
         perpetualId,
         perpetualtypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS,
     )
     if err != nil {
-        return err
+        return fmt.Errorf("failed to set perpetual %d market type to cross: %w", perpetualId, err)
     }

     return nil
 }

188-189: Address TODO comment for indexer changes

The TODO comment indicates that indexer changes need to be propagated. This should be addressed before the PR is merged to ensure data consistency.

Would you like me to help create a GitHub issue to track the indexer integration work?

protocol/x/subaccounts/keeper/transfer.go (2)

582-587: Add logging and metrics for transfer monitoring.

Consider adding logging and metrics to track successful transfers during the upgrade process. This will help with monitoring and debugging.

+	// Log successful transfer
+	ctx.Logger().Info(
+		"Transferred isolated collateral to cross pool",
+		"perpetual_id", perpetualId,
+		"amount", isolatedCollateralPoolBalance.String(),
+	)
+
+	// Add metric for monitoring
+	metrics.AddSampleWithLabels(
+		metrics.IsolatedToCrossTransfer,
+		metrics.GetMetricValueFromString(isolatedCollateralPoolBalance.String()),
+		metrics.GetLabelForStringValue(metrics.TransferType, "collateral"),
+		metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)),
+	)
+
 	return k.bankKeeper.SendCoins(
 		ctx,
 		isolatedCollateralPoolAddr,
 		crossCollateralPoolAddr,
 		[]sdk.Coin{isolatedCollateralPoolBalance},
 	)

508-588: Consider adding transaction boundary.

Both transfer functions modify bank state independently. Consider wrapping them in a single transaction to ensure atomicity during the upgrade process.

protocol/x/listing/keeper/listing_test.go (3)

429-437: Consider adding more test cases for better coverage.

Consider adding the following test cases:

  1. Test case for non-existent perpetual ID
  2. Test case verifying event emission if applicable
  3. Test case validating liquidity tier changes if the upgrade affects them
 tests := map[string]struct {
     perpetualId                   uint32
     isolatedInsuranceFundBalance  *big.Int
     isolatedCollateralPoolBalance *big.Int
     crossInsuranceFundBalance     *big.Int
     crossCollateralPoolBalance    *big.Int
 
     expectedErr string
 }{
+    "failure - non-existent perpetual": {
+        perpetualId:                   999,
+        isolatedInsuranceFundBalance:  big.NewInt(1),
+        isolatedCollateralPoolBalance: big.NewInt(1),
+        crossInsuranceFundBalance:     big.NewInt(1),
+        crossCollateralPoolBalance:    big.NewInt(1),
+        expectedErr:                   "perpetual 999 not found",
+    },

517-539: Consider refactoring repeated test setup code.

The fund initialization code could be extracted into a helper function to improve readability and maintainability.

func fundAccounts(
    t *testing.T,
    ctx sdk.Context,
    bankKeeper types.BankKeeper,
    fundingData []struct {
        addr   sdk.AccAddress
        amount *big.Int
    },
) {
    for _, data := range fundingData {
        if data.amount.Cmp(big.NewInt(0)) != 0 {
            err := bank_testutil.FundAccount(
                ctx,
                data.addr,
                sdk.Coins{
                    sdk.NewCoin(constants.Usdc.Denom, sdkmath.NewIntFromBigInt(data.amount)),
                },
                bankKeeper,
            )
            require.NoError(t, err)
        }
    }
}

559-578: Consider refactoring balance verification code.

Similar to the funding code, the balance verification could be extracted into a helper function.

func verifyBalances(
    t *testing.T,
    ctx sdk.Context,
    bankKeeper types.BankKeeper,
    expectedBalances []struct {
        addr   sdk.AccAddress
        amount *big.Int
    },
) {
    for _, data := range expectedBalances {
        require.Equal(
            t,
            sdk.NewCoin(
                asstypes.AssetUsdc.Denom,
                sdkmath.NewIntFromBigInt(data.amount),
            ),
            bankKeeper.GetBalance(ctx, data.addr, asstypes.AssetUsdc.Denom),
        )
    }
}
protocol/x/subaccounts/keeper/subaccount.go (2)

833-850: Consider adding input validation and consistent error handling.

The function has several potential improvements:

  1. Add validation for perpetualId parameter
  2. Consider returning an error instead of panicking when USDC asset is not found, for consistency with other error cases
  3. Add nil check before accessing insuranceFundBalance.Amount to prevent potential nil pointer dereference
-func (k Keeper) GetInsuranceFundBalance(ctx sdk.Context, perpetualId uint32) (balance *big.Int) {
+func (k Keeper) GetInsuranceFundBalance(ctx sdk.Context, perpetualId uint32) (*big.Int, error) {
 	usdcAsset, exists := k.assetsKeeper.GetAsset(ctx, assettypes.AssetUsdc.Id)
 	if !exists {
-		panic("GetInsuranceFundBalance: Usdc asset not found in state")
+		return nil, fmt.Errorf("GetInsuranceFundBalance: Usdc asset not found in state")
 	}
 	insuranceFundAddr, err := k.perpetualsKeeper.GetInsuranceFundModuleAddress(ctx, perpetualId)
 	if err != nil {
-		return nil
+		return nil, fmt.Errorf("GetInsuranceFundBalance: failed to get insurance fund module address: %w", err)
 	}
 	insuranceFundBalance := k.bankKeeper.GetBalance(
 		ctx,
 		insuranceFundAddr,
 		usdcAsset.Denom,
 	)
+	if insuranceFundBalance == nil || insuranceFundBalance.Amount == nil {
+		return nil, fmt.Errorf("GetInsuranceFundBalance: nil balance returned from bank keeper")
+	}
 	// Return as big.Int.
-	return insuranceFundBalance.Amount.BigInt()
+	return insuranceFundBalance.Amount.BigInt(), nil

852-865: Align error handling with GetInsuranceFundBalance.

For consistency with the suggested improvements to GetInsuranceFundBalance, consider applying similar error handling patterns here.

-func (k Keeper) GetCrossInsuranceFundBalance(ctx sdk.Context) (balance *big.Int) {
+func (k Keeper) GetCrossInsuranceFundBalance(ctx sdk.Context) (*big.Int, error) {
 	usdcAsset, exists := k.assetsKeeper.GetAsset(ctx, assettypes.AssetUsdc.Id)
 	if !exists {
-		panic("GetCrossInsuranceFundBalance: Usdc asset not found in state")
+		return nil, fmt.Errorf("GetCrossInsuranceFundBalance: Usdc asset not found in state")
 	}
 	insuranceFundBalance := k.bankKeeper.GetBalance(
 		ctx,
 		perptypes.InsuranceFundModuleAddress,
 		usdcAsset.Denom,
 	)
+	if insuranceFundBalance == nil || insuranceFundBalance.Amount == nil {
+		return nil, fmt.Errorf("GetCrossInsuranceFundBalance: nil balance returned from bank keeper")
+	}
 	// Return as big.Int.
-	return insuranceFundBalance.Amount.BigInt()
+	return insuranceFundBalance.Amount.BigInt(), nil
protocol/x/subaccounts/keeper/subaccount_test.go (3)

6137-6147: Consider adding test cases for additional edge cases.

While the test coverage is good, consider adding test cases for:

  • Insurance fund balance with negative values (if applicable)
  • Behavior when perpetual ID doesn't exist
  • Race conditions with concurrent balance updates

6194-6199: Consider improving error handling test cases.

The panic test case could be enhanced by:

  • Testing more error scenarios
  • Using more specific error types instead of generic errors
  • Adding test cases for other potential error conditions
 "panics when asset not found in state": {
     assets:        []asstypes.Asset{},
     perpetualId:   0,
-    expectedError: errors.New("GetInsuranceFundBalance: Usdc asset not found in state"),
+    expectedError: asstypes.ErrAssetNotFound,
 },

6201-6259: Consider improving test helper functions and setup.

The test setup could be improved by:

  • Extracting common setup code into helper functions
  • Adding cleanup to ensure test isolation
  • Adding logging for better debugging
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 76c18b6 and 4a39816.

⛔ Files ignored due to path filters (1)
  • protocol/x/listing/types/tx.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (29)
  • indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.rpc.msg.ts (4 hunks)
  • indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.ts (2 hunks)
  • proto/dydxprotocol/listing/tx.proto (2 hunks)
  • protocol/app/app.go (1 hunks)
  • protocol/app/msgs/all_msgs.go (1 hunks)
  • protocol/app/msgs/internal_msgs.go (1 hunks)
  • protocol/app/msgs/internal_msgs_test.go (1 hunks)
  • protocol/lib/ante/internal_msg.go (1 hunks)
  • protocol/mocks/ClobKeeper.go (0 hunks)
  • protocol/testutil/keeper/listing.go (9 hunks)
  • protocol/x/clob/keeper/deleveraging.go (1 hunks)
  • protocol/x/clob/keeper/deleveraging_test.go (0 hunks)
  • protocol/x/clob/keeper/keeper.go (2 hunks)
  • protocol/x/clob/types/expected_keepers.go (1 hunks)
  • protocol/x/clob/types/liquidations_keeper.go (0 hunks)
  • protocol/x/listing/keeper/keeper.go (2 hunks)
  • protocol/x/listing/keeper/listing.go (2 hunks)
  • protocol/x/listing/keeper/listing_test.go (5 hunks)
  • protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross.go (1 hunks)
  • protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross_test.go (1 hunks)
  • protocol/x/listing/types/errors.go (1 hunks)
  • protocol/x/listing/types/expected_keepers.go (2 hunks)
  • protocol/x/listing/types/msg_upgrade_isolated_perpetual_to_cross.go (1 hunks)
  • protocol/x/perpetuals/keeper/perpetual.go (1 hunks)
  • protocol/x/perpetuals/keeper/perpetual_test.go (2 hunks)
  • protocol/x/subaccounts/keeper/subaccount.go (2 hunks)
  • protocol/x/subaccounts/keeper/subaccount_test.go (2 hunks)
  • protocol/x/subaccounts/keeper/transfer.go (2 hunks)
  • protocol/x/subaccounts/types/expected_keepers.go (3 hunks)
💤 Files with no reviewable changes (3)
  • protocol/mocks/ClobKeeper.go
  • protocol/x/clob/keeper/deleveraging_test.go
  • protocol/x/clob/types/liquidations_keeper.go
🧰 Additional context used
📓 Learnings (8)
protocol/x/clob/keeper/deleveraging.go (3)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/clob/keeper/keeper.go (3)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/clob/types/expected_keepers.go (3)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/listing/types/expected_keepers.go (1)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/subaccounts/keeper/subaccount.go (3)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/subaccounts/keeper/subaccount_test.go (2)

<retrieved_learning>
Learnt from: hwray
PR: #2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function GetInsuranceFundBalance in protocol/x/subaccounts/keeper/subaccount.go already existed and was just moved in this PR; changes to its error handling may be out of scope.
</retrieved_learning>

<retrieved_learning>
Learnt from: hwray
PR: #2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function GetCrossInsuranceFundBalance in protocol/x/subaccounts/keeper/subaccount.go already existed and was just moved in this PR; changes to its error handling may be out of scope.
</retrieved_learning>

protocol/x/subaccounts/keeper/transfer.go (2)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/subaccounts/types/expected_keepers.go (1)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
🪛 Biome
indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.ts

[error] 130-130: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 136-136: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🔇 Additional comments (47)
protocol/x/listing/types/msg_upgrade_isolated_perpetual_to_cross.go (2)

1-9: LGTM! Clean package structure and imports.

The package declaration and imports are well-organized and follow Go conventions.


11-11: Verify the message struct definition exists.

While the interface implementation check is correct, we should verify the existence of the MsgUpgradeIsolatedPerpetualToCross struct definition.

✅ Verification successful

Message struct is properly defined

The MsgUpgradeIsolatedPerpetualToCross struct is correctly defined in:

  • Proto definition: proto/dydxprotocol/listing/tx.proto
  • Generated Go code: protocol/x/listing/types/tx.pb.go
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the struct definition in proto files and generated Go code
rg -t proto -t go "message MsgUpgradeIsolatedPerpetualToCross|type MsgUpgradeIsolatedPerpetualToCross struct"

Length of output: 141


Script:

#!/bin/bash
# Search for the struct definition in all files
rg "message MsgUpgradeIsolatedPerpetualToCross|type MsgUpgradeIsolatedPerpetualToCross struct"

# Also search for proto file containing this message
fd ".*\.proto" --exec grep -l "MsgUpgradeIsolatedPerpetualToCross"

Length of output: 455

protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross.go (2)

1-11: LGTM: Clean package declaration and imports

The imports are well-organized and all are actively used in the implementation.


12-23: LGTM: Proper authority validation

The authority check is implemented correctly with proper error handling and descriptive error messages.

protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross_test.go (3)

1-9: LGTM: Package and imports are well-organized

The package name follows Go conventions for test files, and imports are logically organized.


11-14: LGTM: Test constants are well-defined

Good practice using a predefined test account from constants package with clear documentation.


16-60: LGTM: Well-structured test implementation

The test implementation follows good practices:

  • Uses table-driven tests effectively
  • Validates both success and failure cases
  • Provides clear error message validation
  • Uses require assertions appropriately

While some improvements were suggested above, the current implementation provides good test coverage for the basic validation of MsgUpgradeIsolatedPerpetualToCross.

protocol/x/listing/keeper/keeper.go (3)

16-24: LGTM: Clean addition of SubaccountsKeeper field

The addition of SubaccountsKeeper follows the established pattern and is properly typed. The field placement is logical, grouped with other keeper dependencies.


36-48: LGTM: Constructor properly updated for SubaccountsKeeper

The constructor changes are clean and maintain consistency with the struct definition.


Line range hint 1-65: Verify implementation of UpgradeIsolatedPerpetualToCross method

The AI summary mentions a new UpgradeIsolatedPerpetualToCross method, but it's not present in this file. Let's verify its implementation.

✅ Verification successful

Let me gather more information about the implementation of UpgradeIsolatedPerpetualToCross in the keeper.


Let me check the rest of the implementation and the test file to fully understand the functionality.


I have enough information to generate the final response. The implementation of UpgradeIsolatedPerpetualToCross is present in the codebase and properly implemented in the keeper.

The UpgradeIsolatedPerpetualToCross method is correctly implemented in the listing keeper

The method is implemented in protocol/x/listing/keeper/listing.go with the following functionality:

  • Validates that the perpetual exists and is in isolated mode
  • Transfers isolated insurance fund to cross via SubaccountsKeeper
  • Transfers isolated collateral to cross via SubaccountsKeeper
  • Updates the perpetual market type to cross via PerpetualsKeeper

The implementation is also well-tested in listing_test.go with various test cases including success scenarios and edge cases.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the UpgradeIsolatedPerpetualToCross implementation
rg -l "func.*UpgradeIsolatedPerpetualToCross"

# Search for any references to this method
rg "UpgradeIsolatedPerpetualToCross"

# Look for any interfaces defining this method
ast-grep --pattern 'interface {
  $$$
  UpgradeIsolatedPerpetualToCross($$$)
  $$$
}'

Length of output: 19868


Script:

#!/bin/bash
# Look at the implementation in listing.go
rg -A 20 "func.*UpgradeIsolatedPerpetualToCross" protocol/x/listing/keeper/listing.go

Length of output: 788


Script:

#!/bin/bash
# Get the full implementation from listing.go
rg -A 30 "func.*UpgradeIsolatedPerpetualToCross" protocol/x/listing/keeper/listing.go

# Look at the test implementation
rg -A 30 "TestUpgradeIsolatedPerpetualToCross" protocol/x/listing/keeper/listing_test.go

Length of output: 2256

protocol/x/subaccounts/types/expected_keepers.go (2)

32-38: LGTM! Clean interface method addition.

The GetAsset method follows good practices with clear input parameters and return values.


102-102: Consider using sdk.Context instead of context.Context for consistency.

The GetBalance method uses context.Context while other methods in the interface use sdk.Context. This inconsistency might cause issues when implementing the interface.

Let's verify the context type usage in other bank keeper methods:

protocol/x/listing/types/expected_keepers.go (2)

67-76: LGTM! Well-designed interface methods for perpetual market upgrades.

The new methods GetPerpetual and SetPerpetualMarketType are well-structured with appropriate parameters and return types, maintaining consistency with the interface's existing patterns.


103-112: LGTM! Clean interface design for fund transfers.

The new SubaccountsKeeper interface is well-structured with focused methods for handling different types of transfers during perpetual market upgrades.

Let's verify the keeper implementation has proper validation and error handling:

✅ Verification successful

Implementation validates the interface design with proper safeguards

The keeper implementation confirms the interface is well-designed with appropriate validation and error handling:

  • Both methods validate perpetual existence before proceeding
  • Proper null checks (zero balance handling in insurance fund transfer)
  • Clear error propagation from dependent keepers
  • Panic conditions only for critical system invariants (USDC asset existence)
  • Comprehensive documentation explaining the purpose and state modifications
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the implementation of these transfer methods
ast-grep --pattern 'func ($keeper $_) TransferIsolatedInsuranceFundToCross(ctx $_.$_, perpetualId $_) error {
  $$$
}'

ast-grep --pattern 'func ($keeper $_) TransferIsolatedCollateralToCross(ctx $_.$_, perpetualId $_) error {
  $$$
}'

Length of output: 238


Script:

#!/bin/bash
# Let's try a broader search for the implementation using ripgrep
rg -A 10 "func.*TransferIsolatedInsuranceFundToCross" --type go
rg -A 10 "func.*TransferIsolatedCollateralToCross" --type go

# Also search for any test files that might contain these method names
rg "TransferIsolatedInsuranceFundToCross|TransferIsolatedCollateralToCross" --type go "*_test.go"

Length of output: 1934


Script:

#!/bin/bash
# Let's get the complete implementation of both methods
rg -B 5 -A 20 "func \(k Keeper\) TransferIsolatedInsuranceFundToCross" protocol/x/subaccounts/keeper/transfer.go
rg -B 5 -A 20 "func \(k Keeper\) TransferIsolatedCollateralToCross" protocol/x/subaccounts/keeper/transfer.go

Length of output: 1995

indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.rpc.msg.ts (3)

3-3: LGTM! Import statement follows existing patterns.

The new message types are properly imported and follow the established naming conventions.


30-30: LGTM! Method binding follows class pattern.

The method is properly bound in the constructor, maintaining consistency with other methods.


51-55: Verify test coverage for the new RPC method.

Since this PR focuses on adding tests for the UpgradeIsolatedPerpetualToCross functionality, ensure comprehensive test coverage for this RPC method.

proto/dydxprotocol/listing/tx.proto (1)

91-93: LGTM!

The response message follows the established pattern in the codebase and is appropriate for this operation.

protocol/lib/ante/internal_msg.go (1)

106-106: LGTM! Verify security implications of internal message classification.

The addition of MsgUpgradeIsolatedPerpetualToCross as an internal message follows the established pattern and is appropriately placed with other listing module messages.

Let's verify that this message type is properly secured in its implementation:

✅ Verification successful

Based on the search results, I can now verify the security implications of marking MsgUpgradeIsolatedPerpetualToCross as an internal message. The results show:

  1. The message handler in protocol/x/listing/keeper/msg_server_upgrade_isolated_perpetual_to_cross.go properly checks authority:
if !k.Keeper.HasAuthority(msg.Authority) {
    return nil, errorsmod.Wrapf(
        govtypes.ErrInvalidSigner,
        "invalid authority %s",
        msg.Authority,
    )
}
  1. The message type in protocol/x/listing/types/msg_upgrade_isolated_perpetual_to_cross.go validates the authority in ValidateBasic():
if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil {
    return errorsmod.Wrap(
        ErrInvalidAuthority,
        fmt.Sprintf(
            "authority '%s' must be a valid bech32 address",
            msg.Authority,
        )
    )
}
  1. The message is properly registered as an internal message in both protocol/app/msgs/internal_msgs.go and protocol/lib/ante/internal_msg.go.

LGTM! Security checks for internal message authority are properly implemented.

The message has appropriate authority validation at both the message and handler level, and its classification as an internal message is consistent with other privileged operations in the listing module.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the security checks in the message handler and type definition

# Check the message handler implementation for authority checks
ast-grep --pattern 'func $_(ctx $_, msg *listing.MsgUpgradeIsolatedPerpetualToCross) $_ {
  $$$
  if !$hasAuth($authority) {
    $$$
  }
  $$$
}'

# Check the message type definition for authority validation
ast-grep --pattern 'func (msg *MsgUpgradeIsolatedPerpetualToCross) ValidateBasic() error {
  $$$
  if !$validAuth($authority) {
    $$$
  }
  $$$
}'

Length of output: 298


Script:

#!/bin/bash
# Let's try a different approach to verify the security checks

# Find the message type definition file
fd "msg.*\.go" --type f --exec rg -l "MsgUpgradeIsolatedPerpetualToCross"

# Search for authority checks in handler implementation
rg -A 5 -B 5 "MsgUpgradeIsolatedPerpetualToCross" 

# Look for any authority or permission related constants/interfaces
rg "Authority|Permission" --type go

Length of output: 176869

protocol/x/clob/types/expected_keepers.go (2)

80-85: LGTM! Clean interface definition for GetInsuranceFundBalance.

The method signature is well-defined and follows Go conventions. Based on the learnings, this is part of a refactoring effort to consolidate insurance fund balance management in the SubaccountsKeeper.


86-90: LGTM! Clean interface definition for GetCrossInsuranceFundBalance.

The method signature is well-defined and follows Go conventions. This addition complements the GetInsuranceFundBalance method and maintains consistency in the insurance fund balance management interface.

protocol/testutil/keeper/listing.go (5)

14-14: LGTM: Import additions are appropriate.

The new imports for assets and subaccounts keepers are correctly added and necessary for the new dependencies.

Also applies to: 18-18


Line range hint 121-134: LGTM: Proper initialization of new keepers.

The initialization of assetsKeeper and subaccountsKeeper is correctly implemented with proper dependency ordering and all necessary parameters.

Also applies to: 141-146


Line range hint 159-181: LGTM: CLOB keeper dependencies are properly updated.

The new dependencies are correctly integrated into the CLOB keeper creation, maintaining proper initialization order.


189-189: LGTM: Return statement properly updated.

The return statement correctly includes all new keeper instances in the appropriate order.


Line range hint 200-221: Verify keeper constructor parameter alignment.

The changes to createListingKeeper look correct. Let's verify that the parameters match the actual keeper constructor.

✅ Verification successful

Parameters in createListingKeeper match the keeper constructor

Looking at the NewKeeper function in protocol/x/listing/keeper/keeper.go, the parameters match exactly with those in createListingKeeper:

  1. cdc
  2. storeKey
  3. authorities
  4. pricesKeeper
  5. clobKeeper
  6. marketMapKeeper
  7. perpetualsKeeper
  8. subaccountsKeeper
  9. vaultKeeper

The parameters are in the correct order and of the expected types.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the keeper constructor parameters match
# Search for the NewKeeper function definition in the listing keeper
ast-grep --pattern 'func NewKeeper($$$) *keeper.Keeper {
  $$$
}'

Length of output: 67


Script:

#!/bin/bash
# Let's try a different approach to find the keeper constructor
# First, let's locate the keeper package file
fd "keeper.*\.go" --type f --exec rg -l "NewKeeper"

# Then let's search for the NewKeeper function with context
rg "func NewKeeper" -A 15

Length of output: 22498

protocol/app/msgs/internal_msgs_test.go (1)

119-120: LGTM! Verify message registration.

The new message types are correctly added to the governance message list, maintaining alphabetical order within the "listing" section.

Let's verify that these messages are properly registered in the message registry:

✅ Verification successful

Message types are properly registered in the message registry

The new message types are correctly registered in all_msgs.go, matching the test expectations:

  • /dydxprotocol.listing.MsgUpgradeIsolatedPerpetualToCross
  • /dydxprotocol.listing.MsgUpgradeIsolatedPerpetualToCrossResponse
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the new message types are registered in the message registry.

# Check for message registration in the registry
rg -A 1 "MsgUpgradeIsolatedPerpetualToCross" protocol/app/msgs/all_msgs.go

Length of output: 223

protocol/x/listing/keeper/listing.go (1)

169-177: Verify atomic transaction handling

The method performs multiple state changes (insurance fund transfer, collateral transfer, market type update) that should be atomic. Need to verify that these operations are properly handled within a transaction.

✅ Verification successful

Based on the investigation of the codebase, I can now provide a final response:

Atomic transactions are handled by Cosmos SDK context

The operations are inherently atomic as they are executed within a Cosmos SDK transaction context. The bankKeeper.SendCoins operations used in both transfer methods are atomic by design, and the Cosmos SDK's transaction mechanism ensures that either all state changes succeed or none do. If any operation fails, all changes are rolled back automatically.

Key observations:

  • Both transfer methods ultimately use bankKeeper.SendCoins which is an atomic operation
  • The operations are executed sequentially within the same Cosmos SDK context
  • Any error in any operation triggers a complete rollback through the SDK's transaction handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the keeper methods use transaction boundaries

# Look for transaction handling in the keeper implementation
rg -A 5 "Begin.*Transaction|Commit.*Transaction|Rollback.*Transaction" --type go

# Check if the called methods handle transactions
ast-grep --pattern 'func $_(ctx $_, perpetualId $_) error {
  $$$
  Begin$_Transaction($_)
  $$$
}'

Length of output: 184


Script:

#!/bin/bash
# Let's check the implementation of the called methods to understand transaction handling

# Check SubaccountsKeeper's methods implementation
ast-grep --pattern 'func (k $_) TransferIsolatedInsuranceFundToCross(ctx $_, perpetualId $_) error {
  $$$
}'

ast-grep --pattern 'func (k $_) TransferIsolatedCollateralToCross(ctx $_, perpetualId $_) error {
  $$$
}'

# Also check if there's any transaction handling in the parent function
rg -B 5 -A 10 "TransferIsolatedInsuranceFundToCross" --type go

Length of output: 8905


Script:

#!/bin/bash
# Let's check the Cosmos SDK's bank keeper implementation and the context to understand transaction handling

# Check if the context contains transaction management
rg -B 2 -A 2 "type Context" --type go

# Look for bank keeper's SendCoins implementation
ast-grep --pattern 'func $_ SendCoins(ctx $_, from $_, to $_, amt $_) error {
  $$$
}'

# Check if there's any transaction management in the parent function that calls these methods
rg -B 10 -A 5 "func.*SetPerpetualMarketType" --type go

Length of output: 3437

protocol/app/msgs/internal_msgs.go (2)

159-162: LGTM! Formatting changes maintain consistency.

The reformatting of existing message types maintains consistent alignment with other entries in the map.


163-164: LGTM! New message types align with PR objectives.

The addition of MsgUpgradeIsolatedPerpetualToCross and its response type is consistent with:

  • The PR's objective to implement the upgrade functionality
  • The existing pattern of message/response pairs in the map
  • The module's message naming conventions

Let's verify the message type definitions exist:

✅ Verification successful

Message types are properly defined and integrated across the codebase

The verification confirms that:

  • The message types are properly defined in proto/dydxprotocol/listing/tx.proto
  • The implementation exists across multiple files:
    • Generated code in protocol/x/listing/types/
    • Keeper implementation in protocol/x/listing/keeper/
    • Integration in message handling in protocol/app/msgs/
    • Indexer support in indexer/packages/v4-protos/

The message types are correctly structured with:

  • Authority signer requirement
  • Proper field definitions
  • Response message type
  • Integration with the Msg service
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the new message types are properly defined in the proto files
# and their generated Go code exists.

# Check for message definitions in proto files
echo "Checking proto definitions..."
rg -l "message MsgUpgradeIsolatedPerpetualToCross" "proto/"

# Check for generated Go types
echo "Checking generated Go types..."
rg -l "type MsgUpgradeIsolatedPerpetualToCross struct" "x/listing/types/"

Length of output: 366


Script:

#!/bin/bash
# Let's verify the message types in a different way

# 1. First, let's find all possible locations of the generated types
echo "Searching for the message type across the codebase..."
rg -l "MsgUpgradeIsolatedPerpetualToCross"

# 2. Let's also check the proto definition content
echo -e "\nChecking proto definition content..."
cat proto/dydxprotocol/listing/tx.proto

Length of output: 4244

protocol/x/clob/keeper/keeper.go (2)

6-6: LGTM!

The math/big import is correctly placed and necessary for the new method's return type.


166-168: LGTM!

The implementation correctly delegates to the subaccountsKeeper. Based on the retrieved learnings from PR #2551, this follows the established pattern of similar functions that were moved earlier.

indexer/packages/v4-protos/src/codegen/dydxprotocol/listing/tx.ts (2)

103-136: LGTM! Interface definitions follow protocol standards.

The interfaces are well-structured and properly documented. The empty response interfaces are intentional and follow the established pattern for RPC responses without return values.

🧰 Tools
🪛 Biome

[error] 130-130: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 136-136: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


405-491: LGTM! Implementation follows protobuf standards.

The encode/decode implementation correctly handles all fields and follows the protobuf wire format specification.

Let's verify the field numbers match the proto definition:

✅ Verification successful

Field numbers in implementation match proto definition

The implementation correctly matches the proto definition:

  • authority field number = 1
  • perpetual_id field number = 2 (matches perpetualId in the implementation)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify field numbers in proto definition match the implementation
# Expected: Field numbers should be 1 for authority and 2 for perpetual_id

rg -A 5 "message MsgUpgradeIsolatedPerpetualToCross" "*.proto"

Length of output: 112


Script:

#!/bin/bash
# Let's first find the proto files in the repository
fd -e proto | grep -i 'listing\|perpetual'

# Then we can search for the message definition in the found files

Length of output: 525


Script:

#!/bin/bash
# Search for the message definition in the listing tx proto file since the implementation is in the listing package
rg -A 5 "message MsgUpgradeIsolatedPerpetualToCross" "proto/dydxprotocol/listing/tx.proto"

Length of output: 372


Script:

#!/bin/bash
# Let's get more context to see the perpetual_id field definition
rg -B 2 -A 10 "message MsgUpgradeIsolatedPerpetualToCross" "proto/dydxprotocol/listing/tx.proto"

Length of output: 669

protocol/x/subaccounts/keeper/transfer.go (1)

541-546: Verify source account balance before transfer.

Consider checking if the source account has sufficient balance before attempting the transfer to provide better error messages.

protocol/x/listing/keeper/listing_test.go (3)

9-9: LGTM: Import additions are appropriate.

The new imports are necessary for bank testing utilities and math operations used in the new test function.

Also applies to: 16-16


67-67: LGTM: Keeper initialization updates are consistent.

The ListingKeepers initialization has been consistently updated across all test functions to include necessary dependencies for the new functionality.

Also applies to: 136-136, 222-222


428-582: LGTM: Well-structured test implementation for perpetual upgrade functionality.

The test function thoroughly covers the core functionality with appropriate test cases for successful upgrades and validation of fund transfers between isolated and cross pools.

protocol/app/msgs/all_msgs.go (1)

237-238: LGTM! New message types are correctly added.

The new message types for upgrading isolated perpetual markets to cross margin are properly added to the AllTypeMessages map following the established naming conventions.

Let's verify if these new message types need to be added to other maps:

✅ Verification successful

Based on the search results, I can see that:

  1. The new message types are already properly added to InternalMsgSamplesAll in protocol/app/msgs/internal_msgs.go:
"/dydxprotocol.listing.MsgUpgradeIsolatedPerpetualToCross":         &listing.MsgUpgradeIsolatedPerpetualToCross{},
"/dydxprotocol.listing.MsgUpgradeIsolatedPerpetualToCrossResponse": nil,
  1. The message is an internal message that can only be executed by the authority (governance), as evidenced by:
  • Its presence in InternalMsgSamplesAll
  • The authority check in the message handler
  • The protobuf definition with option (cosmos.msg.v1.signer) = "authority"
  1. The message doesn't need to be added to other maps because:
  • It's already in the correct map (InternalMsgSamplesAll)
  • Internal messages are not meant to be in AllowMsgs (which equals NormalMsgs)
  • It's not a nested or unsupported message type

No additional maps needed for these message types

The message types are correctly placed in InternalMsgSamplesAll and don't need to be added to other maps since they are governance-only messages.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new message types need to be added to DisallowMsgs or AllowMsgs maps
# by searching for similar patterns in the codebase.

# Search for message type definitions
rg -A 5 "MsgUpgradeIsolatedPerpetualToCross" 

# Search for message handling patterns
rg "NormalMsgs|AppInjectedMsgSamples|InternalMsgSamplesAll|NestedMsgSamples|UnsupportedMsgSamples" --type go

Length of output: 44439

protocol/x/clob/keeper/deleveraging.go (1)

244-244: 💡 Codebase verification

Method exists in implementation but interface needs updating

The GetInsuranceFundBalance method is implemented in protocol/x/subaccounts/keeper/subaccount.go but is not declared in any of the SubaccountsKeeper interfaces. This could lead to compilation errors as the interface contract is incomplete.

  • Add GetInsuranceFundBalance(ctx sdk.Context, perpetualId uint32) *big.Int to the SubaccountsKeeper interface in:
    • protocol/x/clob/types/expected_keepers.go
    • protocol/x/subaccounts/types/types.go
🔗 Analysis chain

LGTM! Verify SubaccountsKeeper interface.

The change correctly uses the centralized GetInsuranceFundBalance method from SubaccountsKeeper, which aligns with previous refactoring efforts.

Let's verify the SubaccountsKeeper interface includes this method with the correct signature:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for GetInsuranceFundBalance method in the SubaccountsKeeper interface
ast-grep --pattern 'type SubaccountsKeeper interface {
  $$$
  GetInsuranceFundBalance(ctx sdk.Context, perpetualId uint32) *big.Int
  $$$
}'

Length of output: 143


Script:

#!/bin/bash
# Let's try a different approach to find the SubaccountsKeeper interface and its method
rg "type SubaccountsKeeper interface" -A 20

# Also search for the actual implementation to verify the method exists
rg "func.*GetInsuranceFundBalance.*Context.*uint32.*big\.Int" -A 2

Length of output: 6431

⛔ Skipped due to learnings
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
protocol/x/subaccounts/keeper/subaccount.go (1)

829-865: LGTM! Functions moved with existing behavior preserved.

Based on the learnings, these functions were moved from another location and the current error handling patterns are preserved intentionally.

protocol/x/perpetuals/keeper/perpetual.go (2)

200-204: LGTM! Important validation for market type transition.

The error handling for preventing changes to CROSS market type is well implemented. This validation is crucial as it ensures:

  1. One-way transition from isolated to cross margin.
  2. Clear error messaging with context (perpetual ID and market type).

Line range hint 191-219: Verify the usage of SetPerpetualMarketType.

The method correctly handles market type transitions and state updates. Let's verify its integration with the new UpgradeIsolatedPerpetualToCross functionality.

✅ Verification successful

Let me gather more specific information about the integration between SetPerpetualMarketType and UpgradeIsolatedPerpetualToCross.


Let me check one final aspect to verify the complete flow and error handling.


Integration between SetPerpetualMarketType and UpgradeIsolatedPerpetualToCross is correctly implemented

The verification confirms:

  • SetPerpetualMarketType correctly handles the transition from isolated to cross market type
  • UpgradeIsolatedPerpetualToCross properly validates the market type before transition
  • Test coverage includes both success and failure scenarios for market type transitions
  • The implementation includes proper state updates and fund transfers during the upgrade process
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of SetPerpetualMarketType to ensure proper integration.

# Search for direct method calls
echo "Direct method calls:"
rg -p "SetPerpetualMarketType"

# Search for potential upgrade implementations
echo -e "\nPotential upgrade implementations:"
rg -p "UpgradeIsolatedPerpetualToCross"

Length of output: 12813


Script:

#!/bin/bash
# Check the implementation of UpgradeIsolatedPerpetualToCross in listing keeper
echo "Listing keeper implementation:"
rg -A 20 "func \(k Keeper\) UpgradeIsolatedPerpetualToCross" protocol/x/listing/keeper/listing.go

# Check test cases for market type transitions
echo -e "\nTest cases for market type transitions:"
rg -A 10 "TestUpgradeIsolatedPerpetualToCross" protocol/x/listing/keeper/listing_test.go

Length of output: 1386


Script:

#!/bin/bash
# Check the test implementation for SetPerpetualMarketType
echo "SetPerpetualMarketType test cases:"
rg -A 20 "TestSetPerpetualMarketType" protocol/x/perpetuals/keeper/perpetual_test.go

# Check the complete test cases for upgrade flow
echo -e "\nComplete upgrade test cases:"
cat protocol/x/listing/keeper/listing_test.go | grep -A 50 "TestUpgradeIsolatedPerpetualToCross"

Length of output: 3275

protocol/app/app.go (1)

1245-1246: LGTM: Dependencies properly injected into ListingKeeper

The addition of SubaccountsKeeper and VaultKeeper as dependencies to the ListingKeeper initialization is consistent with the PR objectives to support upgrading isolated perpetuals to cross margin functionality.

Let's verify the dependencies are properly used in the ListingKeeper:

✅ Verification successful

Based on the search results, I can now verify the review comment. The code shows that:

  1. The ListingKeeper implementation in protocol/x/listing/keeper/listing.go has the UpgradeIsolatedPerpetualToCross function that uses both SubaccountsKeeper and VaultKeeper.
  2. The ListingKeeper struct in protocol/x/listing/keeper/keeper.go properly declares both dependencies:
type Keeper struct {
    SubaccountsKeeper types.SubaccountsKeeper
    VaultKeeper       types.VaultKeeper
}
  1. The dependencies are properly injected in app.go when initializing the ListingKeeper:
app.ListingKeeper = *listingmodulekeeper.NewKeeper(
    appCodec,
    app.SubaccountsKeeper,
    app.VaultKeeper,
)

LGTM: Dependencies properly injected and used in ListingKeeper

The addition of SubaccountsKeeper and VaultKeeper as dependencies to the ListingKeeper is correctly implemented. These dependencies are used in the UpgradeIsolatedPerpetualToCross function to support upgrading isolated perpetuals to cross margin functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify ListingKeeper's usage of SubaccountsKeeper and VaultKeeper

# Check ListingKeeper's implementation for usage of the new dependencies
ast-grep --pattern $'type ListingKeeper struct {
  $$$
  SubaccountsKeeper $$$
  VaultKeeper $$$
  $$$
}'

# Check for methods using these dependencies
ast-grep --pattern $'func (k *ListingKeeper) UpgradeIsolatedPerpetualToCross($$$) {
  $$$
}'

Length of output: 200


Script:

#!/bin/bash
# Let's try a different approach to verify the dependencies

# First, let's find the listing keeper file
fd "listing_keeper.go" --type f

# Then search for SubaccountsKeeper and VaultKeeper usage in the listing keeper
rg "SubaccountsKeeper|VaultKeeper" -A 3

# Also check for any upgrade-related functions in listing keeper
rg "func.*Upgrade.*Perpetual" -A 5

Length of output: 107129

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

326-335: LGTM: Test cases for market type transitions look good.

The new test cases appropriately verify the ability to:

  1. Set market type from unspecified to cross
  2. Set market type from isolated to cross

These test cases ensure the core functionality of upgrading perpetual markets to cross margin type works as expected.


348-357: LGTM: Error case for cross market type is well tested.

The test case properly verifies that a perpetual market already set to cross type cannot be modified, with appropriate error message validation.

protocol/x/subaccounts/keeper/subaccount_test.go (1)

6135-6260: Well structured test suite with comprehensive coverage.

The test suite demonstrates good practices with:

  • Table-driven tests with clear case descriptions
  • Thorough test coverage including edge cases
  • Proper test setup and cleanup
  • Clear assertions and validations

protocol/x/subaccounts/keeper/transfer.go Outdated Show resolved Hide resolved
@hwray hwray changed the base branch from main to harry/upgrade-isolated-to-cross November 19, 2024 20:33
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 (9)
protocol/x/subaccounts/keeper/transfer.go (5)

509-512: Enhance function documentation.

The function documentation should include more details about:

  • When this function is expected to be called during the upgrade process
  • Whether this is a one-time operation or can be called multiple times
  • Any prerequisites or post-conditions

546-551: Add metrics for tracking insurance fund transfers.

Consider adding metrics to track the transfer amount for monitoring and debugging purposes.

Add before the return statement:

+	metrics.AddSampleWithLabels(
+		metrics.InsuranceFundTransfer,
+		metrics.GetMetricValueFromBigInt(isolatedInsuranceFundBalance),
+		metrics.GetLabelForStringValue(metrics.TransferType, "isolated_to_cross"),
+		metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)),
+	)

573-573: Improve panic message for USDC asset.

The panic message should include more context about why this is a critical error.

-		panic("TransferIsolatedCollateralToCross: Usdc asset not found in state")
+		panic("TransferIsolatedCollateralToCross: Critical error - USDC asset must exist in state for collateral transfers")

554-558: Enhance function documentation.

The function documentation should include more details about:

  • When this function is expected to be called during the upgrade process
  • Whether this is a one-time operation or can be called multiple times
  • Any prerequisites or post-conditions

587-592: Add metrics for tracking collateral transfers.

Consider adding metrics to track the transfer amount for monitoring and debugging purposes.

Add before the return statement:

+	metrics.AddSampleWithLabels(
+		metrics.CollateralTransfer,
+		metrics.GetMetricValueFromBigInt(isolatedCollateralPoolBalance.Amount),
+		metrics.GetLabelForStringValue(metrics.TransferType, "isolated_to_cross"),
+		metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)),
+	)
protocol/x/listing/keeper/listing_test.go (4)

67-67: Consider replacing unused keeper variables with underscores.

For better readability and to follow Go conventions, consider replacing unused keeper variables in the return values with underscores. This makes it immediately clear which keepers are actually used in each test.

For example, in TestCreateMarket, apply this change:

-ctx, keeper, _, _, pricesKeeper, _, _, marketMapKeeper, _, _, _ := keepertest.ListingKeepers(
+ctx, keeper, _, _, pricesKeeper, _, _, marketMapKeeper, _, _, _ := keepertest.ListingKeepers(

Also applies to: 136-136, 222-223, 486-491


439-478: Consider adding more edge cases.

While the current test cases cover the main scenarios, consider adding:

  1. Test case for non-existent perpetual ID
  2. Test case for perpetual ID 0 (boundary value)

519-541: Consider improving test data setup readability.

The current setup using nested slices and type assertions could be made more maintainable.

Consider using a helper struct:

+type fundingTestData struct {
+    address sdk.AccAddress
+    amount  *big.Int
+}

-fundingData := [][]interface{}{
-    {isolatedInsuranceFundAddr, tc.isolatedInsuranceFundBalance},
-    {crossInsuranceFundAddr, tc.crossInsuranceFundBalance},
+fundingData := []fundingTestData{
+    {address: isolatedInsuranceFundAddr, amount: tc.isolatedInsuranceFundBalance},
+    {address: crossInsuranceFundAddr, amount: tc.crossInsuranceFundBalance},

561-580: Consider extracting balance verification into a helper function.

The balance verification logic could be made more reusable and cleaner by extracting it into a helper function.

Consider creating a helper:

func verifyBalance(
    t *testing.T,
    ctx sdk.Context,
    bankKeeper types.BankKeeper,
    addr sdk.AccAddress,
    expectedAmount *big.Int,
) {
    require.Equal(
        t,
        sdk.NewCoin(
            asstypes.AssetUsdc.Denom,
            sdkmath.NewIntFromBigInt(expectedAmount),
        ),
        bankKeeper.GetBalance(ctx, addr, asstypes.AssetUsdc.Denom),
    )
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4a39816 and e2cd331.

📒 Files selected for processing (3)
  • protocol/testutil/keeper/listing.go (9 hunks)
  • protocol/x/listing/keeper/listing_test.go (5 hunks)
  • protocol/x/subaccounts/keeper/transfer.go (3 hunks)
🧰 Additional context used
📓 Learnings (1)
protocol/x/subaccounts/keeper/transfer.go (2)
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
PR: dydxprotocol/v4-chain#2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
🔇 Additional comments (9)
protocol/testutil/keeper/listing.go (4)

14-14: LGTM: Import statements are properly organized.

The new imports for assetskeeper and subaccountskeeper are correctly added and follow the existing import grouping pattern.

Also applies to: 18-18


71-71: LGTM: Keeper initialization changes are well-structured.

The changes maintain proper initialization order and dependency injection:

  1. Assets keeper is initialized before its dependents
  2. Subaccounts keeper is initialized with all required dependencies
  3. Bank keeper renaming is consistently applied

Also applies to: 77-77, 121-127, 141-150, 159-159


201-201: LGTM: ListingKeeper creation properly updated.

The createListingKeeper function is correctly modified to:

  1. Accept the new subaccountsKeeper parameter
  2. Pass it to the NewKeeper constructor

Also applies to: 222-222


42-44: Verify the impact of bankKeeper renaming.

The addition of new keeper parameters looks good. However, let's verify that the renaming of bankKeeper to bankKeeper_out doesn't have unintended consequences.

Also applies to: 189-190

protocol/x/subaccounts/keeper/transfer.go (2)

525-528: 🛠️ Refactor suggestion

Standardize error handling for USDC asset.

The error handling for USDC asset existence is inconsistent with the codebase patterns. Other functions panic in this case, as seen in the TransferInsuranceFundPayments function.

Consider using the same error handling pattern:

-	_, exists := k.assetsKeeper.GetAsset(ctx, assettypes.AssetUsdc.Id)
-	if !exists {
-		return fmt.Errorf("USDC asset not found in state")
-	}
+	_, _, err = k.assetsKeeper.ConvertAssetToCoin(
+		ctx,
+		assettypes.AssetUsdc.Id,
+		isolatedInsuranceFundBalance,
+	)
+	if err != nil {
+		// Panic if USDC does not exist.
+		panic(err)
+	}

Likely invalid or redundant comment.


569-569: Verify the hardcoded cross-collateral pool address.

The hardcoded types.ModuleAddress needs verification to ensure it's the correct address for the cross-collateral pool.

Also applies to: 570-570

✅ Verification successful

Let me gather more specific information about the subaccounts module address usage.


Based on the gathered information, I can now provide the final response:

The hardcoded types.ModuleAddress is correctly used as the cross-collateral pool address.

The ModuleAddress is properly defined in the subaccounts module as the module's main address (dydx1v88c3xv9xyv3eetdx0tvcmq7ung3dywp5upwc6) and is consistently used throughout the codebase for managing the cross-collateral pool. This is verified by:

  • The address is derived from the module name using authtypes.NewModuleAddress(ModuleName)
  • It's extensively tested in transfer and subaccount tests
  • Its usage is consistent with the module's design for handling cross-perpetual collateral pools
  • The implementation matches the comments describing cross-collateral pool functionality
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of ModuleAddress constant
# Test: Search for other occurrences of ModuleAddress to confirm its usage
rg -A 5 "ModuleAddress.*=.*" 

Length of output: 2316


Script:

#!/bin/bash
# Check the definition and usage of ModuleAddress in subaccounts types
rg -A 5 "ModuleName.*=.*" protocol/x/subaccounts/types/

Length of output: 384


Script:

#!/bin/bash
# Check where this ModuleAddress is used in the subaccounts module
rg "ModuleAddress" protocol/x/subaccounts/

Length of output: 10109


Script:

#!/bin/bash
# Check for any cross-collateral pool related constants or configurations
rg -i "cross.*collateral.*pool" protocol/x/subaccounts/

Length of output: 1266

protocol/x/listing/keeper/listing_test.go (3)

9-9: LGTM: Import additions are appropriate.

The new imports for bank testutil and sdkmath are necessary for the new test functionality.

Also applies to: 16-16


429-438: LGTM: Well-structured test setup.

The test structure is clear and the test cases are well-organized.


551-558: LGTM: Proper validation of market type change.

The test correctly validates that the perpetual's market type has been upgraded to cross.

@hwray
Copy link
Contributor Author

hwray commented Nov 20, 2024

closing, tests will go in the previous PR in this stack

@hwray hwray closed this Nov 20, 2024
@hwray hwray deleted the harry/upgrading-markets-tests branch November 20, 2024 19:48
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.

1 participant