virto-network / open-runtime-module-library

Substrate Open Runtime Module Library
Apache License 2.0
0 stars 1 forks source link

Support multiple fee recipients #10

Open stanly-johnson opened 2 years ago

stanly-johnson commented 2 years ago

Currently the fee_handler function can handle only one fee recipient fn apply_fees(from: &Account, to: &Account) -> (Account, Percent);

We can improve this function by returning a list of fee recipients fn apply_fees(from: &Account, to: &Account) -> Vec<(Account, Percent)>;

In the release extrinsic, the fee amount should be transferred to all recipients returned by apply_fees provided the count is less than MAX_FEE_RECIPIENTS. It is also important to implement dynamic weights for this extrinsic to account for too many recipients.

olanod commented 2 years ago

Since we are using the bounded vec already I think this is something we can tackle now, I'm thinking the bound of the recipient limit can even be hardcoded(e.g. 8 or 16) to make it easier with the weights.
One extra feature we can have to future proof this more is to return the bounded vec of Fee objects that have besides an account(&self) -> &Account method have a total/apply or equivalent that receives the total amount and returns an amount. A Fee::Percent(_, Percent) does the calculation but other kinds of fee(e.g. Fee::Fixed, Fee::System,...) would just return the already stored amount.

olanod commented 2 years ago

Throwing more ideas to the pot, fees don't have to be just a list of accounts that will receive money from the payer it can also include accounts that will "give money" money to the payer, in other words discounts.
Discounts and promotions are very common in the e-commerce world, our fee handler can be more of a FeeAndDiscountHandler(better name required) that returns similar to the previously mentioned Fee object a struct that can represent fixed amounts or percentages that can be either positive or negative.

To give an example, imagine 🧑‍🌾 Bob selling milk in a marketplace and 👩🏽Alice buying a bottle for 100 MLK, 🐮 milkyplace takes a 3% fee for each bottle that Bob sells, there's also a tax for diary products in their local community of 0.1%, Alice might be the holder of a NFT coupon that gives her a 5% discount and on top of that the Virto nation wants their people to have strong bones so it gives people 50MLK for each bottle. Alice still pays 100MLK(bottle) + 3MLK(fee) + 0.1MLK(tax) + 5MLK(example release incentive) = 108.1MLK, but the since the list now part of the payment detail also includes discounts, those are reserved from the accounts returned from the handler(i.e. 5MLK taken from the coupon issuer and 50MLK from Virto) so when Alice releases the funds it gets back 60MLK🥛!.