Skip to content
This repository was archived by the owner on Aug 30, 2022. It is now read-only.
This repository was archived by the owner on Aug 30, 2022. It is now read-only.

[feature/standartization] Transfer with fee #11

@Avm07

Description

@Avm07

Sometimes business model for token smart contract want have fee from token transfer. We need standard interface how to do transfer with fee, count fees, inform receiver/sender from transaction payload, which will be used in blockchain history solution such as Hyperion, Chronicle, dfuse etc.

One of possible signature and realization for fee = 1% * quantity:

      * Allows `from` account to transfer to `to` account the `quantity - fee` tokens.
      * One account is debited, smart contract account is credited with fee tokens and the `to` account is credited with quantity - fee tokens.
      *
      * @param from - the account to transfer from,
      * @param to - the account to be transferred to,
      * @param quantity - the quantity of tokens to be transferred,
      * @param fee - the quantity of tokens to be paid as commission,
      * @param memo - the memo string to accompany the transaction.

      [[eosio::action]] void transfer(const name& from, const name& to, const asset& quantity, const asset& fee, const string&  memo);
void token::transfer( const name& from,
                      const name& to,
                      const asset& quantity,
                      const asset& fee,
                      const string&  memo )
{
    check( from != to, "cannot transfer to self" );
    require_auth( from );
    check( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.code();
    stats statstable( get_self(), sym.raw() );
    const auto& st = statstable.get( sym.raw() );

    require_recipient( from );
    require_recipient( to );

    check( quantity.is_valid(), "invalid quantity" );
    check( fee.is_valid(), "invalid fee" );
    check( quantity.amount > 0, "must transfer positive quantity" );
    check( quantity.amount > 1, "can not transfer minimum amount");
    check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    check( fee.symbol == quantity.symbol, "fee symbol precision mismatch" );
    check( is_valid_fee(fee), "invalid fee quantity" );
    check( memo.size() <= 256, "memo has more than 256 bytes" );

    auto payer = has_auth( to ) ? to : from;

    sub_balance( from, quantity );
    add_balance( get_self(), fee, payer );
    add_balance( to, quantity - fee, payer );
}

bool token::is_valid_fee( const asset& quantity, const asset& fee )
{
      return fee == count_fee(quantity) ? true : false;
}

asset token::count_fee( const asset& quantity )
{
      return (quantity.amount > 100 ? asset(quantity.amount / 100, quantity.symbol) : asset(1, quantity.symbol));
}

So from transaction history we can calculate how much tokens received(quantity - fee).
Total fees received by summing all transfer transactions fee field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions