diff --git a/contracts/TestAsyncDecrypt.sol b/contracts/TestAsyncDecrypt.sol index 0a5e6e9..e4b8bcf 100644 --- a/contracts/TestAsyncDecrypt.sol +++ b/contracts/TestAsyncDecrypt.sol @@ -8,6 +8,8 @@ import "fhevm/config/ZamaGatewayConfig.sol"; import "fhevm/gateway/GatewayCaller.sol"; /// @notice Contract for testing asynchronous decryption using the Gateway +/* solhint-disable max-states-count*/ +/* solhint-disable var-name-mixedcase*/ contract TestAsyncDecrypt is SepoliaZamaFHEVMConfig, SepoliaZamaGatewayConfig, GatewayCaller { /// @dev Encrypted state variables ebool xBool; diff --git a/eslint.config.mjs b/eslint.config.mjs index 03e3173..9a73964 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -10,7 +10,7 @@ export default [ linterOptions: { reportUnusedDisableDirectives: "off", }, - ignores: ["abi/", "artifacts/", "cache/", "res/", "types/*"], + ignores: [".abi/", ".artifacts/", ".cache/", ".coverage/", ".res/", ".types/"], }, eslint.configs.recommended, ...tseslint.configs.recommended, diff --git a/hardhat.config.ts b/hardhat.config.ts index 74fcf35..361fc67 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,10 +1,9 @@ import "@nomicfoundation/hardhat-toolbox"; import "@openzeppelin/hardhat-upgrades"; import dotenv from "dotenv"; -import * as fs from "fs-extra"; import "hardhat-deploy"; import "hardhat-ignore-warnings"; -import type { HardhatUserConfig, extendProvider } from "hardhat/config"; +import { HardhatUserConfig, extendProvider } from "hardhat/config"; import { task } from "hardhat/config"; import type { NetworkUserConfig } from "hardhat/types"; import { resolve } from "path"; @@ -33,7 +32,7 @@ const dotenvConfigPath: string = process.env.DOTENV_CONFIG_PATH || "./.env"; dotenv.config({ path: resolve(__dirname, dotenvConfigPath) }); // Ensure that we have all the environment variables we need. -let mnemonic: string = process.env.MNEMONIC!; +const mnemonic: string = process.env.MNEMONIC!; const chainIds = { zama: 8009, @@ -75,17 +74,7 @@ task("coverage").setAction(async (taskArgs, hre, runSuper) => { await runSuper(taskArgs); }); -function replaceImportStatement(filePath: string, oldImport: string, newImport: string): void { - try { - let fileContent = fs.readFileSync(filePath, "utf-8"); - fileContent = fileContent.replace(oldImport, newImport); - fs.writeFileSync(filePath, fileContent, "utf-8"); - } catch (error) { - console.error(`Error updating file: ${error}`); - } -} - -task("test", async (taskArgs, hre, runSuper) => { +task("test", async (_taskArgs, hre, runSuper) => { // Run modified test task if (hre.network.name === "hardhat") { await setCodeMocked(hre); diff --git a/tasks/mint.ts b/tasks/mint.ts index ee7b70e..5c505f6 100644 --- a/tasks/mint.ts +++ b/tasks/mint.ts @@ -2,6 +2,8 @@ import { task } from "hardhat/config"; import type { TaskArguments } from "hardhat/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { MyConfidentialERC20 } from "../types"; + task("task:deployConfidentialERC20").setAction(async function (taskArguments: TaskArguments, { ethers }) { const signers = await ethers.getSigners(); const erc20Factory = await ethers.getContractFactory("MyConfidentialERC20"); @@ -18,7 +20,7 @@ task("task:mint") const signers = await ethers.getSigners(); - const erc20 = (await ethers.getContractAt("MyConfidentialERC20", ERC20.address)) as any; + const erc20 = (await ethers.getContractAt("MyConfidentialERC20", ERC20.address)) as MyConfidentialERC20; const tx = await erc20.connect(signers[0]).mint(+taskArguments.mint); const rcpt = await tx.wait(); diff --git a/test/asyncDecrypt.ts b/test/asyncDecrypt.ts index ee53e6e..17b3d12 100644 --- a/test/asyncDecrypt.ts +++ b/test/asyncDecrypt.ts @@ -1,4 +1,5 @@ import { Wallet, ZeroAddress } from "ethers"; +import gatewayArtifact from "fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json"; import { ethers, network } from "hardhat"; import { ACL_ADDRESS, GATEWAYCONTRACT_ADDRESS, KMSVERIFIER_ADDRESS, PRIVATE_KEY_KMS_SIGNER } from "./constants"; @@ -6,10 +7,7 @@ import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; import { impersonateAddress } from "./mockedSetup"; import { waitNBlocks } from "./utils"; -const gatewayArtifact = require("fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json"); - const networkName = network.name; - const aclAdd = ACL_ADDRESS; const CiphertextType = { diff --git a/test/confidentialERC20/ConfidentialERC20.ts b/test/confidentialERC20/ConfidentialERC20.ts index e892ea9..83364c8 100644 --- a/test/confidentialERC20/ConfidentialERC20.ts +++ b/test/confidentialERC20/ConfidentialERC20.ts @@ -27,9 +27,8 @@ describe("ConfidentialERC20", function () { // Reencrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); const balanceAlice = await reencryptEuint64( - this.signers, + this.signers.alice, this.fhevm, - "alice", balanceHandleAlice, this.contractAddress, ); @@ -59,9 +58,8 @@ describe("ConfidentialERC20", function () { // Reencrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); const balanceAlice = await reencryptEuint64( - this.signers, + this.signers.alice, this.fhevm, - "alice", balanceHandleAlice, this.contractAddress, ); @@ -69,17 +67,17 @@ describe("ConfidentialERC20", function () { // Reencrypt Bob's balance const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress); + const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress); expect(balanceBob).to.equal(1337); // on the other hand, Bob should be unable to read Alice's balance await expect( - reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleAlice, this.contractAddress), + reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleAlice, this.contractAddress), ).to.be.rejectedWith("User is not authorized to reencrypt this handle!"); // and should be impossible to call reencrypt if contractAddress === userAddress await expect( - reencryptEuint64(this.signers, this.fhevm, "alice", balanceHandleAlice, this.signers.alice.address), + reencryptEuint64(this.signers.alice, this.fhevm, balanceHandleAlice, this.signers.alice.address), ).to.be.rejectedWith("userAddress should not be equal to contractAddress when requesting reencryption!"); }); @@ -99,9 +97,8 @@ describe("ConfidentialERC20", function () { const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); const balanceAlice = await reencryptEuint64( - this.signers, + this.signers.alice, this.fhevm, - "alice", balanceHandleAlice, this.contractAddress, ); @@ -109,7 +106,7 @@ describe("ConfidentialERC20", function () { // Reencrypt Bob's balance const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress); + const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress); expect(balanceBob).to.equal(0); }); @@ -142,9 +139,8 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); const balanceAlice = await reencryptEuint64( - this.signers, + this.signers.alice, this.fhevm, - "alice", balanceHandleAlice, this.contractAddress, ); @@ -152,7 +148,7 @@ describe("ConfidentialERC20", function () { // Decrypt Bob's balance const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress); + const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress); expect(balanceBob).to.equal(0); // check that transfer did not happen, as expected const inputBob2 = this.fhevm.createEncryptedInput(this.contractAddress, this.signers.bob.address); @@ -169,9 +165,8 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance const balanceHandleAlice2 = await this.erc20.balanceOf(this.signers.alice); const balanceAlice2 = await reencryptEuint64( - this.signers, + this.signers.alice, this.fhevm, - "alice", balanceHandleAlice2, this.contractAddress, ); @@ -179,13 +174,7 @@ describe("ConfidentialERC20", function () { // Decrypt Bob's balance const balanceHandleBob2 = await this.erc20.balanceOf(this.signers.bob); - const balanceBob2 = await reencryptEuint64( - this.signers, - this.fhevm, - "bob", - balanceHandleBob2, - this.contractAddress, - ); + const balanceBob2 = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob2, this.contractAddress); expect(balanceBob2).to.equal(1337); // check that transfer did happen this time }); diff --git a/test/coprocessorUtils.ts b/test/coprocessorUtils.ts index 6ae58b7..05a5d97 100644 --- a/test/coprocessorUtils.ts +++ b/test/coprocessorUtils.ts @@ -16,7 +16,7 @@ let counterRand = 0; //const db = new Database('./sql.db'); // on-disk db for debugging const db = new Database(":memory:"); -export function insertSQL(handle: string, clearText: BigInt, replace: boolean = false) { +export function insertSQL(handle: string, clearText: bigint, replace: boolean = false) { if (replace) { // this is useful if using snapshots while sampling different random numbers on each revert db.run("INSERT OR REPLACE INTO ciphertexts (handle, clearText) VALUES (?, ?)", [handle, clearText.toString()]); @@ -27,7 +27,7 @@ export function insertSQL(handle: string, clearText: BigInt, replace: boolean = // Decrypt any handle, bypassing ACL // WARNING : only for testing or internal use -export const getClearText = async (handle: BigInt): Promise => { +export const getClearText = async (handle: bigint): Promise => { const handleStr = "0x" + handle.toString(16).padStart(64, "0"); return new Promise((resolve, reject) => { @@ -102,7 +102,7 @@ function getRandomBigInt(numBits: number): bigint { return randomBigInt; } -function bitwiseNotUintBits(value: BigInt, numBits: number) { +function bitwiseNotUintBits(value: bigint, numBits: number) { if (typeof value !== "bigint") { throw new TypeError("The input value must be a BigInt."); } diff --git a/test/fhevmjsMocked.ts b/test/fhevmjsMocked.ts index e7be4e9..5c3f014 100644 --- a/test/fhevmjsMocked.ts +++ b/test/fhevmjsMocked.ts @@ -1,8 +1,7 @@ import { toBigIntBE, toBufferBE } from "bigint-buffer"; import crypto from "crypto"; -import dotenv from "dotenv"; import { Wallet, ethers } from "ethers"; -import * as fs from "fs"; +import hre from "hardhat"; import { Keccak } from "sha3"; import { isAddress } from "web3-validator"; @@ -16,10 +15,6 @@ import { import { insertSQL } from "./coprocessorUtils"; import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; -const hre = require("hardhat"); - -const aclAdd = ACL_ADDRESS; - enum Types { ebool = 0, euint4, @@ -362,7 +357,7 @@ function uint8ArrayToHexString(uint8Array: Uint8Array) { } function numberToHex(num: number) { - let hex = num.toString(16); + const hex = num.toString(16); return hex.length % 2 ? "0" + hex : hex; } @@ -401,10 +396,9 @@ async function computeInputSignatureCopro( userAddress: string, contractAddress: string, ): Promise { - let signature: string; const privKeySigner = PRIVATE_KEY_COPROCESSOR_ACCOUNT; const coprocSigner = new Wallet(privKeySigner).connect(ethers.provider); - signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner); + const signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner); return signature; } diff --git a/test/gatewayDecrypt/testAsyncDecrypt.ts b/test/gatewayDecrypt/testAsyncDecrypt.ts index 894e36d..2bed66b 100644 --- a/test/gatewayDecrypt/testAsyncDecrypt.ts +++ b/test/gatewayDecrypt/testAsyncDecrypt.ts @@ -143,7 +143,7 @@ describe("TestAsyncDecrypt", function () { const tx2 = await this.contract.connect(this.signers.carol).requestMixed(5, 15); await tx2.wait(); await awaitAllDecryptionResults(); - let yB = await this.contract.yBool(); + const yB = await this.contract.yBool(); expect(yB).to.equal(true); let y = await this.contract.yUint4(); expect(y).to.equal(4); @@ -151,7 +151,7 @@ describe("TestAsyncDecrypt", function () { expect(y).to.equal(42); y = await this.contract.yUint16(); expect(y).to.equal(16); - let yAdd = await this.contract.yAddress(); + const yAdd = await this.contract.yAddress(); expect(yAdd).to.equal("0x8ba1f109551bD432803012645Ac136ddd64DBA72"); y = await this.contract.yUint32(); expect(y).to.equal(52); // 5+15+32 diff --git a/test/reencrypt.ts b/test/reencrypt.ts index 6b74b9e..6b7b0d0 100644 --- a/test/reencrypt.ts +++ b/test/reencrypt.ts @@ -1,11 +1,6 @@ +import { Signer } from "ethers"; import { FhevmInstance } from "fhevmjs/node"; -import { ACCOUNT_NAMES } from "./constants"; -import { Signers } from "./signers"; - -// Add type definition at the top of the file -type AccountName = (typeof ACCOUNT_NAMES)[number]; - const EBOOL_T = 0; const EUINT4_T = 1; const EUINT8_T = 2; @@ -36,137 +31,125 @@ export function verifyType(handle: bigint, expectedType: number) { } export async function reencryptEbool( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EBOOL_T); - return (await reencryptHandle(signers, instances, user, handle, contractAddress)) === 1n; + return (await reencryptHandle(signer, instance, handle, contractAddress)) === 1n; } export async function reencryptEuint4( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT4_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEuint8( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT8_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEuint16( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT16_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEuint32( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT32_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEuint64( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT64_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEuint128( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT128_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEaddress( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT160_T); - const addressAsUint160: bigint = await reencryptHandle(signers, instances, user, handle, contractAddress); + const addressAsUint160: bigint = await reencryptHandle(signer, instance, handle, contractAddress); const handleStr = "0x" + addressAsUint160.toString(16).padStart(40, "0"); return handleStr; } export async function reencryptEuint256( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EUINT256_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEbytes64( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EBYTES64_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEbytes128( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EBYTES128_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } export async function reencryptEbytes256( - signers: Signers, - instances: FhevmInstance, - user: AccountName, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { verifyType(handle, EBYTES256_T); - return reencryptHandle(signers, instances, user, handle, contractAddress); + return reencryptHandle(signer, instance, handle, contractAddress); } /** @@ -174,19 +157,14 @@ export async function reencryptEbytes256( * It does not verify types. */ async function reencryptHandle( - signers: Signers, + signer: Signer, instance: FhevmInstance, - user: AccountName, handle: bigint, contractAddress: string, ): Promise { const { publicKey: publicKey, privateKey: privateKey } = instance.generateKeypair(); const eip712 = instance.createEIP712(publicKey, contractAddress); - const signature = await signers[user as keyof Signers].signTypedData( - eip712.domain, - { Reencrypt: eip712.types.Reencrypt }, - eip712.message, - ); + const signature = await signer.signTypedData(eip712.domain, { Reencrypt: eip712.types.Reencrypt }, eip712.message); const reencryptedHandle = await instance.reencrypt( handle, @@ -194,7 +172,7 @@ async function reencryptHandle( publicKey, signature.replace("0x", ""), contractAddress, - signers[user as keyof Signers].address, + await signer.getAddress(), ); return reencryptedHandle; diff --git a/test/signers.ts b/test/signers.ts index fb98a77..5fe72ca 100644 --- a/test/signers.ts +++ b/test/signers.ts @@ -9,7 +9,7 @@ export interface Signers { [K in AccountNames]: HardhatEthersSigner; } -let signers: Signers = {} as Signers; +const signers: Signers = {} as Signers; export const initSigners = async (): Promise => { if (Object.entries(signers).length === 0) {