From 5148a019bd9213e882697d1ef3d54d791e0bbb5d Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Tue, 17 Mar 2026 13:32:26 +1100 Subject: [PATCH 01/15] Add consol option to doAccounting Hardhat task --- contracts/tasks/tasks.js | 9 ++++++++- contracts/tasks/validator.js | 21 ++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index c2c4a1ee68..ed5d64a26c 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -1444,7 +1444,13 @@ subtask( undefined, types.int ) - .setAction(async ({ index }) => { + .addOptionalParam( + "consol", + "Call the consolidation controller instead of the strategy", + false, + types.boolean + ) + .setAction(async ({ index, consol }) => { const signer = await getSigner(); const nativeStakingStrategy = await resolveNativeStakingStrategyProxy( @@ -1452,6 +1458,7 @@ subtask( ); await doAccounting({ + consol, signer, nativeStakingStrategy, }); diff --git a/contracts/tasks/validator.js b/contracts/tasks/validator.js index c38fc51534..01c4f2b22d 100644 --- a/contracts/tasks/validator.js +++ b/contracts/tasks/validator.js @@ -169,9 +169,24 @@ async function exitValidator({ index, pubkey, operatorids, signer }) { await logTxDetails(tx, "exitSsvValidator"); } -async function doAccounting({ signer, nativeStakingStrategy }) { - log(`About to doAccounting`); - const tx = await nativeStakingStrategy.connect(signer).doAccounting(); +async function doAccounting({ signer, nativeStakingStrategy, consol = false }) { + let tx; + + if (consol) { + const controller = await resolveContract("ConsolidationController"); + log( + `About to doAccounting via ConsolidationController ${controller.address} for strategy ${nativeStakingStrategy.address}` + ); + tx = await controller + .connect(signer) + .doAccounting(nativeStakingStrategy.address); + } else { + log( + `About to doAccounting directly on strategy ${nativeStakingStrategy.address}` + ); + tx = await nativeStakingStrategy.connect(signer).doAccounting(); + } + await logTxDetails(tx, "doAccounting"); } From c5b58fcc53ad02e784dc955ab68adfbf5d635cfe Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Tue, 17 Mar 2026 14:29:34 +1100 Subject: [PATCH 02/15] Changed doAccounting Action to use the ConsolidationController --- .../scripts/defender-actions/doAccounting.js | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/contracts/scripts/defender-actions/doAccounting.js b/contracts/scripts/defender-actions/doAccounting.js index 1203aa69d0..0239ae35f6 100644 --- a/contracts/scripts/defender-actions/doAccounting.js +++ b/contracts/scripts/defender-actions/doAccounting.js @@ -3,7 +3,13 @@ const { Defender } = require("@openzeppelin/defender-sdk"); const addresses = require("../../utils/addresses"); const { logTxDetails } = require("../../utils/txLogger"); -const nativeStakingStrategyAbi = require("../../abi/native_staking_SSV_strategy.json"); +const { + address: mainnetConsolidationControllerAddress, + abi: consolidationControllerAbi, +} = require("../../deployments/mainnet/ConsolidationController.json"); +const { + address: hoodiConsolidationControllerAddress, +} = require("../../deployments/hoodi/ConsolidationController.json"); const log = require("../../utils/logger")("action:doAccounting"); @@ -22,26 +28,64 @@ const handler = async (event) => { }); const network = await provider.getNetwork(); - const networkName = network.chainId === 1 ? "mainnet" : "holesky"; + const networkName = + network.chainId === 1 + ? "mainnet" + : network.chainId === 560048 + ? "hoodi" + : undefined; + if (!networkName) { + throw new Error( + `Action only supports mainnet and hoodi, not chainId ${network.chainId}` + ); + } log(`Network: ${networkName} with chain id (${network.chainId})`); - // await doAccounting("NativeStakingSSVStrategyProxy", networkName, signer); - await doAccounting("NativeStakingSSVStrategy2Proxy", networkName, signer); - await doAccounting("NativeStakingSSVStrategy3Proxy", networkName, signer); + const consolidationControllerAddress = + networkName === "mainnet" + ? mainnetConsolidationControllerAddress + : hoodiConsolidationControllerAddress; + log( + `Resolved ConsolidationController address to ${consolidationControllerAddress}` + ); + const consolidationController = new ethers.Contract( + consolidationControllerAddress, + consolidationControllerAbi, + signer + ); + + await doAccounting( + "NativeStakingSSVStrategy2Proxy", + networkName, + signer, + consolidationController + ); + await doAccounting( + "NativeStakingSSVStrategy3Proxy", + networkName, + signer, + consolidationController + ); }; -const doAccounting = async (proxyName, networkName, signer) => { +const doAccounting = async ( + proxyName, + networkName, + signer, + consolidationController +) => { const nativeStakingProxyAddress = addresses[networkName][proxyName]; + if (!nativeStakingProxyAddress) { + throw new Error( + `Failed to resolve ${proxyName} on the ${networkName} network` + ); + } log(`Resolved ${proxyName} address to ${nativeStakingProxyAddress}`); - const nativeStakingStrategy = new ethers.Contract( - nativeStakingProxyAddress, - nativeStakingStrategyAbi, - signer - ); - - const tx = await nativeStakingStrategy.connect(signer).doAccounting(); - await logTxDetails(tx, `doAccounting for ${proxyName}`); + const tx = await consolidationController + .connect(signer) + .doAccounting(nativeStakingProxyAddress); + await logTxDetails(tx, `doAccounting for ${proxyName} via controller`); }; module.exports = { handler }; From c66a8e6a315641cc007313cf4c78ff5e925fa8e0 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Tue, 17 Mar 2026 16:30:31 +1100 Subject: [PATCH 03/15] Added getValidators Hardhat task Refactored getting Beacon chain data to use Lodestar. So removed Beaconcha.in API use --- contracts/tasks/beacon.js | 168 +++++++++++++++++++++++++++++++++++++- contracts/tasks/tasks.js | 19 +++++ contracts/utils/beacon.js | 130 +++++++++++++---------------- 3 files changed, 243 insertions(+), 74 deletions(-) diff --git a/contracts/tasks/beacon.js b/contracts/tasks/beacon.js index a8ca90b470..40af13bfb8 100644 --- a/contracts/tasks/beacon.js +++ b/contracts/tasks/beacon.js @@ -11,9 +11,10 @@ const addresses = require("../utils/addresses"); const { getBeaconBlock, getValidator: getValidatorBeacon, + getValidators: getValidatorsBeacon, getSlot, } = require("../utils/beacon"); -const { bytes32 } = require("../utils/regex"); +const { bytes32, validatorKeys } = require("../utils/regex"); const { resolveContract } = require("../utils/resolvers"); const { generateValidatorPubKeyProof, @@ -28,9 +29,96 @@ const { toHex } = require("../utils/units"); const { logTxDetails } = require("../utils/txLogger"); const { getNetworkName } = require("../utils/hardhat-helpers"); const { ZERO_BYTES32 } = require("../utils/constants"); +const { + address: mainnetCompoundingStakingSSVStrategyProxy, +} = require("../deployments/mainnet/CompoundingStakingSSVStrategyProxy.json"); +const { + address: hoodiNativeStakingSSVStrategyProxy, +} = require("../deployments/hoodi/NativeStakingSSVStrategyProxy.json"); +const { + address: hoodiCompoundingStakingSSVStrategyProxy, +} = require("../deployments/hoodi/CompoundingStakingSSVStrategyProxy.json"); const log = require("../utils/logger")("task:beacon"); +const getStrategyNetworkName = async () => { + const networkName = await getNetworkName(); + if (networkName === "hardhat") { + return process.env.FORK_NETWORK_NAME || process.env.NETWORK_NAME || "hardhat"; + } + return networkName; +}; + +const getKnownWithdrawalStrategies = (networkName) => { + if (networkName === "mainnet") { + return [ + { + label: "NativeStakingSSVStrategyProxy", + address: addresses.mainnet.NativeStakingSSVStrategyProxy, + }, + { + label: "NativeStakingSSVStrategy2Proxy", + address: addresses.mainnet.NativeStakingSSVStrategy2Proxy, + }, + { + label: "NativeStakingSSVStrategy3Proxy", + address: addresses.mainnet.NativeStakingSSVStrategy3Proxy, + }, + { + label: "CompoundingStakingSSVStrategyProxy", + address: mainnetCompoundingStakingSSVStrategyProxy, + }, + ]; + } + + if (networkName === "hoodi") { + return [ + { + label: "NativeStakingSSVStrategyProxy", + address: hoodiNativeStakingSSVStrategyProxy, + }, + { + label: "CompoundingStakingSSVStrategyProxy", + address: hoodiCompoundingStakingSSVStrategyProxy, + }, + ]; + } + + if (networkName === "holesky") { + return [ + { + label: "NativeStakingSSVStrategyProxy", + address: addresses.holesky.NativeStakingSSVStrategyProxy, + }, + ]; + } + + return []; +}; + +const getLinkedStrategy = (withdrawalCredentials, networkName) => { + const credentialType = withdrawalCredentials.slice(0, 4).toLowerCase(); + const linkedAddress = ethers.utils.getAddress( + `0x${withdrawalCredentials.slice(-40)}` + ); + const knownStrategy = getKnownWithdrawalStrategies(networkName).find( + ({ address }) => address?.toLowerCase() === linkedAddress.toLowerCase() + ); + + if (knownStrategy) { + return knownStrategy.label; + } + + if (credentialType === "0x01" || credentialType === "0x02") { + return `Unknown ${credentialType}`; + } + + return `Type ${credentialType}`; +}; + +const getValidatorType = (withdrawalCredentials) => + withdrawalCredentials.slice(0, 4).toLowerCase(); + /// Returns an ethers provider connected to the Ethereum mainnet or Hoodi. /// @param {Provider} [provider] - Optional ethers provider connected to local fork or live chain. Uses Hardhat provider if not supplied. async function getLiveProvider(provider) { @@ -904,10 +992,88 @@ async function getValidator({ slot, index, pubkey }) { ); } +async function getValidators({ pubkeys, slot }) { + if (!pubkeys.match(validatorKeys)) { + throw Error( + `Public keys not a comma-separated list of public keys with 0x prefixes` + ); + } + + const networkName = await getStrategyNetworkName(); + const { stateView } = await getBeaconBlock(slot, networkName); + + const beaconValidators = await getValidatorsBeacon(pubkeys); + const beaconValidatorList = Array.isArray(beaconValidators) + ? beaconValidators + : [beaconValidators]; + const validators = beaconValidatorList.map((beaconValidator) => ({ + index: Number(beaconValidator.validatorindex), + pubkey: beaconValidator.pubkey, + })); + + console.log( + `Validators at slot ${stateView.slot}, epoch ${BigInt(stateView.slot) / 32n}:` + ); + + const rows = []; + for (const { pubkey, index } of validators) { + const validator = stateView.validators.get(index); + if ( + !validator || + toHex(validator.node.root) === + "0x0000000000000000000000000000000000000000000000000000000000000000" + ) { + throw new Error( + `Validator ${pubkey} at index ${index} not found for slot ${slot}` + ); + } + + const withdrawalCredentials = toHex(validator.withdrawalCredentials); + const validatorType = getValidatorType(withdrawalCredentials); + const linkedStrategy = getLinkedStrategy(withdrawalCredentials, networkName); + const balance = stateView.balances.get(index); + + rows.push({ + Pubkey: pubkey, + Type: validatorType, + Slashed: String(validator.slashed), + Balance: `${formatUnits(balance, 9)} ETH`, + ExitEpoch: String(validator.exitEpoch), + WithdrawableEpoch: String(validator.withdrawableEpoch), + LinkedStrategy: linkedStrategy, + }); + } + + const columns = [ + "Pubkey", + "Type", + "Slashed", + "Balance", + "ExitEpoch", + "WithdrawableEpoch", + "LinkedStrategy", + ]; + const widths = Object.fromEntries( + columns.map((column) => [ + column, + Math.max(column.length, ...rows.map((row) => row[column].length)), + ]) + ); + const formatRow = (row) => + columns.map((column) => row[column].padEnd(widths[column])).join(" "); + + console.log(formatRow(Object.fromEntries(columns.map((column) => [column, column])))); + console.log(columns.map((column) => "-".repeat(widths[column])).join(" ")); + for (const row of rows) { + console.log(formatRow(row)); + } +} + module.exports = { requestValidatorWithdraw, beaconRoot, getValidator, + getValidators, verifyValidator, verifyDeposit, verifyDeposits, diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index ed5d64a26c..9e8adce3ac 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -128,6 +128,7 @@ const { requestValidatorWithdraw, beaconRoot, getValidator, + getValidators, verifyValidator, verifyDeposit, verifyDeposits, @@ -2119,6 +2120,24 @@ task("getValidator").setAction(async (_, __, runSuper) => { return runSuper(); }); +subtask("getValidators", "Gets the details of multiple validators") + .addParam( + "pubkeys", + "Comma separated list of validator public keys in hex format with a 0x prefix", + undefined, + types.string + ) + .addOptionalParam( + "slot", + "Beacon chain slot. Default head", + undefined, + types.int + ) + .setAction(getValidators); +task("getValidators").setAction(async (_, __, runSuper) => { + return runSuper(); +}); + subtask("verifyValidator", "Verify a validator on the Beacon chain") .addParam( "index", diff --git a/contracts/utils/beacon.js b/contracts/utils/beacon.js index 6a68781bac..96529602e0 100644 --- a/contracts/utils/beacon.js +++ b/contracts/utils/beacon.js @@ -1,5 +1,4 @@ const fs = require("fs"); -const fetch = require("node-fetch"); const ethers = require("ethers"); const { createHash } = require("crypto"); const { parseUnits } = require("ethers/lib/utils"); @@ -8,28 +7,30 @@ const { beaconChainGenesisTimeMainnet, beaconChainGenesisTimeHoodi, } = require("./constants"); -const { getNetworkName } = require("./hardhat-helpers"); const log = require("./logger")("utils:beacon"); +const SLOTS_PER_EPOCH = 32; + +const normalizeValidatorResponse = ({ index, balance, status, validator }) => ({ + index: Number(index), + validatorindex: Number(index), + balance: Number(balance), + status, + pubkey: ethers.utils.hexlify(validator.pubkey), + withdrawalcredentials: ethers.utils.hexlify(validator.withdrawalCredentials), + effectivebalance: Number(validator.effectiveBalance), + slashed: validator.slashed, + activationepoch: Number(validator.activationEpoch), + activationeligibilityepoch: Number(validator.activationEligibilityEpoch), + exitepoch: Number(validator.exitEpoch), + withdrawableepoch: Number(validator.withdrawableEpoch), +}); + /// They following use Lodestar API calls const getValidatorBalance = async (pubkey) => { - const client = await configClient(); - - log(`Fetching validator details for ${pubkey} from the beacon node`); - const validatorRes = await client.beacon.getStateValidator({ - stateId: "head", - validatorId: pubkey, - }); - if (!validatorRes.ok) { - console.error(validatorRes); - throw Error( - `Failed to get validator details for ${pubkey}. Status ${validatorRes.status} ${validatorRes.statusText}` - ); - } - - const values = validatorRes.value(); + const values = await getValidator(pubkey); log(`Got balance ${values.balance} for validator ${values.index}`); return values.balance; }; @@ -181,74 +182,57 @@ const configClient = async () => { return client; }; -/// The following connect directly to the BeaconChain API -/// They could be replaced with Lodestar API calls in the future. - const getValidator = async (pubkey) => { - const networkName = await getNetworkName(); - // some other beacon providers don't support fetching of the validator by pubkey - const beaconProvider = `https://${ - networkName === "mainnet" ? "" : `${networkName}.` - }beaconcha.in/api/v1/`; - - return await beaconchainRequest(`validator/${pubkey}`, beaconProvider); -}; + const client = await configClient(); -const getValidators = async (pubkeys, beaconChainApiKey) => { - const encodedPubkeys = encodeURIComponent(pubkeys); - return await beaconchainRequest( - `validator/${encodedPubkeys}`, - beaconChainApiKey - ); -}; + log(`Fetching validator details for ${pubkey} from the beacon node`); + const validatorRes = await client.beacon.getStateValidator({ + stateId: "head", + validatorId: pubkey, + }); + if (!validatorRes.ok) { + console.error(validatorRes); + throw Error( + `Failed to get validator details for ${pubkey}. Status ${validatorRes.status} ${validatorRes.statusText}` + ); + } -const getEpoch = async (epochId = "latest") => { - return await beaconchainRequest(`epoch/${epochId}`); + return normalizeValidatorResponse(validatorRes.value()); }; -const beaconchainRequest = async (endpoint, overrideProvider) => { - const networkName = await getNetworkName(); - - const API_URL = - overrideProvider || - process.env.BEACON_PROVIDER_URL || - `https://${ - networkName === "mainnet" ? "" : `${networkName}.` - }beaconcha.in/api/v1/`; +const getValidators = async (pubkeys) => { + const client = await configClient(); + const validatorIds = Array.isArray(pubkeys) ? pubkeys : pubkeys.split(","); - const apikey = process.env.BEACONCHAIN_API_KEY; - const url = `${API_URL}${endpoint}`; - if (!apikey) { - throw new Error( - "Set BEACONCHAIN_API_KEY in order to be able to query the API" + log( + `Fetching ${validatorIds.length} validator details from the beacon node` + ); + const validatorsRes = await client.beacon.getStateValidators({ + stateId: "head", + validatorIds, + }); + if (!validatorsRes.ok) { + console.error(validatorsRes); + throw Error( + `Failed to get validator details for ${validatorIds.join(",")}. Status ${validatorsRes.status} ${validatorsRes.statusText}` ); } - const headers = { - Accept: "application/json", - "Content-Type": "application/json", - apikey, - }; - - log(`About to call Beacon API: ${url} `); - - const rawResponse = await fetch(url, { - method: "GET", - headers, - }); + const validators = validatorsRes.value().map(normalizeValidatorResponse); + return validators.length === 1 ? validators[0] : validators; +}; - const response = await rawResponse.json(); - if (response.status != "OK") { - log(`Call to Beacon API failed: ${url}`); - log(`response: `, response); - throw new Error( - `Call to Beacon API failed. Error: ${JSON.stringify(response.error)}` - ); - } else { - log(`GET request to Beacon API succeeded. Response: `, response); +const getEpoch = async (epochId = "latest") => { + if (epochId !== "latest") { + return { + epoch: Number(epochId), + }; } - return response.data; + const slot = await getSlot("head"); + return { + epoch: Math.floor(Number(slot) / SLOTS_PER_EPOCH), + }; }; const serializeUint64 = async (value) => { From 13d9adfd36c678cfd59e9f1d4935d05a85976cfb Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Tue, 17 Mar 2026 16:36:16 +1100 Subject: [PATCH 04/15] Removed reference to BEACONCHAIN_API_KEY Formatting of getValidators --- contracts/dev.env | 3 --- contracts/tasks/beacon.js | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/contracts/dev.env b/contracts/dev.env index 77f3895f7d..3548a2a64c 100644 --- a/contracts/dev.env +++ b/contracts/dev.env @@ -69,8 +69,5 @@ VALIDATOR_KEYS_S3_BUCKET_NAME=[validator-keys-test | validator-keys] # need to be recovered VALIDATOR_MASTER_ENCRYPTED_PRIVATE_KEY= -# Beaconcha.in API key can be obtained by creating an account -BEACONCHAIN_API_KEY= - # Tenderly access token required to upload newly deployed and verified contracts to Tenderly TENDERLY_ACCESS_TOKEN= \ No newline at end of file diff --git a/contracts/tasks/beacon.js b/contracts/tasks/beacon.js index 40af13bfb8..68cc6385a4 100644 --- a/contracts/tasks/beacon.js +++ b/contracts/tasks/beacon.js @@ -1037,7 +1037,7 @@ async function getValidators({ pubkeys, slot }) { Pubkey: pubkey, Type: validatorType, Slashed: String(validator.slashed), - Balance: `${formatUnits(balance, 9)} ETH`, + "Balance ETH": formatUnits(balance, 9), ExitEpoch: String(validator.exitEpoch), WithdrawableEpoch: String(validator.withdrawableEpoch), LinkedStrategy: linkedStrategy, @@ -1048,7 +1048,7 @@ async function getValidators({ pubkeys, slot }) { "Pubkey", "Type", "Slashed", - "Balance", + "Balance ETH", "ExitEpoch", "WithdrawableEpoch", "LinkedStrategy", From bc2cef2e7447ebcf13b173d55ac4b44c1213ab8f Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Wed, 18 Mar 2026 12:17:42 +1100 Subject: [PATCH 05/15] More formatting of the output of the getValidators Hardhat task Added epoch option to getValidators Hardhat task --- .../scripts/defender-actions/doAccounting.js | 4 +- contracts/tasks/beacon.js | 93 +++++++++++++++---- contracts/tasks/tasks.js | 12 +++ contracts/utils/beacon.js | 8 +- 4 files changed, 91 insertions(+), 26 deletions(-) diff --git a/contracts/scripts/defender-actions/doAccounting.js b/contracts/scripts/defender-actions/doAccounting.js index 0239ae35f6..bbea98ce88 100644 --- a/contracts/scripts/defender-actions/doAccounting.js +++ b/contracts/scripts/defender-actions/doAccounting.js @@ -32,8 +32,8 @@ const handler = async (event) => { network.chainId === 1 ? "mainnet" : network.chainId === 560048 - ? "hoodi" - : undefined; + ? "hoodi" + : undefined; if (!networkName) { throw new Error( `Action only supports mainnet and hoodi, not chainId ${network.chainId}` diff --git a/contracts/tasks/beacon.js b/contracts/tasks/beacon.js index 68cc6385a4..747eb05c00 100644 --- a/contracts/tasks/beacon.js +++ b/contracts/tasks/beacon.js @@ -13,6 +13,7 @@ const { getValidator: getValidatorBeacon, getValidators: getValidatorsBeacon, getSlot, + calcBlockTimestamp, } = require("../utils/beacon"); const { bytes32, validatorKeys } = require("../utils/regex"); const { resolveContract } = require("../utils/resolvers"); @@ -40,11 +41,14 @@ const { } = require("../deployments/hoodi/CompoundingStakingSSVStrategyProxy.json"); const log = require("../utils/logger")("task:beacon"); +const MAX_DATE_MS = 8640000000000000n; const getStrategyNetworkName = async () => { const networkName = await getNetworkName(); if (networkName === "hardhat") { - return process.env.FORK_NETWORK_NAME || process.env.NETWORK_NAME || "hardhat"; + return ( + process.env.FORK_NETWORK_NAME || process.env.NETWORK_NAME || "hardhat" + ); } return networkName; }; @@ -97,7 +101,6 @@ const getKnownWithdrawalStrategies = (networkName) => { }; const getLinkedStrategy = (withdrawalCredentials, networkName) => { - const credentialType = withdrawalCredentials.slice(0, 4).toLowerCase(); const linkedAddress = ethers.utils.getAddress( `0x${withdrawalCredentials.slice(-40)}` ); @@ -109,16 +112,52 @@ const getLinkedStrategy = (withdrawalCredentials, networkName) => { return knownStrategy.label; } - if (credentialType === "0x01" || credentialType === "0x02") { - return `Unknown ${credentialType}`; - } - - return `Type ${credentialType}`; + return "Unknown"; }; const getValidatorType = (withdrawalCredentials) => withdrawalCredentials.slice(0, 4).toLowerCase(); +const resolveBeaconSlot = ({ slot, epoch }) => { + if (slot !== undefined && epoch !== undefined) { + throw new Error("Pass either `slot` or `epoch`, not both"); + } + + if (epoch !== undefined) { + return epoch * 32; + } + + return slot; +}; + +const formatEpochUtc = (epoch, networkName) => { + if (epoch === undefined || epoch === null) { + return "N/A"; + } + + if (typeof epoch === "number" && !Number.isFinite(epoch)) { + return "Infinity"; + } + + const slot = BigInt(epoch) * 32n; + const timestampMs = calcBlockTimestamp(slot, networkName) * 1000n; + + if (timestampMs > MAX_DATE_MS) { + return "N/A"; + } + + const date = new Date(Number(timestampMs)); + const day = String(date.getUTCDate()).padStart(2, "0"); + const month = date.toLocaleString("en-GB", { + month: "short", + timeZone: "UTC", + }); + const hours = String(date.getUTCHours()).padStart(2, "0"); + const minutes = String(date.getUTCMinutes()).padStart(2, "0"); + + return `${day} ${month} ${hours}:${minutes}`; +}; + /// Returns an ethers provider connected to the Ethereum mainnet or Hoodi. /// @param {Provider} [provider] - Optional ethers provider connected to local fork or live chain. Uses Hardhat provider if not supplied. async function getLiveProvider(provider) { @@ -795,7 +834,7 @@ async function beaconRoot({ block, live, signer }) { return { root, timestamp }; } -async function getValidator({ slot, index, pubkey }) { +async function getValidator({ slot, epoch, index, pubkey }) { if (!index && !pubkey) { throw new Error("Either `index` or `pubkey` parameter is required"); } @@ -806,8 +845,9 @@ async function getValidator({ slot, index, pubkey }) { } // Uses the latest slot if the slot is undefined + const blockId = resolveBeaconSlot({ slot, epoch }); const networkName = await getNetworkName(); - const { blockView, stateView } = await getBeaconBlock(slot, networkName); + const { blockView, stateView } = await getBeaconBlock(blockId, networkName); const validator = stateView.validators.get(index); if ( @@ -815,7 +855,9 @@ async function getValidator({ slot, index, pubkey }) { toHex(validator.node.root) == "0x0000000000000000000000000000000000000000000000000000000000000000" ) { - throw new Error(`Validator at index ${index} not found for slot ${slot}`); + throw new Error( + `Validator at index ${index} not found for slot ${blockId}` + ); } const balance = stateView.balances.get(index); @@ -992,15 +1034,16 @@ async function getValidator({ slot, index, pubkey }) { ); } -async function getValidators({ pubkeys, slot }) { +async function getValidators({ pubkeys, slot, epoch }) { if (!pubkeys.match(validatorKeys)) { throw Error( `Public keys not a comma-separated list of public keys with 0x prefixes` ); } + const blockId = resolveBeaconSlot({ slot, epoch }); const networkName = await getStrategyNetworkName(); - const { stateView } = await getBeaconBlock(slot, networkName); + const { stateView } = await getBeaconBlock(blockId, networkName); const beaconValidators = await getValidatorsBeacon(pubkeys); const beaconValidatorList = Array.isArray(beaconValidators) @@ -1012,7 +1055,9 @@ async function getValidators({ pubkeys, slot }) { })); console.log( - `Validators at slot ${stateView.slot}, epoch ${BigInt(stateView.slot) / 32n}:` + `Validators at slot ${stateView.slot}, epoch ${ + BigInt(stateView.slot) / 32n + }:` ); const rows = []; @@ -1024,28 +1069,34 @@ async function getValidators({ pubkeys, slot }) { "0x0000000000000000000000000000000000000000000000000000000000000000" ) { throw new Error( - `Validator ${pubkey} at index ${index} not found for slot ${slot}` + `Validator ${pubkey} at index ${index} not found for slot ${blockId}` ); } const withdrawalCredentials = toHex(validator.withdrawalCredentials); const validatorType = getValidatorType(withdrawalCredentials); - const linkedStrategy = getLinkedStrategy(withdrawalCredentials, networkName); + const linkedStrategy = getLinkedStrategy( + withdrawalCredentials, + networkName + ); const balance = stateView.balances.get(index); rows.push({ - Pubkey: pubkey, + Index: String(index), Type: validatorType, Slashed: String(validator.slashed), "Balance ETH": formatUnits(balance, 9), - ExitEpoch: String(validator.exitEpoch), - WithdrawableEpoch: String(validator.withdrawableEpoch), + ExitEpoch: formatEpochUtc(validator.exitEpoch, networkName), + WithdrawableEpoch: formatEpochUtc( + validator.withdrawableEpoch, + networkName + ), LinkedStrategy: linkedStrategy, }); } const columns = [ - "Pubkey", + "Index", "Type", "Slashed", "Balance ETH", @@ -1062,7 +1113,9 @@ async function getValidators({ pubkeys, slot }) { const formatRow = (row) => columns.map((column) => row[column].padEnd(widths[column])).join(" "); - console.log(formatRow(Object.fromEntries(columns.map((column) => [column, column])))); + console.log( + formatRow(Object.fromEntries(columns.map((column) => [column, column]))) + ); console.log(columns.map((column) => "-".repeat(widths[column])).join(" ")); for (const row of rows) { console.log(formatRow(row)); diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index 9e8adce3ac..b2ad10a2f4 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -2115,6 +2115,12 @@ subtask("getValidator", "Gets the details of a validator") undefined, types.int ) + .addOptionalParam( + "epoch", + "Beacon chain epoch. Uses the first slot of the epoch", + undefined, + types.int + ) .setAction(getValidator); task("getValidator").setAction(async (_, __, runSuper) => { return runSuper(); @@ -2133,6 +2139,12 @@ subtask("getValidators", "Gets the details of multiple validators") undefined, types.int ) + .addOptionalParam( + "epoch", + "Beacon chain epoch. Uses the first slot of the epoch", + undefined, + types.int + ) .setAction(getValidators); task("getValidators").setAction(async (_, __, runSuper) => { return runSuper(); diff --git a/contracts/utils/beacon.js b/contracts/utils/beacon.js index 96529602e0..d930669732 100644 --- a/contracts/utils/beacon.js +++ b/contracts/utils/beacon.js @@ -204,9 +204,7 @@ const getValidators = async (pubkeys) => { const client = await configClient(); const validatorIds = Array.isArray(pubkeys) ? pubkeys : pubkeys.split(","); - log( - `Fetching ${validatorIds.length} validator details from the beacon node` - ); + log(`Fetching ${validatorIds.length} validator details from the beacon node`); const validatorsRes = await client.beacon.getStateValidators({ stateId: "head", validatorIds, @@ -214,7 +212,9 @@ const getValidators = async (pubkeys) => { if (!validatorsRes.ok) { console.error(validatorsRes); throw Error( - `Failed to get validator details for ${validatorIds.join(",")}. Status ${validatorsRes.status} ${validatorsRes.statusText}` + `Failed to get validator details for ${validatorIds.join(",")}. Status ${ + validatorsRes.status + } ${validatorsRes.statusText}` ); } From 197a6fcf00047d5cc2d64f20c7aa4448b4ae6630 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Wed, 18 Mar 2026 12:37:04 +1100 Subject: [PATCH 06/15] Added Claude and AGENTS md files --- AGENTS.md | 11 ++++ CLAUDE.md | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..35dd573b5d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,11 @@ +## Codex Instructions + +- See [CLAUDE.md](/Users/nicholasaddison/Documents/Origin/workspaces/origin-dollar/CLAUDE.md) for repo commands, architecture, and workflow details. +- All smart contract work happens in `contracts/`. Run repo commands from `/Users/nicholasaddison/Documents/Origin/workspaces/origin-dollar/contracts`. +- After making code changes, run Prettier before finishing. +- For JS edits under `contracts/`, run `pnpm prettier:js`. +- For Solidity edits under `contracts/`, run `pnpm prettier:sol`. +- If both JS and Solidity files changed, run both commands. +- Prefer the smallest relevant verification after edits. +- Do not reformat or modify unrelated files just to satisfy style. +- Do not fix unrelated failing tests or lint issues unless explicitly asked. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..200d3a7f54 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,191 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Origin DeFi's OTokens monorepo containing smart contracts for: +- **OUSD** (Origin Dollar) - a yield-bearing stablecoin +- **OETH** (Origin Ether) - an Ethereum liquid staking token +- **OS** (Origin Sonic) - Sonic chain native token + +Deployed on Ethereum Mainnet, Base, Arbitrum, Sonic, Plume, Holesky, and Hoodi. All smart contract work happens in the `contracts/` directory. + +## Setup + +```bash +cd contracts +cp dev.env .env # Set PROVIDER_URL to Alchemy/Infura endpoint +pnpm i +``` + +Key `.env` variables: `PROVIDER_URL`, `SONIC_PROVIDER_URL`, `BASE_PROVIDER_URL`, `BLOCK_NUMBER`, `ACCOUNTS_TO_FUND`. + +## Commands (run from `contracts/`) + +### Build +```bash +pnpm hardhat compile # Compile changed contracts +pnpm clean && pnpm hardhat compile # Full recompile +``` + +### Lint & Format +```bash +pnpm lint # Run all linters (Solidity + JS) +pnpm lint:sol # solhint for Solidity +pnpm lint:js # eslint for JavaScript +pnpm prettier:check # Check formatting +pnpm prettier # Format all files +``` + +### Unit Tests +```bash +pnpm test # Mainnet unit tests +pnpm test:base # Base network unit tests +pnpm test:sonic # Sonic network unit tests +pnpm test:coverage # Mainnet unit tests with coverage +``` + +### Fork Tests (require `PROVIDER_URL` in `.env`) +```bash +# Option 1: Fork each time (like CI) +pnpm test:fork # All mainnet fork tests +pnpm test:fork -- test/strategies/foo.fork-test.js # Single fork test file + +# Option 2: Nested forking (faster for dev iteration) +FORK=true pnpm run node # Terminal 1: start forked node with deployments +pnpm test:fork # Terminal 2: tests reuse running node + +# Other networks +pnpm test:arb-fork +pnpm test:base-fork +pnpm test:sonic-fork +pnpm test:hol-fork +``` + +### Useful Options +```bash +export DEBUG=origin:* # Enable all debug logging +export REPORT_GAS=true # Show gas usage in test output +export CONTRACT_SIZE=true # Show contract sizes after compile +``` + +## Workflow Guidance + +- Run repo commands from `contracts/` for smart contract work. +- After making code changes, run Prettier before finishing. +- For JS edits under `contracts/`, run `pnpm prettier:js`. +- For Solidity edits under `contracts/`, run `pnpm prettier:sol`. +- If both JS and Solidity files changed, run both commands. +- Prefer the smallest relevant verification after edits. +- Do not reformat or modify unrelated files just to satisfy style. +- Do not fix unrelated failing tests or lint issues unless explicitly asked. + +## Architecture + +### Core Pattern: Upgradeable Proxy Contracts +All major contracts use the OpenZeppelin upgradeable proxy pattern. Each has a `*Proxy` contract (minimal proxy) pointing to an implementation. Proxies are deployed via `hardhat-deploy` scripts in `deploy/`. + +### Vaults (Central Component) +Vaults (`contracts/vault/`) are the core of each OToken. They handle: +- Minting/burning OTokens +- Managing collateral allocation across strategies +- Rebalancing via `allocate()` +- Yield accounting via `rebase()` + +Each chain/token has its own vault: `OUSDVault`, `OETHVault`, `OETHBVault` (Base), `OETHSVault` (Sonic), `OETPVault` (Plume). + +Vault logic is split across two implementation contracts: `VaultCore` (user-facing mint/redeem) and `VaultAdmin` (governance functions). + +### Strategies (Yield Generation) +Located in `contracts/strategies/`. Each strategy: +- Inherits from `InitializableAbstractStrategy` +- Implements `deposit()`, `withdraw()`, `withdrawAll()`, `checkBalance()`, `collectRewardTokens()` +- Is registered with a vault and allocated collateral + +Key strategies: Aave, Compound, Convex/Curve, Balancer, Morpho, Native Staking (SSV validators). + +### OTokens +`contracts/token/OUSD.sol` and `contracts/token/OETH.sol` - rebasing ERC-20 tokens. OUSD rebases to all holders; OETH uses a similar mechanism for ETH-denominated yield. + +### Oracle System +`contracts/oracle/` - price feed aggregation. `OracleRouter` routes price queries to appropriate Chainlink feeds or Curve pool oracles, with staleness checks. Each network has its own router. + +### Harvesters +`contracts/harvest/` - collect reward tokens from strategies and swap to yield-bearing assets. `Harvester` for OUSD, `OETHHarvester` for OETH, network-specific variants exist. + +### Automation (Defender Actions) +`scripts/defender-actions/` - OpenZeppelin Defender automation scripts for: +- `doAccounting` - periodic vault accounting +- `harvest` - automated harvesting +- `sonicRequestWithdrawal` / `sonicClaimWithdrawals` - Sonic staking lifecycle +- `crossChainRelay` - Base ↔ Mainnet CCTP relay + +Bundle with: `pnpm rollup -c ./scripts/defender-actions/rollup.config.cjs` + +### Cross-Chain +- LayerZero OApp for messaging +- CCTP (Circle) for USDC bridging +- Network-specific bridge contracts in `contracts/bridges/` + +### Pool Boosters +`contracts/poolBooster/` - Merkl distribution contracts for incentivizing liquidity pools. `PoolBoostCentralRegistry` tracks all boosters. + +### Key Utility Files +- `utils/addresses.js` - master address registry for all networks/contracts (~32KB) +- `utils/deploy.js` - deployment helper functions (use these patterns when writing deploy scripts) +- `utils/constants.js` - protocol constants + +## Test Organization + +``` +test/ + _fixture.js # Main fixture: deploys all contracts + mocks for unit tests + _fixture-base.js # Base network fixture + _fixture-sonic.js # Sonic network fixture + _hot-deploy.js # Hot deploy support for dev iteration + vault/ # Vault tests (unit + fork) + strategies/ # Strategy tests (unit + fork) + behaviour/ # Shared behavioral test suites (used across strategies) +``` + +**Fork test files** are named `*.fork-test.js` and run against real deployed contracts on a network fork. + +**Unit test files** are named `*.js` (without `.fork-test`) and run against local mocks. + +**Behavior tests** (`test/behaviour/`) define reusable test suites (e.g., `shouldBehaveLikeStrategy`) that are composed into strategy-specific test files. + +**Fixtures**: Each test file imports from `_fixture.js` which uses `loadFixture()` for snapshot-based test isolation. The fixture deploys mocks and wires up contracts identically to mainnet structure. + +## Deployment Scripts + +Located in `deploy/` and numbered sequentially (e.g., `001_ousd.js`, `002_vault.js`). Each script uses `hardhat-deploy` plugin conventions - exports a deploy function and tags. + +When adding a new deployment script, increment the number and follow existing patterns in `utils/deploy.js` (especially `deployWithConfirmation` and `withConfirmation`). + +## Roles & Access Control + +Four key roles used across all contracts: +- **Deployer** - deploys contracts (set via `DEPLOYER_PK` env var) +- **Governor** - timelock-controlled governance address (set via `GOVERNOR_PK` env var) +- **Strategist** - multisig for day-to-day operations +- **Guardian** - emergency pause capability + +For fork tests, these addresses are impersonated. Set `IMPERSONATE=0x...` env var to impersonate any account on a running fork node. + +## Contract Verification + +Use `yarn` (not `pnpm`) for verification. Always pass `--contract` flag to avoid slowdowns: +```bash +yarn hardhat --network mainnet verify --contract contracts/vault/VaultAdmin.sol:VaultAdmin 0xADDRESS +``` + +Auto-verify on deploy: `VERIFY_CONTRACTS=true pnpm deploy:mainnet` + +## Logger Pattern + +```js +const log = require("../utils/logger")("module-name"); +log("something happened"); +// Enable: export DEBUG=origin:module-name* +``` From 02fa87469bb57a2b891bbf4f04ac6452b9cfecc8 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Wed, 18 Mar 2026 20:47:30 +1100 Subject: [PATCH 07/15] Added safe option to confirmConsol Refactored writing Safe file into safe util --- contracts/tasks/consolidation.js | 47 +++++++++++++++++++++++++- contracts/tasks/tasks.js | 11 ++++-- contracts/utils/deploy.js | 21 +++--------- contracts/utils/safe.js | 57 ++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 20 deletions(-) create mode 100644 contracts/utils/safe.js diff --git a/contracts/tasks/consolidation.js b/contracts/tasks/consolidation.js index 537e1b9190..5cbb04bcd8 100644 --- a/contracts/tasks/consolidation.js +++ b/contracts/tasks/consolidation.js @@ -1,12 +1,40 @@ +const path = require("path"); const { getSigner } = require("../utils/signers"); const addresses = require("../utils/addresses"); const { verifyBalances } = require("./beacon"); const { resolveContract } = require("../utils/resolvers"); +const { writeSafeTransactionBuilderFile } = require("../utils/safe"); const { logTxDetails } = require("../utils/txLogger"); const log = require("../utils/logger")("utils:consolidation"); +async function writeConfirmConsolidationSafeFile({ + controller, + balanceProofs, + pendingDepositProofs, +}) { + const tx = await controller.populateTransaction.confirmConsolidation( + balanceProofs, + pendingDepositProofs + ); + const safeOwner = await controller.owner(); + const safeFilePath = await writeSafeTransactionBuilderFile({ + filePath: path.resolve(__dirname, "../../logs/confirmConsol-safe.json"), + safeAddress: safeOwner, + name: "confirmConsol", + transactions: [ + { + to: controller.address, + value: "0", + data: tx.data, + }, + ], + }); + + return { safeFilePath, safeOwner }; +} + async function requestConsolidation({ source, target, cluster }) { const signer = await getSigner(); const controller = await resolveContract("ConsolidationController"); @@ -49,7 +77,7 @@ async function failConsolidation({ source }) { await logTxDetails(tx, "failConsolidation"); } -async function confirmConsolidation() { +async function confirmConsolidation({ safe = false }) { const signer = await getSigner(); const controller = await resolveContract("ConsolidationController"); @@ -57,6 +85,23 @@ async function confirmConsolidation() { dryrun: true, }); + if (safe) { + log( + `Generating Safe file for confirmConsolidation via ConsolidationController ${controller.address}` + ); + const { safeFilePath, safeOwner } = await writeConfirmConsolidationSafeFile( + { + controller, + balanceProofs, + pendingDepositProofs, + } + ); + + console.log(`Safe owner : ${safeOwner}`); + console.log(`Safe file : ${safeFilePath}`); + return; + } + log(`About to confirm validator consolidations`); const tx = await controller .connect(signer) diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index b2ad10a2f4..5d0127cf31 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -2636,9 +2636,14 @@ task("failConsol").setAction(async (_, __, runSuper) => { return runSuper(); }); -subtask("confirmConsol", "Confirm a validator consolidation").setAction( - confirmConsolidation -); +subtask("confirmConsol", "Confirm a validator consolidation") + .addOptionalParam( + "safe", + "Generate a Safe Transaction Builder file instead of sending the transaction", + false, + types.boolean + ) + .setAction(confirmConsolidation); task("confirmConsol").setAction(async (_, __, runSuper) => { return runSuper(); }); diff --git a/contracts/utils/deploy.js b/contracts/utils/deploy.js index 23026d6e32..acab4fdea4 100644 --- a/contracts/utils/deploy.js +++ b/contracts/utils/deploy.js @@ -31,6 +31,7 @@ const { } = require("../tasks/storageSlots"); const addresses = require("../utils/addresses.js"); +const { buildSafeTransactionBuilderJson } = require("../utils/safe"); const { getTxOpts } = require("../utils/tx"); const { sleep } = require("../utils/time"); const { @@ -964,28 +965,16 @@ async function buildGnosisSafeJson( contractMethods, contractInputsValues ) { - const { chainId } = await ethers.provider.getNetwork(); - const json = { - version: "1.0", - chainId: chainId.toString(), - createdAt: parseInt(Date.now() / 1000), - meta: { - name: "Transaction Batch", - description: "", - txBuilderVersion: "1.16.1", - createdFromSafeAddress: safeAddress || addresses.mainnet.Guardian, - createdFromOwnerAddress: "", - }, + return buildSafeTransactionBuilderJson({ + safeAddress: safeAddress || addresses.mainnet.Guardian, + name: "Transaction Batch", transactions: targets.map((target, i) => ({ to: target, value: "0", - data: null, contractMethod: contractMethods[i], contractInputsValues: contractInputsValues[i], })), - }; - - return json; + }); } async function simulateWithTimelockImpersonation(proposal) { diff --git a/contracts/utils/safe.js b/contracts/utils/safe.js new file mode 100644 index 0000000000..65ff982ba5 --- /dev/null +++ b/contracts/utils/safe.js @@ -0,0 +1,57 @@ +const fs = require("fs"); +const path = require("path"); + +async function buildSafeTransactionBuilderJson({ + safeAddress, + name, + transactions, + description = "", +}) { + const { chainId } = await ethers.provider.getNetwork(); + + return { + version: "1.0", + chainId: chainId.toString(), + createdAt: Math.floor(Date.now() / 1000), + meta: { + name, + description, + txBuilderVersion: "1.16.1", + createdFromSafeAddress: safeAddress, + createdFromOwnerAddress: "", + }, + transactions: transactions.map((tx) => ({ + to: tx.to, + value: tx.value ?? "0", + data: tx.data ?? null, + contractMethod: tx.contractMethod ?? null, + contractInputsValues: tx.contractInputsValues ?? null, + })), + }; +} + +async function writeSafeTransactionBuilderFile({ + filePath, + safeAddress, + name, + transactions, + description = "", +}) { + const resolvedFilePath = path.resolve(filePath); + const safeJson = await buildSafeTransactionBuilderJson({ + safeAddress, + name, + transactions, + description, + }); + + fs.mkdirSync(path.dirname(resolvedFilePath), { recursive: true }); + fs.writeFileSync(resolvedFilePath, JSON.stringify(safeJson, null, 2)); + + return resolvedFilePath; +} + +module.exports = { + buildSafeTransactionBuilderJson, + writeSafeTransactionBuilderFile, +}; From 12b579d68ddfd2aed9eebe2c91c4464205ff2fc0 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Thu, 19 Mar 2026 20:28:04 +1100 Subject: [PATCH 08/15] Got getValidators working with dRPC --- contracts/utils/beacon.js | 75 ++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/contracts/utils/beacon.js b/contracts/utils/beacon.js index d930669732..05366a790b 100644 --- a/contracts/utils/beacon.js +++ b/contracts/utils/beacon.js @@ -200,25 +200,76 @@ const getValidator = async (pubkey) => { return normalizeValidatorResponse(validatorRes.value()); }; +const getValidatorsIndividually = async (client, validatorIds) => { + const validators = []; + + for (const validatorId of validatorIds) { + log(`Falling back to single-validator lookup for ${validatorId}`); + + const validatorRes = await client.beacon.getStateValidator({ + stateId: "head", + validatorId, + }); + if (!validatorRes.ok) { + console.error(validatorRes); + throw Error( + `Failed to get validator details for ${validatorId}. Status ${validatorRes.status} ${validatorRes.statusText}` + ); + } + + validators.push(validatorRes.value()); + } + + return validators; +}; + +const getValidatorsByPost = async (client, validatorIds, attempts = 2) => { + let lastError; + + for (let attempt = 1; attempt <= attempts; attempt++) { + try { + const postValidatorsRes = await client.beacon.postStateValidators({ + stateId: "head", + validatorIds, + }); + + if (postValidatorsRes.ok) { + return postValidatorsRes.value(); + } + + lastError = new Error( + `Bulk validator POST failed with status ${postValidatorsRes.status} ${postValidatorsRes.statusText}` + ); + log(`${lastError.message}. Attempt ${attempt} of ${attempts}.`); + } catch (err) { + lastError = err; + log( + `Bulk validator POST threw ${err.name || "Error"}: ${ + err.message + }. Attempt ${attempt} of ${attempts}.` + ); + } + } + + if (lastError) { + log(`Bulk validator POST failed after ${attempts} attempts.`); + } + + return null; +}; + const getValidators = async (pubkeys) => { const client = await configClient(); const validatorIds = Array.isArray(pubkeys) ? pubkeys : pubkeys.split(","); log(`Fetching ${validatorIds.length} validator details from the beacon node`); - const validatorsRes = await client.beacon.getStateValidators({ - stateId: "head", - validatorIds, - }); - if (!validatorsRes.ok) { - console.error(validatorsRes); - throw Error( - `Failed to get validator details for ${validatorIds.join(",")}. Status ${ - validatorsRes.status - } ${validatorsRes.statusText}` - ); + let validators = await getValidatorsByPost(client, validatorIds); + + if (!validators) { + validators = await getValidatorsIndividually(client, validatorIds); } - const validators = validatorsRes.value().map(normalizeValidatorResponse); + validators = validators.map(normalizeValidatorResponse); return validators.length === 1 ? validators[0] : validators; }; From b4aeb463abb374a56b7be893a0af7a964d1b0192 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 20 Mar 2026 02:09:26 +1100 Subject: [PATCH 09/15] Added consol option to verifyDeposits which has to call snapBalances on the ConsolidationController --- contracts/tasks/beacon.js | 7 +++++-- contracts/tasks/tasks.js | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/contracts/tasks/beacon.js b/contracts/tasks/beacon.js index 747eb05c00..6f7498e76f 100644 --- a/contracts/tasks/beacon.js +++ b/contracts/tasks/beacon.js @@ -316,11 +316,14 @@ async function getProcessedDeposits(pendingDeposits) { return { processedDeposits, depositProcessedSlot }; } -async function verifyDeposits({ dryrun, signer }) { +async function verifyDeposits({ dryrun, signer, consol = false }) { const stakingStrategy = await resolveContract( "CompoundingStakingSSVStrategyProxy", "CompoundingStakingSSVStrategy" ); + const contract = consol + ? await resolveContract("ConsolidationController") + : stakingStrategy; const stakingStrategyView = await resolveContract( "CompoundingStakingStrategyView" ); @@ -343,7 +346,7 @@ async function verifyDeposits({ dryrun, signer }) { if (processedDeposits.length > 0) { log(`About to snap balances before verifying deposits`); if (!dryrun) { - await stakingStrategy.connect(signer).snapBalances(); + await contract.connect(signer).snapBalances(); } } else { console.log( diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index 5d0127cf31..d9a8629126 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -2229,6 +2229,12 @@ subtask("verifyDeposits", "Verify any processed deposit on the Beacon chain") false, types.boolean ) + .addOptionalParam( + "consol", + "Call the consolidation controller instead of the strategy", + false, + types.boolean + ) .setAction(async (taskArgs) => { const signer = await getSigner(); await verifyDeposits({ ...taskArgs, signer }); From ee03bd250f38950fc004073070ef5e94ce901711 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 20 Mar 2026 10:53:57 +1100 Subject: [PATCH 10/15] FIxed consolidation fork tests --- .../stakingConsolidation.mainnet.fork-test.js | 98 +++++++++---------- 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/contracts/test/strategies/stakingConsolidation.mainnet.fork-test.js b/contracts/test/strategies/stakingConsolidation.mainnet.fork-test.js index feac422942..44c85816fe 100644 --- a/contracts/test/strategies/stakingConsolidation.mainnet.fork-test.js +++ b/contracts/test/strategies/stakingConsolidation.mainnet.fork-test.js @@ -70,52 +70,50 @@ const activeTargetPubKey = // Balance proofs after the deposit to validator with slot 13498458 has been verified. // Run the following Hardhat task to get the proofs: -// pnpm hardhat verifyBalances --network mainnet --dryrun true --over-ids 2150199,2178131,2183214 --over-bals 40,32.5,32.5 --test true --slot 13820911 +// pnpm hardhat verifyBalances --network mainnet --dryrun true --test true --over-ids 2178131,2213390 --over-bals 32.5,32.5 --slot 13928087 const balanceProofs = { beaconBlockRoot: - "0x57469dee806b5d800485608d35abd4da7e67126a47766ebcf0d48e893ee6154f", + "0x93f545e9c23550f0934192e433a74438e65beec7c90f92a771b5e611ae494dfc", balancesContainerRoot: - "0x1d604276c380fcb4cf2f582470238fb5889e689cba7c41b1e3fe65d27c73ccf4", + "0x8f27c7c7ce2f490662a385bd0e1f8cff0edbefae993e39ca2f21205429b3814a", balancesContainerProof: - "0xf65464168068584bb4a21c0c5fd6c274baf02f99b1da447f8efe6ed3766fd3f5760b7f8ed792320bd25f4cad20917acd5be79af36ed474b7e548ec993b9ea3cf1f1221d4b2026ea1c33aa92fe7ed03063d310f641838ebdc57e71658ff428f7e6f653e3cd87cc3a92fca300518a08c6580b008aed8738be147dd7d618224333112b7970cbcaba44c8f553f22c313115f0d122be434fc1504eea62460a893cd1df5d97a633f1f54c669a48a2a6e222f75edcba625dd5ac4e802ad3e39a8bc411c9533b5252513c39201e005a893f087ca06c204f92ec39a8600d53d27a5e2d8223024fc916ff3494356d4883c169c8adf57c2192bdc3f0b10b9a83a58b6c7e0278800dc66329ce086cf603342490ca86d9cd0c770b68b20210003abcd6688a8fd", + "0x85324c52a14d47585124af7b122fb4e5dc95a328195a69cdbd2ac467a380087bde78b6f9afdee27c83dcab795db1174fb31809c3e18ccd101c45ca92146a34ba0fe39f130e2611965f830d94a77f38cd694b1c92c82bb1426082fd11974bf67429a18eca977c27b0c22f5df812b50554ee42926f66b70fe930751eaee9e5577c88cbdc15d22d62cf98507f4ec9c2859d7a3604a8712b3a4696e8ca42eca1293c35ecb1dce6bdc3af85bd9cf2f1f03cb8a04d217a199b03abd30d462a261fe2e7445fd94dbbc7e4c1e17974c0745d82a97865458517ec4d426b861f9c4e90e9d0b53e114879b41538e556e5d6a209127efcd4b0fe59e0bf64de8357cdc2273d6ec0cdabace9443f7ec6183c3a82e1762c339d8dfbbd1dfca1ba16967b4f2e6e8a", validatorBalanceLeaves: [ - "0x7a8ab3730700000023cfdfad260000003982b3730700000000902f5009000000", - "0x7aafe17f07000000bdb4e6c80e000000c388b073070000000000000000000000", - "0x6409ac7307000000ae8dab7307000000fdf3ab730700000000a5269107000000", - "0x3f0fab73070000005b11ab730700000000a52691070000009893ab7307000000", - "0xd488a37307000000a9c4a3730700000000ca9a3b00000000278a30393a000000", + "0xfd7c8373070000008984d5b626000000dba68373070000002e054f8207000000", + "0x7bc26d8107000000a9b15ccc0e0000004b9e8073070000000000000000000000", + "0x1fc47c7307000000e2b07c73070000000c927c730700000000a5269107000000", + "0x519f7b7307000000d2af7b73070000002a70028407000000f6977b7307000000", + "0xec30747307000000255474730700000000a52691070000001026e9463a000000", ], validatorBalanceProofs: [ - "0x91b5b373070000000f5b947607000000c69bb37307000000ad8bb373070000002adb4b4d69aaa69999f8b3cbac82cf30021304b10b86b96e946e6a901f18f75224611fe1968ec31b981143053376294c33d69029cd7020f43f7c88ee4b9e3dd0d9643e68f61a9ef90d7b450a8a39ed3d90c21cbb2121dc944e37849589e2609b75c6831a8584bc2df390d2c9f8657f92f4ca00fbcf85535c338a010a5a5ca2d3363ae1b917d8abb8186f9c9164a4d7e7d01b71fd9afb81e06044a8f9254ef260257dfb4ded8623bb06afb633e2e3f42de6f04a4a9da86c7f76a1dc6e738cdb7d064fc376df41d1f4d5779d91c43dfd2f44048a9b5fa5cc6e494dcbc69ce8f0d8a66f67b94aa46ad3d2a13b3e7524ae6479798be4a385f9c22528a8855b4113490f7522733c6449f70e9dbd3d1e40532c5fd5907fa8defe5d9f28a339581cfa9508ca6a515161156ef6e234be16294447b9b715d45a9fedf07448ca69ab7cca965e8f9894c0713ffe7b126d4da8e55779ac189f8a7daced838aeaddfc4827969685e6150805346707b93fd3dc16814572f4c4fe4a30d90fd628e063e4d2205dd5b2a7bb0dd5255b2c61841a99b48c3babc957c15a141494601902ba973d57521c68d67dfd3b5ced51600e0a31c73aee5aedd366f71cd93c71db921fbade5f0528d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0x7727b07307000000f514b07307000000873eb07307000000b601b07307000000183c4e10c45c942ee250aa76bd23a1d800d54268d003fb1a18ae5ca972043ebe8f849544ae96b739513ef3adf3a763f014412136caef897aec2bf43720261b5c48c14c7ba08e9fe98700839b6ea94ae236bdad7cf389a3804e5b310802418f067dee5f7e3e5066707996a3d1055218a0dff7532da97c9f5033c0603a9e2647c26fec04fb17237a2d2455868f83347647f64b62795870f18fa182c47081687341fc841beb580b1fa782b67bd091055a01e4683ec1bfbf4a7639ed4782a78a434a971a91917fb6d43248bf82d99342b5e3aac6b0aa06b66f9257c32a2ee1e6da355656cbe9a197887ddd2c410865a33aff7af986e4d88746ea051f5a1bcaa02c0e262a9b5c3c422e58d1e8d46f91b043d0ee54f516a00aac8fec28cfbec0430ae969ee8e706cb9dfa5cc255705b74cfbd9f76688eeab5cc6647e8588c761122449277e6c70dfb2a07d54f5ad9dc549c76cb89346fee016ceb5fb44f325ec5fa2fb85e6150805346707b93fd3dc16814572f4c4fe4a30d90fd628e063e4d2205dd5b2a7bb0dd5255b2c61841a99b48c3babc957c15a141494601902ba973d57521c68d67dfd3b5ced51600e0a31c73aee5aedd366f71cd93c71db921fbade5f0528d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0x8cc2ac7307000000d897ac73070000009abaac730700000078b1ac7307000000814d0dd3b4acd0848a47f7378d5c3a886a7488afc68adad0bf7fd8477ced719cdded1b98c8f7d178a2aab509451d3fa7cfb394dc047d9e05f45182193b27954ae41e0ee0e7344b0c1d5f6be53b587184a6af22641a5186c1e20d289b9d21dd7f53716ea2a449ae8ab9f57eb48f54e19b10cd81fcf7b41d8d926ef96db4774fca3154c1a8a6bd9f407a754999bae28d5a52f60a882e2bef913d6a49b69dcfffb2fa455ba67c4f4f77d669e278eb5db87a725f2e495a8e178f901aa40e81ade553da6afa3b62292061875f98c5ca555d8c95b0805b5c3472ab8ed1d7e21ec69125ff1e3150177812d52d46da594edb68e2e068b4c276d099cc6fdf61d0d03dd4aad2af44ed1850e478c1cde81367aec61f42c944f6a5bd8dd044e85ca932a68871c99062e06b6219b0c8ca7b61742fa6bb77905e056fd4cb4b2df98d95342235d039c9f7b479a6451d9094c841633f2c8f36d2b09927f7e759b74a657e838ae6649161103e879228422ccc782be76afe3cd49d0b44daebccb07923c902c763b05cfd21614438b342b4d85364d0113b4de132bad8e203a3527279c407b16287dd35b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0xe53dab730700000035cc6cdf34000000fbf6aa7307000000f711ab73070000009682c65d1c4036364924f9417050ee73139745e3642024cdfa54ba42f2f409129a238c0a619a8261f0cf2459022017e90a24b23d06bf17ebcaad7352b33d84c4430eb7069ff7fe8821c33259a0f5d3c9e3547a45cc4e55b52e3b3cb1e309b065d0839d15655f330f8c2163ba7f303b28e20cdeed40428f262808827dd7772d5f41d88e801531b6fc001f13e56dcda7b85847ee1cf82019ffc676491f3f28f2f6ae5f2d1463291a3c054dfafece2f66d5be5f8e23158a5affb8f01dc426ac92ee523af231453375227b8a5b30249daf624ce3dc9a7294de89c9ee3df82b377d5ce17fce17f6b74c587f00459ea68711f4d78fe2c18cbd88e4593204dfdf4ce7a3982939c8ec817b8e7ed6be08cff3199428cf53c8a0ca867cca13dd56e5ca4e4763156f99dffc9e353c9b43d3060af2e34082095d67bef79c36123a831da45e48a9ab34cd219d0c2968c850974a3b63325b3548eafa81c176ddbb1298ecb779895e5f5a1c999ddb3ab5cebb4e819d9ca20f4cb0266d991e75beffbf8b10e4868efd21614438b342b4d85364d0113b4de132bad8e203a3527279c407b16287dd35b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0xcb78ba8009000000b655dd7307000000a07ca3730700000051e7a3730700000048b5aeabe78ac2b7b61c4aaa9ab4460fd34383d18f11c43ca65b55cd9dcb9b42d8bf40346d06af2a014c15569c023ba72ff22a01e3c4e3dc123fb97bb908f068e2bc617d6e29f374de3ea70877300ab7f397fa0b76f497b7913e20e8cc33ed4359f949bd3d019e29c132b361999ff6c4a14319828327a019ceee766fdfa4203a77098e14fdd75a3e41ad3d4477a656422f083f82a905be2e0290954025999ce95375896f270c17584036fb92cfff7c0cff6a81376293a209c67a3bd894d132065d748f54fa9cf15329ad5a0842e0f92adcb2da3546ef5c3ed6e94cb3691df0241cc56f7672df03265293f1bb0ee6aec8d26ca7fb8c445f24c33efab6e8f4963880f3f7b969bc260cad58d020cc261c895fb40b84e6eb557902c3eab37834a0be70a88a6553c49e6ed09b126341cf2b33a4c0e95394fe77df5f3b1742762761a36cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220962a82a34e2052c79f5e61e9356af68ac626d1f90b3c55cc78ebd38bcbb8c1ce359cbf71469d381be46ee475d45943e100c63489e90082a360e7dade3abb7598b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", + "0x917d8373070000009eaf837307000000ea7d837307000000b39e8373070000008c48c30a5f5ae1a56746099c051ca96073e376aac7551f0d6d6a15a9a48f4052d994e0b28373640577c0ab09ace51a55fef80ad962e2faed045b55947a7a4f34e54d6073f9d09e38595b3f6ecfd92945b721d23784789129babc2094a2915987da37705db46c6e770d7f8c5b9ec69d35257f92434347705e56b1d5d561f2fdaa50a600d0379af06018ac56268cf9a870f71986b9a9e60cdf51fb3c6d0d52e9f0670e19e0ff26a62093902fbca179f7f36f258d50a9073149f965612acb5773dcfd63d877accda0a33848d28d9689f0e3b83a09bef854569381d7889bbb536159d7e71add819625b8fb0ede9e5c35e0ed113de4618d5f442e7f82e0a0f582c4ac53f83b465d1d41767e25220cc72c91e6b5eceb05f2952e98dad8db50a87de1b6ed1740dd097f2086df81b875c8b39db903df524bdc88b56ac9a50f1ca1ab16ba6ecf6113eb8e424f51815a7f0a0864004680bf513454bba188ec30a1c66a9b8534965f292af9adf02e23328f62e4bef83791aeb3d729ed87cd9838fad6790dd7d66891394e3eeb07d48be1bf8604cac743a2841e87a4e163862255cf07f5195f0ebdd8cd635541d51b39455c8da6481af73661128d0b29da8a88c5da854f3144daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0x5058807307000000d6c780730700000070bf7f76070000002560807307000000a360ff8aa16d43dbf04b07a5b55942294f5d57adf813a844d305c8c6b2cd993ffbf093e17c6938a06cc1a21c77904c05c21e5f710e745ca3e40b88f1671050c633b03e8a35f6247def38d97d633697663930096b94cf96bda09764ec852d3abc29848299af499e3c19da8a78b953624818e08eb50a7b4bd6cdb884e7c4e9f9de7a3b437e6ac8737e2fb5e8268cc3b4804f92bfb6efd420fe08b0f69cda9653f46e8a1707614ee210693a4ab9296bca5d1f7d5ff3e435f4d1a842d94e669f2404986fb00fe176687a08685b8333dc93c6d4a3a549a9efd75c64709d82d8c95eec837c502df948738b0e5a1e5cc552caf4f8c1a87ec43a01a890b069acbb0936c417af734a796fa2937aad9c827c0db2f0acf793fafdef4eddd71a12886765359e8d8fc5bf9ce38b8bdd8fbea19bd20cc3974d7fb337f1e513b7121df301e709733eb355e772fa45ebc65fb923d0eff6c2dc7632e422725146683ad8b8bad084f634965f292af9adf02e23328f62e4bef83791aeb3d729ed87cd9838fad6790dd7d66891394e3eeb07d48be1bf8604cac743a2841e87a4e163862255cf07f5195f0ebdd8cd635541d51b39455c8da6481af73661128d0b29da8a88c5da854f3144daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xa49a7c7307000000acf67c730700000037e57c730700000033e57c73070000008511637653965e07d7eeec0223160f5358eadfaa3c6105ba20ea3bdf05ba7c6f75e7b877dedc859f9584a998e122e6aeffa96b9f05459f83e3936af6e50659ce6544de0e1bcef3cf00b1214e085b562bbab1889bd25bcf8849fe8c1da7fdec72a5148e91dd117e0dab7a05c9d2394e7e66cb7b21096dc8690dd0d8208c336604aad72859e0cbcf82058befcb3ceb8cea7fb7067115232dd11ab59a47ed538aeb46933c6defd1f2f9ab6c19b5e9d6bdfd184d7913f2e0cc9b588116966b5f5cf0b966c56783dfe114de1a7df4dc96def908aa579b9b56e06e4b0465f7d1332fc5cf9a044bff818ea2b269f25762c367896911a93f2203a913d64e811611b1da45d7d5b62bc68abf2e770261e5ae2c128f915c56a61a166a4cdbb3372911b6c69f9abff178ccc312b22b154981de48b8a5b0650b3a4e175ab9dd3636e67e5c4eff6b93420876ef20a461a47eb645ed08b852f79e40ce93cd2b9203568fbbd6094c34b74724946c4673142c68b9fd1d7daa05f34dd5747a10f1c5010de31d47960e78c9350c52049bb9000dbda4f0a908c8eb29606b74fb3702653514a19cb6147f6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xe8b07b73070000006e5bb4eb34000000be957b730700000097867b730700000059e193bc2473fca31d2a10f8454520bee1957d7e3e9ced87f2e8425c0c08f6bb52cf8c48e946e9da705ac19a462706b411d24b8f373e325a628208d7047d0ffc0fee33b653cd0fd01e2ca1608a9b94c94c67f365657d8a86a53bc8dfaa3988a724504dfe79b6f5afb44ecf53753aad7efff2452183032a5b1219b5c99f384719c1022f632a5e029648ce78f33b5cbe1c606c327b7b29aa4c03cff2be1ae5ccebac8253bf25ade6c873f6509570ce4a30783c746c5875ca346078e184eac19dfc9f416299e9fb4250b04a8e3e2d22a2771eda8639962bc285055754f357667fdd80cd1d2fef1f6a297426c80d198e5821e538e851fc608333ac632937e0753b69b1b1cba2be0ab14696726eac8f6b818ef3d0396e6d563b73d378a48f0ed77cd518b72fef2551971a58c574c4fad812bbd71e0a41ed97c1c74d3f665e4f849945939fc1349559b3feaf32db756fbdb425cb7de72cee400a0a83ae1a3fc1541ee163812708e31e1ec62e05f94e47973926890f90e5e6bdfc4e034e6d75ace091b678c9350c52049bb9000dbda4f0a908c8eb29606b74fb3702653514a19cb6147f6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xc14ded8209000000d3399f7507000000c35c74730700000052547473070000003fd8a8a3abe91daabbcefb46c12679757b5ef84a1d1a86f88ff4f72108743082c16a90f3122651c46b9fe13ad5fa9039689f8f8310bd87fede796de7ae7e6b8b26e8b864ab910e64fac8d21420305ac13d40ff60b337734cbed410b74d045b4b191c8a834a78383c882c63cd73b5ec3045147d6866b03d668926675421d9dd9430059267161313dd5d8078f97681146f8ad9699662294f8d96838c1a02eb55950ba94ee41400881a940e82b104faa44ea94de3aafc6708bdfdfad612e5f8b3b17db9f9b3303b7fb8910a42ac46832ad3dbc1122ff9b81ce8343aea02b9dd4f08b85f6f22463648903c3e2c93d738ec5c5bbabc7969d350c5fb65538711c7651da9758deaadab0eda5cf7047a9b4cf76f32ba76d0f410e2eb0979f709ef7c3a875c6c2088e2ae731e9e64583785467c21b800cf320d9807a45210ef86d0b70e44efa206455c565617f73c5a3a4cd1b98c93d21d398f2bc25a63c5ea5095c8fd3905383a708f1ae8e6cdfef5a2aabf0fa4bf39ab9c9dd8aca35c9fd45ea283df683a83c2524a66c24e653e6fa354bbba4050ce12082d94df4108e75baf1b125bfe6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", ], }; const pendingDepositProofs = { pendingDepositContainerRoot: - "0x07a707c8f0cf4aca57d27a9bb2ab16fa3cfbc11b78124d8dfd1a4078196c0c8c", + "0x8e9a353f5d80d749c0f322bc97530477e6c5a3ca14b253d0a26264872b45bdcf", pendingDepositContainerProof: - "0x2bc2f2dad0202c8b321b844aa1b3b9d1b0ffcea3f6d7a93ec81a730ac50e63fdb47a0cc94e65bb91b64ff7327832564dbb190bb792e044f485deda924863c4db27b4b67bd5f307a23dde240ef20096635b24d79d7a8057fa660d042f2dfb20eac78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123cad3149b34212918f6bc172d60e0dc71eb965d69d92ccf4373686d358af9c771e9533b5252513c39201e005a893f087ca06c204f92ec39a8600d53d27a5e2d8223024fc916ff3494356d4883c169c8adf57c2192bdc3f0b10b9a83a58b6c7e0278800dc66329ce086cf603342490ca86d9cd0c770b68b20210003abcd6688a8fd", - pendingDepositIndexes: [24060, 50280, 24059, 24058, 24057, 16528, 24055], + "0xc5a691c90b1e5a4b98433a0f4bd86eba8048f63b7d3a1b4fb66ba0c7ae8812773db8d01d9495a3bbeb4f3d22d6a373692bbbf60c638fa615738f83ac08f464c9f7507516e2aa2af211bec2d8c99165b7fad41b628ba3483ae4538d0297e9959bc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123ce0ef6aa1d629eca8a8ec78c2649b889f0c585e16e92862010bb41d58afd7df61445fd94dbbc7e4c1e17974c0745d82a97865458517ec4d426b861f9c4e90e9d0b53e114879b41538e556e5d6a209127efcd4b0fe59e0bf64de8357cdc2273d6ec0cdabace9443f7ec6183c3a82e1762c339d8dfbbd1dfca1ba16967b4f2e6e8a", + pendingDepositIndexes: [6791, 33011, 6790, 6789, 6788, 6786], pendingDepositRoots: [ "0xe43aa97c7b45d686240e148893fb944692f4a5513afca99a351c1f20e26c5597", "0xf1947604474b44eec74edd4768599915239e72f4002737713af83febc36398cb", "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225ce", "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5d", "0xac9a98d48b7b13938bbf6c50c07b7d9f41c78c2dc9515280ec3cab9209ac44ba", - "0xbee3eb2fda60ca0a8adce2791490ef0fb414b84d5f9467f094a5abac12a4afd1", "0x5daaa459171d3c16aa9c68ece5f1192d0be4900291029fe9dee738493895ab8e", ], pendingDepositProofs: [ - "0xded0993aa9a75aa36416422175e06bc345602ea084fcc2f27b6436e64d5d0bc8fc9110055ae92751f36ee90fe2a3c25149f00547e90dae303b5d39e4f25080f0f29a9186f99e0866908b531b08bfc3390aa1b1bddb3b6bdf5766b0c9b9432a93d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x97748b89e2948e942d8d6215fd9496942c5df9d149ae9e7160b62a50abb13e3d2028cedcf850cf9779fc1a21b360cb8c8603d34bff12279fc18dc3ae30f43d419fa76e4e5b19d33fa33ffcee83c228cc3473d6aba6b8d695b754fecc3bd6f3d29cfeb7cf94db25f4fe20f33acff305564791c97fccff3a123a5dbe41ab4a015870e84b57f0c628580708e00160e2f3cc44dd7a1110d5544dc0d0c9cc213e89afd317a78a3c3006a235a24da0b8010ab6caf70b151a8c0743859dffd5bae95cb466922dbd696108eaab1e27408c9c4e796430e506b808905494b5e0f32578f59e757e24b682fb94e5efe111eb8aa0adb8d06eacc805232b893b4e7045b7ca04b5d64ae47eaf3037b50a5afc2d5457d6feb0b5167e1530566a9c2431e44fd85083eec1d5ef0619d311773d3fe579304084b2c341e81c2a8bccba3143d48561ad1242f920c73342b2e90cf162d94473ab8ed4c6d28259777108a717e8c5a4312ff593a5ed25b13823e8ee9d53c93c1c8c51388229af97d596f49ab3d7bcd5aa8745b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5fdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e7a45ea59e241bd537ee551e2d4b6b0756004839a42767ae113c3891b7056ad1740e13f32ee31a7c21f350694ce2809b5db0268ab71549c51e09365cbcc3d9ee18fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5d5f1ba92b82d7073122621c73e6af3e70746b94bf6d20b9f94e871095bdcf6122a3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225ce5f1ba92b82d7073122621c73e6af3e70746b94bf6d20b9f94e871095bdcf6122a3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x308dba54c2444e4683aa4c92c423532dae274d39dc0a95a2871b90006b41a3570f3225288e19861b9e39393c62293f55e0638f778e8e0cd34815ba42d3b92feda3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x9b06f36ea5e8e7ba833832a61c9facb8db666134bba4e1c5ef74f4174a9e43a4c4fe22cc2ba736d7af11e26b9152f1ef7d9757c588f46915acd8adead189aa47096ad82b8ec78f320b53c63a312e4517efbb205b1a5bc71f21776d1a28244f260f4e47c398bbdbe17a7cc96cbc7ba548039d5c9ec057b43aab992c4e5b950839e3baf30942d62204400a59e3413a530f0b2f63ebdfa260abf833512ca010a5212eee1b5aeb8630d46197c5e32908e495f84534ef9d9a852b83fc413776e201e77ed77d0ba56ce929b8d3db53d1724c0c5ba3c60640eda489b7fb824ce4ed3ea9bec20551dc2d9e16255bfbeb3d4d00badcd7eb8d9fd35aedef99feb52d69a75163472173d644d1c69f6054a005a607398b8b2ecefb0e6ddf642cbd02b171f26ed9cb26f04e0c811550f70dc948973c22e2fde8c6712a1da72a399ac4bee0d3e754ce0b3653d53a959bd57edd3baf9d901546910de11d5a7f53cdb091d30552cfed573ca637fba29361cee8faac4883878350624d13a380b7da3bf9f831f12ea7e0228b961983fa30bd6586f0ece3a66a83fc789a2c803d765ca0d29955f0f8d8a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0xc182d7661fdeb3ee903f8dd7ecc70f23872de8fffdddd73370c7b83d722525f1ce74353fece6c946005bc85e4771ae46ba00c6552dec62e813548c3dc1316ba8ad0d6dd24f6ea2f15e7ce6b2df96cde6b66742a01f68a2af50a179077cefb2fe55cb4cecc74f7add89ba98e95068300bdab5134daa8d73cfde3f5dbce945fcb22046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", + "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225cead345f10252274408791763ea728c60cfd0c0e4b830a4478358e903ea5fb8e9d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xf7249eead0f1aea2b1fbd85cc602f80baf13e0a02cf9d3089e718e6658ce1693f792d6b43e88db568ea6dfcb3610f61591ee6b5c6eaeb6ccfef90f21d4b59639d55dd5372c0ccbe43f33259d9de97bfbb1e50625553b883a20f883ac588df75c54591b16d0df56bd9b2fef101017199b4beb0fdd39204fdee898baf569b591734284ea78eab42ac0bc127e4a33c0f1b6b1d7ce7f1c22c077571b4b4ab17cd6d15ec0911248ab6ac0fb6e40784dee43a812f1b2e6825e663b3c3bb9c8e919f1276b2bd5a3617467e8bc2a537855f2f6ace03a9fc68c3bde3fd4ea00e6428a4114a8749e8f840f1e524602b6b9ef58a896ac8ccba0e55bb89c72eae1130fcf463433b6e9dcdd3563b9304399dbabe9f1cb6c5681c72c703678e5bcb6a343607a9844c92daa1fe18120b85cdebb842c8761b2318bd50bad75742cd23e24674e55657075a0f80fc134385cae7ca7a8d0bf310debf5e875dd4c2ed98f5082e013576152827b331483b5af2d583798206b7673defe032939eaa66fba62754814cddc226b0d00c895f66aea0409aa599d3f4e99192e2bacb7a99bf00646e55d758f18bd72f2d4e1e15bc9b4649c63daf8060b6b26098a0f3837e145b78e5418c4fe23c9b58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da729378453c470d6bb6d6d92cb4b1f45bdf68e17b3b2d513ccad61d8e91baeec8cbf2c568fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xe43aa97c7b45d686240e148893fb944692f4a5513afca99a351c1f20e26c5597ad345f10252274408791763ea728c60cfd0c0e4b830a4478358e903ea5fb8e9d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xac9a98d48b7b13938bbf6c50c07b7d9f41c78c2dc9515280ec3cab9209ac44bad1382044558891e141307d62d35f69c7e8ef2566e8a758ac46807c46fab10b6d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5dd1382044558891e141307d62d35f69c7e8ef2566e8a758ac46807c46fab10b6d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0x308dba54c2444e4683aa4c92c423532dae274d39dc0a95a2871b90006b41a357f48cf215d71cd05cb4214ebac67ba013270cc2c9b3e9cd3764671f1461135947ff01249f12eebda99afdc7882e5a0b55955740fe202576daabaf7fd026a0d73e44e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", ], }; const emptyCluster = [ @@ -598,7 +596,7 @@ describe("ForkTest: Consolidation of Staking Strategies", function () { }); it("Fail to request consolidation to a target validator with a pending deposit", async () => { const activeWithDepositCompoundingValidatorPubKey = - "0x8b5f08ce7af02245ae664a96fde5af1585edaa257f852490e5bb1957f1b3433b9b213577a3e475d6b034618f641f3bee"; + "0x8427639adf9c746f7d7271ddee3bbcd7a1f3b4beb3bd67224c345d7c7e7cffd58d61d5bc84a3ab7d0f909ebf71da7b8b"; // Target validator pre-conditions const targetPubKeyHash = hashPubKey( @@ -1240,52 +1238,50 @@ describe("ForkTest: Consolidation of Staking Strategies", function () { // Balance proofs after the consolidation has been processed on the beacon chain // Validator with index 2178131 has its balance increaed by 96 ETH // Run the following Hardhat task to get the proofs: - // pnpm hardhat verifyBalances --network mainnet --dryrun true --over-ids 2150199,2178131,2183214 --over-bals 40,128.5,32.5 --test true --slot 13820911 + // pnpm hardhat verifyBalances --network mainnet --dryrun true --test true --over-ids 2178131,2213390 --over-bals 128.5,32.5 --slot 13928087 const balanceProofs = { beaconBlockRoot: - "0x76d868a26b29a98ed195634587802aa0fcfd335a3a086b89aa99616e97843375", + "0x0585a4f9646714ef9af7b69c6ed1fa74d8ef44f748c193e8de4d2d994d78345e", balancesContainerRoot: - "0xf5205af51f66aa27be195bfb0e69c4f366ea3995ecb3035ab5e4830580f29c54", + "0x76eb3a513bc54c3167a144f41aec2b124417364bc31b4601dfda0604f071630e", balancesContainerProof: - "0xf65464168068584bb4a21c0c5fd6c274baf02f99b1da447f8efe6ed3766fd3f5760b7f8ed792320bd25f4cad20917acd5be79af36ed474b7e548ec993b9ea3cf1f1221d4b2026ea1c33aa92fe7ed03063d310f641838ebdc57e71658ff428f7e6f653e3cd87cc3a92fca300518a08c6580b008aed8738be147dd7d618224333112b7970cbcaba44c8f553f22c313115f0d122be434fc1504eea62460a893cd1df5d97a633f1f54c669a48a2a6e222f75edcba625dd5ac4e802ad3e39a8bc411c9533b5252513c39201e005a893f087ca06c204f92ec39a8600d53d27a5e2d8223024fc916ff3494356d4883c169c8adf57c2192bdc3f0b10b9a83a58b6c7e0278800dc66329ce086cf603342490ca86d9cd0c770b68b20210003abcd6688a8fd", + "0x85324c52a14d47585124af7b122fb4e5dc95a328195a69cdbd2ac467a380087bde78b6f9afdee27c83dcab795db1174fb31809c3e18ccd101c45ca92146a34ba0fe39f130e2611965f830d94a77f38cd694b1c92c82bb1426082fd11974bf67429a18eca977c27b0c22f5df812b50554ee42926f66b70fe930751eaee9e5577c88cbdc15d22d62cf98507f4ec9c2859d7a3604a8712b3a4696e8ca42eca1293c35ecb1dce6bdc3af85bd9cf2f1f03cb8a04d217a199b03abd30d462a261fe2e7445fd94dbbc7e4c1e17974c0745d82a97865458517ec4d426b861f9c4e90e9d0b53e114879b41538e556e5d6a209127efcd4b0fe59e0bf64de8357cdc2273d6ec0cdabace9443f7ec6183c3a82e1762c339d8dfbbd1dfca1ba16967b4f2e6e8a", validatorBalanceLeaves: [ - "0x7a8ab3730700000023cfdfad260000003982b3730700000000902f5009000000", - "0x7aafe17f07000000bdb4e6c80e000000c388b073070000000000000000000000", - "0x6409ac7307000000ae8dab7307000000fdf3ab7307000000006532eb1d000000", - "0x3f0fab73070000005b11ab730700000000a52691070000009893ab7307000000", - "0xd488a37307000000a9c4a3730700000000ca9a3b00000000278a30393a000000", + "0xfd7c8373070000008984d5b626000000dba68373070000002e054f8207000000", + "0x7bc26d8107000000a9b15ccc0e0000004b9e8073070000000000000000000000", + "0x1fc47c7307000000e2b07c73070000000c927c7307000000006532eb1d000000", + "0x519f7b7307000000d2af7b73070000002a70028407000000f6977b7307000000", + "0xec30747307000000255474730700000000a52691070000001026e9463a000000", ], validatorBalanceProofs: [ - "0x91b5b373070000000f5b947607000000c69bb37307000000ad8bb373070000002adb4b4d69aaa69999f8b3cbac82cf30021304b10b86b96e946e6a901f18f75224611fe1968ec31b981143053376294c33d69029cd7020f43f7c88ee4b9e3dd0d9643e68f61a9ef90d7b450a8a39ed3d90c21cbb2121dc944e37849589e2609b75c6831a8584bc2df390d2c9f8657f92f4ca00fbcf85535c338a010a5a5ca2d3363ae1b917d8abb8186f9c9164a4d7e7d01b71fd9afb81e06044a8f9254ef260257dfb4ded8623bb06afb633e2e3f42de6f04a4a9da86c7f76a1dc6e738cdb7d064fc376df41d1f4d5779d91c43dfd2f44048a9b5fa5cc6e494dcbc69ce8f0d8a66f67b94aa46ad3d2a13b3e7524ae6479798be4a385f9c22528a8855b4113490f7522733c6449f70e9dbd3d1e40532c5fd5907fa8defe5d9f28a339581cfa9508ca6a515161156ef6e234be16294447b9b715d45a9fedf07448ca69ab7cca965e8f9894c0713ffe7b126d4da8e55779ac189f8a7daced838aeaddfc4827969685e6150805346707b93fd3dc16814572f4c4fe4a30d90fd628e063e4d2205dd5b2a7bb0dd5255b2c61841a99b48c3babc957c15a141494601902ba973d57521c64366a37bf3c5715f15d615521e846b4ed70623bea1a1ccfdc2e59a719bb6298d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0x7727b07307000000f514b07307000000873eb07307000000b601b07307000000183c4e10c45c942ee250aa76bd23a1d800d54268d003fb1a18ae5ca972043ebe8f849544ae96b739513ef3adf3a763f014412136caef897aec2bf43720261b5c48c14c7ba08e9fe98700839b6ea94ae236bdad7cf389a3804e5b310802418f067dee5f7e3e5066707996a3d1055218a0dff7532da97c9f5033c0603a9e2647c26fec04fb17237a2d2455868f83347647f64b62795870f18fa182c47081687341fc841beb580b1fa782b67bd091055a01e4683ec1bfbf4a7639ed4782a78a434a971a91917fb6d43248bf82d99342b5e3aac6b0aa06b66f9257c32a2ee1e6da355656cbe9a197887ddd2c410865a33aff7af986e4d88746ea051f5a1bcaa02c0e262a9b5c3c422e58d1e8d46f91b043d0ee54f516a00aac8fec28cfbec0430ae969ee8e706cb9dfa5cc255705b74cfbd9f76688eeab5cc6647e8588c761122449277e6c70dfb2a07d54f5ad9dc549c76cb89346fee016ceb5fb44f325ec5fa2fb85e6150805346707b93fd3dc16814572f4c4fe4a30d90fd628e063e4d2205dd5b2a7bb0dd5255b2c61841a99b48c3babc957c15a141494601902ba973d57521c64366a37bf3c5715f15d615521e846b4ed70623bea1a1ccfdc2e59a719bb6298d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0x8cc2ac7307000000d897ac73070000009abaac730700000078b1ac7307000000814d0dd3b4acd0848a47f7378d5c3a886a7488afc68adad0bf7fd8477ced719cdded1b98c8f7d178a2aab509451d3fa7cfb394dc047d9e05f45182193b27954ae41e0ee0e7344b0c1d5f6be53b587184a6af22641a5186c1e20d289b9d21dd7f53716ea2a449ae8ab9f57eb48f54e19b10cd81fcf7b41d8d926ef96db4774fca3154c1a8a6bd9f407a754999bae28d5a52f60a882e2bef913d6a49b69dcfffb2fa455ba67c4f4f77d669e278eb5db87a725f2e495a8e178f901aa40e81ade553da6afa3b62292061875f98c5ca555d8c95b0805b5c3472ab8ed1d7e21ec69125ff1e3150177812d52d46da594edb68e2e068b4c276d099cc6fdf61d0d03dd4aad2af44ed1850e478c1cde81367aec61f42c944f6a5bd8dd044e85ca932a68871c99062e06b6219b0c8ca7b61742fa6bb77905e056fd4cb4b2df98d95342235d039c9f7b479a6451d9094c841633f2c8f36d2b09927f7e759b74a657e838ae6649161103e879228422ccc782be76afe3cd49d0b44daebccb07923c902c763b05cfd21614438b342b4d85364d0113b4de132bad8e203a3527279c407b16287dd35b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0xe53dab730700000035cc6cdf34000000fbf6aa7307000000f711ab73070000009682c65d1c4036364924f9417050ee73139745e3642024cdfa54ba42f2f409129a238c0a619a8261f0cf2459022017e90a24b23d06bf17ebcaad7352b33d84c4430eb7069ff7fe8821c33259a0f5d3c9e3547a45cc4e55b52e3b3cb1e309b065d0839d15655f330f8c2163ba7f303b28e20cdeed40428f262808827dd7772d5f41d88e801531b6fc001f13e56dcda7b85847ee1cf82019ffc676491f3f28f2f6ae5f2d1463291a3c054dfafece2f66d5be5f8e23158a5affb8f01dc426ac92ee523af231453375227b8a5b30249daf624ce3dc9a7294de89c9ee3df82b377d5ce17fce17f6b74c587f00459ea68711f4d78fe2c18cbd88e4593204dfdf4ce7a3982939c8ec817b8e7ed6be08cff3199428cf53c8a0ca867cca13dd56e5ca4e4763156f99dffc9e353c9b43d3060af2e34082095d67bef79c36123a831da45e48a9ab34cd219d0c2968c850974a3b63325b3548eafa81c176ddbb1298ecb779892cde802610168e65526d12dd46f4ed0cb6d21c2162132ee8d363de8d1338a958fd21614438b342b4d85364d0113b4de132bad8e203a3527279c407b16287dd35b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", - "0xcb78ba8009000000b655dd7307000000a07ca3730700000051e7a3730700000048b5aeabe78ac2b7b61c4aaa9ab4460fd34383d18f11c43ca65b55cd9dcb9b42d8bf40346d06af2a014c15569c023ba72ff22a01e3c4e3dc123fb97bb908f068e2bc617d6e29f374de3ea70877300ab7f397fa0b76f497b7913e20e8cc33ed4359f949bd3d019e29c132b361999ff6c4a14319828327a019ceee766fdfa4203a77098e14fdd75a3e41ad3d4477a656422f083f82a905be2e0290954025999ce95375896f270c17584036fb92cfff7c0cff6a81376293a209c67a3bd894d132065d748f54fa9cf15329ad5a0842e0f92adcb2da3546ef5c3ed6e94cb3691df0241cc56f7672df03265293f1bb0ee6aec8d26ca7fb8c445f24c33efab6e8f4963880f3f7b969bc260cad58d020cc261c895fb40b84e6eb557902c3eab37834a0be70a88a6553c49e6ed09b126341cf2b33a4c0e95394fe77df5f3b1742762761a36cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220962a82a34e2052c79f5e61e9356af68ac626d1f90b3c55cc78ebd38bcbb8c1cebbe95552e4b3b69b498ac3f5bc17d73710c25988b8f4ec54baf40c57620748e7b2c59c0a3c35390bd100bcb753f931fe2d993bc0691809ec7865bab8fd9b0821d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43171dddf37a0c24cf8721a714a8fd680643f1bb3fc01e06c541d2bcf8602a5d6cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74afd5210000000000000000000000000000000000000000000000000000000000", + "0x917d8373070000009eaf837307000000ea7d837307000000b39e8373070000008c48c30a5f5ae1a56746099c051ca96073e376aac7551f0d6d6a15a9a48f4052d994e0b28373640577c0ab09ace51a55fef80ad962e2faed045b55947a7a4f34e54d6073f9d09e38595b3f6ecfd92945b721d23784789129babc2094a2915987da37705db46c6e770d7f8c5b9ec69d35257f92434347705e56b1d5d561f2fdaa50a600d0379af06018ac56268cf9a870f71986b9a9e60cdf51fb3c6d0d52e9f0670e19e0ff26a62093902fbca179f7f36f258d50a9073149f965612acb5773dcfd63d877accda0a33848d28d9689f0e3b83a09bef854569381d7889bbb536159d7e71add819625b8fb0ede9e5c35e0ed113de4618d5f442e7f82e0a0f582c4ac53f83b465d1d41767e25220cc72c91e6b5eceb05f2952e98dad8db50a87de1b6ed1740dd097f2086df81b875c8b39db903df524bdc88b56ac9a50f1ca1ab16ba6ecf6113eb8e424f51815a7f0a0864004680bf513454bba188ec30a1c66a9b8534965f292af9adf02e23328f62e4bef83791aeb3d729ed87cd9838fad6790dd7d66891394e3eeb07d48be1bf8604cac743a2841e87a4e163862255cf07f5195fc3d571aa74d41c43bb1109597b4fa8aea80f0a8f96490216df86e921f1c320b1daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0x5058807307000000d6c780730700000070bf7f76070000002560807307000000a360ff8aa16d43dbf04b07a5b55942294f5d57adf813a844d305c8c6b2cd993ffbf093e17c6938a06cc1a21c77904c05c21e5f710e745ca3e40b88f1671050c633b03e8a35f6247def38d97d633697663930096b94cf96bda09764ec852d3abc29848299af499e3c19da8a78b953624818e08eb50a7b4bd6cdb884e7c4e9f9de7a3b437e6ac8737e2fb5e8268cc3b4804f92bfb6efd420fe08b0f69cda9653f46e8a1707614ee210693a4ab9296bca5d1f7d5ff3e435f4d1a842d94e669f2404986fb00fe176687a08685b8333dc93c6d4a3a549a9efd75c64709d82d8c95eec837c502df948738b0e5a1e5cc552caf4f8c1a87ec43a01a890b069acbb0936c417af734a796fa2937aad9c827c0db2f0acf793fafdef4eddd71a12886765359e8d8fc5bf9ce38b8bdd8fbea19bd20cc3974d7fb337f1e513b7121df301e709733eb355e772fa45ebc65fb923d0eff6c2dc7632e422725146683ad8b8bad084f634965f292af9adf02e23328f62e4bef83791aeb3d729ed87cd9838fad6790dd7d66891394e3eeb07d48be1bf8604cac743a2841e87a4e163862255cf07f5195fc3d571aa74d41c43bb1109597b4fa8aea80f0a8f96490216df86e921f1c320b1daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xa49a7c7307000000acf67c730700000037e57c730700000033e57c73070000008511637653965e07d7eeec0223160f5358eadfaa3c6105ba20ea3bdf05ba7c6f75e7b877dedc859f9584a998e122e6aeffa96b9f05459f83e3936af6e50659ce6544de0e1bcef3cf00b1214e085b562bbab1889bd25bcf8849fe8c1da7fdec72a5148e91dd117e0dab7a05c9d2394e7e66cb7b21096dc8690dd0d8208c336604aad72859e0cbcf82058befcb3ceb8cea7fb7067115232dd11ab59a47ed538aeb46933c6defd1f2f9ab6c19b5e9d6bdfd184d7913f2e0cc9b588116966b5f5cf0b966c56783dfe114de1a7df4dc96def908aa579b9b56e06e4b0465f7d1332fc5cf9a044bff818ea2b269f25762c367896911a93f2203a913d64e811611b1da45d7d5b62bc68abf2e770261e5ae2c128f915c56a61a166a4cdbb3372911b6c69f9abff178ccc312b22b154981de48b8a5b0650b3a4e175ab9dd3636e67e5c4eff6b93420876ef20a461a47eb645ed08b852f79e40ce93cd2b9203568fbbd6094c34b74724946c4673142c68b9fd1d7daa05f34dd5747a10f1c5010de31d47960e78c9350c52049bb9000dbda4f0a908c8eb29606b74fb3702653514a19cb6147f6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xe8b07b73070000006e5bb4eb34000000be957b730700000097867b730700000059e193bc2473fca31d2a10f8454520bee1957d7e3e9ced87f2e8425c0c08f6bb52cf8c48e946e9da705ac19a462706b411d24b8f373e325a628208d7047d0ffc0fee33b653cd0fd01e2ca1608a9b94c94c67f365657d8a86a53bc8dfaa3988a724504dfe79b6f5afb44ecf53753aad7efff2452183032a5b1219b5c99f384719c1022f632a5e029648ce78f33b5cbe1c606c327b7b29aa4c03cff2be1ae5ccebac8253bf25ade6c873f6509570ce4a30783c746c5875ca346078e184eac19dfc9f416299e9fb4250b04a8e3e2d22a2771eda8639962bc285055754f357667fdd80cd1d2fef1f6a297426c80d198e5821e538e851fc608333ac632937e0753b69b1b1cba2be0ab14696726eac8f6b818ef3d0396e6d563b73d378a48f0ed77cd518b72fef2551971a58c574c4fad812bbd71e0a41ed97c1c74d3f665e4f849945939fc1349559b3feaf32db756fbdb425cb7de72cee400a0a83ae1a3fc1541ee189c4fc42c193ce14c667e64f4eb2fc21440f68cf73e9699e07375a2fd0f8fc8a78c9350c52049bb9000dbda4f0a908c8eb29606b74fb3702653514a19cb6147f6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", + "0xc14ded8209000000d3399f7507000000c35c74730700000052547473070000003fd8a8a3abe91daabbcefb46c12679757b5ef84a1d1a86f88ff4f72108743082c16a90f3122651c46b9fe13ad5fa9039689f8f8310bd87fede796de7ae7e6b8b26e8b864ab910e64fac8d21420305ac13d40ff60b337734cbed410b74d045b4b191c8a834a78383c882c63cd73b5ec3045147d6866b03d668926675421d9dd9430059267161313dd5d8078f97681146f8ad9699662294f8d96838c1a02eb55950ba94ee41400881a940e82b104faa44ea94de3aafc6708bdfdfad612e5f8b3b17db9f9b3303b7fb8910a42ac46832ad3dbc1122ff9b81ce8343aea02b9dd4f08b85f6f22463648903c3e2c93d738ec5c5bbabc7969d350c5fb65538711c7651da9758deaadab0eda5cf7047a9b4cf76f32ba76d0f410e2eb0979f709ef7c3a875c6c2088e2ae731e9e64583785467c21b800cf320d9807a45210ef86d0b70e44efa206455c565617f73c5a3a4cd1b98c93d21d398f2bc25a63c5ea5095c8fd3905383a708f1ae8e6cdfef5a2aabf0fa4bf39ab9c9dd8aca35c9fd45ea283df6841e9556a1a468e0ec9db8f5e65d97cc5cb7b5f972ad5da74bde8088c87cefd5c6db4c812b0451988f4ee7061bc49e1f7fe37e1a2548469e13db07d9f235e9023daeeea7a208232bf77025a6e81e886e674b3aadc3931bc8f0268e2b8350d63608fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a43e251b9aa4f9097ef23129626b849648d24e38fb1f16829559482a9d5da28473cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467657cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe18869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7c6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc52f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362cbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c32755d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a748d18220000000000000000000000000000000000000000000000000000000000", ], }; const pendingDepositProofs = { pendingDepositContainerRoot: - "0x07a707c8f0cf4aca57d27a9bb2ab16fa3cfbc11b78124d8dfd1a4078196c0c8c", + "0x8e9a353f5d80d749c0f322bc97530477e6c5a3ca14b253d0a26264872b45bdcf", pendingDepositContainerProof: - "0x2bc2f2dad0202c8b321b844aa1b3b9d1b0ffcea3f6d7a93ec81a730ac50e63fdb47a0cc94e65bb91b64ff7327832564dbb190bb792e044f485deda924863c4db27b4b67bd5f307a23dde240ef20096635b24d79d7a8057fa660d042f2dfb20eac78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c804faef706ca86dbbc46224317452144603f4b9ef2daf957a720b4a92fd879609533b5252513c39201e005a893f087ca06c204f92ec39a8600d53d27a5e2d8223024fc916ff3494356d4883c169c8adf57c2192bdc3f0b10b9a83a58b6c7e0278800dc66329ce086cf603342490ca86d9cd0c770b68b20210003abcd6688a8fd", - pendingDepositIndexes: [24060, 50280, 24059, 24058, 24057, 16528, 24055], + "0xc5a691c90b1e5a4b98433a0f4bd86eba8048f63b7d3a1b4fb66ba0c7ae8812773db8d01d9495a3bbeb4f3d22d6a373692bbbf60c638fa615738f83ac08f464c9f7507516e2aa2af211bec2d8c99165b7fad41b628ba3483ae4538d0297e9959bc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c6f4581fa3557c0472f9fbe2c878e71bfb3e8b60ea9e1290bce380cb644d55829445fd94dbbc7e4c1e17974c0745d82a97865458517ec4d426b861f9c4e90e9d0b53e114879b41538e556e5d6a209127efcd4b0fe59e0bf64de8357cdc2273d6ec0cdabace9443f7ec6183c3a82e1762c339d8dfbbd1dfca1ba16967b4f2e6e8a", + pendingDepositIndexes: [6791, 33011, 6790, 6789, 6788, 6786], pendingDepositRoots: [ "0xe43aa97c7b45d686240e148893fb944692f4a5513afca99a351c1f20e26c5597", "0xf1947604474b44eec74edd4768599915239e72f4002737713af83febc36398cb", "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225ce", "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5d", "0xac9a98d48b7b13938bbf6c50c07b7d9f41c78c2dc9515280ec3cab9209ac44ba", - "0xbee3eb2fda60ca0a8adce2791490ef0fb414b84d5f9467f094a5abac12a4afd1", "0x5daaa459171d3c16aa9c68ece5f1192d0be4900291029fe9dee738493895ab8e", ], pendingDepositProofs: [ - "0xded0993aa9a75aa36416422175e06bc345602ea084fcc2f27b6436e64d5d0bc8fc9110055ae92751f36ee90fe2a3c25149f00547e90dae303b5d39e4f25080f0f29a9186f99e0866908b531b08bfc3390aa1b1bddb3b6bdf5766b0c9b9432a93d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x97748b89e2948e942d8d6215fd9496942c5df9d149ae9e7160b62a50abb13e3d2028cedcf850cf9779fc1a21b360cb8c8603d34bff12279fc18dc3ae30f43d419fa76e4e5b19d33fa33ffcee83c228cc3473d6aba6b8d695b754fecc3bd6f3d29cfeb7cf94db25f4fe20f33acff305564791c97fccff3a123a5dbe41ab4a015870e84b57f0c628580708e00160e2f3cc44dd7a1110d5544dc0d0c9cc213e89afd317a78a3c3006a235a24da0b8010ab6caf70b151a8c0743859dffd5bae95cb466922dbd696108eaab1e27408c9c4e796430e506b808905494b5e0f32578f59e757e24b682fb94e5efe111eb8aa0adb8d06eacc805232b893b4e7045b7ca04b5d64ae47eaf3037b50a5afc2d5457d6feb0b5167e1530566a9c2431e44fd85083eec1d5ef0619d311773d3fe579304084b2c341e81c2a8bccba3143d48561ad1242f920c73342b2e90cf162d94473ab8ed4c6d28259777108a717e8c5a4312ff593a5ed25b13823e8ee9d53c93c1c8c51388229af97d596f49ab3d7bcd5aa8745b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5fdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e7a45ea59e241bd537ee551e2d4b6b0756004839a42767ae113c3891b7056ad1740e13f32ee31a7c21f350694ce2809b5db0268ab71549c51e09365cbcc3d9ee18fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5d5f1ba92b82d7073122621c73e6af3e70746b94bf6d20b9f94e871095bdcf6122a3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225ce5f1ba92b82d7073122621c73e6af3e70746b94bf6d20b9f94e871095bdcf6122a3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x308dba54c2444e4683aa4c92c423532dae274d39dc0a95a2871b90006b41a3570f3225288e19861b9e39393c62293f55e0638f778e8e0cd34815ba42d3b92feda3f8084875220bfa806319550c0105a913b0fd54eabbc319f4fa6c6b0554f1b1d7ffd3896a6505d3a1232eba1b826b9a8fa15ddd83b105694629cb37850253f62046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0x9b06f36ea5e8e7ba833832a61c9facb8db666134bba4e1c5ef74f4174a9e43a4c4fe22cc2ba736d7af11e26b9152f1ef7d9757c588f46915acd8adead189aa47096ad82b8ec78f320b53c63a312e4517efbb205b1a5bc71f21776d1a28244f260f4e47c398bbdbe17a7cc96cbc7ba548039d5c9ec057b43aab992c4e5b950839e3baf30942d62204400a59e3413a530f0b2f63ebdfa260abf833512ca010a5212eee1b5aeb8630d46197c5e32908e495f84534ef9d9a852b83fc413776e201e77ed77d0ba56ce929b8d3db53d1724c0c5ba3c60640eda489b7fb824ce4ed3ea9bec20551dc2d9e16255bfbeb3d4d00badcd7eb8d9fd35aedef99feb52d69a75163472173d644d1c69f6054a005a607398b8b2ecefb0e6ddf642cbd02b171f26ed9cb26f04e0c811550f70dc948973c22e2fde8c6712a1da72a399ac4bee0d3e754ce0b3653d53a959bd57edd3baf9d901546910de11d5a7f53cdb091d30552cfed573ca637fba29361cee8faac4883878350624d13a380b7da3bf9f831f12ea7e0228b961983fa30bd6586f0ece3a66a83fc789a2c803d765ca0d29955f0f8d8a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", - "0xc182d7661fdeb3ee903f8dd7ecc70f23872de8fffdddd73370c7b83d722525f1ce74353fece6c946005bc85e4771ae46ba00c6552dec62e813548c3dc1316ba8ad0d6dd24f6ea2f15e7ce6b2df96cde6b66742a01f68a2af50a179077cefb2fe55cb4cecc74f7add89ba98e95068300bdab5134daa8d73cfde3f5dbce945fcb22046fcdb00826ba3af9bb7cf8574cbbdcf5de0e05e82601a1c0b563ee54524cfe96e89146d016c902f37f7fc8c0ef5f9c3cfe603544a4a894d4225ac487d9b82e5456c92114c9a147b2b7147212a7d72420eaaee78e01076100c1b098047c39ae03f2031b583b14a37c8605742dc40398b747ff49959156a53cefc81e26bb78896e1ad9765cfde6a401db69201219331363920a9b1a25e74c6732c59c295547582c74d36fc3ae2790fa792f521df1a0984de4b4817f35d0453bdb1b24614ddd1e08cc7bb3993e4d6081405ba4756e32fe5da24d089599e4afe40097bb120989181f922ee5e6deb87920de0a545bd71f600e9663d9140428057672c5e0f01f9c09bdecf022a597387fba04c9c603c7c8eeca2d479e6841c2b7bcb2f9384cf9672a7df347263a18cbb550e7cac025e02a7be713e279bd0b827a1286684edad0a468a113372aad2fed7897bd236dc0cc5aef8eb7c88b5063ba375bfc6e2e38a0411b3ade837b8b6c21e87e1485fa4a73a72b634e6d193ef33849da18c89cd29b0688fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a4676530ca000000000000000000000000000000000000000000000000000000000000", + "0xb052e26ca38ea7d23a9d8e2b4e0930caec9762902558a0c69a6165d2b34225cead345f10252274408791763ea728c60cfd0c0e4b830a4478358e903ea5fb8e9d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xf7249eead0f1aea2b1fbd85cc602f80baf13e0a02cf9d3089e718e6658ce1693f792d6b43e88db568ea6dfcb3610f61591ee6b5c6eaeb6ccfef90f21d4b59639d55dd5372c0ccbe43f33259d9de97bfbb1e50625553b883a20f883ac588df75c54591b16d0df56bd9b2fef101017199b4beb0fdd39204fdee898baf569b591734284ea78eab42ac0bc127e4a33c0f1b6b1d7ce7f1c22c077571b4b4ab17cd6d15ec0911248ab6ac0fb6e40784dee43a812f1b2e6825e663b3c3bb9c8e919f1276b2bd5a3617467e8bc2a537855f2f6ace03a9fc68c3bde3fd4ea00e6428a4114a8749e8f840f1e524602b6b9ef58a896ac8ccba0e55bb89c72eae1130fcf463433b6e9dcdd3563b9304399dbabe9f1cb6c5681c72c703678e5bcb6a343607a9844c92daa1fe18120b85cdebb842c8761b2318bd50bad75742cd23e24674e55657075a0f80fc134385cae7ca7a8d0bf310debf5e875dd4c2ed98f5082e013576152827b331483b5af2d583798206b7673defe032939eaa66fba62754814cddc226b0d00c895f66aea0409aa599d3f4e99192e2bacb7a99bf00646e55d758f18bd72f2d4e1e15bc9b4649c63daf8060b6b26098a0f3837e145b78e5418c4fe23c9b58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da729378453c470d6bb6d6d92cb4b1f45bdf68e17b3b2d513ccad61d8e91baeec8cbf2c568fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xe43aa97c7b45d686240e148893fb944692f4a5513afca99a351c1f20e26c5597ad345f10252274408791763ea728c60cfd0c0e4b830a4478358e903ea5fb8e9d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0xac9a98d48b7b13938bbf6c50c07b7d9f41c78c2dc9515280ec3cab9209ac44bad1382044558891e141307d62d35f69c7e8ef2566e8a758ac46807c46fab10b6d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0x5884a4ac9f90f068ebec13e3be02253bc0f44b196572038dd09e77edf8ec0d5dd1382044558891e141307d62d35f69c7e8ef2566e8a758ac46807c46fab10b6d16631debd57ef20f7e5d80e7309e1c5cbe09fba84a45739d0c2f7a5385b99de044e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", + "0x308dba54c2444e4683aa4c92c423532dae274d39dc0a95a2871b90006b41a357f48cf215d71cd05cb4214ebac67ba013270cc2c9b3e9cd3764671f1461135947ff01249f12eebda99afdc7882e5a0b55955740fe202576daabaf7fd026a0d73e44e3aedd9b6413b72e62e221a47feac65b8b61639e4d8c3f9595cb28f5a2ed0928f91fd42bd629d13ea3d088dc7684890efb7bd6982995cb06b993262d317fe481cb939e8682f2529ac5b34889c745c9c3d451c6acae5603acd9e750b81054e588a198201c81b745cd183dc6b095f0281c04ec988c9d9e5a372e145eb5f03a4936392d008637fb405334e3793bcd032cec028bbfcf3de88b34bd4c893d350dc8fa58dccb16086ce949d26e8061c375a96ab0aa4dbc7d0ba7340a2732faab6dd749aee54ff9f9e931158eaca9fd12e915a1f7c205b499d7cf98fb2c9b70b55cfdff2cf7a711c6d0a64a4c0819b47e1e8c98534a134bf0a46773151d8ca393f25cfcb86c8f337e89e710accfcacd13518797b5f871b33f5f8a522d1070b5dd3851fb301c44c748be1402321a538f1f3d0ec0ed99161b33c8d7ab778e58ea4013f2ed12cb9bcd9bbcb04e046d6ae4c230f7a759e0c88be26bb8f34c33e0fa1d121dab1875e7cf07f93e85275fc8eb4755076cd072cb30830890c57ccc0ac57fec3d1bb0ac320fc57a100f5f395873579aed371896e8be97a52c5f03809c5f2aceb08fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17fcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9cfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d731206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc021352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a467659aa5000000000000000000000000000000000000000000000000000000000000", ], }; const minWithdrableTime = 261 * 32 * 12; // 261 epochs From cb5299d8168c21926509fefe8e2fb8176fd0411d Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 20 Mar 2026 14:23:31 +1100 Subject: [PATCH 11/15] Deploy script to migrate the SSV clusters to ETH payment --- .../183_migrate_ssv_clusters_to_eth.js | 61 +++++++++++++++++++ contracts/tasks/governance.js | 13 +++- contracts/utils/deploy.js | 42 ++++++++++--- contracts/utils/governor.js | 2 +- 4 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js diff --git a/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js b/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js new file mode 100644 index 0000000000..84ae77513f --- /dev/null +++ b/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js @@ -0,0 +1,61 @@ +const { deploymentWithGovernanceProposal } = require("../../utils/deploy"); +const { getClusterInfo, splitOperatorIds } = require("../../utils/ssv"); + +const strategyConfigs = [ + { + proxyName: "NativeStakingSSVStrategy2Proxy", + contractName: "NativeStakingSSVStrategy", + operatorids: "752,753,754,755", + }, + { + proxyName: "NativeStakingSSVStrategy3Proxy", + contractName: "NativeStakingSSVStrategy", + operatorids: "338,339,340,341", + }, + { + proxyName: "CompoundingStakingSSVStrategyProxy", + contractName: "CompoundingStakingSSVStrategy", + operatorids: "2070,2071,2072,2073", + }, +]; + +module.exports = deploymentWithGovernanceProposal( + { + deployName: "183_migrate_ssv_clusters_to_eth", + forceDeploy: false, + // forceSkip: true, + reduceQueueTime: true, + deployerIsProposer: false, + proposalId: "", + }, + async ({ ethers }) => { + const ethValue = ethers.utils.parseEther("1"); + const actions = []; + + for (const strategyConfig of strategyConfigs) { + const proxy = await ethers.getContract(strategyConfig.proxyName); + const strategy = await ethers.getContractAt( + strategyConfig.contractName, + proxy.address + ); + const operatorIds = splitOperatorIds(strategyConfig.operatorids); + const { cluster } = await getClusterInfo({ + operatorids: operatorIds.join(","), + ownerAddress: strategy.address, + }); + + actions.push({ + contract: strategy, + signature: + "migrateClusterToETH(uint64[],(uint32,uint64,uint64,bool,uint256))", + args: [operatorIds, cluster], + value: ethValue, + }); + } + + return { + name: "Migrate SSV clusters to ETH billing for OETH staking strategies", + actions, + }; + } +); diff --git a/contracts/tasks/governance.js b/contracts/tasks/governance.js index 268811fed8..27ee3905e0 100644 --- a/contracts/tasks/governance.js +++ b/contracts/tasks/governance.js @@ -2,7 +2,11 @@ const { sleep } = require("../utils/time.js"); async function execute(taskArguments, hre) { const { isMainnet, isFork } = require("../test/helpers"); - const { withConfirmation, impersonateGuardian } = require("../utils/deploy"); + const { + withConfirmation, + impersonateGuardian, + getProposalExecutionValue, + } = require("../utils/deploy"); if (isMainnet) { throw new Error("The execute task can not be used on mainnet"); @@ -54,7 +58,12 @@ async function execute(taskArguments, hre) { if (isFork) { // On the fork, impersonate the guardian and execute the proposal. await impersonateGuardian(); - await withConfirmation(governor.connect(sGuardian).execute(propId)); + const executionValue = await getProposalExecutionValue(governor, propId); + await withConfirmation( + governor.connect(sGuardian).execute(propId, { + ...(executionValue.gt(0) ? { value: executionValue } : {}), + }) + ); } else { // Localhost network. Execute as the governor account. await governor.connect(sGovernor).execute(propId); diff --git a/contracts/utils/deploy.js b/contracts/utils/deploy.js index acab4fdea4..6ccd7f1d5e 100644 --- a/contracts/utils/deploy.js +++ b/contracts/utils/deploy.js @@ -595,7 +595,10 @@ const executeGovernanceProposalOnFork = async ({ // Don't ask me why but this seems to force hardhat to // update state and cause the random failures to stop await getProposalState(proposalIdBn); - await governorSix.getActions(proposalIdBn); + const executionValue = await getProposalExecutionValue( + governorSix, + proposalIdBn + ); executionRetries = executionRetries - 1; try { @@ -604,6 +607,7 @@ const executeGovernanceProposalOnFork = async ({ "execute(uint256)" ](proposalIdBn, { gasLimit: executeGasLimit || undefined, + ...(executionValue.gt(0) ? { value: executionValue } : {}), }); } catch (e) { console.error(e); @@ -963,30 +967,47 @@ async function buildGnosisSafeJson( safeAddress, targets, contractMethods, - contractInputsValues + contractInputsValues, + values = [] ) { return buildSafeTransactionBuilderJson({ safeAddress: safeAddress || addresses.mainnet.Guardian, name: "Transaction Batch", transactions: targets.map((target, i) => ({ to: target, - value: "0", + value: BigNumber.from(values[i] ?? 0).toString(), contractMethod: contractMethods[i], contractInputsValues: contractInputsValues[i], })), }); } +async function getProposalExecutionValue(governor, proposalId) { + const actions = await governor.getActions(proposalId); + const rawValues = + actions[1] || (typeof actions.values === "function" ? [] : actions.values); + const values = Array.from(rawValues || []); + + return values.reduce( + (sum, value) => sum.add(BigNumber.from(value)), + BigNumber.from(0) + ); +} + async function simulateWithTimelockImpersonation(proposal) { log("Simulating the proposal directly on the timelock..."); const { timelockAddr } = await getNamedAccounts(); const timelock = await impersonateAndFund(timelockAddr); for (const action of proposal.actions) { - const { contract, signature, args } = action; + const { contract, signature, args, value } = action; + const txOpts = { + ...(await getTxOpts()), + ...(value ? { value } : {}), + }; log(`Sending governance action ${signature} to ${contract.address}`); - await contract.connect(timelock)[signature](...args, await getTxOpts()); + await contract.connect(timelock)[signature](...args, txOpts); console.log(`... ${signature} completed`); } @@ -1221,18 +1242,22 @@ function deploymentWithGuardianGovernor(opts, fn) { const guardianActions = []; for (const action of proposal.actions) { - const { contract, signature, args } = action; + const { contract, signature, args, value } = action; + const txOpts = { + ...(await getTxOpts()), + ...(value ? { value } : {}), + }; log(`Sending governance action ${signature} to ${contract.address}`); const result = await withConfirmation( - contract.connect(sGuardian)[signature](...args, await getTxOpts()) + contract.connect(sGuardian)[signature](...args, txOpts) ); guardianActions.push({ sig: signature, args: args, to: contract.address, data: result.data, - value: result.value.toString(), + value: BigNumber.from(value ?? result.value ?? 0).toString(), }); console.log(`... ${signature} completed`); @@ -1438,6 +1463,7 @@ module.exports = { constructContractMethod, buildGnosisSafeJson, + getProposalExecutionValue, encodeSaltForCreateX, createPoolBoosterSonic, diff --git a/contracts/utils/governor.js b/contracts/utils/governor.js index 5d82832ffe..1fd6cb3682 100644 --- a/contracts/utils/governor.js +++ b/contracts/utils/governor.js @@ -47,7 +47,7 @@ async function proposeGovernanceArgs(governorArgsArray) { return [ targets, - Array(governorArgsArray.length).fill(BigNumber.from(0)), + governorArgsArray.map((action) => BigNumber.from(action.value ?? 0)), sigs, calldata, ]; From da64b82a04092b9944826a32fe49e16488981314 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 20 Mar 2026 16:23:18 +1100 Subject: [PATCH 12/15] Fix 183 deploy which was defaulting to Hoodi --- contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js b/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js index 84ae77513f..37e70164c5 100644 --- a/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js +++ b/contracts/deploy/mainnet/183_migrate_ssv_clusters_to_eth.js @@ -30,6 +30,7 @@ module.exports = deploymentWithGovernanceProposal( }, async ({ ethers }) => { const ethValue = ethers.utils.parseEther("1"); + const { chainId } = await ethers.provider.getNetwork(); const actions = []; for (const strategyConfig of strategyConfigs) { @@ -40,6 +41,7 @@ module.exports = deploymentWithGovernanceProposal( ); const operatorIds = splitOperatorIds(strategyConfig.operatorids); const { cluster } = await getClusterInfo({ + chainId, operatorids: operatorIds.join(","), ownerAddress: strategy.address, }); From 967e15150dbd8ff2d65bef06f7223c664b3132ea Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 20 Mar 2026 16:44:38 +1100 Subject: [PATCH 13/15] Updated Claude file --- CLAUDE.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 200d3a7f54..bd5815ab47 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,9 +93,11 @@ Vaults (`contracts/vault/`) are the core of each OToken. They handle: - Rebalancing via `allocate()` - Yield accounting via `rebase()` -Each chain/token has its own vault: `OUSDVault`, `OETHVault`, `OETHBVault` (Base), `OETHSVault` (Sonic), `OETPVault` (Plume). +Each chain/token has its own vault: `OUSDVault`, `OETHVault`, `OETHBVault` (Base), `OETHSVault` (Sonic) and `OETPVault` (Plume). `OETPVault` is being shut down and will be removed from the repo after all funds are withdrawn. Vault logic is split across two implementation contracts: `VaultCore` (user-facing mint/redeem) and `VaultAdmin` (governance functions). +`VaultCore` inherits from `VaultAdmin` and is now deployed as a single implementation contract for simplicity. +Previously they were deployed as separate implementations with a shared proxy. This was because the contract was too big to deploy as a single implementation, but after the simplification, it can now be deployed as one. ### Strategies (Yield Generation) Located in `contracts/strategies/`. Each strategy: @@ -124,9 +126,9 @@ Key strategies: Aave, Compound, Convex/Curve, Balancer, Morpho, Native Staking ( Bundle with: `pnpm rollup -c ./scripts/defender-actions/rollup.config.cjs` ### Cross-Chain -- LayerZero OApp for messaging - CCTP (Circle) for USDC bridging - Network-specific bridge contracts in `contracts/bridges/` +- LayerZero OApp was planned to be used for Plume but is no longer going to be used. ### Pool Boosters `contracts/poolBooster/` - Merkl distribution contracts for incentivizing liquidity pools. `PoolBoostCentralRegistry` tracks all boosters. From cde960ffe540a9edf70a8bfac096d46d8a8c272e Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Mon, 23 Mar 2026 15:23:59 +1100 Subject: [PATCH 14/15] Upgrade Lodestar dependencies --- contracts/package.json | 12 +- contracts/pnpm-lock.yaml | 249 +++++++++++++++++++++++++++------------ 2 files changed, 180 insertions(+), 81 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 12218c1866..b57127a4f6 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -135,12 +135,12 @@ "@layerzerolabs/lz-evm-protocol-v2": "^3.0.87", "@layerzerolabs/lz-v2-utilities": "^3.0.88", "@layerzerolabs/oapp-evm": "^0.3.2", - "@lodestar/api": "^1.39.1", - "@lodestar/config": "^1.39.1", - "@lodestar/params": "^1.39.1", - "@lodestar/state-transition": "^1.39.1", - "@lodestar/types": "^1.39.1", - "@lodestar/utils": "^1.39.1" + "@lodestar/api": "^1.41.0", + "@lodestar/config": "^1.41.0", + "@lodestar/params": "^1.41.0", + "@lodestar/state-transition": "^1.41.0", + "@lodestar/types": "^1.41.0", + "@lodestar/utils": "^1.41.0" }, "resolutions": { "@openzeppelin/contracts": "4.4.2" diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 595331675f..6cd43c34ac 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -33,23 +33,23 @@ importers: specifier: ^0.3.2 version: 0.3.3(8279ee0c0af7c87772d82cabf31ab483) '@lodestar/api': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@lodestar/config': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@lodestar/params': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@lodestar/state-transition': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@lodestar/types': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@lodestar/utils': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 devDependencies: '@aws-sdk/client-kms': specifier: 3.598.0 @@ -1172,23 +1172,31 @@ packages: '@openzeppelin/contracts': 4.4.2 '@openzeppelin/contracts-upgradeable': ^4.8.1 || ^5.0.0 - '@lodestar/api@1.39.1': - resolution: {integrity: sha512-pg+URGip3am/qPO1ZzpWA1a7Ik8qyplh+2D2I55DcCawJeUWLz5/TZrPYaqgT7EJl82Llg2OleQL6kIiqfcAjQ==} + '@lodestar/api@1.41.0': + resolution: {integrity: sha512-W4xO2zcws+ZxI57Z/0tg10nxdWLVART5tTNhmCSjs11dpb4HBbo/D1dw/SavTzI5ME7Y5NwQ5kJpd8gdc0B8ag==} - '@lodestar/config@1.39.1': - resolution: {integrity: sha512-4WNOTuDewswshF+ohY3k6tdj5AIqmXtiL9epA4Ph25K4/rtDj8aFmJPguL99zppv7ipc6YuLqOSHBB7OwPzkwQ==} + '@lodestar/config@1.41.0': + resolution: {integrity: sha512-ftz4acxaN69Td6rG0qPwJOtz8mXs3q4Tg8grtnoCjNLKOnOVzHqyJtAVbslinEindN9mK+dQ3KLBHFhZMrIbbA==} - '@lodestar/params@1.39.1': - resolution: {integrity: sha512-G1kdPfpuG5JSMQLiHBbcJTZTCsKn8oXA+fCU7sLhHofQ/FBs62qLXI+c9elfu3gjFEEiIhv575BM1hEUb4FBuw==} + '@lodestar/params@1.41.0': + resolution: {integrity: sha512-jUau8Ui1K7P/FJu88ZVV0E0/sbeYDRXQj0kIDboaCF2BRCATmcFxfBEiACH/9e4ITVCwjDdiJG3vqUdIyEK27Q==} - '@lodestar/state-transition@1.39.1': - resolution: {integrity: sha512-pgG81JplIaZP+pvDWgTDWQp8AGiJZizx4aigfmMnIstnkU4VONMeOnkkgpicm0ffrBLim5iR/BFH6pMBdK2NUA==} + '@lodestar/spec-test-util@1.41.0': + resolution: {integrity: sha512-QyRHNQGQdl3kL9+6OklfG1/Dk3XCzf6F7CAAqdYdGiBKkv3St/J9Y0zJPYtynuPigNtqviXgC16zG9RXe1gJiw==} + hasBin: true + peerDependencies: + '@chainsafe/ssz': ^1.2.2 + '@lodestar/types': ^1.41.0 + vitest: 'catalog:' + + '@lodestar/state-transition@1.41.0': + resolution: {integrity: sha512-QDfZE++H5EFZ8Tw/6k7ZEVGSFRb+s7yITZlu636TGtqhTkXOamNcokBF3BickdonX58t2FMEuCLcyCf4IYX13g==} - '@lodestar/types@1.39.1': - resolution: {integrity: sha512-eaQLf8F9iTKqyzHfhaDSlAvUofN8LcpOOOBXYHdOQNnQk8vRCnmF2RYCBhq0AnqhY+Fvea/yVqO+M6qh5uBK0A==} + '@lodestar/types@1.41.0': + resolution: {integrity: sha512-iJzaE9EAS3sbBl3DGwIxjKeEks30+DdSBpx26kkqa3tc6ejC3Y73d8F31G9qqkCN40If6TJlv2yC8xbphhoB5Q==} - '@lodestar/utils@1.39.1': - resolution: {integrity: sha512-PHEt50aODY4ZLV20vw12Z9nh130Q+4SCcAIiY4GZP5ktMLJ12gkgAj/P8VfATHsJRjjASDIS4/nhynjLK53tHw==} + '@lodestar/utils@1.41.0': + resolution: {integrity: sha512-D/KtN7qlQZe3sNDdSaCyD0bmwEHBmW9PYhROSsM2/JjIABOERH+1zJqj76a22igp3WcvrMCAkEs71mF9oLzWOQ==} '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} @@ -2205,6 +2213,15 @@ packages: resolution: {integrity: sha512-80c+wtVzl5JJT8UQskxVYYG3oZb4pkhY0zDe0ab/RX4+8f9+W5d8wI4BT0wLB0wFQTSnbW+QdBSpkHA/vRyGBA==} engines: {node: '>=10'} + '@vekexasia/bigint-buffer2@1.1.1': + resolution: {integrity: sha512-uL63NGANn85oKrsrvD0CzgmkuMlWQnGv/J7sz0QQ2CnRaF1nMF0fAoRFH9PFtGRr62ZCA14qkHZATyBZbKYlRQ==} + engines: {node: '>= 14.0.0'} + peerDependencies: + '@vekexasia/bigint-uint8array': '*' + peerDependenciesMeta: + '@vekexasia/bigint-uint8array': + optional: true + abbrev@1.0.9: resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} @@ -2278,6 +2295,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + amazon-cognito-identity-js@6.3.16: resolution: {integrity: sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==} @@ -2475,10 +2495,6 @@ packages: bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} - bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -2486,9 +2502,6 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bip39@3.0.4: resolution: {integrity: sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==} @@ -2513,6 +2526,9 @@ packages: bn.js@5.2.2: resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + bn.js@5.2.3: + resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + body-parser@1.20.4: resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -3464,9 +3480,6 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -3688,6 +3701,11 @@ packages: engines: {node: '>=12'} deprecated: Glob versions prior to v9 are no longer supported + glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} engines: {node: '>=6'} @@ -4437,6 +4455,9 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@5.0.1: resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} engines: {node: '>=10'} @@ -4445,6 +4466,10 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@8.0.7: + resolution: {integrity: sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==} + engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -4455,6 +4480,10 @@ packages: minipass@2.9.0: resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -4926,6 +4955,14 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + qs@6.5.3: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} @@ -5077,6 +5114,11 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} + engines: {node: '>=14'} + hasBin: true + ripemd160@2.0.3: resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} engines: {node: '>= 0.8'} @@ -5267,6 +5309,9 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} + snappyjs@0.7.0: + resolution: {integrity: sha512-u5iEEXkMe2EInQio6Wv9LWHOQYRDbD2O9hzS27GpT/lwfIQhTCnHCTqedqHIHe9ZcvQo+9au6vngQayipz1NYw==} + solc@0.4.26: resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} hasBin: true @@ -5338,8 +5383,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -8286,28 +8331,45 @@ snapshots: '@openzeppelin/contracts': 4.4.2 '@openzeppelin/contracts-upgradeable': 4.7.3 - '@lodestar/api@1.39.1': + '@lodestar/api@1.41.0': dependencies: '@chainsafe/persistent-merkle-tree': 1.2.1 '@chainsafe/ssz': 1.3.0 - '@lodestar/config': 1.39.1 - '@lodestar/params': 1.39.1 - '@lodestar/types': 1.39.1 - '@lodestar/utils': 1.39.1 + '@lodestar/config': 1.41.0 + '@lodestar/params': 1.41.0 + '@lodestar/types': 1.41.0 + '@lodestar/utils': 1.41.0 eventsource: 2.0.2 - qs: 6.14.0 + qs: 6.15.0 + transitivePeerDependencies: + - '@vekexasia/bigint-uint8array' + - vitest - '@lodestar/config@1.39.1': + '@lodestar/config@1.41.0': dependencies: '@chainsafe/as-sha256': 1.2.0 '@chainsafe/ssz': 1.3.0 - '@lodestar/params': 1.39.1 - '@lodestar/types': 1.39.1 - '@lodestar/utils': 1.39.1 + '@lodestar/params': 1.41.0 + '@lodestar/spec-test-util': 1.41.0(@chainsafe/ssz@1.3.0)(@lodestar/types@1.41.0) + '@lodestar/types': 1.41.0 + '@lodestar/utils': 1.41.0 + transitivePeerDependencies: + - '@vekexasia/bigint-uint8array' + - vitest - '@lodestar/params@1.39.1': {} + '@lodestar/params@1.41.0': {} - '@lodestar/state-transition@1.39.1': + '@lodestar/spec-test-util@1.41.0(@chainsafe/ssz@1.3.0)(@lodestar/types@1.41.0)': + dependencies: + '@chainsafe/ssz': 1.3.0 + '@lodestar/types': 1.41.0 + '@lodestar/utils': 1.41.0 + rimraf: 4.4.1 + snappyjs: 0.7.0 + transitivePeerDependencies: + - '@vekexasia/bigint-uint8array' + + '@lodestar/state-transition@1.41.0': dependencies: '@chainsafe/as-sha256': 1.2.0 '@chainsafe/blst': 2.2.0 @@ -8316,25 +8378,30 @@ snapshots: '@chainsafe/pubkey-index-map': 3.0.0 '@chainsafe/ssz': 1.3.0 '@chainsafe/swap-or-not-shuffle': 1.2.1 - '@lodestar/config': 1.39.1 - '@lodestar/params': 1.39.1 - '@lodestar/types': 1.39.1 - '@lodestar/utils': 1.39.1 - bigint-buffer: 1.1.5 + '@lodestar/config': 1.41.0 + '@lodestar/params': 1.41.0 + '@lodestar/types': 1.41.0 + '@lodestar/utils': 1.41.0 + '@vekexasia/bigint-buffer2': 1.1.1 + transitivePeerDependencies: + - '@vekexasia/bigint-uint8array' + - vitest - '@lodestar/types@1.39.1': + '@lodestar/types@1.41.0': dependencies: '@chainsafe/ssz': 1.3.0 - '@lodestar/params': 1.39.1 + '@lodestar/params': 1.41.0 ethereum-cryptography: 2.2.1 - '@lodestar/utils@1.39.1': + '@lodestar/utils@1.41.0': dependencies: '@chainsafe/as-sha256': 1.2.0 + '@vekexasia/bigint-buffer2': 1.1.1 any-signal: 4.2.0 - bigint-buffer: 1.1.5 case: 1.6.3 js-yaml: 4.1.1 + transitivePeerDependencies: + - '@vekexasia/bigint-uint8array' '@noble/ciphers@1.3.0': {} @@ -9764,6 +9831,8 @@ snapshots: '@uniswap/v3-core': 1.0.0 base64-sol: 1.0.1 + '@vekexasia/bigint-buffer2@1.1.1': {} + abbrev@1.0.9: {} abitype@1.2.3(typescript@4.9.5)(zod@3.25.76): @@ -9839,6 +9908,13 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + amazon-cognito-identity-js@6.3.16: dependencies: '@aws-crypto/sha256-js': 1.2.2 @@ -10015,18 +10091,10 @@ snapshots: bech32@1.1.4: {} - bigint-buffer@1.1.5: - dependencies: - bindings: 1.5.0 - bignumber.js@9.3.1: {} binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bip39@3.0.4: dependencies: '@types/node': 11.11.6 @@ -10048,6 +10116,8 @@ snapshots: bn.js@5.2.2: {} + bn.js@5.2.3: {} + body-parser@1.20.4: dependencies: bytes: 3.1.2 @@ -10058,7 +10128,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.14.0 + qs: 6.14.2 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -11199,7 +11269,7 @@ snapshots: parseurl: 1.3.3 path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.14.0 + qs: 6.14.2 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.19.2 @@ -11280,8 +11350,6 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-uri-to-path@1.0.0: {} - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -11547,6 +11615,13 @@ snapshots: minimatch: 5.1.6 once: 1.4.0 + glob@9.3.5: + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.7 + minipass: 4.2.8 + path-scurry: 1.11.1 + global-modules@2.0.0: dependencies: global-prefix: 3.0.0 @@ -12390,6 +12465,10 @@ snapshots: dependencies: brace-expansion: 1.1.12 + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + minimatch@5.0.1: dependencies: brace-expansion: 2.0.2 @@ -12398,6 +12477,10 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimatch@8.0.7: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 @@ -12409,6 +12492,8 @@ snapshots: safe-buffer: 5.2.1 yallist: 3.1.1 + minipass@4.2.8: {} + minipass@7.1.2: {} minizlib@1.3.3: @@ -12866,6 +12951,14 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + qs@6.5.3: {} query-string@5.1.1: @@ -13023,6 +13116,10 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@4.4.1: + dependencies: + glob: 9.3.5 + ripemd160@2.0.3: dependencies: hash-base: 3.1.2 @@ -13275,6 +13372,8 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 + snappyjs@0.7.0: {} + solc@0.4.26: dependencies: fs-extra: 0.30.0 @@ -13414,16 +13513,16 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.23 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.23 - spdx-license-ids@3.0.22: {} + spdx-license-ids@3.0.23: {} sprintf-js@1.0.3: {} @@ -13634,7 +13733,7 @@ snapshots: table@6.8.2: dependencies: - ajv: 8.17.1 + ajv: 8.18.0 lodash.truncate: 4.4.2 slice-ansi: 4.0.0 string-width: 4.2.3 @@ -13730,7 +13829,7 @@ snapshots: diff: 4.0.2 glob: 7.2.3 js-yaml: 3.14.2 - minimatch: 3.1.2 + minimatch: 3.1.5 mkdirp: 0.5.6 resolve: 1.22.11 semver: 5.7.2 @@ -14117,7 +14216,7 @@ snapshots: web3-eth-iban@1.10.4: dependencies: - bn.js: 5.2.2 + bn.js: 5.2.3 web3-utils: 1.10.4 web3-eth-iban@1.7.3: From fa61e48fe951c17a14544db69b2d4414c4574670 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Wed, 25 Mar 2026 09:48:03 +1100 Subject: [PATCH 15/15] Changed back to using GET for bulk validators --- contracts/utils/beacon.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/utils/beacon.js b/contracts/utils/beacon.js index 05366a790b..8c4578b09c 100644 --- a/contracts/utils/beacon.js +++ b/contracts/utils/beacon.js @@ -223,28 +223,28 @@ const getValidatorsIndividually = async (client, validatorIds) => { return validators; }; -const getValidatorsByPost = async (client, validatorIds, attempts = 2) => { +const getValidatorsByGet = async (client, validatorIds, attempts = 2) => { let lastError; for (let attempt = 1; attempt <= attempts; attempt++) { try { - const postValidatorsRes = await client.beacon.postStateValidators({ + const getValidatorsRes = await client.beacon.getStateValidators({ stateId: "head", validatorIds, }); - if (postValidatorsRes.ok) { - return postValidatorsRes.value(); + if (getValidatorsRes.ok) { + return getValidatorsRes.value(); } lastError = new Error( - `Bulk validator POST failed with status ${postValidatorsRes.status} ${postValidatorsRes.statusText}` + `Bulk validator GET failed with status ${getValidatorsRes.status} ${getValidatorsRes.statusText}` ); log(`${lastError.message}. Attempt ${attempt} of ${attempts}.`); } catch (err) { lastError = err; log( - `Bulk validator POST threw ${err.name || "Error"}: ${ + `Bulk validator GET threw ${err.name || "Error"}: ${ err.message }. Attempt ${attempt} of ${attempts}.` ); @@ -252,7 +252,7 @@ const getValidatorsByPost = async (client, validatorIds, attempts = 2) => { } if (lastError) { - log(`Bulk validator POST failed after ${attempts} attempts.`); + log(`Bulk validator GET failed after ${attempts} attempts.`); } return null; @@ -263,7 +263,7 @@ const getValidators = async (pubkeys) => { const validatorIds = Array.isArray(pubkeys) ? pubkeys : pubkeys.split(","); log(`Fetching ${validatorIds.length} validator details from the beacon node`); - let validators = await getValidatorsByPost(client, validatorIds); + let validators = await getValidatorsByGet(client, validatorIds); if (!validators) { validators = await getValidatorsIndividually(client, validatorIds);