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

Decimal handling (6 and 18) #48

Open
vladjdk opened this issue Apr 3, 2025 · 2 comments
Open

Decimal handling (6 and 18) #48

vladjdk opened this issue Apr 3, 2025 · 2 comments
Assignees

Comments

@vladjdk
Copy link
Member

vladjdk commented Apr 3, 2025

Gracefully handling the interoperability between 6 decimal Cosmos coins and 18-decimal ERC-20 tokens

@dudong2
Copy link

dudong2 commented Apr 7, 2025

Problem

The EVM operates with 18 decimals, while the Cosmos SDK is based on 6 decimals. This mismatch can lead to inconsistencies when handling values below 10^-6 in the EVM.

Currently, cosmos-evm mitigates this by rounding down any fractional value below 10^-6.
However, this approach may cause inconsistencies such as:

  • Value transfers not reflected when the transferred amount is less than 10^-6
  • Logical mismatches in DApps like Uniswap V2, e.g., in ETH → ERC20 swap, due to inaccurate handling of small unit amounts

Test

  1. Transfer of amounts below 10^-6

    • EOA → EOA transfer
    • CA -> EOA transfer
      • Transaction succeeded
      • Transferred amount was zero
  2. Gas fees below 10^-6

    • Transaction succeeded
    • No gas consumed

Solution

  1. Adopt Kava’s x/precisebank module

    • kava/x/precisebank
    • Account-level fractional balances to handle decimal mismatches between the SDK and EVM precisely
    • As a x/bank wrapper, x/precisebank module selectively applies its logic to specified EVM denoms, while falling back to the x/bank logic for all other denoms.
    • All operations are handled in 18-decimal units, while the SDK-level 6-decimal accounting is backed by:
      • Integer balances (like, uatom) for on-chain state
      • Fractional balances for sub-10^-6 precision
    • Pros
      • Enables lossless precision for all token operations, including transfers, mints, and burns
      • Prevents invisible asset loss or rounding inconsistency, especially in DeFi protocols where accuracy is critical
      • Only requires modifying app.go to provide x/vm with x/precisebank keeper in place of the x/bank
    • Cons
      • The module is not yet included on Kava mainnet
      • However, since it would be included in the scope of the upcoming cosmos-evm audit, potential security risks are manageable
  2. Continue using Flooring

    • Discards values below 10^-6 by rounding them down to zero in accordance with SDK-level integer accounting
    • For gas-related concerns, spam can be mitigated by enforcing a min gas price greater than or equal to 10^-6, ensuring that transactions consuming extremely small amounts of gas are still charged meaningfully.
    • Pros
      • Very simple and requires no changes to the current implementation
      • Aligns with existing Cosmos SDK behavior
    • Cons
      • Not battle-tested because it has never been included in the mainnet
      • Any fractional value under 10^-6 from the EVM will be lost on the Cosmos side
      • This can lead to practical inconsistencies for DApps that rely on precise accounting, such as automated market makers or fee-sensitive contracts
      • Requires clear validation that existing DApps are unaffected — not just through testing, but via in-depth architectural understanding of their precision requirements

Summary

Feature x/precisebank Flooring
Precision ✅ Yes ❌ No
Complexity ⚠️ Mid ✅ Low
Security Audit Status ❌ No ❌ No
DApp Compatibility ✅ High ⚠️ Limited
Error Accumulation ✅ Prevented ❌ Not handled

Direction

  • Given that x/precisebank is simple to integrate and provides full precision handling for EVM-SDK decimal mismatch, b-harvest rnd team has agreed to proceed with this solution.
  • All required work is feasible within the current schedule.
    • Additional integration and E2E tests will be added.

@dudong2
Copy link

dudong2 commented Apr 8, 2025

Test coverage:

  • As mentioned in the Direction section, we plan to add integration and E2E tests before finalizing the work.
    • Fuzz tests with arbitrary 18-decimal values
    • Edge cases (e.g., 1 wei transfers, boundary conditions)
    • ERC20 precompile behavior (transfer, balanceOf, totalSupply)
    • IBC transfers with fractional amounts
    • Staking with a(n) values
    • Additional invariant check will be added:

Invariants

  • Existing invariants are comprehensive.
  • But comparison with total supply is missing — we plan to include it

Migration

  • Migration plan is clear and simple:
    • Case 1: Chains already using 18-decimal denoms in both SDK and EVM (e.g., Injective with ainj)
      → No precision mismatch, x/bank can remain

    • Case 2: Chains using 6-decimal denoms in SDK (e.g., uatom)
      → All fractional balances are effectively zero
      → Migration is as simple as replacing x/bank with x/precisebank

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

No branches or pull requests

2 participants