diff --git a/test/governance/Comp.fixture.ts b/test/governance/Comp.fixture.ts index ef6d4c7..62b0af8 100644 --- a/test/governance/Comp.fixture.ts +++ b/test/governance/Comp.fixture.ts @@ -7,7 +7,9 @@ import { FhevmInstances } from "../types"; export async function deployCompFixture(signers: Signers): Promise { const contractFactory = await ethers.getContractFactory("TestComp"); - const contract = await contractFactory.connect(signers.alice).deploy(signers.alice.address); + const contract = await contractFactory + .connect(signers.alice) + .deploy(signers.alice.address, "CompoundZama", "COMP", "1.0"); await contract.waitForDeployment(); return contract; } diff --git a/test/governance/Comp.test.ts b/test/governance/Comp.test.ts index 9f046a0..85b07ae 100644 --- a/test/governance/Comp.test.ts +++ b/test/governance/Comp.test.ts @@ -67,14 +67,17 @@ describe("Comp", function () { }); it("can delegate votes via delegateBySig if signature is valid", async function () { + const delegator = this.signers.alice; const delegatee = this.signers.bob; const nonce = 0; let latestBlockNumber = await ethers.provider.getBlockNumber(); const block = await ethers.provider.getBlock(latestBlockNumber); const expiry = block!.timestamp + 100; - const [v, r, s] = await delegateBySig(this.signers.alice, delegatee.address, this.comp, nonce, expiry); + const signature = await delegateBySig(delegator, delegatee.address, this.comp, nonce, expiry, false); - const tx = await this.comp.connect(this.signers.alice).delegateBySig(delegatee, nonce, expiry, v, r, s); + const tx = await this.comp + .connect(this.signers.alice) + .delegateBySig(delegator, delegatee, nonce, expiry, signature); await tx.wait(); latestBlockNumber = await ethers.provider.getBlockNumber(); @@ -125,49 +128,56 @@ describe("Comp", function () { }); it("cannot delegate votes if nonce is invalid", async function () { + const delegator = this.signers.alice; const delegatee = this.signers.bob; const nonce = 0; let latestBlockNumber = await ethers.provider.getBlockNumber(); const block = await ethers.provider.getBlock(latestBlockNumber); const expiry = block!.timestamp + 100; - const [v, r, s] = await delegateBySig(this.signers.alice, delegatee.address, this.comp, nonce, expiry); + const signature = await delegateBySig(delegator, delegatee.address, this.comp, nonce, expiry); - const tx = await this.comp.connect(this.signers.alice).delegateBySig(delegatee, nonce, expiry, v, r, s); + const tx = await this.comp + .connect(this.signers.alice) + .delegateBySig(delegator, delegatee, nonce, expiry, signature); await tx.wait(); // Cannot reuse same nonce when delegating by sig - await expect(this.comp.delegateBySig(delegatee, nonce, expiry, v, r, s)).to.be.revertedWith( - "Comp::delegateBySig: invalid nonce", + await expect(this.comp.delegateBySig(delegator, delegatee, nonce, expiry, signature)).to.be.revertedWithCustomError( + this.comp, + "SignatureNonceInvalid", ); }); it("cannot delegate votes if signer is invalid", async function () { + const delegator = this.signers.alice; const delegatee = this.signers.bob; const nonce = 0; let latestBlockNumber = await ethers.provider.getBlockNumber(); const block = await ethers.provider.getBlock(latestBlockNumber); const expiry = block!.timestamp + 100; - const [v, r, s] = await delegateBySig(this.signers.alice, delegatee.address, this.comp, nonce, expiry); - // Cannot use invalid signature when delegating by sig - await expect(this.comp.delegateBySig(delegatee, nonce, expiry, 30, r, s)).to.be.revertedWith( - "Comp::delegateBySig: invalid signature", + // Signer is not the delegator + const signature = await delegateBySig(this.signers.carol, delegatee.address, this.comp, nonce, expiry); + await expect(this.comp.delegateBySig(delegator, delegatee, nonce, expiry, signature)).to.be.revertedWithCustomError( + this.comp, + "SignatureVerificationFail", ); }); it("cannot delegate votes if signature has expired", async function () { + const delegator = this.signers.alice; const delegatee = this.signers.bob; const nonce = 0; let latestBlockNumber = await ethers.provider.getBlockNumber(); const block = await ethers.provider.getBlock(latestBlockNumber); const expiry = block!.timestamp + 100; - const [v, r, s] = await delegateBySig(this.signers.alice, delegatee.address, this.comp, nonce, expiry); + const signature = await delegateBySig(delegator, delegatee.address, this.comp, nonce, expiry); ethers.provider.send("evm_increaseTime", ["0xffff"]); - await expect(this.comp.connect(delegatee).delegateBySig(delegatee, nonce, expiry, v, r, s)).to.be.revertedWith( - "Comp::delegateBySig: signature expired", - ); + await expect( + this.comp.connect(delegatee).delegateBySig(delegator, delegatee, nonce, expiry, signature), + ).to.be.revertedWithCustomError(this.comp, "SignatureExpired"); }); it("cannot request votes if blocktime is equal to current blocktime", async function () { diff --git a/test/governance/DelegateBySig.ts b/test/governance/DelegateBySig.ts index bc0fe7c..08f6cff 100644 --- a/test/governance/DelegateBySig.ts +++ b/test/governance/DelegateBySig.ts @@ -4,26 +4,42 @@ import { Address } from "hardhat-deploy/types"; import type { Comp } from "../../types"; +/** + * + * @param _signer Signer from ethers. + * @param _delegatee Delegatee address. + * @param _comp Comp token. + * @param _nonce Nonce to sign. + * @param _expiry Expiry timestamp. + * @param _is64Bytes Whether the signature must be 64 bytes. If false, it has 65 bytes. + * Default is false. + * @dev See: https://eips.ethereum.org/EIPS/eip-2098 + * @returns The signature. + */ export const delegateBySig = async ( _signer: HardhatEthersSigner, _delegatee: Address, _comp: Comp, _nonce: number, _expiry: number, -): Promise<[BigInt, string, string]> => { + _is64Bytes: boolean = false, +): Promise => { const compAddress_ = await _comp.getAddress(); const delegatee_ = _delegatee; const nonce_ = _nonce; const expiry_ = _expiry; - const network = await ethers.provider.getNetwork(); const chainId = network.chainId; + const domain = { name: await _comp.name(), + version: "1.0", chainId: chainId, verifyingContract: compAddress_, }; + // Delegation(address delegatee,uint256 nonce,uint256 expiry) + const types = { Delegation: [ { @@ -48,9 +64,5 @@ export const delegateBySig = async ( }; const signature = await _signer.signTypedData(domain, types, message); - const sigRSV = ethers.Signature.from(signature); - const v = 27 + sigRSV.yParity; - const r = sigRSV.r; - const s = sigRSV.s; - return [BigInt(v), r, s]; + return signature; };