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
qq
it means that
vv
tokens in StarkEx represent
qvq*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 =
101810^{-18}
WEI). This means that '1' in our system represents 10,000,000 WEI or
101110^{-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
10710^{-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
10810^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
def getErc20AssetInfo(address):
2
ERC20_SELECTOR = '0xf47261b0'
3
# '0xf47261b0' = bytes4(keccak256('ERC20Token(address)'))
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
def getErc20AssetType(quantum, address):
10
asset_info = getErc20AssetInfo(address)
11
asset_type = keccak256(asset_info, quantum)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
def getErc20AssetId(quantum, address):
17
asset_id = getErc20AssetType(quantum, address)
18
return asset_id
Copied!

ERC721

1
def getErc721AssetInfo(address):
2
ERC721_SELECTOR = '0x02571792'
3
# 0x02571792 = bytes4(keccak256('ERC721Token(address,uint256)'))
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
def getErc721AssetType(address):
10
asset_info = getErc721AssetInfo(address)
11
asset_type = keccak256(asset_info, 1)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
def getErc721AssetId(token_id, address):
17
asset_type = getErc721AssetType(address)
18
asset_id = keccak256('NFT:', asset_type, token_id)
19
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
20
return asset_id
Copied!

Mintable ERC721

1
def getErcMintable721AssetInfo(address):
2
MINTABLE_ERC721_SELECTOR = '0xb8b86672'
3
# 0xb8b86672 = bytes4(keccak256('MintableERC721Token(address,uint256)'))
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
def getMintableErc721AssetType(address):
10
asset_info = getErcMintable721AssetInfo(address)
11
asset_type = keccak256(asset_info, 1)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
def getMintableErc721AssetId(minting_blob, address):
17
asset_type = getMintableErc721AssetType(address)
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
def getErcMintable20AssetInfo(address):
2
MINTABLE_ERC20_SELECTOR = '0x68646e2d'
3
# 0xb8b86672 = bytes4(keccak256('MintableERC20Token(address)'))
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
def getMintableErc20AssetType(address, quantum):
10
asset_info = getErcMintable20AssetInfo(address)
11
asset_type = keccak256(asset_info, quantum)
12
& 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
13
return asset_type
14
15
16
def getMintableErc20AssetId(minting_blob, address, quantum):
17
asset_type = getMintableErc721AssetType(address, quantum)
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!
Last modified 6d ago