From e102c9d8dda0297d25d33c9946b9cd3efea5bed7 Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Mon, 27 May 2024 19:29:40 -0700 Subject: [PATCH 1/7] added e2e test --- test/v2/core/sgETH.spec.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index 4b5046c..e0766fb 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -53,4 +53,33 @@ describe("SgETH.sol", () => { .and.to.be.emit(sgEth, "RoleRevoked") .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); }); + + it("e2e test", async () => { + const WSGETH = await ethers.getContractFactory("WSGETH"); + const wsgETH = await WSGETH.deploy(sgEth.address, 24 * 60 * 60); + await wsgETH.deployed(); + + const feeCalc = ethers.constants.AddressZero; // not sure if it is right + const numValidators = 1000; + const adminFee = 0; + + const addresses = [ + feeCalc, + sgEth.address, + wsgETH.address, + ethers.constants.AddressZero, // using dummy address + ethers.constants.AddressZero, // using dummy address + ]; + + const Minter = await ethers.getContractFactory("SharedDepositMinterV2"); + const minter = await Minter.deploy(numValidators, adminFee, addresses); + await minter.deployed(); + + await sgEth.removeMinter(deployer.address); + await sgEth.transferOwnership(minter.address); + + await expect(sgEth.connect(deployer).transferOwnership(alice.address)).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${ethers.constants.HashZero}`, + ); + }); }); From ce17f8b30c4213bdcb768ba4c348c9d100daa480 Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Mon, 27 May 2024 19:38:15 -0700 Subject: [PATCH 2/7] added comment --- test/v2/core/sgETH.spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index e0766fb..980c4a0 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -55,6 +55,7 @@ describe("SgETH.sol", () => { }); it("e2e test", async () => { + // deploy sgeth const WSGETH = await ethers.getContractFactory("WSGETH"); const wsgETH = await WSGETH.deploy(sgEth.address, 24 * 60 * 60); await wsgETH.deployed(); @@ -71,13 +72,18 @@ describe("SgETH.sol", () => { ethers.constants.AddressZero, // using dummy address ]; + // add secondary minter contract / eoa const Minter = await ethers.getContractFactory("SharedDepositMinterV2"); const minter = await Minter.deploy(numValidators, adminFee, addresses); await minter.deployed(); + // revoke deployer minter rights await sgEth.removeMinter(deployer.address); + // add secondary owner + // revoke deployer admin rights await sgEth.transferOwnership(minter.address); + // check auth invariants are preserved. i.e ex owner and outsiders cannot interact with the contract await expect(sgEth.connect(deployer).transferOwnership(alice.address)).to.be.revertedWith( `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${ethers.constants.HashZero}`, ); From e34c0b9bad1b5cf621dc0216cee1678676470207 Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Mon, 27 May 2024 19:43:43 -0700 Subject: [PATCH 3/7] fix --- test/v2/core/sgETH.spec.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index 980c4a0..b828aca 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -78,10 +78,15 @@ describe("SgETH.sol", () => { await minter.deployed(); // revoke deployer minter rights + // actually don't need to do this because deployer doesn't have minter role await sgEth.removeMinter(deployer.address); // add secondary owner // revoke deployer admin rights - await sgEth.transferOwnership(minter.address); + await expect(sgEth.transferOwnership(minter.address)) + .to.be.emit(sgEth, "RoleGranted") + .withArgs(ethers.constants.HashZero, minter.address, deployer.address) + .and.to.be.emit(sgEth, "RoleRevoked") + .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); // check auth invariants are preserved. i.e ex owner and outsiders cannot interact with the contract await expect(sgEth.connect(deployer).transferOwnership(alice.address)).to.be.revertedWith( From df46a1fa24877b07d944dd6dbe141cc0bc28488e Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Tue, 28 May 2024 05:26:30 -0700 Subject: [PATCH 4/7] fix from feedback --- test/v2/core/sgETH.spec.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index b828aca..427acb8 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -1,5 +1,6 @@ const {ethers} = require("hardhat"); const {expect} = require("chai"); +const {parseEther} = require("ethers/lib/utils"); describe("SgETH.sol", () => { let sgEth, deployer, alice; @@ -65,11 +66,11 @@ describe("SgETH.sol", () => { const adminFee = 0; const addresses = [ - feeCalc, - sgEth.address, - wsgETH.address, - ethers.constants.AddressZero, // using dummy address + feeCalc, // fee calculator + sgEth.address, // sgETH address + wsgETH.address, // wsgETH address ethers.constants.AddressZero, // using dummy address + ethers.constants.AddressZero, // deposit contract ]; // add secondary minter contract / eoa @@ -77,8 +78,23 @@ describe("SgETH.sol", () => { const minter = await Minter.deploy(numValidators, adminFee, addresses); await minter.deployed(); - // revoke deployer minter rights - // actually don't need to do this because deployer doesn't have minter role + // deployer can't mint + await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${MINTER_ROLE}`, + ); + // no one can't mint + await expect(sgEth.connect(alice).mint(alice.address, parseEther("1"))).to.be.revertedWith( + `AccessControl: account ${alice.address.toLowerCase()} is missing role ${MINTER_ROLE}`, + ); + // add minter + await expect(sgEth.connect(deployer).addMinter(deployer.address)) + .to.be.emit(sgEth, "RoleGranted") + .withArgs(MINTER_ROLE, deployer.address, deployer.address); + // minter can mint + await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))) + .to.be.emit(sgEth, "Transfer") + .withArgs(ethers.constants.AddressZero, deployer.address, parseEther("1")); + await sgEth.removeMinter(deployer.address); // add secondary owner // revoke deployer admin rights From 0bd982011a6b969660a20eab4078e539b1113a16 Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Tue, 28 May 2024 05:27:45 -0700 Subject: [PATCH 5/7] changed comment --- test/v2/core/sgETH.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index 427acb8..26096a8 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -69,7 +69,7 @@ describe("SgETH.sol", () => { feeCalc, // fee calculator sgEth.address, // sgETH address wsgETH.address, // wsgETH address - ethers.constants.AddressZero, // using dummy address + ethers.constants.AddressZero, // government address ethers.constants.AddressZero, // deposit contract ]; From a4c4ec070ea7009fa5d45bc47ea0f8618775f12a Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Wed, 29 May 2024 06:12:33 -0700 Subject: [PATCH 6/7] e2e test finished --- test/v2/core/sgETH.spec.js | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index 26096a8..32dc8f2 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -3,11 +3,11 @@ const {expect} = require("chai"); const {parseEther} = require("ethers/lib/utils"); describe("SgETH.sol", () => { - let sgEth, deployer, alice; + let sgEth, deployer, alice, multiSig; let MINTER_ROLE; beforeEach(async () => { - const [owner, addr1] = await ethers.getSigners(); + const [owner, addr1, addr2] = await ethers.getSigners(); const SgETH = await ethers.getContractFactory("SgETH"); sgEth = await SgETH.deploy([]); @@ -15,6 +15,7 @@ describe("SgETH.sol", () => { deployer = owner; alice = addr1; + multiSig = addr2; MINTER_ROLE = await sgEth.MINTER(); }); @@ -61,16 +62,29 @@ describe("SgETH.sol", () => { const wsgETH = await WSGETH.deploy(sgEth.address, 24 * 60 * 60); await wsgETH.deployed(); - const feeCalc = ethers.constants.AddressZero; // not sure if it is right + const splitterAddresses = [deployer.address, multiSig.address, wsgETH.address]; + const splitterValues = [6, 3, 31]; + + const PaymentSplitter = await ethers.getContractFactory("PaymentSplitter"); + const paymentSplitter = await PaymentSplitter.deploy(splitterAddresses, splitterValues); + await paymentSplitter.deployed(); + + const rolloverVirtual = "1080000000000000000"; + const vETH2Addr = "0x898bad2774eb97cf6b94605677f43b41871410b1"; + + const Withdrawals = await ethers.getContractFactory("Withdrawals"); + const withdrawals = await Withdrawals.deploy(vETH2Addr, rolloverVirtual); + await withdrawals.deployed(); + const numValidators = 1000; const adminFee = 0; const addresses = [ - feeCalc, // fee calculator + paymentSplitter.address, // fee splitter sgEth.address, // sgETH address wsgETH.address, // wsgETH address - ethers.constants.AddressZero, // government address - ethers.constants.AddressZero, // deposit contract + multiSig.address, // government address + ethers.constants.AddressZero, // deposit contract address - can't find deposit contract - using dummy address ]; // add secondary minter contract / eoa @@ -78,6 +92,15 @@ describe("SgETH.sol", () => { const minter = await Minter.deploy(numValidators, adminFee, addresses); await minter.deployed(); + const RewardsReceiver = await ethers.getContractFactory("RewardsReceiver"); + const rewardsReceiver = await RewardsReceiver.deploy(withdrawals.address, [ + sgEth.address, + wsgETH.address, + paymentSplitter.address, + minter.address, + ]); + await rewardsReceiver.deployed(); + // deployer can't mint await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))).to.be.revertedWith( `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${MINTER_ROLE}`, @@ -98,9 +121,9 @@ describe("SgETH.sol", () => { await sgEth.removeMinter(deployer.address); // add secondary owner // revoke deployer admin rights - await expect(sgEth.transferOwnership(minter.address)) + await expect(sgEth.transferOwnership(multiSig.address)) .to.be.emit(sgEth, "RoleGranted") - .withArgs(ethers.constants.HashZero, minter.address, deployer.address) + .withArgs(ethers.constants.HashZero, multiSig.address, deployer.address) .and.to.be.emit(sgEth, "RoleRevoked") .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); From 47fc6b9158707ebd02678da44f68168b2752fe27 Mon Sep 17 00:00:00 2001 From: devlancer412 Date: Thu, 30 May 2024 12:53:55 -0700 Subject: [PATCH 7/7] split e2e test to new file --- test/v2/core/e2e.spec.js | 99 ++++++++++++++++++++++++++++++++++++++ test/v2/core/sgETH.spec.js | 77 ----------------------------- 2 files changed, 99 insertions(+), 77 deletions(-) create mode 100644 test/v2/core/e2e.spec.js diff --git a/test/v2/core/e2e.spec.js b/test/v2/core/e2e.spec.js new file mode 100644 index 0000000..441f904 --- /dev/null +++ b/test/v2/core/e2e.spec.js @@ -0,0 +1,99 @@ +const {ethers} = require("hardhat"); +const {expect} = require("chai"); +const {parseEther} = require("ethers/lib/utils"); + +describe("e2e test", () => { + let sgEth, deployer, alice, multiSig; + let MINTER_ROLE; + + beforeEach(async () => { + const [owner, addr1, addr2] = await ethers.getSigners(); + + const SgETH = await ethers.getContractFactory("SgETH"); + sgEth = await SgETH.deploy([]); + await sgEth.deployed(); + + deployer = owner; + alice = addr1; + multiSig = addr2; + + MINTER_ROLE = await sgEth.MINTER(); + + // deploy sgeth + const WSGETH = await ethers.getContractFactory("WSGETH"); + const wsgETH = await WSGETH.deploy(sgEth.address, 24 * 60 * 60); + await wsgETH.deployed(); + + const splitterAddresses = [deployer.address, multiSig.address, wsgETH.address]; + const splitterValues = [6, 3, 31]; + + const PaymentSplitter = await ethers.getContractFactory("PaymentSplitter"); + const paymentSplitter = await PaymentSplitter.deploy(splitterAddresses, splitterValues); + await paymentSplitter.deployed(); + + const rolloverVirtual = "1080000000000000000"; + const vETH2Addr = "0x898bad2774eb97cf6b94605677f43b41871410b1"; + + const Withdrawals = await ethers.getContractFactory("Withdrawals"); + const withdrawals = await Withdrawals.deploy(vETH2Addr, rolloverVirtual); + await withdrawals.deployed(); + + const numValidators = 1000; + const adminFee = 0; + + const addresses = [ + paymentSplitter.address, // fee splitter + sgEth.address, // sgETH address + wsgETH.address, // wsgETH address + multiSig.address, // government address + ethers.constants.AddressZero, // deposit contract address - can't find deposit contract - using dummy address + ]; + + // add secondary minter contract / eoa + const Minter = await ethers.getContractFactory("SharedDepositMinterV2"); + const minter = await Minter.deploy(numValidators, adminFee, addresses); + await minter.deployed(); + + const RewardsReceiver = await ethers.getContractFactory("RewardsReceiver"); + const rewardsReceiver = await RewardsReceiver.deploy(withdrawals.address, [ + sgEth.address, + wsgETH.address, + paymentSplitter.address, + minter.address, + ]); + await rewardsReceiver.deployed(); + }); + + it("e2e test", async () => { + // deployer can't mint + await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${MINTER_ROLE}`, + ); + // no one can't mint + await expect(sgEth.connect(alice).mint(alice.address, parseEther("1"))).to.be.revertedWith( + `AccessControl: account ${alice.address.toLowerCase()} is missing role ${MINTER_ROLE}`, + ); + // add minter + await expect(sgEth.connect(deployer).addMinter(deployer.address)) + .to.be.emit(sgEth, "RoleGranted") + .withArgs(MINTER_ROLE, deployer.address, deployer.address); + // minter can mint + await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))) + .to.be.emit(sgEth, "Transfer") + .withArgs(ethers.constants.AddressZero, deployer.address, parseEther("1")); + + await sgEth.removeMinter(deployer.address); + // add secondary owner + // revoke deployer admin rights + await expect(sgEth.transferOwnership(multiSig.address)) + .to.be.emit(sgEth, "RoleGranted") + .withArgs(ethers.constants.HashZero, multiSig.address, deployer.address) + .and.to.be.emit(sgEth, "RoleRevoked") + .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); + + // check auth invariants are preserved. i.e ex owner and outsiders cannot interact with the contract + await expect(sgEth.connect(deployer).transferOwnership(alice.address)).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${ethers.constants.HashZero}`, + ); + }); +}); diff --git a/test/v2/core/sgETH.spec.js b/test/v2/core/sgETH.spec.js index 32dc8f2..797b379 100644 --- a/test/v2/core/sgETH.spec.js +++ b/test/v2/core/sgETH.spec.js @@ -55,81 +55,4 @@ describe("SgETH.sol", () => { .and.to.be.emit(sgEth, "RoleRevoked") .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); }); - - it("e2e test", async () => { - // deploy sgeth - const WSGETH = await ethers.getContractFactory("WSGETH"); - const wsgETH = await WSGETH.deploy(sgEth.address, 24 * 60 * 60); - await wsgETH.deployed(); - - const splitterAddresses = [deployer.address, multiSig.address, wsgETH.address]; - const splitterValues = [6, 3, 31]; - - const PaymentSplitter = await ethers.getContractFactory("PaymentSplitter"); - const paymentSplitter = await PaymentSplitter.deploy(splitterAddresses, splitterValues); - await paymentSplitter.deployed(); - - const rolloverVirtual = "1080000000000000000"; - const vETH2Addr = "0x898bad2774eb97cf6b94605677f43b41871410b1"; - - const Withdrawals = await ethers.getContractFactory("Withdrawals"); - const withdrawals = await Withdrawals.deploy(vETH2Addr, rolloverVirtual); - await withdrawals.deployed(); - - const numValidators = 1000; - const adminFee = 0; - - const addresses = [ - paymentSplitter.address, // fee splitter - sgEth.address, // sgETH address - wsgETH.address, // wsgETH address - multiSig.address, // government address - ethers.constants.AddressZero, // deposit contract address - can't find deposit contract - using dummy address - ]; - - // add secondary minter contract / eoa - const Minter = await ethers.getContractFactory("SharedDepositMinterV2"); - const minter = await Minter.deploy(numValidators, adminFee, addresses); - await minter.deployed(); - - const RewardsReceiver = await ethers.getContractFactory("RewardsReceiver"); - const rewardsReceiver = await RewardsReceiver.deploy(withdrawals.address, [ - sgEth.address, - wsgETH.address, - paymentSplitter.address, - minter.address, - ]); - await rewardsReceiver.deployed(); - - // deployer can't mint - await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))).to.be.revertedWith( - `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${MINTER_ROLE}`, - ); - // no one can't mint - await expect(sgEth.connect(alice).mint(alice.address, parseEther("1"))).to.be.revertedWith( - `AccessControl: account ${alice.address.toLowerCase()} is missing role ${MINTER_ROLE}`, - ); - // add minter - await expect(sgEth.connect(deployer).addMinter(deployer.address)) - .to.be.emit(sgEth, "RoleGranted") - .withArgs(MINTER_ROLE, deployer.address, deployer.address); - // minter can mint - await expect(sgEth.connect(deployer).mint(deployer.address, parseEther("1"))) - .to.be.emit(sgEth, "Transfer") - .withArgs(ethers.constants.AddressZero, deployer.address, parseEther("1")); - - await sgEth.removeMinter(deployer.address); - // add secondary owner - // revoke deployer admin rights - await expect(sgEth.transferOwnership(multiSig.address)) - .to.be.emit(sgEth, "RoleGranted") - .withArgs(ethers.constants.HashZero, multiSig.address, deployer.address) - .and.to.be.emit(sgEth, "RoleRevoked") - .withArgs(ethers.constants.HashZero, deployer.address, deployer.address); - - // check auth invariants are preserved. i.e ex owner and outsiders cannot interact with the contract - await expect(sgEth.connect(deployer).transferOwnership(alice.address)).to.be.revertedWith( - `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${ethers.constants.HashZero}`, - ); - }); });