wrong check for ETH balance is done inside the MagicSpend#validatePaymasterUserOp which can lead to reverts inside MagicSpend#postOp #133
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-110
🤖_110_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-03-coinbase/blob/e0573369b865d47fed778de00a7b6df65ab1744e/src/MagicSpend/MagicSpend.sol#L133
Vulnerability details
Impact
If the MagicSpend paymaster is called by the EntryPoint with an aggregation of user/s operations the check done inside
MagicSpend#validatePaymasterUserOp
for the ETH balance is not enough and can produce a revert whenMagicSpend@postOp
is executed putting this paymaster on a bad reputation by wrongly pass the validation and working only with a bundle of size 1 for the user operation.If a MagicSpend paymaster contract is used with
handleAggregatedOps
we get the same revert.Proof of Concept
The revert happen becouse 'MagicSpend#validatePaymasterUserOp' and
MagicSpend#postOp
are coded to be called sequentially one after the other. But in theEntryPoint
contract both function are called separately in a for loop which hinders the 'MagicSpend#validatePaymasterUserOp' ETH balance validation on this line :https://github.com/code-423n4/2024-03-coinbase/blob/e0573369b865d47fed778de00a7b6df65ab1744e/src/MagicSpend/MagicSpend.sol#L133
The validation passes and when looping on
postOp
function the revert can happen on this line becouse the functionSafeTransferLib.forceSafeTransferETH
checks the balance and if its less then amount to send it reverts withETHTransferFailed()
https://github.com/code-423n4/2024-03-coinbase/blob/e0573369b865d47fed778de00a7b6df65ab1744e/src/MagicSpend/MagicSpend.sol#L160-L162
The following POC is a new test inside the
Integration.t.sol
file which demonstrates that if we construct an array of UserOps operations that is bigger then one the test will fail with a revert ofETHTransferFailed()
when executingMagicSpend::postOp
.Tools Used
Manual review
Recommended Mitigation Steps
Check the ETH balance by taking in account the already promised withdraw amounts by introducing a global variable :
Don't forget to decrease the
allWithdraws
variable when the amount is withdrawn to the user !Assessed type
Error
The text was updated successfully, but these errors were encountered: