From 67641fbb8493a1b65f9f4278be615cdec7214e49 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 5 Jul 2023 12:34:05 +0200 Subject: [PATCH 1/3] Deployment script for WalletCoordinator upgrade We add a script for WalletCoordinator contract upgrade. The current WalletCoordinator contract deployed to mainnet is owned by Threshold Council, so it cannot be upgraded right away by the deployer. The deployer will deploy a fresh WalletCoordinator contract implementation, then Threshold Council need to execute transactions to upgrade the WalletCoordinator proxy to the new implementation and set the initial values for newely added parameters. --- .../81_upgrade_wallet_coordinator_v2.ts | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 solidity/deploy/81_upgrade_wallet_coordinator_v2.ts diff --git a/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts b/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts new file mode 100644 index 000000000..5428dbb5b --- /dev/null +++ b/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts @@ -0,0 +1,98 @@ +import { Artifact, HardhatRuntimeEnvironment } from "hardhat/types" +import { DeployFunction, Deployment } from "hardhat-deploy/types" +import { ContractFactory } from "ethers" +import { ProxyAdmin, WalletCoordinator } from "../typechain" + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { ethers, helpers, deployments } = hre + + const { deployer } = await helpers.signers.getNamedSigners() + + const proxyDeployment: Deployment = await deployments.get("WalletCoordinator") + const implementationContractFactory: ContractFactory = + await ethers.getContractFactory("WalletCoordinator", { + signer: deployer, + }) + + // Deploy new implementation contract + const newImplementationAddress: string = (await hre.upgrades.prepareUpgrade( + proxyDeployment, + implementationContractFactory, + { + kind: "transparent", + } + )) as string + + deployments.log( + `new implementation contract deployed at: ${newImplementationAddress}` + ) + + // Assemble proxy upgrade transaction. + const proxyAdmin: ProxyAdmin = await hre.upgrades.admin.getInstance() + const proxyAdminOwner = await proxyAdmin.owner() + + const upgradeTxData = await proxyAdmin.interface.encodeFunctionData( + "upgrade", + [proxyDeployment.address, newImplementationAddress] + ) + + deployments.log( + `proxy admin owner ${proxyAdminOwner} is required to upgrade proxy implementation with transaction:\n` + + `\t\tfrom: ${proxyAdminOwner}\n` + + `\t\tto: ${proxyAdmin.address}\n` + + `\t\tdata: ${upgradeTxData}` + ) + + // Assemble parameters upgrade transaction. + const walletCoordinator: WalletCoordinator = + await helpers.contracts.getContract("WalletCoordinator") + + const walletCoordinatorOwner = await walletCoordinator.owner() + + const updateRedemptionProposalParametersTxData = + walletCoordinator.interface.encodeFunctionData( + "updateRedemptionProposalParameters", + [7200, 600, 7200, 20, 20000] + ) + + deployments.log( + `WalletCoordinator owner ${walletCoordinatorOwner} is required to update redemption proposal parameters with transaction:\n` + + `\t\tfrom: ${walletCoordinatorOwner}\n` + + `\t\tto: ${walletCoordinator.address}\n` + + `\t\tdata: ${updateRedemptionProposalParametersTxData}` + ) + + // Update Deployment Artifact + const walletCoordinatorArtifact: Artifact = + hre.artifacts.readArtifactSync("WalletCoordinator") + + await deployments.save("WalletCoordinator", { + ...proxyDeployment, + abi: walletCoordinatorArtifact.abi, + implementation: newImplementationAddress, + }) + + if (hre.network.tags.etherscan) { + // We use `verify` instead of `verify:verify` as the `verify` task is defined + // in "@openzeppelin/hardhat-upgrades" to perform Etherscan verification + // of Proxy and Implementation contracts. + await hre.run("verify", { + address: proxyDeployment.address, + constructorArgsParams: proxyDeployment.args, + }) + } + + if (hre.network.tags.tenderly) { + await hre.tenderly.verify({ + name: "WalletCoordinator", + address: newImplementationAddress, + }) + } +} + +export default func + +func.tags = ["UpgradeWalletCoordinator"] +// When running an upgrade uncomment the skip below and run the command: +// yarn deploy --tags UpgradeWalletCoordinator --network +func.skip = async () => true From 0c405da4fda019fe7a8294329bf55dd9f0704af3 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 5 Jul 2023 13:49:02 +0200 Subject: [PATCH 2/3] Updates to WalletCoordinator upgrade script - cast type of proxy admin instance - update deployment artifact before referencing it in by `getContract("WalletCoordinator")` - verify implementation contract --- .../81_upgrade_wallet_coordinator_v2.ts | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts b/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts index 5428dbb5b..09f34895a 100644 --- a/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts +++ b/solidity/deploy/81_upgrade_wallet_coordinator_v2.ts @@ -28,7 +28,8 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ) // Assemble proxy upgrade transaction. - const proxyAdmin: ProxyAdmin = await hre.upgrades.admin.getInstance() + const proxyAdmin: ProxyAdmin = + (await hre.upgrades.admin.getInstance()) as ProxyAdmin const proxyAdminOwner = await proxyAdmin.owner() const upgradeTxData = await proxyAdmin.interface.encodeFunctionData( @@ -43,6 +44,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { `\t\tdata: ${upgradeTxData}` ) + // Update Deployment Artifact + const walletCoordinatorArtifact: Artifact = + hre.artifacts.readArtifactSync("WalletCoordinator") + + await deployments.save("WalletCoordinator", { + ...proxyDeployment, + abi: walletCoordinatorArtifact.abi, + implementation: newImplementationAddress, + }) + // Assemble parameters upgrade transaction. const walletCoordinator: WalletCoordinator = await helpers.contracts.getContract("WalletCoordinator") @@ -62,22 +73,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { `\t\tdata: ${updateRedemptionProposalParametersTxData}` ) - // Update Deployment Artifact - const walletCoordinatorArtifact: Artifact = - hre.artifacts.readArtifactSync("WalletCoordinator") - - await deployments.save("WalletCoordinator", { - ...proxyDeployment, - abi: walletCoordinatorArtifact.abi, - implementation: newImplementationAddress, - }) - if (hre.network.tags.etherscan) { // We use `verify` instead of `verify:verify` as the `verify` task is defined // in "@openzeppelin/hardhat-upgrades" to perform Etherscan verification // of Proxy and Implementation contracts. await hre.run("verify", { - address: proxyDeployment.address, + address: newImplementationAddress, constructorArgsParams: proxyDeployment.args, }) } From b339d7bb306f68fa883f1f09e50122b408fc102c Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Wed, 5 Jul 2023 13:51:49 +0200 Subject: [PATCH 3/3] Upgraded WalletCoordinator mainnet artifact --- solidity/.openzeppelin/mainnet.json | 270 +++++++++++++++++ .../mainnet/WalletCoordinator.json | 271 +++++++++++++++++- solidity/export.json | 267 +++++++++++++++++ 3 files changed, 806 insertions(+), 2 deletions(-) diff --git a/solidity/.openzeppelin/mainnet.json b/solidity/.openzeppelin/mainnet.json index b21fce9c9..c9e658efc 100644 --- a/solidity/.openzeppelin/mainnet.json +++ b/solidity/.openzeppelin/mainnet.json @@ -1646,6 +1646,276 @@ } } } + }, + "ce16848058a776a80d070af74d85fb4d1e632b07a9857bddcd0276c13aaf20c6": { + "address": "0x10Fb5943E2F4F67Ee6a533DaE49B6d4cC443ffE5", + "txHash": "0xe13747dba11729d2fd7aa9eca5ebba44073591c774122760008a3dd6e2dced76", + "layout": { + "solcVersion": "0.8.17", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "reimbursementPool", + "offset": 0, + "slot": "101", + "type": "t_contract(ReimbursementPool)8816", + "contract": "Reimbursable", + "src": "@keep-network/random-beacon/contracts/Reimbursable.sol:51" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "Reimbursable", + "src": "@keep-network/random-beacon/contracts/Reimbursable.sol:51" + }, + { + "label": "isCoordinator", + "offset": 0, + "slot": "151", + "type": "t_mapping(t_address,t_bool)", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:150" + }, + { + "label": "walletLock", + "offset": 0, + "slot": "152", + "type": "t_mapping(t_bytes20,t_struct(WalletLock)34672_storage)", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:152" + }, + { + "label": "bridge", + "offset": 0, + "slot": "153", + "type": "t_contract(Bridge)25740", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:154" + }, + { + "label": "heartbeatRequestValidity", + "offset": 20, + "slot": "153", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:165" + }, + { + "label": "heartbeatRequestGasOffset", + "offset": 24, + "slot": "153", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:169" + }, + { + "label": "depositSweepProposalValidity", + "offset": 28, + "slot": "153", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:181" + }, + { + "label": "depositMinAge", + "offset": 0, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:191" + }, + { + "label": "depositRefundSafetyMargin", + "offset": 4, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:212" + }, + { + "label": "depositSweepMaxSize", + "offset": 8, + "slot": "154", + "type": "t_uint16", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:214" + }, + { + "label": "depositSweepProposalSubmissionGasOffset", + "offset": 10, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:218" + }, + { + "label": "redemptionProposalValidity", + "offset": 14, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:230" + }, + { + "label": "redemptionRequestMinAge", + "offset": 18, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:238" + }, + { + "label": "redemptionRequestTimeoutSafetyMargin", + "offset": 22, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:261" + }, + { + "label": "redemptionMaxSize", + "offset": 26, + "slot": "154", + "type": "t_uint16", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:265" + }, + { + "label": "redemptionProposalSubmissionGasOffset", + "offset": 28, + "slot": "154", + "type": "t_uint32", + "contract": "WalletCoordinator", + "src": "contracts/bridge/WalletCoordinator.sol:274" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes20": { + "label": "bytes20", + "numberOfBytes": "20" + }, + "t_contract(Bridge)25740": { + "label": "contract Bridge", + "numberOfBytes": "20" + }, + "t_contract(ReimbursementPool)8816": { + "label": "contract ReimbursementPool", + "numberOfBytes": "20" + }, + "t_enum(WalletAction)34664": { + "label": "enum WalletCoordinator.WalletAction", + "members": [ + "Idle", + "Heartbeat", + "DepositSweep", + "Redemption", + "MovingFunds", + "MovedFundsSweep" + ], + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "label": "mapping(address => bool)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes20,t_struct(WalletLock)34672_storage)": { + "label": "mapping(bytes20 => struct WalletCoordinator.WalletLock)", + "numberOfBytes": "32" + }, + "t_struct(WalletLock)34672_storage": { + "label": "struct WalletCoordinator.WalletLock", + "members": [ + { + "label": "expiresAt", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "cause", + "type": "t_enum(WalletAction)34664", + "offset": 4, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint16": { + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } diff --git a/solidity/deployments/mainnet/WalletCoordinator.json b/solidity/deployments/mainnet/WalletCoordinator.json index feefc6882..3e5b15065 100644 --- a/solidity/deployments/mainnet/WalletCoordinator.json +++ b/solidity/deployments/mainnet/WalletCoordinator.json @@ -193,6 +193,79 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionProposalValidity", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionRequestMinAge", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionRequestTimeoutSafetyMargin", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "redemptionMaxSize", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionProposalSubmissionGasOffset", + "type": "uint32" + } + ], + "name": "RedemptionProposalParametersUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "coordinator", + "type": "address" + } + ], + "name": "RedemptionProposalSubmitted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -381,6 +454,71 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "redemptionMaxSize", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionProposalSubmissionGasOffset", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionProposalValidity", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionRequestMinAge", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionRequestTimeoutSafetyMargin", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "reimbursementPool", @@ -544,6 +682,66 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "submitRedemptionProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "submitRedemptionProposalWithReimbursement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -621,6 +819,39 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_redemptionProposalValidity", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_redemptionRequestMinAge", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_redemptionRequestTimeoutSafetyMargin", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "_redemptionMaxSize", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "_redemptionProposalSubmissionGasOffset", + "type": "uint32" + } + ], + "name": "updateRedemptionProposalParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -741,6 +972,42 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "validateRedemptionProposal", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -834,7 +1101,7 @@ "status": 1, "byzantium": true }, - "numDeployments": 1, - "implementation": "0x9eAE6e8e99d27D377F1EA0659b0CB16ce8aD32bA", + "numDeployments": 3, + "implementation": "0x10Fb5943E2F4F67Ee6a533DaE49B6d4cC443ffE5", "devdoc": "Contract deployed as upgradable proxy" } \ No newline at end of file diff --git a/solidity/export.json b/solidity/export.json index cef4b247b..d3b83c7ee 100644 --- a/solidity/export.json +++ b/solidity/export.json @@ -11385,6 +11385,79 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionProposalValidity", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionRequestMinAge", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionRequestTimeoutSafetyMargin", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "redemptionMaxSize", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "redemptionProposalSubmissionGasOffset", + "type": "uint32" + } + ], + "name": "RedemptionProposalParametersUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "coordinator", + "type": "address" + } + ], + "name": "RedemptionProposalSubmitted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -11573,6 +11646,71 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "redemptionMaxSize", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionProposalSubmissionGasOffset", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionProposalValidity", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionRequestMinAge", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionRequestTimeoutSafetyMargin", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "reimbursementPool", @@ -11736,6 +11874,66 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "submitRedemptionProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "submitRedemptionProposalWithReimbursement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -11813,6 +12011,39 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_redemptionProposalValidity", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_redemptionRequestMinAge", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_redemptionRequestTimeoutSafetyMargin", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "_redemptionMaxSize", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "_redemptionProposalSubmissionGasOffset", + "type": "uint32" + } + ], + "name": "updateRedemptionProposalParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -11933,6 +12164,42 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes20", + "name": "walletPubKeyHash", + "type": "bytes20" + }, + { + "internalType": "bytes[]", + "name": "redeemersOutputScripts", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "redemptionTxFee", + "type": "uint256" + } + ], + "internalType": "struct WalletCoordinator.RedemptionProposal", + "name": "proposal", + "type": "tuple" + } + ], + "name": "validateRedemptionProposal", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ {