Skip to content

feat: implement uniswap-sdk entities#7117

Open
limitofzero wants to merge 29 commits intodevelopfrom
feat/migrate-from-uniswap-sdk-2
Open

feat: implement uniswap-sdk entities#7117
limitofzero wants to merge 29 commits intodevelopfrom
feat/migrate-from-uniswap-sdk-2

Conversation

@limitofzero
Copy link
Contributor

@limitofzero limitofzero commented Mar 6, 2026

Summary

Main goal of the pr: move entities from uniswap-sdk into cowsap. Remove extra deps like invariant, decimals.js, big.js and toFormat, and replaced them by utils in @cowprotocl/currencies (toSignificant etc). Added test coverage.

Unfortunately, there is no bundle size changed because uniswap sdk is using inside other packages, but its a good step to remove it in the future

Also I removed checkByAddress params and token fee data because we don't use it anywhere.

More detailed changes list:

  • Removed: Ether, WETH9, MaxUint256(from uniswap, replaced by cowswap/sdk)
  • All entity implementations that were previously just re-exports:
  • entities/baseCurrency.ts, constants.ts, currency.ts, nativeCurrency.ts, token.ts
  • entities/fractions/fraction.ts, currencyAmount.ts, percent.ts, price.ts
  • utils/toFixed.ts — pure BigInt toFixed (replaces big.js)
  • utils/toSignificant.ts — pure BigInt toSignificant (replaces decimal.js-light)
  • utils/applyFormat.ts — grouping separator formatting
  • Removed packages: @uniswap/sdk-core@3.2.6, decimal.js-light, toformat
  • Removed @uniswap/sdk-core as a dependency
    • calculatePriceImpact.test.ts — replaced WETH9 with WRAPPED_NATIVE_CURRENCIES from cow-sdk
    • recentTokensStorage.ts, TokensTableRow.tsx, common-const/types.ts — minor adjustments following the entity changes

To Test

Need to check rates and rounding of prices, they should work as before this pr. There is no functional changes, just need regress: check rates on swap/twap and in history(also in order progress). Rounding and decimals should be the same.

Summary by CodeRabbit

Release Notes

  • Refactor

    • Improved internal token storage and management system for better reliability
    • Reorganized currency handling and price calculation infrastructure
    • Enhanced approval mechanism for enhanced compatibility
  • Tests

    • Added comprehensive test coverage for currency operations and token management

@vercel
Copy link

vercel bot commented Mar 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cowfi Ready Ready Preview Mar 11, 2026 10:18pm
explorer-dev Ready Ready Preview Mar 11, 2026 10:18pm
swap-dev Ready Ready Preview Mar 11, 2026 10:18pm
widget-configurator Ready Ready Preview Mar 11, 2026 10:18pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
cosmos Ignored Ignored Mar 11, 2026 10:18pm
sdk-tools Ignored Ignored Preview Mar 11, 2026 10:18pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dd59fc12-2281-486b-af85-cfce943e54b1

📥 Commits

Reviewing files that changed from the base of the PR and between 02349cd and 068b850.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • libs/currency/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/currency/package.json

Walkthrough

This pull request introduces a comprehensive currency library layer built on arbitrary-precision arithmetic. It establishes abstract base classes for currency types (BaseCurrency, NativeCurrency, Token), implements core mathematical classes (Fraction, CurrencyAmount, Percent, Price), adds formatting utilities, and refactors imports throughout to use the new local abstractions instead of external dependencies. Several import paths are updated to reflect dependency changes.

Changes

Cohort / File(s) Summary
Import and Dependency Updates
apps/cowswap-frontend/src/legacy/components/Tokens/TokensTableRow.tsx, libs/common-utils/src/calculatePriceImpact.test.ts, libs/currency/package.json
Updated imports: replaced MaxUint256 with MAX_UINT256 from @cowprotocol/cow-sdk; replaced WETH9 import with WRAPPED_NATIVE_CURRENCIES; updated package.json dependencies to use @cowprotocol/cow-sdk and jsbi.
Constructor Parameter Cleanup
libs/common-const/src/types.ts
Removed bypassChecksum parameter from TokenWithLogo and LpToken constructors; added public visibility to logoURI parameter in TokenWithLogo.
Token Storage Refactoring
apps/cowswap-frontend/src/modules/tokensList/utils/recentTokensStorage.ts
Restructured token persistence layer: introduced buildNextStoredTokens, persistRecentTokenSelection, persistStoredTokens, canUseLocalStorage, insertToken, sanitizeStoredTokensMap helpers; shifted from Map-based to per-chain array-based storage with insertion logic and sanitization.
Test Mocking Infrastructure
apps/cowswap-frontend/src/modules/erc20Approve/hooks/useIsApprovalOrPermitRequired.test.ts
Added TestNativeCurrency mock class extending NativeCurrency; replaced direct Ether references with mockNativeToken throughout test scenarios.
Currency Library Base Abstractions
libs/currency/src/entities/baseCurrency.ts, libs/currency/src/entities/nativeCurrency.ts, libs/currency/src/entities/token.ts, libs/currency/src/entities/currency.ts
Established abstract BaseCurrency with chainId, decimals, symbol, name properties; created NativeCurrency and Token implementations; defined Currency union type (NativeCurrency | Token).
Types and Constants
libs/currency/src/entities/constants.ts
Introduced BigintIsh type alias, Rounding and TradeType enums for use across currency entities.
Fraction Mathematical Foundation
libs/currency/src/entities/fractions/fraction.ts, libs/currency/src/entities/fractions/fraction.test.ts
Implemented Fraction class with JSBI for arbitrary-precision arithmetic; supports add, subtract, multiply, divide, comparison, and formatting (toSignificant, toFixed).
Currency Amount Implementation
libs/currency/src/entities/fractions/currencyAmount.ts, libs/currency/src/entities/fractions/currencyAmount.test.ts
Created generic CurrencyAmount<T extends Currency> class extending Fraction; includes fromRawAmount and fromFractionalAmount factories; implements currency-aware arithmetic and wrapped getter.
Percentage and Price Representations
libs/currency/src/entities/fractions/percent.ts, libs/currency/src/entities/fractions/percent.test.ts, libs/currency/src/entities/fractions/price.ts, libs/currency/src/entities/fractions/price.test.ts
Added Percent class scaling by 100 for percentage display; implemented generic Price<TBase, TQuote> class for currency pairs with multiply, quote, and invert operations.
Numeric Formatting Utilities
libs/currency/src/utils/applyFormat.ts, libs/currency/src/utils/applyFormat.test.ts, libs/currency/src/utils/toFixed.ts, libs/currency/src/utils/toSignificant.ts, libs/currency/src/utils/toSignificant.test.ts
Added formatters: applyFormat and stripTrailingZeros for group/decimal separators; toFixed for fixed-decimal rounding; toSignificant with exponent calculation for significant-digit formatting without scientific notation.
Library Re-exports
libs/currency/src/index.ts
Consolidated public API: replaced @uniswap/sdk-core re-exports with local entity exports (BaseCurrency, Currency, CurrencyAmount, Fraction, Percent, Price, NativeCurrency, Token, Rounding, TradeType, BigintIsh).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 Hops of joy for math made precise,
Fractions dance with JSBI's dice,
Currencies align in harmony bright,
From base to token, a unified sight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main objective: implementing Uniswap SDK entities locally within the cowswap codebase.
Description check ✅ Passed The PR description includes a clear summary, detailed changes list, testing guidance, and background information aligning with the template structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/migrate-from-uniswap-sdk-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

public tags: string[] = [],
) {
super(chainId, address, decimals, symbol, name, bypassChecksum)
super(chainId, address, decimals, symbol, name)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we don't use bypassChecksum anywhere

/**
* Represents an ERC20 token with a unique address and some metadata.
*/
export class Token extends BaseCurrency {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

here I removed address check to integrate btc/sol support, will add it later. For our logic it's not necessary

* number of decimal places, using the given rounding mode.
* Never returns scientific notation.
*/
export function toFixed(numerator: string, denominator: string, decimalPlaces: number, rounding: Rounding): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is a replace for toFormat lib method from uniswap sdk

* number of significant digits, using the given rounding mode.
* Never returns scientific notation.
*/
export function toSignificant(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

its a replacement of Big and decimals js, this libs were used as a cascade for formatting, I've adjusted their implementation without these deps

Copy link
Contributor Author

Choose a reason for hiding this comment

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

everything is covered by tests

import { BigintIsh, Rounding } from '../constants'
import { Currency } from '../currency'

export class Price<TBase extends Currency, TQuote extends Currency> extends Fraction {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

copypast from uniswap with our lint adjustments

/**
* A currency is any fungible financial instrument, including Ether, all ERC20 tokens, and other chain-native currencies
*/
export abstract class BaseCurrency {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

copypast with removing unnecessary changes

import JSBI from 'jsbi'

// exports for external consumption
export type BigintIsh = JSBI | string | number
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going remove it and replace on bigint, but in the next iteration to not extend the scope

/**
* applies number formatting to a numeric string that uses '.' as the decimal separator.
*/
export function applyFormat(value: string, format: FormatOptions = {}): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

toFormat analog

import { Rounding } from '../entities/constants'

// returns floor(log10(num/den)), assuming numerator and denominator are positive.
export function findExponent(numerator: bigint, denominator: bigint): number {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's a common alghorithm to calculate exponent to make it faster, complexity is log10(num/den)

@limitofzero limitofzero requested a review from a team March 10, 2026 18:07
@limitofzero limitofzero self-assigned this Mar 10, 2026
@limitofzero limitofzero requested a review from a team March 10, 2026 18:07
@limitofzero limitofzero changed the title [DRAFT] feat: implement uniswap-sdk entities feat: implement uniswap-sdk entities Mar 10, 2026
Copy link
Contributor

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

LGTM!


protected constructor(currency: T, numerator: BigintIsh, denominator?: BigintIsh) {
super(numerator, denominator)
if (!JSBI.lessThanOrEqual(this.quotient, MAX_UINT)) throw new Error('AMOUNT')
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these the actual error messages or placeholders?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

* Represents the native currency of the chain on which it resides, e.g.
*/
export abstract class NativeCurrency extends BaseCurrency {
override readonly isNative: true = true
Copy link
Contributor

Choose a reason for hiding this comment

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

Noticed this pattern in a few different places, wondering whether this is needed, as you can always use instanceof.

},
"dependencies": {
"@uniswap/sdk-core": "^3.0.1"
"@cowprotocol/cow-sdk": "7.4.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

v8 has already been published and merged to develop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thank you, fixed

@Danziger
Copy link
Contributor

@limitofzero Added a few minor comments/questions, but approved.

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.

3 participants