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

feat(wallet): migrate 0x Swap API to v2 #26231

Merged
merged 10 commits into from
Nov 6, 2024
Merged

feat(wallet): migrate 0x Swap API to v2 #26231

merged 10 commits into from
Nov 6, 2024

Conversation

onyb
Copy link
Member

@onyb onyb commented Oct 25, 2024

Resolves brave/brave-browser#41891

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

See STR in linked issue

@onyb onyb requested review from a team as code owners October 25, 2024 15:55
@github-actions github-actions bot added CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet feature/web3/wallet/core chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch puLL-Merge labels Oct 25, 2024
Copy link
Contributor

@Douglashdaniel Douglashdaniel left a comment

Choose a reason for hiding this comment

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

++

@@ -448,74 +448,71 @@ union SwapTransactionParamsUnion {

union SwapQuoteUnion {
JupiterQuote jupiter_quote;
ZeroExQuote zero_ex_quote;
ZeroExQuoteInfo zero_ex_quote;
Copy link
Contributor

Choose a reason for hiding this comment

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

should we change this to zero_ex_quote_info to distinguish from ZeroExQuote? it seems ZeroExQuoteInfo now contains an optional of ZeroExQuote

Copy link
Member Author

Choose a reason for hiding this comment

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

The refactoring here should fix this.

Comment on lines 1009 to 1010
// 0x specific validations
if (quoteUnion?.zeroExQuote?.liquidityAvailable === false) {
return 'insufficientLiquidity'
}

if (quoteErrorUnion?.zeroExError) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In this case, shouldn't quoteErrorUnion.zeroExError. isInsufficientLiquidity == true?
checking both QuoteUnion and QuoteErrorUnion for errors seems odd to me. Also the quoteErrorUnion.zeroExError.isInsufficientAllowance case seems to be ignored.

Copy link
Member Author

Choose a reason for hiding this comment

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

This was actually done because 0x API v2 now returns isInsufficientLiquidity as part of the quote instead of an error response. But now that I think about it, retaining the old interface is cleaner. You can find this change here: review(nuo-xu): reuse ZeroExQuote and drop ZeroExQuoteInfo struct

Also the quoteErrorUnion.zeroExError.isInsufficientAllowance case seems to be ignored

Allowance checks are no longer returned as part of the error response from the API. If this changes in future, will add this back. Meanwhile, the desktop code already handles allowance checks just like LiFi and Squid.

@github-actions github-actions bot removed the chromium-version-mismatch The Chromium version on the PR branch does not match the version on the target branch label Oct 30, 2024
@onyb onyb requested a review from nuo-xu October 30, 2024 08:27
@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Copy link
Collaborator

@supermassive supermassive left a comment

Choose a reason for hiding this comment

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

wallet core lgtm

};

struct ZeroExFees {
ZeroExFee? zero_ex_fee;
};

struct ZeroExQuote {
string price;
Copy link
Contributor

@nuo-xu nuo-xu Nov 5, 2024

Choose a reason for hiding this comment

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

is it possible to keep the price in ZeroExQuote? we are using it to calculate sell_token's market price value. I don't think desktop UI has market value displayed in swap. iOS has an outdated UI still has this Market Price value

Copy link
Member Author

@onyb onyb Nov 5, 2024

Choose a reason for hiding this comment

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

Is it possible to infer this on this client-side like we do on desktop?

rate: new Amount(quote.buyAmount)
.divideByDecimals(toToken.decimals)
.div(new Amount(quote.sellAmount).divideByDecimals(fromToken.decimals)),

In the backend, we no longer have this field and we don't know about the buy/sell token decimals to be able to correctly compute the rate.

Copy link
Contributor

@nuo-xu nuo-xu Nov 5, 2024

Choose a reason for hiding this comment

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

we have no problem with sell amount and buy amount. just the market price for the sell token.
i think iOS can do one of the following:
1. fetch market price for sell token using assetRatioService api instead of from quote response.
2. remove this market price label but need to move that refresh button else where for users to refetch quote.
cc @jamesmudgett and design @kleantzogu

Copy link
Member Author

Choose a reason for hiding this comment

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

My understanding is that "Market Price in ETH" is the exchange rate between buyToken and sellToken. I don't think using the assetRatioService will be correct here, since it's the CEX/global exchange rate and not the one as per the AMM swap quote.

Copy link
Contributor

Choose a reason for hiding this comment

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

you are right. i think this leave us removing that label. i just need to figure out where to put that refetch button.

Copy link
Member Author

Choose a reason for hiding this comment

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

Highlighting again (see #26231 (comment)) that the "Market price in <sellToken>" can be determined using buyAmount and sellAmount formatted with their respective decimals.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that it's "Market price in ETH" and not "Market price of ETH".

Copy link
Contributor

Choose a reason for hiding this comment

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

ah! i mistakenly thought the sell amount and buy amount are from the ZeroExTransaction. ok yeah i think we can using those two values to determine the market price. Thanks!

@nuo-xu nuo-xu requested a review from a team as a code owner November 5, 2024 20:36
Copy link
Contributor

github-actions bot commented Nov 5, 2024

[puLL-Merge] - brave/brave-core@26231

Description

This PR updates the 0x API integration in the Brave Wallet to use the newer allowance-holder API. It modifies the request and response handling for quotes and transactions, updates the data models, and adjusts the UI components to work with the new data structure.

Possible Issues

  1. The removal of the estimatedPriceImpact field from the 0x response might affect the accuracy of displayed price impact information. The new calculation method using fiat values could potentially be less accurate or behave differently in edge cases.

  2. The change in the way routing information is handled (from sources to route.fills) might lead to inconsistencies in how multi-hop or split trades are displayed or processed.

Security Hotspots

  1. The new allowance target address is now being fetched from a predefined list based on the chain ID. Ensure that this list is kept up-to-date and secure, as using an incorrect allowance target could potentially lead to loss of funds.

  2. The removal of the skipValidation parameter in the API requests means that allowance checks are now likely performed on the server-side. Ensure that this doesn't introduce any new attack vectors or ways to bypass important checks.

Changes

Changes

components/brave_wallet/browser/brave_wallet_constants.cc:

  • Added a new function GetZeroExAllowanceHolderAddress to retrieve the allowance holder address for a given chain ID.
  • Removed several chain-specific API URL constants.

components/brave_wallet/browser/brave_wallet_constants.h:

  • Updated constants related to 0x API, including removing chain-specific URLs and adding new allowance holder addresses.
  • Added declaration for GetZeroExAllowanceHolderAddress function.

components/brave_wallet/browser/swap_response_parser.cc:

  • Significantly refactored the parsing logic for 0x API responses to match the new allowance-holder API structure.
  • Updated error handling to match new error response format.

components/brave_wallet/browser/swap_response_parser.h:

  • Updated function signatures to reflect changes in parsing logic.

components/brave_wallet/browser/swap_response_parser_unittest.cc:

  • Updated unit tests to match new response structures and parsing logic.

components/brave_wallet/browser/swap_service.cc:

  • Updated URL construction for 0x API requests to use the new allowance-holder endpoints.
  • Modified request parameter handling to match the new API requirements.
  • Updated error handling and response processing.

components/brave_wallet/browser/swap_service.h:

  • Updated function signatures to reflect changes in service logic.

components/brave_wallet/browser/swap_service_unittest.cc:

  • Updated unit tests to match new service behavior and API structures.

components/brave_wallet/common/brave_wallet.mojom:

  • Updated data structures to match new 0x API response format.

components/brave_wallet_ui/common/async/mocks/bridge.ts:

  • Updated mock data structures to match new 0x API response format.

components/brave_wallet_ui/page/screens/swap/hooks/useSwap.ts:

  • Removed check for isInsufficientAllowance in 0x error handling.

components/brave_wallet_ui/page/screens/swap/hooks/useZeroEx.ts:

  • Updated transaction processing to use gas instead of estimatedGas.

components/brave_wallet_ui/page/screens/swap/swap.utils.ts:

  • Updated quote option generation to use new data structure from 0x API.
  • Modified price impact calculation to use fiat values instead of the removed estimatedPriceImpact field.

ios/brave-ios/Sources/BraveWallet/Crypto/Stores/SwapTokenStore.swift:

  • Updated handling of 0x quote data to match new response structure.
  • Modified price and amount calculations to use new fields.

ios/brave-ios/Sources/BraveWallet/Preview MockContent.swift:

  • Updated mock 0x quote data to match new structure.

ios/brave-ios/Sources/BraveWallet/Preview MockSwapService.swift:

  • Updated mock swap service to use new 0x transaction structure.

ios/brave-ios/Tests/BraveWalletTests/SwapTokenStoreTests.swift:

  • Updated test data to match new 0x quote structure.

Copy link
Collaborator

@StephenHeaps StephenHeaps left a comment

Choose a reason for hiding this comment

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

@onyb @nuo-xu Safer sign isn't showing with Zero Ex anymore (iOS & desktop), is that known / expected with this change?

proportionBps: "10000"
)]
),
sellAmount: "1000000000000000000",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nite: restore the 1 ETH comment

@onyb
Copy link
Member Author

onyb commented Nov 6, 2024

Safer sign isn't showing with Zero Ex anymore (iOS & desktop)

@StephenHeaps Yes this is expected. The contracts are not public yet, so I'm unable to add the parsers right now. Will follow it up in a future PR.

@onyb onyb merged commit 606c380 into master Nov 6, 2024
17 checks passed
@onyb onyb deleted the f/wallet/0x-api-v2 branch November 6, 2024 16:21
@github-actions github-actions bot added this to the 1.73.x - Nightly milestone Nov 6, 2024
@bsclifton bsclifton modified the milestones: 1.73.x - Nightly, 1.74.x - Nightly Nov 6, 2024
@brave-builds
Copy link
Collaborator

Released in v1.75.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet/core feature/web3/wallet puLL-Merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate 0x Swap API to v2
7 participants