Balance Packing Transfer Efficiency

One of the advantages of having multiple fungible token classes within the same contract is that we can more efficiently transfer different token classes in a single transaction. Most of the efficiency gains can be attributed to the ability to “pack” balances together within a share “storage slot” (256 bits), saving some storage cost. Storing data on the blockchain is one of the most expensive operations. Occupying less storage space can significantly reduce costs, and this might be even truer in the near future.

In our MCT implementation, we store 16 token balances within a single uint256 (a 256 bits unsigned integer) where each token balance occupies 16 bits. You can then keep track of as many token balances as you want by having many uint256 where balances are packed in. However, because of this packing, a given token balance can’t exceed 2¹⁶, or 65,546 . This can be a reasonable limit for many applications. For instance, under what circumstances would a single player need to be able to own more than 2¹⁶ swords? The one instance where this limit could become a problem is for a custodial exchange or proxy contract holding the funds on the behalf of many users, however, it is unclear whether or not this will be a problem in practice. Nevertheless, the amount of packing can easily be modified. For instance, packing 8 token balances in an uint256 instead of 16 increases the balance limit from 65,546 to 4,294,967,296 . One can also do the opposite and increase the amount of token balances packed per uint256 , reducing the balance limit but increasing storage efficiency.

The efficiency gains come from the fact that you can transfer 16 token classes with a single storage update, which is much less costly. However, the balance of these token classes needs to be packed within the same uint256 in order to benefit from this efficiency gain. Indeed, if you transfer 16 token classes where their balance is stored in different uint256 , then you will have 16 storage updates, like a regular ERC-20 transfer. This means that token classes that are more likely to be transferred together should have IDs that are close to each others (e.g. 23, 24, 25, etc.) as well, increasing the likelihood of having many token classes within the same uint256.

These compromises and assumptions might be inappropriate for some applications, but we believe others will find this useful.