Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: adjustments for reencrypt functions #47

Merged
merged 3 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/TestAsyncDecrypt.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import "fhevm/config/ZamaGatewayConfig.sol";
import "fhevm/gateway/GatewayCaller.sol";

/// @notice Contract for testing asynchronous decryption using the Gateway
/* solhint-disable max-states-count*/
/* solhint-disable var-name-mixedcase*/
contract TestAsyncDecrypt is SepoliaZamaFHEVMConfig, SepoliaZamaGatewayConfig, GatewayCaller {
/// @dev Encrypted state variables
ebool xBool;
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default [
linterOptions: {
reportUnusedDisableDirectives: "off",
},
ignores: ["abi/", "artifacts/", "cache/", "res/", "types/*"],
ignores: [".abi/", ".artifacts/", ".cache/", ".coverage/", ".res/", ".types/"],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
Expand Down
17 changes: 3 additions & 14 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import "@nomicfoundation/hardhat-toolbox";
import "@openzeppelin/hardhat-upgrades";
import dotenv from "dotenv";
import * as fs from "fs-extra";
import "hardhat-deploy";
import "hardhat-ignore-warnings";
import type { HardhatUserConfig, extendProvider } from "hardhat/config";
import { HardhatUserConfig, extendProvider } from "hardhat/config";
import { task } from "hardhat/config";
import type { NetworkUserConfig } from "hardhat/types";
import { resolve } from "path";
Expand Down Expand Up @@ -33,7 +32,7 @@ const dotenvConfigPath: string = process.env.DOTENV_CONFIG_PATH || "./.env";
dotenv.config({ path: resolve(__dirname, dotenvConfigPath) });

// Ensure that we have all the environment variables we need.
let mnemonic: string = process.env.MNEMONIC!;
const mnemonic: string = process.env.MNEMONIC!;

const chainIds = {
zama: 8009,
Expand Down Expand Up @@ -75,17 +74,7 @@ task("coverage").setAction(async (taskArgs, hre, runSuper) => {
await runSuper(taskArgs);
});

function replaceImportStatement(filePath: string, oldImport: string, newImport: string): void {
try {
let fileContent = fs.readFileSync(filePath, "utf-8");
fileContent = fileContent.replace(oldImport, newImport);
fs.writeFileSync(filePath, fileContent, "utf-8");
} catch (error) {
console.error(`Error updating file: ${error}`);
}
}

task("test", async (taskArgs, hre, runSuper) => {
task("test", async (_taskArgs, hre, runSuper) => {
// Run modified test task
if (hre.network.name === "hardhat") {
await setCodeMocked(hre);
Expand Down
4 changes: 3 additions & 1 deletion tasks/mint.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { task } from "hardhat/config";
import type { TaskArguments } from "hardhat/types";

import { MyConfidentialERC20 } from "../types";

task("task:deployConfidentialERC20").setAction(async function (taskArguments: TaskArguments, { ethers }) {
const signers = await ethers.getSigners();
const erc20Factory = await ethers.getContractFactory("MyConfidentialERC20");
Expand All @@ -17,7 +19,7 @@ task("task:mint")

const signers = await ethers.getSigners();

const erc20 = (await ethers.getContractAt("MyConfidentialERC20", ERC20.address)) as any;
const erc20 = (await ethers.getContractAt("MyConfidentialERC20", ERC20.address)) as MyConfidentialERC20;

await erc20.connect(signers[0]).mint(+taskArguments.mint);

Expand Down
4 changes: 1 addition & 3 deletions test/asyncDecrypt.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Wallet, ZeroAddress } from "ethers";
import gatewayArtifact from "fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json";
import { ethers, network } from "hardhat";

import { ACL_ADDRESS, GATEWAYCONTRACT_ADDRESS, KMSVERIFIER_ADDRESS, PRIVATE_KEY_KMS_SIGNER } from "./constants";
import { awaitCoprocessor, getClearText } from "./coprocessorUtils";
import { impersonateAddress } from "./mockedSetup";
import { waitNBlocks } from "./utils";

const gatewayArtifact = require("fhevm-core-contracts/artifacts/gateway/GatewayContract.sol/GatewayContract.json");

const networkName = network.name;

const aclAdd = ACL_ADDRESS;

const CiphertextType = {
Expand Down Expand Up @@ -122,7 +120,7 @@
await awaitCoprocessor();

// first check tat all handles are allowed for decryption
const aclArtifact = require("fhevm-core-contracts/artifacts/contracts/ACL.sol/ACL.json");

Check failure on line 123 in test/asyncDecrypt.ts

View workflow job for this annotation

GitHub Actions / ci

A `require()` style import is forbidden
const acl = await ethers.getContractAt(aclArtifact.abi, ACL_ADDRESS);
const isAllowedForDec = await Promise.all(handles.map(async (handle) => acl.isAllowedForDecryption(handle)));
if (!allTrue(isAllowedForDec)) {
Expand Down
33 changes: 11 additions & 22 deletions test/confidentialERC20/ConfidentialERC20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ describe("ConfidentialERC20", function () {
// Reencrypt Alice's balance
const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice);
const balanceAlice = await reencryptEuint64(
this.signers,
this.signers.alice,
this.fhevm,
"alice",
balanceHandleAlice,
this.contractAddress,
);
Expand Down Expand Up @@ -59,27 +58,26 @@ describe("ConfidentialERC20", function () {
// Reencrypt Alice's balance
const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice);
const balanceAlice = await reencryptEuint64(
this.signers,
this.signers.alice,
this.fhevm,
"alice",
balanceHandleAlice,
this.contractAddress,
);
expect(balanceAlice).to.equal(10000 - 1337);

// Reencrypt Bob's balance
const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob);
const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress);
const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress);
expect(balanceBob).to.equal(1337);

// on the other hand, Bob should be unable to read Alice's balance
await expect(
reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleAlice, this.contractAddress),
reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleAlice, this.contractAddress),
).to.be.rejectedWith("User is not authorized to reencrypt this handle!");

// and should be impossible to call reencrypt if contractAddress === userAddress
await expect(
reencryptEuint64(this.signers, this.fhevm, "alice", balanceHandleAlice, this.signers.alice.address),
reencryptEuint64(this.signers.alice, this.fhevm, balanceHandleAlice, this.signers.alice.address),
).to.be.rejectedWith("userAddress should not be equal to contractAddress when requesting reencryption!");
});

Expand All @@ -99,17 +97,16 @@ describe("ConfidentialERC20", function () {

const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice);
const balanceAlice = await reencryptEuint64(
this.signers,
this.signers.alice,
this.fhevm,
"alice",
balanceHandleAlice,
this.contractAddress,
);
expect(balanceAlice).to.equal(1000);

// Reencrypt Bob's balance
const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob);
const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress);
const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress);
expect(balanceBob).to.equal(0);
});

Expand Down Expand Up @@ -142,17 +139,16 @@ describe("ConfidentialERC20", function () {
// Decrypt Alice's balance
const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice);
const balanceAlice = await reencryptEuint64(
this.signers,
this.signers.alice,
this.fhevm,
"alice",
balanceHandleAlice,
this.contractAddress,
);
expect(balanceAlice).to.equal(10000); // check that transfer did not happen, as expected

// Decrypt Bob's balance
const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob);
const balanceBob = await reencryptEuint64(this.signers, this.fhevm, "bob", balanceHandleBob, this.contractAddress);
const balanceBob = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob, this.contractAddress);
expect(balanceBob).to.equal(0); // check that transfer did not happen, as expected

const inputBob2 = this.fhevm.createEncryptedInput(this.contractAddress, this.signers.bob.address);
Expand All @@ -169,23 +165,16 @@ describe("ConfidentialERC20", function () {
// Decrypt Alice's balance
const balanceHandleAlice2 = await this.erc20.balanceOf(this.signers.alice);
const balanceAlice2 = await reencryptEuint64(
this.signers,
this.signers.alice,
this.fhevm,
"alice",
balanceHandleAlice2,
this.contractAddress,
);
expect(balanceAlice2).to.equal(10000 - 1337); // check that transfer did happen this time

// Decrypt Bob's balance
const balanceHandleBob2 = await this.erc20.balanceOf(this.signers.bob);
const balanceBob2 = await reencryptEuint64(
this.signers,
this.fhevm,
"bob",
balanceHandleBob2,
this.contractAddress,
);
const balanceBob2 = await reencryptEuint64(this.signers.bob, this.fhevm, balanceHandleBob2, this.contractAddress);
expect(balanceBob2).to.equal(1337); // check that transfer did happen this time
});

Expand Down
6 changes: 3 additions & 3 deletions test/coprocessorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
let firstBlockListening = 0;
let lastBlockSnapshot = 0;
let lastCounterRand = 0;
let counterRand = 0;

Check failure on line 14 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

'counterRand' is assigned a value but never used

//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()]);
Expand All @@ -27,7 +27,7 @@

// Decrypt any handle, bypassing ACL
// WARNING : only for testing or internal use
export const getClearText = async (handle: BigInt): Promise<string> => {
export const getClearText = async (handle: bigint): Promise<string> => {
const handleStr = "0x" + handle.toString(16).padStart(64, "0");

return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -102,7 +102,7 @@
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.");
}
Expand Down Expand Up @@ -184,7 +184,7 @@
eventName: parsedLog.name,
args: parsedLog.args,
};
} catch (e) {

Check failure on line 187 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

'e' is defined but never used
// If the log cannot be parsed, skip it
return null;
}
Expand Down Expand Up @@ -567,9 +567,9 @@
handle = ethers.toBeHex(event.args[3], 32);
resultType = parseInt(handle.slice(-4, -2), 16);
handle = ethers.toBeHex(event.args[3], 32);
const clearControl = BigInt(await getClearText(event.args[0]));

Check failure on line 570 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected lexical declaration in case block
const clearIfTrue = BigInt(await getClearText(event.args[1]));

Check failure on line 571 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected lexical declaration in case block
const clearIfFalse = BigInt(await getClearText(event.args[2]));

Check failure on line 572 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected lexical declaration in case block
if (clearControl === 1n) {
clearText = clearIfTrue;
} else {
Expand Down Expand Up @@ -782,7 +782,7 @@
FHEGasConsumed += operatorPrices["fheEq"].nonScalar[type];
}

case "FheNe":

Check failure on line 785 in test/coprocessorUtils.ts

View workflow job for this annotation

GitHub Actions / ci

Expected a 'break' statement before 'case'
handle = ethers.toBeHex(event.args[0], 32);
type = parseInt(handle.slice(-4, -2), 16);
if (event.args[2] === "0x01") {
Expand Down
12 changes: 3 additions & 9 deletions test/fhevmjsMocked.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { toBigIntBE, toBufferBE } from "bigint-buffer";
import crypto from "crypto";
import dotenv from "dotenv";
import { Wallet, ethers } from "ethers";
import * as fs from "fs";
import hre from "hardhat";
import { Keccak } from "sha3";
import { isAddress } from "web3-validator";

Expand All @@ -16,10 +15,6 @@
import { insertSQL } from "./coprocessorUtils";
import { awaitCoprocessor, getClearText } from "./coprocessorUtils";

const hre = require("hardhat");

const aclAdd = ACL_ADDRESS;

enum Types {
ebool = 0,
euint4,
Expand Down Expand Up @@ -144,7 +139,7 @@
}

// ACL checking
const aclArtifact = require("fhevm-core-contracts/artifacts/contracts/ACL.sol/ACL.json");

Check failure on line 142 in test/fhevmjsMocked.ts

View workflow job for this annotation

GitHub Actions / ci

A `require()` style import is forbidden
const acl = await hre.ethers.getContractAt(aclArtifact.abi, ACL_ADDRESS);
const userAllowed = await acl.persistAllowed(handle, userAddress);
const contractAllowed = await acl.persistAllowed(handle, contractAddress);
Expand Down Expand Up @@ -362,7 +357,7 @@
}

function numberToHex(num: number) {
let hex = num.toString(16);
const hex = num.toString(16);
return hex.length % 2 ? "0" + hex : hex;
}

Expand Down Expand Up @@ -401,10 +396,9 @@
userAddress: string,
contractAddress: string,
): Promise<string> {
let signature: string;
const privKeySigner = PRIVATE_KEY_COPROCESSOR_ACCOUNT;
const coprocSigner = new Wallet(privKeySigner).connect(ethers.provider);
signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner);
const signature = await coprocSign(hash, handlesList, userAddress, contractAddress, coprocSigner);
return signature;
}

Expand Down
4 changes: 2 additions & 2 deletions test/gatewayDecrypt/testAsyncDecrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ describe("TestAsyncDecrypt", function () {
const tx2 = await this.contract.connect(this.signers.carol).requestMixed(5, 15);
await tx2.wait();
await awaitAllDecryptionResults();
let yB = await this.contract.yBool();
const yB = await this.contract.yBool();
expect(yB).to.equal(true);
let y = await this.contract.yUint4();
expect(y).to.equal(4);
y = await this.contract.yUint8();
expect(y).to.equal(42);
y = await this.contract.yUint16();
expect(y).to.equal(16);
let yAdd = await this.contract.yAddress();
const yAdd = await this.contract.yAddress();
expect(yAdd).to.equal("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
y = await this.contract.yUint32();
expect(y).to.equal(52); // 5+15+32
Expand Down
Loading
Loading