StarkEx Specific Concepts

# Quantization and Resolution

In the Ethereum blockchain, the amounts of tokens are represented by a 256-bit number. However, for reasons of efficiency, all the amounts in StarkEx are represented by a 64-bit number.
Since the inputs to all the off-chain transactions and some on-chain requests are given in StarkEx representation, it is crucial that the code that generates the transaction signature uses the correct quantization/resolution. Therefore, the quantization/resolution is reflected in the assetId, i.e. a unique StarkEx asset representation, as we explain in detail below.
In this section, we explain how to convert between one representation to the other.

## Quantization

The quantization factor (sometimes referred to as quantum) represents the multiplier of a StarkEx amount of tokens to get the blockchain amount. Namely, if the quantization of an asset is
$q$
it means that
$v$
tokens in StarkEx represent
$q*v$
tokens in blockchain representation.
For example, say that the quantization of ETH in StarkEx is 10,000,000. (Note: In blockchain, ETH amount is represented by WEI, 1 ETH =
$10^{-18}$
WEI). This means that '1' in our system represents 10,000,000 WEI or
$10^{-11}$
ETH on blockchain.
The quantization factor is necessary for every asset that can be represented on-chain. This is clear when looking at the deposit flow. The on-chain deposit transaction gets an unquantized amount of tokens from the user, yet the parameter to the on-chain call is a quantized amount.

## Resolution

The resolution factor represents the reverse direction from quantization. That is, instead of asking "how many WEI are represented by writing '1' in the system" we ask: "what is the number in the system that represents 1 ETH" .
As an example, say that the resolution of ETH is 10,000,000. This means that 10,000,000 tokens in our system represent 1ETH, therefore 1 in the system is
$10^{-7}$
ETH.
In perpetual trading, we use resolution, rather than quantization, for all the synthetic assets. Notice that since these assets are not represented on-chain, quantization is not needed. However, resolution provides the following benefits:
• Since signed external Oracle prices are given in round units, for example, BTC/ETH and not Satoshi/WEI, it makes the translation to the price used in the system, sound.
• Since users usually refer to buying/selling in round units, for example, BTC and not satoshi, it makes the system easier to understand.

# AssetInfo, AssetType and AssetId

Inside StarkEx and independently of their standard (ETH/ERC20/ERC721/Synthetics), all assets have the same APIs.
In the off-chain application, the assetId uniquely identifies the asset for all the off-chain flows (Transfer/Conditional Transfer/Limit Order/Withdrawal)
In perpetual trading, the synthetic assets are not represented on-chain and thus the off-chainassetIdrepresentation is enough for them. The assetId of a synthetic asset is a 120-bit number that represents their identity and resolution. For example, "ETH-8".encode('ascii') represents Ethereum with a resolution of
$10^8$
.
For on-chain assets (non-synthetic assets), the off-chain assetId is cryptographically bound to the identity of the token as represented on-chain (external ERC20/721 for deposit/withdraw goes through, correct quantization, etc), and therefore the calculation of assetId is as follows:
1. 1.
We call assetInfo, the string concatenation of selector (explained below) and address _(if relevant)._ It enables StarkEx to redeem assets according to their initial standard.
2. 2.
We call assetType, the 250-bit hash of assetInfo **_and quantum. It enables StarkEx to convert off-chain \_balance to on-chain balance
3. 3.
We call assetId, a 250-bit number which definition depends on the asset standard. assetId is the only asset identifier off-chain.
To compute assetInfo , assetType and assetId, we need:
1. 1.
Selector, the 4-byte constant specifying the asset standard. Either ETH, ERC20, or ERC721.
2. 2.
Address **(if relevant), __the asset contract address
3. 3.
Quantum **(if relevant), the multiplicative factor from the on-chain 256-bits integer balance to the 63-bits integer used as balance in StarkEx. Only amounts divisible by the quantum can be deposited in the system.
4. 4.
TokenId **(if relevant), __the asset serial number in the context of ERC721

### Computing assetInfo, assetType and assetId

Below you can find a pseudo-code of the computation. Full implementation in JS can be found here.

### ETH

1
def getEthAssetInfo():
2
ETH_SELECTOR = '0x8322fff2' # '0x8322fff2' = bytes4(keccak256(“ETH()”))
3
asset_info = ETH_SELECTOR
4
return asset_info
5
6
7
def getEthAssetType(quantum):
8
asset_info = getEthAssetInfo()
9
asset_type = keccak256(asset_info, quantum)
10
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
11
return asset_type
12
13
14
def getEthAssetId(quantum):
15
asset_id = getEthAssetType(quantum)
16
return asset_id
Copied!

### ERC20

1
2
ERC20_SELECTOR = '0xf47261b0'
3
4
asset_info = ERC20_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')
5
# For ERC20, asset_info is 36 bytes long
6
return asset_info
7
8
9
10
11
asset_type = keccak256(asset_info, quantum)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
17
18
return asset_id
Copied!

### ERC721

1
2
ERC721_SELECTOR = '0x02571792'
3
4
asset_info = ERC721_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')
5
# For ERC721, asset_info is 36 bytes long.
6
return asset_info
7
8
9
10
11
asset_type = keccak256(asset_info, 1)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
17
18
asset_id = keccak256('NFT:', asset_type, token_id)
19
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
20
return asset_id
Copied!

### Mintable ERC721

1
2
MINTABLE_ERC721_SELECTOR = '0xb8b86672'
3
4
asset_info = MINTABLE_ERC721_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')
5
# For Mintable ERC721, asset_info is 36 bytes long.
6
return asset_info
7
8
9
10
11
asset_type = keccak256(asset_info, 1)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
17
18
blob_hash = keccak256(minting_blob)
19
asset_id = keccak256('MINTABLE:', asset_type, blob_hash)
20
& 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
21
asset_id = asset_id
22
| 0x400000000000000000000000000000000000000000000000000000000000000
23
return asset_id
Copied!

### Mintable ERC20

1
2
MINTABLE_ERC20_SELECTOR = '0x68646e2d'
3
4
asset_info = MINTABLE_ERC20_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')
5
# For Mintable ERC20, asset_info is 36 bytes long.
6
return asset_info
7
8
9
10
11
asset_type = keccak256(asset_info, quantum)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
17
18
blob_hash = keccak256(minting_blob)
19
asset_id = keccak256('MINTABLE:', asset_type, blob_hash)
20
& 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
21
asset_id = asset_id
22
| 0x400000000000000000000000000000000000000000000000000000000000000
23
return asset_id
Copied!