# 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. 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. We call assetType, the 250-bit hash of assetInfo **_and quantum. It enables StarkEx to convert off-chain \_balance to on-chain balance

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. Selector, the 4-byte constant specifying the asset standard. Either ETH, ERC20, or ERC721.

2. Address **(if relevant), __the asset contract address

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

def getEthAssetInfo():   ETH_SELECTOR = '0x8322fff2' # '0x8322fff2' = bytes4(keccak256(“ETH()”))       asset_info = ETH_SELECTOR   return asset_info​​def getEthAssetType(quantum):    asset_info = getEthAssetInfo()   asset_type = keccak256(asset_info, quantum)                & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_type​​def getEthAssetId(quantum):   asset_id = getEthAssetType(quantum)   return asset_id

### ERC20

def getErc20AssetInfo(address):   ERC20_SELECTOR = '0xf47261b0'   # '0xf47261b0' = bytes4(keccak256('ERC20Token(address)'))    asset_info = ERC20_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')   # For ERC20, asset_info is 36 bytes long   return asset_info​​def getErc20AssetType(quantum, address):   asset_info = getErc20AssetInfo(address)   asset_type = keccak256(asset_info, quantum)                & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_type​​def getErc20AssetId(quantum, address):   asset_id = getErc20AssetType(quantum, address)   return asset_id

### ERC721

def getErc721AssetInfo(address):   ERC721_SELECTOR = '0x02571792'   # 0x02571792 = bytes4(keccak256('ERC721Token(address,uint256)'))   asset_info = ERC721_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')   # For ERC721, asset_info is 36 bytes long.   return asset_info​​def getErc721AssetType(address):   asset_info = getErc721AssetInfo(address)   asset_type = keccak256(asset_info, 1)                & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_type​​def getErc721AssetId(token_id, address):   asset_type = getErc721AssetType(address)   asset_id = keccak256('NFT:', asset_type, token_id)               & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_id

### Mintable ERC721

def getErcMintable721AssetInfo(address):   MINTABLE_ERC721_SELECTOR = '0xb8b86672'   # 0xb8b86672 = bytes4(keccak256('MintableERC721Token(address,uint256)'))   asset_info = MINTABLE_ERC721_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')   # For Mintable ERC721, asset_info is 36 bytes long.   return asset_info​​def getMintableErc721AssetType(address):   asset_info = getErcMintable721AssetInfo(address)   asset_type = keccak256(asset_info, 1)                & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_type​​def getMintableErc721AssetId(minting_blob, address):   asset_type = getMintableErc721AssetType(address)   blob_hash = keccak256(minting_blob)   asset_id = keccak256('MINTABLE:', asset_type, blob_hash)               & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   asset_id = asset_id                | 0x4000000000000000000000000000000000000000000000000000000000000000   return asset_id

### Mintable ERC20

def getErcMintable20AssetInfo(address):   MINTABLE_ERC20_SELECTOR = '0x68646e2d'   # 0xb8b86672 = bytes4(keccak256('MintableERC20Token(address)'))   asset_info = MINTABLE_ERC20_SELECTOR + bytes.fromhex(address[2:]).rjust(32, b'\0')   # For Mintable ERC20, asset_info is 36 bytes long.   return asset_info​​def getMintableErc20AssetType(address, quantum):   asset_info = getErcMintable20AssetInfo(address)   asset_type = keccak256(asset_info, quantum)                & 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   return asset_type​​def getMintableErc20AssetId(minting_blob, address, quantum):   asset_type = getMintableErc721AssetType(address, quantum)   blob_hash = keccak256(minting_blob)   asset_id = keccak256('MINTABLE:', asset_type, blob_hash)               & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF   asset_id = asset_id                | 0x4000000000000000000000000000000000000000000000000000000000000000   return asset_id