Fungible resource managers
Fungible resource managers are created for fungible resource types. Each type of resource will have its own resource manager that uniquely identifies this type.
The resource managers have methods that allow the owner to perform admin-like actions. This includes minting resources, burning resources, updating the resource metadata, and changing permissions (such as changing whether the resource is mintable, burnable, etc.).
Below is a list of all the functions and methods a fungible resource manager exposes.
Function: create()
The function signature is create(owner_role: OwnerRole, track_total_supply: bool, divisibility: u8, resource_roles: FungibleResourceRoles, metadata: ModuleConfig<MetadataInit>, address_reservation: Option<GlobalAddressReservation>, api: &mut Y)
.
This function is part of the resource package and is intended to be used to create a new resource manager for a new fungible resource.
The owner_role
argument is of type OwnerRole
, which is the following enum:
The two types of owner roles (aside from the None
type) determine whether the owner role can be updated later on or whether it is fixed forever.
The first thing the function does is create a node for the new resource manager. In creating this node, it ensures that the divisibility
specified is valid (which means it is between 0 and 18 inclusive). When doing this, it stores a few fields into this node:
The
divisibility
is stored in its own field.A
TotalSupply
field is created iftrack_total_supply
istrue
.
The roles specified in resource_roles
are also stored as part of the node. This is so that the node can later ensure that any callers of role-protected functions have the required roles to call them. These roles are as follows:
Once the node is created, if the user provided an address reservation in address_reservation
, then the function calls into the kernel to create this address reservation. This is a way for the caller to know and decide the address of this resource ahead of time.
Finally, the node is globalized, which then allows the newly created resource-manager blueprint to be accessible by other blueprints in the global context. The resource manager's address is returned to the caller.
Function: create_with_initial_supply()
The function signature is create_with_initial_supply(owner_role: OwnerRole, track_total_supply: bool, divisibility: u8, initial_supply: Decimal, resource_roles: FungibleResourceRoles, metadata: ModuleConfig<MetadataInit>, address_reservation: Option<GlobalAddressReservation>, api: &mut Y)
.
This function has the same logic as the create()
function but also lets the caller pass in an initial_supply
. This value is then checked to ensure it is divisible by divisibility
, not negative, and not greater than 2**152
.
Additionally, this function returns a bucket containing the minted resources (i.e., the initial supply) along with the address of the newly created resource manager.
Method: mint()
The method signature is mint(amount: Decimal, api: &mut Y)
.
This method is only callable by callers that have access to the MINTER_ROLE
.
This method first ensures that this resource is mintable (meaning it has the Mint
feature enabled). It then ensures that the amount
argument is divisible by this resource's divisibility and that the amount is positive and not greater than the maximum mint amount of 2**152
.
If all of these checks pass, the method creates a new bucket with the minted resources. It also updates the resource's TotalSupply
field by the minted amount if the TrackTotalSupply
feature was set when creating this resource.
Method: burn()
The method signature is burn(bucket: Bucket, api: &mut Y)
.
This method is only callable by callers that have access to the BURNER_ROLE
.
This method first ensures that this resource is burnable (meaning it has the Burn
feature enabled).
It then drops the bucket, which has the same flow as when a fungible bucket's put()
method is called (which puts the resources from another bucket into the bucket that it is called on). The drop_fungible_bucket()
method is used to do this, which ensures that that resource in the bucket originated from this resource manager.
Once the bucket is dropped, the burn flow is complete. Optionally, if this resource's TrackTotalSupply
feature is enabled, the TotalSupply
field is updated to account for the burned resources.
Method: package_burn()
The method signature is package_burn(bucket: Bucket, api: &mut Y)
.
This method is the exact same as the burn()
method, except it can only be called within the package. It allows the burning of tokens by vaults.
Method: drop_empty_bucket()
The method signature is drop_empty_bucket(bucket: Bucket, api: &mut Y)
.
This method is used to drop empty buckets of this resource. It is primarily used to get rid of empty buckets in transactions (because otherwise the transaction will revert if there are buckets still in the worktop).
There are checks here to ensure that the bucket does not have any locked or liquid resources in it.
Method: create_empty_bucket()
The function signature is create_empty_bucket(api: &mut Y)
.
This function creates an empty bucket for this resource and returns it.
Function: create_empty_vault()
The function signature is create_empty_vault(api: &mut Y)
.
This function creates an empty vault for this resource and returns it.
Method: get_resource_type()
The method signature is get_resource_type(api: &mut Y)
.
This method returns the resource type of this resource.
Method: get_total_supply()
The method signature is get_total_supply(api: &mut Y)
.
This method returns the current total supply of this resource.
Method: amount_for_withdrawal()
The method signature is amount_for_withdrawal(api: &mut Y, amount: Decimal, withdraw_strategy: WithdrawStrategy)
.
This method returns the amount of tokens that would actually be withdrawn out of a vault or bucket for a specified amount
and withdraw_strategy
.
Nonfungible resource managers
Nonfungible resource managers are created for nonfungible resource types. Each type of resource will have its own resource manager that uniquely identifies this type.
The resource managers have methods that allow the owner to perform admin-like actions. This includes minting resources, burning resources, updating the resource metadata, and changing permissions (such as changing whether the resource is mintable, burnable, etc.).
The functions and methods in a nonfungible resource manager are very similar to the ones in the fungible resource manager. The differences are the same between fungible and nonfungible buckets (for example, minting is done through an index map of nonfungible IDs, rather than by a specified amount
).
There is an additional mint method for RUID
-type nonfungible resources, but aside from being a different type of nonfungible resource, it is the same.