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

add ways to catch AA33 with revert reason #68

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions contracts/sponsorship/SponsorshipPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ contract SponsorshipPaymaster is
) public override nonReentrant {
if (withdrawAddress == address(0)) revert CanNotWithdrawToZeroAddress();
uint256 currentBalance = paymasterIdBalances[msg.sender];
if (amount > currentBalance)
revert InsufficientBalance(amount, currentBalance);
require(amount <= currentBalance, "Sponsorship Paymaster: Insufficient funds to withdraw from gas tank");
paymasterIdBalances[msg.sender] = currentBalance - amount;
entryPoint.withdrawTo(withdrawAddress, amount);
emit GasWithdrawn(msg.sender, withdrawAddress, amount);
Expand Down Expand Up @@ -315,7 +314,7 @@ contract SponsorshipPaymaster is
);
uint256 sigLength = signature.length;
// we only "require" it here so that the revert reason on invalid signature will be of "VerifyingPaymaster", and not "ECDSA"
if (sigLength != 65) revert InvalidPaymasterSignatureLength(sigLength);
require(sigLength == 65, "Sponsorship Paymaster:invalid paymaster signature length");
//don't revert on signature failure: return SIG_VALIDATION_FAILED
if (
verifyingSigner != hash.toEthSignedMessageHash().recover(signature)
Expand All @@ -324,18 +323,14 @@ contract SponsorshipPaymaster is
return (context, _packValidationData(true, validUntil, validAfter));
}

require(priceMarkup <= 2e6, "Verifying PM:high markup %");
require(priceMarkup <= 2e6, "Sponsorship Paymaster: high markup %");

uint32 dynamicMarkup = MathLib.maxuint32(priceMarkup, fixedPriceMarkup);

uint256 effectiveCost = (requiredPreFund * dynamicMarkup) /
PRICE_DENOMINATOR;

if (effectiveCost > paymasterIdBalances[paymasterId])
revert InsufficientBalance(
effectiveCost,
paymasterIdBalances[paymasterId]
);
require(effectiveCost <= paymasterIdBalances[paymasterId], "Sponsorship Paymaster: paymasterId does not have enough deposit");

context = abi.encode(
paymasterId,
Expand Down
75 changes: 69 additions & 6 deletions test/sponsorship-paymaster/biconomy-sponsorship-paymaster-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
let ethersSigner;

let offchainSigner: Signer, deployer: Signer, feeCollector: Signer;
let secondFundingId: Signer;
let secondFundingId: Signer, thirdFundingId: Signer;

let sponsorshipPaymaster: SponsorshipPaymaster;
let smartWalletImp: BiconomyAccountImplementation;
Expand All @@ -61,6 +61,7 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
depositorSigner = ethersSigner[2];
feeCollector = ethersSigner[3];
secondFundingId = ethersSigner[4];
thirdFundingId = ethersSigner[5];
walletOwner = deployer; // ethersSigner[0];

const offchainSignerAddress = await offchainSigner.getAddress();
Expand Down Expand Up @@ -156,6 +157,7 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {

describe("Verifying paymaster basic positive tests", () => {
it("Should Fail when there is no deposit for paymaster id", async () => {
// Review
const paymasterId = await depositorSigner.getAddress();
console.log("paymaster Id ", paymasterId);
const userOp = await getUserOpWithPaymasterInfo(paymasterId);
Expand Down Expand Up @@ -557,9 +559,71 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
paymasterIdBalanceDiff.mul(BigNumber.from(1)).div(BigNumber.from(11))
);
});

it("fails for fundingId which does not have enough deposit", async () => {
const fundingId = await thirdFundingId.getAddress();

await sponsorshipPaymaster
.connect(deployer)
.setUnaccountedEPGasOverhead(18500);

// do not deposit

const signer = await sponsorshipPaymaster.verifyingSigner();
const offchainSignerAddress = await offchainSigner.getAddress();
expect(signer).to.be.equal(offchainSignerAddress);

const userOp1 = await fillAndSign(
{
sender: walletAddress,
verificationGasLimit: 200000,
},
walletOwner,
entryPoint,
"nonce"
);

const hash = await sponsorshipPaymaster.getHash(
userOp1,
fundingId,
MOCK_VALID_UNTIL,
MOCK_VALID_AFTER,
dynamicMarkup
);
const sig = await offchainSigner.signMessage(arrayify(hash));
const userOp = await fillAndSign(
{
...userOp1,
paymasterAndData: hexConcat([
paymasterAddress,
ethers.utils.defaultAbiCoder.encode(
["address", "uint48", "uint48", "uint32"],
[fundingId, MOCK_VALID_UNTIL, MOCK_VALID_AFTER, dynamicMarkup]
),
sig,
]),
},
walletOwner,
entryPoint,
"nonce"
);

const signatureWithModuleAddress = ethers.utils.defaultAbiCoder.encode(
["bytes", "address"],
[userOp.signature, ecdsaModule.address]
);
userOp.signature = signatureWithModuleAddress;

await expect(entryPoint.callStatic.simulateValidation(userOp))
.to.be.revertedWithCustomError(entryPoint, "FailedOp")
.withArgs(
0,
"AA33 reverted: Sponsorship Paymaster: paymasterId does not have enough deposit"
);
});
});

describe("Verifying Paymaster - read methods and state checks", () => {
describe("Sponsorship Paymaster - read methods and state checks", () => {
it("Should parse data properly", async () => {
const paymasterAndData = hexConcat([
paymasterAddress,
Expand Down Expand Up @@ -607,7 +671,7 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
});
});

describe("Verifying Paymaster - deposit and withdraw tests", () => {
describe("Sponsorship Paymaster - deposit and withdraw tests", () => {
it("Deposits into the specified address", async () => {
const paymasterId = await depositorSigner.getAddress();

Expand Down Expand Up @@ -652,9 +716,8 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
sponsorshipPaymaster
.connect(depositorSigner)
.withdrawTo(paymasterId, parseEther("1.1"))
).to.be.revertedWithCustomError(
sponsorshipPaymaster,
"InsufficientBalance"
).to.be.revertedWith(
"Sponsorship Paymaster: Insufficient withdrawable funds"
);
});
});
Expand Down
Loading