Skip to content

Commit

Permalink
Merge pull request #88 from bcnmy/feat/hardhat-tests
Browse files Browse the repository at this point in the history
feat: hardhat tests
  • Loading branch information
livingrockrises authored Jun 2, 2024
2 parents e07b273 + 3097693 commit 61cced5
Show file tree
Hide file tree
Showing 15 changed files with 1,797 additions and 471 deletions.
2 changes: 1 addition & 1 deletion .solcover.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
skipFiles: ["test", "lib/", "/utils", "/mocks", "contracts/mocks"],
skipFiles: ["test", "/lib", "/utils", "/mocks", "contracts/mocks", "lib/ModuleTypeLib", "contracts/mocks"],
};
4 changes: 2 additions & 2 deletions contracts/factory/BiconomyMetaFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Stakeable } from "../common/Stakeable.sol";

// can stake
// can whitelist factories
// deployAccount with chosen factory and required data for that facotry
// deployAccount with chosen factory and required data for that factory

/// @title Nexus - BiconomyMetaFactory
/// @notice Manages the creation of Modular Smart Accounts compliant with ERC-7579 and ERC-4337 using a factory pattern.
Expand Down Expand Up @@ -53,7 +53,7 @@ contract BiconomyMetaFactory is Stakeable {
/// @dev factoryData is posted on the factory using factory.call(factoryData)
/// instead of calling a specific method always to allow more freedom.
/// factory should know how to decode this factoryData
/// @notice These factories could possibly enshrine specific module/s to avoid arbitary execution and prevent griefing.
/// @notice These factories could possibly enshrine specific module/s to avoid arbitrary execution and prevent griefing.
/// @notice Another benefit of this pattern is that the factory can be upgraded without changing this contract.
/// @param factory The address of the factory to be used for deployment.
/// @param factoryData The encoded data for the method to be called on the Factory.
Expand Down
99 changes: 99 additions & 0 deletions test/hardhat/common/Stakeable.specs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ethers } from "hardhat";
import { expect } from "chai";
import { AddressLike, parseEther } from "ethers";
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { EntryPoint, Nexus, Stakeable } from "../../../typechain-types";
import { deployContractsAndSAFixture } from "../utils/deployment";
import { zeroAddress } from "viem";

describe("Stakeable tests", function () {
let smartAccount: Nexus;
let entryPoint: EntryPoint;
let ownerAddress: AddressLike;
let entryPointAddress: AddressLike;

let stakeable: Stakeable;

beforeEach(async function () {
const setup = await loadFixture(deployContractsAndSAFixture);
entryPoint = setup.entryPoint;
smartAccount = setup.deployedNexus;
stakeable = setup.stakeable;
ownerAddress = setup.accountOwner.address;
entryPointAddress = await setup.entryPoint.getAddress();
});

describe("Stakeable basic tests", function () {
it("Should correctly stake", async function () {
const balanceBefore = await ethers.provider.getBalance(entryPointAddress);
await stakeable.addStake(entryPointAddress, 60, {
value: parseEther("1"),
});
const balanceAfter = await ethers.provider.getBalance(entryPointAddress);

expect(balanceAfter - balanceBefore).to.eq(parseEther("1"));
});

it("Should fail to call addStake if not owner <= 0", async function () {
const randomEOA = ethers.Wallet.createRandom(ethers.provider);
await expect(
stakeable
.connect(randomEOA)
.addStake(entryPointAddress, 0, { value: parseEther("1") }),
).to.be.reverted;
});

it("Should fail to call withdrawStake if not owner <= 0", async function () {
const randomEOA = ethers.Wallet.createRandom(ethers.provider);
await expect(
stakeable
.connect(randomEOA)
.withdrawStake(entryPointAddress, ownerAddress),
).to.be.reverted;
});

it("Should fail to call unlockStake if not owner <= 0", async function () {
const randomEOA = ethers.Wallet.createRandom(ethers.provider);
await expect(stakeable.connect(randomEOA).unlockStake(entryPointAddress))
.to.be.reverted;
});

it("Should fail to stake with a delay <= 0", async function () {
await expect(
stakeable.addStake(entryPointAddress, 0, { value: parseEther("1") }),
).to.be.revertedWith("must specify unstake delay");
});

it("Should fail to add stake to an incorrect entrypoint address", async function () {
await expect(
stakeable.addStake(zeroAddress, 0, { value: parseEther("1") }),
).to.be.revertedWith("Invalid EP address");
});

it("Should fail to unlock stake from an incorrect entrypoint address", async function () {
await expect(stakeable.unlockStake(zeroAddress)).to.be.revertedWith(
"Invalid EP address",
);
});

it("Should fail to withdraw stake from an incorrect entrypoint address", async function () {
await expect(
stakeable.withdrawStake(zeroAddress, ownerAddress),
).to.be.revertedWith("Invalid EP address");
});

it("Should correctly unlock and withdraw", async function () {
await stakeable.addStake(entryPointAddress, 1, {
value: parseEther("1"),
});

await stakeable.unlockStake(entryPointAddress);

const balanceBefore = await ethers.provider.getBalance(ownerAddress);
await stakeable.withdrawStake(entryPointAddress, ownerAddress);
const balanceAfter = await ethers.provider.getBalance(ownerAddress);

expect(balanceAfter - balanceBefore).to.eq(parseEther("1"));
});
});
});
175 changes: 0 additions & 175 deletions test/hardhat/smart-account/MSA.Factory.specs.ts

This file was deleted.

Loading

0 comments on commit 61cced5

Please sign in to comment.