Search code examples
smartcontractsnearprotocol

NEAR Protocol Fungible Tokens logic NEP-21


I have questions about: fungible Token example and NEP-21 itself.

  1. It's a possible situation when escrow allowances > 0, but account balance = 0. Is it legal flow and why?
  2. It never checks account_id exists or not. Why? Is it secure?
  3. Anyone can call: inc_allowance/dec_allowance?

And for let owner_id = env::predecessor_account_id(); will be created new account, new escrow allowance automatically (if not exist). Is that logic correct and why?

  1. get_account always created a new account. It looks redundant.

For example:

fn get_account(&self, owner_id: &AccountId) -> Account {
    assert!(env::is_valid_account_id(owner_id.as_bytes()), "Owner's account ID is invalid");
    let account_hash = env::sha256(owner_id.as_bytes());
    self.accounts.get(&account_hash).unwrap_or_else(|| Account::new(account_hash))
}

Will create "always" new account for new owner_id. And it's possible then that account will never be used. So is it really practical to silently "create" an account with get_account?

  1. transfer_from is never check owner_id as the real owner of the account. Is there logic to protect transferring only by real owners?
  2. Why fungible token doesn't have a name/title?
  3. Do the NEAR Protocol have some standard or logic for Fungible Tokens exchange?

Solution

  • It's a possible situation when escrow allowances > 0, but account balance = 0. Is it legal flow and why?

    AFAIU allowance is just a sanity upper bound that prevents abuse. Two accounts can have two allowance for the same account that together sum up to a number larger than account balance.

    It never checks account_id exists or not. Why? Is it secure?

    In a sharded blockchain it is impossible to check for account existence without an asynchronous cross-contract call, since that other account might live on a different shard. Additionally, by the time we get a reply from that other shard this account can be created/deleted.

    Anyone can call: inc_allowance/dec_allowance?

    It can be only called by the owner, see: https://github.com/near/near-sdk-rs/blob/master/examples/fungible-token/src/lib.rs#L106

    And for let owner_id = env::predecessor_account_id(); will be created new account, new escrow allowance automatically (if not exist). Is that logic correct and why?

    Yes. I am not sure, why this would be contradictory.

    get_account always created a new account. It looks redundant.

    It might be redundant, but it also might be optimized out by the compiler in situations like this one: https://github.com/near/near-sdk-rs/blob/master/examples/fungible-token/src/lib.rs#L213

    transfer_from is never check owner_id as the real owner of the account. Is there logic to protect transferring only by real owners?

    It is implied in this check: https://github.com/near/near-sdk-rs/blob/master/examples/fungible-token/src/lib.rs#L174-L180 If it is not the case of an escrow, then env::predecessor_account_id() should be equal to owner_id. So the receipt/transaction must have been sent from the account of the owner.

    Why fungible token doesn't have a name/title?

    We are working on adding metadata to our contracts, see our Q1 OKRs here: https://airtable.com/shrw0AD36eIbfEW02

    Do the NEAR Protocol have some standard or logic for Fungible Tokens exchange?

    We have partners working on implementing something similar, but I don't think we have a standard.