pendulum-chain / pendulum

GNU General Public License v3.0
43 stars 14 forks source link

Add fee for incoming assets #385

Closed gianfra-t closed 6 months ago

gianfra-t commented 6 months ago

Closes #181

We modify the Trader and Barrier implementations in order to be able to charge fees on the incoming asset sent.

Barrier

Barrier is modified from `AllowUnpaidExecutionFrom to a set of barriers.

The implementation for tuples allows the xcm_executor to iterate throughout all the barriers, until one returns Ok on it's implementation of should_execute.

The most important barrier to keep note of is AllowTopLevelPaidExecutionFrom<Everything>, which filters all XCM messages that do NOT contain an operation that deposits assets in the holding (like WithdrawAsset or DepositReserve) and that does NOT contain a BuyExecution with proper weight limit.

The other defined barriers are:

Trader

The implemented trader is TakeFirstAssetTrader defined here.

This trader will attempt to subtract the the fee in the first defined asset in the BuyExecution instruction, taking it from the holding registry. This implies that it must be deposited into it first by the sender.

The trader will first attempt to convert the MultiAsset defined in the fee to a local asset id. It will then call our custom fee charger implementation to get the amount in the local asset id to be subtracted as fee payment.

To obtain this value, we make use of the base amount given by the WeightToFee implementation, and adjust it by the relative value of that token vs the relay chain token which the previous configuration used 1:1 to charge fees in relay token. (this can be seen here. The fee collected will then be handled by the custom fee handler which is defined here to be transferred in it's entirety to the treasury

gianfra-t commented 6 months ago

I modified the relative valuations (roughly accurate), yet could not find the price for AMPE. As for TakeWeightCredit I'm sorry I missed the comment. This barrier is set as one of the multiple barriers we use. It's purpose as far as I understand is to allow local messages to be sent.

The barrier is simple. It just attempts to consume some credit that is passed when calling execute_xcm_in_credit. When execute_xcm is called, it just actually calls execute_xcm_in_credit with 0 credit see here. I believe the intention of this barrier is so that we can call execute_xcm_in_credit with a message coming from inside the runtime, like here, where we can define the credit we want.

TorstenStueber commented 6 months ago

Oh, of course, I missed that you actually do you TakeWeightCredit. Sure, it is meant for internal use, e.g., when initiating a reserveAssetTransfer from our chain, then the xcm message that will be executed locally will take the weight credit from the transaction fee, so that it totally fine.