diff --git a/CustomProvider.ts b/CustomProvider.ts index b60308e..d48f2f4 100644 --- a/CustomProvider.ts +++ b/CustomProvider.ts @@ -1,4 +1,3 @@ -import { ethers } from "ethers"; import { ProviderWrapper } from "hardhat/plugins"; import type { EIP1193Provider, RequestArguments } from "hardhat/types"; @@ -19,11 +18,6 @@ class CustomProvider extends ProviderWrapper implements Test { } async request(args: RequestArguments): ReturnType { - if (args.method === "eth_estimateGas") { - const estimatedGasLimit = BigInt((await this._wrappedProvider.request(args)) as bigint); - const increasedGasLimit = ethers.toBeHex((estimatedGasLimit * 120n) / 100n); // override estimated gasLimit by 120%, to avoid some edge case with ethermint gas estimation - return increasedGasLimit; - } if (args.method === "evm_revert") { const result = await this._wrappedProvider.request(args); const blockNumberHex = (await this._wrappedProvider.request({ method: "eth_blockNumber" })) as string; diff --git a/README.md b/README.md index e46f92a..153ce13 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,10 @@ inherited contracts. // SPDX-License-Identifier: BSD-3-Clause-Clear pragma solidity ^0.8.24; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; import { ConfidentialERC20 } from "fhevm-contracts/contracts/token/ERC20/ConfidentialERC20.sol"; -contract MyERC20 is MockZamaFHEVMConfig, ConfidentialERC20 { +contract MyERC20 is SepoliaZamaFHEVMConfig, ConfidentialERC20 { constructor() ConfidentialERC20("MyToken", "MYTOKEN") { _unsafeMint(1000000, msg.sender); } diff --git a/contracts/test/governance/TestConfidentialERC20Votes.sol b/contracts/test/governance/TestConfidentialERC20Votes.sol index 5b0a398..9eb9b9f 100644 --- a/contracts/test/governance/TestConfidentialERC20Votes.sol +++ b/contracts/test/governance/TestConfidentialERC20Votes.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.24; import { ConfidentialERC20Votes } from "../../governance/ConfidentialERC20Votes.sol"; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; -contract TestConfidentialERC20Votes is MockZamaFHEVMConfig, ConfidentialERC20Votes { +contract TestConfidentialERC20Votes is SepoliaZamaFHEVMConfig, ConfidentialERC20Votes { constructor( address owner_, string memory name_, diff --git a/contracts/test/governance/TestConfidentialGovernorAlpha.sol b/contracts/test/governance/TestConfidentialGovernorAlpha.sol index 40595f3..a4ecca5 100644 --- a/contracts/test/governance/TestConfidentialGovernorAlpha.sol +++ b/contracts/test/governance/TestConfidentialGovernorAlpha.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.24; import { ConfidentialGovernorAlpha } from "../../governance/ConfidentialGovernorAlpha.sol"; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; -import { MockZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol"; -contract TestConfidentialGovernorAlpha is MockZamaFHEVMConfig, MockZamaGatewayConfig, ConfidentialGovernorAlpha { +contract TestConfidentialGovernorAlpha is SepoliaZamaFHEVMConfig, SepoliaZamaGatewayConfig, ConfidentialGovernorAlpha { constructor( address owner_, address timelock_, diff --git a/contracts/test/token/ERC20/TestConfidentialERC20Mintable.sol b/contracts/test/token/ERC20/TestConfidentialERC20Mintable.sol index 4fd9317..250d2de 100644 --- a/contracts/test/token/ERC20/TestConfidentialERC20Mintable.sol +++ b/contracts/test/token/ERC20/TestConfidentialERC20Mintable.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.24; import { ConfidentialERC20Mintable } from "../../../token/ERC20/extensions/ConfidentialERC20Mintable.sol"; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; -contract TestConfidentialERC20Mintable is MockZamaFHEVMConfig, ConfidentialERC20Mintable { +contract TestConfidentialERC20Mintable is SepoliaZamaFHEVMConfig, ConfidentialERC20Mintable { constructor( string memory name_, string memory symbol_, diff --git a/contracts/test/token/ERC20/TestConfidentialERC20WithErrorsMintable.sol b/contracts/test/token/ERC20/TestConfidentialERC20WithErrorsMintable.sol index 2fe0137..6d91c3e 100644 --- a/contracts/test/token/ERC20/TestConfidentialERC20WithErrorsMintable.sol +++ b/contracts/test/token/ERC20/TestConfidentialERC20WithErrorsMintable.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.24; import { ConfidentialERC20WithErrorsMintable } from "../../../token/ERC20/extensions/ConfidentialERC20WithErrorsMintable.sol"; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; -contract TestConfidentialERC20WithErrorsMintable is MockZamaFHEVMConfig, ConfidentialERC20WithErrorsMintable { +contract TestConfidentialERC20WithErrorsMintable is SepoliaZamaFHEVMConfig, ConfidentialERC20WithErrorsMintable { constructor( string memory name_, string memory symbol_, diff --git a/contracts/test/utils/TestEncryptedErrors.sol b/contracts/test/utils/TestEncryptedErrors.sol index 95be14f..dc4c047 100644 --- a/contracts/test/utils/TestEncryptedErrors.sol +++ b/contracts/test/utils/TestEncryptedErrors.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.24; import "fhevm/lib/TFHE.sol"; import { EncryptedErrors } from "../../utils/EncryptedErrors.sol"; -import { MockZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; +import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol"; -contract TestEncryptedErrors is MockZamaFHEVMConfig, EncryptedErrors { +contract TestEncryptedErrors is SepoliaZamaFHEVMConfig, EncryptedErrors { constructor(uint8 totalNumberErrorCodes_) EncryptedErrors(totalNumberErrorCodes_) { for (uint8 i; i <= totalNumberErrorCodes_; i++) { /// @dev It is not possible to access the _errorCodeDefinitions since it is private. diff --git a/hardhat.config.ts b/hardhat.config.ts index 1081d41..9c1ac97 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,22 +1,14 @@ import "@nomicfoundation/hardhat-toolbox"; import "@openzeppelin/hardhat-upgrades"; import dotenv from "dotenv"; -import * as fs from "fs-extra"; import "hardhat-ignore-warnings"; -import type { HardhatUserConfig } from "hardhat/config"; -import { extendProvider, task } from "hardhat/config"; +import { HardhatUserConfig, extendProvider } from "hardhat/config"; +import { task } from "hardhat/config"; import type { NetworkUserConfig } from "hardhat/types"; import { resolve } from "path"; -import * as path from "path"; -import "solidity-docgen"; import CustomProvider from "./CustomProvider"; -// Adjust the import path as needed -import "./tasks/accounts"; -import "./tasks/getEthereumAddress"; -import "./tasks/taskDeploy"; -import "./tasks/taskGatewayRelayer"; -import "./tasks/taskTFHE"; +import { setCodeMocked } from "./test/mockedSetup"; extendProvider(async (provider) => { const newProvider = new CustomProvider(provider); @@ -36,10 +28,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. -const mnemonic: string | undefined = process.env.MNEMONIC; -if (!mnemonic) { - throw new Error("Please set your MNEMONIC in a .env file"); -} +const mnemonic: string = process.env.MNEMONIC!; const chainIds = { zama: 8009, @@ -77,59 +66,14 @@ function getChainConfig(chain: keyof typeof chainIds): NetworkUserConfig { task("coverage").setAction(async (taskArgs, hre, runSuper) => { hre.config.networks.hardhat.allowUnlimitedContractSize = true; hre.config.networks.hardhat.blockGasLimit = 1099511627775; + 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) => { // Run modified test task if (hre.network.name === "hardhat") { - // in fhevm mode all this block is done when launching the node via `pnmp fhevm:start` - const privKeyGatewayDeployer = process.env.PRIVATE_KEY_GATEWAY_DEPLOYER; - const privKeyFhevmDeployer = process.env.PRIVATE_KEY_FHEVM_DEPLOYER; - await hre.run("task:computeGatewayAddress", { privateKey: privKeyGatewayDeployer }); - await hre.run("task:computeACLAddress", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:computeTFHEExecutorAddress", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:computeKMSVerifierAddress", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:computeInputVerifierAddress", { privateKey: privKeyFhevmDeployer, useAddress: false }); - await hre.run("task:computeFHEPaymentAddress", { privateKey: privKeyFhevmDeployer }); - await hre.run("compile:specific", { contract: "contracts/" }); - const sourceDir = path.resolve(__dirname, "node_modules/fhevm-core-contracts/"); - const destinationDir = path.resolve(__dirname, "fhevmTemp/"); - fs.copySync(sourceDir, destinationDir, { dereference: true }); - - const sourceDir2 = path.resolve("./node_modules/fhevm/gateway/GatewayContract.sol"); - const destinationFilePath = path.join(destinationDir, "GatewayContract.sol"); - fs.copySync(sourceDir2, destinationFilePath, { dereference: true }); - const oldImport = `import "../lib/TFHE.sol";`; - const newImport = `import "fhevm/lib/TFHE.sol";`; - replaceImportStatement(destinationFilePath, oldImport, newImport); - const sourceDir3 = path.resolve("./node_modules/fhevm/gateway/IKMSVerifier.sol"); - const destinationFilePath3 = path.join(destinationDir, "IKMSVerifier.sol"); - fs.copySync(sourceDir3, destinationFilePath3, { dereference: true }); - - await hre.run("compile:specific", { contract: "fhevmTemp/" }); - await hre.run("task:faucetToPrivate", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:deployACL", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:deployTFHEExecutor", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:deployKMSVerifier", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:deployInputVerifier", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:deployFHEPayment", { privateKey: privKeyFhevmDeployer }); - await hre.run("task:addSigners", { - numSigners: process.env.NUM_KMS_SIGNERS!, - privateKey: privKeyFhevmDeployer, - useAddress: false, - }); - await hre.run("task:launchFhevm", { skipGetCoin: false, useAddress: false }); + await setCodeMocked(hre); } await runSuper(); }); diff --git a/package.json b/package.json index ef77dac..a5ba9a0 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,9 @@ "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", "ethers": "^6.13.4", - "fhevm": "0.6.0-1", - "fhevm-core-contracts": "0.1.0-2", - "fhevmjs": "^0.6.0-4", + "fhevm": "0.6.0", + "fhevm-core-contracts": "0.6.0", + "fhevmjs": "0.6.0", "fs-extra": "^11.2.0", "hardhat": "2.22.14", "hardhat-gas-reporter": "^1.0.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 637b001..381fe3e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,14 +91,14 @@ importers: specifier: ^6.13.4 version: 6.13.4 fhevm: - specifier: 0.6.0-1 - version: 0.6.0-1 + specifier: 0.6.0 + version: 0.6.0 fhevm-core-contracts: - specifier: 0.1.0-2 - version: 0.1.0-2 + specifier: 0.6.0 + version: 0.6.0 fhevmjs: - specifier: ^0.6.0-4 - version: 0.6.0-4 + specifier: 0.6.0 + version: 0.6.0 fs-extra: specifier: ^11.2.0 version: 11.2.0 @@ -980,9 +980,6 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/keccak@3.0.5': - resolution: {integrity: sha512-Mvu4StIJ9KyfPXDVRv3h0fWNBAjHPBQZ8EPcxhqA8FG6pLzxtytVXU5owB6J2/8xZ+ZspWTXJEUjAHt0pk0I1Q==} - '@types/lru-cache@5.1.1': resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} @@ -1926,15 +1923,15 @@ packages: node-fetch: optional: true - fhevm-core-contracts@0.1.0-2: - resolution: {integrity: sha512-lTUodggGV4+pZVFRKRb22t3rWyfR8iFZLgNxRBozgAEUSsIDe16PI9vn8PkfJzJJdOlPk9XsTY6/s1pACDbwfA==} + fhevm-core-contracts@0.6.0: + resolution: {integrity: sha512-j62NNTITZOqHTl0sw4EjBV9YJTPDMnBzzYMoLVtoeHUMibZj6jgkBofEltjVmpKRjQr0O5q6xf+Xw9fDOlFQSg==} - fhevm@0.6.0-1: - resolution: {integrity: sha512-tMmwQHfJftwHar3ZFWg5dIHO0cl64QCklYNvKgABBUEF3sHdt9DtjI6bLQQmMY4e0FEOYfuaAiU0PfRIlFY+xA==} + fhevm@0.6.0: + resolution: {integrity: sha512-6tcVRLzlhg0s1gThACYCVP94Ir/k61Zaj4IsVyEBFP7WJEHdeOF61OYUZIIKlMofKdToVBadNus+XO8ys47Ysw==} engines: {node: '>=20.0.0'} - fhevmjs@0.6.0-4: - resolution: {integrity: sha512-gPnEHnkAwoJivP+K1KtOx7ZeBpZGtQW1QaAVC1zxDtMWQKCcqJMmNQOt0ur/2buw6WE4VfDIIWXneZ1hHCzLHQ==} + fhevmjs@0.6.0: + resolution: {integrity: sha512-xukyiXv+KertTTEIhFuZp2jW31RBOXUC6TfVZBAUVEr1xiTnvXtePwuutvqj3rabnclRBTzr/j4UmEPvCaGXQw==} engines: {node: '>=20'} hasBin: true @@ -2811,11 +2808,11 @@ packages: resolution: {integrity: sha512-bJ9zMDuNGzVQg1xv0bCPzyEDxHgbrx7/xGj6CDokvizZZmastPsOh0JJLuY8wA5q2SfX1TLNMk7XNV8WxbGxzA==} engines: {node: '>= 14.0.0'} - node-tfhe@0.8.6: - resolution: {integrity: sha512-u9WHiD/vTQ/FIph+52l/jyKzyDh/vLnyw50oSdz0eb1CTs2lqbiA8l8MNxgMkBP1zDadR0qzg37VCt3UkoC2ig==} + node-tfhe@0.9.1: + resolution: {integrity: sha512-M2CbUVX4DQneaaK/4fygy9lW0zjOOzM8yGWAgbKGRt/Gd07zaloFEGGHW7dbmUaHo022q1uo7nzxyYhe4UgqCw==} - node-tkms@0.9.0-rc3: - resolution: {integrity: sha512-Jr3faNAudjBO2Up+Gc3QPF7Dq07fDR/n0NKCHGtS69qLKnoqqaKxGULdKg3gpbtdx0wnj/GaQjvprUIgnIm7yQ==} + node-tkms@0.9.0-rc36: + resolution: {integrity: sha512-oGqJfjvb/igd9VgQaqYbzKc+CmrnQ/eY0ShmdE3JDKXL3C4Re/tBswT0KkWmlT1aM+Lxt5ihRNOs2oHtrPqr5w==} nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} @@ -3053,9 +3050,6 @@ packages: pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3064,10 +3058,6 @@ packages: resolution: {integrity: sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==} engines: {node: '>=0.6'} - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3554,8 +3544,8 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - tfhe@0.8.6: - resolution: {integrity: sha512-Mxa6ywC4fAayHK0xBPJfrVUt4Tt5+ozQyVQcAlj3gK1i5rJI/pcwCDvf27Xxtkb0fMyRYgKDwrETVfC51r1Fcw==} + tfhe@0.9.1: + resolution: {integrity: sha512-kmtl7KfCCZJaFhm9lUYsTtat+yT0qzOiO6bOidM2Pt7/7jptkbS2/myeGHxb9qi2/aJ30g2joo1euKZPa207tg==} then-request@6.0.2: resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} @@ -3570,8 +3560,8 @@ packages: tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} - tkms@0.9.0-rc3: - resolution: {integrity: sha512-7ynaHiFnXS9Xok62vsi2GGeTUxmb1Ao7I5k9akE8lEQ5M9FERmaGLF3TapDLGsYMDz7Km7dFeTfrsjCg38OC/w==} + tkms@0.9.0-rc36: + resolution: {integrity: sha512-8IoRi6mYgnrmwTNBe/ejvHOFRhs5M6o2Ls2RVXCgAzSVBBBWJC1O8hquqlciHfME/VooUD4iokzEaBfADvoXZw==} tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} @@ -3745,10 +3735,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url@0.11.4: - resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} - engines: {node: '>= 0.4'} - utf8@3.0.0: resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} @@ -3765,6 +3751,9 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + wasm-feature-detect@1.8.0: + resolution: {integrity: sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==} + web3-errors@1.3.0: resolution: {integrity: sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ==} engines: {node: '>=14', npm: '>=6.12.0'} @@ -5018,10 +5007,6 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/keccak@3.0.5': - dependencies: - '@types/node': 18.19.59 - '@types/lru-cache@5.1.1': {} '@types/minimatch@5.1.2': {} @@ -6142,9 +6127,9 @@ snapshots: is-subset: 0.1.1 regexparam: 3.0.0 - fhevm-core-contracts@0.1.0-2: {} + fhevm-core-contracts@0.6.0: {} - fhevm@0.6.0-1: + fhevm@0.6.0: dependencies: '@openzeppelin/contracts': 5.0.2 extra-bigint: 1.2.0 @@ -6153,19 +6138,17 @@ snapshots: - bluebird - supports-color - fhevmjs@0.6.0-4: + fhevmjs@0.6.0: dependencies: - '@types/keccak': 3.0.5 bigint-buffer: 1.1.5 commander: 11.1.0 fetch-mock: 11.1.5 - node-tfhe: 0.8.6 - node-tkms: 0.9.0-rc3 - sha3: 2.1.4 - tfhe: 0.8.6 - tkms: 0.9.0-rc3 - url: 0.11.4 - web3-validator: 2.0.6 + keccak: 3.0.4 + node-tfhe: 0.9.1 + node-tkms: 0.9.0-rc36 + tfhe: 0.9.1 + tkms: 0.9.0-rc36 + wasm-feature-detect: 1.8.0 transitivePeerDependencies: - node-fetch @@ -7135,9 +7118,9 @@ snapshots: dependencies: shallowequal: 1.1.0 - node-tfhe@0.8.6: {} + node-tfhe@0.9.1: {} - node-tkms@0.9.0-rc3: {} + node-tkms@0.9.0-rc36: {} nofilter@3.1.0: {} @@ -7361,18 +7344,12 @@ snapshots: end-of-stream: 1.4.4 once: 1.4.0 - punycode@1.4.1: {} - punycode@2.3.1: {} qs@6.12.0: dependencies: side-channel: 1.0.6 - qs@6.13.0: - dependencies: - side-channel: 1.0.6 - queue-microtask@1.2.3: {} quick-lru@5.1.1: {} @@ -7922,7 +7899,7 @@ snapshots: text-table@0.2.0: {} - tfhe@0.8.6: {} + tfhe@0.9.1: {} then-request@6.0.2: dependencies: @@ -7946,7 +7923,7 @@ snapshots: tinyexec@0.3.1: {} - tkms@0.9.0-rc3: {} + tkms@0.9.0-rc36: {} tmp@0.0.33: dependencies: @@ -8105,11 +8082,6 @@ snapshots: dependencies: punycode: 2.3.1 - url@0.11.4: - dependencies: - punycode: 1.4.1 - qs: 6.13.0 - utf8@3.0.0: {} util-deprecate@1.0.2: {} @@ -8126,6 +8098,8 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + wasm-feature-detect@1.8.0: {} + web3-errors@1.3.0: dependencies: web3-types: 1.8.1 diff --git a/test/asyncDecrypt.ts b/test/asyncDecrypt.ts index b683543..6e1e58e 100644 --- a/test/asyncDecrypt.ts +++ b/test/asyncDecrypt.ts @@ -1,16 +1,14 @@ -import dotenv from "dotenv"; -import { Wallet } from "ethers"; -import fs from "fs"; +import { Contract, Wallet, ZeroAddress } from "ethers"; +import gatewayArtifact from "fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json"; import { ethers, network } from "hardhat"; -import { GatewayContract } from "../types"; +import { ACL_ADDRESS, GATEWAYCONTRACT_ADDRESS, KMSVERIFIER_ADDRESS, PRIVATE_KEY_KMS_SIGNER } from "./constants"; import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; +import { impersonateAddress } from "./mockedSetup"; import { waitNBlocks } from "./utils"; const networkName = network.name; - -const parsedEnvACL = dotenv.parse(fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.acl")); -const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS; +const aclAdd = ACL_ADDRESS; const CiphertextType = { 0: "bool", @@ -32,13 +30,6 @@ const currentTime = (): string => { return now.toLocaleTimeString("en-US", { hour12: true, hour: "numeric", minute: "numeric", second: "numeric" }); }; -const parsedEnv = dotenv.parse(fs.readFileSync("node_modules/fhevm/gateway/.env.gateway")); -let relayer: Wallet; -if (networkName === "hardhat") { - const privKeyRelayer = process.env.PRIVATE_KEY_GATEWAY_RELAYER; - relayer = new ethers.Wallet(privKeyRelayer!, ethers.provider); -} - const argEvents = "(uint256 indexed requestID, uint256[] cts, address contractCaller, bytes4 callbackSelector, uint256 msgValue, uint256 maxTimestamp, bool passSignaturesToCaller)"; const ifaceEventDecryption = new ethers.Interface(["event EventDecryption" + argEvents]); @@ -46,7 +37,7 @@ const ifaceEventDecryption = new ethers.Interface(["event EventDecryption" + arg const argEvents2 = "(uint256 indexed requestID, bool success, bytes result)"; const ifaceResultCallback = new ethers.Interface(["event ResultCallback" + argEvents2]); -let gateway: GatewayContract; +let gateway: Contract; let firstBlockListening: number; let lastBlockSnapshotForDecrypt: number; @@ -57,22 +48,22 @@ export const initGateway = async (): Promise => { await ethers.provider.send("set_lastBlockSnapshotForDecrypt", [firstBlockListening]); } // this function will emit logs for every request and fulfilment of a decryption - gateway = await ethers.getContractAt("GatewayContract", parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS); + gateway = await ethers.getContractAt(gatewayArtifact.abi, GATEWAYCONTRACT_ADDRESS); gateway.on( "EventDecryption", - async (requestID, cts, contractCaller, callbackSelector, msgValue, maxTimestamp, eventData) => { + async (requestID, _cts, _contractCaller, _callbackSelector, _msgValue, _maxTimestamp, eventData) => { const blockNumber = eventData.log.blockNumber; - console.log(`${await currentTime()} - Requested decrypt on block ${blockNumber} (requestID ${requestID})`); + console.log(`${currentTime()} - Requested decrypt on block ${blockNumber} (requestID ${requestID})`); }, ); - gateway.on("ResultCallback", async (requestID, success, result, eventData) => { + gateway.on("ResultCallback", async (requestID, _success, _result, eventData) => { const blockNumber = eventData.log.blockNumber; - console.log(`${await currentTime()} - Fulfilled decrypt on block ${blockNumber} (requestID ${requestID})`); + console.log(`${currentTime()} - Fulfilled decrypt on block ${blockNumber} (requestID ${requestID})`); }); }; export const awaitAllDecryptionResults = async (): Promise => { - gateway = await ethers.getContractAt("GatewayContract", parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS); + gateway = await ethers.getContractAt(gatewayArtifact.abi, GATEWAYCONTRACT_ADDRESS); const provider = ethers.provider; if (networkName === "hardhat" && hre.__SOLIDITY_COVERAGE_RUNNING !== true) { // evm_snapshot is not supported in coverage mode @@ -90,17 +81,16 @@ export const awaitAllDecryptionResults = async (): Promise => { }; const getAlreadyFulfilledDecryptions = async (): Promise<[bigint]> => { - let results = []; + let results: any[] | PromiseLike<[bigint]> = []; const eventDecryptionResult = await gateway.filters.ResultCallback().getTopicFilter(); const filterDecryptionResult = { - address: parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS, + address: GATEWAYCONTRACT_ADDRESS, fromBlock: firstBlockListening, toBlock: "latest", topics: eventDecryptionResult, }; const pastResults = await ethers.provider.getLogs(filterDecryptionResult); results = results.concat(pastResults.map((result) => ifaceResultCallback.parseLog(result).args[0])); - return results; }; @@ -110,7 +100,7 @@ const fulfillAllPastRequestsIds = async (mocked: boolean) => { const eventDecryption = await gateway.filters.EventDecryption().getTopicFilter(); const results = await getAlreadyFulfilledDecryptions(); const filterDecryption = { - address: parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS, + address: GATEWAYCONTRACT_ADDRESS, fromBlock: firstBlockListening, toBlock: "latest", topics: eventDecryption, @@ -130,13 +120,13 @@ const fulfillAllPastRequestsIds = async (mocked: boolean) => { await awaitCoprocessor(); // first check tat all handles are allowed for decryption - const aclFactory = await ethers.getContractFactory("fhevmTemp/contracts/ACL.sol:ACL"); - const acl = aclFactory.attach(aclAdd); + const aclArtifact = require("fhevm-core-contracts/artifacts/contracts/ACL.sol/ACL.json"); + const acl = await ethers.getContractAt(aclArtifact.abi, ACL_ADDRESS); const isAllowedForDec = await Promise.all(handles.map(async (handle) => acl.isAllowedForDecryption(handle))); if (!allTrue(isAllowedForDec)) { throw new Error("Some handle is not authorized for decryption"); } - const types = typesList.map((num) => CiphertextType[num]); + const types = typesList.map((num: string | number) => CiphertextType[num]); const values = await Promise.all(handles.map(async (handle) => BigInt(await getClearText(handle)))); const valuesFormatted = values.map((value, index) => types[index] === "address" ? "0x" + value.toString(16).padStart(40, "0") : value, @@ -162,14 +152,14 @@ const fulfillAllPastRequestsIds = async (mocked: boolean) => { calldata = "0x" + encodedData.slice(66).slice(0, -64); // we also pop the last 32 bytes (empty bytes[]) } - const numSigners = +process.env.NUM_KMS_SIGNERS!; + const numSigners = 1; // for the moment mocked mode only uses 1 signer const decryptResultsEIP712signatures = await computeDecryptSignatures(handles, calldata, numSigners); - const tx = await gateway + const relayer = await impersonateAddress(hre, ZeroAddress, ethers.parseEther("100")); + await gateway .connect(relayer) .fulfillRequest(requestID, calldata, decryptResultsEIP712signatures, { value: msgValue }); - await tx.wait(); } else { - // in fhEVM mode we must wait until the gateway service relayer submits the decryption fulfillment tx + // in non-mocked mode we must wait until the gateway service relayer submits the decryption fulfillment tx await waitNBlocks(1); await fulfillAllPastRequestsIds(mocked); } @@ -185,7 +175,7 @@ async function computeDecryptSignatures( const signatures: string[] = []; for (let idx = 0; idx < numSigners; idx++) { - const privKeySigner = process.env[`PRIVATE_KEY_KMS_SIGNER_${idx}`]; + const privKeySigner = PRIVATE_KEY_KMS_SIGNER; if (privKeySigner) { const kmsSigner = new ethers.Wallet(privKeySigner).connect(ethers.provider); const signature = await kmsSign(handlesList, decryptedResult, kmsSigner); @@ -198,9 +188,7 @@ async function computeDecryptSignatures( } async function kmsSign(handlesList: bigint[], decryptedResult: string, kmsSigner: Wallet) { - const kmsAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.kmsverifier"), - ).KMS_VERIFIER_CONTRACT_ADDRESS; + const kmsAdd = KMSVERIFIER_ADDRESS; const chainId = (await ethers.provider.getNetwork()).chainId; const domain = { diff --git a/test/confidentialERC20/ConfidentialERC20.fixture.ts b/test/confidentialERC20/ConfidentialERC20.fixture.ts index 7eed5b2..d890579 100644 --- a/test/confidentialERC20/ConfidentialERC20.fixture.ts +++ b/test/confidentialERC20/ConfidentialERC20.fixture.ts @@ -1,45 +1,41 @@ +import { Signer } from "ethers"; +import { FhevmInstance } from "fhevmjs/node"; import { ethers } from "hardhat"; import type { IConfidentialERC20, TestConfidentialERC20Mintable } from "../../types"; import { reencryptEuint64 } from "../reencrypt"; -import { Signers } from "../signers"; -import { FhevmInstances } from "../types"; export async function deployConfidentialERC20Fixture( - signers: Signers, + signer: Signer, name: string, symbol: string, - owner: string, + ownerAddress: string, ): Promise { const contractFactory = await ethers.getContractFactory("TestConfidentialERC20Mintable"); - const contract = await contractFactory - .connect(signers[owner as keyof Signers]) - .deploy(name, symbol, signers[owner as keyof Signers].address); + const contract = await contractFactory.connect(signer).deploy(name, symbol, ownerAddress); await contract.waitForDeployment(); return contract; } export async function reencryptAllowance( - signers: Signers, - instances: FhevmInstances, - account: string, - spender: string, + account: Signer, + spender: Signer, + instance: FhevmInstance, token: IConfidentialERC20, tokenAddress: string, ): Promise { - const allowanceHandle = await token.allowance(signers[account as keyof Signers], signers[spender as keyof Signers]); - const allowance = await reencryptEuint64(signers, instances, account, allowanceHandle, tokenAddress); + const allowanceHandle = await token.allowance(account, spender); + const allowance = await reencryptEuint64(account, instance, allowanceHandle, tokenAddress); return allowance; } export async function reencryptBalance( - signers: Signers, - instances: FhevmInstances, - account: string, + account: Signer, + instance: FhevmInstance, token: IConfidentialERC20, tokenAddress: string, ): Promise { - const balanceHandle = await token.balanceOf(signers[account as keyof Signers]); - const balance = await reencryptEuint64(signers, instances, account, balanceHandle, tokenAddress); + const balanceHandle = await token.balanceOf(account); + const balance = await reencryptEuint64(account, instance, balanceHandle, tokenAddress); return balance; } diff --git a/test/confidentialERC20/ConfidentialERC20.test.ts b/test/confidentialERC20/ConfidentialERC20.test.ts index 10b807e..e4f3fdf 100644 --- a/test/confidentialERC20/ConfidentialERC20.test.ts +++ b/test/confidentialERC20/ConfidentialERC20.test.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; -import { createInstances } from "../instance"; +import { createInstance } from "../instance"; import { getSigners, initSigners } from "../signers"; import { deployConfidentialERC20Fixture, reencryptAllowance, reencryptBalance } from "./ConfidentialERC20.fixture"; @@ -9,15 +9,20 @@ describe("ConfidentialERC20", function () { const PLACEHOLDER = 2n ** 256n - 1n; before(async function () { - await initSigners(2); + await initSigners(); this.signers = await getSigners(); + this.instance = await createInstance(); }); beforeEach(async function () { - const contract = await deployConfidentialERC20Fixture(this.signers, "Naraggara", "NARA", "alice"); + const contract = await deployConfidentialERC20Fixture( + this.signers.alice, + "Naraggara", + "NARA", + await this.signers.alice.getAddress(), + ); this.confidentialERC20Address = await contract.getAddress(); this.confidentialERC20 = contract; - this.instances = await createInstances(this.signers); }); it("post-deployment state", async function () { @@ -33,13 +38,7 @@ describe("ConfidentialERC20", function () { await expect(tx).to.emit(this.confidentialERC20, "Mint").withArgs(this.signers.alice, mintAmount); expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); expect(await this.confidentialERC20.totalSupply()).to.equal(mintAmount); @@ -52,7 +51,7 @@ describe("ConfidentialERC20", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -68,24 +67,12 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount - transferAmount); // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(transferAmount); }); @@ -98,7 +85,7 @@ describe("ConfidentialERC20", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -115,24 +102,12 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(0); }); @@ -145,10 +120,7 @@ describe("ConfidentialERC20", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const inputAlice = this.instances.alice.createEncryptedInput( - this.confidentialERC20Address, - this.signers.alice.address, - ); + const inputAlice = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); inputAlice.add64(transferAmount); const encryptedAllowanceAmount = await inputAlice.encrypt(); @@ -165,17 +137,16 @@ describe("ConfidentialERC20", function () { // @dev The allowance amount is set to be equal to the transfer amount. expect( await reencryptAllowance( - this.signers, - this.instances, - "alice", - "bob", + this.signers.alice, + this.signers.bob, + this.instance, this.confidentialERC20, this.confidentialERC20Address, ), ).to.equal(transferAmount); const bobErc20 = this.confidentialERC20.connect(this.signers.bob); - const inputBob1 = this.instances.bob.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); + const inputBob1 = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); inputBob1.add64(transferAmount + 1); // above allowance so next tx should actually not send any token const encryptedTransferAmount = await inputBob1.encrypt(); @@ -192,27 +163,15 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); // check that transfer did not happen, as expected // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(0); // check that transfer did not happen, as expected - const inputBob2 = this.instances.bob.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); + const inputBob2 = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); inputBob2.add64(transferAmount); // below allowance so next tx should send token const encryptedTransferAmount2 = await inputBob2.encrypt(); @@ -226,33 +185,20 @@ describe("ConfidentialERC20", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount - transferAmount); // check that transfer did happen this time // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(transferAmount); // check that transfer did happen this time // Verify Alice's allowance is 0 expect( await reencryptAllowance( - this.signers, - this.instances, - "alice", - "bob", + this.signers.alice, + this.signers.bob, + this.instance, this.confidentialERC20, this.confidentialERC20Address, ), @@ -262,10 +208,7 @@ describe("ConfidentialERC20", function () { it("should not be able to read the allowance if not spender/owner after initialization", async function () { const amount = 10_000; - const inputAlice = this.instances.alice.createEncryptedInput( - this.confidentialERC20Address, - this.signers.alice.address, - ); + const inputAlice = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); inputAlice.add64(amount); const encryptedAllowanceAmount = await inputAlice.encrypt(); @@ -279,8 +222,8 @@ describe("ConfidentialERC20", function () { const allowanceHandleAlice = await this.confidentialERC20.allowance(this.signers.alice, this.signers.bob); - const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = this.instances.carol.generateKeypair(); - const eip712Carol = this.instances.carol.createEIP712(publicKeyCarol, this.confidentialERC20Address); + const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = await this.instance.generateKeypair(); + const eip712Carol = this.instance.createEIP712(publicKeyCarol, this.confidentialERC20Address); const signatureCarol = await this.signers.carol.signTypedData( eip712Carol.domain, { Reencrypt: eip712Carol.types.Reencrypt }, @@ -288,7 +231,7 @@ describe("ConfidentialERC20", function () { ); await expect( - this.instances.bob.reencrypt( + this.instance.reencrypt( allowanceHandleAlice, privateKeyCarol, publicKeyCarol, @@ -307,8 +250,8 @@ describe("ConfidentialERC20", function () { const balanceHandleAlice = await this.confidentialERC20.balanceOf(this.signers.alice); - const { publicKey: publicKeyBob, privateKey: privateKeyBob } = this.instances.bob.generateKeypair(); - const eip712Bob = this.instances.bob.createEIP712(publicKeyBob, this.confidentialERC20Address); + const { publicKey: publicKeyBob, privateKey: privateKeyBob } = await this.instance.generateKeypair(); + const eip712Bob = this.instance.createEIP712(publicKeyBob, this.confidentialERC20Address); const signatureBob = await this.signers.bob.signTypedData( eip712Bob.domain, { Reencrypt: eip712Bob.types.Reencrypt }, @@ -316,7 +259,7 @@ describe("ConfidentialERC20", function () { ); await expect( - this.instances.bob.reencrypt( + this.instance.reencrypt( balanceHandleAlice, privateKeyBob, publicKeyBob, @@ -334,7 +277,7 @@ describe("ConfidentialERC20", function () { const tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -353,7 +296,7 @@ describe("ConfidentialERC20", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -379,7 +322,7 @@ describe("ConfidentialERC20", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - let input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + let input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(mintAmount); const encryptedAllowanceAmount = await input.encrypt(); @@ -389,7 +332,7 @@ describe("ConfidentialERC20", function () { "approve(address,bytes32,bytes)" ](this.signers.carol.address, encryptedAllowanceAmount.handles[0], encryptedAllowanceAmount.inputProof); - input = this.instances.carol.createEncryptedInput(this.confidentialERC20Address, this.signers.carol.address); + input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.carol.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -413,7 +356,7 @@ describe("ConfidentialERC20", function () { it("sender who is not allowed cannot approve using a handle from another account", async function () { const amount = 100_000; - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(amount); const encryptedAllowanceAmount = await input.encrypt(); diff --git a/test/confidentialERC20/ConfidentialERC20WithErrors.fixture.ts b/test/confidentialERC20/ConfidentialERC20WithErrors.fixture.ts index 4b7ea16..12e6a07 100644 --- a/test/confidentialERC20/ConfidentialERC20WithErrors.fixture.ts +++ b/test/confidentialERC20/ConfidentialERC20WithErrors.fixture.ts @@ -1,34 +1,31 @@ +import { Signer } from "ethers"; +import { FhevmInstance } from "fhevmjs/node"; import { ethers } from "hardhat"; import type { TestConfidentialERC20WithErrorsMintable } from "../../types"; import { reencryptEuint8 } from "../reencrypt"; -import { Signers } from "../signers"; -import { FhevmInstances } from "../types"; export async function deployConfidentialERC20WithErrorsFixture( - signers: Signers, + signer: Signer, name: string, symbol: string, - owner: string, + ownerAddress: string, ): Promise { const contractFactory = await ethers.getContractFactory("TestConfidentialERC20WithErrorsMintable"); - const contract = await contractFactory - .connect(signers[owner as keyof Signers]) - .deploy(name, symbol, signers[owner as keyof Signers].address); + const contract = await contractFactory.connect(signer).deploy(name, symbol, ownerAddress); await contract.waitForDeployment(); return contract; } export async function checkErrorCode( - signers: Signers, - instances: FhevmInstances, - account: string, + account: Signer, + instance: FhevmInstance, transferId: bigint, token: TestConfidentialERC20WithErrorsMintable, tokenAddress: string, ): Promise { const errorCodeHandle = await token.getErrorCodeForTransferId(transferId); - const errorCode = await reencryptEuint8(signers, instances, account, errorCodeHandle, tokenAddress); + const errorCode = await reencryptEuint8(account, instance, errorCodeHandle, tokenAddress); switch (errorCode) { case 0n: { return "NO_ERROR"; diff --git a/test/confidentialERC20/ConfidentialERC20WithErrors.test.ts b/test/confidentialERC20/ConfidentialERC20WithErrors.test.ts index ebd2a62..249eb58 100644 --- a/test/confidentialERC20/ConfidentialERC20WithErrors.test.ts +++ b/test/confidentialERC20/ConfidentialERC20WithErrors.test.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; -import { createInstances } from "../instance"; +import { createInstance } from "../instance"; import { getSigners, initSigners } from "../signers"; import { reencryptAllowance, reencryptBalance } from "./ConfidentialERC20.fixture"; import { checkErrorCode, deployConfidentialERC20WithErrorsFixture } from "./ConfidentialERC20WithErrors.fixture"; @@ -10,15 +10,20 @@ describe("ConfidentialERC20WithErrors", function () { const PLACEHOLDER = 2n ** 256n - 1n; before(async function () { - await initSigners(2); + await initSigners(); this.signers = await getSigners(); + this.instance = await createInstance(); }); beforeEach(async function () { - const contract = await deployConfidentialERC20WithErrorsFixture(this.signers, "Naraggara", "NARA", "alice"); + const contract = await deployConfidentialERC20WithErrorsFixture( + this.signers.alice, + "Naraggara", + "NARA", + await this.signers.alice.getAddress(), + ); this.confidentialERC20Address = await contract.getAddress(); this.confidentialERC20 = contract; - this.instances = await createInstances(this.signers); }); it("post-deployment state", async function () { @@ -34,13 +39,7 @@ describe("ConfidentialERC20WithErrors", function () { await expect(tx).to.emit(this.confidentialERC20, "Mint").withArgs(this.signers.alice, mintAmount); expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); expect(await this.confidentialERC20.totalSupply()).to.equal(mintAmount); @@ -54,7 +53,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -70,32 +69,19 @@ describe("ConfidentialERC20WithErrors", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount - transferAmount); // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(transferAmount); // Check the error code matches no error expect( await checkErrorCode( - this.signers, - this.instances, - "alice", + this.signers.alice, + this.instance, expectedTransferId, this.confidentialERC20, this.confidentialERC20Address, @@ -105,9 +91,8 @@ describe("ConfidentialERC20WithErrors", function () { // Check that both the from/to address can read the error code expect( await checkErrorCode( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, expectedTransferId, this.confidentialERC20, this.confidentialERC20Address, @@ -125,7 +110,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -141,32 +126,19 @@ describe("ConfidentialERC20WithErrors", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(0); // Check that the error code matches if balance is not sufficient expect( await checkErrorCode( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, expectedTransferId, this.confidentialERC20, this.confidentialERC20Address, @@ -183,10 +155,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const inputAlice = this.instances.alice.createEncryptedInput( - this.confidentialERC20Address, - this.signers.alice.address, - ); + const inputAlice = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); inputAlice.add64(transferAmount); const encryptedAllowanceAmount = await inputAlice.encrypt(); @@ -203,10 +172,9 @@ describe("ConfidentialERC20WithErrors", function () { // @dev The allowance amount is set to be equal to the transfer amount. expect( await reencryptAllowance( - this.signers, - this.instances, - "alice", - "bob", + this.signers.alice, + this.signers.bob, + this.instance, this.confidentialERC20, this.confidentialERC20Address, ), @@ -214,7 +182,7 @@ describe("ConfidentialERC20WithErrors", function () { const expectedTransferId1 = 0n; - const inputBob1 = this.instances.bob.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); + const inputBob1 = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); inputBob1.add64(transferAmount + 1); // above allowance so next tx should actually not send any token const encryptedTransferAmount = await inputBob1.encrypt(); @@ -230,32 +198,19 @@ describe("ConfidentialERC20WithErrors", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount); // check that transfer did not happen, as expected // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(0); // check that transfer did not happen, as expected // Check that the error code matches if approval is not sufficient expect( await checkErrorCode( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, expectedTransferId1, this.confidentialERC20, this.confidentialERC20Address, @@ -264,7 +219,7 @@ describe("ConfidentialERC20WithErrors", function () { const expectedTransferId2 = 1n; - const inputBob2 = this.instances.bob.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); + const inputBob2 = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.bob.address); inputBob2.add64(transferAmount); // below allowance so next tx should send token const encryptedTransferAmount2 = await inputBob2.encrypt(); @@ -280,33 +235,20 @@ describe("ConfidentialERC20WithErrors", function () { // Decrypt Alice's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "alice", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.alice, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(mintAmount - transferAmount); // check that transfer did happen this time // Decrypt Bob's balance expect( - await reencryptBalance( - this.signers, - this.instances, - "bob", - this.confidentialERC20, - this.confidentialERC20Address, - ), + await reencryptBalance(this.signers.bob, this.instance, this.confidentialERC20, this.confidentialERC20Address), ).to.equal(transferAmount); // check that transfer did happen this time // Verify Alice's allowance is 0 expect( await reencryptAllowance( - this.signers, - this.instances, - "alice", - "bob", + this.signers.alice, + this.signers.bob, + this.instance, this.confidentialERC20, this.confidentialERC20Address, ), @@ -315,9 +257,8 @@ describe("ConfidentialERC20WithErrors", function () { // Check that the error code matches if there is no error expect( await checkErrorCode( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, expectedTransferId2, this.confidentialERC20, this.confidentialERC20Address, @@ -328,10 +269,7 @@ describe("ConfidentialERC20WithErrors", function () { it("should not be able to read the allowance if not spender/owner after initialization", async function () { const amount = 10_000; - const inputAlice = this.instances.alice.createEncryptedInput( - this.confidentialERC20Address, - this.signers.alice.address, - ); + const inputAlice = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); inputAlice.add64(amount); const encryptedAllowanceAmount = await inputAlice.encrypt(); @@ -345,8 +283,8 @@ describe("ConfidentialERC20WithErrors", function () { const allowanceHandleAlice = await this.confidentialERC20.allowance(this.signers.alice, this.signers.bob); - const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = this.instances.carol.generateKeypair(); - const eip712Carol = this.instances.carol.createEIP712(publicKeyCarol, this.confidentialERC20Address); + const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = await this.instance.generateKeypair(); + const eip712Carol = this.instance.createEIP712(publicKeyCarol, this.confidentialERC20Address); const signatureCarol = await this.signers.carol.signTypedData( eip712Carol.domain, { Reencrypt: eip712Carol.types.Reencrypt }, @@ -354,7 +292,7 @@ describe("ConfidentialERC20WithErrors", function () { ); await expect( - this.instances.bob.reencrypt( + this.instance.reencrypt( allowanceHandleAlice, privateKeyCarol, publicKeyCarol, @@ -373,8 +311,8 @@ describe("ConfidentialERC20WithErrors", function () { const balanceHandleAlice = await this.confidentialERC20.balanceOf(this.signers.alice); - const { publicKey: publicKeyBob, privateKey: privateKeyBob } = this.instances.bob.generateKeypair(); - const eip712Bob = this.instances.bob.createEIP712(publicKeyBob, this.confidentialERC20Address); + const { publicKey: publicKeyBob, privateKey: privateKeyBob } = await this.instance.generateKeypair(); + const eip712Bob = this.instance.createEIP712(publicKeyBob, this.confidentialERC20Address); const signatureBob = await this.signers.bob.signTypedData( eip712Bob.domain, { Reencrypt: eip712Bob.types.Reencrypt }, @@ -382,7 +320,7 @@ describe("ConfidentialERC20WithErrors", function () { ); await expect( - this.instances.bob.reencrypt( + this.instance.reencrypt( balanceHandleAlice, privateKeyBob, publicKeyBob, @@ -400,7 +338,7 @@ describe("ConfidentialERC20WithErrors", function () { const tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -420,7 +358,7 @@ describe("ConfidentialERC20WithErrors", function () { const tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -439,7 +377,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -465,7 +403,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - let input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + let input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(mintAmount); const encryptedAllowanceAmount = await input.encrypt(); @@ -475,7 +413,7 @@ describe("ConfidentialERC20WithErrors", function () { "approve(address,bytes32,bytes)" ](this.signers.carol.address, encryptedAllowanceAmount.handles[0], encryptedAllowanceAmount.inputProof); - input = this.instances.carol.createEncryptedInput(this.confidentialERC20Address, this.signers.carol.address); + input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.carol.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -505,7 +443,7 @@ describe("ConfidentialERC20WithErrors", function () { let tx = await this.confidentialERC20.connect(this.signers.alice).mint(mintAmount); await tx.wait(); - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -521,8 +459,8 @@ describe("ConfidentialERC20WithErrors", function () { const errorCodeHandle = await this.confidentialERC20.getErrorCodeForTransferId(expectedTransferId); - const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = this.instances.carol.generateKeypair(); - const eip712Carol = this.instances.carol.createEIP712(publicKeyCarol, this.confidentialERC20Address); + const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = this.instance.generateKeypair(); + const eip712Carol = this.instance.createEIP712(publicKeyCarol, this.confidentialERC20Address); const signatureCarol = await this.signers.carol.signTypedData( eip712Carol.domain, { Reencrypt: eip712Carol.types.Reencrypt }, @@ -530,7 +468,7 @@ describe("ConfidentialERC20WithErrors", function () { ); await expect( - this.instances.bob.reencrypt( + this.instance.reencrypt( errorCodeHandle, privateKeyCarol, publicKeyCarol, @@ -543,7 +481,7 @@ describe("ConfidentialERC20WithErrors", function () { it("sender who is not allowed cannot approve using a handle from another account", async function () { const amount = 100_000; - const input = this.instances.alice.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.confidentialERC20Address, this.signers.alice.address); input.add64(amount); const encryptedAllowanceAmount = await input.encrypt(); diff --git a/test/constants.ts b/test/constants.ts new file mode 100644 index 0000000..7c9d80e --- /dev/null +++ b/test/constants.ts @@ -0,0 +1,10 @@ +export const TFHEEXECUTOR_ADDRESS = "0x687408ab54661ba0b4aef3a44156c616c6955e07"; +export const ACL_ADDRESS = "0xfee8407e2f5e3ee68ad77cae98c434e637f516e5"; +export const FHEPAYMENT_ADDRESS = "0xfb03be574d14c256d56f09a198b586bdfc0a9de2"; +export const KMSVERIFIER_ADDRESS = "0x9d6891a6240d6130c54ae243d8005063d05fe14b"; +export const INPUTVERIFIER_ADDRESS = "0x3a2DA6f1daE9eF988B48d9CF27523FA31a8eBE50"; +export const GATEWAYCONTRACT_ADDRESS = "0x33347831500f1e73f0cccbb95c9f86b94d7b1123"; +export const PRIVATE_KEY_KMS_SIGNER = "388b7680e4e1afa06efbfd45cdd1fe39f3c6af381df6555a19661f283b97de91"; +export const PRIVATE_KEY_COPROCESSOR_ACCOUNT = "7ec8ada6642fc4ccfb7729bc29c17cf8d21b61abd5642d1db992c0b8672ab901"; +export const GATEWAY_URL = "https://gateway.sepolia.zama.ai/"; +export const ACCOUNT_NAMES = ["alice", "bob", "carol", "dave", "eve", "fred", "greg", "hugo", "ian", "jane"]; diff --git a/test/coprocessorUtils.ts b/test/coprocessorUtils.ts index d082313..05a5d97 100644 --- a/test/coprocessorUtils.ts +++ b/test/coprocessorUtils.ts @@ -1,14 +1,12 @@ -import dotenv from "dotenv"; import { log2 } from "extra-bigint"; -import * as fs from "fs"; import { ethers } from "hardhat"; import hre from "hardhat"; import { Database } from "sqlite3"; -import operatorsPrices from "./operatorsPrices.json"; +import { TFHEEXECUTOR_ADDRESS } from "./constants"; +import operatorPrices from "./operatorPrices.json"; -const parsedEnvCoprocessor = dotenv.parse(fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.exec")); -const coprocAddress = parsedEnvCoprocessor.TFHE_EXECUTOR_CONTRACT_ADDRESS; +const executorAddress = TFHEEXECUTOR_ADDRESS; let firstBlockListening = 0; let lastBlockSnapshot = 0; @@ -18,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()]); @@ -29,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) => { @@ -104,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."); } @@ -167,11 +165,11 @@ async function processAllPastTFHEExecutorEvents() { } } - const contract = new ethers.Contract(coprocAddress, abi, provider); + const contract = new ethers.Contract(executorAddress, abi, provider); // Fetch all events emitted by the contract const filter = { - address: coprocAddress, + address: executorAddress, fromBlock: firstBlockListening, toBlock: latestBlockNumber, }; @@ -605,9 +603,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb if (receipt.status === 0) { throw new Error("Transaction reverted"); } - const contract = new ethers.Contract(coprocAddress, abi, ethers.provider); + const contract = new ethers.Contract(executorAddress, abi, ethers.provider); const relevantLogs = receipt.logs.filter((log: ethers.Log) => { - if (log.address.toLowerCase() !== coprocAddress.toLowerCase()) { + if (log.address.toLowerCase() !== executorAddress.toLowerCase()) { return false; } try { @@ -637,21 +635,21 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb switch (event.name) { case "TrivialEncrypt": type = parseInt(event.args[1], 16); - FHEGasConsumed += operatorsPrices["trivialEncrypt"].types[type]; + FHEGasConsumed += operatorPrices["trivialEncrypt"].types[type]; break; case "TrivialEncryptBytes": type = parseInt(event.args[1], 16); - FHEGasConsumed += operatorsPrices["trivialEncrypt"].types[type]; + FHEGasConsumed += operatorPrices["trivialEncrypt"].types[type]; break; case "FheAdd": handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheAdd"].scalar[type]; + FHEGasConsumed += operatorPrices["fheAdd"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheAdd"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheAdd"].nonScalar[type]; } break; @@ -659,9 +657,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheSub"].scalar[type]; + FHEGasConsumed += operatorPrices["fheSub"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheSub"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheSub"].nonScalar[type]; } break; @@ -669,9 +667,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheMul"].scalar[type]; + FHEGasConsumed += operatorPrices["fheMul"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheMul"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheMul"].nonScalar[type]; } break; @@ -679,7 +677,7 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheDiv"].scalar[type]; + FHEGasConsumed += operatorPrices["fheDiv"].scalar[type]; } else { throw new Error("Non-scalar div not implemented yet"); } @@ -689,7 +687,7 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheRem"].scalar[type]; + FHEGasConsumed += operatorPrices["fheRem"].scalar[type]; } else { throw new Error("Non-scalar rem not implemented yet"); } @@ -699,9 +697,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheBitAnd"].scalar[type]; + FHEGasConsumed += operatorPrices["fheBitAnd"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheBitAnd"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheBitAnd"].nonScalar[type]; } break; @@ -709,9 +707,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheBitOr"].scalar[type]; + FHEGasConsumed += operatorPrices["fheBitOr"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheBitOr"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheBitOr"].nonScalar[type]; } break; @@ -719,9 +717,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheBitXor"].scalar[type]; + FHEGasConsumed += operatorPrices["fheBitXor"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheBitXor"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheBitXor"].nonScalar[type]; } break; @@ -729,9 +727,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheBitShl"].scalar[type]; + FHEGasConsumed += operatorPrices["fheBitShl"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheBitShl"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheBitShl"].nonScalar[type]; } break; @@ -739,9 +737,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheBitShr"].scalar[type]; + FHEGasConsumed += operatorPrices["fheBitShr"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheBitShr"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheBitShr"].nonScalar[type]; } break; @@ -749,9 +747,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheRotl"].scalar[type]; + FHEGasConsumed += operatorPrices["fheRotl"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheRotl"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheRotl"].nonScalar[type]; } break; @@ -759,9 +757,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheRotr"].scalar[type]; + FHEGasConsumed += operatorPrices["fheRotr"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheRotr"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheRotr"].nonScalar[type]; } break; @@ -769,9 +767,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheEq"].scalar[type]; + FHEGasConsumed += operatorPrices["fheEq"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheEq"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheEq"].nonScalar[type]; } break; @@ -779,18 +777,18 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheEq"].scalar[type]; + FHEGasConsumed += operatorPrices["fheEq"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheEq"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheEq"].nonScalar[type]; } case "FheNe": handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheNe"].scalar[type]; + FHEGasConsumed += operatorPrices["fheNe"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheNe"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheNe"].nonScalar[type]; } break; @@ -798,9 +796,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheNe"].scalar[type]; + FHEGasConsumed += operatorPrices["fheNe"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheNe"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheNe"].nonScalar[type]; } break; @@ -808,9 +806,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheGe"].scalar[type]; + FHEGasConsumed += operatorPrices["fheGe"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheGe"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheGe"].nonScalar[type]; } break; @@ -818,9 +816,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheGt"].scalar[type]; + FHEGasConsumed += operatorPrices["fheGt"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheGt"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheGt"].nonScalar[type]; } break; @@ -828,9 +826,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheLe"].scalar[type]; + FHEGasConsumed += operatorPrices["fheLe"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheLe"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheLe"].nonScalar[type]; } break; @@ -838,9 +836,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheLt"].scalar[type]; + FHEGasConsumed += operatorPrices["fheLt"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheLt"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheLt"].nonScalar[type]; } break; @@ -848,9 +846,9 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheMax"].scalar[type]; + FHEGasConsumed += operatorPrices["fheMax"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheMax"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheMax"].nonScalar[type]; } break; @@ -858,44 +856,44 @@ export function getFHEGasFromTxReceipt(receipt: ethers.TransactionReceipt): numb handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); if (event.args[2] === "0x01") { - FHEGasConsumed += operatorsPrices["fheMin"].scalar[type]; + FHEGasConsumed += operatorPrices["fheMin"].scalar[type]; } else { - FHEGasConsumed += operatorsPrices["fheMin"].nonScalar[type]; + FHEGasConsumed += operatorPrices["fheMin"].nonScalar[type]; } break; case "Cast": handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); - FHEGasConsumed += operatorsPrices["cast"].types[type]; + FHEGasConsumed += operatorPrices["cast"].types[type]; break; case "FheNot": handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); - FHEGasConsumed += operatorsPrices["fheNot"].types[type]; + FHEGasConsumed += operatorPrices["fheNot"].types[type]; break; case "FheNeg": handle = ethers.toBeHex(event.args[0], 32); type = parseInt(handle.slice(-4, -2), 16); - FHEGasConsumed += operatorsPrices["fheNeg"].types[type]; + FHEGasConsumed += operatorPrices["fheNeg"].types[type]; break; case "FheIfThenElse": handle = ethers.toBeHex(event.args[3], 32); type = parseInt(handle.slice(-4, -2), 16); - FHEGasConsumed += operatorsPrices["ifThenElse"].types[type]; + FHEGasConsumed += operatorPrices["ifThenElse"].types[type]; break; case "FheRand": type = parseInt(event.args[0], 16); - FHEGasConsumed += operatorsPrices["fheRand"].types[type]; + FHEGasConsumed += operatorPrices["fheRand"].types[type]; break; case "FheRandBounded": type = parseInt(event.args[1], 16); - FHEGasConsumed += operatorsPrices["fheRandBounded"].types[type]; + FHEGasConsumed += operatorPrices["fheRandBounded"].types[type]; break; } } diff --git a/test/fhevmjsMocked.ts b/test/fhevmjsMocked.ts index 5e89903..5c3f014 100644 --- a/test/fhevmjsMocked.ts +++ b/test/fhevmjsMocked.ts @@ -1,19 +1,20 @@ -import { toBigIntBE } from "bigint-buffer"; -import { toBufferBE } from "bigint-buffer"; +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"; +import { + ACL_ADDRESS, + INPUTVERIFIER_ADDRESS, + KMSVERIFIER_ADDRESS, + PRIVATE_KEY_COPROCESSOR_ACCOUNT, + PRIVATE_KEY_KMS_SIGNER, +} from "./constants"; import { insertSQL } from "./coprocessorUtils"; import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; -const parsedEnvACL = dotenv.parse(fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.acl")); -const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS; - enum Types { ebool = 0, euint4, @@ -138,11 +139,10 @@ export const reencryptRequestMocked = async ( } // ACL checking - const aclFactory = await hre.ethers.getContractFactory("fhevmTemp/contracts/ACL.sol:ACL"); - const acl = aclFactory.attach(aclAdd); + const aclArtifact = require("fhevm-core-contracts/artifacts/contracts/ACL.sol/ACL.json"); + const acl = await hre.ethers.getContractAt(aclArtifact.abi, ACL_ADDRESS); const userAllowed = await acl.persistAllowed(handle, userAddress); const contractAllowed = await acl.persistAllowed(handle, contractAddress); - const isAllowed = userAllowed && contractAllowed; if (!isAllowed) { throw new Error("User is not authorized to reencrypt this handle!"); @@ -307,31 +307,27 @@ export const createEncryptedInputMocked = (contractAddress: string, userAddress: }); let inputProof = "0x" + numberToHex(handles.length); // for coprocessor : numHandles + numSignersKMS + hashCT + list_handles + signatureCopro + signatureKMSSigners (total len : 1+1+32+NUM_HANDLES*32+65+65*numSignersKMS) // for native : numHandles + numSignersKMS + list_handles + signatureKMSSigners + bundleCiphertext (total len : 1+1+NUM_HANDLES*32+65*numSignersKMS+bundleCiphertext.length) - const numSigners = +process.env.NUM_KMS_SIGNERS!; + const numSigners = 1; // @note: only 1 signer in mocked mode for the moment inputProof += numberToHex(numSigners); - if (process.env.IS_COPROCESSOR === "true") { - // coprocessor - inputProof += hash.toString("hex"); - - const listHandlesStr = handles.map((i) => uint8ArrayToHexString(i)); - listHandlesStr.map((handle) => (inputProof += handle)); - const listHandles = listHandlesStr.map((i) => BigInt("0x" + i)); - const sigCoproc = await computeInputSignatureCopro( - "0x" + hash.toString("hex"), - listHandles, - userAddress, - contractAddress, - ); - inputProof += sigCoproc.slice(2); - - const signaturesKMS = await computeInputSignaturesKMS( - "0x" + hash.toString("hex"), - userAddress, - contractAddress, - ); - signaturesKMS.map((sigKMS) => (inputProof += sigKMS.slice(2))); - listHandlesStr.map((handle, i) => insertSQL("0x" + handle, values[i])); - } else { + //if (process.env.IS_COPROCESSOR === "true") { // @note: for now we support only the coprocessor mode, not native + // coprocessor + inputProof += hash.toString("hex"); + + const listHandlesStr = handles.map((i) => uint8ArrayToHexString(i)); + listHandlesStr.map((handle) => (inputProof += handle)); + const listHandles = listHandlesStr.map((i) => BigInt("0x" + i)); + const sigCoproc = await computeInputSignatureCopro( + "0x" + hash.toString("hex"), + listHandles, + userAddress, + contractAddress, + ); + inputProof += sigCoproc.slice(2); + + const signaturesKMS = await computeInputSignaturesKMS("0x" + hash.toString("hex"), userAddress, contractAddress); + signaturesKMS.map((sigKMS) => (inputProof += sigKMS.slice(2))); + listHandlesStr.map((handle, i) => insertSQL("0x" + handle, values[i])); + /*} else { // native const listHandlesStr = handles.map((i) => uint8ArrayToHexString(i)); listHandlesStr.map((handle) => (inputProof += handle)); @@ -344,7 +340,7 @@ export const createEncryptedInputMocked = (contractAddress: string, userAddress: listHandlesStr.map((handle, i) => insertSQL("0x" + handle, values[i])); inputProof += encrypted.toString("hex"); - } + }*/ return { handles, @@ -400,14 +396,9 @@ async function computeInputSignatureCopro( userAddress: string, contractAddress: string, ): Promise { - let signature: string; - const privKeySigner = process.env["PRIVATE_KEY_COPROCESSOR_ACCOUNT"]; - if (privKeySigner) { - const coprocSigner = new Wallet(privKeySigner).connect(ethers.provider); - signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner); - } else { - throw new Error(`Private key for coprocessor not found in environment variables`); - } + const privKeySigner = PRIVATE_KEY_COPROCESSOR_ACCOUNT; + const coprocSigner = new Wallet(privKeySigner).connect(ethers.provider); + const signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner); return signature; } @@ -417,16 +408,12 @@ async function computeInputSignaturesKMS( contractAddress: string, ): Promise { const signatures: string[] = []; - const numSigners = +process.env.NUM_KMS_SIGNERS!; + const numSigners = 1; // @note: only 1 KMS signer in mocked mode for now for (let idx = 0; idx < numSigners; idx++) { - const privKeySigner = process.env[`PRIVATE_KEY_KMS_SIGNER_${idx}`]; - if (privKeySigner) { - const kmsSigner = new ethers.Wallet(privKeySigner).connect(ethers.provider); - const signature = await kmsSign(hash, userAddress, contractAddress, kmsSigner); - signatures.push(signature); - } else { - throw new Error(`Private key for signer ${idx} not found in environment variables`); - } + const privKeySigner = PRIVATE_KEY_KMS_SIGNER; + const kmsSigner = new ethers.Wallet(privKeySigner).connect(ethers.provider); + const signature = await kmsSign(hash, userAddress, contractAddress, kmsSigner); + signatures.push(signature); } return signatures; } @@ -438,13 +425,9 @@ async function coprocSign( contractAddress: string, signer: Wallet, ): Promise { - const inputAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.inputverifier"), - ).INPUT_VERIFIER_CONTRACT_ADDRESS; + const inputAdd = INPUTVERIFIER_ADDRESS; const chainId = hre.__SOLIDITY_COVERAGE_RUNNING ? 31337 : network.config.chainId; - const aclAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.acl"), - ).ACL_CONTRACT_ADDRESS; + const aclAdd = ACL_ADDRESS; const domain = { name: "InputVerifier", @@ -501,13 +484,9 @@ async function kmsSign( contractAddress: string, signer: Wallet, ): Promise { - const kmsVerifierAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.kmsverifier"), - ).KMS_VERIFIER_CONTRACT_ADDRESS; + const kmsVerifierAdd = KMSVERIFIER_ADDRESS; const chainId = hre.__SOLIDITY_COVERAGE_RUNNING ? 31337 : network.config.chainId; - const aclAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.acl"), - ).ACL_CONTRACT_ADDRESS; + const aclAdd = ACL_ADDRESS; const domain = { name: "KMSVerifier", diff --git a/test/governance/CompoundTimelock.test.ts b/test/governance/CompoundTimelock.test.ts index 86354ae..41c20ed 100644 --- a/test/governance/CompoundTimelock.test.ts +++ b/test/governance/CompoundTimelock.test.ts @@ -6,12 +6,12 @@ import { deployTimelockFixture } from "./ConfidentialGovernorAlpha.fixture"; describe("CompoundTimelock", function () { before(async function () { - await initSigners(3); + await initSigners(); this.signers = await getSigners(); }); beforeEach(async function () { - this.timelock = await deployTimelockFixture(this.signers.alice.address); + this.timelock = await deployTimelockFixture(this.signers.alice, this.signers.alice.address); }); it("non-timelock account could not call setPendingAdmin", async function () { diff --git a/test/governance/ConfidentialERC20Votes.fixture.ts b/test/governance/ConfidentialERC20Votes.fixture.ts index 70cdce6..8bb506a 100644 --- a/test/governance/ConfidentialERC20Votes.fixture.ts +++ b/test/governance/ConfidentialERC20Votes.fixture.ts @@ -1,67 +1,62 @@ -import { parseUnits } from "ethers"; +import { Signer, parseUnits } from "ethers"; +import { FhevmInstance } from "fhevmjs/node"; import { ethers } from "hardhat"; import type { TestConfidentialERC20Votes } from "../../types"; import { reencryptEuint64 } from "../reencrypt"; -import { Signers } from "../signers"; -import { FhevmInstances } from "../types"; -export async function deployConfidentialERC20Votes(signers: Signers): Promise { +export async function deployConfidentialERC20Votes(signer: Signer): Promise { const contractFactory = await ethers.getContractFactory("TestConfidentialERC20Votes"); const contract = await contractFactory - .connect(signers.alice) - .deploy(signers.alice.address, "CompoundZama", "CONFIDENTIAL_ERC20_VOTES", "1.0", parseUnits("10000000", 6)); + .connect(signer) + .deploy(await signer.getAddress(), "CompoundZama", "CONFIDENTIAL_ERC20_VOTES", "1.0", parseUnits("10000000", 6)); await contract.waitForDeployment(); return contract; } export async function transferTokensAndDelegate( - signers: Signers, - instances: FhevmInstances, + owner: Signer, + delegator: Signer, + delegateeAddress: string, + instance: FhevmInstance, transferAmount: bigint, - account: string, - delegate: string, confidentialERC20Votes: TestConfidentialERC20Votes, confidentialERC20VotesAddress: string, ): Promise { - const input = instances.alice.createEncryptedInput(confidentialERC20VotesAddress, signers.alice.address); + const input = instance.createEncryptedInput(confidentialERC20VotesAddress, await owner.getAddress()); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); let tx = await confidentialERC20Votes - .connect(signers.alice) + .connect(owner) [ "transfer(address,bytes32,bytes)" - ](signers[account as keyof Signers], encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof); + ](await delegator.getAddress(), encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof); await tx.wait(); - tx = await confidentialERC20Votes - .connect(signers[account as keyof Signers]) - .delegate(signers[delegate as keyof Signers].address); + tx = await confidentialERC20Votes.connect(delegator).delegate(delegateeAddress); await tx.wait(); } export async function reencryptCurrentVotes( - signers: Signers, - instances: FhevmInstances, - account: string, + account: Signer, + instance: FhevmInstance, confidentialERC20Votes: TestConfidentialERC20Votes, confidentialERC20VotesAddress: string, ): Promise { - const voteHandle = await confidentialERC20Votes.getCurrentVotes(signers[account as keyof Signers].address); - const vote = await reencryptEuint64(signers, instances, account, voteHandle, confidentialERC20VotesAddress); + const voteHandle = await confidentialERC20Votes.getCurrentVotes(await account.getAddress()); + const vote = await reencryptEuint64(account, instance, voteHandle, confidentialERC20VotesAddress); return vote; } export async function reencryptPriorVotes( - signers: Signers, - instances: FhevmInstances, - account: string, + account: Signer, + instance: FhevmInstance, blockNumber: number, confidentialERC20Votes: TestConfidentialERC20Votes, confidentialERC20VotesAddress: string, ): Promise { - const voteHandle = await confidentialERC20Votes.getPriorVotes(signers[account as keyof Signers].address, blockNumber); - const vote = await reencryptEuint64(signers, instances, account, voteHandle, confidentialERC20VotesAddress); + const voteHandle = await confidentialERC20Votes.getPriorVotes(await account.getAddress(), blockNumber); + const vote = await reencryptEuint64(account, instance, voteHandle, confidentialERC20VotesAddress); return vote; } diff --git a/test/governance/ConfidentialERC20Votes.test.ts b/test/governance/ConfidentialERC20Votes.test.ts index d3484d0..a53f967 100644 --- a/test/governance/ConfidentialERC20Votes.test.ts +++ b/test/governance/ConfidentialERC20Votes.test.ts @@ -3,7 +3,7 @@ import { parseUnits } from "ethers"; import { ethers, network } from "hardhat"; import { reencryptBalance } from "../confidentialERC20/ConfidentialERC20.fixture"; -import { createInstances } from "../instance"; +import { createInstance } from "../instance"; import { reencryptEuint64 } from "../reencrypt"; import { getSigners, initSigners } from "../signers"; import { waitNBlocks } from "../utils"; @@ -20,24 +20,22 @@ describe("ConfidentialERC20Votes", function () { const NULL_ADDRESS = "0x0000000000000000000000000000000000000000"; before(async function () { - await initSigners(3); + await initSigners(); this.signers = await getSigners(); + this.instance = await createInstance(); }); beforeEach(async function () { - const contract = await deployConfidentialERC20Votes(this.signers); + const contract = await deployConfidentialERC20Votes(this.signers.alice); this.confidentialERC20VotesAddress = await contract.getAddress(); this.confidentialERC20Votes = contract; - this.instances = await createInstances(this.signers); }); it("should transfer tokens", async function () { const transferAmount = parseUnits(String(2_000_000), 6); - const input = this.instances.alice.createEncryptedInput( - this.confidentialERC20VotesAddress, - this.signers.alice.address, - ); + const input = this.instance.createEncryptedInput(this.confidentialERC20VotesAddress, this.signers.alice.address); + input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -54,9 +52,8 @@ describe("ConfidentialERC20Votes", function () { // Decrypt Alice's balance expect( await reencryptBalance( - this.signers, - this.instances, - "alice", + this.signers.alice, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -65,9 +62,8 @@ describe("ConfidentialERC20Votes", function () { // Decrypt Bob's balance expect( await reencryptBalance( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -85,9 +81,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -97,18 +92,16 @@ describe("ConfidentialERC20Votes", function () { // Verify the two functions return the same. expect( await reencryptPriorVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), ).to.equal( await reencryptCurrentVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -137,9 +130,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -149,18 +141,16 @@ describe("ConfidentialERC20Votes", function () { // Verify the two functions return the same. expect( await reencryptPriorVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), ).to.equal( await reencryptCurrentVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -176,9 +166,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "alice", + this.signers.alice, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -186,10 +175,7 @@ describe("ConfidentialERC20Votes", function () { ).to.equal(parseUnits(String(10_000_000), 6)); const transferAmount = parseUnits(String(10_000_000), 6); - const input = this.instances.alice.createEncryptedInput( - this.confidentialERC20VotesAddress, - this.signers.alice.address, - ); + const input = this.instance.createEncryptedInput(this.confidentialERC20VotesAddress, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -206,9 +192,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "alice", + this.signers.alice, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -311,10 +296,7 @@ describe("ConfidentialERC20Votes", function () { // Alice transfers 1M tokens to Bob, 1M tokens to Carol, 1M tokens to Dave const transferAmount = parseUnits(String(1_000_000), 6); - const input = this.instances.alice.createEncryptedInput( - this.confidentialERC20VotesAddress, - this.signers.alice.address, - ); + const input = this.instance.createEncryptedInput(this.confidentialERC20VotesAddress, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -356,9 +338,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "dave", + this.signers.dave, + this.instance, firstCheckPointBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -367,9 +348,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "dave", + this.signers.dave, + this.instance, secondCheckPointBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -398,7 +378,7 @@ describe("ConfidentialERC20Votes", function () { expect(currentVoteHandle).to.be.eq(0n); await expect( - reencryptEuint64(this.signers, this.instances, "bob", currentVoteHandle, this.confidentialERC20Votes), + reencryptEuint64(this.signers.bob, this.instance, currentVoteHandle, this.confidentialERC20Votes), ).to.be.rejectedWith("Handle is not initialized"); // 2. If no checkpoint exists using getPriorVotes @@ -413,7 +393,7 @@ describe("ConfidentialERC20Votes", function () { expect(currentVoteHandle).not.to.be.eq(0n); await expect( - reencryptEuint64(this.signers, this.instances, "bob", currentVoteHandle, this.confidentialERC20Votes), + reencryptEuint64(this.signers.bob, this.instance, currentVoteHandle, this.confidentialERC20Votes), ).to.be.rejectedWith("Invalid contract address."); // 3. If a checkpoint exists using getPriorVotes but block.number < block of first checkpoint @@ -431,7 +411,7 @@ describe("ConfidentialERC20Votes", function () { expect(currentVoteHandle).not.to.be.eq(0n); await expect( - reencryptEuint64(this.signers, this.instances, "bob", currentVoteHandle, this.confidentialERC20Votes), + reencryptEuint64(this.signers.bob, this.instance, currentVoteHandle, this.confidentialERC20Votes), ).to.be.rejectedWith("Invalid contract address."); }); @@ -467,9 +447,8 @@ describe("ConfidentialERC20Votes", function () { if (blockNumbers[i] % 2 === 0) { expect( await reencryptPriorVotes( - this.signers, - this.instances, - startWithAlice ? "alice" : "carol", + startWithAlice ? this.signers.alice : this.signers.carol, + this.instance, blockNumbers[i], this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -478,9 +457,8 @@ describe("ConfidentialERC20Votes", function () { } else { expect( await reencryptPriorVotes( - this.signers, - this.instances, - startWithAlice ? "carol" : "alice", + startWithAlice ? this.signers.carol : this.signers.alice, + this.instance, blockNumbers[i], this.confidentialERC20Votes, this.confidentialERC20VotesAddress, @@ -515,10 +493,7 @@ describe("ConfidentialERC20Votes", function () { it("different voters can delegate to same delegatee", async function () { const transferAmount = parseUnits(String(2_000_000), 6); - const input = this.instances.alice.createEncryptedInput( - this.confidentialERC20VotesAddress, - this.signers.alice.address, - ); + const input = this.instance.createEncryptedInput(this.confidentialERC20VotesAddress, this.signers.alice.address); input.add64(transferAmount); const encryptedTransferAmount = await input.encrypt(); @@ -541,9 +516,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptCurrentVotes( - this.signers, - this.instances, - "carol", + this.signers.carol, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -551,18 +525,16 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptPriorVotes( - this.signers, - this.instances, - "carol", + this.signers.carol, + this.instance, latestBlockNumber, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), ).to.equal( await reencryptCurrentVotes( - this.signers, - this.instances, - "carol", + this.signers.carol, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -588,9 +560,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptCurrentVotes( - this.signers, - this.instances, - "bob", + this.signers.bob, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), @@ -598,9 +569,8 @@ describe("ConfidentialERC20Votes", function () { expect( await reencryptCurrentVotes( - this.signers, - this.instances, - "carol", + this.signers.carol, + this.instance, this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ), diff --git a/test/governance/ConfidentialGovernorAlpha.fixture.ts b/test/governance/ConfidentialGovernorAlpha.fixture.ts index 3feb643..ad3771f 100644 --- a/test/governance/ConfidentialGovernorAlpha.fixture.ts +++ b/test/governance/ConfidentialGovernorAlpha.fixture.ts @@ -1,20 +1,19 @@ +import { Signer } from "ethers"; +import { FhevmInstance } from "fhevmjs/node"; import { ethers } from "hardhat"; import type { CompoundTimelock, TestConfidentialGovernorAlpha } from "../../types"; import { reencryptEbool, reencryptEuint64 } from "../reencrypt"; -import { Signers, getSigners } from "../signers"; -import { FhevmInstances } from "../types"; -export async function deployTimelockFixture(admin: string): Promise { - const signers = await getSigners(); +export async function deployTimelockFixture(signer: Signer, adminAddress: string): Promise { const timelockFactory = await ethers.getContractFactory("CompoundTimelock"); - const timelock = await timelockFactory.connect(signers.alice).deploy(admin, 60 * 60 * 24 * 2); + const timelock = await timelockFactory.connect(signer).deploy(adminAddress, 60 * 60 * 24 * 2); await timelock.waitForDeployment(); return timelock; } export async function deployConfidentialGovernorAlphaFixture( - signers: Signers, + signer: Signer, confidentialERC20VotesAddress: string, timelockAddress: string, ): Promise { @@ -25,26 +24,22 @@ export async function deployConfidentialGovernorAlphaFixture( const maxDecryptionDelay = 60 * 5; const governorFactory = await ethers.getContractFactory("TestConfidentialGovernorAlpha"); const governor = await governorFactory - .connect(signers.alice) - .deploy(signers.alice.address, timelockAddress, confidentialERC20VotesAddress, votingPeriod, maxDecryptionDelay); + .connect(signer) + .deploy(signer, timelockAddress, confidentialERC20VotesAddress, votingPeriod, maxDecryptionDelay); await governor.waitForDeployment(); return governor; } export async function reencryptVoteReceipt( - signers: Signers, - instances: FhevmInstances, + account: Signer, + instance: FhevmInstance, proposalId: bigint, - account: string, governor: TestConfidentialGovernorAlpha, governorAddress: string, ): Promise<[boolean, boolean, bigint]> { - const [hasVoted, supportHandle, voteHandle] = await governor.getReceipt( - proposalId, - signers[account as keyof Signers].address, - ); - const support = await reencryptEbool(signers, instances, account, supportHandle, governorAddress); - const vote = await reencryptEuint64(signers, instances, account, voteHandle, governorAddress); + const [hasVoted, supportHandle, voteHandle] = await governor.getReceipt(proposalId, await account.getAddress()); + const support = await reencryptEbool(account, instance, supportHandle, governorAddress); + const vote = await reencryptEuint64(account, instance, voteHandle, governorAddress); return [hasVoted, support, vote]; } diff --git a/test/governance/ConfidentialGovernorAlpha.test.ts b/test/governance/ConfidentialGovernorAlpha.test.ts index 324e927..14d1137 100644 --- a/test/governance/ConfidentialGovernorAlpha.test.ts +++ b/test/governance/ConfidentialGovernorAlpha.test.ts @@ -3,7 +3,7 @@ import { parseUnits } from "ethers"; import { ethers, network } from "hardhat"; import { awaitAllDecryptionResults } from "../asyncDecrypt"; -import { createInstances } from "../instance"; +import { createInstance } from "../instance"; import { getSigners, initSigners } from "../signers"; import { mineNBlocks } from "../utils"; import { deployConfidentialERC20Votes, transferTokensAndDelegate } from "./ConfidentialERC20Votes.fixture"; @@ -15,30 +15,31 @@ import { describe("ConfidentialGovernorAlpha", function () { before(async function () { - await initSigners(4); + await initSigners(); this.signers = await getSigners(); + this.instance = await createInstance(); }); beforeEach(async function () { - const contract = await deployConfidentialERC20Votes(this.signers); + const contract = await deployConfidentialERC20Votes(this.signers.alice); this.confidentialERC20Votes = contract; this.confidentialERC20VotesAddress = await contract.getAddress(); - this.instances = await createInstances(this.signers); const precomputedGovernorAddress = ethers.getCreateAddress({ from: this.signers.alice.address, nonce: (await this.signers.alice.getNonce()) + 1, }); - const timelock = await deployTimelockFixture(precomputedGovernorAddress); + const timelock = await deployTimelockFixture(this.signers.alice, precomputedGovernorAddress); this.timelock = timelock; this.timelockAddress = await timelock.getAddress(); const governor = await deployConfidentialGovernorAlphaFixture( - this.signers, + this.signers.alice, this.confidentialERC20VotesAddress, this.timelockAddress, ); + this.governor = governor; this.governorAddress = await governor.getAddress(); @@ -59,11 +60,11 @@ describe("ConfidentialGovernorAlpha", function () { const description = "description"; await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -115,15 +116,14 @@ describe("ConfidentialGovernorAlpha", function () { const description = "description"; await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); - const tx = await this.governor .connect(this.signers.bob) .propose(targets, values, signatures, calldatas, description); @@ -155,21 +155,21 @@ describe("ConfidentialGovernorAlpha", function () { // Bob and Carol receive 200k tokens and delegate to themselves. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.carol, + await this.signers.carol.getAddress(), + this.instance, transferAmount, - "carol", - "carol", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -184,7 +184,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob and Carol vote for - let input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + let input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); let encryptedVote = await input.encrypt(); tx = await this.governor @@ -196,7 +196,7 @@ describe("ConfidentialGovernorAlpha", function () { 1n, // @dev proposalId ); - input = this.instances.carol.createEncryptedInput(this.governorAddress, this.signers.carol.address); + input = this.instance.createEncryptedInput(this.governorAddress, this.signers.carol.address); input.addBool(true); encryptedVote = await input.encrypt(); tx = await this.governor @@ -210,10 +210,9 @@ describe("ConfidentialGovernorAlpha", function () { // Bob/Carol can reeencrypt his/her receipt let [hasVoted, support, votes] = await reencryptVoteReceipt( - this.signers, - this.instances, + this.signers.bob, + this.instance, proposalId, - "bob", this.governor, this.governorAddress, ); @@ -223,10 +222,9 @@ describe("ConfidentialGovernorAlpha", function () { expect(votes).to.be.eq(transferAmount); [hasVoted, support, votes] = await reencryptVoteReceipt( - this.signers, - this.instances, + this.signers.carol, + this.instance, proposalId, - "carol", this.governor, this.governorAddress, ); @@ -304,11 +302,11 @@ describe("ConfidentialGovernorAlpha", function () { // Bob receives enough to create a proposal but not enough to match the quorum. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -322,7 +320,7 @@ describe("ConfidentialGovernorAlpha", function () { const proposalId = await this.governor.latestProposalIds(this.signers.bob.address); // VOTE - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor @@ -332,10 +330,9 @@ describe("ConfidentialGovernorAlpha", function () { // Bob reeencrypts his receipt const [hasVoted, support, votes] = await reencryptVoteReceipt( - this.signers, - this.instances, + this.signers.bob, + this.instance, proposalId, - "bob", this.governor, this.governorAddress, ); @@ -378,25 +375,24 @@ describe("ConfidentialGovernorAlpha", function () { // Bob and Carol receive 200k tokens and delegate to themselves. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmountFor, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.carol, + await this.signers.carol.getAddress(), + this.instance, transferAmountAgainst, - "carol", - "carol", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); - // INITIATE A PROPOSAL let tx = await this.governor.connect(this.signers.bob).propose(targets, values, signatures, calldatas, description); await tx.wait(); @@ -407,7 +403,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob votes for but Carol votes against - let input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + let input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); let encryptedVote = await input.encrypt(); tx = await this.governor @@ -415,7 +411,7 @@ describe("ConfidentialGovernorAlpha", function () { ["castVote(uint256,bytes32,bytes)"](proposalId, encryptedVote.handles[0], encryptedVote.inputProof); await tx.wait(); - input = this.instances.carol.createEncryptedInput(this.governorAddress, this.signers.carol.address); + input = this.instance.createEncryptedInput(this.governorAddress, this.signers.carol.address); input.addBool(false); encryptedVote = await input.encrypt(); tx = await this.governor @@ -425,10 +421,9 @@ describe("ConfidentialGovernorAlpha", function () { // Bob/Carol can reeencrypt his/her receipt let [hasVoted, support, votes] = await reencryptVoteReceipt( - this.signers, - this.instances, + this.signers.bob, + this.instance, proposalId, - "bob", this.governor, this.governorAddress, ); @@ -438,10 +433,9 @@ describe("ConfidentialGovernorAlpha", function () { expect(votes).to.be.eq(transferAmountFor); [hasVoted, support, votes] = await reencryptVoteReceipt( - this.signers, - this.instances, + this.signers.carol, + this.instance, proposalId, - "carol", this.governor, this.governorAddress, ); @@ -620,15 +614,14 @@ describe("ConfidentialGovernorAlpha", function () { const transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); - const tx = await this.governor .connect(this.signers.bob) .propose(targets, values, signatures, calldatas, description); @@ -650,11 +643,11 @@ describe("ConfidentialGovernorAlpha", function () { const transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -679,11 +672,11 @@ describe("ConfidentialGovernorAlpha", function () { // Bob receives 400k tokens and delegates to himself. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -698,7 +691,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob casts a vote - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor @@ -740,15 +733,14 @@ describe("ConfidentialGovernorAlpha", function () { // CANNOT CANCEL IF REJECTED await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); - let tx = await this.governor.connect(this.signers.bob).propose(targets, values, signatures, calldatas, description); await tx.wait(); await awaitAllDecryptionResults(); @@ -764,11 +756,11 @@ describe("ConfidentialGovernorAlpha", function () { transferAmount = (await this.governor.QUORUM_VOTES()) - 1n; await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.carol, + await this.signers.carol.getAddress(), + this.instance, transferAmount, - "carol", - "carol", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -779,7 +771,7 @@ describe("ConfidentialGovernorAlpha", function () { proposalId = await this.governor.latestProposalIds(this.signers.carol.address); - let input = this.instances.carol.createEncryptedInput(this.governorAddress, this.signers.carol.address); + let input = this.instance.createEncryptedInput(this.governorAddress, this.signers.carol.address); input.addBool(true); let encryptedVote = await input.encrypt(); tx = await this.governor @@ -803,11 +795,11 @@ describe("ConfidentialGovernorAlpha", function () { transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.dave, + this.signers.dave.address, + this.instance, transferAmount, - "dave", - "dave", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -818,7 +810,7 @@ describe("ConfidentialGovernorAlpha", function () { proposalId = await this.governor.latestProposalIds(this.signers.dave.address); - input = this.instances.dave.createEncryptedInput(this.governorAddress, this.signers.dave.address); + input = this.instance.createEncryptedInput(this.governorAddress, this.signers.dave.address); input.addBool(true); encryptedVote = await input.encrypt(); tx = await this.governor @@ -872,11 +864,11 @@ describe("ConfidentialGovernorAlpha", function () { const transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -891,7 +883,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob votes for - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor @@ -937,11 +929,11 @@ describe("ConfidentialGovernorAlpha", function () { const transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -956,7 +948,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob votes for - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor @@ -981,11 +973,11 @@ describe("ConfidentialGovernorAlpha", function () { const transferAmount = await this.governor.QUORUM_VOTES(); await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -993,7 +985,7 @@ describe("ConfidentialGovernorAlpha", function () { let tx = await this.governor.connect(this.signers.bob).propose(targets, values, signatures, calldatas, description); const proposalId = await this.governor.latestProposalIds(this.signers.bob.address); - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); @@ -1034,11 +1026,11 @@ describe("ConfidentialGovernorAlpha", function () { // Bob receives 400k tokens and delegates to himself. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -1053,7 +1045,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob casts a vote - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor @@ -1078,11 +1070,11 @@ describe("ConfidentialGovernorAlpha", function () { // Bob receives 400k tokens and delegates to himself. await transferTokensAndDelegate( - this.signers, - this.instances, + this.signers.alice, + this.signers.bob, + await this.signers.bob.getAddress(), + this.instance, transferAmount, - "bob", - "bob", this.confidentialERC20Votes, this.confidentialERC20VotesAddress, ); @@ -1097,7 +1089,7 @@ describe("ConfidentialGovernorAlpha", function () { // VOTE // Bob casts a vote - const input = this.instances.bob.createEncryptedInput(this.governorAddress, this.signers.bob.address); + const input = this.instance.createEncryptedInput(this.governorAddress, this.signers.bob.address); input.addBool(true); const encryptedVote = await input.encrypt(); tx = await this.governor diff --git a/test/governance/DelegateBySig.ts b/test/governance/DelegateBySig.ts index d7c9f29..979876f 100644 --- a/test/governance/DelegateBySig.ts +++ b/test/governance/DelegateBySig.ts @@ -1,6 +1,5 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; import { ethers } from "hardhat"; -import { Address } from "hardhat-deploy/types"; import type { ConfidentialERC20Votes } from "../../types"; @@ -15,7 +14,7 @@ import type { ConfidentialERC20Votes } from "../../types"; */ export const delegateBySig = async ( _signer: HardhatEthersSigner, - _delegatee: Address, + _delegatee: string, _confidentialERC20Votes: ConfidentialERC20Votes, _nonce: number, _expiry: number, diff --git a/test/handleTypeCheck.ts b/test/handleTypeCheck.ts deleted file mode 100644 index dfe7ddc..0000000 --- a/test/handleTypeCheck.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const EBOOL_T = 0; -export const EUINT4_T = 1; -export const EUINT8_T = 2; -export const EUINT16_T = 3; -export const EUINT32_T = 4; -export const EUINT64_T = 5; -export const EUINT128_T = 6; -export const EUINT160_T = 7; // @dev It is the one for eaddresses. -export const EUINT256_T = 8; -export const EBYTES64_T = 9; -export const EBYTES128_T = 10; -export const EBYTES256_T = 11; - -export function verifyType(handle: bigint, expectedType: number) { - if (handle === 0n) { - throw "Handle is not initialized"; - } - - if (handle.toString(2).length > 256) { - throw "Handle is not a bytes32"; - } - - const typeCt = handle >> 8n; - - if (Number(typeCt % 256n) !== expectedType) { - throw "Wrong encrypted type for the handle"; - } -} diff --git a/test/instance.ts b/test/instance.ts index 0f687a0..e310c2b 100644 --- a/test/instance.ts +++ b/test/instance.ts @@ -1,350 +1,30 @@ -import dotenv from "dotenv"; -import { - clientKeyDecryptor, - createEIP712, - createInstance as createFhevmInstance, - generateKeypair, - getCiphertextCallParams, -} from "fhevmjs"; -import { readFileSync } from "fs"; -import * as fs from "fs"; -import { ethers, ethers as hethers, network } from "hardhat"; -import { homedir } from "os"; -import path from "path"; +import { createEIP712, createInstance as createFhevmInstance, generateKeypair } from "fhevmjs"; +import { FhevmInstance } from "fhevmjs/node"; +import { network } from "hardhat"; -import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; +import { ACL_ADDRESS, GATEWAY_URL, KMSVERIFIER_ADDRESS } from "./constants"; import { createEncryptedInputMocked, reencryptRequestMocked } from "./fhevmjsMocked"; -import { - EBOOL_T, - EBYTES64_T, - EBYTES128_T, - EBYTES256_T, - EUINT4_T, - EUINT8_T, - EUINT16_T, - EUINT32_T, - EUINT64_T, - EUINT128_T, - EUINT160_T, - EUINT256_T, - verifyType, -} from "./handleTypeCheck"; -import type { Signers } from "./signers"; -import { FhevmInstances } from "./types"; -const FHE_CLIENT_KEY_PATH = process.env.FHE_CLIENT_KEY_PATH; - -let clientKey: Uint8Array | undefined; - -const kmsAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.kmsverifier"), -).KMS_VERIFIER_CONTRACT_ADDRESS; - -const aclAdd = dotenv.parse( - fs.readFileSync("node_modules/fhevm-core-contracts/addresses/.env.acl"), -).ACL_CONTRACT_ADDRESS; - -const createInstanceMocked = async () => { - const instance = { - reencrypt: reencryptRequestMocked, - createEncryptedInput: createEncryptedInputMocked, - getPublicKey: () => "0xFFAA44433", - generateKeypair: generateKeypair, - createEIP712: createEIP712(network.config.chainId), - }; - - return instance; -}; - -export const createInstances = async (accounts: Signers): Promise => { - // Create instance - const instances: FhevmInstances = {} as FhevmInstances; - if (network.name === "hardhat") { - await Promise.all( - Object.keys(accounts).map(async (k) => { - instances[k as keyof FhevmInstances] = await createInstanceMocked(); - }), - ); - } else { - await Promise.all( - Object.keys(accounts).map(async (k) => { - instances[k as keyof FhevmInstances] = await createInstance(); - }), - ); - } - return instances; -}; - -export const createInstance = async () => { - const instance = await createFhevmInstance({ - networkUrl: network.config.url, - kmsContractAddress: kmsAdd, - aclContractAddress: aclAdd, - gatewayUrl: "http://localhost:7077", - }); - return instance; -}; - -const getCiphertext = async (handle: bigint, ethers: typeof hethers): Promise => { - return ethers.provider.call(getCiphertextCallParams(handle)); -}; - -const getDecryptor = () => { - if (clientKey == null) { - if (FHE_CLIENT_KEY_PATH) { - clientKey = readFileSync(FHE_CLIENT_KEY_PATH); - } else { - const home = homedir(); - const clientKeyPath = path.join(home, "network-fhe-keys/cks"); - clientKey = readFileSync(clientKeyPath); - } - } - return clientKeyDecryptor(clientKey); -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} a handle to decrypt - * @returns {bool} - */ -export const decryptBool = async (handle: bigint): Promise => { - verifyType(handle, EBOOL_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return (await getClearText(handle)) === "1"; - } else { - return getDecryptor().decryptBool(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decrypt4 = async (handle: bigint): Promise => { - verifyType(handle, EUINT4_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt4(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} a handle to decrypt - * @returns {bigint} - */ -export const decrypt8 = async (handle: bigint): Promise => { - verifyType(handle, EUINT8_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt8(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decrypt16 = async (handle: bigint): Promise => { - verifyType(handle, EUINT16_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt16(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decrypt32 = async (handle: bigint): Promise => { - verifyType(handle, EUINT32_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt32(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decrypt64 = async (handle: bigint): Promise => { - verifyType(handle, EUINT64_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt64(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ - -export const decrypt128 = async (handle: bigint): Promise => { - verifyType(handle, EUINT128_T); - if (network.name === "hardhat") { - await awaitCoprocessor(); - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt128(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ - -export const decrypt256 = async (handle: bigint): Promise => { - verifyType(handle, EUINT256_T); - if (network.name === "hardhat") { - await awaitCoprocessor(); - - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decrypt256(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {string} - */ -export const decryptAddress = async (handle: bigint): Promise => { - verifyType(handle, EUINT160_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - const bigintAdd = BigInt(await getClearText(handle)); - const handleStr = "0x" + bigintAdd.toString(16).padStart(40, "0"); - return handleStr; - } else { - return getDecryptor().decryptAddress(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} a handle to decrypt - * @returns {bigint} - */ - -export const decryptEbytes64 = async (handle: bigint): Promise => { - verifyType(handle, EBYTES64_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decryptEbytes64(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decryptEbytes128 = async (handle: bigint): Promise => { - verifyType(handle, EBYTES128_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decryptEbytes128(await getCiphertext(handle, ethers)); - } -}; - -/** - * @debug - * This function is intended for debugging purposes only. - * It cannot be used in production code, since it requires the FHE private key for decryption. - * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. - * - * @param {bigint} handle to decrypt - * @returns {bigint} - */ -export const decryptEbytes256 = async (handle: bigint): Promise => { - verifyType(handle, EBYTES256_T); - - if (network.name === "hardhat") { - await awaitCoprocessor(); - - return BigInt(await getClearText(handle)); - } else { - return getDecryptor().decryptEbytes256(await getCiphertext(handle, ethers)); +const kmsAdd = KMSVERIFIER_ADDRESS; +const aclAdd = ACL_ADDRESS; + +export const createInstance = async (): Promise => { + if (network.name === "hardhat") { + const instance = { + reencrypt: reencryptRequestMocked, + createEncryptedInput: createEncryptedInputMocked, + getPublicKey: () => "0xFFAA44433", + generateKeypair: generateKeypair, + createEIP712: createEIP712(network.config.chainId), + }; + return instance; + } else { + const instance = await createFhevmInstance({ + kmsContractAddress: kmsAdd, + aclContractAddress: aclAdd, + networkUrl: network.config.url, + gatewayUrl: GATEWAY_URL, + }); + return instance; } }; diff --git a/test/mockedSetup.ts b/test/mockedSetup.ts new file mode 100644 index 0000000..58e89f3 --- /dev/null +++ b/test/mockedSetup.ts @@ -0,0 +1,56 @@ +import { ZeroAddress } from "ethers"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { + ACL_ADDRESS, + FHEPAYMENT_ADDRESS, + GATEWAYCONTRACT_ADDRESS, + INPUTVERIFIER_ADDRESS, + KMSVERIFIER_ADDRESS, + PRIVATE_KEY_KMS_SIGNER, + TFHEEXECUTOR_ADDRESS, +} from "./constants"; + +const OneAddress = "0x0000000000000000000000000000000000000001"; + +export async function setCodeMocked(hre: HardhatRuntimeEnvironment) { + const aclArtifact = require("fhevm-core-contracts/artifacts/contracts/ACL.sol/ACL.json"); + const aclBytecode = aclArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [ACL_ADDRESS, aclBytecode]); + const execArtifact = require("fhevm-core-contracts/artifacts/contracts/TFHEExecutorWithEvents.sol/TFHEExecutorWithEvents.json"); + const execBytecode = execArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [TFHEEXECUTOR_ADDRESS, execBytecode]); + const kmsArtifact = require("fhevm-core-contracts/artifacts/contracts/KMSVerifier.sol/KMSVerifier.json"); + const kmsBytecode = kmsArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [KMSVERIFIER_ADDRESS, kmsBytecode]); + const inputArtifact = require("fhevm-core-contracts/artifacts/contracts/InputVerifier.coprocessor.sol/InputVerifier.json"); + const inputBytecode = inputArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [INPUTVERIFIER_ADDRESS, inputBytecode]); + const fhepaymentArtifact = require("fhevm-core-contracts/artifacts/contracts/FHEPayment.sol/FHEPayment.json"); + const fhepaymentBytecode = fhepaymentArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [FHEPAYMENT_ADDRESS, fhepaymentBytecode]); + const gatewayArtifact = require("fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json"); + const gatewayBytecode = gatewayArtifact.deployedBytecode; + await hre.network.provider.send("hardhat_setCode", [GATEWAYCONTRACT_ADDRESS, gatewayBytecode]); + const zero = await impersonateAddress(hre, ZeroAddress, hre.ethers.parseEther("100")); + const one = await impersonateAddress(hre, OneAddress, hre.ethers.parseEther("100")); + const kmsSigner = new hre.ethers.Wallet(PRIVATE_KEY_KMS_SIGNER); + const kms = await hre.ethers.getContractAt(kmsArtifact.abi, KMSVERIFIER_ADDRESS); + await kms.connect(zero).initialize(OneAddress); + await kms.connect(one).addSigner(kmsSigner); + const input = await hre.ethers.getContractAt(inputArtifact.abi, INPUTVERIFIER_ADDRESS); + await input.connect(zero).initialize(OneAddress); + const gateway = await hre.ethers.getContractAt(gatewayArtifact.abi, GATEWAYCONTRACT_ADDRESS); + await gateway.connect(zero).addRelayer(ZeroAddress); +} + +export async function impersonateAddress(hre: HardhatRuntimeEnvironment, address: string, amount: bigint) { + // for mocked mode + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [address], + }); + await hre.network.provider.send("hardhat_setBalance", [address, hre.ethers.toBeHex(amount)]); + const impersonatedSigner = await hre.ethers.getSigner(address); + return impersonatedSigner; +} diff --git a/test/operatorPrices.json b/test/operatorPrices.json new file mode 100644 index 0000000..d7f31a6 --- /dev/null +++ b/test/operatorPrices.json @@ -0,0 +1,218 @@ +{ + "fheAdd": { + "binary": true, + "scalar": { "1": 65000, "2": 94000, "3": 133000, "4": 162000, "5": 188000, "6": 218000, "8": 253000 }, + "nonScalar": { "1": 65000, "2": 94000, "3": 133000, "4": 162000, "5": 188000, "6": 218000, "8": 253000 } + }, + "fheSub": { + "binary": true, + "scalar": { "1": 65000, "2": 94000, "3": 133000, "4": 162000, "5": 188000, "6": 218000, "8": 253000 }, + "nonScalar": { "1": 65000, "2": 94000, "3": 133000, "4": 162000, "5": 188000, "6": 218000, "8": 253000 } + }, + "fheMul": { + "binary": true, + "scalar": { "1": 88000, "2": 159000, "3": 208000, "4": 264000, "5": 356000, "6": 480000, "8": 647000 }, + "nonScalar": { "1": 150000, "2": 197000, "3": 262000, "4": 359000, "5": 641000, "6": 1145000, "8": 2045000 } + }, + "fheDiv": { + "binary": true, + "scalar": { "1": 139000, "2": 238000, "3": 314000, "4": 398000, "5": 584000, "6": 857000, "8": 1258000 } + }, + "fheRem": { + "binary": true, + "scalar": { "1": 286000, "2": 460000, "3": 622000, "4": 805000, "5": 1095000, "6": 1499000, "8": 2052000 } + }, + "fheBitAnd": { + "binary": true, + "scalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 } + }, + "fheBitOr": { + "binary": true, + "scalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 } + }, + "fheBitXor": { + "binary": true, + "scalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "0": 26000, "1": 32000, "2": 34000, "3": 34000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 } + }, + "fheShl": { + "binary": true, + "scalar": { "1": 35000, "2": 35000, "3": 35000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "1": 116000, "2": 133000, "3": 153000, "4": 183000, "5": 227000, "6": 282000, "8": 350000 } + }, + "fheShr": { + "binary": true, + "scalar": { "1": 35000, "2": 35000, "3": 35000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "1": 116000, "2": 133000, "3": 153000, "4": 183000, "5": 227000, "6": 282000, "8": 350000 } + }, + "fheRotl": { + "binary": true, + "scalar": { "1": 35000, "2": 35000, "3": 35000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "1": 116000, "2": 133000, "3": 153000, "4": 183000, "5": 227000, "6": 282000, "8": 350000 } + }, + "fheRotr": { + "binary": true, + "scalar": { "1": 35000, "2": 35000, "3": 35000, "4": 35000, "5": 38000, "6": 41000, "8": 44000 }, + "nonScalar": { "1": 116000, "2": 133000, "3": 153000, "4": 183000, "5": 227000, "6": 282000, "8": 350000 } + }, + "fheEq": { + "binary": true, + "scalar": { + "0": 49000, + "1": 51000, + "2": 53000, + "3": 54000, + "4": 82000, + "5": 86000, + "6": 88000, + "7": 90000, + "8": 100000, + "9": 150000, + "10": 200000, + "11": 300000 + }, + "nonScalar": { + "0": 49000, + "1": 51000, + "2": 53000, + "3": 54000, + "4": 82000, + "5": 86000, + "6": 88000, + "7": 90000, + "8": 100000, + "9": 150000, + "10": 200000, + "11": 300000 + } + }, + "fheNe": { + "binary": true, + "scalar": { + "0": 49000, + "1": 51000, + "2": 53000, + "3": 54000, + "4": 82000, + "5": 86000, + "6": 88000, + "7": 90000, + "8": 100000, + "9": 150000, + "10": 200000, + "11": 300000 + }, + "nonScalar": { + "0": 49000, + "1": 51000, + "2": 53000, + "3": 54000, + "4": 82000, + "5": 86000, + "6": 88000, + "7": 90000, + "8": 100000, + "9": 150000, + "10": 200000, + "11": 300000 + } + }, + "fheGe": { + "binary": true, + "scalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 }, + "nonScalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 } + }, + "fheGt": { + "binary": true, + "scalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 }, + "nonScalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 } + }, + "fheLe": { + "binary": true, + "scalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 }, + "nonScalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 } + }, + "fheLt": { + "binary": true, + "scalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 }, + "nonScalar": { "1": 70000, "2": 82000, "3": 105000, "4": 128000, "5": 156000, "6": 190000, "8": 231000 } + }, + "fheMin": { + "binary": true, + "scalar": { "1": 121000, "2": 128000, "3": 150000, "4": 164000, "5": 192000, "6": 225000, "8": 264000 }, + "nonScalar": { "1": 121000, "2": 128000, "3": 153000, "4": 183000, "5": 210000, "6": 241000, "8": 277000 } + }, + "fheMax": { + "binary": true, + "scalar": { "1": 121000, "2": 128000, "3": 150000, "4": 164000, "5": 192000, "6": 225000, "8": 264000 }, + "nonScalar": { "1": 121000, "2": 128000, "3": 153000, "4": 183000, "5": 210000, "6": 241000, "8": 277000 } + }, + "fheNeg": { + "binary": false, + "types": { "1": 60000, "2": 95000, "3": 131000, "4": 160000, "5": 199000, "6": 248000, "8": 309000 } + }, + "fheNot": { + "binary": false, + "types": { "0": 30000, "1": 33000, "2": 34000, "3": 35000, "4": 36000, "5": 37000, "6": 38000, "8": 39000 } + }, + "cast": { + "binary": false, + "types": { "0": 200, "1": 200, "2": 200, "3": 200, "4": 200, "5": 200, "6": 200, "8": 200 } + }, + "trivialEncrypt": { + "binary": false, + "types": { + "0": 100, + "1": 100, + "2": 100, + "3": 200, + "4": 300, + "5": 600, + "6": 650, + "7": 700, + "8": 800, + "9": 1600, + "10": 3200, + "11": 6400 + } + }, + "ifThenElse": { + "binary": false, + "types": { + "0": 43000, + "1": 45000, + "2": 47000, + "3": 47000, + "4": 50000, + "5": 53000, + "6": 70000, + "7": 80000, + "8": 90000, + "9": 150000, + "10": 200000, + "11": 300000 + } + }, + "fheRand": { + "binary": false, + "types": { + "0": 100000, + "1": 100000, + "2": 100000, + "3": 100000, + "4": 100000, + "5": 100000, + "6": 100000, + "8": 100000, + "9": 200000, + "10": 300000, + "11": 400000 + } + }, + "fheRandBounded": { + "binary": false, + "types": { "1": 100000, "2": 100000, "3": 100000, "4": 100000, "5": 100000, "6": 100000, "8": 100000 } + } +} diff --git a/test/operatorsPrices.json b/test/operatorsPrices.json deleted file mode 100644 index 8c861dc..0000000 --- a/test/operatorsPrices.json +++ /dev/null @@ -1,530 +0,0 @@ -{ - "fheAdd": { - "binary": true, - "scalar": { - "1": 65000, - "2": 94000, - "3": 133000, - "4": 162000, - "5": 188000, - "6": 218000, - "8": 253000 - }, - "nonScalar": { - "1": 65000, - "2": 94000, - "3": 133000, - "4": 162000, - "5": 188000, - "6": 218000, - "8": 253000 - } - }, - "fheSub": { - "binary": true, - "scalar": { - "1": 65000, - "2": 94000, - "3": 133000, - "4": 162000, - "5": 188000, - "6": 218000, - "8": 253000 - }, - "nonScalar": { - "1": 65000, - "2": 94000, - "3": 133000, - "4": 162000, - "5": 188000, - "6": 218000, - "8": 253000 - } - }, - "fheMul": { - "binary": true, - "scalar": { - "1": 88000, - "2": 159000, - "3": 208000, - "4": 264000, - "5": 356000, - "6": 480000, - "8": 647000 - }, - "nonScalar": { - "1": 150000, - "2": 197000, - "3": 262000, - "4": 359000, - "5": 641000, - "6": 1145000, - "8": 2045000 - } - }, - "fheDiv": { - "binary": true, - "scalar": { - "1": 139000, - "2": 238000, - "3": 314000, - "4": 398000, - "5": 584000, - "6": 857000, - "8": 1258000 - } - }, - "fheRem": { - "binary": true, - "scalar": { - "1": 286000, - "2": 460000, - "3": 622000, - "4": 805000, - "5": 1095000, - "6": 1499000, - "8": 2052000 - } - }, - "fheBitAnd": { - "binary": true, - "scalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - } - }, - "fheBitOr": { - "binary": true, - "scalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - } - }, - "fheBitXor": { - "binary": true, - "scalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "0": 26000, - "1": 32000, - "2": 34000, - "3": 34000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - } - }, - "fheShl": { - "binary": true, - "scalar": { - "1": 35000, - "2": 35000, - "3": 35000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "1": 116000, - "2": 133000, - "3": 153000, - "4": 183000, - "5": 227000, - "6": 282000, - "8": 350000 - } - }, - "fheShr": { - "binary": true, - "scalar": { - "1": 35000, - "2": 35000, - "3": 35000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "1": 116000, - "2": 133000, - "3": 153000, - "4": 183000, - "5": 227000, - "6": 282000, - "8": 350000 - } - }, - "fheRotl": { - "binary": true, - "scalar": { - "1": 35000, - "2": 35000, - "3": 35000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "1": 116000, - "2": 133000, - "3": 153000, - "4": 183000, - "5": 227000, - "6": 282000, - "8": 350000 - } - }, - "fheRotr": { - "binary": true, - "scalar": { - "1": 35000, - "2": 35000, - "3": 35000, - "4": 35000, - "5": 38000, - "6": 41000, - "8": 44000 - }, - "nonScalar": { - "1": 116000, - "2": 133000, - "3": 153000, - "4": 183000, - "5": 227000, - "6": 282000, - "8": 350000 - } - }, - "fheEq": { - "binary": true, - "scalar": { - "0": 49000, - "1": 51000, - "2": 53000, - "3": 54000, - "4": 82000, - "5": 86000, - "6": 88000, - "7": 90000, - "8": 100000, - "9": 150000, - "10": 200000, - "11": 300000 - }, - "nonScalar": { - "0": 49000, - "1": 51000, - "2": 53000, - "3": 54000, - "4": 82000, - "5": 86000, - "6": 88000, - "7": 90000, - "8": 100000, - "9": 150000, - "10": 200000, - "11": 300000 - } - }, - "fheNe": { - "binary": true, - "scalar": { - "0": 49000, - "1": 51000, - "2": 53000, - "3": 54000, - "4": 82000, - "5": 86000, - "6": 88000, - "7": 90000, - "8": 100000, - "9": 150000, - "10": 200000, - "11": 300000 - }, - "nonScalar": { - "0": 49000, - "1": 51000, - "2": 53000, - "3": 54000, - "4": 82000, - "5": 86000, - "6": 88000, - "7": 90000, - "8": 100000, - "9": 150000, - "10": 200000, - "11": 300000 - } - }, - "fheGe": { - "binary": true, - "scalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - }, - "nonScalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - } - }, - "fheGt": { - "binary": true, - "scalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - }, - "nonScalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - } - }, - "fheLe": { - "binary": true, - "scalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - }, - "nonScalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - } - }, - "fheLt": { - "binary": true, - "scalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - }, - "nonScalar": { - "1": 70000, - "2": 82000, - "3": 105000, - "4": 128000, - "5": 156000, - "6": 190000, - "8": 231000 - } - }, - "fheMin": { - "binary": true, - "scalar": { - "1": 121000, - "2": 128000, - "3": 150000, - "4": 164000, - "5": 192000, - "6": 225000, - "8": 264000 - }, - "nonScalar": { - "1": 121000, - "2": 128000, - "3": 153000, - "4": 183000, - "5": 210000, - "6": 241000, - "8": 277000 - } - }, - "fheMax": { - "binary": true, - "scalar": { - "1": 121000, - "2": 128000, - "3": 150000, - "4": 164000, - "5": 192000, - "6": 225000, - "8": 264000 - }, - "nonScalar": { - "1": 121000, - "2": 128000, - "3": 153000, - "4": 183000, - "5": 210000, - "6": 241000, - "8": 277000 - } - }, - "fheNeg": { - "binary": false, - "types": { - "1": 60000, - "2": 95000, - "3": 131000, - "4": 160000, - "5": 199000, - "6": 248000, - "8": 309000 - } - }, - "fheNot": { - "binary": false, - "types": { - "0": 30000, - "1": 33000, - "2": 34000, - "3": 35000, - "4": 36000, - "5": 37000, - "6": 38000, - "8": 39000 - } - }, - "cast": { - "binary": false, - "types": { - "0": 200, - "1": 200, - "2": 200, - "3": 200, - "4": 200, - "5": 200, - "6": 200, - "8": 200 - } - }, - "trivialEncrypt": { - "binary": false, - "types": { - "0": 100, - "1": 100, - "2": 100, - "3": 200, - "4": 300, - "5": 600, - "6": 650, - "7": 700, - "8": 800, - "9": 1600, - "10": 3200, - "11": 6400 - } - }, - "ifThenElse": { - "binary": false, - "types": { - "0": 43000, - "1": 45000, - "2": 47000, - "3": 47000, - "4": 50000, - "5": 53000, - "6": 70000, - "7": 80000, - "8": 90000, - "9": 150000, - "10": 200000, - "11": 300000 - } - }, - "fheRand": { - "binary": false, - "types": { - "0": 100000, - "1": 100000, - "2": 100000, - "3": 100000, - "4": 100000, - "5": 100000, - "6": 100000, - "8": 100000, - "9": 200000, - "10": 300000, - "11": 400000 - } - }, - "fheRandBounded": { - "binary": false, - "types": { - "1": 100000, - "2": 100000, - "3": 100000, - "4": 100000, - "5": 100000, - "6": 100000, - "8": 100000 - } - } -} diff --git a/test/reencrypt.ts b/test/reencrypt.ts index 8c79e63..6b7b0d0 100644 --- a/test/reencrypt.ts +++ b/test/reencrypt.ts @@ -1,5 +1,5 @@ -import { Signers } from "./signers"; -import type { FhevmInstances } from "./types"; +import { Signer } from "ethers"; +import { FhevmInstance } from "fhevmjs/node"; const EBOOL_T = 0; const EUINT4_T = 1; @@ -31,137 +31,125 @@ export function verifyType(handle: bigint, expectedType: number) { } export async function reencryptEbool( - signers: Signers, - instances: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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: FhevmInstances, - user: string, + 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); } /** @@ -169,27 +157,22 @@ export async function reencryptEbytes256( * It does not verify types. */ async function reencryptHandle( - signers: Signers, - instances: FhevmInstances, - user: string, + signer: Signer, + instance: FhevmInstance, handle: bigint, contractAddress: string, ): Promise { - const { publicKey: publicKey, privateKey: privateKey } = instances[user as keyof FhevmInstances].generateKeypair(); - const eip712 = instances[user as keyof FhevmInstances].createEIP712(publicKey, contractAddress); - const signature = await signers[user as keyof Signers].signTypedData( - eip712.domain, - { Reencrypt: eip712.types.Reencrypt }, - eip712.message, - ); + const { publicKey: publicKey, privateKey: privateKey } = instance.generateKeypair(); + const eip712 = instance.createEIP712(publicKey, contractAddress); + const signature = await signer.signTypedData(eip712.domain, { Reencrypt: eip712.types.Reencrypt }, eip712.message); - const reencryptedHandle = await instances[user as keyof FhevmInstances].reencrypt( + const reencryptedHandle = await instance.reencrypt( handle, privateKey, 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 8b017d1..5fe72ca 100644 --- a/test/signers.ts +++ b/test/signers.ts @@ -1,69 +1,22 @@ import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; -import { exec as oldExec } from "child_process"; -import { config, ethers } from "hardhat"; -import { promisify } from "util"; +import { ethers } from "hardhat"; -import { waitForBalance } from "./utils"; +import { ACCOUNT_NAMES } from "./constants"; -const exec = promisify(oldExec); +type AccountNames = (typeof ACCOUNT_NAMES)[number]; export interface Signers { - alice: HardhatEthersSigner; - bob: HardhatEthersSigner; - carol: HardhatEthersSigner; - dave: HardhatEthersSigner; - eve: HardhatEthersSigner; + [K in AccountNames]: HardhatEthersSigner; } -let signers: Signers; +const signers: Signers = {} as Signers; -const keys: (keyof Signers)[] = ["alice", "bob", "carol", "dave", "eve"]; - -const getCoin = async (address: string) => { - const containerName = process.env["TEST_CONTAINER_NAME"] || "zama-dev-fhevm-validator-1"; - const response = await exec(`docker exec -i ${containerName} faucet ${address} | grep height`); - const res = JSON.parse(response.stdout); - if (res.raw_log.match("account sequence mismatch")) await getCoin(address); -}; - -const faucet = async (address: string) => { - const balance = await ethers.provider.getBalance(address); - if (balance > 0) return; - await getCoin(address); - await waitForBalance(address); -}; - -export const initSigners = async (quantity: number): Promise => { - const q = process.env.HARDHAT_PARALLEL ? Math.min(quantity, 5) : 5; - if (!signers) { - if (process.env.HARDHAT_PARALLEL && config.defaultNetwork === "local") { - signers = { - alice: ethers.Wallet.createRandom().connect(ethers.provider), - bob: ethers.Wallet.createRandom().connect(ethers.provider), - carol: ethers.Wallet.createRandom().connect(ethers.provider), - dave: ethers.Wallet.createRandom().connect(ethers.provider), - eve: ethers.Wallet.createRandom().connect(ethers.provider), - }; - } else if (!process.env.HARDHAT_PARALLEL) { - const eSigners = await ethers.getSigners(); - signers = { - alice: eSigners[0], - bob: eSigners[1], - carol: eSigners[2], - dave: eSigners[3], - eve: eSigners[4], - }; - } else { - throw new Error("Can't run parallel mode if network is not 'local'"); - } - - if (config.defaultNetwork === "local") { - const faucetP: Promise[] = []; - for (let i = 0; i < q; i += 1) { - const account = signers[keys[i]]; - faucetP.push(faucet(account.address)); - } - await Promise.all(faucetP); +export const initSigners = async (): Promise => { + if (Object.entries(signers).length === 0) { + const eSigners = await ethers.getSigners(); + for (let index = 0; index < ACCOUNT_NAMES.length; index++) { + const name = ACCOUNT_NAMES[index]; + signers[name] = eSigners[index]; } } }; @@ -71,5 +24,3 @@ export const initSigners = async (quantity: number): Promise => { export const getSigners = async (): Promise => { return signers; }; - -export const requestFaucet = faucet; diff --git a/test/types.ts b/test/types.ts deleted file mode 100644 index 6afcffe..0000000 --- a/test/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { FhevmInstance } from "fhevmjs"; - -import type { Signers } from "./signers"; - -declare module "mocha" { - export interface Context { - signers: Signers; - contractAddress: string; - instances: FhevmInstances; - } -} - -export interface FhevmInstances { - alice: FhevmInstance; - bob: FhevmInstance; - carol: FhevmInstance; - dave: FhevmInstance; - eve: FhevmInstance; -} diff --git a/test/utils.ts b/test/utils.ts index ae071be..79b8076 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,73 +1,33 @@ import { toBufferBE } from "bigint-buffer"; -import { ContractMethodArgs, Typed } from "ethers"; import { ethers, network } from "hardhat"; -import { TypedContractMethod } from "../types/common"; +import { awaitCoprocessor, getClearText } from "./coprocessorUtils"; -export const waitForBlock = (blockNumber: bigint | number) => { - if (network.name === "hardhat") { - return new Promise((resolve, reject) => { - const intervalId = setInterval(async () => { - try { - const currentBlock = await ethers.provider.getBlockNumber(); - if (BigInt(currentBlock) >= blockNumber) { - clearInterval(intervalId); - resolve(currentBlock); - } - } catch (error) { - clearInterval(intervalId); - reject(error); - } - }, 50); // Check every 50 milliseconds - }); - } else { - return new Promise((resolve, reject) => { - const waitBlock = async (currentBlock: number) => { - if (blockNumber <= BigInt(currentBlock)) { - await ethers.provider.off("block", waitBlock); - resolve(blockNumber); - } - }; - ethers.provider.on("block", waitBlock).catch((err) => { - reject(err); - }); - }); +export const mineNBlocks = async (n: number) => { + for (let index = 0; index < n; index++) { + await ethers.provider.send("evm_mine"); } }; +export const bigIntToBytes64 = (value: bigint) => { + return new Uint8Array(toBufferBE(value, 64)); +}; + +export const bigIntToBytes128 = (value: bigint) => { + return new Uint8Array(toBufferBE(value, 128)); +}; + +export const bigIntToBytes256 = (value: bigint) => { + return new Uint8Array(toBufferBE(value, 256)); +}; + export const waitNBlocks = async (Nblocks: number) => { const currentBlock = await ethers.provider.getBlockNumber(); if (network.name === "hardhat") { await produceDummyTransactions(Nblocks); + } else { + await waitForBlock(BigInt(currentBlock + Nblocks)); } - await waitForBlock(currentBlock + Nblocks); -}; - -export const waitForBalance = async (address: string): Promise => { - return new Promise((resolve, reject) => { - const checkBalance = async () => { - const balance = await ethers.provider.getBalance(address); - if (balance > 0) { - await ethers.provider.off("block", checkBalance); - resolve(); - } - }; - ethers.provider.on("block", checkBalance).catch((err) => { - reject(err); - }); - }); -}; - -export const createTransaction = async ( - method: TypedContractMethod, - ...params: A -) => { - const gasLimit = await method.estimateGas(...params); - const updatedParams: ContractMethodArgs = [ - ...params, - { gasLimit: Math.min(Math.round(+gasLimit.toString() * 1.2), 10000000) }, - ]; - return method(...updatedParams); }; export const produceDummyTransactions = async (blockCount: number) => { @@ -85,25 +45,274 @@ export const produceDummyTransactions = async (blockCount: number) => { } }; -export const mineNBlocks = async (n: number) => { - for (let index = 0; index < n; index++) { - await ethers.provider.send("evm_mine"); - } +const waitForBlock = (blockNumber: bigint) => { + return new Promise((resolve, reject) => { + const waitBlock = async (currentBlock: number) => { + if (blockNumber <= BigInt(currentBlock)) { + await ethers.provider.off("block", waitBlock); + resolve(blockNumber); + } + }; + ethers.provider.on("block", waitBlock).catch((err) => { + reject(err); + }); + }); }; -export const bigIntToBytes64 = (value: bigint) => { - return new Uint8Array(toBufferBE(value, 64)); -}; +const EBOOL_T = 0; +const EUINT4_T = 1; +const EUINT8_T = 2; +const EUINT16_T = 3; +const EUINT32_T = 4; +const EUINT64_T = 5; +const EUINT128_T = 6; +const EUINT160_T = 7; // @dev It is the one for eaddresses. +const EUINT256_T = 8; +const EBYTES64_T = 9; +const EBYTES128_T = 10; +const EBYTES256_T = 11; -export const bigIntToBytes128 = (value: bigint) => { - return new Uint8Array(toBufferBE(value, 128)); -}; +function verifyType(handle: bigint, expectedType: number) { + if (handle === 0n) { + throw "Handle is not initialized"; + } + if (handle.toString(2).length > 256) { + throw "Handle is not a bytes32"; + } + const typeCt = handle >> 8n; + if (Number(typeCt % 256n) !== expectedType) { + throw "Wrong encrypted type for the handle"; + } +} -export const bigIntToBytes256 = (value: bigint) => { - return new Uint8Array(toBufferBE(value, 256)); -}; +export const debug = { + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bool} + */ + decryptBool: async (handle: bigint): Promise => { + verifyType(handle, EBOOL_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return (await getClearText(handle)) === "1"; + } else { + throw Error("The debug.decryptBool function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt4: async (handle: bigint): Promise => { + verifyType(handle, EUINT4_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt4 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ + decrypt8: async (handle: bigint): Promise => { + verifyType(handle, EUINT8_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt8 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt16: async (handle: bigint): Promise => { + verifyType(handle, EUINT16_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt16 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt32: async (handle: bigint): Promise => { + verifyType(handle, EUINT32_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt32 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt64: async (handle: bigint): Promise => { + verifyType(handle, EUINT64_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt64 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt128: async (handle: bigint): Promise => { + verifyType(handle, EUINT128_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt128 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decrypt256: async (handle: bigint): Promise => { + verifyType(handle, EUINT256_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return BigInt(await getClearText(handle)); + } else { + throw Error("The debug.decrypt256 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {string} + */ + decryptAddress: async (handle: bigint): Promise => { + verifyType(handle, EUINT160_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + const bigintAdd = BigInt(await getClearText(handle)); + const handleStr = "0x" + bigintAdd.toString(16).padStart(40, "0"); + return handleStr; + } else { + throw Error("The debug.decryptAddress function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ + decryptEbytes64: async (handle: bigint): Promise => { + verifyType(handle, EBYTES64_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return ethers.toBeHex(await getClearText(handle), 64); + } else { + throw Error("The debug.decryptEbytes64 function can only be called in mocked mode"); + } + }, + + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decryptEbytes128: async (handle: bigint): Promise => { + verifyType(handle, EBYTES128_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return ethers.toBeHex(await getClearText(handle), 128); + } else { + throw Error("The debug.decryptEbytes128 function can only be called in mocked mode"); + } + }, -export const bigIntToBytes = (value: bigint) => { - const byteArrayLength = Math.ceil(value.toString(2).length / 8); - return new Uint8Array(toBufferLE(value, byteArrayLength)); + /** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} handle to decrypt + * @returns {bigint} + */ + decryptEbytes256: async (handle: bigint): Promise => { + verifyType(handle, EBYTES256_T); + if (network.name === "hardhat") { + await awaitCoprocessor(); + return ethers.toBeHex(await getClearText(handle), 256); + } else { + throw Error("The debug.decryptEbytes256 function can only be called in mocked mode"); + } + }, }; diff --git a/test/utils/EncryptedErrors.fixture.ts b/test/utils/EncryptedErrors.fixture.ts index ba8295e..285fb10 100644 --- a/test/utils/EncryptedErrors.fixture.ts +++ b/test/utils/EncryptedErrors.fixture.ts @@ -1,11 +1,11 @@ +import { Signer } from "ethers"; import { ethers } from "hardhat"; import type { TestEncryptedErrors } from "../../types"; -import { Signers } from "../signers"; -export async function deployEncryptedErrors(signers: Signers, numberErrors: number): Promise { +export async function deployEncryptedErrors(signer: Signer, numberErrors: number): Promise { const contractFactory = await ethers.getContractFactory("TestEncryptedErrors"); - const contract = await contractFactory.connect(signers.alice).deploy(numberErrors); + const contract = await contractFactory.connect(signer).deploy(numberErrors); await contract.waitForDeployment(); return contract; } diff --git a/test/utils/EncryptedErrors.test.ts b/test/utils/EncryptedErrors.test.ts index 4e277ad..26a886a 100644 --- a/test/utils/EncryptedErrors.test.ts +++ b/test/utils/EncryptedErrors.test.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; -import { createInstances } from "../instance"; +import { createInstance } from "../instance"; import { reencryptEuint8 } from "../reencrypt"; import { getSigners, initSigners } from "../signers"; import { deployEncryptedErrors } from "./EncryptedErrors.fixture"; @@ -10,14 +10,14 @@ describe("EncryptedErrors", function () { const NO_ERROR_CODE = 0n; before(async function () { - await initSigners(3); + await initSigners(); this.signers = await getSigners(); - this.instances = await createInstances(this.signers); + this.instance = await createInstance(); }); beforeEach(async function () { this.numberErrors = 3; - const contract = await deployEncryptedErrors(this.signers, this.numberErrors); + const contract = await deployEncryptedErrors(this.signers.alice, this.numberErrors); this.encryptedErrorsAddress = await contract.getAddress(); this.encryptedErrors = contract; }); @@ -28,9 +28,7 @@ describe("EncryptedErrors", function () { for (let i = 0; i < 3; i++) { const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeDefinition(i); - expect( - await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress), - ).to.be.eq(i); + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq(i); } }); @@ -39,7 +37,7 @@ describe("EncryptedErrors", function () { const condition = true; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await this.encryptedErrors @@ -47,7 +45,7 @@ describe("EncryptedErrors", function () { .errorDefineIf(encryptedData.handles[0], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( targetErrorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -58,7 +56,7 @@ describe("EncryptedErrors", function () { const condition = false; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await this.encryptedErrors @@ -66,7 +64,7 @@ describe("EncryptedErrors", function () { .errorDefineIf(encryptedData.handles[0], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( NO_ERROR_CODE, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -77,7 +75,7 @@ describe("EncryptedErrors", function () { const condition = true; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await this.encryptedErrors @@ -85,7 +83,7 @@ describe("EncryptedErrors", function () { .errorDefineIfNot(encryptedData.handles[0], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( NO_ERROR_CODE, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -96,7 +94,7 @@ describe("EncryptedErrors", function () { const condition = false; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await this.encryptedErrors @@ -104,7 +102,7 @@ describe("EncryptedErrors", function () { .errorDefineIfNot(encryptedData.handles[0], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( targetErrorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -116,7 +114,7 @@ describe("EncryptedErrors", function () { const errorCode = 1; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).add8(errorCode).encrypt(); await this.encryptedErrors @@ -124,7 +122,7 @@ describe("EncryptedErrors", function () { .errorChangeIf(encryptedData.handles[0], encryptedData.handles[1], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( targetErrorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -136,7 +134,7 @@ describe("EncryptedErrors", function () { const errorCode = 1; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).add8(errorCode).encrypt(); await this.encryptedErrors @@ -144,7 +142,7 @@ describe("EncryptedErrors", function () { .errorChangeIf(encryptedData.handles[0], encryptedData.handles[1], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( errorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -156,7 +154,7 @@ describe("EncryptedErrors", function () { const errorCode = 1; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).add8(errorCode).encrypt(); await this.encryptedErrors @@ -164,7 +162,7 @@ describe("EncryptedErrors", function () { .errorChangeIfNot(encryptedData.handles[0], encryptedData.handles[1], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( errorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -176,7 +174,7 @@ describe("EncryptedErrors", function () { const errorCode = 1; const targetErrorCode = 2; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).add8(errorCode).encrypt(); await this.encryptedErrors @@ -184,7 +182,7 @@ describe("EncryptedErrors", function () { .errorChangeIfNot(encryptedData.handles[0], encryptedData.handles[1], encryptedData.inputProof, targetErrorCode); const handle = await this.encryptedErrors.connect(this.signers.alice).errorGetCodeEmitted(0); - expect(await reencryptEuint8(this.signers, this.instances, "alice", handle, this.encryptedErrorsAddress)).to.be.eq( + expect(await reencryptEuint8(this.signers.alice, this.instance, handle, this.encryptedErrorsAddress)).to.be.eq( targetErrorCode, ); expect(await this.encryptedErrors.errorGetCounter()).to.be.eq(BigInt("1")); @@ -203,7 +201,7 @@ describe("EncryptedErrors", function () { const condition = true; const targetErrorCode = (await this.encryptedErrors.errorGetNumCodesDefined()) + 1n; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await expect( @@ -223,7 +221,7 @@ describe("EncryptedErrors", function () { const condition = true; const targetErrorCode = 0; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).encrypt(); await expect( @@ -244,7 +242,7 @@ describe("EncryptedErrors", function () { const errorCode = 1; const targetErrorCode = (await this.encryptedErrors.errorGetNumCodesDefined()) + 1n; - const input = this.instances.alice.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); + const input = this.instance.createEncryptedInput(this.encryptedErrorsAddress, this.signers.alice.address); const encryptedData = await input.addBool(condition).add8(errorCode).encrypt(); await expect(