Skip to content

Commit 5f70a94

Browse files
author
Qiu-INJ
committed
Add annotations for decimal utilty.
1 parent c1cc34b commit 5f70a94

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/injective/utils.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,35 @@
11
from decimal import Decimal
2+
"""
3+
One thing you may need to pay more attention to is how to deal with decimals in injective exchange.
4+
As we all known, different crypto currecies require diffrent decimal precisions.
5+
Separately, ERC-20 tokens(e.g. INJ) have decimals of 18 or another number(like 6 for USDT and USDC).
6+
So in injective system that means ** having 1 INJ is 1e18 inj ** and that ** 1 USDT is actually 100000 peggy0xdac17f958d2ee523a2206206994597c13d831ec7**.
27
8+
For spot markets, a price reflects the ** relative exchange rate ** between two tokens.
9+
If the tokens have the same decimal scale, that's great since the prices
10+
become interpretable e.g. USDT/USDC (both have 6 decimals e.g. for USDT https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract)
11+
or MATIC/INJ (both have 18 decimals) since the decimals cancel out.
12+
Prices however start to look wonky once you have exchanges between two tokens of different decimals, which unfortunately is most pairs with USDT or USDC denominations.
13+
As such, I've created some simple utility functions by keeping a hardcoded dictionary in injective-py and you can aslo achieve such utilities by yourself
14+
(e.g. you can use external API like Alchemy's getTokenMetadata to fetch decimal of base and quote asset).
315
16+
So for INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12.
17+
Note that this market also happens to have a MinPriceTickSize of 1e-15.
18+
This makes sense since since it's defining the minimum price increment of the relative exchange of INJ to USDT.
19+
Note that this market also happens to have a MinQuantityTickSize of 1e15.
20+
This also makes sense since it refers to the minimum INJ quantity tick size each order must have, which is 1e15/1e18 = 0.001 INJ.
21+
"""
422
def price_float_to_string(price, base_decimals, quote_decimals, precision=18) -> str:
23+
"""transfer price[float] to string which satisfies what injective exchange backend requires
24+
25+
Args:
26+
price ([float]): normal price, you can read it directly in exchange front-end
27+
base_decimals ([int]): decimal of base asset
28+
quote_decimals ([int]): quote asset's decimal
29+
precision (int, optional): [description]. Defaults to 18.
30+
Returns:
31+
str: relative price for base asset and quote asset. For INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12.
32+
"""
533
scale = Decimal(quote_decimals - base_decimals)
634
exchange_price = Decimal(price) * pow(10, scale)
735
price_string = ("{:."+str(precision)+"f}").format(exchange_price)
@@ -10,6 +38,16 @@ def price_float_to_string(price, base_decimals, quote_decimals, precision=18) ->
1038

1139

1240
def quantity_float_to_string(quantity, base_decimals, precision=18) -> str:
41+
"""transfer quantity[float] to string which satisfies what injective exchange backend requires
42+
43+
Args:
44+
quantity ([type]): normal quantity, you can read it in exchange front-end
45+
base_decimals ([type]): decimal of base asset
46+
precision (int, optional): [description]. Defaults to 18.
47+
48+
Returns:
49+
str: acutally quanity of base asset[data type: string] For 1 INJ, the quantity you end up is 1e18 inj
50+
"""
1351
scale = Decimal(base_decimals)
1452
exchange_quantity = Decimal(quantity) * pow(10, scale)
1553
quantity_string = ("{:."+str(precision)+"f}").format(exchange_quantity)
@@ -18,11 +56,30 @@ def quantity_float_to_string(quantity, base_decimals, precision=18) -> str:
1856

1957

2058
def price_string_to_float(price_string, base_decimals, quote_decimals) -> float:
59+
"""
60+
Args:
61+
price_string ([type]): price with string data type that injective-exchange backend returns
62+
base_decimals ([type]): decimal of base asset
63+
quote_decimals ([type]): decimal of quote asset
64+
65+
Returns:
66+
float: actual price what you can read directly from front-end.
67+
For 6.9e-12 inj/peggy0xdac17f958d2ee523a2206206994597c13d831ec7**, the price you end up getting is 6.9 INJ/USDT.
68+
"""
2169
scale = float(base_decimals - quote_decimals)
2270
return float(price_string) * pow(10, scale)
2371

2472

2573
def quantity_string_to_float(quantity_string, base_decimals) -> float:
74+
"""
75+
76+
Args:
77+
quantity_string ([type]): quantity string that injective-exchange backend returns
78+
base_decimals ([type]): decimal of base asset
79+
80+
Returns:
81+
float: actually quantity, for 1e18 inj, you will get 1 INJ
82+
"""
2683
scale = float(0 - base_decimals)
2784
return float(quantity_string) * pow(10, scale)
2885

0 commit comments

Comments
 (0)