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

Convert variants: check for large difference in amount #3958

Merged
merged 2 commits into from
Nov 18, 2024

Conversation

jonator
Copy link
Member

@jonator jonator commented Nov 18, 2024

What is the purpose of the change:

Add more user protection imposing a limit on price impact when converting non-alloy variants, such as USDC.

If the amounts in vs out differ by more than 5% in the quote, block the conversion tx from being possible. Since we're converting like kinds, we can assume the amounts (with respective decimals in place) should be about the same. This is instead of comparing USD values, which may not be accurate if there's issues getting prices.

Linear Task

Hot fix.

Brief Changelog

  • Include in/out amount diff slippage check in isError flag

Testing and Verifying

Tested small change locally

@jonator jonator requested a review from a team November 18, 2024 16:43
Copy link

vercel bot commented Nov 18, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
osmosis-frontend ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 18, 2024 5:43pm
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
osmosis-frontend-datadog ⬜️ Ignored (Inspect) Visit Preview Nov 18, 2024 5:43pm
osmosis-frontend-dev ⬜️ Ignored (Inspect) Visit Preview Nov 18, 2024 5:43pm
osmosis-frontend-edgenet ⬜️ Ignored (Inspect) Nov 18, 2024 5:43pm
osmosis-testnet ⬜️ Ignored (Inspect) Visit Preview Nov 18, 2024 5:43pm

Copy link
Contributor

coderabbitai bot commented Nov 18, 2024

Walkthrough

The pull request introduces modifications to the PortfolioAssetBalancesTable component and the useConvertVariant hook. Changes to the table component include adjustments to button class names for improved responsiveness and clarity, along with refined logic for handling asset actions, particularly for "OSMO" and "ATOM" assets. The useConvertVariant hook now includes a check for significant discrepancies between input and output amounts, enhancing the error handling logic. Overall, the changes focus on improving UI elements and ensuring clear action handling without altering existing functionality.

Changes

File Path Change Summary
packages/web/components/table/portfolio-asset-balances.tsx - Adjusted button class names for consistency.
- Streamlined button class definition in AssetActionsCell.
- Updated onSelectAction for clearer routing of asset actions.
- Enhanced confirmUnverifiedAsset function for better activation button display.
- Updated AssetActionsDropdown for consistency with new button styles.
packages/web/hooks/use-convert-variant.ts - Added isLargeAmountDiff check for discrepancies between input and output amounts.
- Modified error handling logic to include isLargeAmountDiff.
- Added import for Dec from @keplr-wallet/unit.
packages/web/hooks/__tests__/use-convert-variant.test.ts - Added test suite for checkLargeAmountDiff function with three test cases validating its behavior.

Possibly related PRs

Suggested reviewers

  • JoseRFelix
  • MaxMillington

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/web/hooks/__tests__/use-convert-variant.test.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/packages/web/.eslintrc.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.


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: 0

🧹 Outside diff range and nitpick comments (1)
packages/web/hooks/use-convert-variant.ts (1)

153-162: Consider improving code documentation and maintainability

The implementation correctly checks for a significant difference between input and output amounts, with proper null checks and decimal handling. However, a few improvements could make the code more maintainable:

  1. Extract the threshold as a named constant to improve maintainability
  2. Enhance the comments to explain the rationale behind the 95% threshold

Consider this improvement:

+// Threshold for maximum acceptable difference between input and output amounts
+// Set to 95% to protect users from significant value loss during conversion
+const MINIMUM_OUTPUT_RATIO = new Dec("0.95");
+
 // Check for large difference in amount of in v out
-// Include decimals, but we know the amounts should be priced 1:1
+// For non-alloy variants (e.g., USDC), we expect the conversion to maintain
+// approximately equal value. If output is less than 95% of input, we flag it
+// as a potentially unfavorable conversion to protect users.
 const isLargeAmountDiff = useMemo(() => {
   // toDec should include decimals
   const inAmount = variant?.amount.toDec();
   const outAmount = quote?.amount.toDec();
   if (!inAmount || !outAmount || inAmount.isZero()) return false;
   // Out amount should be 95% or more of the input amount
-  return outAmount.quo(inAmount).lt(new Dec("0.95"));
+  return outAmount.quo(inAmount).lt(MINIMUM_OUTPUT_RATIO);
 }, [variant, quote?.amount]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between dba7d07 and e1f1b82.

📒 Files selected for processing (2)
  • packages/web/components/table/portfolio-asset-balances.tsx (2 hunks)
  • packages/web/hooks/use-convert-variant.ts (2 hunks)
🔇 Additional comments (5)
packages/web/hooks/use-convert-variant.ts (3)

1-1: LGTM: Appropriate import for decimal calculations

The addition of Dec from @keplr-wallet/unit is well-placed and necessary for the precise decimal calculations in the new amount difference check.


170-170: LGTM: Error flag properly integrates the new check

The modification correctly incorporates the new amount difference check into the error conditions, effectively preventing conversions with significant value discrepancies.


153-170: Verify interaction with existing slippage protection

The new amount difference check provides user protection at the UI level. However, we should verify its interaction with the existing slippage check in getConvertVariantMessages.

Let's analyze the relationship between these checks:

✅ Verification successful

Let me search for the existing slippage check in getConvertVariantMessages to verify the interaction.


Let me search for the implementation details of the quote handling in variant conversion to understand how the new check interacts with existing protections.


Based on the code analysis, I can now provide a final response about the interaction between the new amount difference check and existing protections.

New UI check complements existing quote protection

The new 5% amount difference check (isLargeAmountDiff) operates at the UI level and is independent of the quote handling in getConvertVariantMessages. It serves as an early warning system before the transaction is even constructed, while any quote-related protections would apply during the actual swap execution.

  • The check uses isError flag to prevent proceeding when output is less than 95% of input
  • This is complementary to existing protections as it:
    • Catches potential issues before transaction construction
    • Provides clear feedback about significant amount differences
    • Does not interfere with quote handling or execution
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential conflicts between the new amount difference check
# and existing slippage protection

# Search for slippage-related code and amount checks
rg -A 5 "slippage|amount.*check" 

# Look for other conversion protection mechanisms
ast-grep --pattern 'maxSlippage = $_'

Length of output: 99978


Script:

#!/bin/bash
# Search for getConvertVariantMessages implementation and any slippage-related checks
rg -A 10 "getConvertVariantMessages" 

# Also search for any other amount difference checks in the codebase
ast-grep --pattern 'amount.$_?.toDec().quo($_).lt($_)'

Length of output: 3462


Script:

#!/bin/bash
# Search for quote-related code in variant conversion
rg -A 15 "quote.*amount" packages/web/hooks/use-convert-variant.ts

# Look for any existing protection mechanisms in the conversion flow
ast-grep --pattern 'function getConvertVariantMessages($$$)'

Length of output: 910

packages/web/components/table/portfolio-asset-balances.tsx (2)

575-575: LGTM! Button styling is consistent with design system.

The styling changes for the activate button maintain consistency with the overall UI design.


590-590: LGTM! Convert button styling aligns with activate button.

The styling changes maintain visual consistency between the convert and activate buttons. However, since this PR introduces checks for large differences in amount during conversion, let's verify the integration with the conversion modal.

✅ Verification successful

Based on the shell script results, I can now generate the final response since I have found evidence of the amount difference check implementation in the codebase.

Amount difference check is properly integrated with conversion logic

The conversion logic includes a safety check that verifies the output amount is at least 95% of the input amount via isLargeAmountDiff in use-convert-variant.ts. This check is properly integrated into the error state handling of the conversion flow, ensuring users are protected from unfavorable conversions.

  • The check is implemented in packages/web/hooks/use-convert-variant.ts and is used to set the error state: isError: isLargeAmountDiff || isQuoteError || isPortfolioAssetsError
  • The 95% threshold is consistent with the e2e tests in swap-router.spec.ts which verify similar protections for token swaps
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration between the convert button and the amount difference check
# Expected: Find the implementation of the amount difference check in the conversion logic

# Look for the conversion-related hooks and their usage
ast-grep --pattern 'useConvertVariant' 

# Look for amount difference check implementation
rg -A 10 'isLargeAmountDiff|amountDiff|difference.*amount'

Length of output: 6379

Copy link
Collaborator

@JoseRFelix JoseRFelix left a comment

Choose a reason for hiding this comment

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

Looks great! I believe we just need a unit test

packages/web/hooks/use-convert-variant.ts Outdated Show resolved Hide resolved
@jonator jonator requested a review from JoseRFelix November 18, 2024 17:36
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 (2)
packages/web/hooks/__tests__/use-convert-variant.test.ts (2)

5-8: Consider additional edge cases and more descriptive test names.

While testing zero input is important, consider:

  1. Adding tests for very small (near-zero) input amounts
  2. Renaming the test to clarify why zero input is a special case (e.g., "skips difference check when input amount is zero")
  3. Adding test cases for negative amounts if they should be handled

10-20: Tests align well with requirements, consider additional scenarios.

The test cases effectively verify the 95% threshold requirement and include good boundary testing. However, consider adding:

  1. Tests with different decimal places (e.g., 1.5, 0.05)
  2. Tests with very large numbers to verify no overflow issues
  3. Tests with maximum decimal precision supported by Dec

Example additions:

test("handles decimal amounts correctly", () => {
  expect(checkLargeAmountDiff(new Dec("1.5"), new Dec("1.425"))).toBe(false); // 95%
  expect(checkLargeAmountDiff(new Dec("1.5"), new Dec("1.424"))).toBe(true);  // 94.9%
});

test("handles large numbers correctly", () => {
  expect(checkLargeAmountDiff(new Dec("1000000"), new Dec("950000"))).toBe(false);
  expect(checkLargeAmountDiff(new Dec("1000000"), new Dec("949999"))).toBe(true);
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e1f1b82 and ed17fb7.

📒 Files selected for processing (2)
  • packages/web/hooks/__tests__/use-convert-variant.test.ts (1 hunks)
  • packages/web/hooks/use-convert-variant.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web/hooks/use-convert-variant.ts
🔇 Additional comments (2)
packages/web/hooks/__tests__/use-convert-variant.test.ts (2)

1-3: LGTM! Appropriate imports for decimal-precise calculations.

The use of Dec from @keplr-wallet/unit ensures precise decimal calculations, which is crucial for financial operations.


1-21: Verify test coverage with the main implementation.

The tests effectively verify the 5% difference threshold mentioned in the PR objectives. Let's ensure the implementation matches these tests.

✅ Verification successful

Let me check the actual implementation to verify it matches the test cases.


Tests align perfectly with implementation

The implementation in use-convert-variant.ts matches the test cases exactly. The checkLargeAmountDiff function uses the same 95% threshold (0.95) and follows the same logic:

  • Returns false for zero input amounts
  • Returns false when output is 95% or more of input amount
  • Returns true when output is less than 95% of input amount
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find and verify the main implementation
ast-grep --pattern 'export function checkLargeAmountDiff($_) {
  $$$
}'

# Check for any other uses of the 0.95 threshold
rg -l "0\.95|95" --type ts

Length of output: 3407


Script:

#!/bin/bash
# Get the implementation of checkLargeAmountDiff
cat packages/web/hooks/use-convert-variant.ts

Length of output: 7775

@jonator jonator merged commit 3ba184a into stage Nov 18, 2024
33 of 34 checks passed
@jonator jonator deleted the jon/convert-variant-price-impact branch November 18, 2024 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants