Skip to content

Fungible Token Contract

Izek edited this page Feb 9, 2022 · 4 revisions

Imagine a fungible token contract deployed at ft. Let's say this contract saves all user balances to a Map data structure internally, and adding a key for a new user requires 0.00235Ⓝ. This contract therefore uses the Storage Management standard to pass this cost onto users, so that a new user must effectively pay a registration fee to interact with this contract of 0.00235Ⓝ, or 2350000000000000000000 yoctoⓃ (yocto = 10-24).

For this contract, storage_balance_bounds will be:

{
    "min": "2350000000000000000000",
    "max": "2350000000000000000000"
}

This means a user must deposit 0.00235Ⓝ to interact with this contract, and that attempts to deposit more than this will have no effect (attached deposits will be immediately refunded).

Let's follow two users, Alice with account alice and Bob with account bob, as they interact with ft through the following scenarios:

  1. Alice registers herself
  2. Alice registers Bob
  3. Alice tries to register Bob again
  4. Alice force-closes her account
  5. Bob gracefully closes his account

1. Account pays own registration fee

High-level explanation

  • Alice checks if she is registered with the ft contract.
  • Alice determines the needed registration fee to register with the ft contract.
  • Alice issues a transaction to deposit Ⓝ for her account.

Technical calls

  1. Alice queries a view-only method to determine if she already has storage on this contract with ft::storage_balance_of({"account_id": "alice"}). Using NEAR CLI to make this view call, the command would be:

    near view ft storage_balance_of '{"account_id": "alice"}'
    

The response:

   null
  1. Alice uses NEAR CLI to make a view call.

    near view ft storage_balance_bounds
    

As mentioned above, this will show that both min and max are both 2350000000000000000000 yoctoⓃ.

  1. Alice converts this yoctoⓃ amount to 0.00235 Ⓝ, then calls ft::storage_deposit with this attached deposit. Using NEAR CLI:

     near call ft storage_deposit '' \
         --accountId alice --amount 0.00235
    

The result:

{
    total: "2350000000000000000000",
    available: "0"
}

2. Account pays for another account's storage

Alice wishes to eventually send ft tokens to Bob who is not registered. She decides to pay for Bob's storage.

High-level explanation Alice issues a transaction to deposit Ⓝ for Bob's account.

Technical calls Alice calls ft::storage_deposit({"account_id": "bob"}) with the attached deposit of '0.00235'. Using NEAR CLI the command would be:

   near call ft storage_deposit '{"account_id": "bob"}' \
       --accountId alice --amount 0.00235

The result:

{
  total: "2350000000000000000000",
  available: "0"
}

3. Unnecessary attempt to register already-registered account

Alice accidentally makes the same call again, and even misses a leading zero in her deposit amount.

   near call ft storage_deposit '{"account_id": "bob"}' \
     --accountId alice --amount 0.0235

The result:

{
  total: "2350000000000000000000",
  available: "0"
}

Additionally, Alice will be refunded the 0.0235Ⓝ she attached, because the storage_deposit_bounds.max specifies that Bob's account cannot have a total balance larger than 0.00235Ⓝ.

4. Account force-closes registration

Alice decides she doesn't care about her ft tokens and wants to forcibly recover her registration fee. If the contract permits this operation, her remaining ft tokens will either be burned or transferred to another account, which she may or may not have the ability to specify prior to force-closing.

High-level explanation

Alice issues a transaction to unregister her account and recover the Ⓝ from her registration fee. She must attach 1 yoctoⓃ, expressed in Ⓝ as .000000000000000000000001.

Technical calls

Alice calls ft::storage_unregister({"force": true}) with a 1 yoctoⓃ deposit. Using NEAR CLI the command would be:

   near call ft storage_unregister '{ "force": true }' \
     --accountId alice --depositYocto 1

The result:

   true

5. Account gracefully closes registration

Bob wants to close his account, but has a non-zero balance of ft tokens.

High-level explanation

  1. Bob tries to gracefully close his account, calling storage_unregister() without specifying force=true. This results in an intelligible error that tells him why his account can't yet be unregistered gracefully.
  2. Bob sends all of his ft tokens to a friend.
  3. Bob retries to gracefully close his account. It works.

Technical calls

  1. Bob calls ft::storage_unregister() with a 1 yoctoⓃ deposit. Using NEAR CLI the command would be:

    near call ft storage_unregister '' \
      --accountId bob --depositYocto 1
    

It fails with a message like "Cannot gracefully close account with positive remaining balance; bob has balance N" 2. Bob transfers his tokens to a friend using ft_transfer from the Fungible Token Core standard. 3. Bob tries the call from Step 1 again. It works.

Astro App

AstroDAO App

Tech Stack

Architecture

Entities

DAOs

Users

Groups

Proposals

Bounties

Treasury

Storage

Processes

Transaction

Voting

Completing a Bounty

Lockup Contracts Delegation

Search

Tips and Tricks

Use Cases

Ecosystem

NEAR

Smart Contract

NEAR CLI

Gas

Bond

Clone this wiki locally