# Asset Precision Differences

Source: https://developers.bitgo.com/docs/oes-partner-asset-precision

## Overview

BitGo supports the full divisibility of each asset (documented in the [Coins and Tokens](/coins) table). If your platform supports only smaller divisibilities, BitGo must calculate the precision of the maximum and minimum amounts on a per transaction basis. This page provides examples of three assets (ETH, GUSD, and USDT) that you can reference to better understand how BitGo calculates and validates precision.

BitGo uses the following terms when calculating precision:

* **Base Unit** - Smallest measurable unit of an asset.
    * Example: A wei.
* **Big Unit** -  Largest measurable unit of an asset.
    * Example: An ether.
* **Divisibility** - Amount of base units per big unit.
    * Example: Ether is divisible by 10<sup>-18</sup>. Therefore, 1 ether = 1,000,000,000,000,000,000 wei.
* **Precision** - Total maximum number of digits that can be used to represent a value.
    * Example: BitGo supports a maximum of 32 digits for any value. Therefore the maximum amount of ether that BitGo can display is 99,999,999,999,999.999999999999999999 ETH.
* **Scale** - Number of digits to the right of a decimal in a representation.
    * Example: 1 wei = 0.000000000000000001 ether. Therefore, the scale is 18.

---

## Asset Precision & Trading Units

The following table shows the precision and scale that BitGo uses versus an example partner.

| Asset | Asset Divisibility | BitGo Precision | BitGo Scale[^1] | Partner Precision | Partner Scale | BitGo Base Units<br/>(Minimum Trading Unit) | BitGo Base Units<br/>(Maximum Trading Amount) |
| :---- | :----------------- | :-------------- | :------------------------------------------------ | :---------------- | :------------------ | :------------------------------------------ | :-------------------------------------------- |
| ETH   | 10¹⁸               | 32              | 18                                                | 28                | 8                   | 10¹⁰                                        | 10³¹ - 1                                      |
| GUSD  | 10²                | 32              | 2                                                 | 28                | 5                   | 10⁰                                         | 10²⁴ - 1                                      |
| USDT  | 10⁶                | 32              | 6                                                 | 28                | 5                   | 10¹                                         | 10²⁸ - 1                                      |

[^1]: Always equals log(asset divisibility).

## Minimum Trading Unit

BitGo uses the following formulas to calculate minimum trading units:

* BitGo minimum trading big unit = 1/10<sup>BitGo scale</sup>
* Partner minimum trading big unit = 1/10<sup>partner scale</sup>
* Minimum trading base unit = 10<sup>log(asset divisibility)</sup> - min(BitGo scale, partner scale)
* Minimum trading big unit = minimum trading base unit / asset divisibility

##### USDT

* BitGo minimum trading big unit: 1/10<sup>6</sup> = 10<sup>-6</sup> USDT
* Partner minimum trading big unit: 1/10<sup>5</sup> = 10<sup>-5</sup> USDT
* Minimum trading base unit: 10<sup>6</sup> - min(6, 5) = 10<sup>1</sup> = 10 base units
* Minimum trading big unit: 10/10<sup>6</sup> = 10<sup>-5</sup> USDT

##### GUSD

* BitGo minimum trading big unit: 1/10<sup>2</sup> = 10<sup>-2</sup> GUSD
* Partner minimum trading big unit: 1/10<sup>5</sup> = 10<sup>-5</sup> GUSD
* Minimum trading base unit: 10<sup>2</sup> - min(2, 5) = 10<sup>0</sup> = 1 base unit
* Minimum trading big unit: 1 / 10<sup>2</sup> = 10<sup>-2</sup> GUSD

##### ETH

* BitGo minimum trading big unit: 1/10<sup>18</sup> = 10<sup>-18</sup> ETH
* Partner minimum trading big unit: 1/10<sup>8</sup> = 10<sup>-8</sup> ETH
* Minimum trading base unit: 10<sup>18</sup> - min(18, 8) = 10<sup>10</sup> = 10<sup>10</sup> base units
* Minimum trading big unit: 10<sup>10</sup> / 10<sup>18</sup> = 10<sup>-8</sup> ETH

---

## Maximum Trading Amount

BitGo uses the following formulas to calculate maximum trading units:

* Overflow buffer = 10<sup>2</sup> base units
* Maximum trading base units = 10<sup>min(BitGo precision - BitGo scale, partner precision - partner scale) + log(asset divisibility) - log(overflow buffer) + 1</sup> - 1
* Maximum trading big units = maximum trading base units / asset divisibility

##### ETH

* Calculation:
10<sup>min(32 - 18, 28 - 8) + 18 - 2 + 1</sup> - 1 = 10<sup>min(14, 20) + 18 - 2 + 1</sup> - 1 = 10<sup>14 + 18 - 2 + 1</sup> - 1 = 10<sup>31</sup> - 1 base units
* Maximum trading big units: (10<sup>31</sup> - 1) / 10<sup>18</sup> ETH

##### GUSD

* Calculation: 
10<sup>min(32 - 2, 28 - 5) + 2 - 2 + 1</sup> - 1 = 10<sup>min(30,23) + 2 - 2 + 1</sup> - 1 =10<sup>23 + 2  - 2 + 1</sup> - 1= 10<sup>24</sup> - 1 base units
* Maximum trading big units: 
(10<sup>24</sup> - 1) / 10<sup>2</sup> GUSD

##### USDT

* Calculation: 
10<sup>min(32 - 6, 28 - 5) + 6 - 2 + 1</sup> - 1 = 10<sup>min(26,23) + 6 - 2 + 1</sup> - 1 = 10<sup>28</sup> - 1 base units
* Maximum trading big units: 
(10<sup>28</sup> - 1) / 10<sup>6</sup> USDT

---

## Acceptance Scenarios

### Allocate and Deallocate

In this example, a client allocates or deallocates 0.00005 to or from the partner:

* Client converts: round(0.00005 * 10<sup>6</sup>) = 50
* BitGo registers: 50
* 5 mod 10 base units = 0
* 50 < 10<sup>28</sup> - 1 base units → **Valid**

### Trade

In this example, a partner fills a client's trade order of 0.0005 GUSD. However, BitGo only partially fills the trade due to the client accumulating dust that they can't withdraw or deallocate. Specifically:

* Theres an amount in the partner's trading account that's so small that BitGo doesn't track it in off-chain custody.
* The client can't withdraw the small amount from the partner because withdrawals can only happen at BitGo after deallocation from the partner.
* In order for a settlement or deallocation to occur, the amount must be traded away into an amount or currency that's trackable by BitGo.
* BitGo doesn't account for dust at the partner platform during client and partner reconciliations.

### Settlement

In this example, a settlement of 0.00005 USDT occurs between the partner and the client:

* Partner converts: round(0.00005 * 10<sup>6</sup>) = 50
* BitGo registers: 50
* 5 mod 10 base units = 0
* 50 < 10<sup>28</sup> - 1 base units → **Valid**

In this example, a settlement of 0.0005 GUSD occurs between a partner and client:

* Partner converts: round(0.0005 * 10<sup>2</sup>) = 0
* BitGo registers: 0
* Below minimum unit (10<sup>-2</sup> GUSD)
* Action proceeds as **no-op** (no change)

## Rejection Scenarios

### Allocate and Deallocate

In this example, a client attempts to allocate or deallocate 10^{26} USDT to or from a partner:

* Client converts: round(10<sup>26</sup> * 10<sup>6</sup>) = 10<sup>32</sup>
* BitGo registers: 10<sup>32</sup>
* 10<sup>32</sup> mod 10 base units = 0 but 10<sup>32</sup> > 10<sup>28</sup> - 1 base units → **Rejected**

In this example, a client attempts to allocate or deallocate 0.000005 USDT to or from a partner:

* Client converts: round(0.000005 * 10<sup>6</sup>) = 5
* BitGo registers: 5
* 5 mod 10 base units  &ne; 0 → **Rejected**

### Settle

In this example, a partner attempts to settle 0.000005 USDT with a client:

* Partner converts: round(0.000005 * 10<sup>6</sup>) = 5
* BitGo registers: 5
* 5 mod 10 base units &ne; 0 → **Rejected**

In this example, a partner attempts to settle 10^{20} ETH with a client:

* Partner converts: round(10<sup>20</sup> * 10<sup>18</sup>) = 10<sup>38</sup>
* Possible overflow (partner max digits = 20)
* BitGo registers: 10<sup>38</sup>
* 10<sup>38</sup> mod 10<sup>10</sup> base units =0 but 10<sup>38</sup> > 10<sup>31</sup> - 1 base units → **Rejected**
