diff --git a/.gitignore b/.gitignore index b9b70a29..69caed40 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,4 @@ types deployments typechain typechain-types +.openzeppelin/unknown* diff --git a/CustomProvider.ts b/CustomProvider.ts index 1777e133..a587ceaf 100644 --- a/CustomProvider.ts +++ b/CustomProvider.ts @@ -28,13 +28,9 @@ class CustomProvider extends ProviderWrapper { this.lastBlockSnapshotForDecrypt = parseInt(blockNumberHex); const parsedEnvCoprocessor = dotenv.parse(fs.readFileSync('lib/.env.exec')); const coprocAdd = parsedEnvCoprocessor.TFHE_EXECUTOR_CONTRACT_ADDRESS; - const callData = { - to: coprocAdd, - data: '0x1f20d85c', - }; this.lastCounterRand = await this._wrappedProvider.request({ - method: 'eth_call', - params: [callData, 'latest'], + method: 'eth_getStorageAt', + params: [coprocAdd, '0xa436a06f0efce5ea38c956a21e24202a59b3b746d48a23fb52b4a5bc33fe3e00', 'latest'], }); return result; } diff --git a/codegen/payments.ts b/codegen/payments.ts index 38e237f3..3c76090a 100644 --- a/codegen/payments.ts +++ b/codegen/payments.ts @@ -14,8 +14,9 @@ export function generateFHEPayment(priceData: PriceData): string { import "./TFHEExecutorAddress.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; - import "@openzeppelin/contracts/access/Ownable2Step.sol"; - + import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; + import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; + error FHEGasBlockLimitExceeded(); error CallerMustBeTFHEExecutorContract(); error OnlyScalarOperationsAreSupported(); @@ -28,7 +29,7 @@ export function generateFHEPayment(priceData: PriceData): string { error AllContractsNotAuthorized(); error ContractNotWhitelisted(); - contract FHEPayment is Ownable2Step { + contract FHEPayment is UUPSUpgradeable, Ownable2StepUpgradeable { /// @notice Name of the contract string private constant CONTRACT_NAME = "FHEPayment"; @@ -36,135 +37,183 @@ export function generateFHEPayment(priceData: PriceData): string { uint256 private constant MAJOR_VERSION = 0; uint256 private constant MINOR_VERSION = 1; uint256 private constant PATCH_VERSION = 0; - address public immutable tfheExecutorAddress = tfheExecutorAdd; + address public constant tfheExecutorAddress = tfheExecutorAdd; uint256 private constant FHE_GAS_BLOCKLIMIT = 10_000_000; uint256 private constant MIN_FHE_GASPRICE = 10_000_000; // minimum of 0.01 Gwei uint256 private constant FHE_GASPRICE_NATIVE_RATIO = 1000; // fhe gas price is set to 0.1% of native gas price (if above minimum) - uint256 private lastBlock; - uint256 private currentBlockConsumption; - uint256 public claimableUsedFHEGas; + /// @custom:storage-location erc7201:fhevm.storage.FHEPayment + struct FHEPaymentStorage { + uint256 lastBlock; + uint256 currentBlockConsumption; + uint256 claimableUsedFHEGas; + mapping(address payer => uint256 depositedAmount) depositsETH; + mapping(address user => bool allowedAllContracts) allowedAll; + mapping(address user => mapping(address dappContract => bool isWhitelisted)) whitelistedDapps; + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEPayment")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant FHEPaymentStorageLocation = + 0x4c5af501c90907b9fb888b6dd79405547def38a1dc3110f42d77f5dbc3222e00; - mapping(address payer => uint256 depositedAmount) private depositsETH; - mapping(address user => bool allowedAllContracts) private allowedAll; - mapping(address user => mapping(address dappContract => bool isWhitelisted)) private whitelistedDapps; - - constructor() Ownable(msg.sender) {} - - function recoverBurntFunds(address receiver) external onlyOwner { - uint256 claimableUsedFHEGas_ = claimableUsedFHEGas; - claimableUsedFHEGas = 0; - (bool success, ) = receiver.call{value: claimableUsedFHEGas_}(""); - if(!success) revert RecoveryFailed(); + function _getFHEPaymentStorage() internal pure returns (FHEPaymentStorage storage $) { + assembly { + $.slot := FHEPaymentStorageLocation + } + } + + function getTFHEExecutorAddress() public view virtual returns (address) { + return tfheExecutorAddress; } - function depositETH(address account) external payable { - depositsETH[account] += msg.value; + function getClaimableUsedFHEGas() public view virtual returns (uint256) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.claimableUsedFHEGas; } - function withdrawETH(uint256 amount, address receiver) external { - depositsETH[msg.sender] -= amount; + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the contract setting \`initialOwner\` as the initial owner + function initialize(address initialOwner) external initializer { + __Ownable_init(initialOwner); + } + + function recoverBurntFunds(address receiver) external virtual onlyOwner { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + uint256 claimableUsedFHEGas_ = $.claimableUsedFHEGas; + $.claimableUsedFHEGas = 0; + (bool success, ) = receiver.call{value: claimableUsedFHEGas_}(""); + if (!success) revert RecoveryFailed(); + } + + function depositETH(address account) external payable virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + $.depositsETH[account] += msg.value; + } + + function withdrawETH(uint256 amount, address receiver) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + $.depositsETH[msg.sender] -= amount; (bool success, ) = receiver.call{value: amount}(""); - if(!success) revert WithdrawalFailed(); + if (!success) revert WithdrawalFailed(); } - function getAvailableDepositsETH(address account) external view returns (uint256) { - return depositsETH[account]; + function getAvailableDepositsETH(address account) external view virtual returns (uint256) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.depositsETH[account]; } - - function didAuthorizeAllContracts(address account) external view returns (bool) { - return allowedAll[account]; + + function didAuthorizeAllContracts(address account) external view virtual returns (bool) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.allowedAll[account]; } - - function didWhitelistContract(address user, address dappContract) external view returns (bool) { - return whitelistedDapps[user][dappContract]; + + function didWhitelistContract(address user, address dappContract) external view virtual returns (bool) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.whitelistedDapps[user][dappContract]; } - - function authorizeAllContracts() external { - if (allowedAll[msg.sender]) revert AlreadyAuthorizedAllContracts(); - allowedAll[msg.sender] = true; + + function authorizeAllContracts() external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.allowedAll[msg.sender]) revert AlreadyAuthorizedAllContracts(); + $.allowedAll[msg.sender] = true; } - - function whitelistContract(address dappContract) external { - if (whitelistedDapps[msg.sender][dappContract]) revert AlreadyWhitelistedContract(); - whitelistedDapps[msg.sender][dappContract] = true; + + function whitelistContract(address dappContract) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.whitelistedDapps[msg.sender][dappContract]) revert AlreadyWhitelistedContract(); + $.whitelistedDapps[msg.sender][dappContract] = true; } - - function removeAuthorizationAllContracts() external { - if (!allowedAll[msg.sender]) revert AllContractsNotAuthorized(); - allowedAll[msg.sender] = false; + + function removeAuthorizationAllContracts() external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if (!$.allowedAll[msg.sender]) revert AllContractsNotAuthorized(); + $.allowedAll[msg.sender] = false; } - - function removeWhitelistedContract(address dappContract) external { - if (!whitelistedDapps[msg.sender][dappContract]) revert ContractNotWhitelisted(); - whitelistedDapps[msg.sender][dappContract] = false; + + function removeWhitelistedContract(address dappContract) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if (!$.whitelistedDapps[msg.sender][dappContract]) revert ContractNotWhitelisted(); + $.whitelistedDapps[msg.sender][dappContract] = false; } - + // @notice: to be used in the context of account abstraction, before an FHE tx, to make the contract address replace tx.origin as a spender - function becomeTransientSpender() external { - assembly { - tstore(0, caller()) - } + function becomeTransientSpender() external virtual { + assembly { + tstore(0, caller()) + } } - + // @notice: to be used in the context of account abstraction, after an FHE tx, to avoid issues if batched with other userOps - function stopBeingTransientSpender() external { - assembly { - tstore(0, 0) - } + function stopBeingTransientSpender() external virtual { + assembly { + tstore(0, 0) + } } - - function updateFunding(address payer, uint256 paidAmountGas) private { + + function updateFunding(address payer, uint256 paidAmountGas) internal virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); uint256 ratio_gas = (tx.gasprice * FHE_GASPRICE_NATIVE_RATIO) / 1_000_000; uint256 effective_fhe_gasPrice = ratio_gas > MIN_FHE_GASPRICE ? ratio_gas : MIN_FHE_GASPRICE; uint256 paidAmountWei = effective_fhe_gasPrice * paidAmountGas; - uint256 depositedAmount = depositsETH[payer]; + uint256 depositedAmount = $.depositsETH[payer]; if (paidAmountWei > depositedAmount) { - // if dApp is not enough funded, fallbacks to user (tx.origin by default, in case of an EOA, + // if dApp is not enough funded, fallbacks to user (tx.origin by default, in case of an EOA, // otherwise a smart contract account should call \`becomeTransientSpender\` before, in the same tx address spender; assembly { - spender := tload(0) + spender := tload(0) } spender = spender == address(0) ? tx.origin : spender; - if (allowedAll[spender] || whitelistedDapps[spender][payer]) { - uint256 depositedAmountUser = depositsETH[spender]; + if ($.allowedAll[spender] || $.whitelistedDapps[spender][payer]) { + uint256 depositedAmountUser = $.depositsETH[spender]; if (paidAmountWei > depositedAmountUser) revert AccountNotEnoughFunded(); unchecked { - depositsETH[spender] = depositedAmountUser - paidAmountWei; + $.depositsETH[spender] = depositedAmountUser - paidAmountWei; } - currentBlockConsumption += paidAmountGas; - claimableUsedFHEGas += paidAmountWei; + $.currentBlockConsumption += paidAmountGas; + $.claimableUsedFHEGas += paidAmountWei; } else { revert AccountNotEnoughFunded(); } } else { unchecked { - depositsETH[payer] = depositedAmount - paidAmountWei; + $.depositsETH[payer] = depositedAmount - paidAmountWei; } - currentBlockConsumption += paidAmountGas; - claimableUsedFHEGas += paidAmountWei; + $.currentBlockConsumption += paidAmountGas; + $.claimableUsedFHEGas += paidAmountWei; } } - - function checkIfNewBlock() private { + + function checkIfNewBlock() internal virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); uint256 lastBlock_ = block.number; - if (block.number > lastBlock) { - lastBlock = lastBlock_; - currentBlockConsumption = 0; + if (block.number > $.lastBlock) { + $.lastBlock = lastBlock_; + $.currentBlockConsumption = 0; } + } + + function checkFHEGasBlockLimit() internal view virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); }\n\n`; for (const [operation, data] of Object.entries(priceData)) { const functionName = `payFor${operation.charAt(0).toUpperCase() + operation.slice(1)}`; if (data.binary) { - output += ` function ${functionName}(address payer, uint8 resultType, bytes1 scalarByte) external { + output += ` function ${functionName}(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if(msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); `; } else { - output += ` function ${functionName}(address payer, uint8 resultType) external { + output += ` function ${functionName}(address payer, uint8 resultType) external virtual { if(msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); `; } @@ -185,7 +234,7 @@ ${generatePriceChecks(data.nonScalar)} if (data.types) output += `${generatePriceChecks(data.types)}`; } - output += `if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + output += `checkFHEGasBlockLimit(); }\n\n`; } @@ -193,7 +242,7 @@ ${generatePriceChecks(data.nonScalar)} output + ` /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/codegen/templates.ts b/codegen/templates.ts index 7fd6f0a3..20cb372c 100644 --- a/codegen/templates.ts +++ b/codegen/templates.ts @@ -51,7 +51,8 @@ function binaryOperatorImpl(op: Operator): string { ` function ${op.name}(uint256 lhs, uint256 rhs${scalarArg}) internal returns (uint256 result) { ${scalarSection} - result = ITFHEExecutor(tfheExecutorAdd).${fname}(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).${fname}(lhs, rhs, scalarByte); }` + '\n' ); } @@ -68,14 +69,29 @@ export function implSol(ctx: CodegenContext, operators: Operator[]): string { pragma solidity ^0.8.24; import "./TFHE.sol"; -import "./TFHEExecutorAddress.sol"; -import "./ACLAddress.sol"; +import "./FHEVMConfig.sol"; ${coprocessorInterface} ${aclInterface} library Impl { + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant FHEVMConfigLocation = 0xed8d60e34876f751cc8b014c560745351147d9de11b9347c854e881b128ea600; + + function getFHEVMConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct storage $) { + assembly { + $.slot := FHEVMConfigLocation + } + } + + function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + $.ACLAddress = fhevmConfig.ACLAddress; + $.TFHEExecutorAddress = fhevmConfig.TFHEExecutorAddress; + $.FHEPaymentAddress = fhevmConfig.FHEPaymentAddress; + $.KMSVerifierAddress = fhevmConfig.KMSVerifierAddress; + } `); operators.forEach((op) => { @@ -187,6 +203,7 @@ function generateACLInterface(): string { function allow(uint256 handle, address account) external; function cleanTransientStorage() external; function isAllowed(uint256 handle, address account) external view returns(bool); + function allowForDecryption(uint256[] memory handlesList) external; } `; } @@ -204,17 +221,20 @@ export function tfheSol( pragma solidity ^0.8.24; +import "./Impl.sol"; +import "./FHEVMConfig.sol"; + + ${commonSolLib()} -import "./Impl.sol"; + library TFHE { + function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { + Impl.setFHEVM(fhevmConfig); + } `); - supportedBits.forEach((b) => { - res.push(` euint${b} constant NIL${b} = euint${b}.wrap(0); -`); - }); if (mocked) { res.push(` // Return true if the enrypted bool is initialized and false otherwise. @@ -639,7 +659,8 @@ function unaryOperatorImpl(op: Operator): string { let fname = operatorFheLibFunction(op); return ` function ${op.name}(uint256 ct) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).${fname}(ct); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).${fname}(ct); } `; } @@ -949,7 +970,8 @@ function implCustomMethods(ctx: CodegenContext): string { // If 'control's value is 'true', the result has the same value as 'ifTrue'. // If 'control's value is 'false', the result has the same value as 'ifFalse'. function select(uint256 control, uint256 ifTrue, uint256 ifFalse) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheIfThenElse(control, ifTrue, ifFalse); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheIfThenElse(control, ifTrue, ifFalse); } function verify( @@ -957,46 +979,55 @@ function implCustomMethods(ctx: CodegenContext): string { bytes memory inputProof, uint8 toType ) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).verifyCiphertext(inputHandle, msg.sender, inputProof, bytes1(toType)); - IACL(aclAdd).allowTransient(result, msg.sender); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).verifyCiphertext(inputHandle, msg.sender, inputProof, bytes1(toType)); + IACL($.ACLAddress).allowTransient(result, msg.sender); } function cast( uint256 ciphertext, uint8 toType ) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).cast(ciphertext, bytes1(toType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).cast(ciphertext, bytes1(toType)); } function trivialEncrypt( uint256 value, uint8 toType ) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).trivialEncrypt(value, bytes1(toType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).trivialEncrypt(value, bytes1(toType)); } function rand(uint8 randType) internal returns(uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheRand(bytes1(randType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRand(bytes1(randType)); } function randBounded(uint256 upperBound, uint8 randType) internal returns(uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheRandBounded(upperBound, bytes1(randType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRandBounded(upperBound, bytes1(randType)); } function allowTransient(uint256 handle, address account) internal { - IACL(aclAdd).allowTransient(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).allowTransient(handle, account); } function allow(uint256 handle, address account) internal { - IACL(aclAdd).allow(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).allow(handle, account); } function cleanTransientStorage() internal { - IACL(aclAdd).cleanTransientStorage(); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).cleanTransientStorage(); } function isAllowed(uint256 handle, address account) internal view returns (bool) { - return IACL(aclAdd).isAllowed(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + return IACL($.ACLAddress).isAllowed(handle, account); } `; } @@ -1006,7 +1037,8 @@ export function paymentSol(): string { pragma solidity ^0.8.24; -import "../lib/FHEPaymentAddress.sol"; +import "../lib/FHEVMConfig.sol"; +import "../lib/Impl.sol"; interface IFHEPayment { function depositETH(address account) external payable; @@ -1016,27 +1048,33 @@ interface IFHEPayment { library Payment { function depositForAccount(address account, uint256 amount) internal { - IFHEPayment(fhePaymentAdd).depositETH{value: amount}(account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).depositETH{value: amount}(account); } function depositForThis(uint256 amount) internal { - IFHEPayment(fhePaymentAdd).depositETH{value: amount}(address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).depositETH{value: amount}(address(this)); } function withdrawToAccount(address account, uint256 amount) internal { - IFHEPayment(fhePaymentAdd).withdrawETH(amount, account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).withdrawETH(amount, account); } function withdrawToThis(uint256 amount) internal { - IFHEPayment(fhePaymentAdd).withdrawETH(amount, address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).withdrawETH(amount, address(this)); } function getDepositedBalanceOfAccount(address account) internal view returns (uint256) { - return IFHEPayment(fhePaymentAdd).getAvailableDepositsETH(account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + return IFHEPayment($.FHEPaymentAddress).getAvailableDepositsETH(account); } function getDepositedBalanceOfThis() internal view returns (uint256) { - return IFHEPayment(fhePaymentAdd).getAvailableDepositsETH(address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + return IFHEPayment($.FHEPaymentAddress).getAvailableDepositsETH(address(this)); } } `; diff --git a/codegen/testgen.ts b/codegen/testgen.ts index a07fa6dd..96844d98 100644 --- a/codegen/testgen.ts +++ b/codegen/testgen.ts @@ -242,6 +242,7 @@ export function generateSmartContract(os: OverloadShard): string { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/ACLUpgradedExample.sol b/examples/ACLUpgradedExample.sol new file mode 100644 index 00000000..8f3143ba --- /dev/null +++ b/examples/ACLUpgradedExample.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "../lib/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 new file mode 100644 index 00000000..0cc853f2 --- /dev/null +++ b/examples/ACLUpgradedExample2.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "../lib/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/BlindAuction.sol b/examples/BlindAuction.sol index d90f9cc8..9207a949 100644 --- a/examples/BlindAuction.sol +++ b/examples/BlindAuction.sol @@ -57,6 +57,8 @@ contract BlindAuction is Ownable2Step, GatewayCaller { uint256 biddingTime, bool isStoppable ) payable Ownable(msg.sender) { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + Gateway.setGateway(Gateway.defaultGatewayAddress()); Payment.depositForThis(msg.value); beneficiary = _beneficiary; tokenContract = _tokenContract; diff --git a/examples/EncryptedERC20.sol b/examples/EncryptedERC20.sol index 575ae185..ea2e7820 100644 --- a/examples/EncryptedERC20.sol +++ b/examples/EncryptedERC20.sol @@ -23,6 +23,7 @@ contract EncryptedERC20 is Ownable2Step { mapping(address => mapping(address => euint64)) internal allowances; constructor(string memory name_, string memory symbol_) payable Ownable(msg.sender) { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); _name = name_; _symbol = symbol_; diff --git a/examples/FHEPaymentUpgradedExample.sol b/examples/FHEPaymentUpgradedExample.sol new file mode 100644 index 00000000..ad8ac9a2 --- /dev/null +++ b/examples/FHEPaymentUpgradedExample.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "../lib/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 new file mode 100644 index 00000000..43c15b6a --- /dev/null +++ b/examples/GatewayContractUpgradedExample.sol @@ -0,0 +1,32 @@ +// 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 new file mode 100644 index 00000000..f010da76 --- /dev/null +++ b/examples/KMSUpgradedExample.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "../lib/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/PaymentLimit.sol b/examples/PaymentLimit.sol index bbe8e13a..85d9adff 100644 --- a/examples/PaymentLimit.sol +++ b/examples/PaymentLimit.sol @@ -8,6 +8,7 @@ import "../payment/Payment.sol"; contract PaymentLimit { constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/Rand.sol b/examples/Rand.sol index fb5cce5c..183b4f08 100644 --- a/examples/Rand.sol +++ b/examples/Rand.sol @@ -13,6 +13,7 @@ contract Rand { euint64 public value64Bounded; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/Reencrypt.sol b/examples/Reencrypt.sol index 1976da5f..7243e99d 100644 --- a/examples/Reencrypt.sol +++ b/examples/Reencrypt.sol @@ -16,6 +16,8 @@ contract Reencrypt { ebytes256 public yBytes256; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + Payment.depositForThis(msg.value); xBool = TFHE.asEbool(true); diff --git a/examples/TFHEExecutorUpgradedExample.sol b/examples/TFHEExecutorUpgradedExample.sol new file mode 100644 index 00000000..cf439ebe --- /dev/null +++ b/examples/TFHEExecutorUpgradedExample.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "../lib/TFHEExecutor.sol"; + +contract TFHEExecutorUpgradedExample is TFHEExecutor { + /// @notice Name of the contract + string private constant CONTRACT_NAME = "TFHEExecutor"; + + /// @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/TestAsyncDecrypt.sol b/examples/TestAsyncDecrypt.sol index 80b46b10..df3ba797 100644 --- a/examples/TestAsyncDecrypt.sol +++ b/examples/TestAsyncDecrypt.sol @@ -33,6 +33,8 @@ contract TestAsyncDecrypt is GatewayCaller { uint256 public latestRequestID; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + Gateway.setGateway(Gateway.defaultGatewayAddress()); Payment.depositForThis(msg.value); xBool = TFHE.asEbool(true); TFHE.allow(xBool, address(this)); diff --git a/examples/tests/TFHEManualTestSuite.sol b/examples/tests/TFHEManualTestSuite.sol index b8cbca8b..20a65b8d 100644 --- a/examples/tests/TFHEManualTestSuite.sol +++ b/examples/tests/TFHEManualTestSuite.sol @@ -14,6 +14,7 @@ contract TFHEManualTestSuite { eaddress public resAdd; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite1.sol b/examples/tests/TFHETestSuite1.sol index 741ca334..7b0269db 100644 --- a/examples/tests/TFHETestSuite1.sol +++ b/examples/tests/TFHETestSuite1.sol @@ -13,6 +13,7 @@ contract TFHETestSuite1 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite2.sol b/examples/tests/TFHETestSuite2.sol index 4956eba1..faa53c1f 100644 --- a/examples/tests/TFHETestSuite2.sol +++ b/examples/tests/TFHETestSuite2.sol @@ -13,6 +13,7 @@ contract TFHETestSuite2 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite3.sol b/examples/tests/TFHETestSuite3.sol index 1b5da24f..d6f9e182 100644 --- a/examples/tests/TFHETestSuite3.sol +++ b/examples/tests/TFHETestSuite3.sol @@ -13,6 +13,7 @@ contract TFHETestSuite3 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite4.sol b/examples/tests/TFHETestSuite4.sol index 27362514..b2818a38 100644 --- a/examples/tests/TFHETestSuite4.sol +++ b/examples/tests/TFHETestSuite4.sol @@ -13,6 +13,7 @@ contract TFHETestSuite4 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite5.sol b/examples/tests/TFHETestSuite5.sol index 73c9815e..d4d3ec18 100644 --- a/examples/tests/TFHETestSuite5.sol +++ b/examples/tests/TFHETestSuite5.sol @@ -13,6 +13,7 @@ contract TFHETestSuite5 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/examples/tests/TFHETestSuite6.sol b/examples/tests/TFHETestSuite6.sol index 41f90758..31d7b52c 100644 --- a/examples/tests/TFHETestSuite6.sol +++ b/examples/tests/TFHETestSuite6.sol @@ -13,6 +13,7 @@ contract TFHETestSuite6 { euint64 public res64; constructor() payable { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); Payment.depositForThis(msg.value); } diff --git a/gateway/GatewayCaller.sol b/gateway/GatewayCaller.sol index 8b22bb95..79b4699f 100644 --- a/gateway/GatewayCaller.sol +++ b/gateway/GatewayCaller.sol @@ -7,7 +7,7 @@ import "./lib/Gateway.sol"; abstract contract GatewayCaller { modifier onlyGateway() { - require(msg.sender == Gateway.GatewayContractAddress()); + require(msg.sender == Gateway.gatewayContractAddress()); _; } mapping(uint256 => ebool[]) private paramsEBool; diff --git a/gateway/GatewayContract.sol b/gateway/GatewayContract.sol index 4ec2ffd5..f21b9ec5 100644 --- a/gateway/GatewayContract.sol +++ b/gateway/GatewayContract.sol @@ -3,11 +3,13 @@ pragma solidity ^0.8.24; import "../lib/TFHE.sol"; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; -import "../lib/KMSVerifier.sol"; +import "../lib/KMSVerifierAddress.sol"; +import "./IKMSVerifier.sol"; -contract GatewayContract is Ownable2Step { +contract GatewayContract is UUPSUpgradeable, Ownable2StepUpgradeable { /// @notice Name of the contract string private constant CONTRACT_NAME = "GatewayContract"; @@ -16,9 +18,9 @@ contract GatewayContract is Ownable2Step { uint256 private constant MINOR_VERSION = 1; uint256 private constant PATCH_VERSION = 0; - KMSVerifier immutable kmsVerifier; + IKMSVerifier private constant kmsVerifier = IKMSVerifier(kmsVerifierAdd); - uint256 public constant MAX_DELAY = 1 days; + uint256 private constant MAX_DELAY = 1 days; struct DecryptionRequest { uint256[] cts; @@ -29,12 +31,6 @@ contract GatewayContract is Ownable2Step { bool passSignaturesToCaller; } - uint256 public counter; // tracks the number of decryption requests - - mapping(address => bool) public isRelayer; - mapping(uint256 => DecryptionRequest) internal decryptionRequests; - mapping(uint256 => bool) internal isFulfilled; - event EventDecryption( uint256 indexed requestID, uint256[] cts, @@ -51,32 +47,80 @@ contract GatewayContract is Ownable2Step { event ResultCallback(uint256 indexed requestID, bool success, bytes result); - constructor(address _gatewayOwner, address _kmsVerifier) Ownable(_gatewayOwner) { - kmsVerifier = KMSVerifier(_kmsVerifier); + function getMAX_DELAY() external virtual returns (uint256) { + return MAX_DELAY; + } + + function getKmsVerifierAddress() external virtual returns (address) { + return kmsVerifierAdd; + } + + function getCounter() external virtual returns (uint256) { + GatewayContractStorage storage $ = _getGatewayContractStorage(); + return $.counter; + } + + function isRelayer(address account) external virtual returns (bool) { + GatewayContractStorage storage $ = _getGatewayContractStorage(); + return $.isRelayer[account]; + } + + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + /// @custom:storage-location erc7201:fhevm.storage.GatewayContract + struct GatewayContractStorage { + uint256 counter; // tracks the number of decryption requests + mapping(address => bool) isRelayer; + mapping(uint256 => DecryptionRequest) decryptionRequests; + mapping(uint256 => bool) isFulfilled; + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.GatewayContract")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant GatewayContractStorageLocation = + 0x2f81b8bba57448689ab73c47570e3de1ee7f779a62f121c9631b35b3eda2aa00; + + function _getGatewayContractStorage() internal pure returns (GatewayContractStorage storage $) { + assembly { + $.slot := GatewayContractStorageLocation + } + } + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(address _gatewayOwner) external initializer { + __Ownable_init(_gatewayOwner); } modifier onlyRelayer() { - require(isRelayer[msg.sender], "Not relayer"); + GatewayContractStorage storage $ = _getGatewayContractStorage(); + require($.isRelayer[msg.sender], "Not relayer"); _; } - function addRelayer(address relayerAddress) external onlyOwner { - require(!isRelayer[relayerAddress], "Address is already relayer"); - isRelayer[relayerAddress] = true; + function addRelayer(address relayerAddress) external virtual onlyOwner { + GatewayContractStorage storage $ = _getGatewayContractStorage(); + require(!$.isRelayer[relayerAddress], "Address is already relayer"); + $.isRelayer[relayerAddress] = true; emit AddedRelayer(relayerAddress); } - function removeRelayer(address relayerAddress) external onlyOwner { - require(isRelayer[relayerAddress], "Address is not a relayer"); - isRelayer[relayerAddress] = false; + function removeRelayer(address relayerAddress) external virtual onlyOwner { + GatewayContractStorage storage $ = _getGatewayContractStorage(); + require($.isRelayer[relayerAddress], "Address is not a relayer"); + $.isRelayer[relayerAddress] = false; emit RemovedRelayer(relayerAddress); } - function isExpiredOrFulfilled(uint256 requestID) external view returns (bool) { + function isExpiredOrFulfilled(uint256 requestID) external view virtual returns (bool) { + GatewayContractStorage storage $ = _getGatewayContractStorage(); uint256 timeNow = block.timestamp; return - isFulfilled[requestID] || - (timeNow > decryptionRequests[requestID].maxTimestamp && decryptionRequests[requestID].maxTimestamp != 0); + $.isFulfilled[requestID] || + (timeNow > $.decryptionRequests[requestID].maxTimestamp && + $.decryptionRequests[requestID].maxTimestamp != 0); } /// @notice Requests the decryption of n ciphertexts `ctsHandles` with the result returned in a callback. @@ -94,11 +138,12 @@ contract GatewayContract is Ownable2Step { uint256 msgValue, uint256 maxTimestamp, bool passSignaturesToCaller - ) external returns (uint256 initialCounter) { + ) external virtual returns (uint256 initialCounter) { require(maxTimestamp > block.timestamp, "maxTimestamp must be a future date"); require(maxTimestamp <= block.timestamp + MAX_DELAY, "maxTimestamp exceeded MAX_DELAY"); - initialCounter = counter; - DecryptionRequest storage decryptionReq = decryptionRequests[initialCounter]; + GatewayContractStorage storage $ = _getGatewayContractStorage(); + initialCounter = $.counter; + DecryptionRequest storage decryptionReq = $.decryptionRequests[initialCounter]; uint256 len = ctsHandles.length; for (uint256 i = 0; i < len; i++) { @@ -119,7 +164,7 @@ contract GatewayContract is Ownable2Step { maxTimestamp, passSignaturesToCaller ); - counter++; + $.counter++; } // Called by the relayer to pass the decryption results from the KMS to the callback function @@ -128,14 +173,15 @@ contract GatewayContract is Ownable2Step { uint256 requestID, bytes memory decryptedCts, bytes[] memory signatures - ) external payable onlyRelayer { + ) external payable virtual onlyRelayer { // TODO: this should be un-commented once KMS will have the signatures implemented //require( // kmsVerifier.verifySignatures(decryptionRequests[requestID].cts, decryptedCts, signatures), // "KMS signature verification failed" //); - require(!isFulfilled[requestID], "Request is already fulfilled"); - DecryptionRequest memory decryptionReq = decryptionRequests[requestID]; + GatewayContractStorage storage $ = _getGatewayContractStorage(); + require(!$.isFulfilled[requestID], "Request is already fulfilled"); + DecryptionRequest memory decryptionReq = $.decryptionRequests[requestID]; require(block.timestamp <= decryptionReq.maxTimestamp, "Too late"); bytes memory callbackCalldata = abi.encodeWithSelector(decryptionReq.callbackSelector, requestID); bool passSignatures = decryptionReq.passSignaturesToCaller; @@ -147,12 +193,12 @@ contract GatewayContract is Ownable2Step { callbackCalldata ); emit ResultCallback(requestID, success, result); - isFulfilled[requestID] = true; + $.isFulfilled[requestID] = true; } /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/gateway/IKMSVerifier.sol b/gateway/IKMSVerifier.sol new file mode 100644 index 00000000..fddcfe42 --- /dev/null +++ b/gateway/IKMSVerifier.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +interface IKMSVerifier { + function verifySignatures( + uint256[] memory handlesList, + bytes memory decryptedResult, + bytes[] memory signatures + ) external returns (bool); +} diff --git a/gateway/lib/Gateway.sol b/gateway/lib/Gateway.sol index b8357e3e..eb45ad94 100644 --- a/gateway/lib/Gateway.sol +++ b/gateway/lib/Gateway.sol @@ -2,17 +2,46 @@ pragma solidity ^0.8.24; -import "../GatewayContract.sol"; -import "../../lib/ACL.sol"; -import "../../lib/KMSVerifier.sol"; +import "./GatewayContractAddress.sol"; +import "../IKMSVerifier.sol"; +import "../../lib/Impl.sol"; -GatewayContract constant gatewayContract = GatewayContract(0xc8c9303Cd7F337fab769686B593B87DC3403E0ce); // Replace by GatewayContract address -ACL constant acl = ACL(0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92); // Replace by ACL address -KMSVerifier constant kmsVerifier = KMSVerifier(address(0x12B064FB845C1cc05e9493856a1D637a73e944bE)); +interface IGatewayContract { + function requestDecryption( + uint256[] calldata ctsHandles, + bytes4 callbackSelector, + uint256 msgValue, + uint256 maxTimestamp, + bool passSignaturesToCaller + ) external returns (uint256); +} library Gateway { - function GatewayContractAddress() internal pure returns (address) { - return address(gatewayContract); + struct GatewayConfigStruct { + address GatewayContractAddress; + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.GatewayConfig")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant GatewayLocation = 0x93ab6e17f2c461cce6ea5d4ec117e51dda77a64affc2b2c05f8cd440def0e700; + + function defaultGatewayAddress() internal pure returns (address) { + return GATEWAY_CONTRACT_PREDEPLOY_ADDRESS; + } + + function getGetwayConfig() internal pure returns (GatewayConfigStruct storage $) { + assembly { + $.slot := GatewayLocation + } + } + + function setGateway(address gatewayAddress) internal { + GatewayConfigStruct storage $ = getGetwayConfig(); + $.GatewayContractAddress = gatewayAddress; + } + + function gatewayContractAddress() internal view returns (address) { + GatewayConfigStruct storage $ = getGetwayConfig(); + return $.GatewayContractAddress; } function toUint256(ebool newCT) internal pure returns (uint256 ct) { @@ -54,8 +83,10 @@ library Gateway { uint256 maxTimestamp, bool passSignaturesToCaller ) internal returns (uint256 requestID) { - acl.allowForDecryption(ctsHandles); - requestID = gatewayContract.requestDecryption( + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IACL($.ACLAddress).allowForDecryption(ctsHandles); + GatewayConfigStruct storage $$ = getGetwayConfig(); + requestID = IGatewayContract($$.GatewayContractAddress).requestDecryption( ctsHandles, callbackSelector, msgValue, @@ -75,6 +106,7 @@ library Gateway { assembly { calldatacopy(add(decryptedResult, 0x20), start, length) // Copy the relevant part of calldata to decryptedResult memory } - return kmsVerifier.verifySignatures(handlesList, decryptedResult, signatures); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + return IKMSVerifier($.KMSVerifierAddress).verifySignatures(handlesList, decryptedResult, signatures); } } diff --git a/gateway/lib/GatewayContractAddress.sol b/gateway/lib/GatewayContractAddress.sol new file mode 100644 index 00000000..ea9d8976 --- /dev/null +++ b/gateway/lib/GatewayContractAddress.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +address constant GATEWAY_CONTRACT_PREDEPLOY_ADDRESS = 0x096b4679d45fB675d4e2c1E4565009Cec99A12B1; diff --git a/hardhat.config.ts b/hardhat.config.ts index a9348cf0..e7e3e248 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,4 +1,5 @@ import '@nomicfoundation/hardhat-toolbox'; +import '@openzeppelin/hardhat-upgrades'; import dotenv from 'dotenv'; import 'hardhat-deploy'; import 'hardhat-ignore-warnings'; diff --git a/lib/.env.acl b/lib/.env.acl index 196053bb..adc70118 100644 --- a/lib/.env.acl +++ b/lib/.env.acl @@ -1 +1 @@ -ACL_CONTRACT_ADDRESS=0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92 +ACL_CONTRACT_ADDRESS=0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c diff --git a/lib/.env.exec b/lib/.env.exec index 439a4ca1..b0bb5d23 100644 --- a/lib/.env.exec +++ b/lib/.env.exec @@ -1 +1 @@ -TFHE_EXECUTOR_CONTRACT_ADDRESS=0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c +TFHE_EXECUTOR_CONTRACT_ADDRESS=0xcCAe95fF1d11656358E782570dF0418F59fA40e1 diff --git a/lib/.env.fhepayment b/lib/.env.fhepayment index ad2c49d5..fef9dea0 100644 --- a/lib/.env.fhepayment +++ b/lib/.env.fhepayment @@ -1 +1 @@ -FHE_PAYMENT_CONTRACT_ADDRESS=0xcCAe95fF1d11656358E782570dF0418F59fA40e1 +FHE_PAYMENT_CONTRACT_ADDRESS=0x52054F36036811ca418be59e41Fc6DD1b9e4F4c8 diff --git a/lib/.env.kmsverifier b/lib/.env.kmsverifier index 1c7685e4..23871484 100644 --- a/lib/.env.kmsverifier +++ b/lib/.env.kmsverifier @@ -1 +1 @@ -KMS_VERIFIER_CONTRACT_ADDRESS=0x12B064FB845C1cc05e9493856a1D637a73e944bE +KMS_VERIFIER_CONTRACT_ADDRESS=0x857Ca72A957920Fa0FB138602995839866Bd4005 diff --git a/lib/ACL.sol b/lib/ACL.sol index 9a1a662d..92aa52d9 100644 --- a/lib/ACL.sol +++ b/lib/ACL.sol @@ -3,9 +3,11 @@ pragma solidity ^0.8.24; import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import "./TFHEExecutorAddress.sol"; -contract ACL { +contract ACL is UUPSUpgradeable, Ownable2StepUpgradeable { /// @notice Name of the contract string private constant CONTRACT_NAME = "ACL"; @@ -14,25 +16,48 @@ contract ACL { uint256 private constant MINOR_VERSION = 1; uint256 private constant PATCH_VERSION = 0; - address public immutable tfheExecutorAddress = tfheExecutorAdd; + address private constant tfheExecutorAddress = tfheExecutorAdd; - mapping(uint256 => bool) public allowedForDecryption; + /// @custom:storage-location erc7201:fhevm.storage.ACL + struct ACLStorage { + mapping(uint256 handle => mapping(address account => bool isAllowed)) persistedAllowedPairs; + mapping(uint256 => bool) allowedForDecryption; + mapping(address account => mapping(address delegatee => mapping(address contractAddress => bool isDelegate))) delegates; + } - // A set of (handle, address) pairs. - // If address A is in the set for handle H, full access is granted to H for A. - mapping(uint256 handle => mapping(address account => bool isAllowed)) public persistedAllowedPairs; + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.ACL")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant ACLStorageLocation = 0xa688f31953c2015baaf8c0a488ee1ee22eb0e05273cc1fd31ea4cbee42febc00; - mapping(address account => mapping(address delegatee => mapping(address contractAddress => bool isDelegate))) - public delegates; + function _getACLStorage() internal pure returns (ACLStorage storage $) { + assembly { + $.slot := ACLStorageLocation + } + } + + function getTFHEExecutorAddress() public view virtual returns (address) { + return tfheExecutorAddress; + } event NewDelegation(address indexed sender, address indexed delegatee, address indexed contractAddress); event RevokedDelegation(address indexed sender, address indexed delegatee, address indexed contractAddress); event AllowedForDecryption(uint256[] handlesList); + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the contract setting `initialOwner` as the initial owner + function initialize(address initialOwner) external initializer { + __Ownable_init(initialOwner); + } + // allowTransient use of `handle` for address `account`. // The caller must be allowed to use `handle` for allowTransient() to succeed. If not, allowTransient() reverts. // @note: The Coprocessor contract can always `allowTransient`, contrarily to `allow` - function allowTransient(uint256 handle, address account) public { + function allowTransient(uint256 handle, address account) public virtual { if (msg.sender != tfheExecutorAddress) { require(isAllowed(handle, msg.sender), "sender isn't allowed"); } @@ -46,7 +71,7 @@ contract ACL { } } - function allowedTransient(uint256 handle, address account) public view returns (bool) { + function allowedTransient(uint256 handle, address account) public view virtual returns (bool) { bool isAllowedTransient; bytes32 key = keccak256(abi.encodePacked(handle, account)); assembly { @@ -55,7 +80,7 @@ contract ACL { return isAllowedTransient; } - function cleanTransientStorage() external { + function cleanTransientStorage() external virtual { // this function removes the transient allowances, could be useful for integration with Account Abstraction when bundling several UserOps calling the TFHEExecutorCoprocessor assembly { let length := tload(0) @@ -75,31 +100,35 @@ contract ACL { // Allow use of `handle` for address `account`. // The caller must be allowed to use `handle` for allow() to succeed. If not, allow() reverts. - function allow(uint256 handle, address account) external { + function allow(uint256 handle, address account) external virtual { + ACLStorage storage $ = _getACLStorage(); require(isAllowed(handle, msg.sender), "sender isn't allowed"); - persistedAllowedPairs[handle][account] = true; + $.persistedAllowedPairs[handle][account] = true; } // Returns true if address `a` is allowed to use `c` and false otherwise. - function persistAllowed(uint256 handle, address account) public view returns (bool) { - return persistedAllowedPairs[handle][account]; + function persistAllowed(uint256 handle, address account) public view virtual returns (bool) { + ACLStorage storage $ = _getACLStorage(); + return $.persistedAllowedPairs[handle][account]; } // Useful in the context of account abstraction for issuing reencryption requests from a smart contract account - function isAllowed(uint256 handle, address account) public view returns (bool) { + function isAllowed(uint256 handle, address account) public view virtual returns (bool) { return allowedTransient(handle, account) || persistAllowed(handle, account); } - function delegateAccountForContract(address delegatee, address contractAddress) external { + function delegateAccountForContract(address delegatee, address contractAddress) external virtual { require(contractAddress != msg.sender, "contractAddress should be different from msg.sender"); - require(!delegates[msg.sender][delegatee][contractAddress], "already delegated"); - delegates[msg.sender][delegatee][contractAddress] = true; + ACLStorage storage $ = _getACLStorage(); + require(!$.delegates[msg.sender][delegatee][contractAddress], "already delegated"); + $.delegates[msg.sender][delegatee][contractAddress] = true; emit NewDelegation(msg.sender, delegatee, contractAddress); } - function removeDelegationForContract(address delegatee, address contractAddress) external { - require(delegates[msg.sender][delegatee][contractAddress], "not delegated yet"); - delegates[msg.sender][delegatee][contractAddress] = false; + function removeDelegationForContract(address delegatee, address contractAddress) external virtual { + ACLStorage storage $ = _getACLStorage(); + require($.delegates[msg.sender][delegatee][contractAddress], "not delegated yet"); + $.delegates[msg.sender][delegatee][contractAddress] = false; emit RevokedDelegation(msg.sender, delegatee, contractAddress); } @@ -108,26 +137,33 @@ contract ACL { uint256 handle, address contractAddress, address account - ) external view returns (bool) { + ) external view virtual returns (bool) { + ACLStorage storage $ = _getACLStorage(); return - persistedAllowedPairs[handle][account] && - persistedAllowedPairs[handle][contractAddress] && - delegates[account][delegatee][contractAddress]; + $.persistedAllowedPairs[handle][account] && + $.persistedAllowedPairs[handle][contractAddress] && + $.delegates[account][delegatee][contractAddress]; } - function allowForDecryption(uint256[] memory handlesList) external { + function allowForDecryption(uint256[] memory handlesList) external virtual { uint256 len = handlesList.length; + ACLStorage storage $ = _getACLStorage(); for (uint256 k = 0; k < len; k++) { uint256 handle = handlesList[k]; require(isAllowed(handle, msg.sender), "sender isn't allowed"); - allowedForDecryption[handle] = true; + $.allowedForDecryption[handle] = true; } emit AllowedForDecryption(handlesList); } + function isAllowedForDecryption(uint256 handle) public virtual returns (bool) { + ACLStorage storage $ = _getACLStorage(); + return $.allowedForDecryption[handle]; + } + /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/lib/ACLAddress.sol b/lib/ACLAddress.sol index 4912cca8..2052f317 100644 --- a/lib/ACLAddress.sol +++ b/lib/ACLAddress.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.24; -address constant aclAdd = 0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92; +address constant aclAdd = 0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c; diff --git a/lib/FHEPayment.sol b/lib/FHEPayment.sol index 5dd56e8e..d04a969c 100644 --- a/lib/FHEPayment.sol +++ b/lib/FHEPayment.sol @@ -4,7 +4,8 @@ pragma solidity ^0.8.24; import "./TFHEExecutorAddress.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; error FHEGasBlockLimitExceeded(); error CallerMustBeTFHEExecutorContract(); @@ -18,7 +19,7 @@ error AlreadyWhitelistedContract(); error AllContractsNotAuthorized(); error ContractNotWhitelisted(); -contract FHEPayment is Ownable2Step { +contract FHEPayment is UUPSUpgradeable, Ownable2StepUpgradeable { /// @notice Name of the contract string private constant CONTRACT_NAME = "FHEPayment"; @@ -26,90 +27,132 @@ contract FHEPayment is Ownable2Step { uint256 private constant MAJOR_VERSION = 0; uint256 private constant MINOR_VERSION = 1; uint256 private constant PATCH_VERSION = 0; - address public immutable tfheExecutorAddress = tfheExecutorAdd; + address public constant tfheExecutorAddress = tfheExecutorAdd; uint256 private constant FHE_GAS_BLOCKLIMIT = 10_000_000; uint256 private constant MIN_FHE_GASPRICE = 10_000_000; // minimum of 0.01 Gwei uint256 private constant FHE_GASPRICE_NATIVE_RATIO = 1000; // fhe gas price is set to 0.1% of native gas price (if above minimum) - uint256 private lastBlock; - uint256 private currentBlockConsumption; - uint256 public claimableUsedFHEGas; + /// @custom:storage-location erc7201:fhevm.storage.FHEPayment + struct FHEPaymentStorage { + uint256 lastBlock; + uint256 currentBlockConsumption; + uint256 claimableUsedFHEGas; + mapping(address payer => uint256 depositedAmount) depositsETH; + mapping(address user => bool allowedAllContracts) allowedAll; + mapping(address user => mapping(address dappContract => bool isWhitelisted)) whitelistedDapps; + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEPayment")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant FHEPaymentStorageLocation = + 0x4c5af501c90907b9fb888b6dd79405547def38a1dc3110f42d77f5dbc3222e00; + + function _getFHEPaymentStorage() internal pure returns (FHEPaymentStorage storage $) { + assembly { + $.slot := FHEPaymentStorageLocation + } + } - mapping(address payer => uint256 depositedAmount) private depositsETH; - mapping(address user => bool allowedAllContracts) private allowedAll; - mapping(address user => mapping(address dappContract => bool isWhitelisted)) private whitelistedDapps; + function getTFHEExecutorAddress() public view virtual returns (address) { + return tfheExecutorAddress; + } - constructor() Ownable(msg.sender) {} + function getClaimableUsedFHEGas() public view virtual returns (uint256) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.claimableUsedFHEGas; + } - function recoverBurntFunds(address receiver) external onlyOwner { - uint256 claimableUsedFHEGas_ = claimableUsedFHEGas; - claimableUsedFHEGas = 0; + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the contract setting `initialOwner` as the initial owner + function initialize(address initialOwner) external initializer { + __Ownable_init(initialOwner); + } + + function recoverBurntFunds(address receiver) external virtual onlyOwner { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + uint256 claimableUsedFHEGas_ = $.claimableUsedFHEGas; + $.claimableUsedFHEGas = 0; (bool success, ) = receiver.call{value: claimableUsedFHEGas_}(""); if (!success) revert RecoveryFailed(); } - function depositETH(address account) external payable { - depositsETH[account] += msg.value; + function depositETH(address account) external payable virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + $.depositsETH[account] += msg.value; } - function withdrawETH(uint256 amount, address receiver) external { - depositsETH[msg.sender] -= amount; + function withdrawETH(uint256 amount, address receiver) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + $.depositsETH[msg.sender] -= amount; (bool success, ) = receiver.call{value: amount}(""); if (!success) revert WithdrawalFailed(); } - function getAvailableDepositsETH(address account) external view returns (uint256) { - return depositsETH[account]; + function getAvailableDepositsETH(address account) external view virtual returns (uint256) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.depositsETH[account]; } - function didAuthorizeAllContracts(address account) external view returns (bool) { - return allowedAll[account]; + function didAuthorizeAllContracts(address account) external view virtual returns (bool) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.allowedAll[account]; } - function didWhitelistContract(address user, address dappContract) external view returns (bool) { - return whitelistedDapps[user][dappContract]; + function didWhitelistContract(address user, address dappContract) external view virtual returns (bool) { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + return $.whitelistedDapps[user][dappContract]; } - function authorizeAllContracts() external { - if (allowedAll[msg.sender]) revert AlreadyAuthorizedAllContracts(); - allowedAll[msg.sender] = true; + function authorizeAllContracts() external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.allowedAll[msg.sender]) revert AlreadyAuthorizedAllContracts(); + $.allowedAll[msg.sender] = true; } - function whitelistContract(address dappContract) external { - if (whitelistedDapps[msg.sender][dappContract]) revert AlreadyWhitelistedContract(); - whitelistedDapps[msg.sender][dappContract] = true; + function whitelistContract(address dappContract) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.whitelistedDapps[msg.sender][dappContract]) revert AlreadyWhitelistedContract(); + $.whitelistedDapps[msg.sender][dappContract] = true; } - function removeAuthorizationAllContracts() external { - if (!allowedAll[msg.sender]) revert AllContractsNotAuthorized(); - allowedAll[msg.sender] = false; + function removeAuthorizationAllContracts() external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if (!$.allowedAll[msg.sender]) revert AllContractsNotAuthorized(); + $.allowedAll[msg.sender] = false; } - function removeWhitelistedContract(address dappContract) external { - if (!whitelistedDapps[msg.sender][dappContract]) revert ContractNotWhitelisted(); - whitelistedDapps[msg.sender][dappContract] = false; + function removeWhitelistedContract(address dappContract) external virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if (!$.whitelistedDapps[msg.sender][dappContract]) revert ContractNotWhitelisted(); + $.whitelistedDapps[msg.sender][dappContract] = false; } // @notice: to be used in the context of account abstraction, before an FHE tx, to make the contract address replace tx.origin as a spender - function becomeTransientSpender() external { + function becomeTransientSpender() external virtual { assembly { tstore(0, caller()) } } // @notice: to be used in the context of account abstraction, after an FHE tx, to avoid issues if batched with other userOps - function stopBeingTransientSpender() external { + function stopBeingTransientSpender() external virtual { assembly { tstore(0, 0) } } - function updateFunding(address payer, uint256 paidAmountGas) private { + function updateFunding(address payer, uint256 paidAmountGas) internal virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); uint256 ratio_gas = (tx.gasprice * FHE_GASPRICE_NATIVE_RATIO) / 1_000_000; uint256 effective_fhe_gasPrice = ratio_gas > MIN_FHE_GASPRICE ? ratio_gas : MIN_FHE_GASPRICE; uint256 paidAmountWei = effective_fhe_gasPrice * paidAmountGas; - uint256 depositedAmount = depositsETH[payer]; + uint256 depositedAmount = $.depositsETH[payer]; if (paidAmountWei > depositedAmount) { // if dApp is not enough funded, fallbacks to user (tx.origin by default, in case of an EOA, // otherwise a smart contract account should call `becomeTransientSpender` before, in the same tx @@ -118,35 +161,41 @@ contract FHEPayment is Ownable2Step { spender := tload(0) } spender = spender == address(0) ? tx.origin : spender; - if (allowedAll[spender] || whitelistedDapps[spender][payer]) { - uint256 depositedAmountUser = depositsETH[spender]; + if ($.allowedAll[spender] || $.whitelistedDapps[spender][payer]) { + uint256 depositedAmountUser = $.depositsETH[spender]; if (paidAmountWei > depositedAmountUser) revert AccountNotEnoughFunded(); unchecked { - depositsETH[spender] = depositedAmountUser - paidAmountWei; + $.depositsETH[spender] = depositedAmountUser - paidAmountWei; } - currentBlockConsumption += paidAmountGas; - claimableUsedFHEGas += paidAmountWei; + $.currentBlockConsumption += paidAmountGas; + $.claimableUsedFHEGas += paidAmountWei; } else { revert AccountNotEnoughFunded(); } } else { unchecked { - depositsETH[payer] = depositedAmount - paidAmountWei; + $.depositsETH[payer] = depositedAmount - paidAmountWei; } - currentBlockConsumption += paidAmountGas; - claimableUsedFHEGas += paidAmountWei; + $.currentBlockConsumption += paidAmountGas; + $.claimableUsedFHEGas += paidAmountWei; } } - function checkIfNewBlock() private { + function checkIfNewBlock() internal virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); uint256 lastBlock_ = block.number; - if (block.number > lastBlock) { - lastBlock = lastBlock_; - currentBlockConsumption = 0; + if (block.number > $.lastBlock) { + $.lastBlock = lastBlock_; + $.currentBlockConsumption = 0; } } - function payForFheAdd(address payer, uint8 resultType, bytes1 scalarByte) external { + function checkFHEGasBlockLimit() internal view virtual { + FHEPaymentStorage storage $ = _getFHEPaymentStorage(); + if ($.currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + } + + function payForFheAdd(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -174,10 +223,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 188000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheSub(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheSub(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -205,10 +254,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 188000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheMul(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheMul(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -236,10 +285,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 641000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheDiv(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheDiv(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte != 0x01) revert OnlyScalarOperationsAreSupported(); @@ -254,10 +303,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 584000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheRem(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheRem(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte != 0x01) revert OnlyScalarOperationsAreSupported(); @@ -272,10 +321,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 1095000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheBitAnd(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheBitAnd(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte != 0x00) revert OnlyNonScalarOperationsAreSupported(); @@ -292,10 +341,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 38000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheBitOr(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheBitOr(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte != 0x00) revert OnlyNonScalarOperationsAreSupported(); @@ -312,10 +361,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 38000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheBitXor(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheBitXor(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte != 0x00) revert OnlyNonScalarOperationsAreSupported(); @@ -332,10 +381,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 38000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheShl(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheShl(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -363,10 +412,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 227000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheShr(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheShr(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -394,10 +443,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 227000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheRotl(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheRotl(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -425,10 +474,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 227000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheRotr(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheRotr(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -456,10 +505,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 227000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheEq(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheEq(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -495,10 +544,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 300000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheNe(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheNe(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -534,10 +583,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 300000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheGe(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheGe(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -565,10 +614,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 156000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheGt(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheGt(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -596,10 +645,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 156000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheLe(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheLe(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -627,10 +676,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 156000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheLt(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheLt(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -658,10 +707,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 156000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheMin(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheMin(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -689,10 +738,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 210000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheMax(address payer, uint8 resultType, bytes1 scalarByte) external { + function payForFheMax(address payer, uint8 resultType, bytes1 scalarByte) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); checkIfNewBlock(); if (scalarByte == 0x01) { @@ -720,10 +769,10 @@ contract FHEPayment is Ownable2Step { updateFunding(payer, 210000); } } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheNeg(address payer, uint8 resultType) external { + function payForFheNeg(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 1) { updateFunding(payer, 60000); @@ -736,10 +785,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 199000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheNot(address payer, uint8 resultType) external { + function payForFheNot(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 0) { updateFunding(payer, 30000); @@ -754,10 +803,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 37000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForCast(address payer, uint8 resultType) external { + function payForCast(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 1) { updateFunding(payer, 200); @@ -770,10 +819,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 200); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForTrivialEncrypt(address payer, uint8 resultType) external { + function payForTrivialEncrypt(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 0) { updateFunding(payer, 100); @@ -790,10 +839,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 7) { updateFunding(payer, 700); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForIfThenElse(address payer, uint8 resultType) external { + function payForIfThenElse(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 1) { updateFunding(payer, 45000); @@ -808,10 +857,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 7) { updateFunding(payer, 80000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheRand(address payer, uint8 resultType) external { + function payForFheRand(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 2) { updateFunding(payer, 100000); @@ -822,10 +871,10 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 100000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } - function payForFheRandBounded(address payer, uint8 resultType) external { + function payForFheRandBounded(address payer, uint8 resultType) external virtual { if (msg.sender != tfheExecutorAddress) revert CallerMustBeTFHEExecutorContract(); if (resultType == 2) { updateFunding(payer, 100000); @@ -836,12 +885,12 @@ contract FHEPayment is Ownable2Step { } else if (resultType == 5) { updateFunding(payer, 100000); } - if (currentBlockConsumption >= FHE_GAS_BLOCKLIMIT) revert FHEGasBlockLimitExceeded(); + checkFHEGasBlockLimit(); } /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/lib/FHEPaymentAddress.sol b/lib/FHEPaymentAddress.sol index eee8a05c..110e4c56 100644 --- a/lib/FHEPaymentAddress.sol +++ b/lib/FHEPaymentAddress.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.24; -address constant fhePaymentAdd = 0xcCAe95fF1d11656358E782570dF0418F59fA40e1; +address constant fhePaymentAdd = 0x52054F36036811ca418be59e41Fc6DD1b9e4F4c8; diff --git a/lib/FHEVMConfig.sol b/lib/FHEVMConfig.sol new file mode 100644 index 00000000..a3b48eaf --- /dev/null +++ b/lib/FHEVMConfig.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear + +pragma solidity ^0.8.24; + +import "./ACLAddress.sol"; +import "./FHEPaymentAddress.sol"; +import "./KMSVerifierAddress.sol"; +import "./TFHEExecutorAddress.sol"; + +library FHEVMConfig { + struct FHEVMConfigStruct { + address ACLAddress; + address TFHEExecutorAddress; + address FHEPaymentAddress; + address KMSVerifierAddress; + } + + /// @dev Function to return an immutable struct + function defaultConfig() internal pure returns (FHEVMConfigStruct memory) { + return + FHEVMConfigStruct({ + ACLAddress: aclAdd, + TFHEExecutorAddress: tfheExecutorAdd, + FHEPaymentAddress: fhePaymentAdd, + KMSVerifierAddress: kmsVerifierAdd + }); + } +} diff --git a/lib/Impl.sol b/lib/Impl.sol index 280d457b..f95499f1 100644 --- a/lib/Impl.sol +++ b/lib/Impl.sol @@ -3,8 +3,7 @@ pragma solidity ^0.8.24; import "./TFHE.sol"; -import "./TFHEExecutorAddress.sol"; -import "./ACLAddress.sol"; +import "./FHEVMConfig.sol"; interface ITFHEExecutor { function fheAdd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result); @@ -47,9 +46,27 @@ interface IACL { function allow(uint256 handle, address account) external; function cleanTransientStorage() external; function isAllowed(uint256 handle, address account) external view returns (bool); + function allowForDecryption(uint256[] memory handlesList) external; } library Impl { + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant FHEVMConfigLocation = 0xed8d60e34876f751cc8b014c560745351147d9de11b9347c854e881b128ea600; + + function getFHEVMConfig() internal pure returns (FHEVMConfig.FHEVMConfigStruct storage $) { + assembly { + $.slot := FHEVMConfigLocation + } + } + + function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + $.ACLAddress = fhevmConfig.ACLAddress; + $.TFHEExecutorAddress = fhevmConfig.TFHEExecutorAddress; + $.FHEPaymentAddress = fhevmConfig.FHEPaymentAddress; + $.KMSVerifierAddress = fhevmConfig.KMSVerifierAddress; + } + function add(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { bytes1 scalarByte; if (scalar) { @@ -57,7 +74,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheAdd(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheAdd(lhs, rhs, scalarByte); } function sub(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -67,7 +85,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheSub(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheSub(lhs, rhs, scalarByte); } function mul(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -77,32 +96,38 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheMul(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheMul(lhs, rhs, scalarByte); } function div(uint256 lhs, uint256 rhs) internal returns (uint256 result) { bytes1 scalarByte = 0x01; - result = ITFHEExecutor(tfheExecutorAdd).fheDiv(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheDiv(lhs, rhs, scalarByte); } function rem(uint256 lhs, uint256 rhs) internal returns (uint256 result) { bytes1 scalarByte = 0x01; - result = ITFHEExecutor(tfheExecutorAdd).fheRem(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRem(lhs, rhs, scalarByte); } function and(uint256 lhs, uint256 rhs) internal returns (uint256 result) { bytes1 scalarByte = 0x00; - result = ITFHEExecutor(tfheExecutorAdd).fheBitAnd(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheBitAnd(lhs, rhs, scalarByte); } function or(uint256 lhs, uint256 rhs) internal returns (uint256 result) { bytes1 scalarByte = 0x00; - result = ITFHEExecutor(tfheExecutorAdd).fheBitOr(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheBitOr(lhs, rhs, scalarByte); } function xor(uint256 lhs, uint256 rhs) internal returns (uint256 result) { bytes1 scalarByte = 0x00; - result = ITFHEExecutor(tfheExecutorAdd).fheBitXor(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheBitXor(lhs, rhs, scalarByte); } function shl(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -112,7 +137,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheShl(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheShl(lhs, rhs, scalarByte); } function shr(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -122,7 +148,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheShr(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheShr(lhs, rhs, scalarByte); } function rotl(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -132,7 +159,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheRotl(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRotl(lhs, rhs, scalarByte); } function rotr(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -142,7 +170,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheRotr(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRotr(lhs, rhs, scalarByte); } function eq(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -152,7 +181,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheEq(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheEq(lhs, rhs, scalarByte); } function ne(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -162,7 +192,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheNe(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheNe(lhs, rhs, scalarByte); } function ge(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -172,7 +203,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheGe(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheGe(lhs, rhs, scalarByte); } function gt(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -182,7 +214,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheGt(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheGt(lhs, rhs, scalarByte); } function le(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -192,7 +225,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheLe(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheLe(lhs, rhs, scalarByte); } function lt(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -202,7 +236,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheLt(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheLt(lhs, rhs, scalarByte); } function min(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -212,7 +247,8 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheMin(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheMin(lhs, rhs, scalarByte); } function max(uint256 lhs, uint256 rhs, bool scalar) internal returns (uint256 result) { @@ -222,57 +258,75 @@ library Impl { } else { scalarByte = 0x00; } - result = ITFHEExecutor(tfheExecutorAdd).fheMax(lhs, rhs, scalarByte); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheMax(lhs, rhs, scalarByte); } function neg(uint256 ct) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheNeg(ct); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheNeg(ct); } function not(uint256 ct) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheNot(ct); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheNot(ct); } // If 'control's value is 'true', the result has the same value as 'ifTrue'. // If 'control's value is 'false', the result has the same value as 'ifFalse'. function select(uint256 control, uint256 ifTrue, uint256 ifFalse) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheIfThenElse(control, ifTrue, ifFalse); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheIfThenElse(control, ifTrue, ifFalse); } function verify(bytes32 inputHandle, bytes memory inputProof, uint8 toType) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).verifyCiphertext(inputHandle, msg.sender, inputProof, bytes1(toType)); - IACL(aclAdd).allowTransient(result, msg.sender); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).verifyCiphertext( + inputHandle, + msg.sender, + inputProof, + bytes1(toType) + ); + IACL($.ACLAddress).allowTransient(result, msg.sender); } function cast(uint256 ciphertext, uint8 toType) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).cast(ciphertext, bytes1(toType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).cast(ciphertext, bytes1(toType)); } function trivialEncrypt(uint256 value, uint8 toType) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).trivialEncrypt(value, bytes1(toType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).trivialEncrypt(value, bytes1(toType)); } function rand(uint8 randType) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheRand(bytes1(randType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRand(bytes1(randType)); } function randBounded(uint256 upperBound, uint8 randType) internal returns (uint256 result) { - result = ITFHEExecutor(tfheExecutorAdd).fheRandBounded(upperBound, bytes1(randType)); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + result = ITFHEExecutor($.TFHEExecutorAddress).fheRandBounded(upperBound, bytes1(randType)); } function allowTransient(uint256 handle, address account) internal { - IACL(aclAdd).allowTransient(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).allowTransient(handle, account); } function allow(uint256 handle, address account) internal { - IACL(aclAdd).allow(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).allow(handle, account); } function cleanTransientStorage() internal { - IACL(aclAdd).cleanTransientStorage(); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + IACL($.ACLAddress).cleanTransientStorage(); } function isAllowed(uint256 handle, address account) internal view returns (bool) { - return IACL(aclAdd).isAllowed(handle, account); + FHEVMConfig.FHEVMConfigStruct storage $ = getFHEVMConfig(); + return IACL($.ACLAddress).isAllowed(handle, account); } } diff --git a/lib/KMSVerifier.sol b/lib/KMSVerifier.sol index cd07de80..b3bf0537 100644 --- a/lib/KMSVerifier.sol +++ b/lib/KMSVerifier.sol @@ -3,21 +3,22 @@ pragma solidity ^0.8.24; // Importing OpenZeppelin contracts for cryptographic signature verification and access control. import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; /// @title KMS Verifier for signature verification and verifier management /// @author The developer /// @notice This contract allows for the management of verifiers and provides methods to verify signatures /// @dev The contract uses OpenZeppelin's SignatureChecker for cryptographic operations -contract KMSVerifier is Ownable2Step, EIP712 { +contract KMSVerifier is UUPSUpgradeable, Ownable2StepUpgradeable, EIP712Upgradeable { struct DecryptionResult { uint256[] handlesList; bytes decryptedResult; } - string public constant DECRYPTIONRESULT_TYPE = "DecryptionResult(uint256[] handlesList,bytes decryptedResult)"; + string private constant DECRYPTIONRESULT_TYPE = "DecryptionResult(uint256[] handlesList,bytes decryptedResult)"; bytes32 private constant DECRYPTIONRESULT_TYPE_HASH = keccak256(bytes(DECRYPTIONRESULT_TYPE)); /// @notice Name of the contract @@ -28,6 +29,44 @@ contract KMSVerifier is Ownable2Step, EIP712 { uint256 private constant MINOR_VERSION = 1; uint256 private constant PATCH_VERSION = 0; + /// @custom:storage-location erc7201:fhevm.storage.KMSVerifier + struct KMSVerifierStorage { + mapping(address => bool) isVerifier; /// @notice Mapping to keep track of addresses that are verifiers + address[] verifiers; /// @notice Array to keep track of all verifiers + uint256 threshold; /// @notice The threshold for the number of verifiers required for a signature to be valid + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.KMSVerifier")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant KMSVerifierStorageLocation = + 0x7e81a744be86773af8644dd7304fa1dc9350ccabf16cfcaa614ddb78b4ce8900; + + function _getKMSVerifierStorage() internal pure returns (KMSVerifierStorage storage $) { + assembly { + $.slot := KMSVerifierStorageLocation + } + } + + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + function isVerifier(address account) public virtual returns (bool) { + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + return $.isVerifier[account]; + } + + function getVerifiers() public view virtual returns (address[] memory) { + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + return $.verifiers; + } + + function getThreshold() public view virtual returns (uint256) { + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + return $.threshold; + } + + function get_DECRYPTIONRESULT_TYPE() public view virtual returns (string memory) { + return DECRYPTIONRESULT_TYPE; + } + /// @notice Emitted when a verifier is added /// @param verifier The address of the verifier that was added event VerifierAdded(address indexed verifier); @@ -36,36 +75,37 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @param verifier The address of the verifier that was removed event VerifierRemoved(address indexed verifier); - /// @notice Mapping to keep track of addresses that are verifiers - mapping(address => bool) public isVerifier; - - /// @notice Array to keep track of all verifiers - address[] public verifiers; - - /// @notice The threshold for the number of verifiers required for a signature to be valid - uint256 public threshold; + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } - /// @notice Initializes the contract setting the deployer as the initial owner - constructor() Ownable(msg.sender) EIP712(CONTRACT_NAME, "1") {} + /// @notice Initializes the contract setting `initialOwner` as the initial owner + function initialize(address initialOwner) external initializer { + __Ownable_init(initialOwner); + __EIP712_init(CONTRACT_NAME, "1"); + } /// @notice Sets the threshold for the number of verifiers required for a signature to be valid - function applyThreshold() internal { - threshold = (verifiers.length - 1) / 3 + 1; + function applyThreshold() internal virtual { + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + $.threshold = ($.verifiers.length - 1) / 3 + 1; } /// @notice Adds a new verifier /// @dev Only the owner can add a verifier /// @param verifier The address to be added as a verifier - function addVerifier(address verifier) public onlyOwner { + function addVerifier(address verifier) public virtual onlyOwner { require(verifier != address(0), "KMSVerifier: Address is null"); - require(!isVerifier[verifier], "KMSVerifier: Address is already a verifier"); - isVerifier[verifier] = true; - verifiers.push(verifier); + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + require($.isVerifier[verifier], "KMSVerifier: Address is already a verifier"); + $.isVerifier[verifier] = true; + $.verifiers.push(verifier); applyThreshold(); emit VerifierAdded(verifier); } - function hashDecryptionResult(DecryptionResult memory decRes) internal view returns (bytes32) { + function hashDecryptionResult(DecryptionResult memory decRes) internal view virtual returns (bytes32) { return _hashTypedDataV4( keccak256( @@ -81,17 +121,18 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @notice Removes an existing verifier /// @dev Only the owner can remove a verifier /// @param verifier The address to be removed from verifiers - function removeVerifier(address verifier) public onlyOwner { - require(isVerifier[verifier], "KMSVerifier: Address is not a verifier"); + function removeVerifier(address verifier) public virtual onlyOwner { + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + require($.isVerifier[verifier], "KMSVerifier: Address is not a verifier"); // Remove verifier from the mapping - isVerifier[verifier] = false; + $.isVerifier[verifier] = false; // Find the index of the verifier and remove it from the array - for (uint i = 0; i < verifiers.length; i++) { - if (verifiers[i] == verifier) { - verifiers[i] = verifiers[verifiers.length - 1]; // Move the last element into the place to delete - verifiers.pop(); // Remove the last element + for (uint i = 0; i < $.verifiers.length; i++) { + if ($.verifiers[i] == verifier) { + $.verifiers[i] = $.verifiers[$.verifiers.length - 1]; // Move the last element into the place to delete + $.verifiers.pop(); // Remove the last element applyThreshold(); emit VerifierRemoved(verifier); return; @@ -104,7 +145,7 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @param message The hash of the message that was signed /// @param signature The signature to verify /// @return signer The address that supposedly signed the message - function recoverSigner(bytes32 message, bytes memory signature) internal pure returns (address) { + function recoverSigner(bytes32 message, bytes memory signature) internal pure virtual returns (address) { address signerRecovered = ECDSA.recover(message, signature); return signerRecovered; } @@ -119,7 +160,7 @@ contract KMSVerifier is Ownable2Step, EIP712 { uint256[] memory handlesList, bytes memory decryptedResult, bytes[] memory signatures - ) public returns (bool) { + ) public virtual returns (bool) { DecryptionResult memory decRes; decRes.handlesList = handlesList; decRes.decryptedResult = decryptedResult; @@ -132,22 +173,23 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @param message The hash of the message that was signed by all signers /// @param signatures An array of signatures to verify /// @return true if enough provided signatures are valid, false otherwise - function verifySignaturesDigest(bytes32 message, bytes[] memory signatures) internal returns (bool) { + function verifySignaturesDigest(bytes32 message, bytes[] memory signatures) internal virtual returns (bool) { uint256 numSignatures = signatures.length; require(numSignatures > 0, "KmsVerifier: no signatures provided"); - require(numSignatures >= threshold, "KmsVerifier: at least threshold number of signatures required"); + KMSVerifierStorage storage $ = _getKMSVerifierStorage(); + require(numSignatures >= $.threshold, "KmsVerifier: at least threshold number of signatures required"); address[] memory recoveredVerifiers = new address[](numSignatures); uint256 uniqueValidCount; for (uint256 i = 0; i < numSignatures; i++) { address signerRecovered = recoverSigner(message, signatures[i]); - if (isVerifier[signerRecovered]) { + if ($.isVerifier[signerRecovered]) { if (!tload(signerRecovered)) { recoveredVerifiers[uniqueValidCount] = signerRecovered; uniqueValidCount++; tstore(signerRecovered, 1); } } - if (uniqueValidCount >= threshold) { + if (uniqueValidCount >= $.threshold) { for (uint256 j = 0; i < uniqueValidCount; i++) { /// @note : clearing transient storage for composability tstore(recoveredVerifiers[j], 0); @@ -162,7 +204,7 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @dev Uses inline assembly to access the Transient Storage's tstore operation. /// @param location The address used as key where transient storage of the contract is written at /// @param value An uint256 stored at location key in transient storage of the contract - function tstore(address location, uint256 value) private { + function tstore(address location, uint256 value) internal virtual { assembly { tstore(location, value) } @@ -172,7 +214,7 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @dev Uses inline assembly to access the Transient Storage's tload operation. /// @param location The address used as key where transient storage of the contract is read at /// @return value true if value stored at the given location is non-null, false otherwise. - function tload(address location) private view returns (bool value) { + function tload(address location) internal view virtual returns (bool value) { assembly { value := tload(location) } @@ -180,7 +222,7 @@ contract KMSVerifier is Ownable2Step, EIP712 { /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/lib/KMSVerifierAddress.sol b/lib/KMSVerifierAddress.sol index 9899cfdc..34443a5e 100644 --- a/lib/KMSVerifierAddress.sol +++ b/lib/KMSVerifierAddress.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.24; -address constant kmsVerifierAdd = 0x12B064FB845C1cc05e9493856a1D637a73e944bE; +address constant kmsVerifierAdd = 0x857Ca72A957920Fa0FB138602995839866Bd4005; diff --git a/lib/TFHE.sol b/lib/TFHE.sol index 4f7a7f13..e99eed48 100644 --- a/lib/TFHE.sol +++ b/lib/TFHE.sol @@ -2,6 +2,9 @@ pragma solidity ^0.8.24; +import "./Impl.sol"; +import "./FHEVMConfig.sol"; + type ebool is uint256; type euint4 is uint256; type euint8 is uint256; @@ -28,14 +31,10 @@ library Common { uint8 internal constant ebytes256_t = 11; } -import "./Impl.sol"; - library TFHE { - euint4 constant NIL4 = euint4.wrap(0); - euint8 constant NIL8 = euint8.wrap(0); - euint16 constant NIL16 = euint16.wrap(0); - euint32 constant NIL32 = euint32.wrap(0); - euint64 constant NIL64 = euint64.wrap(0); + function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal { + Impl.setFHEVM(fhevmConfig); + } // Return true if the enrypted bool is initialized and false otherwise. function isInitialized(ebool v) internal pure returns (bool) { diff --git a/lib/TFHEExecutor.sol b/lib/TFHEExecutor.sol index f96e55c1..7bfa3450 100644 --- a/lib/TFHEExecutor.sol +++ b/lib/TFHEExecutor.sol @@ -7,12 +7,13 @@ import "./FHEPayment.sol"; import "./FhevmLib.sol"; import "./ACLAddress.sol"; import "./FHEPaymentAddress.sol"; -import "./FhevmLib.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; address constant EXT_TFHE_LIBRARY = address(0x000000000000000000000000000000000000005d); -contract TFHEExecutor { +contract TFHEExecutor is UUPSUpgradeable, Ownable2StepUpgradeable { /// @notice Handle version uint8 public constant HANDLE_VERSION = 0; @@ -27,7 +28,32 @@ contract TFHEExecutor { ACL private constant acl = ACL(aclAdd); FHEPayment private constant fhePayment = FHEPayment(fhePaymentAdd); - uint256 public counterRand = 0; // counter used for computing handles of randomness operators + /// @custom:storage-location erc7201:fhevm.storage.TFHEExecutor + struct TFHEExecutorStorage { + uint256 counterRand; /// @notice counter used for computing handles of randomness operators + } + + // keccak256(abi.encode(uint256(keccak256("fhevm.storage.TFHEExecutor")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant TFHEExecutorStorageLocation = + 0xa436a06f0efce5ea38c956a21e24202a59b3b746d48a23fb52b4a5bc33fe3e00; + + function _getTFHEExecutorStorage() internal pure returns (TFHEExecutorStorage storage $) { + assembly { + $.slot := TFHEExecutorStorageLocation + } + } + + function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {} + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the contract setting `initialOwner` as the initial owner + function initialize(address initialOwner) external initializer { + __Ownable_init(initialOwner); + } enum Operators { fheAdd, @@ -60,30 +86,30 @@ contract TFHEExecutor { fheRandBounded } - function isPowerOfTwo(uint256 x) internal pure returns (bool) { + function isPowerOfTwo(uint256 x) internal pure virtual returns (bool) { return (x > 0) && ((x & (x - 1)) == 0); } /// @dev handle format for user inputs is: keccak256(keccak256(CiphertextFHEList)||index_handle)[0:29] || index_handle || handle_type || handle_version /// @dev other handles format (fhe ops results) is: keccak256(keccak256(rawCiphertextFHEList)||index_handle)[0:30] || handle_type || handle_version /// @dev the CiphertextFHEList actually contains: 1 byte (= N) for size of handles_list, N bytes for the handles_types : 1 per handle, then the original fhe160list raw ciphertext - function typeOf(uint256 handle) internal pure returns (uint8) { + function typeOf(uint256 handle) internal pure virtual returns (uint8) { uint8 typeCt = uint8(handle >> 8); return typeCt; } - function appendType(uint256 prehandle, uint8 handleType) internal pure returns (uint256 result) { + function appendType(uint256 prehandle, uint8 handleType) internal pure virtual returns (uint256 result) { result = prehandle & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000; result = result | (uint256(handleType) << 8); // append type result = result | HANDLE_VERSION; } - function requireType(uint256 handle, uint256 supportedTypes) internal pure { + function requireType(uint256 handle, uint256 supportedTypes) internal pure virtual { uint8 typeCt = typeOf(handle); require((1 << typeCt) & supportedTypes > 0, "Unsupported type"); } - function unaryOp(Operators op, uint256 ct) internal returns (uint256 result) { + function unaryOp(Operators op, uint256 ct) internal virtual returns (uint256 result) { require(acl.isAllowed(ct, msg.sender), "Sender doesn't own ct on op"); result = uint256(keccak256(abi.encodePacked(op, ct))); uint8 typeCt = typeOf(ct); @@ -97,7 +123,7 @@ contract TFHEExecutor { uint256 rhs, bytes1 scalar, uint8 resultType - ) internal returns (uint256 result) { + ) internal virtual returns (uint256 result) { require(acl.isAllowed(lhs, msg.sender), "Sender doesn't own lhs on op"); if (scalar == 0x00) { require(acl.isAllowed(rhs, msg.sender), "Sender doesn't own rhs on op"); @@ -110,7 +136,12 @@ contract TFHEExecutor { acl.allowTransient(result, msg.sender); } - function ternaryOp(Operators op, uint256 lhs, uint256 middle, uint256 rhs) internal returns (uint256 result) { + function ternaryOp( + Operators op, + uint256 lhs, + uint256 middle, + uint256 rhs + ) internal virtual returns (uint256 result) { require(acl.isAllowed(lhs, msg.sender), "Sender doesn't own lhs on op"); require(acl.isAllowed(middle, msg.sender), "Sender doesn't own middle on op"); require(acl.isAllowed(rhs, msg.sender), "Sender doesn't own rhs on op"); @@ -124,7 +155,7 @@ contract TFHEExecutor { acl.allowTransient(result, msg.sender); } - function fheAdd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheAdd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -133,7 +164,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheAdd, lhs, rhs, scalar, lhsType); } - function fheSub(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheSub(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -142,7 +173,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheSub, lhs, rhs, scalar, lhsType); } - function fheMul(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheMul(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -151,7 +182,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheMul, lhs, rhs, scalar, lhsType); } - function fheDiv(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheDiv(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { require(scalarByte & 0x01 == 0x01, "Only fheDiv by a scalar is supported"); uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); @@ -161,7 +192,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheDiv, lhs, rhs, scalar, lhsType); } - function fheRem(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheRem(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { require(scalarByte & 0x01 == 0x01, "Only fheRem by a scalar is supported"); uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); @@ -171,7 +202,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheRem, lhs, rhs, scalar, lhsType); } - function fheBitAnd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheBitAnd(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { require(scalarByte & 0x01 == 0x00, "Only fheBitAnd by a ciphertext is supported"); uint256 supportedTypes = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); @@ -181,7 +212,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheBitAnd, lhs, rhs, scalar, lhsType); } - function fheBitOr(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheBitOr(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { require(scalarByte & 0x01 == 0x00, "Only fheBitOr by a ciphertext is supported"); uint256 supportedTypes = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); @@ -191,7 +222,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheBitOr, lhs, rhs, scalar, lhsType); } - function fheBitXor(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheBitXor(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { require(scalarByte & 0x01 == 0x00, "Only fheBitXor by a ciphertext is supported"); uint256 supportedTypes = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); @@ -201,7 +232,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheBitXor, lhs, rhs, scalar, lhsType); } - function fheShl(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheShl(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -210,7 +241,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheShl, lhs, rhs, scalar, lhsType); } - function fheShr(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheShr(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -219,7 +250,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheShr, lhs, rhs, scalar, lhsType); } - function fheRotl(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheRotl(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -237,7 +268,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheRotr, lhs, rhs, scalar, lhsType); } - function fheEq(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheEq(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5) + (1 << 7) + (1 << 11); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -246,7 +277,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheEq, lhs, rhs, scalar, 0); } - function fheNe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheNe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5) + (1 << 7) + (1 << 11); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -255,7 +286,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheNe, lhs, rhs, scalar, 0); } - function fheGe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheGe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -264,7 +295,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheGe, lhs, rhs, scalar, 0); } - function fheGt(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheGt(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -273,7 +304,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheGt, lhs, rhs, scalar, 0); } - function fheLe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheLe(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -282,7 +313,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheLe, lhs, rhs, scalar, 0); } - function fheLt(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheLt(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -291,7 +322,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheLt, lhs, rhs, scalar, 0); } - function fheMin(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheMin(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -300,7 +331,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheMin, lhs, rhs, scalar, lhsType); } - function fheMax(uint256 lhs, uint256 rhs, bytes1 scalarByte) external returns (uint256 result) { + function fheMax(uint256 lhs, uint256 rhs, bytes1 scalarByte) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(lhs, supportedTypes); uint8 lhsType = typeOf(lhs); @@ -309,7 +340,7 @@ contract TFHEExecutor { result = binaryOp(Operators.fheMax, lhs, rhs, scalar, lhsType); } - function fheNeg(uint256 ct) external returns (uint256 result) { + function fheNeg(uint256 ct) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(ct, supportedTypes); uint8 typeCt = typeOf(ct); @@ -317,7 +348,7 @@ contract TFHEExecutor { result = unaryOp(Operators.fheNeg, ct); } - function fheNot(uint256 ct) external returns (uint256 result) { + function fheNot(uint256 ct) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(ct, supportedTypes); uint8 typeCt = typeOf(ct); @@ -330,7 +361,7 @@ contract TFHEExecutor { address callerAddress, bytes memory inputProof, bytes1 inputType - ) external returns (uint256 result) { + ) external virtual returns (uint256 result) { result = FhevmLib(address(EXT_TFHE_LIBRARY)).verifyCiphertext( inputHandle, callerAddress, @@ -341,7 +372,7 @@ contract TFHEExecutor { acl.allowTransient(result, msg.sender); } - function cast(uint256 ct, bytes1 toType) external returns (uint256 result) { + function cast(uint256 ct, bytes1 toType) external virtual returns (uint256 result) { require(acl.isAllowed(ct, msg.sender), "Sender doesn't own ct on cast"); uint256 supportedTypesInput = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); requireType(ct, supportedTypesInput); @@ -355,7 +386,7 @@ contract TFHEExecutor { acl.allowTransient(result, msg.sender); } - function trivialEncrypt(uint256 pt, bytes1 toType) external returns (uint256 result) { + function trivialEncrypt(uint256 pt, bytes1 toType) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 0) + (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5) + (1 << 7); uint8 toT = uint8(toType); require((1 << toT) & supportedTypes > 0, "Unsupported type"); @@ -365,7 +396,7 @@ contract TFHEExecutor { acl.allowTransient(result, msg.sender); } - function fheIfThenElse(uint256 control, uint256 ifTrue, uint256 ifFalse) external returns (uint256 result) { + function fheIfThenElse(uint256 control, uint256 ifTrue, uint256 ifFalse) external virtual returns (uint256 result) { uint256 supportedTypes = (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5) + (1 << 7); requireType(ifTrue, supportedTypes); uint8 typeCt = typeOf(ifTrue); @@ -373,32 +404,34 @@ contract TFHEExecutor { result = ternaryOp(Operators.fheIfThenElse, control, ifTrue, ifFalse); } - function fheRand(bytes1 randType) external returns (uint256 result) { + function fheRand(bytes1 randType) external virtual returns (uint256 result) { + TFHEExecutorStorage storage $ = _getTFHEExecutorStorage(); uint256 supportedTypes = (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); uint8 randT = uint8(randType); require((1 << randT) & supportedTypes > 0, "Unsupported erandom type"); fhePayment.payForFheRand(msg.sender, randT); - result = uint256(keccak256(abi.encodePacked(Operators.fheRand, randType, counterRand))); + result = uint256(keccak256(abi.encodePacked(Operators.fheRand, randType, $.counterRand))); result = appendType(result, randT); acl.allowTransient(result, msg.sender); - counterRand++; + $.counterRand++; } - function fheRandBounded(uint256 upperBound, bytes1 randType) external returns (uint256 result) { + function fheRandBounded(uint256 upperBound, bytes1 randType) external virtual returns (uint256 result) { + TFHEExecutorStorage storage $ = _getTFHEExecutorStorage(); uint256 supportedTypes = (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5); uint8 randT = uint8(randType); require((1 << randT) & supportedTypes > 0, "Unsupported erandom type"); require(isPowerOfTwo(upperBound), "UpperBound must be a power of 2"); fhePayment.payForFheRandBounded(msg.sender, randT); - result = uint256(keccak256(abi.encodePacked(Operators.fheRandBounded, upperBound, randType, counterRand))); + result = uint256(keccak256(abi.encodePacked(Operators.fheRandBounded, upperBound, randType, $.counterRand))); result = appendType(result, randT); acl.allowTransient(result, msg.sender); - counterRand++; + $.counterRand++; } /// @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 returns (string memory) { + function getVersion() external pure virtual returns (string memory) { return string( abi.encodePacked( diff --git a/lib/TFHEExecutorAddress.sol b/lib/TFHEExecutorAddress.sol index 57748a1b..64d75675 100644 --- a/lib/TFHEExecutorAddress.sol +++ b/lib/TFHEExecutorAddress.sol @@ -2,4 +2,4 @@ pragma solidity ^0.8.24; -address constant tfheExecutorAdd = 0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c; +address constant tfheExecutorAdd = 0xcCAe95fF1d11656358E782570dF0418F59fA40e1; diff --git a/package-lock.json b/package-lock.json index 0514e080..40339561 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,11 +19,13 @@ "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-network-helpers": "^1.0.6", - "@nomicfoundation/hardhat-toolbox": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.10", + "@openzeppelin/contracts-upgradeable": "^5.0.2", + "@openzeppelin/hardhat-upgrades": "^3.2.1", "@trivago/prettier-plugin-sort-imports": "^4.0.0", - "@typechain/ethers-v6": "^0.4.0", - "@typechain/hardhat": "^8.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.4", "@types/fs-extra": "^9.0.13", "@types/mocha": "^10.0.0", @@ -40,7 +42,7 @@ "eslint-config-prettier": "^8.5.0", "ethers": "^6.8.0", "fhevmjs": "^0.5.0", - "hardhat": "^2.22.8", + "hardhat": "^2.22.10", "hardhat-deploy": "^0.11.29", "hardhat-gas-reporter": "^1.0.2", "hardhat-ignore-warnings": "^0.2.11", @@ -65,6 +67,62 @@ "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", "dev": true }, + "node_modules/@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "dev": true, + "dependencies": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", + "dev": true, + "dependencies": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/types/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -105,12 +163,12 @@ } }, "node_modules/@babel/helper-environment-visitor/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -132,12 +190,12 @@ } }, "node_modules/@babel/helper-function-name/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -158,12 +216,12 @@ } }, "node_modules/@babel/helper-hoist-variables/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -184,12 +242,12 @@ } }, "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -198,9 +256,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -302,10 +360,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -313,27 +374,41 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/parser/node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -363,12 +438,12 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -378,12 +453,12 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -498,6 +573,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -513,6 +598,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -561,9 +658,9 @@ } }, "node_modules/@ethereumjs/util/node_modules/@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "dependencies": { "@noble/hashes": "1.4.0" @@ -585,12 +682,12 @@ } }, "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", - "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "dependencies": { - "@noble/curves": "1.4.0", + "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" @@ -1354,6 +1451,28 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1417,9 +1536,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -1714,9 +1833,9 @@ } }, "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", - "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz", + "integrity": "sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -1727,6 +1846,39 @@ "hardhat": "^2.0.0" } }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", + "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", + "dev": true, + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.5", + "@nomicfoundation/ignition-ui": "^0.15.5", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", + "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", + "dev": true, + "peer": true, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/ignition-core": "^0.15.5", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, "node_modules/@nomicfoundation/hardhat-network-helpers": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", @@ -1740,34 +1892,35 @@ } }, "node_modules/@nomicfoundation/hardhat-toolbox": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-3.0.0.tgz", - "integrity": "sha512-MsteDXd0UagMksqm9KvcFG6gNKYNa3GGNCy73iQ6bEasEgg2v8Qjl6XA5hjs8o5UD5A3153B6W2BIVJ8SxYUtA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", + "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", "dev": true, "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomicfoundation/hardhat-verify": "^1.0.0", - "@typechain/ethers-v6": "^0.4.0", - "@typechain/hardhat": "^8.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": ">=12.0.0", + "@types/node": ">=18.0.0", "chai": "^4.2.0", "ethers": "^6.4.0", "hardhat": "^2.11.0", "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.1", "ts-node": ">=8.0.0", - "typechain": "^8.2.0", + "typechain": "^8.3.0", "typescript": ">=4.5.0" } }, "node_modules/@nomicfoundation/hardhat-verify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz", - "integrity": "sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.10.tgz", + "integrity": "sha512-3zoTZGQhpeOm6piJDdsGb6euzZAd7N5Tk0zPQvGnfKQ0+AoxKz/7i4if12goi8IDTuUGElAUuZyQB8PMQoXA5g==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -1855,6 +2008,169 @@ "node": ">=4" } }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", + "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", + "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/slang": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.17.0.tgz", + "integrity": "sha512-1GlkGRcGpVnjFw9Z1vvDKOKo2mzparFt7qrl2pDxWp+jrVtlvej98yCMX52pVyrYE7ZeOSZFnx/DtsSgoukStQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/slang-darwin-arm64": "0.17.0", + "@nomicfoundation/slang-darwin-x64": "0.17.0", + "@nomicfoundation/slang-linux-arm64-gnu": "0.17.0", + "@nomicfoundation/slang-linux-arm64-musl": "0.17.0", + "@nomicfoundation/slang-linux-x64-gnu": "0.17.0", + "@nomicfoundation/slang-linux-x64-musl": "0.17.0", + "@nomicfoundation/slang-win32-arm64-msvc": "0.17.0", + "@nomicfoundation/slang-win32-ia32-msvc": "0.17.0", + "@nomicfoundation/slang-win32-x64-msvc": "0.17.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-darwin-arm64": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-arm64/-/slang-darwin-arm64-0.17.0.tgz", + "integrity": "sha512-O0q94EUtoWy9A5kOTOa9/khtxXDYnLqmuda9pQELurSiwbQEVCPQL8kb34VbOW+ifdre66JM/05Xw9JWhIZ9sA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-darwin-x64": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-darwin-x64/-/slang-darwin-x64-0.17.0.tgz", + "integrity": "sha512-IaDbHzvT08sBK2HyGzonWhq1uu8IxdjmTqAWHr25Oh/PYnamdi8u4qchZXXYKz/DHLoYN3vIpBXoqLQIomhD/g==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-arm64-gnu": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-gnu/-/slang-linux-arm64-gnu-0.17.0.tgz", + "integrity": "sha512-Lj4anvOsQZxs1SycG8VyT2Rl2oqIhyLSUCgGepTt3CiJ/bM+8r8bLJIgh8vKkki4BWz49YsYIgaJB2IPv8FFTw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-arm64-musl": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-arm64-musl/-/slang-linux-arm64-musl-0.17.0.tgz", + "integrity": "sha512-/xkTCa9d5SIWUBQE3BmLqDFfJRr4yUBwbl4ynPiGUpRXrD69cs6pWKkwjwz/FdBpXqVo36I+zY95qzoTj/YhOA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-x64-gnu": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-gnu/-/slang-linux-x64-gnu-0.17.0.tgz", + "integrity": "sha512-oe5IO5vntOqYvTd67deCHPIWuSuWm6aYtT2/0Kqz2/VLtGz4ClEulBSRwfnNzBVtw2nksWipE1w8BzhImI7Syg==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-linux-x64-musl": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-linux-x64-musl/-/slang-linux-x64-musl-0.17.0.tgz", + "integrity": "sha512-PpYCI5K/kgLAMXaPY0V4VST5gCDprEOh7z/47tbI8kJQumI5odjsj/Cs8MpTo7/uRH6flKYbVNgUzcocWVYrAQ==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-arm64-msvc": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-arm64-msvc/-/slang-win32-arm64-msvc-0.17.0.tgz", + "integrity": "sha512-u/Mkf7OjokdBilP7QOJj6QYJU4/mjkbKnTX21wLyCIzeVWS7yafRPYpBycKIBj2pRRZ6ceAY5EqRpb0aiCq+0Q==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-ia32-msvc": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-ia32-msvc/-/slang-win32-ia32-msvc-0.17.0.tgz", + "integrity": "sha512-XJBVQfNnZQUv0tP2JSJ573S+pmgrLWgqSZOGaMllnB/TL1gRci4Z7dYRJUF2s82GlRJE+FHSI2Ro6JISKmlXCg==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/slang-win32-x64-msvc": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang-win32-x64-msvc/-/slang-win32-x64-msvc-0.17.0.tgz", + "integrity": "sha512-zPGsAeiTfqfPNYHD8BfrahQmYzA78ZraoHKTGraq/1xwJwzBK4bu/NtvVA4pJjBV+B4L6DCxVhSbpn40q26JQA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", @@ -2012,10 +2328,124 @@ "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", + "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", + "dev": true, + "peerDependencies": { + "@openzeppelin/contracts": "5.0.2" + } + }, + "node_modules/@openzeppelin/defender-sdk-base-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.14.3.tgz", + "integrity": "sha512-4yG9E8N1c/ZP2jNR+Ah19wi7SBKpauAV/VcYcm7rg1dltDbzbH/oZnnXJlymT7IfjTPXkKHW8TPsaqz3EjS7tA==", + "dev": true, + "dependencies": { + "amazon-cognito-identity-js": "^6.3.6", + "async-retry": "^1.3.3" + } + }, + "node_modules/@openzeppelin/defender-sdk-deploy-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.14.3.tgz", + "integrity": "sha512-51WIZJz251lndK7uQU4gBE0gBX+2ZNTgf+hemtJUEPCpHtkooBRFFMID3EPGMKXVqf872pU8K3Huu9PyYQu6bw==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "1.14.3", + "axios": "^1.7.2", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/defender-sdk-network-client": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.14.3.tgz", + "integrity": "sha512-qrJLs2ubKSwrhP0x4V2QOPhlc1q8TYnkAcvjvk34VXMS8lhY1cpXSGoxnTw3Mi+eCSE1xOzKWISLi1UAOQOJIw==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "1.14.3", + "axios": "^1.7.2", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.2.1.tgz", + "integrity": "sha512-Zy5M3QhkzwGdpzQmk+xbWdYOGJWjoTvwbBKYLhctu9B91DoprlhDRaZUwCtunwTdynkTDGdVfGr0kIkvycyKjw==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^1.10.0", + "@openzeppelin/defender-sdk-deploy-client": "^1.10.0", + "@openzeppelin/defender-sdk-network-client": "^1.10.0", + "@openzeppelin/upgrades-core": "^1.35.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.1.5", + "proper-lockfile": "^4.1.1", + "undici": "^6.11.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "ethers": "^6.6.0", + "hardhat": "^2.0.2" + }, + "peerDependenciesMeta": { + "@nomicfoundation/hardhat-verify": { + "optional": true + } + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/undici": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "dev": true, + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.37.0.tgz", + "integrity": "sha512-vpxe60KrbFubY09vlGZqBJdBXs0IqvZmH7+UueFiM0xK/V12lMwxyiNXkFv8+HZ7K8abRevYphVtEzrUWelQhQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/slang": "^0.17.0", + "cbor": "^9.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimatch": "^9.0.5", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.51" + }, + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@scure/base": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", - "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.8.tgz", + "integrity": "sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg==", "dev": true, "funding": { "url": "https://paulmillr.com/funding/" @@ -2036,9 +2466,9 @@ } }, "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "dependencies": { "@noble/hashes": "1.4.0" @@ -2100,12 +2530,6 @@ "node": ">=6" } }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@sentry/hub": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", @@ -2120,12 +2544,6 @@ "node": ">=6" } }, - "node_modules/@sentry/hub/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@sentry/minimal": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", @@ -2140,12 +2558,6 @@ "node": ">=6" } }, - "node_modules/@sentry/minimal/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@sentry/node": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", @@ -2166,12 +2578,6 @@ "node": ">=6" } }, - "node_modules/@sentry/node/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@sentry/tracing": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", @@ -2188,12 +2594,6 @@ "node": ">=6" } }, - "node_modules/@sentry/tracing/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@sentry/types": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", @@ -2216,10 +2616,22 @@ "node": ">=6" } }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/types/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, "node_modules/@solidity-parser/parser": { @@ -2288,9 +2700,9 @@ "dev": true }, "node_modules/@typechain/ethers-v6": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.4.3.tgz", - "integrity": "sha512-TrxBsyb4ryhaY9keP6RzhFCviWYApcLCIRMPyWaKp2cZZrfaM3QBoxXTnw/eO4+DAY3l+8O0brNW0WgeQeOiDA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", "dev": true, "dependencies": { "lodash": "^4.17.15", @@ -2298,23 +2710,23 @@ }, "peerDependencies": { "ethers": "6.x", - "typechain": "^8.3.1", + "typechain": "^8.3.2", "typescript": ">=4.7.0" } }, "node_modules/@typechain/hardhat": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-8.0.3.tgz", - "integrity": "sha512-MytSmJJn+gs7Mqrpt/gWkTCOpOQ6ZDfRrRT2gtZL0rfGe4QrU4x9ZdW15fFbVM/XTa+5EsKiOMYXhRABibNeng==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", + "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", "dev": true, "dependencies": { "fs-extra": "^9.1.0" }, "peerDependencies": { - "@typechain/ethers-v6": "^0.4.3", + "@typechain/ethers-v6": "^0.5.1", "ethers": "^6.1.0", "hardhat": "^2.9.9", - "typechain": "^8.3.1" + "typechain": "^8.3.2" } }, "node_modules/@typechain/hardhat/node_modules/fs-extra": { @@ -2342,9 +2754,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", "dev": true }, "node_modules/@types/chai-as-promised": { @@ -2436,12 +2848,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "20.16.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.4.tgz", + "integrity": "sha512-ioyQ1zK9aGEomJ45zz8S8IdzElyxhvP1RVWnPrXDf6wFaUb+kk1tEcVVJkF7RPGM0VWI7cp5U57oCPIn5iN1qg==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/pbkdf2": { @@ -2524,9 +2936,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2647,9 +3059,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2685,9 +3097,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2726,9 +3138,9 @@ "devOptional": true }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2826,6 +3238,19 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amazon-cognito-identity-js": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.12.tgz", + "integrity": "sha512-s7NKDZgx336cp+oDeUtB2ZzT8jWJp/v2LWuYl+LQtMEODe22RF1IJ4nRiDATp+rp1pTffCZcm44Quw4jx2bqNg==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, "node_modules/amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -3007,6 +3432,15 @@ "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dev": true, + "dependencies": { + "retry": "0.13.1" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3038,12 +3472,14 @@ } }, "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/balanced-match": { @@ -3053,9 +3489,9 @@ "devOptional": true }, "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", "dev": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -3199,13 +3635,12 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -3267,27 +3702,14 @@ } }, "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "node_modules/buffer-from": { @@ -3340,30 +3762,6 @@ "node": ">= 10" } }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cacache/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -3451,9 +3849,9 @@ } }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -3462,7 +3860,7 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" @@ -3860,6 +4258,12 @@ "dot-prop": "^5.1.0" } }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4034,9 +4438,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "devOptional": true, "dependencies": { "ms": "2.1.2" @@ -4152,9 +4556,9 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -4332,9 +4736,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -4539,6 +4943,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -4579,6 +4993,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -4622,9 +5048,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4751,19 +5177,8 @@ } ], "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { @@ -4827,21 +5242,21 @@ } }, "node_modules/ethereum-bloom-filters": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", - "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", "dev": true, "dependencies": { "@noble/hashes": "^1.4.0" } }, "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", "dev": true, "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -4927,9 +5342,9 @@ } }, "node_modules/ethers": { - "version": "6.13.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", - "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.2.tgz", + "integrity": "sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg==", "dev": true, "funding": [ { @@ -4960,6 +5375,12 @@ "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", "dev": true }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", @@ -5017,6 +5438,12 @@ "resolved": "https://registry.npmjs.org/extra-bigint/-/extra-bigint-1.1.18.tgz", "integrity": "sha512-edCTFKhq84Htzmg3MTii8TNsyQlIIG5k9f/OJ7/PrX80Ob57GXtIW6PJt/UqRvyCa4TgYKhmYVRfQfajL3ku0w==" }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5063,6 +5490,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -5073,15 +5506,14 @@ } }, "node_modules/fhevmjs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fhevmjs/-/fhevmjs-0.5.0.tgz", - "integrity": "sha512-H68CZrlVrgQgOGKOuVwuNl5gvwBOnIhpAMnf8AboKaBZeesiup/i2tbyh+/eRvpr3uhRkwGtndSnneutYvhY+A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fhevmjs/-/fhevmjs-0.5.2.tgz", + "integrity": "sha512-p/p4VTuUUohhGLZ8UgWUnO0rbuw5VummB4fAovUyILeyJ0oBVpGKKwkoaBXNKv40HDo+mvpkDBi6+HdSsMHvNg==", "dev": true, "dependencies": { "@types/keccak": "^3.0.4", "bigint-buffer": "^1.1.5", "commander": "^11.0.0", - "ethers": "^6.6.4", "node-fetch": "^2.7.0", "node-tfhe": "^0.6.3", "sha3": "^2.1.4", @@ -5091,6 +5523,9 @@ }, "bin": { "fhevm": "bin/fhevm.js" + }, + "engines": { + "node": ">=20" } }, "node_modules/file-entry-cache": { @@ -5205,9 +5640,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "dev": true, "funding": [ { @@ -5283,17 +5718,6 @@ "node": ">= 8" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -5306,6 +5730,20 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "devOptional": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5503,6 +5941,28 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -5625,9 +6085,9 @@ } }, "node_modules/hardhat": { - "version": "2.22.8", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.8.tgz", - "integrity": "sha512-hPh2feBGRswkXkoXUFW6NbxgiYtEzp/3uvVFjYROy6fA9LH8BobUyxStlyhSKj4+v1Y23ZoUBOVWL84IcLACrA==", + "version": "2.22.10", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.10.tgz", + "integrity": "sha512-JRUDdiystjniAvBGFmJRsiIZSOP2/6s++8xRDe3TzLeQXlWWHsXBrd9wd3JWFyKXvgMqMeLL5Sz/oNxXKYw9vg==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -5722,6 +6182,15 @@ "zksync-web3": "^0.14.3" } }, + "node_modules/hardhat-deploy/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/hardhat-deploy/node_modules/ethers": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", @@ -5805,15 +6274,6 @@ "solidity-comments": "^0.0.2" } }, - "node_modules/hardhat-ignore-warnings/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/hardhat-ignore-warnings/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -6313,18 +6773,29 @@ ] }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", "dev": true }, "node_modules/import-fresh": { @@ -6428,12 +6899,6 @@ "node": ">= 12" } }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "optional": true - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -6610,12 +7075,28 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "devOptional": true }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, "node_modules/javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", "dev": true }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "dev": true + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -6676,6 +7157,13 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "peer": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6730,6 +7218,16 @@ "node": ">=0.10.0" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6826,12 +7324,15 @@ "dev": true }, "node_modules/lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": "14 || >=16.14" + "node": ">=10" } }, "node_modules/make-error": { @@ -6867,30 +7368,6 @@ "node": ">= 10" } }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/markdown-table": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", @@ -6939,9 +7416,9 @@ "dev": true }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -6996,15 +7473,18 @@ "dev": true }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -7016,10 +7496,12 @@ } }, "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { "node": ">=8" } @@ -7036,18 +7518,6 @@ "node": ">= 8" } }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-fetch": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", @@ -7065,18 +7535,6 @@ "encoding": "^0.1.12" } }, - "node_modules/minipass-fetch/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", @@ -7089,18 +7547,6 @@ "node": ">= 8" } }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -7113,18 +7559,6 @@ "node": ">=8" } }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", @@ -7137,18 +7571,6 @@ "node": ">=8" } }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -7161,17 +7583,6 @@ "node": ">= 8" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -7199,81 +7610,40 @@ } }, "node_modules/mocha": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.5.2.tgz", - "integrity": "sha512-9btlN3JKCefPf+vKd/kcKz2SXxi12z6JswkGfaAF0saQvnsqLJk504ZmbxhSoENge08E9dsymozKgFMTl5PQsA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/mocha/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -7295,9 +7665,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7361,6 +7731,26 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -7377,9 +7767,9 @@ "dev": true }, "node_modules/node-abi": { - "version": "3.65.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", - "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", + "version": "3.67.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", + "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", "dependencies": { "semver": "^7.3.5" }, @@ -7458,9 +7848,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -7783,6 +8173,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/path-scurry/node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -7827,9 +8223,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -7897,9 +8293,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -7912,14 +8308,13 @@ } }, "node_modules/prettier-plugin-solidity": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.3.1.tgz", - "integrity": "sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.4.1.tgz", + "integrity": "sha512-Mq8EtfacVZ/0+uDKTtHZGW3Aa7vEbX/BNx63hmVg6YTiTXSiuKP0amj0G6pGwjmLaOfymWh3QgXEZkjQbU8QRg==", "dev": true, "dependencies": { - "@solidity-parser/parser": "^0.17.0", - "semver": "^7.5.4", - "solidity-comments-extractor": "^0.0.8" + "@solidity-parser/parser": "^0.18.0", + "semver": "^7.5.4" }, "engines": { "node": ">=16" @@ -7929,15 +8324,15 @@ } }, "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.17.0.tgz", - "integrity": "sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", "dev": true }, "node_modules/prettier-plugin-solidity/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -7980,6 +8375,49 @@ "node": ">=10" } }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proper-lockfile/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -8005,9 +8443,9 @@ } }, "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, "dependencies": { "side-channel": "^1.0.6" @@ -8134,6 +8572,28 @@ "node": ">=6.0.0" } }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/reduce-flatten": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", @@ -8216,10 +8676,10 @@ } }, "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "optional": true, + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, "engines": { "node": ">= 4" } @@ -8252,15 +8712,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/rimraf/node_modules/glob": { "version": "9.3.5", "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", @@ -8294,6 +8745,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -8398,6 +8858,16 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/sc-istanbul/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/sc-istanbul/node_modules/glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -8450,12 +8920,30 @@ "node": ">=4" } }, + "node_modules/sc-istanbul/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/sc-istanbul/node_modules/resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true }, + "node_modules/sc-istanbul/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/sc-istanbul/node_modules/supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -8511,9 +8999,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -8589,6 +9077,30 @@ "buffer": "6.0.3" } }, + "node_modules/sha3/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -8655,7 +9167,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true + "devOptional": true }, "node_modules/simple-concat": { "version": "1.0.1", @@ -8700,6 +9212,13 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "peer": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8803,6 +9322,12 @@ "semver": "bin/semver" } }, + "node_modules/solidity-ast": { + "version": "0.4.58", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.58.tgz", + "integrity": "sha512-fiAEDlMEc+xziMn0IpZf2vUbqxyXYZK4BqBiTaz2ZUqOP0p1fdJzUc9xpv74Jdxb5BLAiCUFv5UenkXIpHn3cA==", + "dev": true + }, "node_modules/solidity-comments": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/solidity-comments/-/solidity-comments-0.0.2.tgz", @@ -8856,12 +9381,6 @@ "node": ">= 10" } }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.8.tgz", - "integrity": "sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g==", - "dev": true - }, "node_modules/solidity-comments-freebsd-x64": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/solidity-comments-freebsd-x64/-/solidity-comments-freebsd-x64-0.0.2.tgz", @@ -9131,9 +9650,9 @@ } }, "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -9191,11 +9710,21 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true }, "node_modules/sqlite3": { "version": "5.1.7", @@ -9237,18 +9766,6 @@ "node": ">= 8" } }, - "node_modules/ssri/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", @@ -9429,15 +9946,15 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -9570,6 +10087,16 @@ "node": ">= 0.12" } }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -9807,9 +10334,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "node_modules/tsort": { @@ -9833,12 +10360,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -9875,9 +10396,9 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "engines": { "node": ">=4" @@ -9919,6 +10440,16 @@ "typescript": ">=4.3.0" } }, + "node_modules/typechain/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/typechain/node_modules/fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -9963,6 +10494,18 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/typechain/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/typechain/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -10006,9 +10549,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10028,9 +10571,9 @@ } }, "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, "optional": true, "bin": { @@ -10053,9 +10596,15 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", "dev": true }, "node_modules/unique-filename": { @@ -10104,13 +10653,16 @@ } }, "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "dev": true, "dependencies": { "punycode": "^1.4.1", - "qs": "^6.11.2" + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/url/node_modules/punycode": { @@ -10159,12 +10711,12 @@ "dev": true }, "node_modules/web3-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.2.0.tgz", - "integrity": "sha512-58Kczou5zyjcm9LuSs5Hrm6VrG8t9p2J8X0yGArZrhKNPZL66gMGkOUpPx+EopE944Sk4yE+Q25hKv4H5BH+kA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.3.0.tgz", + "integrity": "sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ==", "dev": true, "dependencies": { - "web3-types": "^1.6.0" + "web3-types": "^1.7.0" }, "engines": { "node": ">=14", @@ -10201,9 +10753,9 @@ } }, "node_modules/web3-utils/node_modules/@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "dependencies": { "@noble/hashes": "1.4.0" @@ -10225,12 +10777,12 @@ } }, "node_modules/web3-utils/node_modules/ethereum-cryptography": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", - "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "dependencies": { - "@noble/curves": "1.4.0", + "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" @@ -10254,9 +10806,9 @@ } }, "node_modules/web3-validator/node_modules/@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "dependencies": { "@noble/hashes": "1.4.0" @@ -10278,12 +10830,12 @@ } }, "node_modules/web3-validator/node_modules/ethereum-cryptography": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", - "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "dependencies": { - "@noble/curves": "1.4.0", + "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" @@ -10398,9 +10950,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { @@ -10479,9 +11031,9 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" diff --git a/package.json b/package.json index 9a01d156..5ed80b8c 100644 --- a/package.json +++ b/package.json @@ -56,11 +56,13 @@ "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-network-helpers": "^1.0.6", - "@nomicfoundation/hardhat-toolbox": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.10", + "@openzeppelin/contracts-upgradeable": "^5.0.2", + "@openzeppelin/hardhat-upgrades": "^3.2.1", "@trivago/prettier-plugin-sort-imports": "^4.0.0", - "@typechain/ethers-v6": "^0.4.0", - "@typechain/hardhat": "^8.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.4", "@types/fs-extra": "^9.0.13", "@types/mocha": "^10.0.0", @@ -77,7 +79,7 @@ "eslint-config-prettier": "^8.5.0", "ethers": "^6.8.0", "fhevmjs": "^0.5.0", - "hardhat": "^2.22.8", + "hardhat": "^2.22.10", "hardhat-deploy": "^0.11.29", "hardhat-gas-reporter": "^1.0.2", "hardhat-ignore-warnings": "^0.2.11", diff --git a/payment/Payment.sol b/payment/Payment.sol index 0197a5a6..09f844f8 100644 --- a/payment/Payment.sol +++ b/payment/Payment.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.24; -import "../lib/FHEPaymentAddress.sol"; +import "../lib/FHEVMConfig.sol"; +import "../lib/Impl.sol"; interface IFHEPayment { function depositETH(address account) external payable; @@ -12,26 +13,32 @@ interface IFHEPayment { library Payment { function depositForAccount(address account, uint256 amount) internal { - IFHEPayment(fhePaymentAdd).depositETH{value: amount}(account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).depositETH{value: amount}(account); } function depositForThis(uint256 amount) internal { - IFHEPayment(fhePaymentAdd).depositETH{value: amount}(address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).depositETH{value: amount}(address(this)); } function withdrawToAccount(address account, uint256 amount) internal { - IFHEPayment(fhePaymentAdd).withdrawETH(amount, account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).withdrawETH(amount, account); } function withdrawToThis(uint256 amount) internal { - IFHEPayment(fhePaymentAdd).withdrawETH(amount, address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + IFHEPayment($.FHEPaymentAddress).withdrawETH(amount, address(this)); } function getDepositedBalanceOfAccount(address account) internal view returns (uint256) { - return IFHEPayment(fhePaymentAdd).getAvailableDepositsETH(account); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + return IFHEPayment($.FHEPaymentAddress).getAvailableDepositsETH(account); } function getDepositedBalanceOfThis() internal view returns (uint256) { - return IFHEPayment(fhePaymentAdd).getAvailableDepositsETH(address(this)); + FHEVMConfig.FHEVMConfigStruct storage $ = Impl.getFHEVMConfig(); + return IFHEPayment($.FHEPaymentAddress).getAvailableDepositsETH(address(this)); } } diff --git a/tasks/taskDeploy.ts b/tasks/taskDeploy.ts index 2d9b226b..b6d851fc 100644 --- a/tasks/taskDeploy.ts +++ b/tasks/taskDeploy.ts @@ -15,13 +15,13 @@ task('task:deployERC20').setAction(async function (taskArguments: TaskArguments, task('task:deployGateway') .addParam('privateKey', 'The deployer private key') .addParam('ownerAddress', 'The owner address') - .setAction(async function (taskArguments: TaskArguments, { ethers }) { + .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) { const deployer = new ethers.Wallet(taskArguments.privateKey).connect(ethers.provider); - const envConfig2 = dotenv.parse(fs.readFileSync('lib/.env.kmsverifier')); - const gatewayFactory = await ethers.getContractFactory('GatewayContract'); - const Gateway = await gatewayFactory - .connect(deployer) - .deploy(taskArguments.ownerAddress, envConfig2.KMS_VERIFIER_CONTRACT_ADDRESS); + const factory = await ethers.getContractFactory('GatewayContract', deployer); + const Gateway = await upgrades.deployProxy(factory, [taskArguments.ownerAddress], { + initializer: 'initialize', + kind: 'uups', + }); await Gateway.waitForDeployment(); const GatewayContractAddress = await Gateway.getAddress(); const envConfig = dotenv.parse(fs.readFileSync('gateway/.env.gateway')); @@ -60,54 +60,54 @@ task('task:deployIdentity').setAction(async function (taskArguments: TaskArgumen console.log(`npx hardhat task:identity:balanceOf --erc20 ${erc20Address} --user alice`); }); -task('task:deployACL').setAction(async function (taskArguments: TaskArguments, { ethers }) { +task('task:deployACL').setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) { const deployer = (await ethers.getSigners())[9]; - const factory = await ethers.getContractFactory('ACL'); - const acl = await factory.connect(deployer).deploy(); + const factory = await ethers.getContractFactory('ACL', deployer); + const acl = await upgrades.deployProxy(factory, [deployer.address], { initializer: 'initialize', kind: 'uups' }); await acl.waitForDeployment(); const address = await acl.getAddress(); const envConfigAcl = dotenv.parse(fs.readFileSync('lib/.env.acl')); if (address !== envConfigAcl.ACL_CONTRACT_ADDRESS) { - throw new Error(`The nonce of the deployer account is not corret. Please relaunch a clean instance of the fhEVM`); + throw new Error(`The nonce of the deployer account is not correct. Please relaunch a clean instance of the fhEVM`); } console.log('ACL was deployed at address:', address); }); -task('task:deployTFHEExecutor').setAction(async function (taskArguments: TaskArguments, { ethers }) { +task('task:deployTFHEExecutor').setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) { const deployer = (await ethers.getSigners())[9]; - const factory = await ethers.getContractFactory('TFHEExecutor'); - const exec = await factory.connect(deployer).deploy(); + const factory = await ethers.getContractFactory('TFHEExecutor', deployer); + const exec = await upgrades.deployProxy(factory, [deployer.address], { initializer: 'initialize', kind: 'uups' }); await exec.waitForDeployment(); const address = await exec.getAddress(); const envConfig = dotenv.parse(fs.readFileSync('lib/.env.exec')); if (address !== envConfig.TFHE_EXECUTOR_CONTRACT_ADDRESS) { - throw new Error(`The nonce of the deployer account is not corret. Please relaunch a clean instance of the fhEVM`); + throw new Error(`The nonce of the deployer account is not correct. Please relaunch a clean instance of the fhEVM`); } console.log('TFHEExecutor was deployed at address:', address); }); -task('task:deployKMSVerifier').setAction(async function (taskArguments: TaskArguments, { ethers }) { +task('task:deployKMSVerifier').setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) { const deployer = (await ethers.getSigners())[9]; - const factory = await ethers.getContractFactory('KMSVerifier'); - const exec = await factory.connect(deployer).deploy(); - await exec.waitForDeployment(); - const address = await exec.getAddress(); + const factory = await ethers.getContractFactory('KMSVerifier', deployer); + const kms = await upgrades.deployProxy(factory, [deployer.address], { initializer: 'initialize', kind: 'uups' }); + await kms.waitForDeployment(); + const address = await kms.getAddress(); const envConfig = dotenv.parse(fs.readFileSync('lib/.env.kmsverifier')); if (address !== envConfig.KMS_VERIFIER_CONTRACT_ADDRESS) { - throw new Error(`The nonce of the deployer account is not corret. Please relaunch a clean instance of the fhEVM`); + throw new Error(`The nonce of the deployer account is not correct. Please relaunch a clean instance of the fhEVM`); } console.log('KMSVerifier was deployed at address:', address); }); -task('task:deployFHEPayment').setAction(async function (taskArguments: TaskArguments, { ethers }) { +task('task:deployFHEPayment').setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) { const deployer = (await ethers.getSigners())[9]; - const factory = await ethers.getContractFactory('FHEPayment'); - const exec = await factory.connect(deployer).deploy(); - await exec.waitForDeployment(); - const address = await exec.getAddress(); + const factory = await ethers.getContractFactory('FHEPayment', deployer); + const payment = await upgrades.deployProxy(factory, [deployer.address], { initializer: 'initialize', kind: 'uups' }); + await payment.waitForDeployment(); + const address = await payment.getAddress(); const envConfig = dotenv.parse(fs.readFileSync('lib/.env.fhepayment')); if (address !== envConfig.FHE_PAYMENT_CONTRACT_ADDRESS) { - throw new Error(`The nonce of the deployer account is not corret. Please relaunch a clean instance of the fhEVM`); + throw new Error(`The nonce of the deployer account is not correct. Please relaunch a clean instance of the fhEVM`); } console.log('FHEPayment was deployed at address:', address); }); diff --git a/tasks/taskGatewayRelayer.ts b/tasks/taskGatewayRelayer.ts index 8f002cf6..945024f3 100644 --- a/tasks/taskGatewayRelayer.ts +++ b/tasks/taskGatewayRelayer.ts @@ -21,10 +21,10 @@ task('task:computePredeployAddress') const deployerAddress = new ethers.Wallet(taskArguments.privateKey).address; const gatewayContractAddressPrecomputed = ethers.getCreateAddress({ from: deployerAddress, - nonce: 0, // deployer is supposed to have nonce 0 when deploying GatewayContract + nonce: 1, // deployer is supposed to have nonce 0 when deploying GatewayContract (0 nonce for implementation, +1 for UUPS) }); const envFilePath = path.join(__dirname, '../gateway/.env.gateway'); - const content = `GATEWAY_CONTRACT_PREDEPLOY_ADDRESS=${gatewayContractAddressPrecomputed}\n`; + const content = `GATEWAY_CONTRACT_PREDEPLOY_ADDRESS=${gatewayContractAddressPrecomputed}`; try { fs.writeFileSync(envFilePath, content, { flag: 'w' }); console.log('gatewayContractAddress written to gateway/.env.gateway successfully!'); @@ -37,13 +37,13 @@ task('task:computePredeployAddress') pragma solidity ^0.8.24; address constant GATEWAY_CONTRACT_PREDEPLOY_ADDRESS = ${gatewayContractAddressPrecomputed}; - `; +`; try { - fs.writeFileSync('./gateway/lib/PredeployAddress.sol', solidityTemplate, { encoding: 'utf8', flag: 'w' }); - console.log('gateway/lib/PredeployAddress.sol file has been generated successfully.'); + fs.writeFileSync('./gateway/lib/GatewayContractAddress.sol', solidityTemplate, { encoding: 'utf8', flag: 'w' }); + console.log('gateway/lib/GatewayContractAddress.sol file has been generated successfully.'); } catch (error) { - console.error('Failed to write gateway/lib/PredeployAddress.sol', error); + console.error('Failed to write gateway/lib/GatewayContractAddress.sol', error); } }); diff --git a/tasks/taskTFHE.ts b/tasks/taskTFHE.ts index 9872f9b3..04e5cc38 100644 --- a/tasks/taskTFHE.ts +++ b/tasks/taskTFHE.ts @@ -7,7 +7,7 @@ task('task:computeACLAddress').setAction(async function (taskArguments: TaskArgu const deployer = (await ethers.getSigners())[9].address; const aclAddress = ethers.getCreateAddress({ from: deployer, - nonce: 0, // using nonce of 0 for the ACL contract + nonce: 1, // using nonce of 1 for the ACL contract (0 for original implementation, +1 for proxy) }); const envFilePath = path.join(__dirname, '../lib/.env.acl'); const content = `ACL_CONTRACT_ADDRESS=${aclAddress}\n`; @@ -36,7 +36,7 @@ task('task:computeTFHEExecutorAddress').setAction(async function (taskArguments: const deployer = (await ethers.getSigners())[9].address; const execAddress = ethers.getCreateAddress({ from: deployer, - nonce: 1, // using nonce of 1 for the TFHEExecutor contract + nonce: 3, // using nonce of 3 for the TFHEExecutor contract (2 for original implementation, +1 for proxy) }); const envFilePath = path.join(__dirname, '../lib/.env.exec'); const content = `TFHE_EXECUTOR_CONTRACT_ADDRESS=${execAddress}\n`; @@ -65,7 +65,7 @@ task('task:computeKMSVerifierAddress').setAction(async function (taskArguments: const deployer = (await ethers.getSigners())[9].address; const kmsVerfierAddress = ethers.getCreateAddress({ from: deployer, - nonce: 2, // using nonce of 2 for the Kms Verifier contract + nonce: 5, // using nonce of 5 for the KMSVerifier contract (4 for original implementation, +1 for proxy) }); const envFilePath = path.join(__dirname, '../lib/.env.kmsverifier'); const content = `KMS_VERIFIER_CONTRACT_ADDRESS=${kmsVerfierAddress}\n`; @@ -94,7 +94,7 @@ task('task:computeFHEPaymentAddress').setAction(async function (taskArguments: T const deployer = (await ethers.getSigners())[9].address; const fhePaymentAddress = ethers.getCreateAddress({ from: deployer, - nonce: 3, // using nonce of 3 for the FHEPayment contract + nonce: 7, // using nonce of 7 for the FHEPayment contract (6 for original implementation, +1 for proxy) }); const envFilePath = path.join(__dirname, '../lib/.env.fhepayment'); const content = `FHE_PAYMENT_CONTRACT_ADDRESS=${fhePaymentAddress}\n`; diff --git a/test/asyncDecrypt.ts b/test/asyncDecrypt.ts index 2f5237aa..1c6eacb3 100644 --- a/test/asyncDecrypt.ts +++ b/test/asyncDecrypt.ts @@ -9,7 +9,7 @@ import { waitNBlocks } from './utils'; const networkName = network.name; const parsedEnvACL = dotenv.parse(fs.readFileSync('lib/.env.acl')); -const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS.replace(/^0x/, '').replace(/^0+/, '').toLowerCase(); +const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS; const CiphertextType = { 0: 'bool', @@ -123,8 +123,8 @@ const fulfillAllPastRequestsIds = async (mocked: boolean) => { // first check tat all handles are allowed for decryption const aclFactory = await ethers.getContractFactory('ACL'); - const acl = aclFactory.attach(`0x${aclAdd}`); - const isAllowedForDec = await Promise.all(handles.map(async (handle) => acl.allowedForDecryption(handle))); + const acl = aclFactory.attach(aclAdd); + const isAllowedForDec = await Promise.all(handles.map(async (handle) => acl.isAllowedForDecryption(handle))); if (!allTrue(isAllowedForDec)) { throw new Error('Some handle is not authorized for decryption'); } diff --git a/test/encryptedERC20/EncryptedERC20.ts b/test/encryptedERC20/EncryptedERC20.ts index 3f493151..d9cecca5 100644 --- a/test/encryptedERC20/EncryptedERC20.ts +++ b/test/encryptedERC20/EncryptedERC20.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { createInstances, decrypt64 } from '../instance'; +import { createInstances } from '../instance'; import { getSigners, initSigners } from '../signers'; import { deployEncryptedERC20Fixture } from './EncryptedERC20.fixture'; @@ -21,9 +21,24 @@ describe('EncryptedERC20', function () { const transaction = await this.erc20.mint(1000); await transaction.wait(); - const balanceHandle = await this.erc20.balanceOf(this.signers.alice); - const balance = await decrypt64(balanceHandle); - expect(balance).to.equal(1000); + // Reencrypt Alice's balance + const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); + const { publicKey: publicKeyAlice, privateKey: privateKeyAlice } = this.instances.alice.generateKeypair(); + const eip712 = this.instances.alice.createEIP712(publicKeyAlice, this.contractAddress); + const signatureAlice = await this.signers.alice.signTypedData( + eip712.domain, + { Reencrypt: eip712.types.Reencrypt }, + eip712.message, + ); + const balanceAlice = await this.instances.alice.reencrypt( + balanceHandleAlice, + privateKeyAlice, + publicKeyAlice, + signatureAlice.replace('0x', ''), + this.contractAddress, + this.signers.alice.address, + ); + expect(balanceAlice).to.equal(1000); const totalSupply = await this.erc20.totalSupply(); expect(totalSupply).to.equal(1000); @@ -45,21 +60,51 @@ describe('EncryptedERC20', function () { const t2 = await tx.wait(); expect(t2?.status).to.eq(1); - // Decrypt Alice's balance + // Reencrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); - const balanceAlice = await decrypt64(balanceHandleAlice); + const { publicKey: publicKeyAlice, privateKey: privateKeyAlice } = this.instances.alice.generateKeypair(); + const eip712 = this.instances.alice.createEIP712(publicKeyAlice, this.contractAddress); + const signatureAlice = await this.signers.alice.signTypedData( + eip712.domain, + { Reencrypt: eip712.types.Reencrypt }, + eip712.message, + ); + const balanceAlice = await this.instances.alice.reencrypt( + balanceHandleAlice, + privateKeyAlice, + publicKeyAlice, + signatureAlice.replace('0x', ''), + this.contractAddress, + this.signers.alice.address, + ); + expect(balanceAlice).to.equal(10000 - 1337); - // Decrypt Bob's balance + // Reencrypt Bob's balance const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await decrypt64(balanceHandleBob); + + const { publicKey: publicKeyBob, privateKey: privateKeyBob } = this.instances.bob.generateKeypair(); + const eip712Bob = this.instances.bob.createEIP712(publicKeyBob, this.contractAddress); + const signatureBob = await this.signers.bob.signTypedData( + eip712Bob.domain, + { Reencrypt: eip712Bob.types.Reencrypt }, + eip712Bob.message, + ); + const balanceBob = await this.instances.bob.reencrypt( + balanceHandleBob, + privateKeyBob, + publicKeyBob, + signatureBob.replace('0x', ''), + this.contractAddress, + this.signers.bob.address, + ); + expect(balanceBob).to.equal(1337); }); - it('reencrypt - should transfer tokens between two users', async function () { - const transaction = await this.erc20.mint(10000); - const t1 = await transaction.wait(); - expect(t1?.status).to.eq(1); + it('should not transfer tokens between two users', async function () { + const transaction = await this.erc20.mint(1000); + await transaction.wait(); const input = this.instances.alice.createEncryptedInput(this.contractAddress, this.signers.alice.address); input.add64(1337); @@ -69,52 +114,46 @@ describe('EncryptedERC20', function () { encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof, ); - const t2 = await tx.wait(); - expect(t2?.status).to.eq(1); + await tx.wait(); - // Decrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); - const { publicKey, privateKey } = this.instances.alice.generateKeypair(); - const eip712 = this.instances.alice.createEIP712(publicKey, this.contractAddress); - const signature = await this.signers.alice.signTypedData( + const { publicKey: publicKeyAlice, privateKey: privateKeyAlice } = this.instances.alice.generateKeypair(); + const eip712 = this.instances.alice.createEIP712(publicKeyAlice, this.contractAddress); + const signatureAlice = await this.signers.alice.signTypedData( eip712.domain, { Reencrypt: eip712.types.Reencrypt }, eip712.message, ); const balanceAlice = await this.instances.alice.reencrypt( balanceHandleAlice, - privateKey, - publicKey, - signature.replace('0x', ''), + privateKeyAlice, + publicKeyAlice, + signatureAlice.replace('0x', ''), this.contractAddress, this.signers.alice.address, ); - expect(balanceAlice).to.equal(10000 - 1337); - }); + expect(balanceAlice).to.equal(1000); - it('should not transfer tokens between two users', async function () { - const transaction = await this.erc20.mint(1000); - await transaction.wait(); + // Reencrypt Bob's balance + const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const input = this.instances.alice.createEncryptedInput(this.contractAddress, this.signers.alice.address); - input.add64(1337); - const encryptedTransferAmount = input.encrypt(); - const tx = await this.erc20['transfer(address,bytes32,bytes)']( + const { publicKey: publicKeyBob, privateKey: privateKeyBob } = this.instances.bob.generateKeypair(); + const eip712Bob = this.instances.bob.createEIP712(publicKeyBob, this.contractAddress); + const signatureBob = await this.signers.bob.signTypedData( + eip712Bob.domain, + { Reencrypt: eip712Bob.types.Reencrypt }, + eip712Bob.message, + ); + const balanceBob = await this.instances.bob.reencrypt( + balanceHandleBob, + privateKeyBob, + publicKeyBob, + signatureBob.replace('0x', ''), + this.contractAddress, this.signers.bob.address, - encryptedTransferAmount.handles[0], - encryptedTransferAmount.inputProof, ); - await tx.wait(); - // Decrypt Alice's balance - const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); - const balanceAlice = await decrypt64(balanceHandleAlice); - expect(balanceAlice).to.equal(1000); - - // Decrypt Bob's balance - const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await decrypt64(balanceHandleBob); expect(balanceBob).to.equal(0); }); @@ -146,12 +185,40 @@ describe('EncryptedERC20', function () { // Decrypt Alice's balance const balanceHandleAlice = await this.erc20.balanceOf(this.signers.alice); - const balanceAlice = await decrypt64(balanceHandleAlice); + const { publicKey: publicKeyAlice, privateKey: privateKeyAlice } = this.instances.alice.generateKeypair(); + const eip712 = this.instances.alice.createEIP712(publicKeyAlice, this.contractAddress); + const signatureAlice = await this.signers.alice.signTypedData( + eip712.domain, + { Reencrypt: eip712.types.Reencrypt }, + eip712.message, + ); + const balanceAlice = await this.instances.alice.reencrypt( + balanceHandleAlice, + privateKeyAlice, + publicKeyAlice, + signatureAlice.replace('0x', ''), + this.contractAddress, + this.signers.alice.address, + ); expect(balanceAlice).to.equal(10000); // check that transfer did not happen, as expected // Decrypt Bob's balance const balanceHandleBob = await this.erc20.balanceOf(this.signers.bob); - const balanceBob = await decrypt64(balanceHandleBob); + const { publicKey: publicKeyBob, privateKey: privateKeyBob } = this.instances.bob.generateKeypair(); + const eip712Bob = this.instances.bob.createEIP712(publicKeyBob, this.contractAddress); + const signatureBob = await this.signers.bob.signTypedData( + eip712Bob.domain, + { Reencrypt: eip712Bob.types.Reencrypt }, + eip712Bob.message, + ); + const balanceBob = await this.instances.bob.reencrypt( + balanceHandleBob, + privateKeyBob, + publicKeyBob, + signatureBob.replace('0x', ''), + this.contractAddress, + this.signers.bob.address, + ); expect(balanceBob).to.equal(0); // check that transfer did not happen, as expected const inputBob2 = this.instances.bob.createEncryptedInput(this.contractAddress, this.signers.bob.address); @@ -167,12 +234,26 @@ describe('EncryptedERC20', function () { // Decrypt Alice's balance const balanceHandleAlice2 = await this.erc20.balanceOf(this.signers.alice); - const balanceAlice2 = await decrypt64(balanceHandleAlice2); + const balanceAlice2 = await this.instances.alice.reencrypt( + balanceHandleAlice2, + privateKeyAlice, + publicKeyAlice, + signatureAlice.replace('0x', ''), + this.contractAddress, + this.signers.alice.address, + ); expect(balanceAlice2).to.equal(10000 - 1337); // check that transfer did happen this time // Decrypt Bob's balance const balanceHandleBob2 = await this.erc20.balanceOf(this.signers.bob); - const balanceBob2 = await decrypt64(balanceHandleBob2); - expect(balanceBob2).to.equal(1337); // check that transfer did happen this time + const balanceBob2 = await this.instances.bob.reencrypt( + balanceHandleBob2, + privateKeyBob, + publicKeyBob, + signatureBob.replace('0x', ''), + this.contractAddress, + this.signers.bob.address, + ); + expect(balanceBob2).to.equal(1337); // check that transfer did happen this time*/ }); }); diff --git a/test/fhevmjsMocked.ts b/test/fhevmjsMocked.ts index 5ec3c2c6..e34a608b 100644 --- a/test/fhevmjsMocked.ts +++ b/test/fhevmjsMocked.ts @@ -12,7 +12,7 @@ import { awaitCoprocessor, getClearText } from './coprocessorUtils'; const hre = require('hardhat'); const parsedEnvACL = dotenv.parse(fs.readFileSync('lib/.env.acl')); -const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS.replace(/^0x/, '').replace(/^0+/, '').toLowerCase(); +const aclAdd = parsedEnvACL.ACL_CONTRACT_ADDRESS; enum Types { ebool = 0, @@ -122,7 +122,7 @@ export const reencryptRequestMocked = async ( // ACL checking const aclFactory = await hre.ethers.getContractFactory('ACL'); - const acl = aclFactory.attach(`0x${aclAdd}`); + const acl = aclFactory.attach(aclAdd); const userAllowed = await acl.persistAllowed(handle, userAddress); const contractAllowed = await acl.persistAllowed(handle, contractAddress); const isAllowed = userAllowed && contractAllowed; diff --git a/test/instance.ts b/test/instance.ts index cee4a2ec..03090137 100644 --- a/test/instance.ts +++ b/test/instance.ts @@ -67,6 +67,15 @@ const getDecryptor = () => { return clientKeyDecryptor(clientKey); }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bool} + */ export const decryptBool = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -76,6 +85,15 @@ export const decryptBool = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ export const decrypt4 = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -85,6 +103,15 @@ export const decrypt4 = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ export const decrypt8 = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -94,6 +121,15 @@ export const decrypt8 = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ export const decrypt16 = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -103,6 +139,15 @@ export const decrypt16 = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ export const decrypt32 = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -112,6 +157,15 @@ export const decrypt32 = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {bigint} + */ export const decrypt64 = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); @@ -121,6 +175,15 @@ export const decrypt64 = async (handle: bigint): Promise => { } }; +/** + * @debug + * This function is intended for debugging purposes only. + * It cannot be used in production code, since it requires the FHE private key for decryption. + * In production, decryption is only possible via an asyncronous on-chain call to the Gateway. + * + * @param {bigint} a handle to decrypt + * @returns {string} + */ export const decryptAddress = async (handle: bigint): Promise => { if (network.name === 'hardhat') { await awaitCoprocessor(); diff --git a/test/upgrades/upgrades.ts b/test/upgrades/upgrades.ts new file mode 100644 index 00000000..48fdd23c --- /dev/null +++ b/test/upgrades/upgrades.ts @@ -0,0 +1,113 @@ +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('ACL'); + this.aclFactoryUpgraded = await ethers.getContractFactory('ACLUpgradedExample'); + this.kmsFactory = await ethers.getContractFactory('KMSVerifier'); + this.kmsFactoryUpgraded = await ethers.getContractFactory('KMSVerifierUpgradedExample'); + this.executorFactory = await ethers.getContractFactory('TFHEExecutor'); + this.executorFactoryUpgraded = await ethers.getContractFactory('TFHEExecutorUpgradedExample'); + this.paymentFactory = await ethers.getContractFactory('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('lib/.env.acl')).ACL_CONTRACT_ADDRESS; + const deployer = (await ethers.getSigners())[9]; + 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'); + }); +});