FuelLabs/sway-standards

SRC20: A method to retrieve assets

andy-thomason opened this issue · 5 comments

Motivation

SRC20 has a total_assets() method to get the number of assets present and we have new log types to retrieve these data
through log scraping.

However it is still impossible retrieve contract metadata entirely from state as we cannot make any assumptions about the AssetId or sub_id.

Might it not be a good idea to add a method:

    /// Returns the Asset ID at a certain index.
    ///
    /// # Returns
    ///
    /// * [Option<AssetId>] - The Asset ID at a certain index or None if out of bounds.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract: ContractId) {
    ///     let contract_abi = abi(SRC20, contract);
    ///     let asset = contract_abi.asset(0);
    ///     assert(asset.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn asset(index: u64) -> Option<AssetId>;

With this we can enumerate contained assets.

Note that if sub_id < total_assets then this is unnecessary.

I'm not sure this is the right approach, as this requires significant ($O(n)$) state to store all these assets. It also requires contracts to "order" their assets, which they may not want to.

If you could suggest another way to enumerate assets or sub_ids, this would be useful.

A simpler approach would be to simply require sequential sub_ids.

A contract could choose to return sequential sub_ids or use a mapping from asset index to asset.

The former requires zero storage and the latter only one storage slot per asset.

Note that the majority of the current SRC20 implementations use sub_id = 0 and have only one asset requiring no
extra storage to implement this.

I currently have to do symbolic execution of the contracts to impute the assets. Not an option for the causal user.