Documentation Index Fetch the complete documentation index at: https://cosmos-docs-selective-ibc-merge.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
The x/precisebank module from cosmos/evm extends the standard x/bank module from 6 to 18 decimal precision for EVM compatibility.
For conceptual understanding of precision handling and mathematical proofs, see Precision Handling .
Overview
The module acts as a wrapper around x/bank, providing:
18 decimal precision for EVM (10^18 sub-atomic units)
Backward compatibility with 6 decimal Cosmos operations
Transparent conversion between precision levels
Fractional balance tracking for sub-test amounts
Developed with contributions from the Kava team.
State
The module maintains fractional balances and remainder (source ):
Object Key Value Description FractionalBalance0x01 + addressmath.IntAccount fractional balance (0 to 10^12-1) Remainder0x02math.IntUncirculated fractional amount
Balance Representation
Full balance calculation:
atest_balance = test_balance × 10^12 + fractional_balance
Where:
test_balance: Stored in x/bank (6 decimals)
fractional_balance: Stored in x/precisebank (0 to 10^12-1)
atest_balance: Full 18-decimal precision
Keeper Interface
The module provides a bank-compatible keeper (source ):
type Keeper interface {
// Query methods
GetBalance ( ctx , addr , denom ) sdk . Coin
SpendableCoins ( ctx , addr ) sdk . Coins
// Transfer methods
SendCoins ( ctx , from , to , amt ) error
SendCoinsFromModuleToAccount ( ctx , module , to , amt ) error
SendCoinsFromAccountToModule ( ctx , from , module , amt ) error
// Mint/Burn methods
MintCoins ( ctx , module , amt ) error
BurnCoins ( ctx , module , amt ) error
}
Extended Coin Support
Automatic handling of “atest” denomination:
Converts between test and atest transparently
Maintains fractional balances for sub-test amounts
Ensures consistency between x/bank and x/precisebank
Operations
Transfer
Handles both integer and fractional components:
// SendCoins automatically handles precision
keeper . SendCoins ( ctx , from , to , sdk . NewCoins (
sdk . NewCoin ( "atest" , sdk . NewInt ( 1500000000000 )), // 0.0015 test
))
Algorithm:
Subtract from sender (update b(sender) and f(sender))
Add to receiver (update b(receiver) and f(receiver))
Update reserve based on carry/borrow
Remainder unchanged (mathematical guarantee)
Mint
Creates new tokens with proper backing:
// MintCoins with extended precision
keeper . MintCoins ( ctx , moduleName , sdk . NewCoins (
sdk . NewCoin ( "atest" , sdk . NewInt ( 1000000000000000000 )), // 1 test
))
Algorithm:
Add to account (update b(account) and f(account))
Decrease remainder (tokens enter circulation)
Update reserve for consistency
Burn
Removes tokens from circulation:
// BurnCoins with extended precision
keeper . BurnCoins ( ctx , moduleName , sdk . NewCoins (
sdk . NewCoin ( "atest" , sdk . NewInt ( 500000000000 )), // 0.0005 test
))
Algorithm:
Subtract from account (update b(account) and f(account))
Increase remainder (tokens leave circulation)
Update reserve for consistency
Events
Standard bank events with extended precision amounts:
Transfer Events
Event Attributes Description transfersender, recipient, amountFull atest amount coin_spentspender, amountExtended precision coin_receivedreceiver, amountExtended precision
Mint/Burn Events
Event Attributes Description coinbaseminter, amountMinted with 18 decimals burnburner, amountBurned with 18 decimals
Queries
gRPC
service Query {
// Get total of all fractional balances
rpc TotalFractionalBalances ( QueryTotalFractionalBalancesRequest )
returns ( QueryTotalFractionalBalancesResponse );
// Get current remainder amount
rpc Remainder ( QueryRemainderRequest )
returns ( QueryRemainderResponse );
// Get fractional balance for an account
rpc FractionalBalance ( QueryFractionalBalanceRequest )
returns ( QueryFractionalBalanceResponse );
}
CLI
Query-Total
Query-Remainder
Query-Balance
# Query total fractional balances
evmd query precisebank total-fractional-balances
# Example output:
# total: "2000000000000atest"
Integration
For EVM Module
Replace bank keeper with precisebank keeper in app.go:
app . EvmKeeper = evmkeeper . NewKeeper (
app . PrecisebankKeeper , // Instead of app.BankKeeper
// ... other parameters
)
For Other Modules
Query extended balances through standard interface:
// Automatically handles atest denomination
balance := keeper . GetBalance ( ctx , addr , "atest" )
// Transfer with 18 decimal precision
err := keeper . SendCoins ( ctx , from , to ,
sdk . NewCoins ( sdk . NewCoin ( "atest" , amount )))
Reserve Account
The reserve account maintains backing for fractional balances:
Reserve_test × 10^12 = Σ(all fractional balances) + remainder
Monitoring Reserve
# Check reserve account balance
evmd query bank balances cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q
# Verify invariant
evmd query precisebank total-fractional-balances
evmd query precisebank remainder
Invariants
Critical invariants maintained by the module:
Invariant Formula Description Supply Total_atest = Total_test × 10^12 - remainderTotal supply consistency Fractional Range 0 ≤ f(n) < 10^12Valid fractional bounds Reserve Backing Reserve × 10^12 = Σf(n) + rFull backing guarantee Conservation Δ(Total_atest) = Δ(Total_test × 10^12)No creation/destruction
Best Practices
Chain Integration
Reserve Monitoring
Track reserve balance for validation
Set up alerts for invariant violations
Regular audits of fractional sums
Migration Path
// Deploy in passive mode
app . PrecisebankKeeper = precisebankkeeper . NewKeeper (
app . BankKeeper ,
// Fractional balances start at zero
)
Testing
// Verify fractional operations
suite . Require (). Equal (
expectedFractional ,
keeper . GetFractionalBalance ( ctx , addr ),
)
dApp Development
Balance Queries
// Query in atest (18 decimals)
const balance = await queryClient . precisebank . fractionalBalance ({
address: "cosmos1..."
});
Precision Handling
// Convert between precisions
const testAmount = atestAmount / BigInt ( 10 ** 12 );
const atestAmount = testAmount * BigInt ( 10 ** 12 );
Security Considerations
Overflow Protection
All arithmetic uses checked math
Fractional values bounded to [0, 10^12)
Integer overflow impossible by design
Atomicity
Balance updates are atomic
Reserve adjustments in same transaction
No intermediate states visible
Precision Guarantees
No precision loss during operations
All fractional amounts preserved
Rounding only at display layer
Storage Impact
Additional O(n) storage for accounts with fractional balances
Most accounts have zero fractional balance (no storage)
Reserve account: single additional balance
Computation
Constant time operations for all transfers
Single addition/multiplication for balance queries
~10% gas overhead for fractional updates
Optimization
Lazy initialization (fractional balances start at zero)
Sparse storage (only non-zero fractions stored)
Batch operations maintain efficiency
Troubleshooting
Common Issues
Issue Cause Solution ”fractional overflow” Fractional > 10^12 Check calculation logic ”insufficient balance” Including fractional Verify full atest balance ”invariant violation” Supply mismatch Audit reserve and remainder
Validation Commands
# Verify module invariants
evmd query precisebank total-fractional-balances
evmd query precisebank remainder
# Check specific account
evmd query bank balances cosmos1... --denom test
evmd query precisebank fractional-balance cosmos1...
References
Source Code