Skip to content

Commit

Permalink
update test cases for gas numbers and accounting
Browse files Browse the repository at this point in the history
  • Loading branch information
livingrockrises committed Dec 18, 2023
1 parent 4b0a5ae commit 1b3631a
Show file tree
Hide file tree
Showing 2 changed files with 260 additions and 14 deletions.
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at fd81a9
273 changes: 259 additions & 14 deletions test/sponsorship-paymaster/biconomy-verifying-paymaster-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,13 @@ export async function deployEntryPoint(

describe("EntryPoint with VerifyingPaymaster Singleton", function () {
let entryPoint: EntryPoint;
let entryPointStatic: EntryPoint;
let depositorSigner: Signer;
let walletOwner: Signer;
let proxyPaymaster: Contract;
let walletAddress: string, paymasterAddress: string;
let ethersSigner;

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

let verifyingSingletonPaymaster: VerifyingSingletonPaymaster;
// Could also use published package or added submodule (for Account Implementation and Factory)
Expand All @@ -62,15 +61,15 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
let walletFactory: BiconomyAccountFactory;
const abi = ethers.utils.defaultAbiCoder;

beforeEach(async function () {
before(async function () {
ethersSigner = await ethers.getSigners();
entryPoint = await deployEntryPoint();
entryPointStatic = entryPoint.connect(AddressZero);

deployer = ethersSigner[0];
offchainSigner = ethersSigner[1];
depositorSigner = ethersSigner[2];
walletOwner = deployer; // ethersSigner[3];
secondFundingId = ethersSigner[3];
walletOwner = deployer; // ethersSigner[0];

const offchainSignerAddress = await offchainSigner.getAddress();
const walletOwnerAddress = await walletOwner.getAddress();
Expand Down Expand Up @@ -180,14 +179,126 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
});

it("succeed with valid signature", async () => {
const fundingId = await offchainSigner.getAddress();
const signer = await verifyingSingletonPaymaster.verifyingSigner();

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

await verifyingSingletonPaymaster.depositFor(
await verifyingSingletonPaymaster
.connect(deployer)
.setUnaccountedEPGasOverhead(9700);

await verifyingSingletonPaymaster.depositFor(fundingId, {
value: ethers.utils.parseEther("1"),
});

const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceBefore =
await verifyingSingletonPaymaster.getBalance(fundingId);

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

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

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

userOp.signature = signatureWithModuleAddress;

const tx = await entryPoint.handleOps(
[userOp],
await offchainSigner.getAddress(),
{ value: ethers.utils.parseEther("1") }
{
type: 2,
maxFeePerGas: userOp.maxFeePerGas,
maxPriorityFeePerGas: userOp.maxPriorityFeePerGas,
}
);
console.log("userop nonce ", userOp.nonce.toString());
const receipt = await tx.wait();
console.log("effective gas price ", receipt.effectiveGasPrice.toString());
console.log("gas used VPM V1.1.0", receipt.gasUsed.toString());
console.log("gas price", receipt.effectiveGasPrice.toString());

const totalBalDeducted = BigNumber.from(receipt.logs[1].topics[2]);

const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed);
console.log("bundler paid ", bundlerPaid.toString());

const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceAfter =
await verifyingSingletonPaymaster.getBalance(fundingId);

const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub(
paymasterIdBalanceAfter
);
console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString());

expect(paymasterIdBalanceDiff).to.be.equal(totalBalDeducted);

const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter);
console.log("paymasterFundsDiff ", paymasterFundsDiff.toString());

expect(paymasterIdBalanceDiff.sub(paymasterFundsDiff)).to.be.greaterThan(
BigNumber.from(0)
);

await expect(
entryPoint.handleOps([userOp], await offchainSigner.getAddress())
).to.be.reverted;
});

it("succeed with valid signature - second transaction", async () => {
const fundingId = await offchainSigner.getAddress();
const signer = await verifyingSingletonPaymaster.verifyingSigner();

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

await verifyingSingletonPaymaster
.connect(deployer)
.setUnaccountedEPGasOverhead(9700);

await verifyingSingletonPaymaster.depositFor(fundingId, {
value: ethers.utils.parseEther("1"),
});

const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceBefore =
await verifyingSingletonPaymaster.getBalance(fundingId);

const userOp1 = await fillAndSign(
{
sender: walletAddress,
Expand All @@ -200,7 +311,109 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {

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

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

userOp.signature = signatureWithModuleAddress;

const tx = await entryPoint.handleOps(
[userOp],
await offchainSigner.getAddress(),
{
type: 2,
maxFeePerGas: userOp.maxFeePerGas,
maxPriorityFeePerGas: userOp.maxPriorityFeePerGas,
}
);
console.log("userop nonce ", userOp.nonce.toString());
const receipt = await tx.wait();
console.log("effective gas price ", receipt.effectiveGasPrice.toString());
console.log("gas used VPM V1.1.0", receipt.gasUsed.toString());
console.log("gas price", receipt.effectiveGasPrice.toString());

const totalBalDeducted = BigNumber.from(receipt.logs[1].topics[2]);

const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed);
console.log("bundler paid ", bundlerPaid.toString());

const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceAfter =
await verifyingSingletonPaymaster.getBalance(fundingId);

const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub(
paymasterIdBalanceAfter
);
console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString());

expect(paymasterIdBalanceDiff).to.be.equal(totalBalDeducted);

const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter);
console.log("paymasterFundsDiff ", paymasterFundsDiff.toString());

expect(paymasterIdBalanceDiff.sub(paymasterFundsDiff)).to.be.greaterThan(
BigNumber.from(0)
);

await expect(
entryPoint.handleOps([userOp], await offchainSigner.getAddress())
).to.be.reverted;
});

it("succeed with valid signature - same account - different funding id ", async () => {
const fundingId = await secondFundingId.getAddress();
const signer = await verifyingSingletonPaymaster.verifyingSigner();

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

await verifyingSingletonPaymaster
.connect(deployer)
.setUnaccountedEPGasOverhead(9700);

await verifyingSingletonPaymaster.depositFor(fundingId, {
value: ethers.utils.parseEther("1"),
});

const paymasterFundsBefore = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceBefore =
await verifyingSingletonPaymaster.getBalance(fundingId);

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

const hash = await verifyingSingletonPaymaster.getHash(
userOp1,
fundingId,
MOCK_VALID_UNTIL,
MOCK_VALID_AFTER
);
Expand All @@ -212,12 +425,7 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {
paymasterAddress,
ethers.utils.defaultAbiCoder.encode(
["address", "uint48", "uint48", "bytes"],
[
await offchainSigner.getAddress(),
MOCK_VALID_UNTIL,
MOCK_VALID_AFTER,
sig,
]
[fundingId, MOCK_VALID_UNTIL, MOCK_VALID_AFTER, sig]
),
]),
},
Expand All @@ -233,7 +441,44 @@ describe("EntryPoint with VerifyingPaymaster Singleton", function () {

userOp.signature = signatureWithModuleAddress;

await entryPoint.handleOps([userOp], await offchainSigner.getAddress());
const tx = await entryPoint.handleOps(
[userOp],
await offchainSigner.getAddress(),
{
type: 2,
maxFeePerGas: userOp.maxFeePerGas,
maxPriorityFeePerGas: userOp.maxPriorityFeePerGas,
}
);
console.log("userop nonce ", userOp.nonce.toString());
const receipt = await tx.wait();
console.log("effective gas price ", receipt.effectiveGasPrice.toString());
console.log("gas used VPM V1.1.0", receipt.gasUsed.toString());
console.log("gas price", receipt.effectiveGasPrice.toString());

const totalBalDeducted = BigNumber.from(receipt.logs[1].topics[2]);

const bundlerPaid = receipt.effectiveGasPrice.mul(receipt.gasUsed);
console.log("bundler paid ", bundlerPaid.toString());

const paymasterFundsAfter = await entryPoint.balanceOf(paymasterAddress);
const paymasterIdBalanceAfter =
await verifyingSingletonPaymaster.getBalance(fundingId);

const paymasterIdBalanceDiff = paymasterIdBalanceBefore.sub(
paymasterIdBalanceAfter
);
console.log("paymasterIdBalanceDiff ", paymasterIdBalanceDiff.toString());

expect(paymasterIdBalanceDiff).to.be.equal(totalBalDeducted);

const paymasterFundsDiff = paymasterFundsBefore.sub(paymasterFundsAfter);
console.log("paymasterFundsDiff ", paymasterFundsDiff.toString());

expect(paymasterIdBalanceDiff.sub(paymasterFundsDiff)).to.be.greaterThan(
BigNumber.from(0)
);

await expect(
entryPoint.handleOps([userOp], await offchainSigner.getAddress())
).to.be.reverted;
Expand Down

0 comments on commit 1b3631a

Please sign in to comment.