-
Notifications
You must be signed in to change notification settings - Fork 10
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
fix: keep track of pending withdrawals #16
Changes from 2 commits
76b874f
3625f60
0f534f3
893fd40
679589b
3821093
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,25 @@ contract ValidatePaymasterUserOpTest is PaymasterMagicSpendBaseTest, ValidateTes | |
magic.validatePaymasterUserOp(_getUserOp(), userOpHash, maxCost); | ||
} | ||
|
||
function test_revertsIfWithdrawalExceedsBalance() public { | ||
vm.deal(address(magic), 0); | ||
vm.expectRevert(abi.encodeWithSelector(MagicSpend.InsufficientBalance.selector, amount, 0)); | ||
function test_revertsInsufficientAvailableBalance( | ||
uint256 initialBalance, | ||
uint256 pendingWithdrawals, | ||
uint256 withdrawAmount | ||
) public { | ||
initialBalance = bound(initialBalance, 0, type(uint128).max - 2); | ||
pendingWithdrawals = bound(pendingWithdrawals, 0, initialBalance); | ||
uint256 availableBalance = initialBalance - pendingWithdrawals; | ||
withdrawAmount = bound(withdrawAmount, availableBalance + 1, type(uint128).max - 1); | ||
|
||
maxCost = withdrawAmount; | ||
amount = withdrawAmount; | ||
|
||
vm.deal(address(magic), initialBalance); | ||
vm.store(address(magic), bytes32(uint256(0)), bytes32(pendingWithdrawals + 1)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might be better to test multiple calls to validate so that we ensure we are setting / updating correctly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The best approach might be to have a test that simulates the bundler (validation + execution) and keep those unit tests focused on ~1 use case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have integration tests here if you want to write new one https://github.com/coinbase/magic-spend/blob/main/test/Integration.t.sol I think we could have here test_reverts_whenBalanceTooLow1Withdraw test_reverts_whenBalanceTooLow2Withdraws There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replaced the current test implementation to perform two successive validations that exhaust (and exceed) the available balance. |
||
|
||
vm.expectRevert( | ||
abi.encodeWithSelector(MagicSpend.InsufficientAvailableBalance.selector, amount, availableBalance) | ||
); | ||
magic.validatePaymasterUserOp(_getUserOp(), userOpHash, maxCost); | ||
} | ||
|
||
|
@@ -47,6 +63,7 @@ contract ValidatePaymasterUserOpTest is PaymasterMagicSpendBaseTest, ValidateTes | |
} | ||
|
||
function test_emitsCorrectly(address, uint256 amount_, uint256 nonce_) public override { | ||
amount_ = bound(amount_, 0, type(uint256).max - 1); | ||
maxCost = amount_; | ||
super.test_emitsCorrectly(magic.entryPoint(), amount_, nonce_); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure it's worth the gas / visual complexity of subtracting the 1 wei :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you recommend removing it entirely?
The point of this PR was to track the amounts to avoid our paymaster reputation being decreased in case where the bundler would include userops that revert at execution due to insufficient balance. If I remove this I wonder if someone could not use this off-by-one issue intentionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm I don't see a way to exploit this. In this case we are OVER estimating pending withdraws? So the failure case there is a withdraw that gets rejected in validation but could have succeeded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right my bad!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not implemented in this PR, will reconsider it for later.