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

Tx Payment: drop ED requirements for tx payments with exchangeable asset #4488

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

muharem
Copy link
Contributor

@muharem muharem commented May 16, 2024

Drop the Existential Deposit (ED) requirement for the asset amount exchangeable for the fee asset (eg. DOT/KSM) during transaction payments.

This achieved by using SwapCredit implementation of swap, which works with imbalances and does not require a temporary balance account within the transaction payment.

Problem

Currently, every swap during transaction payment, processed with asset A for native asset, must be for an amount greater than the ED of a native asset if the user lacks a native asset account. Since fees are typically smaller, the current implementation necessitates additional swaps to meet the ED during pre_dispatch, with refunds for excess ED swap occurring during post_dispatch. Further details can be found here.

This setup presents an issue where a user is unable to transfer their entire balance and close the account. Instead, the user must transfer slightly less of asset A to ensure there is enough not only for the fee payment but also some extra to meet the ED requirement for their native account during pre_dispatch. In some cases during post_dispatch, the user will have the excess ED swapped back to asset A, while in other cases, it may not be sufficient to meet the ED requirement for asset A, leading it being left in the user's 'temporary' native asset account.

@muharem muharem requested a review from a team as a code owner May 16, 2024 15:30
fellowship-merge-bot bot pushed a commit to polkadot-fellows/runtimes that referenced this pull request May 19, 2024
…310)

Drop the Existential Deposit (ED) requirement for the asset amount
exchangeable for the fee asset (DOT/KSM) during transaction payments.

Currently, every swap during transaction payment, processed with asset
`A` for native asset, must be for an amount greater than the ED of a
native asset if the user lacks a native asset account. Since fees are
typically smaller, the current implementation necessitates additional
swaps to meet the ED during `pre_dispatch`, with refunds for excess ED
swap occurring during `post_dispatch`. Further details can be found
[here](https://github.com/paritytech/polkadot-sdk/blob/115c2477eb287df55107cd95594100ba395ed239/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs#L115).

This setup presents an issue where a user is unable to transfer their
entire balance and close the account. Instead, the user must transfer
slightly less of asset `A` to ensure there is enough not only for the
fee payment but also some extra to meet the ED requirement for their
native account during `pre_dispatch`. In some cases during
`post_dispatch`, the user will have the excess ED swapped back to asset
`A`, while in other cases, it may not be sufficient to meet the ED
requirement for asset `A`, leading it being left in the user's
'temporary' native asset account.
Example:
https://assethub-polkadot.subscan.io/extrinsic/6204018-9?event=6204018-79

Given the importance of this scenario for CEX, I propose a solution that
does not entail breaking changes to the pallets' API and open PR to the
runtimes without waiting for new polkadot-sdk version. Additionally, I
have opened a draft PR with these types in their respective pallets in
FRAME, where they have been tested against existing tests for types
implementing the same contract. PR -
paritytech/polkadot-sdk#4455

Target implementation with breaking changes:
paritytech/polkadot-sdk#4488

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
@muharem muharem added the T1-FRAME This PR/Issue is related to core FRAME, the framework. label May 23, 2024
@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: cargo-clippy
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6280279

Comment on lines +267 to +268
OUF::on_unbalanced(fee);
OUT::on_unbalanced(tip);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can make this as in transaction payment pallet (OU::on_unbalanceds(vec![fee, tip])), if #4564 pr get merged

Copy link
Member

@ggwpez ggwpez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am not that deep into the code, but looks good.

F::total_balance(asset_id.clone(), who).is_zero()
{
// Nothing to refund or the account was removed be the dispatched function.
(initial_asset_consumed, fee_paid)
Copy link
Member

@ggwpez ggwpez May 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could also be that the account is still alive but just does not have any balances of that asset?
But its probably fine - otherwise it would need some more complicated logic to check that the refunded amount is above ED.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. also current implementation for only a native asset (pallet-transaction-payment) also follows this logic and asserts it with a test. there might be other reasons. for example if you transfer all and wanna your account to be removed, you do not wanna any refund back.
may be @kianenigma can add more to this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep the same assumption in the case where the asset is sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@georgepisaltu which assumption? the transfer all and reap account is real use case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assumption that the account was removed. I understand the reap account is a real use case, I was talking about @ggwpez 's situation where you maybe consumed all the asset. It would get messy with the ED calculation, but I think we don't care about that if the asset is sufficient and we have some of it to refund, right? I'm asking if the intended behavior is to ignore this "sufficient" case as with the current impl.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, system account or any other can be still alive.
The intended behavior is to have no refund if a dispatched call results the asset account to be removed, regardless of the asset type.

muharem and others added 3 commits May 27, 2024 10:17
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
@muharem muharem requested a review from liamaharon May 27, 2024 15:41
Copy link
Contributor

@georgepisaltu georgepisaltu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, just a couple of comments

F::total_balance(asset_id.clone(), who).is_zero()
{
// Nothing to refund or the account was removed be the dispatched function.
(initial_asset_consumed, fee_paid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep the same assumption in the case where the asset is sufficient?

Copy link
Contributor

@georgepisaltu georgepisaltu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T1-FRAME This PR/Issue is related to core FRAME, the framework.
Projects
Status: In Development
Status: Audited
Development

Successfully merging this pull request may close these issues.

None yet

4 participants