[CONTRACT UPGRADE] Ref Swap Accommodate Taxes on NEP-141 Tokens

Background:
Taxes are an important component for many token economies to balance inflationary emissions. Major AMMs such as Pancake Swap accommodate token taxes via slippage adjustments. The buyer/seller must adjust slippage to accommodate the tax to execute the transaction.

In the NEKO tokenomics there is a 5% tax on every swap. Half (2.5%) of the NEKO tax is automatically burned; creating a deflationary mechanic. The remaining 2.5% NEKO tax is deposited into the Fortune Cookie Vault where it is distributed back to the community.

The NEKO tax distribution is verifiable on chain. The burn and transfer to vault are logged inside every swap transaction receipt. Also, the NEKO tax percentage reduces over time as the emissions rate declines. This balances deflationary and inflationary pressures.

Issue:
Ref swaps do not support a tax on NEP-141 tokens.

Attempted Solutions:
We have tried two different methods to implement the NEKO 5% tax function. See below.

Process #1:
If we input 1000 NEKO on Ref swapping UI and have our contract calculate the tax in ft_transfer_call function, and pass the taxed amount to ft_on_transfer.

ext_fungible_token_receiver::ft_on_transfer(
sender_id.clone(),
amount_after_tax.into(),
msg,
receiver_id.clone(),
NO_DEPOSIT,
env::prepaid_gas() - GAS_FOR_FT_TRANSFER_CALL,
)then(ext_self::ft_resolve_transfer(…

Since Ref is expecting 1000 NEKO but only 950 (taxed) NEKO is actually transferred, Ref will return error : account not enough deposit

Process #2:
We don’t change the value pass to ft_on_transfer but instead tax user during ft_resolve_transfer ON TOP OF the amount they need to swap.

If we do process #2 the transaction will succeed. However, the user will never able to use the max swap amount again since they always need to have spare tokens to cover the 5% tax. This is very unintuitive and will result in frequent failed transactions.

Contract Upgrade:
Line 65:

const halfValue = percentOfBigNumber(50, max, token?.decimals);
//Addition check for NEKO
if (token.token_id == “ft.nekotoken.near”){
max = percentOfBigNumber(95, max, token?.decimals);
//Addition line end
}

Conclusion:
This contract upgrade can be implemented for future tokens that utilize a tax to balance their token economy.

The upgrade will allow tokens with more advanced tokenomics to flourish and evolve on NEAR Protocol. There has been at least one project that moved operations from NEAR to another chain due to the lack of token tax support by top AMMs. This is hurting the growth of the NEAR ecosystem.

1 Like

Thanks for your proposal. This is now being considered by the Community Board and REF team. Will post updates on how to deal with his scenario soon.

1 Like

Thanks for this proposal. It brings up a great point about protocol fees in general. The questions at hand are:

  1. Should the Ref protocol provide options for LP’s to both charge protocol fees and issue tokens as rewards on swaps?

  2. What value would this bring to the Ref protocol and users over time?

At a first glance, it seems that these types of things should take place outside of the Ref protocol. However, since Ref is the major “Drop Zone” for liquidity on NEAR native, I believe this is something that warrants a deeper discussion.

2 Likes

This code isn’t for the exchange contract, it’s for the ref website

2 Likes

I am not on the ref dev team, but imho hardcoding tokens with a tax isn’t an ideal solution, and probably not sustainable long-term. Also your fix only applies if the user clicks the max button. It doesn’t stop them from entering in amounts manually that will cause the tax collection to fail.

It might be better if the site got tax info from the token contract and warned the user if they enter in a value that would cause the token contract to prevent the transfer. The neko token has a get_fee_rate method, but I think it would be better, if possible, to have the tax info in the token’s metadata, so the client didn’t have to make a separate call for every token just to check if there is a tax.

I see that get_fee_rate on the neko contract returns the integer 5, which i guess is meant to be 5%. Consider using a datatype that is less ambiguous and that can store rates as fractions of a percent. The ref contract follows the near standard for storing token amounts, and stores fees as a bigint/string (its decimals is 4, so 5% would be “500”). (edit: correction, the ref contract stores them as 32bit integers which you divide by 10000 to get the percentage) Future projects may look to your token as the example when creating their own taxable token, so it’s important to do things in a way that is consistent with the protocol and sustainable long term.

btw, I called ft_metadata on the neko token and saw that the value of decimals was “0”. How can you have a 5% tax on a token that can only be stored in whole numbers? What if I have 2 neko and try to sell/swap 1? Will I end up with zero neko, does the contract prevent the sale/swap…?

How should the ref exchange contract handle swap fees for your token?
For example, the NEKO/wNEAR pool has a total fee of 1% which is broken down like this:
LP Fee: 0.8%
Protocol fee: 0.16%
Referral fee: 0.04%

How can this be done with your token, especially if the swap is for less than 3XX neko?

3 Likes

Hey @beng thank you so much for the insightful comment! We are working on a response and some revisions to the initial proposal which will be published soon.

Hey @beng following up, your comments helped us realize changes needed to be made from our end. We have released a NEKO v2 contract ftv2.nekotoken.near which includes two major upgrades:

  1. NEKO token v2 is updated with 24 decimals (NEAR standard). This change is what required the v2 contract.

  2. NEKO tax information is added to the token metadata. Tax info is now under tax_rate in nft_metadata
    The tax rate is dynamic and can be adjusted externally by admin without re deploying the contract. Our goal is to create the standard for tax tokens on NEAR and this is a big step towards this!

With these changes made, it would be great to circle back on a Ref token tax integration!