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/.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/README.md b/README.md index d670ebe4..2b7fcb1a 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,9 @@ npm run fhevm:start # in another terminal npm i cp .env.example .env -./scripts/faucet.sh +npm run fhevm:faucet:alice +npm run fhevm:faucet:bob +npm run fhevm:faucet:carol npm test ``` 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/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/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/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..cb14827b 100644 --- a/test/gatewayDecrypt/testAsyncDecrypt.ts +++ b/test/gatewayDecrypt/testAsyncDecrypt.ts @@ -337,7 +337,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 +345,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'); - }); -});