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

Refunds are transferred to the next users instead of current users. #5

Open
hoshiyari420 opened this issue Apr 8, 2024 · 0 comments

Comments

@hoshiyari420
Copy link

Description

  • Zksync Era has a system for processing refunds. Check here :https://docs.zksync.io/build/developer-reference/fee-model.html#refunds. Each transaction is being refunded certain amount of ETH as gas estimate may be higher than the actual cost of the transaction.
  • In Zksync, these refunds are processed at the end of the transaction; i.e. after thepostTransaction() call to the paymaster.
  • But here in postTransaction() function, all the paymaster ETH balance is transferred back to user. This balance does not include the refunded ETH which will be transferred to the paymaster after this call.
  • Those refunded ETH are stuck in the paymaster contract and transferred to the next user again in the next postTransaction() call.
    userAddress.call{value: address(this).balance}("");
  • Thus the refund that UserA deserved is transferred to next user UserB and this chain continues causing disparity between users refunds. Especially if userA has high gas consuming transaction and userB has negligible gas consuming transaction, the refunds of userA are transferred to userB.
  • It also breaks the assumption balance of paymaster will always be 0 while in fact it will never be 0.

Recommendation

  • There are lot of nuances in the exact calculations of the refunded amount which adds the complexity. But here are few ways.
  1. Use - block.gasprice * (_maxRefundedGas - PAYMASTER_GAS) to calculate exact refund - PAYMASTER_GAS is the hardcoded gas used by postTransaction() function, which is also subject to change during an upgrade - More details here: [General] Paymaster - How to send all the refunded ETH back to the user zkSync-Community-Hub/zksync-developers#278

  2. Maintain a state variable - previousUser -> which provides the previous user address -> send difference of ETH to the previousUser -> update the previousUser to the current user at the end of transaction. By this method, exact refund of userA is transferred during the execution of transaction of userB and exact refund of userB in execution of transaction of userC. Although, utmost care is required during implementation to avoid re-entrancy and DOS attack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant