Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow fractional fees to be charged to _either_ sender or receiver #1926

Closed
tinker-michaelj opened this issue Aug 4, 2021 · 7 comments · Fixed by #1986
Closed

Allow fractional fees to be charged to _either_ sender or receiver #1926

tinker-michaelj opened this issue Aug 4, 2021 · 7 comments · Fixed by #1986
Assignees
Milestone

Comments

@tinker-michaelj
Copy link
Collaborator

tinker-michaelj commented Aug 4, 2021

⛔ Blocked by #1925

Problem

In 0.16.0, fractional fees are always assessed to the receiver of token units.

So if token T has a fractional fee of 1/10 and Alice sends 100T to Bob, then Bob receives only 90T while the fee collector gets 10T.

That is, essentially Bob is charged 10T.

But sometimes we want Alice to be charged the 10T fee in this scenario.

Solution

Update the FractionalFee type with a bool netOfTransfers flag like,

message FractionalFee {
  Fraction fractional_amount = 1; // The fraction of the transferred units to assess as a fee
  int64 minimum_amount = 2; // The minimum amount to assess
  int64 maximum_amount = 3; // The maximum amount to assess (zero implies no maximum)
  bool netOfTransfers = 4; // If true, assesses the fee to the sender, so the receiver gets the full amount from the token transfer list, and the sender is charged an additional fee; if false, the receiver does NOT get the full amount, but only what is left over after paying the fractional fee
}

Alternatives

No response

@Cooper-Kunz
Copy link

Hey @tinker-michaelj, love to see all of the progress on HIP-18 🎊

Curious what the expected use case of this functionality is?

Why would someone want to offset the costs to the sender, effectively making it 110T charged to the sender in aggregate?

Also curious what implications this would have for wallets, and error/response codes that end up in the SDKs?

Would all wallets, etc., now have to check "which direction" the custom fee is moving, with this change?

Any clarity and opportunity for discussion would be greatly appreciated.

@tinker-michaelj
Copy link
Collaborator Author

tinker-michaelj commented Aug 4, 2021

Hey @tinker-michaelj, love to see all of the progress on HIP-18 🎊

Curious what the expected use case of this functionality is?

Why would someone want to offset the costs to the sender, effectively making it 110T charged to the sender in aggregate?

Hi @Cooper-Kunz! This idea came from the HIP-18 discussion here. The related use case was given as,

I think, for example, that marketplace operator can set sales/buy fees respectively. Without smart contracts.
This is a fee case, especially in these days, which is a typically in NFT marketplaces. Depending on the parameters or apis, it would be better to be able to charge all fees to the seller, charge all fees to the buyer, or split them in a 5:5 ratio.

You also wrote,

Also curious what implications this would have for wallets, and error/response codes that end up in the SDKs?

Would all wallets, etc., now have to check "which direction" the custom fee is moving, with this change?

Any clarity and opportunity for discussion would be greatly appreciated.

The TransactionRecord of a CryptoTransfer with custom fees includes a list of AssessedCustomFee messages that give the fees that were assessed. Right now this message does not include the account(s) that paid each fee; but I can create an issue to add that information as well, if you believe it will be useful.

I don't think any new response codes will be required.

I am going to write up the new RoyaltyFee in an issue later tonight. 👍

@Cooper-Kunz
Copy link

Thank you so much for clarifying @tinker-michaelj - you are the best 😄

In general I think that this provides some really nice functionality.

Regarding,

The TransactionRecord of a CryptoTransfer with custom fees includes a list of AssessedCustomFee messages that give the fees that were assessed. Right now this message does not include the account(s) that paid each fee; but I can create an issue to add that information as well, if you believe it will be useful.

It seems as though an application (e.g. a wallet developer) would need to show two distinct types of fees to users. e.g. those that increase the required transfer amount, and those that simply get deducted from the required transfer amount. I agree that having an additional response code seems unnecessary but providing all of the potentially relevant information in the tx receipt, i.e. the payers of each fee, who they went to, etc., would be very valuable. +1 to that addition.

Very excited about RoyaltyFees 👀

@cmdhema
Copy link

cmdhema commented Aug 4, 2021

Hello @Cooper-Kunz This is proposer of the function. Thank you for your answer!

Until now, fractional fee charge to recerver only. With this impoveing(netOfTransfers) we can provide to option for fee charger.
However, How think about that two way fee charge function?
When token created, the fee can be charged only receiver or sender or divide fee and pay each fixed ratio. (e.g 5:5)

@tinker-michaelj
Copy link
Collaborator Author

Thanks @Cooper-Kunz!!

It seems as though an application (e.g. a wallet developer) would need to show two distinct types of fees to users. e.g. those that increase the required transfer amount, and those that simply get deducted from the required transfer amount. I agree that having an additional response code seems unnecessary but providing all of the potentially relevant information in the tx receipt, i.e. the payers of each fee, who they went to, etc., would be very valuable. +1 to that addition.

Created #1938 as step in this direction.

Very excited about RoyaltyFees 👀

Created #1935! As linked in the issue, updated the custom fees README in a branch here to give a bit more color on the proposed charging behavior.

@tinker-michaelj
Copy link
Collaborator Author

Hello @Cooper-Kunz This is proposer of the function. Thank you for your answer!

Until now, fractional fee charge to recerver only. With this impoveing(netOfTransfers) we can provide to option for fee charger.
However, How think about that two way fee charge function?
When token created, the fee can be charged only receiver or sender or divide fee and pay each fixed ratio. (e.g 5:5)

Ah I think I understand @cmdhema...You want something like a receiver_tax_fraction that says what fraction of the fee that the receiver will have "taxed" away (with the sender needing to pay whatever is left).

Maybe like,

message FractionalFee {
  ...
  /* The fraction of the assessed fee that is "taxed" from the receiver (at no additional cost to the sender).
  *   - If missing, or set to 1, then the sender is not charged anything extra---the entire fee is "taxed" from the receiver.
  *   - But if set to a different fraction such as 1/2, then the sender is charged that fraction of the fee IN ADDITION to the units being sent to the receiver. 
  */
  Fraction receiver_tax_fraction = 4; 
}

@bugbytesinc
Copy link

Ok, I gotta call point of order on this. This can quickly get out of hand and become difficult to "explain".

The simple solution is to not change anything: this puts a burden on the wallet creating the transaction to explain to the user why they need to spend X+% to account for the fractional fee when sending FT to a destination.

The next change was proposed to make it so this % could be a surcharge. I would make the argument that this, while not terribly complicated, is unnecessary because wallets can be programmed as above to make it clear to the account holder "where the funds will go"

Adding a receiver_tax_fraction adds another dimension; and as an implementer, I feel this adds much more complexity than is necessary because in the end, its just semantics: Party A spends $+%, party B gets $, and party C gets %, we don't really need 3 dimensional parameters to potentially express the same outcome in n^3 ways when a single one dimensional parameter will express this matter concisely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment