diff --git a/.github/config/commitlint.config.js b/.github/config/commitlint.config.ts similarity index 62% rename from .github/config/commitlint.config.js rename to .github/config/commitlint.config.ts index a96b27f4..e123f1fc 100644 --- a/.github/config/commitlint.config.js +++ b/.github/config/commitlint.config.ts @@ -1,26 +1,27 @@ -const RuleConfigSeverity = require("@commitlint/types").RuleConfigSeverity; +import { RuleConfigSeverity } from '@commitlint/types'; + const Configuration = { /* * Resolve and load @commitlint/config-conventional from node_modules. * Referenced packages must be installed */ - extends: ["@commitlint/config-conventional"], + extends: ['@commitlint/config-conventional'], /* * Resolve and load conventional-changelog-atom from node_modules. * Referenced packages must be installed */ - parserPreset: "conventional-changelog-conventionalcommits", + parserPreset: 'conventional-changelog-conventionalcommits', /* * Resolve and load @commitlint/format from node_modules. * Referenced package must be installed */ - formatter: "@commitlint/format", + formatter: '@commitlint/format', /* * Any rules defined here will override rules from @commitlint/config-conventional */ rules: { - "type-empty": [RuleConfigSeverity.Error, "never"], + 'type-empty': [RuleConfigSeverity.Error, 'never'], }, }; -module.exports = Configuration; +export default Configuration; diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 49964107..cf4a7947 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -19,4 +19,4 @@ jobs: run: | npm install -g @commitlint/cli@^18 - name: Validate all commits from PR - run: npx commitlint --config .github/config/commitlint.config.js --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose + run: npx commitlint --config .github/config/commitlint.config.ts --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 00000000..813b76ee --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx --no-install commitlint --edit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 00000000..81f11611 --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,3 @@ +{ + "*.{js,json,md,sol,ts,yml}": ["npm run prettier -- --write"] +} diff --git a/.npmignore b/.npmignore index 0d50daef..56e2a23e 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,7 @@ * !lib/** !gateway/** +!config/** !package.json !README.md !LICENSE diff --git a/.solcover.js b/.solcover.js index f019682c..91f35d18 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,11 +1,9 @@ -module.exports = { - istanbulReporter: ["html", "lcov"], - providerOptions: { - mnemonic: process.env.MNEMONIC, - }, - skipFiles: ["test"], - mocha: { - fgrep: "[skip-on-coverage]", - invert: true, - }, +export const istanbulReporter = ["html", "lcov"]; +export const providerOptions = { + mnemonic: process.env.MNEMONIC, +}; +export const skipFiles = ["test"]; +export const mocha = { + fgrep: "[skip-on-coverage]", + invert: true, }; diff --git a/ci/scripts/run_ERC20.sh b/ci/scripts/run_ERC20.sh deleted file mode 100755 index 1d5081d8..00000000 --- a/ci/scripts/run_ERC20.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# This script execute a python script within a ready-to-use docker image with all the required python modules. -# The script takes two arguments: -# 1. The private key of the main account which has already funds. -# 2. (Optional) The node address (default: http://host.docker.internal:8545) -# -# Example usage: ./run_ERC20.sh http://host.docker.internal:8545 - -if [ "$#" -lt 2 ]; then - echo "Please give the private key of the main account and optionnaly the node @:port" - echo "Example: `basename "$0"` CB99CAA34343 http://host.docker.internal:8545" - exit -fi - -PRIVATE_KEY=$1 -NODE_ADDRESS=${2:-http://host.docker.internal:8545} - -# Create the keys directory if it doesn't exist -mkdir -p keys - -echo "Exported private key: $PRIVATE_KEY" - -# Run the Python script with the exported private key as an argument -docker compose -f ci/docker-compose.yml run app python ci/tests/ERC20.py $PRIVATE_KEY $NODE_ADDRESS diff --git a/ci/scripts/run_ERC20_ci_test.sh b/ci/scripts/run_ERC20_ci_test.sh deleted file mode 100755 index 213724a9..00000000 --- a/ci/scripts/run_ERC20_ci_test.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# This script exports an Ethereum private key from an evmos node and uses it to run a Python script. -# The script takes two arguments: -# 1. The name of the key to export (e.g., mykey1 or mykey2) -# 2. The path to the evmos directory -# -# Example usage: ./run_ERC20_ci_test.sh mykey1 ../evmos - -if [ "$#" -ne 2 ]; then - echo "Please give the key name (e.g., mykey1 or mykey2) and the path to the evmos directory and optionnaly the node @:port" - echo "Example: `basename "$0"` mykey1 ../evmos" - exit -fi - -key=$1 -PATH_TO_EVMOS=$2 - -# Create the keys directory if it doesn't exist -mkdir -p keys - -# Export the private key from the evmos node -PRIVATE_KEY=$(docker compose -f $PATH_TO_EVMOS/docker-compose/docker-compose.validator.yml exec validator evmosd --home /root/.evmosd keys unsafe-export-eth-key $key --keyring-backend test) - -echo "Exported private key: $PRIVATE_KEY" - -# Run the Python script with the exported private key as an argument -docker compose -f ci/docker-compose.yml run app python ci/tests/ERC20.py $PRIVATE_KEY \ No newline at end of file diff --git a/ci/scripts/run_ERC20_e2e_test.sh b/ci/scripts/run_ERC20_e2e_test.sh deleted file mode 100755 index 32634ec3..00000000 --- a/ci/scripts/run_ERC20_e2e_test.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# This script exports an Ethereum private key from an evmos node and uses it to run a Python script. -# The script takes two arguments: -# 1. The name of the key to export (e.g., mykey1 or mykey2) -# 2. The path to the evmos directory -# -# Example usage: ./run_ERC20_e2e_test.sh.sh mykey1 ../evmos - -if [ "$#" -ne 2 ]; then - echo "Please give the key name (e.g., mykey1 or mykey2) and the path to the evmos directory" - echo "Example: `basename "$0"` mykey1 ../evmos" - exit -fi - -key=$1 -PATH_TO_EVMOS=$2 - -# Create the keys directory if it doesn't exist -mkdir -p keys - -# Export the private key from the evmos node -PRIVATE_KEY=$(docker compose -f $PATH_TO_EVMOS/docker-compose/docker-compose.local.yml exec evmosnodelocal evmosd --home /root/.evmosd keys unsafe-export-eth-key $key --keyring-backend test) - -echo "Exported private key: $PRIVATE_KEY" - -# Run the Python script with the exported private key as an argument -docker compose -f ci/docker-compose.yml run app python ci/tests/ERC20.py $PRIVATE_KEY diff --git a/codegen/templates.ts b/codegen/templates.ts index 8fe74ee5..d494594b 100644 --- a/codegen/templates.ts +++ b/codegen/templates.ts @@ -20,8 +20,11 @@ type ebytes128 is uint256; type ebytes256 is uint256; type einput is bytes32; +/** + * @title Common + * @notice This library contains all the values used to communicate types to the run time. + */ library Common { - // Values used to communicate types to the runtime. uint8 internal constant ebool_t = 0; uint8 internal constant euint4_t = 1; uint8 internal constant euint8_t = 2; @@ -69,7 +72,6 @@ export function implSol(operators: Operator[]): string { res.push(` // SPDX-License-Identifier: BSD-3-Clause-Clear - pragma solidity ^0.8.24; import "./TFHE.sol"; @@ -79,8 +81,12 @@ ${coprocessorInterface} ${aclInterface} +/** + * @title Impl + * @notice This library is the core implementation for computing FHE operations (e.g. add, sub, xor). + */ library Impl { - // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) + /// @dev keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant FHEVMConfigLocation = 0xed8d60e34876f751cc8b014c560745351147d9de11b9347c854e881b128ea600; function getFHEVMConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct storage $) { @@ -159,7 +165,13 @@ function generateImplFhevmLibInterface(operators: Operator[]): string { function generateImplCoprocessorInterface(operators: Operator[]): string { const res: string[] = []; - res.push('interface ITFHEExecutor {'); + res.push(` + /** + * @title ITFHEExecutor + * @notice This interface contains all functions to conduct FHE operations. + */ + interface ITFHEExecutor {`); + operators.forEach((op) => { let functionName = operatorFheLibFunction(op); const tail = 'external returns (uint256 result);'; @@ -205,6 +217,11 @@ function coprocessorInterfaceCustomFunctions(): string { function generateACLInterface(): string { return ` + /** + * @title IACL + * @notice This interface contains all functions that are used to conduct operations + * with the ACL contract. + */ interface IACL { function allowTransient(uint256 ciphertext, address account) external; function allow(uint256 handle, address account) external; @@ -224,7 +241,6 @@ export function tfheSol( const res: string[] = []; res.push(`// SPDX-License-Identifier: BSD-3-Clause-Clear - pragma solidity ^0.8.24; import "./Impl.sol"; @@ -234,7 +250,11 @@ import "./FHEVMConfig.sol"; ${commonSolLib()} - +/** + * @title TFHE + * @notice This library is the interaction point for all smart contract developers + * that interact with TFHE. + */ library TFHE { function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { Impl.setFHEVM(fhevmConfig); diff --git a/commitlint.config.ts b/commitlint.config.ts new file mode 100644 index 00000000..fc5761c8 --- /dev/null +++ b/commitlint.config.ts @@ -0,0 +1,14 @@ +import type { UserConfig } from '@commitlint/types'; + +const Configuration: UserConfig = { + extends: ['@commitlint/config-conventional'], + rules: { + 'type-enum': [ + 2, + 'always', + ['ci', 'chore', 'docs', 'ticket', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'], + ], + }, +}; + +export default Configuration; diff --git a/config/ZamaFHEVMConfig.sol b/config/ZamaFHEVMConfig.sol index ded02c78..32b86383 100644 --- a/config/ZamaFHEVMConfig.sol +++ b/config/ZamaFHEVMConfig.sol @@ -14,20 +14,20 @@ library ZamaFHEVMConfig { function getMockConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct memory) { return FHEVMConfig.FHEVMConfigStruct({ - ACLAddress: 0x339EcE85B9E11a3A3AA557582784a15d7F82AAf2, - TFHEExecutorAddress: 0x596E6682c72946AF006B27C131793F2b62527A4b, - FHEPaymentAddress: 0x6d5A11aC509C707c00bc3A0a113ACcC26c532547, - KMSVerifierAddress: 0x208De73316E44722e16f6dDFF40881A3e4F86104 + ACLAddress: 0xB4d8d77f7F9B465B60c190480c6160b69d695c9D, + TFHEExecutorAddress: 0xFdee168C46e1dFD082E78192b3C622cA78B58669, + FHEPaymentAddress: 0x2527DD76195fD3BFdd2c76D821e1f5d433d82C25, + KMSVerifierAddress: 0x89842EA0b44EF85391Bd1A9f3AC8B382CCF0d3F1 }); } function getSepoliaConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct memory) { return FHEVMConfig.FHEVMConfigStruct({ - ACLAddress: 0x339EcE85B9E11a3A3AA557582784a15d7F82AAf2, - TFHEExecutorAddress: 0x596E6682c72946AF006B27C131793F2b62527A4b, - FHEPaymentAddress: 0x6d5A11aC509C707c00bc3A0a113ACcC26c532547, - KMSVerifierAddress: 0x208De73316E44722e16f6dDFF40881A3e4F86104 + ACLAddress: 0x9479B455904dCccCf8Bc4f7dF8e9A1105cBa2A8e, + TFHEExecutorAddress: 0x199fB61DFdfE46f9F90C9773769c28D9623Bb90e, + FHEPaymentAddress: 0x25FE5d92Ae6f89AF37D177cF818bF27EDFe37F7c, + KMSVerifierAddress: 0x904Af2B61068f686838bD6257E385C2cE7a09195 }); } diff --git a/config/ZamaGatewayConfig.sol b/config/ZamaGatewayConfig.sol index cc28a34f..9fe7d21a 100644 --- a/config/ZamaGatewayConfig.sol +++ b/config/ZamaGatewayConfig.sol @@ -11,11 +11,11 @@ import {Gateway} from "../gateway/lib/Gateway.sol"; */ library ZamaGatewayConfig { function getMockConfig() internal pure returns (address) { - return 0x096b4679d45fB675d4e2c1E4565009Cec99A12B1; + return 0x2C19507EEAd017495e23a98DB1ff20c7eD599ee1; } function getSepoliaConfig() internal pure returns (address) { - return 0x096b4679d45fB675d4e2c1E4565009Cec99A12B1; + return 0x7455c89669cdE1f7Cb6D026DFB87263422D821ca; } function getEthereumConfig() internal pure returns (address) { diff --git a/deploy/deploy.ts b/deploy/deploy.ts deleted file mode 100644 index 495d8aa8..00000000 --- a/deploy/deploy.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { DeployFunction } from 'hardhat-deploy/types'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer } = await hre.getNamedAccounts(); - const { deploy } = hre.deployments; - - const deployed = await deploy('EncryptedERC20', { - from: deployer, - args: ['Naraggara', 'NARA'], - log: true, - }); - - console.log(`EncryptedERC20 contract: `, deployed.address); -}; -export default func; -func.id = 'deploy_encryptedERC20'; // id required to prevent reexecution -func.tags = ['EncryptedERC20']; diff --git a/examples/ACLUpgradedExample.sol b/examples/ACLUpgradedExample.sol deleted file mode 100644 index 01359f90..00000000 --- a/examples/ACLUpgradedExample.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "fhevm-core-contracts/contracts/ACL.sol"; - -contract ACLUpgradedExample is ACL { - /// @notice Name of the contract - string private constant CONTRACT_NAME = "ACL"; - - /// @notice Version of the contract - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 2; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Getter for the name and version of the contract - /// @return string representing the name and the version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/ACLUpgradedExample2.sol b/examples/ACLUpgradedExample2.sol deleted file mode 100644 index 05cb68ad..00000000 --- a/examples/ACLUpgradedExample2.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "fhevm-core-contracts/contracts/ACL.sol"; - -contract ACLUpgradedExample2 is ACL { - /// @notice Name of the contract - string private constant CONTRACT_NAME = "ACL"; - - /// @notice Version of the contract - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 3; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Getter for the name and version of the contract - /// @return string representing the name and the version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/FHEPaymentUpgradedExample.sol b/examples/FHEPaymentUpgradedExample.sol deleted file mode 100644 index 86a70ed4..00000000 --- a/examples/FHEPaymentUpgradedExample.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "fhevm-core-contracts/contracts/FHEPayment.sol"; - -contract FHEPaymentUpgradedExample is FHEPayment { - /// @notice Name of the contract - string private constant CONTRACT_NAME = "FHEPayment"; - - /// @notice Version of the contract - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 2; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Getter for the name and version of the contract - /// @return string representing the name and the version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/GatewayContractUpgradedExample.sol b/examples/GatewayContractUpgradedExample.sol deleted file mode 100644 index 43c15b6a..00000000 --- a/examples/GatewayContractUpgradedExample.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "../gateway/GatewayContract.sol"; - -contract GatewayContractUpgradedExample is GatewayContract { - /// @notice Name of the contract - string private constant CONTRACT_NAME = "GatewayContract"; - - /// @notice Version of the contract - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 2; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Getter for the name and version of the contract - /// @return string representing the name and the version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/KMSUpgradedExample.sol b/examples/KMSUpgradedExample.sol deleted file mode 100644 index f94d3e05..00000000 --- a/examples/KMSUpgradedExample.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "fhevm-core-contracts/contracts/KMSVerifier.sol"; - -contract KMSVerifierUpgradedExample is KMSVerifier { - /// @notice Name of the contract - string private constant CONTRACT_NAME = "KMSVerifier"; - - /// @notice Version of the contract - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 2; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Getter for the name and version of the contract - /// @return string representing the name and the version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/TFHEExecutorUpgradedExample.sol b/examples/TFHEExecutorUpgradedExample.sol deleted file mode 100644 index cf3a7ee5..00000000 --- a/examples/TFHEExecutorUpgradedExample.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause-Clear - -pragma solidity ^0.8.24; - -import "fhevm-core-contracts/contracts/TFHEExecutor.sol"; - -/// @title TFHEExecutorUpgradedExample -/// @dev Contract that extends TFHEExecutor with version information -contract TFHEExecutorUpgradedExample is TFHEExecutor { - /// @dev Name of the contract - string private constant CONTRACT_NAME = "TFHEExecutor"; - - /// @dev Version numbers - uint256 private constant MAJOR_VERSION = 0; - uint256 private constant MINOR_VERSION = 2; - uint256 private constant PATCH_VERSION = 0; - - /// @notice Returns the full version string of the contract - /// @dev Concatenates the contract name and version numbers - /// @return A string representing the full version of the contract - function getVersion() external pure virtual override returns (string memory) { - return - string( - abi.encodePacked( - CONTRACT_NAME, - " v", - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/examples/legacy/Governor/Comp.sol b/examples/legacy/Governor/Comp.sol deleted file mode 100644 index fe14e7c6..00000000 --- a/examples/legacy/Governor/Comp.sol +++ /dev/null @@ -1,350 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.24; - -import "../../../lib/TFHE.sol"; - -contract Comp { - /// @notice EIP-20 token name for this token - string public constant name = "Compound"; - - /// @notice EIP-20 token symbol for this token - string public constant symbol = "COMP"; - - /// @notice EIP-20 token decimals for this token - uint8 public constant decimals = 18; - - /// @notice Total number of tokens in circulation - euint64 public totalSupply = TFHE.asEuint64(1000000); - - /// @notice owner address - address public contractOwner; - - /// @notice allowed smart contract - address public allowedContract; - - /// @notice Allowance amounts on behalf of others - mapping(address => mapping(address => euint64)) internal allowances; - - /// @notice Official record of token balances for each account - mapping(address => euint64) internal balances; - - /// @notice A record of each accounts delegate - mapping(address => address) public delegates; - - /// @notice A checkpoint for marking number of votes from a given block - struct Checkpoint { - uint32 fromBlock; - euint64 votes; - } - - /// @notice A record of votes checkpoints for each account, by index - mapping(address => mapping(uint32 => Checkpoint)) public checkpoints; - - /// @notice The number of checkpoints for each account - mapping(address => uint32) public numCheckpoints; - - /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); - - /// @notice The EIP-712 typehash for the delegation struct used by the contract - bytes32 public constant DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - /// @notice A record of states for signing / validating signatures - mapping(address => uint) public nonces; - - /// @notice An event thats emitted when an account changes its delegate - event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); - - /// @notice An event thats emitted when a delegate account's vote balance changes - event DelegateVotesChanged(address indexed delegate, euint64 previousBalance, euint64 newBalance); - - /// @notice The standard EIP-20 transfer event - event Transfer(address indexed from, address indexed to, euint64 amount); - - /// @notice The standard EIP-20 approval event - event Approval(address indexed owner, address indexed spender, euint64 amount); - - /** - * @notice Construct a new Comp token - * @param account The initial account to grant all the tokens - */ - constructor(address account) { - contractOwner = account; - balances[contractOwner] = totalSupply; - } - - /** - * @notice Set allowed contract that can access votes - * @param contractAddress The address of the smart contract which may access votes - */ - function setAllowedContract(address contractAddress) public onlyContractOwner { - allowedContract = contractAddress; - } - - // /** - // * @notice Get the number of tokens held by the `account` - // * @return reencrypted The number of tokens held - // */ - // function balanceOf( - // bytes32 publicKey, - // bytes calldata signature - // ) public view onlySignedPublicKey(publicKey, signature) returns (bytes memory) { - // return TFHE.reencrypt(balances[msg.sender], publicKey); - // } - - // /** - // * @notice Get the number of tokens - // * @return reencrypted The number of tokens - // */ - // function getTotalSupply() public view returns (uint64) { - // return TFHE.decrypt(totalSupply); - // } - - /** - * @notice Approve `spender` to transfer up to `amount` from `src` - * @dev This will overwrite the approval amount for `spender` - * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve) - * @param spender The address of the account which may transfer tokens - * @param encryptedAmount The number of tokens that are approved - * @return bool Whether or not the approval succeeded - */ - function approve(address spender, einput encryptedAmount, bytes calldata inputProof) external returns (bool) { - address owner = msg.sender; - _approve(owner, spender, TFHE.asEuint64(encryptedAmount, inputProof)); - return true; - } - - function _approve(address owner, address spender, euint64 amount) internal { - emit Approval(owner, spender, amount); - allowances[owner][spender] = amount; - } - - // /** - // * @notice Get the number of tokens `spender` is approved to spend on behalf of `account` - // * @param spender The address of the account spending the funds - // * @return reencrypted The number of tokens approved - // */ - // function allowance(address spender) public view returns (bytes memory reencrypted) { - // address owner = msg.sender; - // return TFHE.reencrypt(_allowance(owner, spender), 0); - // } - - function _allowance(address owner, address spender) internal view returns (euint64) { - return allowances[owner][spender]; - } - - /** - * @notice Transfer `amount` tokens from `msg.sender` to `dst` - * @param to The address of the destination account - * @param encryptedAmount The number of tokens to transfer - */ - function transfer(address to, einput encryptedAmount, bytes calldata inputProof) public { - transfer(to, TFHE.asEuint64(encryptedAmount, inputProof)); - } - - /** - * @notice Transfer `amount` tokens from `msg.sender` to `dst` - * @param to The address of the destination account - * @param amount The number of tokens to transfer - */ - function transfer(address to, euint64 amount) public { - _transfer(msg.sender, to, amount); - } - - /** - * @notice Transfer `amount` tokens from `src` to `dst` - * @param from The address of the source account - * @param to The address of the destination account - * @param encryptedAmount The number of tokens to transfer - * @return bool Whether or not the transfer succeeded - */ - function transferFrom( - address from, - address to, - einput encryptedAmount, - bytes calldata inputProof - ) public returns (bool) { - transferFrom(from, to, TFHE.asEuint64(encryptedAmount, inputProof)); - return true; - } - - /** - * @notice Transfer `amount` tokens from `src` to `dst` - * @param from The address of the source account - * @param to The address of the destination account - * @param amount The number of tokens to transfer - * @return bool Whether or not the transfer succeeded - */ - function transferFrom(address from, address to, euint64 amount) public returns (bool) { - address spender = msg.sender; - _updateAllowance(from, spender, amount); - _transfer(from, to, amount); - return true; - } - - function _updateAllowance(address owner, address spender, euint64 amount) internal { - euint64 currentAllowance = _allowance(owner, spender); - ebool canApprove = TFHE.le(amount, currentAllowance); - _approve(owner, spender, TFHE.select(canApprove, TFHE.sub(currentAllowance, amount), TFHE.asEuint64(0))); - } - - // Transfers an encrypted amount. - function _transfer(address from, address to, euint64 amount) internal { - // Make sure the sender has enough tokens. - ebool canTransfer = TFHE.le(amount, balances[from]); - - // Add to the balance of `to` and subract from the balance of `from`. - balances[to] = TFHE.add(balances[to], TFHE.select(canTransfer, amount, TFHE.asEuint64(0))); - balances[from] = TFHE.sub(balances[from], TFHE.select(canTransfer, amount, TFHE.asEuint64(0))); - emit Transfer(from, to, amount); - - _moveDelegates(delegates[from], delegates[to], amount); - } - - function _moveDelegates(address srcRep, address dstRep, euint64 amount) internal { - if (srcRep != dstRep) { - if (srcRep != address(0)) { - uint32 srcRepNum = numCheckpoints[srcRep]; - euint64 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : TFHE.asEuint64(0); - euint64 srcRepNew = TFHE.sub(srcRepOld, amount); - _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); - } - - if (dstRep != address(0)) { - uint32 dstRepNum = numCheckpoints[dstRep]; - euint64 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : TFHE.asEuint64(0); - euint64 dstRepNew = TFHE.add(dstRepOld, amount); - _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); - } - } - } - - function _writeCheckpoint(address delegatee, uint32 nCheckpoints, euint64 oldVotes, euint64 newVotes) internal { - uint32 blockNumber = safe32(block.number, "Comp::_writeCheckpoint: block number exceeds 32 bits"); - - if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { - checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; - } else { - checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); - numCheckpoints[delegatee] = nCheckpoints + 1; - } - - emit DelegateVotesChanged(delegatee, oldVotes, newVotes); - } - - /** - * @notice Delegate votes from `msg.sender` to `delegatee` - * @param delegatee The address to delegate votes to - */ - function delegate(address delegatee) public { - return _delegate(msg.sender, delegatee); - } - - /** - * @notice Delegates votes from signatory to `delegatee` - * @param delegatee The address to delegate votes to - * @param nonce The contract state required to match the signature - * @param expiry The time at which to expire the signature - * @param v The recovery byte of the signature - * @param r Half of the ECDSA signature pair - * @param s Half of the ECDSA signature pair - */ - function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public { - bytes32 domainSeparator = keccak256( - abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)) - ); - bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "Comp::delegateBySig: invalid signature"); - require(nonce == nonces[signatory]++, "Comp::delegateBySig: invalid nonce"); - require(block.timestamp <= expiry, "Comp::delegateBySig: signature expired"); - return _delegate(signatory, delegatee); - } - - /** - * @notice Gets the current votes balance for `account` - * @param account The address to get votes balance - * @return The number of current votes for `account` - */ - function getCurrentVotes(address account) external onlyAllowedContract returns (euint64) { - uint32 nCheckpoints = numCheckpoints[account]; - return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : TFHE.asEuint64(0); - } - - /** - * @notice Determine the prior number of votes for an account as of a block number - * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. - * @param account The address of the account to check - * @param blockNumber The block number to get the vote balance at - * @return The number of votes the account had as of the given block - */ - function getPriorVotes(address account, uint blockNumber) public onlyAllowedContract returns (euint64) { - require(blockNumber < block.number, "Comp::getPriorVotes: not yet determined"); - - uint32 nCheckpoints = numCheckpoints[account]; - if (nCheckpoints == 0) { - return TFHE.asEuint64(0); - } - - // First check most recent balance - if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { - return checkpoints[account][nCheckpoints - 1].votes; - } - - // Next check implicit zero balance - if (checkpoints[account][0].fromBlock > blockNumber) { - return TFHE.asEuint64(0); - } - - uint32 lower = 0; - uint32 upper = nCheckpoints - 1; - while (upper > lower) { - uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow - Checkpoint memory cp = checkpoints[account][center]; - if (cp.fromBlock == blockNumber) { - return cp.votes; - } else if (cp.fromBlock < blockNumber) { - lower = center; - } else { - upper = center - 1; - } - } - return checkpoints[account][lower].votes; - } - - function _delegate(address delegator, address delegatee) internal { - address currentDelegate = delegates[delegator]; - euint64 delegatorBalance = balances[delegator]; - delegates[delegator] = delegatee; - - emit DelegateChanged(delegator, currentDelegate, delegatee); - - _moveDelegates(currentDelegate, delegatee, delegatorBalance); - } - - function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { - require(n < 2 ** 32, errorMessage); - return uint32(n); - } - - function getChainId() internal view returns (uint) { - uint256 chainId; - assembly { - chainId := chainid() - } - return chainId; - } - - modifier onlyContractOwner() { - require(msg.sender == contractOwner); - _; - } - - modifier onlyAllowedContract() { - require(msg.sender == allowedContract); - _; - } -} diff --git a/examples/legacy/Governor/GovernorZama.sol b/examples/legacy/Governor/GovernorZama.sol deleted file mode 100644 index b4ed0936..00000000 --- a/examples/legacy/Governor/GovernorZama.sol +++ /dev/null @@ -1,464 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.24; - -import "../../../lib/TFHE.sol"; - -contract GovernorZama { - /// @notice The name of this contract - string public constant name = "Compound Governor Zama"; - - /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed - function quorumVotes() public pure returns (uint) { - return 10000; - // return 400000e18; - } // 400,000 = 4% of Comp - - /// @notice The number of votes required in order for a voter to become a proposer - function proposalThreshold() public pure returns (uint64) { - return 3; - // return 100000e18; - } // 100,000 = 1% of Comp - - /// @notice The maximum number of actions that can be included in a proposal - function proposalMaxOperations() public pure returns (uint32) { - return 10; - } // 10 actions - - /// @notice The delay before voting on a proposal may take place, once proposed - function votingDelay() public pure returns (uint32) { - return 1; - } // 1 block - - /// @notice The duration of voting on a proposal, in blocks - function votingPeriod() public pure virtual returns (uint32) { - return 17280; - } // ~3 days in blocks (assuming 15s blocks) - - /// @notice The address of the Compound Protocol Timelock - TimelockInterface public timelock; - - /// @notice The address of the Compound governance token - CompInterface public comp; - - /// @notice The address of the Governor Guardian - address public guardian; - - /// @notice The total number of proposals - uint public proposalCount; - - struct Proposal { - /// @notice Unique id for looking up a proposal - uint id; - /// @notice Creator of the proposal - address proposer; - /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds - uint eta; - /// @notice the ordered list of target addresses for calls to be made - address[] targets; - /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made - uint[] values; - /// @notice The ordered list of function signatures to be called - string[] signatures; - /// @notice The ordered list of calldata to be passed to each call - bytes[] calldatas; - /// @notice The block at which voting begins: holders must delegate their votes prior to this block - uint startBlock; - /// @notice The block at which voting ends: votes must be cast prior to this block - uint endBlock; - /// @notice Current number of votes in favor of this proposal - euint64 forVotes; - /// @notice Current number of votes in opposition to this proposal - euint64 againstVotes; - /// @notice Flag marking whether the proposal has been canceled - bool canceled; - /// @notice Flag marking whether the proposal has been executed - bool executed; - /// @notice Receipts of ballots for the entire set of voters - mapping(address => Receipt) receipts; - } - - /// @notice Ballot receipt record for a voter - struct Receipt { - /// @notice Whether or not a vote has been cast - bool hasVoted; - /// @notice Whether or not the voter supports the proposal - bool support; - /// @notice The number of votes the voter had, which were cast - euint64 votes; - } - - /// @notice Possible states that a proposal may be in - enum ProposalState { - Pending, - Active, - Canceled, - Defeated, - Succeeded, - Queued, - Expired, - Executed - } - - /// @notice The official record of all proposals ever proposed - mapping(uint => Proposal) public proposals; - - /// @notice The latest proposal for each proposer - mapping(address => uint) public latestProposalIds; - - /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); - - /// @notice The EIP-712 typehash for the ballot struct used by the contract - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,bool support)"); - - /// @notice An event emitted when a new proposal is created - event ProposalCreated( - uint id, - address proposer, - address[] targets, - uint[] values, - string[] signatures, - bytes[] calldatas, - uint startBlock, - uint endBlock, - string description - ); - - /// @notice An event emitted when a vote has been cast on a proposal - event VoteCast(address voter, uint proposalId); - // event VoteCast(address voter, uint proposalId, bool support, uint votes); - - /// @notice An event emitted when a proposal has been canceled - event ProposalCanceled(uint id); - - /// @notice An event emitted when a proposal has been queued in the Timelock - event ProposalQueued(uint id, uint eta); - - /// @notice An event emitted when a proposal has been executed in the Timelock - event ProposalExecuted(uint id); - - constructor(address timelock_, address comp_, address guardian_) { - timelock = TimelockInterface(timelock_); - comp = CompInterface(comp_); - guardian = guardian_; - } - - // function propose( - // address[] memory targets, - // uint[] memory values, - // string[] memory signatures, - // bytes[] memory calldatas, - // uint customVotingPeriod, - // string memory description - // ) public returns (uint) { - // require( - // TFHE.decrypt(TFHE.lt(proposalThreshold(), comp.getPriorVotes(msg.sender, block.number - 1))), - // "GovernorAlpha::propose: proposer votes below proposal threshold" - // ); - // require( - // targets.length == values.length && - // targets.length == signatures.length && - // targets.length == calldatas.length, - // "GovernorAlpha::propose: proposal function information arity mismatch" - // ); - // require(targets.length != 0, "GovernorAlpha::propose: must provide actions"); - // require(targets.length <= proposalMaxOperations(), "GovernorAlpha::propose: too many actions"); - - // uint latestProposalId = latestProposalIds[msg.sender]; - // if (latestProposalId != 0) { - // ProposalState proposersLatestProposalState = state(latestProposalId); - // require( - // proposersLatestProposalState != ProposalState.Active, - // "GovernorAlpha::propose: one live proposal per proposer, found an already active proposal" - // ); - // require( - // proposersLatestProposalState != ProposalState.Pending, - // "GovernorAlpha::propose: one live proposal per proposer, found an already pending proposal" - // ); - // } - - // uint startBlock = add256(block.number, votingDelay()); - // uint endBlock = add256(startBlock, customVotingPeriod != 0 ? customVotingPeriod : votingPeriod()); - - // proposalCount++; - // uint proposalId = proposalCount; - // Proposal storage newProposal = proposals[proposalId]; - // // This should never happen but add a check in case. - // require(newProposal.id == 0, "GovernorAlpha::propose: ProposalID collsion"); - // newProposal.id = proposalId; - // newProposal.proposer = msg.sender; - // newProposal.eta = 0; - // newProposal.targets = targets; - // newProposal.values = values; - // newProposal.signatures = signatures; - // newProposal.forVotes = TFHE.asEuint64(0); - // newProposal.againstVotes = TFHE.asEuint64(0); - // newProposal.calldatas = calldatas; - // newProposal.startBlock = startBlock; - // newProposal.endBlock = endBlock; - // newProposal.canceled = false; - // newProposal.executed = false; - - // latestProposalIds[newProposal.proposer] = newProposal.id; - - // emit ProposalCreated( - // newProposal.id, - // msg.sender, - // targets, - // values, - // signatures, - // calldatas, - // startBlock, - // endBlock, - // description - // ); - // return newProposal.id; - // } - - function queue(uint proposalId) public { - require( - state(proposalId) == ProposalState.Succeeded, - "GovernorAlpha::queue: proposal can only be queued if it is succeeded" - ); - Proposal storage proposal = proposals[proposalId]; - uint eta = add256(block.timestamp, timelock.delay()); - for (uint i = 0; i < proposal.targets.length; i++) { - _queueOrRevert(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta); - } - proposal.eta = eta; - emit ProposalQueued(proposalId, eta); - } - - function _queueOrRevert(address target, uint value, string memory signature, bytes memory data, uint eta) internal { - require( - !timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), - "GovernorAlpha::_queueOrRevert: proposal action already queued at eta" - ); - timelock.queueTransaction(target, value, signature, data, eta); - } - - function execute(uint proposalId) public payable { - require( - state(proposalId) == ProposalState.Queued, - "GovernorAlpha::execute: proposal can only be executed if it is queued" - ); - Proposal storage proposal = proposals[proposalId]; - proposal.executed = true; - for (uint i = 0; i < proposal.targets.length; i++) { - timelock.executeTransaction{value: proposal.values[i]}( - proposal.targets[i], - proposal.values[i], - proposal.signatures[i], - proposal.calldatas[i], - proposal.eta - ); - } - emit ProposalExecuted(proposalId); - } - - // function cancel(uint proposalId) public { - // ProposalState proposalState = state(proposalId); - // require(proposalState != ProposalState.Executed, "GovernorAlpha::cancel: cannot cancel executed proposal"); - - // Proposal storage proposal = proposals[proposalId]; - - // ebool proposerAboveThreshold = TFHE.lt(proposalThreshold(), comp.getPriorVotes(msg.sender, block.number - 1)); - - // require(msg.sender == guardian || TFHE.decrypt(proposerAboveThreshold)); - - // proposal.canceled = true; - // for (uint i = 0; i < proposal.targets.length; i++) { - // timelock.cancelTransaction( - // proposal.targets[i], - // proposal.values[i], - // proposal.signatures[i], - // proposal.calldatas[i], - // proposal.eta - // ); - // } - - // emit ProposalCanceled(proposalId); - // } - - function getActions( - uint proposalId - ) - public - view - returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) - { - Proposal storage p = proposals[proposalId]; - return (p.targets, p.values, p.signatures, p.calldatas); - } - - function getReceipt(uint proposalId, address voter) public view returns (Receipt memory) { - return proposals[proposalId].receipts[voter]; - } - - function isDefeated(Proposal storage proposal) private view returns (bool) { - revert(); - // ebool defeated = TFHE.le(proposal.forVotes, proposal.againstVotes); - // ebool reachedQuorum = TFHE.lt(proposal.forVotes, uint64(quorumVotes())); - - // eturn TFHE.decrypt(reachedQuorum) || TFHE.decrypt(defeated); - } - - function state(uint proposalId) public view returns (ProposalState) { - require(proposalCount >= proposalId && proposalId > 0, "GovernorAlpha::state: invalid proposal id"); - Proposal storage proposal = proposals[proposalId]; - if (proposal.canceled) { - return ProposalState.Canceled; - } else if (block.number <= proposal.startBlock) { - return ProposalState.Pending; - } else if (block.number <= proposal.endBlock) { - return ProposalState.Active; - } - // We can't have this for privacy reasons; otherwise, users could spam-call the `state` view function and deduce individual votes. - // We must then only reveal the defeat/success of a proposal after the time limit has been reached. - // else if ( - // proposal.forVotes <= proposal.againstVotes || - // proposal.forVotes < () - // ) { - // return ProposalState.Defeated; - // } - else if (proposal.eta == 0) { - if (isDefeated(proposal)) { - return ProposalState.Defeated; - } else { - return ProposalState.Succeeded; - } - } else if (proposal.executed) { - return ProposalState.Executed; - } else if (block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD())) { - return ProposalState.Expired; - } else { - return ProposalState.Queued; - } - } - - function castVote(uint proposalId, einput support, bytes calldata inputProof) public { - return castVote(proposalId, TFHE.asEbool(support, inputProof)); - } - - function castVote(uint proposalId, ebool support) public { - return _castVote(msg.sender, proposalId, support); - } - - function castVoteBySig( - uint proposalId, - einput support, - bytes calldata inputProof, - uint8 v, - bytes32 r, - bytes32 s - ) public { - return castVoteBySig(proposalId, TFHE.asEbool(support, inputProof), v, r, s); - } - - function castVoteBySig(uint proposalId, ebool support, uint8 v, bytes32 r, bytes32 s) public { - bytes32 domainSeparator = keccak256( - abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)) - ); - bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "GovernorAlpha::castVoteBySig: invalid signature"); - return _castVote(signatory, proposalId, support); - } - - function _castVote(address voter, uint proposalId, ebool support) internal { - require(state(proposalId) == ProposalState.Active, "GovernorAlpha::_castVote: voting is closed"); - Proposal storage proposal = proposals[proposalId]; - Receipt storage receipt = proposal.receipts[voter]; - require(receipt.hasVoted == false, "GovernorAlpha::_castVote: voter already voted"); - euint64 votes = comp.getPriorVotes(voter, proposal.startBlock); - - proposal.forVotes = TFHE.select(support, TFHE.add(proposal.forVotes, votes), proposal.forVotes); - proposal.againstVotes = TFHE.select(support, proposal.againstVotes, TFHE.add(proposal.againstVotes, votes)); - - receipt.hasVoted = true; - receipt.votes = votes; - - // `support` and `votes` are encrypted values, no need to include them in the event. - // emit VoteCast(voter, proposalId, support, votes); - emit VoteCast(voter, proposalId); - } - - function __acceptAdmin() public { - require(msg.sender == guardian, "GovernorAlpha::__acceptAdmin: sender must be gov guardian"); - timelock.acceptAdmin(); - } - - function __abdicate() public { - require(msg.sender == guardian, "GovernorAlpha::__abdicate: sender must be gov guardian"); - guardian = address(0); - } - - function __queueSetTimelockPendingAdmin(address newPendingAdmin, uint eta) public { - require(msg.sender == guardian, "GovernorAlpha::__queueSetTimelockPendingAdmin: sender must be gov guardian"); - timelock.queueTransaction(address(timelock), 0, "setPendingAdmin(address)", abi.encode(newPendingAdmin), eta); - } - - function __executeSetTimelockPendingAdmin(address newPendingAdmin, uint eta) public { - require(msg.sender == guardian, "GovernorAlpha::__executeSetTimelockPendingAdmin: sender must be gov guardian"); - timelock.executeTransaction(address(timelock), 0, "setPendingAdmin(address)", abi.encode(newPendingAdmin), eta); - } - - function add256(uint256 a, uint256 b) internal pure returns (uint) { - uint c = a + b; - require(c >= a, "addition overflow"); - return c; - } - - function sub256(uint256 a, uint256 b) internal pure returns (uint) { - require(b <= a, "subtraction underflow"); - return a - b; - } - - function getChainId() internal view returns (uint) { - uint chainId; - assembly { - chainId := chainid() - } - return chainId; - } -} - -interface TimelockInterface { - function delay() external view returns (uint); - - function GRACE_PERIOD() external view returns (uint); - - function acceptAdmin() external; - - function queuedTransactions(bytes32 hash) external view returns (bool); - - function queueTransaction( - address target, - uint value, - string calldata signature, - bytes calldata data, - uint eta - ) external returns (bytes32); - - function cancelTransaction( - address target, - uint value, - string calldata signature, - bytes calldata data, - uint eta - ) external; - - function executeTransaction( - address target, - uint value, - string calldata signature, - bytes calldata data, - uint eta - ) external payable returns (bytes memory); -} - -interface CompInterface { - function getPriorVotes(address account, uint blockNumber) external view returns (euint64); -} diff --git a/examples/legacy/Governor/SafeMath.sol b/examples/legacy/Governor/SafeMath.sol deleted file mode 100644 index 569e8e8a..00000000 --- a/examples/legacy/Governor/SafeMath.sol +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; - -// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol -// Subject to the MIT license. - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c; - unchecked { - c = a + b; - } - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - uint256 c; - unchecked { - c = a + b; - } - require(c >= a, errorMessage); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot underflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction underflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot underflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c; - unchecked { - c = a * b; - } - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c; - unchecked { - c = a * b; - } - require(c / a == b, errorMessage); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. - * Reverts on division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. - * Reverts with custom message on division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - // Solidity only automatically asserts when dividing by 0 - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} diff --git a/examples/legacy/Governor/Timelock.sol b/examples/legacy/Governor/Timelock.sol deleted file mode 100644 index 4f043dd7..00000000 --- a/examples/legacy/Governor/Timelock.sol +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; - -import "./SafeMath.sol"; - -contract Timelock { - using SafeMath for uint; - - event NewAdmin(address indexed newAdmin); - event NewPendingAdmin(address indexed newPendingAdmin); - event NewDelay(uint indexed newDelay); - event CancelTransaction( - bytes32 indexed txHash, - address indexed target, - uint value, - string signature, - bytes data, - uint eta - ); - event ExecuteTransaction( - bytes32 indexed txHash, - address indexed target, - uint value, - string signature, - bytes data, - uint eta - ); - event QueueTransaction( - bytes32 indexed txHash, - address indexed target, - uint value, - string signature, - bytes data, - uint eta - ); - - uint public constant GRACE_PERIOD = 14 days; - uint public constant MINIMUM_DELAY = 2 days; - uint public constant MAXIMUM_DELAY = 30 days; - - address public admin; - address public pendingAdmin; - uint public delay; - - mapping(bytes32 => bool) public queuedTransactions; - - constructor(address admin_, uint delay_) { - require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - - admin = admin_; - delay = delay_; - } - - receive() external payable {} - - function setDelay(uint delay_) public { - require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock."); - require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - delay = delay_; - - emit NewDelay(delay); - } - - function acceptAdmin() public { - require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin."); - admin = msg.sender; - pendingAdmin = address(0); - - emit NewAdmin(admin); - } - - function setPendingAdmin(address pendingAdmin_) public { - require( - msg.sender == address(this) || msg.sender == admin, - "Timelock::setPendingAdmin: Call must come from Timelock." - ); - pendingAdmin = pendingAdmin_; - - emit NewPendingAdmin(pendingAdmin); - } - - function queueTransaction( - address target, - uint value, - string memory signature, - bytes memory data, - uint eta - ) public returns (bytes32) { - require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin."); - require( - eta >= getBlockTimestamp().add(delay), - "Timelock::queueTransaction: Estimated execution block must satisfy delay." - ); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = true; - - emit QueueTransaction(txHash, target, value, signature, data, eta); - return txHash; - } - - function cancelTransaction( - address target, - uint value, - string memory signature, - bytes memory data, - uint eta - ) public { - require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = false; - - emit CancelTransaction(txHash, target, value, signature, data, eta); - } - - function executeTransaction( - address target, - uint value, - string memory signature, - bytes memory data, - uint eta - ) public payable returns (bytes memory) { - require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued."); - require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock."); - require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale."); - - queuedTransactions[txHash] = false; - - bytes memory callData; - - if (bytes(signature).length == 0) { - callData = data; - } else { - callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); - } - - // solium-disable-next-line security/no-call-value - (bool success, bytes memory returnData) = target.call{value: value}(callData); - require(success, "Timelock::executeTransaction: Transaction execution reverted."); - - emit ExecuteTransaction(txHash, target, value, signature, data, eta); - - return returnData; - } - - function getBlockTimestamp() internal view returns (uint) { - // solium-disable-next-line security/no-block-members - return block.timestamp; - } -} diff --git a/hardhat.config.ts b/hardhat.config.ts index d0c87671..4936aeb5 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,13 +15,11 @@ import CustomProvider from './CustomProvider'; import './tasks/accounts'; import './tasks/etherscanVerify'; import './tasks/getEthereumAddress'; -import './tasks/mint'; import './tasks/taskDeploy'; import './tasks/taskGatewayRelayer'; import './tasks/taskTFHE'; -import './tasks/upgradeProxy'; -extendProvider(async (provider, config, network) => { +extendProvider(async (provider, _config, _network) => { const newProvider = new CustomProvider(provider); return newProvider; }); @@ -92,7 +90,7 @@ task('coverage').setAction(async (taskArgs, hre, runSuper) => { await runSuper(taskArgs); }); -task('test', async (taskArgs, hre, runSuper) => { +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` diff --git a/launch-fhevm-sepolia.sh b/launch-fhevm-sepolia.sh index c557ce82..f178052d 100755 --- a/launch-fhevm-sepolia.sh +++ b/launch-fhevm-sepolia.sh @@ -7,7 +7,7 @@ NUM_KMS_SIGNERS=$(grep NUM_KMS_SIGNERS .env | cut -d '"' -f 2) rm -rf fhevmTemp/ mkdir -p fhevmTemp -cp -L -r node_modules/fhevm-core-contracts/ fhevmTemp/ +cp -L -r node_modules/fhevm-core-contracts/. fhevmTemp/ npx hardhat compile:specific --contract fhevmTemp npx hardhat compile:specific --contract lib npx hardhat compile:specific --contract gateway diff --git a/lib/FHEVMConfig.sol b/lib/FHEVMConfig.sol index 3c10d9a3..e8791c18 100644 --- a/lib/FHEVMConfig.sol +++ b/lib/FHEVMConfig.sol @@ -1,5 +1,4 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear - pragma solidity ^0.8.24; import "fhevm-core-contracts/addresses/ACLAddress.sol"; @@ -7,6 +6,11 @@ import "fhevm-core-contracts/addresses/FHEPaymentAddress.sol"; import "fhevm-core-contracts/addresses/KMSVerifierAddress.sol"; import "fhevm-core-contracts/addresses/TFHEExecutorAddress.sol"; +/** + * @title FHEVMConfig + * @notice This library returns all addresses for the ACL, TFHEExecutor, FHEPayment, + * and KMSVerifier contracts. + */ library FHEVMConfig { struct FHEVMConfigStruct { address ACLAddress; @@ -14,8 +18,10 @@ library FHEVMConfig { address FHEPaymentAddress; address KMSVerifierAddress; } - - /// @dev Function to return an immutable struct + /** + * @notice This function returns a struct containing all contract addresses. + * @dev It returns an immutable struct. + */ function defaultConfig() internal pure returns (FHEVMConfigStruct memory) { return FHEVMConfigStruct({ diff --git a/lib/Impl.sol b/lib/Impl.sol index cf1183db..48b124c8 100644 --- a/lib/Impl.sol +++ b/lib/Impl.sol @@ -1,10 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear - pragma solidity ^0.8.24; import "./TFHE.sol"; import "./FHEVMConfig.sol"; +/** + * @title ITFHEExecutor + * @notice This interface contains all functions to conduct FHE operations. + */ interface ITFHEExecutor { function fheAdd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result); function fheSub(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result); @@ -44,6 +47,11 @@ interface ITFHEExecutor { function fheRandBounded(uint256 upperBound, bytes1 randType) external returns (uint256 result); } +/** + * @title IACL + * @notice This interface contains all functions that are used to conduct operations + * with the ACL contract. + */ interface IACL { function allowTransient(uint256 ciphertext, address account) external; function allow(uint256 handle, address account) external; @@ -52,8 +60,12 @@ interface IACL { function allowForDecryption(uint256[] memory handlesList) external; } +/** + * @title Impl + * @notice This library is the core implementation for computing FHE operations (e.g. add, sub, xor). + */ library Impl { - // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) + /// @dev keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant FHEVMConfigLocation = 0xed8d60e34876f751cc8b014c560745351147d9de11b9347c854e881b128ea600; function getFHEVMConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct storage $) { diff --git a/lib/TFHE.sol b/lib/TFHE.sol index cf10186c..80e3d5a9 100644 --- a/lib/TFHE.sol +++ b/lib/TFHE.sol @@ -1,5 +1,4 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear - pragma solidity ^0.8.24; import "./Impl.sol"; @@ -19,8 +18,11 @@ type ebytes128 is uint256; type ebytes256 is uint256; type einput is bytes32; +/** + * @title Common + * @notice This library contains all the values used to communicate types to the run time. + */ library Common { - // Values used to communicate types to the runtime. uint8 internal constant ebool_t = 0; uint8 internal constant euint4_t = 1; uint8 internal constant euint8_t = 2; @@ -35,6 +37,11 @@ library Common { uint8 internal constant ebytes256_t = 11; } +/** + * @title TFHE + * @notice This library is the interaction point for all smart contract developers + * that interact with TFHE. + */ library TFHE { function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { Impl.setFHEVM(fhevmConfig); diff --git a/package-lock.json b/package-lock.json index 9ded7e45..35a6cf93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fhevm", - "version": "0.6.0-0", + "version": "0.6.0-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fhevm", - "version": "0.6.0-0", + "version": "0.6.0-1", "license": "BSD-3-Clause-Clear", "dependencies": { "@openzeppelin/contracts": "^5.0.1", @@ -14,8 +14,9 @@ "sqlite3": "^5.1.7" }, "devDependencies": { - "@commitlint/config-conventional": "^18.6.1", - "@commitlint/types": "^18.6.1", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", + "@commitlint/types": "^19.5.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-network-helpers": "^1.0.6", @@ -42,11 +43,12 @@ "eslint-config-prettier": "^8.5.0", "ethers": "^6.8.0", "fhevm-core-contracts": "0.1.0-2", - "fhevmjs": "^0.6.0-4", + "fhevmjs": "^0.6.0-8", "hardhat": "^2.22.10", "hardhat-deploy": "^0.11.29", "hardhat-gas-reporter": "^1.0.2", "hardhat-ignore-warnings": "^0.2.11", + "husky": "^9.1.6", "lodash": "^4.17.21", "mocha": "^10.1.0", "prettier": "^3.0.0", @@ -502,31 +504,482 @@ "node": ">=6.9.0" } }, + "node_modules/@commitlint/cli": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.6.0.tgz", + "integrity": "sha512-v17BgGD9w5KnthaKxXnEg6KLq6DYiAxyiN44TpiRtqyW8NSq+Kx99mkEG8Qo6uu6cI5eMzMojW2muJxjmPnF8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^19.5.0", + "@commitlint/lint": "^19.6.0", + "@commitlint/load": "^19.5.0", + "@commitlint/read": "^19.5.0", + "@commitlint/types": "^19.5.0", + "tinyexec": "^0.3.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@commitlint/cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@commitlint/cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@commitlint/config-conventional": { - "version": "18.6.3", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-18.6.3.tgz", - "integrity": "sha512-8ZrRHqF6je+TRaFoJVwszwnOXb/VeYrPmTwPhf0WxpzpGTcYy1p0SPyZ2eRn/sRi/obnWAcobtDAq6+gJQQNhQ==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.6.0.tgz", + "integrity": "sha512-DJT40iMnTYtBtUfw9ApbsLZFke1zKh6llITVJ+x9mtpHD08gsNXaIRqHTmwTZL3dNX5+WoyK7pCN/5zswvkBCQ==", "dev": true, + "license": "MIT", "dependencies": { - "@commitlint/types": "^18.6.1", + "@commitlint/types": "^19.5.0", "conventional-changelog-conventionalcommits": "^7.0.2" }, "engines": { "node": ">=v18" } }, + "node_modules/@commitlint/config-validator": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.5.0.tgz", + "integrity": "sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@commitlint/ensure": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.5.0.tgz", + "integrity": "sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.5.0.tgz", + "integrity": "sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.5.0.tgz", + "integrity": "sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.6.0.tgz", + "integrity": "sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@commitlint/lint": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.6.0.tgz", + "integrity": "sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^19.6.0", + "@commitlint/parse": "^19.5.0", + "@commitlint/rules": "^19.6.0", + "@commitlint/types": "^19.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.5.0.tgz", + "integrity": "sha512-INOUhkL/qaKqwcTUvCE8iIUf5XHsEPCLY9looJ/ipzi7jtGhgmtH7OOFiNvwYgH7mA8osUWOUDV8t4E2HAi4xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.5.0", + "@commitlint/execute-rule": "^19.5.0", + "@commitlint/resolve-extends": "^19.5.0", + "@commitlint/types": "^19.5.0", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/message": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz", + "integrity": "sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.5.0.tgz", + "integrity": "sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.5.0.tgz", + "integrity": "sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^19.5.0", + "@commitlint/types": "^19.5.0", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^0.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.5.0.tgz", + "integrity": "sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.5.0", + "@commitlint/types": "^19.5.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.6.0.tgz", + "integrity": "sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^19.5.0", + "@commitlint/message": "^19.5.0", + "@commitlint/to-lines": "^19.5.0", + "@commitlint/types": "^19.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.5.0.tgz", + "integrity": "sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.5.0.tgz", + "integrity": "sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@commitlint/types": { - "version": "18.6.1", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-18.6.1.tgz", - "integrity": "sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg==", + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.5.0.tgz", + "integrity": "sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.1.0" + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" }, "engines": { "node": ">=v18" } }, + "node_modules/@commitlint/types/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2792,6 +3245,16 @@ "@types/node": "*" } }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", + "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", @@ -4321,6 +4784,19 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "optional": true }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/conventional-changelog-atom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-4.0.0.tgz", @@ -4342,6 +4818,35 @@ "node": ">=16" } }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commits-parser/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -4357,6 +4862,51 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.1.0.tgz", + "integrity": "sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^1.21.6" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -4431,6 +4981,19 @@ "node": "*" } }, + "node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", @@ -4723,6 +5286,16 @@ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "optional": true }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -5543,20 +6116,20 @@ "dev": true }, "node_modules/fhevmjs": { - "version": "0.6.0-4", - "resolved": "https://registry.npmjs.org/fhevmjs/-/fhevmjs-0.6.0-4.tgz", - "integrity": "sha512-gPnEHnkAwoJivP+K1KtOx7ZeBpZGtQW1QaAVC1zxDtMWQKCcqJMmNQOt0ur/2buw6WE4VfDIIWXneZ1hHCzLHQ==", + "version": "0.6.0-9", + "resolved": "https://registry.npmjs.org/fhevmjs/-/fhevmjs-0.6.0-9.tgz", + "integrity": "sha512-DUGeX0xk/pQC9gG1byljxwEinLADRaWV4tsp0Crk8sbbCTEGTJ1rr3NSxvMPNggGFIwoaOeKT99KueKGaPn2gg==", "dev": true, "dependencies": { "@types/keccak": "^3.0.4", "bigint-buffer": "^1.1.5", "commander": "^11.0.0", "fetch-mock": "^11.1.3", - "node-tfhe": "^0.8.6", - "node-tkms": "^0.9.0-rc11", + "node-tfhe": "^0.9.1", + "node-tkms": "0.9.0-rc27", "sha3": "^2.1.4", - "tfhe": "^0.8.3", - "tkms": "^0.9.0-rc11", + "tfhe": "^0.9.1", + "tkms": "0.9.0-rc27", "url": "^0.11.3", "web3-validator": "^2.0.6" }, @@ -5942,6 +6515,34 @@ "node": ">=4" } }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/git-raw-commits/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -6008,6 +6609,32 @@ "node": "*" } }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -6835,6 +7462,22 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6908,6 +7551,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imul": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", @@ -7009,6 +7663,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7136,6 +7797,19 @@ "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", "dev": true }, + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", @@ -7191,6 +7865,16 @@ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", "dev": true }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -7245,6 +7929,13 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7298,6 +7989,16 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, "node_modules/jsonschema": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", @@ -7307,6 +8008,23 @@ "node": "*" } }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/keccak": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", @@ -7363,6 +8081,13 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7402,18 +8127,67 @@ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "dev": true }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -7522,6 +8296,19 @@ "node": ">= 0.10.0" } }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8078,15 +8865,15 @@ } }, "node_modules/node-tfhe": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/node-tfhe/-/node-tfhe-0.8.6.tgz", - "integrity": "sha512-u9WHiD/vTQ/FIph+52l/jyKzyDh/vLnyw50oSdz0eb1CTs2lqbiA8l8MNxgMkBP1zDadR0qzg37VCt3UkoC2ig==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/node-tfhe/-/node-tfhe-0.9.1.tgz", + "integrity": "sha512-M2CbUVX4DQneaaK/4fygy9lW0zjOOzM8yGWAgbKGRt/Gd07zaloFEGGHW7dbmUaHo022q1uo7nzxyYhe4UgqCw==", "dev": true }, "node_modules/node-tkms": { - "version": "0.9.0-rc3", - "resolved": "https://registry.npmjs.org/node-tkms/-/node-tkms-0.9.0-rc3.tgz", - "integrity": "sha512-Jr3faNAudjBO2Up+Gc3QPF7Dq07fDR/n0NKCHGtS69qLKnoqqaKxGULdKg3gpbtdx0wnj/GaQjvprUIgnIm7yQ==", + "version": "0.9.0-rc27", + "resolved": "https://registry.npmjs.org/node-tkms/-/node-tkms-0.9.0-rc27.tgz", + "integrity": "sha512-lRCgH5pHewK5IRkczX1zpDpU0BidGHKDtaN812Yh9fhR97aqKVDWdSidQrOqX7RSstDkHeJ1dDyN6fx2wkQ+4Q==", "dev": true }, "node_modules/nofilter": { @@ -8294,6 +9081,25 @@ "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10240,6 +11046,19 @@ "node": ">=10" } }, + "node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10247,9 +11066,9 @@ "dev": true }, "node_modules/tfhe": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tfhe/-/tfhe-0.8.4.tgz", - "integrity": "sha512-PUXfFo2iIZn3XRTyYaCGomDBz7ImPLS3qYoctYeIsUF8kKdx2yXZ+Uz7rJ/D6vRS630rZRR/NNSzGLpPKeSjfA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/tfhe/-/tfhe-0.9.1.tgz", + "integrity": "sha512-kmtl7KfCCZJaFhm9lUYsTtat+yT0qzOiO6bOidM2Pt7/7jptkbS2/myeGHxb9qi2/aJ30g2joo1euKZPa207tg==", "dev": true }, "node_modules/then-request": { @@ -10294,6 +11113,13 @@ "node": ">= 0.12" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, "node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", @@ -10304,10 +11130,17 @@ "readable-stream": "3" } }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "dev": true, + "license": "MIT" + }, "node_modules/tkms": { - "version": "0.9.0-rc3", - "resolved": "https://registry.npmjs.org/tkms/-/tkms-0.9.0-rc3.tgz", - "integrity": "sha512-7ynaHiFnXS9Xok62vsi2GGeTUxmb1Ao7I5k9akE8lEQ5M9FERmaGLF3TapDLGsYMDz7Km7dFeTfrsjCg38OC/w==", + "version": "0.9.0-rc27", + "resolved": "https://registry.npmjs.org/tkms/-/tkms-0.9.0-rc27.tgz", + "integrity": "sha512-sSO1jb4/gw0FjS+AubW35/KnJfx1qBp2EuIb0gLg7247DS2VlsBh2iNlBtHKKBevhkgfvjdOt0YZT1J0y9Bv/Q==", "dev": true }, "node_modules/tmp": { @@ -10820,6 +11653,19 @@ "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", "dev": true }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", diff --git a/package.json b/package.json index 43066912..02398737 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fhevm", "description": "A Solidity library for interacting with the Zama Blockchain", - "version": "0.6.0-0", + "version": "0.6.0-1", "engines": { "node": ">=20.0.0" }, @@ -16,6 +16,7 @@ "deploy:contracts": "hardhat deploy", "lint": "npm run lint:sol && npm run lint:ts && npm run prettier:check", "lint:ts": "eslint --ignore-path ./.eslintignore --ext .js,.ts .", + "prepare": "husky install", "prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yml}\"", "prettier": "prettier --write \"**/*.{js,json,md,sol,ts,yml}\"", "test:inband": "hardhat test", @@ -43,8 +44,9 @@ }, "homepage": "https://github.com/zama-ai/fhevm#readme", "devDependencies": { - "@commitlint/config-conventional": "^18.6.1", - "@commitlint/types": "^18.6.1", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", + "@commitlint/types": "^19.5.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-network-helpers": "^1.0.6", @@ -70,12 +72,13 @@ "eslint": "^8.28.0", "eslint-config-prettier": "^8.5.0", "ethers": "^6.8.0", - "fhevmjs": "^0.6.0-4", + "fhevmjs": "^0.6.0-8", "fhevm-core-contracts": "0.1.0-2", "hardhat": "^2.22.10", "hardhat-deploy": "^0.11.29", "hardhat-gas-reporter": "^1.0.2", "hardhat-ignore-warnings": "^0.2.11", + "husky": "^9.1.6", "lodash": "^4.17.21", "mocha": "^10.1.0", "prettier": "^3.0.0", diff --git a/remappings.txt b/remappings.txt deleted file mode 100644 index 038a557a..00000000 --- a/remappings.txt +++ /dev/null @@ -1 +0,0 @@ -lib/TFHE=mocks/TFHE \ No newline at end of file diff --git a/scripts/deploy.ts b/scripts/deploy.ts deleted file mode 100644 index e196972d..00000000 --- a/scripts/deploy.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ethers } from 'hardhat'; - -async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const unlockTime = currentTimestampInSeconds + 60; - - const lockedAmount = ethers.parseEther('0.001'); - - const lock = await ethers.deployContract('Lock', [unlockTime], { - value: lockedAmount, - }); - - await lock.waitForDeployment(); - - console.log( - `Lock with ${ethers.formatEther(lockedAmount)}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}`, - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/faucet.sh b/scripts/faucet.sh deleted file mode 100755 index bc06af3e..00000000 --- a/scripts/faucet.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Alice -npm run fhevm:faucet -sleep 8 -npm run fhevm:faucet:bob -sleep 8 -npm run fhevm:faucet:carol - - diff --git a/tasks/mint.ts b/tasks/mint.ts deleted file mode 100644 index 862376c6..00000000 --- a/tasks/mint.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { task } from 'hardhat/config'; -import type { TaskArguments } from 'hardhat/types'; - -task('task:deployERC20').setAction(async function (taskArguments: TaskArguments, { ethers }) { - const signers = await ethers.getSigners(); - const erc20Factory = await ethers.getContractFactory('EncryptedERC20'); - const encryptedERC20 = await erc20Factory.connect(signers[0]).deploy('Naraggara', 'NARA'); - await encryptedERC20.waitForDeployment(); - console.log('EncryptedERC20 deployed to: ', await encryptedERC20.getAddress()); -}); - -task('task:mint') - .addParam('mint', 'Tokens to mint') - .setAction(async function (taskArguments: TaskArguments, hre) { - const { ethers, deployments } = hre; - const EncryptedERC20 = await deployments.get('EncryptedERC20'); - - const signers = await ethers.getSigners(); - - const encryptedERC20 = (await ethers.getContractAt('EncryptedERC20', EncryptedERC20.address)) as any; - - await encryptedERC20.connect(signers[0]).mint(+taskArguments.mint); - - console.log('Mint done: ', taskArguments.mint); - }); diff --git a/tasks/taskDeploy.ts b/tasks/taskDeploy.ts index af4bb36b..295a64e7 100644 --- a/tasks/taskDeploy.ts +++ b/tasks/taskDeploy.ts @@ -3,6 +3,8 @@ import fs from 'fs'; import { task, types } from 'hardhat/config'; import type { TaskArguments } from 'hardhat/types'; +import { KMSVerifier } from '../types'; + task('task:deployGateway') .addParam('privateKey', 'The deployer private key') .addParam('ownerAddress', 'The owner address') @@ -134,12 +136,21 @@ task('task:addSigners') false, types.boolean, ) + .addOptionalParam( + 'customKmsVerifierAddress', + 'Use a custom address for the KMSVerifier contract instead of the default one - ie stored inside .env.kmsverifier', + ) .setAction(async function (taskArguments: TaskArguments, { ethers }) { const deployer = new ethers.Wallet(taskArguments.privateKey).connect(ethers.provider); const factory = await ethers.getContractFactory('fhevmTemp/contracts/KMSVerifier.sol:KMSVerifier', deployer); - const kmsAdd = dotenv.parse( - fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.kmsverifier'), - ).KMS_VERIFIER_CONTRACT_ADDRESS; + let kmsAdd; + if (taskArguments.customKmsVerifierAddress) { + kmsAdd = taskArguments.customKmsVerifierAddress; + } else { + kmsAdd = dotenv.parse( + fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.kmsverifier'), + ).KMS_VERIFIER_CONTRACT_ADDRESS; + } const kmsVerifier = await factory.attach(kmsAdd); for (let idx = 0; idx < taskArguments.numSigners; idx++) { if (!taskArguments.useAddress) { @@ -156,3 +167,47 @@ task('task:addSigners') } } }); + +task('task:getAllSigners') + .addOptionalParam( + 'customKmsVerifierAddress', + 'Use a custom address for the KMSVerifier contract instead of the default one - ie stored inside .env.kmsverifier', + ) + .setAction(async function (taskArguments: TaskArguments, { ethers }) { + const factory = await ethers.getContractFactory('fhevmTemp/contracts/KMSVerifier.sol:KMSVerifier'); + let kmsAdd; + if (taskArguments.customKmsVerifierAddress) { + kmsAdd = taskArguments.customKmsVerifierAddress; + } else { + kmsAdd = dotenv.parse( + fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.kmsverifier'), + ).KMS_VERIFIER_CONTRACT_ADDRESS; + } + const kmsVerifier = (await factory.attach(kmsAdd).connect(ethers.provider)) as KMSVerifier; + const listCurrentKMSSigners = await kmsVerifier.getSigners(); + console.log('The list of current KMS Signers stored inside KMSVerifier contract is: ', listCurrentKMSSigners); + }); + +task('task:removeSigner') + .addParam('privateKey', 'The KMSVerifier owner private key') + .addParam('kmsSignerAddress', 'The KMS Signer address you wish to remove') + .addOptionalParam( + 'customKmsVerifierAddress', + 'Use a custom address for the KMSVerifier contract instead of the default one - ie stored inside .env.kmsverifier', + ) + .setAction(async function (taskArguments: TaskArguments, { ethers }) { + const deployer = new ethers.Wallet(taskArguments.privateKey).connect(ethers.provider); + const factory = await ethers.getContractFactory('fhevmTemp/contracts/KMSVerifier.sol:KMSVerifier', deployer); + let kmsAdd; + if (taskArguments.customKmsVerifierAddress) { + kmsAdd = taskArguments.customKmsVerifierAddress; + } else { + kmsAdd = dotenv.parse( + fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.kmsverifier'), + ).KMS_VERIFIER_CONTRACT_ADDRESS; + } + const kmsVerifier = (await factory.attach(kmsAdd)) as KMSVerifier; + const tx = await kmsVerifier.removeSigner(taskArguments.kmsSignerAddress); + await tx.wait(); + console.log(`KMS signer with address (${taskArguments.kmsSignerAddress}) was removed from KMSVerifier contract`); + }); diff --git a/tasks/upgradeProxy.ts b/tasks/upgradeProxy.ts deleted file mode 100644 index 4fefaf8f..00000000 --- a/tasks/upgradeProxy.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { HardhatEthersHelpers } from '@nomicfoundation/hardhat-ethers/types'; -import { HardhatUpgrades } from '@openzeppelin/hardhat-upgrades'; -import dotenv from 'dotenv'; -import fs from 'fs'; -import { task, types } from 'hardhat/config'; -import type { RunTaskFunction, TaskArguments } from 'hardhat/types'; - -function stripContractName(input: string): string { - const colonIndex = input.lastIndexOf('/'); - if (colonIndex !== -1) { - return input.substring(0, colonIndex); - } - return input; -} - -async function upgradeCurrentToNew( - privateKey: string, - proxyAddress: string, - currentImplem: string, - newImplem: string, - verifyContract: boolean, - upgrades: HardhatUpgrades, - run: RunTaskFunction, - ethers: any, -) { - const deployer = new ethers.Wallet(privateKey).connect(ethers.provider); - await run('compile:specific', { contract: stripContractName(currentImplem) }); - await run('compile:specific', { contract: stripContractName(newImplem) }); - const currentImplementation = await ethers.getContractFactory(currentImplem, deployer); - const proxy = await upgrades.forceImport(proxyAddress, currentImplementation); - const newImplementationFactory = await ethers.getContractFactory(newImplem, deployer); - await upgrades.upgradeProxy(proxy, newImplementationFactory); - if (verifyContract) { - console.log('Waiting 2 minutes before contract verification... Please wait...'); - await new Promise((resolve) => setTimeout(resolve, 2 * 60 * 1000)); - const implementationACLAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); - await run('verify:verify', { - address: implementationACLAddress, - constructorArguments: [], - }); - } -} - -task('task:upgradeACL') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: lib/ACL.sol:ACL', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: examples/ACLUpgradedExample.sol:ACLUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.acl')); - const proxyAddress = parsedEnv.ACL_CONTRACT_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); - -task('task:upgradeTFHEExecutor') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: lib/TFHEExecutor.sol:TFHEExecutor', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: examples/TFHEExecutorUpgradedExample.sol:TFHEExecutorUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.exec')); - const proxyAddress = parsedEnv.TFHE_EXECUTOR_CONTRACT_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); - -task('task:upgradeKMSVerifier') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: lib/KMSVerifier.sol:KMSVerifier', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: examples/KMSVerifierUpgradedExample.sol:KMSVerifierUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.kmsverifier')); - const proxyAddress = parsedEnv.KMS_VERIFIER_CONTRACT_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); - -task('task:upgradeInputVerifier') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: lib/InputVerifier.coprocessor.sol:InputVerifier', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: examples/InputVerifierUpgradedExample.coprocessor.sol:InputVerifierUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.inputverifier')); - const proxyAddress = parsedEnv.INPUT_VERIFIER_CONTRACT_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); - -task('task:upgradeFHEPayment') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: lib/FHEPayment.sol:FHEPayment', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: examples/FHEPaymentUpgradedExample.sol:FHEPaymentUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.fhepayment')); - const proxyAddress = parsedEnv.FHE_PAYMENT_CONTRACT_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); - -task('task:upgradeGatewayContract') - .addParam( - 'currentImplementation', - 'The currently deployed implementation solidity contract path and name, eg: gateway/GatewayContract.sol:GatewayContract', - ) - .addParam( - 'newImplementation', - 'The new implementation solidity contract path and name, eg: example/GatewayContractUpgradedExample.sol:GatewayContractUpgradedExample', - ) - .addParam('privateKey', 'The deployer private key') - .addOptionalParam( - 'verifyContract', - 'Verify new implementation on Etherscan (for eg if deploying on Sepolia or Mainnet)', - false, - types.boolean, - ) - .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades, run }) { - const parsedEnv = dotenv.parse(fs.readFileSync('gateway/.env.gateway')); - const proxyAddress = parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS; - await upgradeCurrentToNew( - taskArguments.privateKey, - proxyAddress, - taskArguments.currentImplementation, - taskArguments.newImplementation, - taskArguments.verifyContract, - upgrades, - run, - ethers, - ); - }); diff --git a/test.ts b/test.ts deleted file mode 100644 index 1a074dfe..00000000 --- a/test.ts +++ /dev/null @@ -1,5 +0,0 @@ -const numShards = 30; -const numSplits = 11; - -const size = Math.floor(numShards / numSplits); -console.log(size); diff --git a/test/asyncDecrypt.ts b/test/asyncDecrypt.ts index 8cf14b6f..092a01f2 100644 --- a/test/asyncDecrypt.ts +++ b/test/asyncDecrypt.ts @@ -58,16 +58,16 @@ export const initGateway = async (): Promise => { } // this function will emit logs for every request and fulfilment of a decryption gateway = await ethers.getContractAt('GatewayContract', parsedEnv.GATEWAY_CONTRACT_PREDEPLOY_ADDRESS); - gateway.on( + await 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) => { + await 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})`); }); }; diff --git a/test/fhevmjsMocked.ts b/test/fhevmjsMocked.ts index 6f827983..779b8849 100644 --- a/test/fhevmjsMocked.ts +++ b/test/fhevmjsMocked.ts @@ -4,14 +4,13 @@ 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 { insertSQL } from './coprocessorUtils'; import { awaitCoprocessor, getClearText } from './coprocessorUtils'; -const hre = require('hardhat'); - const parsedEnvACL = dotenv.parse(fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.acl')); const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS; @@ -361,7 +360,7 @@ function uint8ArrayToHexString(uint8Array: Uint8Array) { } function numberToHex(num: number) { - let hex = num.toString(16); + const hex = num.toString(16); return hex.length % 2 ? '0' + hex : hex; } diff --git a/test/fhevmjsTest/fhevmjsTest.ts b/test/fhevmjsTest/fhevmjsTest.ts index cfb76cb2..a01b648e 100644 --- a/test/fhevmjsTest/fhevmjsTest.ts +++ b/test/fhevmjsTest/fhevmjsTest.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { createInstances } from '../instance'; import { getSigners, initSigners } from '../signers'; -import { bigIntToBytes64, bigIntToBytes128, bigIntToBytes256 } from '../utils'; +import { bigIntToBytes64, bigIntToBytes128 } from '../utils'; describe('Testing fhevmjs/fhevmjsMocked', function () { before(async function () { diff --git a/test/gatewayDecrypt/testAsyncDecrypt.ts b/test/gatewayDecrypt/testAsyncDecrypt.ts index ece79f50..99b0c99f 100644 --- a/test/gatewayDecrypt/testAsyncDecrypt.ts +++ b/test/gatewayDecrypt/testAsyncDecrypt.ts @@ -11,18 +11,7 @@ describe('TestAsyncDecrypt', function () { await initSigners(2); this.signers = await getSigners(); this.relayerAddress = '0x97F272ccfef4026A1F3f0e0E879d514627B84E69'; - - // very first request of decryption always fail at the moment due to a gateway bug - // TODO: remove following 8 lines when the gateway bug will be fixed - const contractFactory = await ethers.getContractFactory('TestAsyncDecrypt'); - this.contract = await contractFactory.connect(this.signers.alice).deploy(); - await this.contract.waitForDeployment(); - this.contractAddress = await this.contract.getAddress(); this.instances = await createInstances(this.signers); - const tx = await this.contract.connect(this.signers.carol).requestUint8({ gasLimit: 5_000_000 }); - await tx.wait(); // this first request is here just to silence the current gateway bug at the moment - await waitNBlocks(1); - await initGateway(); }); @@ -337,7 +326,7 @@ describe('TestAsyncDecrypt', function () { const tx2 = await this.contract.connect(this.signers.carol).requestMixed(5, 15, { gasLimit: 5_000_000 }); 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); @@ -345,7 +334,7 @@ describe('TestAsyncDecrypt', function () { expect(y).to.equal(42); y = await this.contract.yUint16(); expect(y).to.equal(16); - let yAdd = await this.contract.yAddress(); + const yAdd = await this.contract.yAddress(); expect(yAdd).to.equal('0x8ba1f109551bD432803012645Ac136ddd64DBA72'); y = await this.contract.yUint32(); expect(y).to.equal(52); // 5+15+32 diff --git a/test/governor/Comp.fixture.ts b/test/governor/Comp.fixture.ts deleted file mode 100644 index 89c3f401..00000000 --- a/test/governor/Comp.fixture.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ethers } from 'hardhat'; - -import type { Comp } from '../../types'; -import { getSigners } from '../signers'; - -export async function deployCompFixture(): Promise { - const signers = await getSigners(); - - const contractFactory = await ethers.getContractFactory('Comp'); - const contract = await contractFactory.connect(signers.alice).deploy(signers.alice.address); - await contract.waitForDeployment(); - - return contract; -} diff --git a/test/governor/Comp.ts b/test/governor/Comp.ts deleted file mode 100644 index 247aacbb..00000000 --- a/test/governor/Comp.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { expect } from 'chai'; -import { ethers } from 'hardhat'; - -import { createInstances } from '../instance'; -import { getSigners, initSigners } from '../signers'; -import { deployCompFixture } from './Comp.fixture'; - -describe.skip('Comp', function () { - before(async function () { - await initSigners(2); - this.signers = await getSigners(); - }); - - beforeEach(async function () { - const contract = await deployCompFixture(); - this.contractAddress = await contract.getAddress(); - this.comp = contract; - this.instances = await createInstances(this.contractAddress, ethers, this.signers); - }); - - it('should transfer tokens', async function () { - const encryptedAmountToTransfer = this.instances.alice.encrypt64(200000); - const transferTransac = await this.comp['transfer(address,bytes)']( - this.signers.bob.address, - encryptedAmountToTransfer, - ); - - await transferTransac.wait(); - - const aliceToken = this.instances.alice.getPublicKey(this.contractAddress) || { - signature: '', - publicKey: '', - }; - const encryptedAliceBalance = await this.comp.balanceOf(aliceToken.publicKey, aliceToken.signature); - // Decrypt Alice's balance - const aliceBalance = this.instances.alice.decrypt(this.contractAddress, encryptedAliceBalance); - expect(aliceBalance).to.equal(800000); - - const bobToken = this.instances.bob.getPublicKey(this.contractAddress) || { - signature: '', - publicKey: '', - }; - const encryptedBobBalance = await this.comp - .connect(this.signers.bob) - .balanceOf(bobToken.publicKey, bobToken.signature); - // Decrypt Bob's balance - const bobBalance = this.instances.bob.decrypt(this.contractAddress, encryptedBobBalance); - expect(bobBalance).to.equal(200000); - }); -}); diff --git a/test/governor/GovernorZama.fixture.ts b/test/governor/GovernorZama.fixture.ts deleted file mode 100644 index cbee601c..00000000 --- a/test/governor/GovernorZama.fixture.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ethers } from 'hardhat'; - -import { Comp } from '../../types'; -import type { GovernorZama, Timelock } from '../../types'; -import { getSigners } from '../signers'; - -export async function deployTimelockFixture(): Promise { - const signers = await getSigners(); - - const timelockFactory = await ethers.getContractFactory('Timelock'); - const timelock = await timelockFactory.connect(signers.alice).deploy(signers.alice.address, 60 * 60 * 24 * 2); - - await timelock.waitForDeployment(); - - return timelock; -} - -export async function deployGovernorZamaFixture(compContract: Comp, timelock: Timelock): Promise { - const signers = await getSigners(); - - const governorFactory = await ethers.getContractFactory('GovernorZama'); - const governor = await governorFactory - .connect(signers.alice) - .deploy(timelock.getAddress(), compContract.getAddress(), signers.alice.address); - await governor.waitForDeployment(); - - return governor; -} diff --git a/test/governor/GovernorZama.ts b/test/governor/GovernorZama.ts deleted file mode 100644 index 632463d3..00000000 --- a/test/governor/GovernorZama.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { expect } from 'chai'; -import { ethers, network } from 'hardhat'; - -import { createInstances } from '../instance'; -import { getSigners, initSigners } from '../signers'; -import { createTransaction, mineNBlocks, produceDummyTransactions, waitForBlock } from '../utils'; -import { deployCompFixture } from './Comp.fixture'; -import { deployGovernorZamaFixture, deployTimelockFixture } from './GovernorZama.fixture'; - -describe.skip('GovernorZama', function () { - before(async function () { - await initSigners(3); - this.signers = await getSigners(); - this.comp = await deployCompFixture(); - - const instances = await createInstances(await this.comp.getAddress(), ethers, this.signers); - const encryptedAmountToTransfer = instances.alice.encrypt64(100000); - const transfer1 = await this.comp['transfer(address,bytes)'](this.signers.bob.address, encryptedAmountToTransfer); - const transfer2 = await this.comp['transfer(address,bytes)'](this.signers.carol.address, encryptedAmountToTransfer); - await Promise.all([transfer1.wait(), transfer2.wait()]); - - const delegate1 = await this.comp.delegate(this.signers.alice); - const delegate2 = await this.comp.connect(this.signers.bob).delegate(this.signers.bob); - const delegate3 = await this.comp.connect(this.signers.carol).delegate(this.signers.carol); - await Promise.all([delegate1, delegate2, delegate3]); - if (network.name == 'localNetwork1' || network.name == 'hardhat') { - // inside network1 or hardhat blocks are not - // produced unless there are transactions and - // we rely on block production for voting time - produceDummyTransactions(100); - } - }); - - beforeEach(async function () { - const timelock = await deployTimelockFixture(); - - const governor = await deployGovernorZamaFixture(this.comp, timelock); - this.contractAddress = await governor.getAddress(); - this.governor = governor; - this.instances = await createInstances(this.contractAddress, ethers, this.signers); - - const tx1 = await timelock.setPendingAdmin(governor.getAddress()); - await tx1.wait(); - - const transaction = await this.comp.setAllowedContract(this.contractAddress); - const transaction2 = await this.governor.__acceptAdmin(); - - await Promise.all([transaction.wait(), transaction2.wait()]); - }); - - it('should propose a vote', async function () { - const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])]; - const tx = await createTransaction( - this.governor.propose, - [this.signers.alice], - ['0'], - ['getBalanceOf(address)'], - callDatas, - 0, - 'do nothing', - ); - const proposal = await tx.wait(); - expect(proposal?.status).to.equal(1); - const proposalId = await this.governor.latestProposalIds(this.signers.alice.address); - const proposals = await this.governor.proposals(proposalId); - expect(proposals.id).to.equal(proposalId); - expect(proposals.proposer).to.equal(this.signers.alice.address); - }); - - it('should vote and return a Succeed', async function () { - const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])]; - const tx = await createTransaction( - this.governor.propose, - [this.signers.alice], - ['0'], - ['getBalanceOf(address)'], - callDatas, - 5, - 'do nothing', - ); - const proposal = await tx.wait(); - expect(proposal?.status).to.equal(1); - - const proposalId = await this.governor.latestProposalIds(this.signers.alice.address); - const proposals = await this.governor.proposals(proposalId); - if (network.name == 'hardhat') { - await mineNBlocks(2); - } - await waitForBlock(proposals.startBlock + 1n); - // Cast some votes - const encryptedSupportBob = this.instances.bob.encryptBool(true); - const txVoteBob = await createTransaction( - this.governor.connect(this.signers.bob)['castVote(uint256,bytes)'], - proposalId, - encryptedSupportBob, - ); - - const encryptedSupportCarol = this.instances.carol.encryptBool(true); - const txVoteCarol = await createTransaction( - this.governor.connect(this.signers.carol)['castVote(uint256,bytes)'], - proposalId, - encryptedSupportCarol, - ); - - const [bobResults, carolResults] = await Promise.all([txVoteBob.wait(), txVoteCarol.wait()]); - expect(bobResults?.status).to.equal(1); - expect(carolResults?.status).to.equal(1); - if (network.name == 'hardhat') { - await mineNBlocks(5); - } - await waitForBlock(proposals.endBlock + 1n); - - const state = await this.governor.state(proposalId); - expect(state).to.equal(4n); - }); - - it('should vote and return a Defeated ', async function () { - const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])]; - const tx = await createTransaction( - this.governor.propose, - [this.signers.alice], - ['0'], - ['getBalanceOf(address)'], - callDatas, - 4, - 'do nothing', - ); - const proposal = await tx.wait(); - expect(proposal?.status).to.equal(1); - const proposalId = await this.governor.latestProposalIds(this.signers.alice.address); - const proposals = await this.governor.proposals(proposalId); - if (network.name == 'hardhat') { - await mineNBlocks(2); - } - await waitForBlock(proposals.startBlock + 1n); - - // Cast some votes - const encryptedSupportBob = this.instances.bob.encryptBool(false); - const txVoteBob = await createTransaction( - this.governor.connect(this.signers.bob)['castVote(uint256,bytes)'], - proposalId, - encryptedSupportBob, - ); - - const encryptedSupportCarol = this.instances.carol.encryptBool(true); - const txVoteCarol = await createTransaction( - this.governor.connect(this.signers.carol)['castVote(uint256,bytes)'], - proposalId, - encryptedSupportCarol, - ); - - const [bobResults, aliceResults] = await Promise.all([txVoteBob.wait(), txVoteCarol.wait()]); - expect(bobResults?.status).to.equal(1); - expect(aliceResults?.status).to.equal(1); - if (network.name == 'hardhat') { - await mineNBlocks(5); - } - await waitForBlock(proposals.endBlock + 1n); - - const state = await this.governor.state(proposalId); - expect(state).to.equal(3n); - }); - - it('should cancel', async function () { - await this.comp.delegate(this.signers.alice.address); - const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])]; - const tx = await createTransaction( - this.governor.propose, - [this.signers.alice], - ['0'], - ['getBalanceOf(address)'], - callDatas, - 0, - 'do nothing', - ); - const proposal = await tx.wait(); - expect(proposal?.status).to.equal(1); - const proposalId = await this.governor.latestProposalIds(this.signers.alice.address); - const proposals = await this.governor.proposals(proposalId); - if (network.name == 'hardhat') { - await mineNBlocks(2); - } - await waitForBlock(proposals.startBlock + 1n); - - const state = await this.governor.state(proposalId); - expect(state).to.equal(1n); - - const txCancel = await this.governor.cancel(proposalId); - await txCancel.wait(); - const newState = await this.governor.state(proposalId); - expect(newState).to.equal(2n); - }); -}); diff --git a/test/reencryption/reencryption.ts b/test/reencryption/reencryption.ts index 01b6d96f..74c3c5ba 100644 --- a/test/reencryption/reencryption.ts +++ b/test/reencryption/reencryption.ts @@ -1,9 +1,8 @@ import { expect } from 'chai'; -import { ethers, network } from 'hardhat'; +import { ethers } from 'hardhat'; import { createInstances } from '../instance'; import { getSigners, initSigners } from '../signers'; -import { bigIntToBytes256 } from '../utils'; describe('Reencryption', function () { before(async function () { diff --git a/test/tfheOperations/tfheOperations1.ts b/test/tfheOperations/tfheOperations1.ts index 82012291..cc4538f2 100644 --- a/test/tfheOperations/tfheOperations1.ts +++ b/test/tfheOperations/tfheOperations1.ts @@ -20,7 +20,6 @@ import { decrypt32, decrypt64, decrypt128, - decrypt256, decryptBool, } from '../instance'; import { getSigners, initSigners } from '../signers'; diff --git a/test/tfheOperations/tfheOperations10.ts b/test/tfheOperations/tfheOperations10.ts index fa223d0d..7da17e11 100644 --- a/test/tfheOperations/tfheOperations10.ts +++ b/test/tfheOperations/tfheOperations10.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt128, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations11.ts b/test/tfheOperations/tfheOperations11.ts index 74694fec..e712b2ea 100644 --- a/test/tfheOperations/tfheOperations11.ts +++ b/test/tfheOperations/tfheOperations11.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations13.ts b/test/tfheOperations/tfheOperations13.ts index db18a0e6..830ee0a9 100644 --- a/test/tfheOperations/tfheOperations13.ts +++ b/test/tfheOperations/tfheOperations13.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt256 } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations2.ts b/test/tfheOperations/tfheOperations2.ts index 93245365..4aa7d936 100644 --- a/test/tfheOperations/tfheOperations2.ts +++ b/test/tfheOperations/tfheOperations2.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt4, decrypt8, decrypt16, decrypt128, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations3.ts b/test/tfheOperations/tfheOperations3.ts index 33df958e..6181e084 100644 --- a/test/tfheOperations/tfheOperations3.ts +++ b/test/tfheOperations/tfheOperations3.ts @@ -14,7 +14,6 @@ import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite1 import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; import { createInstances, - decrypt4, decrypt8, decrypt16, decrypt32, diff --git a/test/tfheOperations/tfheOperations4.ts b/test/tfheOperations/tfheOperations4.ts index 6dbd34d9..c027f1d9 100644 --- a/test/tfheOperations/tfheOperations4.ts +++ b/test/tfheOperations/tfheOperations4.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt8, decrypt16, decrypt32, decrypt64, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations5.ts b/test/tfheOperations/tfheOperations5.ts index 8bdaf504..a9efee3e 100644 --- a/test/tfheOperations/tfheOperations5.ts +++ b/test/tfheOperations/tfheOperations5.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt16, decrypt32, decrypt64, decrypt128, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations6.ts b/test/tfheOperations/tfheOperations6.ts index 08d806b1..567d950b 100644 --- a/test/tfheOperations/tfheOperations6.ts +++ b/test/tfheOperations/tfheOperations6.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt32, decrypt64, decrypt128, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations7.ts b/test/tfheOperations/tfheOperations7.ts index 078e9d2d..36520112 100644 --- a/test/tfheOperations/tfheOperations7.ts +++ b/test/tfheOperations/tfheOperations7.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt32, decrypt64, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations8.ts b/test/tfheOperations/tfheOperations8.ts index 4b38a2ec..3104fbfd 100644 --- a/test/tfheOperations/tfheOperations8.ts +++ b/test/tfheOperations/tfheOperations8.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt64, decrypt128, decrypt256, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/tfheOperations/tfheOperations9.ts b/test/tfheOperations/tfheOperations9.ts index 4ab60160..a3b33bb7 100644 --- a/test/tfheOperations/tfheOperations9.ts +++ b/test/tfheOperations/tfheOperations9.ts @@ -12,17 +12,7 @@ import type { TFHETestSuite8 } from '../../types/contracts/tests/TFHETestSuite8' import type { TFHETestSuite9 } from '../../types/contracts/tests/TFHETestSuite9'; import type { TFHETestSuite10 } from '../../types/contracts/tests/TFHETestSuite10'; import type { TFHETestSuite11 } from '../../types/contracts/tests/TFHETestSuite11'; -import { - createInstances, - decrypt4, - decrypt8, - decrypt16, - decrypt32, - decrypt64, - decrypt128, - decrypt256, - decryptBool, -} from '../instance'; +import { createInstances, decrypt128, decryptBool } from '../instance'; import { getSigners, initSigners } from '../signers'; async function deployTfheTestFixture1(): Promise { diff --git a/test/upgrades/upgrades.ts b/test/upgrades/upgrades.ts deleted file mode 100644 index 500b6c44..00000000 --- a/test/upgrades/upgrades.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { expect } from 'chai'; -import dotenv from 'dotenv'; -import fs from 'fs'; -import { ethers, upgrades } from 'hardhat'; - -import { getSigners, initSigners } from '../signers'; - -describe('Upgrades', function () { - before(async function () { - await initSigners(2); - this.signers = await getSigners(); - this.aclFactory = await ethers.getContractFactory('fhevmTemp/contracts/ACL.sol:ACL'); - this.aclFactoryUpgraded = await ethers.getContractFactory('ACLUpgradedExample'); - this.kmsFactory = await ethers.getContractFactory('fhevmTemp/contracts/KMSVerifier.sol:KMSVerifier'); - this.kmsFactoryUpgraded = await ethers.getContractFactory('KMSVerifierUpgradedExample'); - this.executorFactory = await ethers.getContractFactory('fhevmTemp/contracts/TFHEExecutor.sol:TFHEExecutor'); - this.executorFactoryUpgraded = await ethers.getContractFactory('TFHEExecutorUpgradedExample'); - this.paymentFactory = await ethers.getContractFactory('fhevmTemp/contracts/FHEPayment.sol:FHEPayment'); - this.paymentFactoryUpgraded = await ethers.getContractFactory('FHEPaymentUpgradedExample'); - this.gatewayFactory = await ethers.getContractFactory('GatewayContract'); - this.gatewayFactoryUpgraded = await ethers.getContractFactory('GatewayContractUpgradedExample'); - }); - - it('deploy upgradable ACL', async function () { - const nonceBef = await ethers.provider.getTransactionCount(this.signers.alice); - const acl = await upgrades.deployProxy(this.aclFactory, [this.signers.alice.address], { - initializer: 'initialize', - kind: 'uups', - }); - await acl.waitForDeployment(); - const ownerBef = await acl.owner(); - expect(await acl.getVersion()).to.equal('ACL v0.1.0'); - const acl2 = await upgrades.upgradeProxy(acl, this.aclFactoryUpgraded); - await acl2.waitForDeployment(); - const ownerAft = await acl2.owner(); - expect(ownerBef).to.equal(ownerAft); - expect(await acl2.getVersion()).to.equal('ACL v0.2.0'); - const aclAddress = ethers.getCreateAddress({ - from: this.signers.alice.address, - nonce: nonceBef, // using nonce of nonceBef instead of nonceBef+1 here, since the original implementation has already been deployer during the setup phase, and hardhat-upgrades plugin is able to detect this and not redeploy twice same contract - }); - expect(aclAddress).to.equal(await acl2.getAddress()); - }); - - it('deploy upgradable KMSVerifier', async function () { - const kms = await upgrades.deployProxy(this.kmsFactory, [this.signers.alice.address], { - initializer: 'initialize', - kind: 'uups', - }); - await kms.waitForDeployment(); - expect(await kms.getVersion()).to.equal('KMSVerifier v0.1.0'); - const kms2 = await upgrades.upgradeProxy(kms, this.kmsFactoryUpgraded); - await kms2.waitForDeployment(); - expect(await kms2.getVersion()).to.equal('KMSVerifier v0.2.0'); - }); - - it('deploy upgradable TFHEExecutor', async function () { - const executor = await upgrades.deployProxy(this.executorFactory, [this.signers.alice.address], { - initializer: 'initialize', - kind: 'uups', - }); - await executor.waitForDeployment(); - expect(await executor.getVersion()).to.equal('TFHEExecutor v0.1.0'); - const executor2 = await upgrades.upgradeProxy(executor, this.executorFactoryUpgraded); - await executor2.waitForDeployment(); - expect(await executor2.getVersion()).to.equal('TFHEExecutor v0.2.0'); - }); - - it('deploy upgradable FHEPayment', async function () { - const payment = await upgrades.deployProxy(this.paymentFactory, [this.signers.alice.address], { - initializer: 'initialize', - kind: 'uups', - }); - await payment.waitForDeployment(); - expect(await payment.getVersion()).to.equal('FHEPayment v0.1.0'); - const payment2 = await upgrades.upgradeProxy(payment, this.paymentFactoryUpgraded); - await payment2.waitForDeployment(); - expect(await payment2.getVersion()).to.equal('FHEPayment v0.2.0'); - }); - - it('deploy upgradable GatewayContract', async function () { - const gateway = await upgrades.deployProxy(this.gatewayFactory, [this.signers.alice.address], { - initializer: 'initialize', - kind: 'uups', - }); - await gateway.waitForDeployment(); - expect(await gateway.getVersion()).to.equal('GatewayContract v0.1.0'); - const gateway2 = await upgrades.upgradeProxy(gateway, this.gatewayFactoryUpgraded); - await gateway2.waitForDeployment(); - expect(await gateway2.getVersion()).to.equal('GatewayContract v0.2.0'); - }); - - it('original owner upgrades the original ACL and transfer ownership', async function () { - const origACLAdd = dotenv.parse( - fs.readFileSync('node_modules/fhevm-core-contracts/addresses/.env.acl'), - ).ACL_CONTRACT_ADDRESS; - const deployer = new ethers.Wallet(process.env.PRIVATE_KEY_FHEVM_DEPLOYER!).connect(ethers.provider); - const acl = await this.aclFactory.attach(origACLAdd, deployer); - expect(await acl.getVersion()).to.equal('ACL v0.1.0'); - const newaclFactoryUpgraded = await ethers.getContractFactory('ACLUpgradedExample', deployer); - const acl2 = await upgrades.upgradeProxy(acl, newaclFactoryUpgraded); - await acl2.waitForDeployment(); - expect(await acl2.getVersion()).to.equal('ACL v0.2.0'); - expect(await acl2.getAddress()).to.equal(origACLAdd); - const newSigner = (await ethers.getSigners())[1]; - await acl2.transferOwnership(newSigner); - await acl2.connect(newSigner).acceptOwnership(); - const newaclFactoryUpgraded2 = await ethers.getContractFactory('ACLUpgradedExample2', deployer); - await expect(upgrades.upgradeProxy(acl2, newaclFactoryUpgraded2)).to.be.reverted; // old owner can no longer upgrade ACL - const newaclFactoryUpgraded3 = await ethers.getContractFactory('ACLUpgradedExample2', newSigner); - const acl3 = await upgrades.upgradeProxy(acl2, newaclFactoryUpgraded3); // new owner can upgrade ACL - await acl3.waitForDeployment(); - expect(await acl3.getVersion()).to.equal('ACL v0.3.0'); - }); -});