> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# PreciseBank

> Extended precision wrapper for x/bank enabling 18 decimal support

The `x/precisebank` module from [cosmos/evm](https://github.com/cosmos/evm) extends the standard `x/bank` module from 6 to 18 decimal precision for EVM compatibility.

<Note>
  For conceptual understanding of precision handling and mathematical proofs, see [Precision Handling](/evm/v0.4.x/documentation/concepts/precision-handling).
</Note>

## 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

<Note>
  Developed with contributions from the [Kava](https://www.kava.io/) team.
</Note>

## State

The module maintains fractional balances and remainder ([source](https://github.com/cosmos/evm/blob/v0.4.1/x/precisebank/types/keys.go)):

| Object              | Key              | Value      | Description                               |
| ------------------- | ---------------- | ---------- | ----------------------------------------- |
| `FractionalBalance` | `0x01 + address` | `math.Int` | Account fractional balance (0 to 10^12-1) |
| `Remainder`         | `0x02`           | `math.Int` | Uncirculated 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](https://github.com/cosmos/evm/blob/v0.4.1/x/precisebank/keeper/keeper.go)):

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
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:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// SendCoins automatically handles precision
keeper.SendCoins(ctx, from, to, sdk.NewCoins(
    sdk.NewCoin("atest", sdk.NewInt(1500000000000)), // 0.0015 test
))
```

**Algorithm:**

1. Subtract from sender (update b(sender) and f(sender))
2. Add to receiver (update b(receiver) and f(receiver))
3. Update reserve based on carry/borrow
4. Remainder unchanged (mathematical guarantee)

### Mint

Creates new tokens with proper backing:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// MintCoins with extended precision
keeper.MintCoins(ctx, moduleName, sdk.NewCoins(
    sdk.NewCoin("atest", sdk.NewInt(1000000000000000000)), // 1 test
))
```

**Algorithm:**

1. Add to account (update b(account) and f(account))
2. Decrease remainder (tokens enter circulation)
3. Update reserve for consistency

### Burn

Removes tokens from circulation:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// BurnCoins with extended precision
keeper.BurnCoins(ctx, moduleName, sdk.NewCoins(
    sdk.NewCoin("atest", sdk.NewInt(500000000000)),  // 0.0005 test
))
```

**Algorithm:**

1. Subtract from account (update b(account) and f(account))
2. Increase remainder (tokens leave circulation)
3. Update reserve for consistency

## Events

Standard bank events with extended precision amounts:

### Transfer Events

| Event           | Attributes                      | Description        |
| --------------- | ------------------------------- | ------------------ |
| `transfer`      | `sender`, `recipient`, `amount` | Full atest amount  |
| `coin_spent`    | `spender`, `amount`             | Extended precision |
| `coin_received` | `receiver`, `amount`            | Extended precision |

### Mint/Burn Events

| Event      | Attributes         | Description             |
| ---------- | ------------------ | ----------------------- |
| `coinbase` | `minter`, `amount` | Minted with 18 decimals |
| `burn`     | `burner`, `amount` | Burned with 18 decimals |

## Queries

### gRPC

```protobuf theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
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

<CodeGroup>
  ```bash Query-Total theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  # Query total fractional balances
  evmd query precisebank total-fractional-balances

  # Example output:
  # total: "2000000000000atest"
  ```

  ```bash Query-Remainder theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  # Query remainder amount
  evmd query precisebank remainder

  # Example output:
  # remainder: "100atest"
  ```

  ```bash Query-Balance theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  # Query account fractional balance
  evmd query precisebank fractional-balance cosmos1...

  # Example output:
  # fractional_balance: "10000atest"
  ```
</CodeGroup>

## Integration

### For EVM Module

Replace bank keeper with precisebank keeper in app.go:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
app.EvmKeeper = evmkeeper.NewKeeper(
    app.PrecisebankKeeper, // Instead of app.BankKeeper
    // ... other parameters
)
```

### For Other Modules

Query extended balances through standard interface:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// 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

```bash theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
# 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 - remainder` | Total supply consistency |
| **Fractional Range** | `0 ≤ f(n) < 10^12`                             | Valid fractional bounds  |
| **Reserve Backing**  | `Reserve × 10^12 = Σf(n) + r`                  | Full backing guarantee   |
| **Conservation**     | `Δ(Total_atest) = Δ(Total_test × 10^12)`       | No creation/destruction  |

## Best Practices

### Chain Integration

1. **Reserve Monitoring**
   * Track reserve balance for validation
   * Set up alerts for invariant violations
   * Regular audits of fractional sums

2. **Migration Path**
   ```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   // Deploy in passive mode
   app.PrecisebankKeeper = precisebankkeeper.NewKeeper(
       app.BankKeeper,
       // Fractional balances start at zero
   )
   ```

3. **Testing**
   ```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   // Verify fractional operations
   suite.Require().Equal(
       expectedFractional,
       keeper.GetFractionalBalance(ctx, addr),
   )
   ```

### dApp Development

1. **Balance Queries**
   ```javascript theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   // Query in atest (18 decimals)
   const balance = await queryClient.precisebank.fractionalBalance({
       address: "cosmos1..."
   });
   ```

2. **Precision Handling**
   ```javascript theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   // 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

## Performance

### 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

```bash theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
# 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

* [PreciseBank Module](https://github.com/cosmos/evm/tree/v0.4.1/x/precisebank) - Implementation
* [Keeper](https://github.com/cosmos/evm/blob/v0.4.1/x/precisebank/keeper/) - Core logic
* [Proto Definitions](https://github.com/cosmos/evm/tree/v0.4.1/proto/cosmos/evm/precisebank/v1) - API specs

### Related Documentation

* [Precision Handling](/evm/v0.4.x/documentation/concepts/precision-handling) - Mathematical foundation
* [VM Module](/evm/v0.4.x/documentation/cosmos-sdk/modules/vm) - EVM integration
* [Bank Module](/sdk/v0.53/build/modules/bank) - Underlying module
