diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..d5ff52b7 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +HOLESKY_PRIVATE_KEY= +HOLESKY_RPC_URL= diff --git a/.env.holesky b/.env.holesky deleted file mode 100644 index 8ca8992a..00000000 --- a/.env.holesky +++ /dev/null @@ -1,6 +0,0 @@ -PRIVATE_KEY= -RPC_URL=https://rpc-holesky.rockx.com -CONTRACT_ADDRESS= -DELEGATION_MANAGER_ADDRESS= -STAKE_REGISTRY_ADDRESS= -AVS_DIRECTORY_ADDRESS= \ No newline at end of file diff --git a/.env.local b/.env.local deleted file mode 100644 index 45319f9d..00000000 --- a/.env.local +++ /dev/null @@ -1,16 +0,0 @@ -PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -RPC_URL=http://127.0.0.1:8545 -CONTRACT_ADDRESS=0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB -DELEGATION_MANAGER_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -STAKE_REGISTRY_ADDRESS=0x9E545E3C0baAB3E08CdfD552C960A1050f373042 -AVS_DIRECTORY_ADDRESS=0x5FC8d32690cc91D4c39d9d3abcBD16989F875707 - - - -HOLESKY_PRIVATE_KEY=0x70cf3589410a4471117581a3ed6aed567d180ad96b51d97bf2744a9c74fe55d0 -HOLESKY_RPC_URL=https://ethereum-holesky-rpc.publicnode.com -HOLESKY_CONTRACT_ADDRESS=0x3361953F4a9628672dCBcDb29e91735fb1985390 -HOLESKY_DELEGATION_MANAGER_ADDRESS=0xA44151489861Fe9e3055d95adC98FbD462B948e7 -HOLESKY_STAKE_REGISTRY_ADDRESS=0x41F6a9eCC12c3Df46608270aAf6C458525269507 -HOLESKY_AVS_DIRECTORY_ADDRESS=0x055733000064333CaDDbC92763c58BF0192fFeBf -HOLESKY_WS_RPC_URL=wss://holesky.drpc.org \ No newline at end of file diff --git a/.gitignore b/.gitignore index cee81baf..8333d032 100644 --- a/.gitignore +++ b/.gitignore @@ -12,9 +12,9 @@ dist/ .idea/ # Ignore TypeScript build artifacts -*.js -*.js.map -*.d.ts +dist/**/*.js +dist/*.js.map +dist/*.d.ts # Ignore local anvil state # utils/anvil/*.json diff --git a/.gitmodules b/.gitmodules index b333b78e..140c014d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ -[submodule "contracts/lib/openzeppelin-contracts"] - path = contracts/lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts -[submodule "contracts/lib/eigenlayer-middleware"] - path = contracts/lib/eigenlayer-middleware - url = https://github.com/layr-Labs/eigenlayer-middleware [submodule "contracts/lib/forge-std"] path = contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "contracts/lib/eigenlayer-middleware"] + path = contracts/lib/eigenlayer-middleware + url = https://github.com/Layr-Labs/eigenlayer-middleware diff --git a/AddNewStrategy.md b/AddNewStrategy.md deleted file mode 100644 index 16ab16fc..00000000 --- a/AddNewStrategy.md +++ /dev/null @@ -1,152 +0,0 @@ -### Guide: Adding a New Strategy to the Hello World AVS - -This guide will help you add a new strategy to the Hello World AVS using Foundry scripts. - -### Prerequisites - -Before starting, ensure you have the following: -- A development environment set up with Foundry. -- Access to the EigenLayer contracts and the Hello World AVS contracts. -- A deployed instance of the Hello World AVS. -- The following addresses: - - Proxy Admin Address - - Pauser Registry Address - - Strategy Base Implementation Address - - Strategy Manager Address - - Delegation Manager Address - - AVS Directory Address - - Hello World Service Manager Proxy Address - - ECDSA Stake Registry Proxy Address - -### Step 1: Setup Your Environment - -Ensure your development environment is set up with Foundry and you have cloned the necessary repositories. Navigate to the directory where your Foundry project is located. - -### Step 2: Prepare the Script - -In your project directory, locate or create the script file (e.g., `AddNewStrategy.s.sol`) where you will write the script to deploy and configure the new strategy. - -### Step 3: Script Outline - -Your script should follow this general outline: - -1. **Imports**: Ensure you have all the necessary imports. -2. **State Variables**: Define state variables for addresses to avoid passing them as arguments multiple times. -3. **Main Function**: Implement the `run` function which will be the entry point. -4. **Helper Functions**: Break down the logic into smaller helper functions to avoid stack too deep issues. - -### Step 4: Define State Variables - -Define the addresses you will use as state variables at the top of your contract to keep your code clean and manageable. - -```solidity -address eigenLayerProxyAdminAddr = /* Proxy Admin Address */; -address eigenLayerPauserRegAddr = /* Pauser Registry Address */; -address baseStrategyImplementationAddr = /* Strategy Base Implementation Address */; -address strategyManagerAddr = /* Strategy Manager Address */; -address delegationManagerAddr = /* Delegation Manager Address */; -address avsDirectoryAddr = /* AVS Directory Address */; -address helloWorldServiceManagerProxyAddr = /* Hello World Service Manager Proxy Address */; -address stakeRegistryProxyAddr = /* ECDSA Stake Registry Proxy Address */; -``` - -### Step 5: Implement the `run` Function - -This function will serve as the entry point to deploy the strategy and update the Hello World AVS. - -```solidity -function run() external { - ERC20Mock erc20Mock = new ERC20Mock(); - StrategyBaseTVLLimits erc20MockStrategy = _deployStrategy(erc20Mock); - _whitelistStrategy(erc20MockStrategy); - _updateHelloWorldAVS(erc20MockStrategy); -} -``` - -### Step 6: Helper Functions - -Implement the helper functions to handle the deployment, whitelisting, and updating the AVS. - -#### Deploy the Strategy - -```solidity -function _deployStrategy(ERC20Mock erc20Mock) internal returns (StrategyBaseTVLLimits) { - ProxyAdmin eigenLayerProxyAdmin = ProxyAdmin(eigenLayerProxyAdminAddr); - PauserRegistry eigenLayerPauserReg = PauserRegistry(eigenLayerPauserRegAddr); - StrategyBaseTVLLimits baseStrategyImplementation = StrategyBaseTVLLimits(baseStrategyImplementationAddr); - - return StrategyBaseTVLLimits( - address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector( - StrategyBaseTVLLimits.initialize.selector, - 1 ether, // maxPerDeposit - 100 ether, // maxDeposits - IERC20(erc20Mock), - eigenLayerPauserReg - ) - ) - ) - ); -} -``` - -#### Whitelist the Strategy - -```solidity -function _whitelistStrategy(StrategyBaseTVLLimits erc20MockStrategy) internal { - IStrategyManager strategyManager = IStrategyManager(strategyManagerAddr); - - IStrategy[] memory strats = new IStrategy[](1); - strats[0] = erc20MockStrategy; - bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1); - thirdPartyTransfersForbiddenValues[0] = false; - strategyManager.addStrategiesToDepositWhitelist( - strats, - thirdPartyTransfersForbiddenValues - ); -} -``` - -#### Update the Hello World AVS - -```solidity -function _updateHelloWorldAVS(StrategyBaseTVLLimits erc20MockStrategy) internal { - IDelegationManager delegationManager = IDelegationManager(delegationManagerAddr); - IAVSDirectory avsDirectory = IAVSDirectory(avsDirectoryAddr); - HelloWorldServiceManager helloWorldServiceManagerProxy = HelloWorldServiceManager(helloWorldServiceManagerProxyAddr); - ECDSAStakeRegistry stakeRegistryProxy = ECDSAStakeRegistry(stakeRegistryProxyAddr); - - StrategyParams memory strategyParams = StrategyParams({ - strategy: erc20MockStrategy, - multiplier: 10_000 - }); - - StrategyParams[] memory strategies = new StrategyParams[](1); - strategies[0] = strategyParams; - - Quorum memory quorum = Quorum({ - strategies: strategies - }); - - stakeRegistryProxy.initialize( - address(helloWorldServiceManagerProxy), - 1, - quorum - ); -} -``` - -### Step 7: Run the Script - -To deploy and verify the contract, run the script using the following Foundry command: - -```bash -forge script script/AddNewStrategy.s.sol:AddStrategyScript --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -v -``` - -### Conclusion - -This guide provides a step-by-step process to add a new strategy to the Hello World AVS using Foundry scripts. By following these steps, you should be able to deploy and integrate new strategies seamlessly. If you encounter any issues, feel free to reach out for support. \ No newline at end of file diff --git a/README.md b/README.md index b354bab0..228de959 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,91 @@ # Hello World AVS -Welcome to the Hello World AVS. +Welcome to the Hello World AVS. This project shows you the simplest functionality you can expect from an AVS. It will give you a concrete understanding of the basic components. -This project shows you the simplest functionality you can expect from an AVS. +### Caveats -It will give you a concrete understanding of the basic components. +- This repo is meant currently intended for _local anvil development testing_. Holesky deployment support will be added shortly. +- Users who wish to build an AVS for Production purposes will want to migrate from the `ECDSAServiceManagerBase` implementation in `HelloWorldServiceManager.sol` to a BLS style architecture using [RegistryCoordinator](https://github.com/Layr-Labs/eigenlayer-middleware/blob/dev/docs/RegistryCoordinator.md). -![hello-world-png](./assets/hello-world-diagram.png) +![hello-world-png](./assets/hello-world-diagramv2.png) -There are 5 steps to this AVS: -- AVS consumer requests a "Hello World" message to be generated and signed -- AVS takes on the request by emitting an event for operators to pick up the request -- any operator who is staked to serve this AVS takes this request, generates this message and signs it -- the operator submits this message with their signature back to the AVS -- *if the operator is in fact registered to the AVS and has the minimum needed stake, the submission is accepted* +### AVS User Flow -That's it. This simple flow highlights some of the core mechanics of how AVSs work. - -Where additional sophistication with AVSs come into the picture: -- the nature of the request is more sophisticated than generating a constant string -- the operators might need to coordinate with each other -- the type of signature is different based on the constraints of the service -- the type and amount of security used to secure the AVS -- and so on... - -## Quick Start - -### Dependencies - -1. [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) -2. [Foundry](https://getfoundry.sh/) -3. [Docker](https://www.docker.com/get-started/) - * Make sure Docker is running for automated deployment +1) AVS consumer requests a "Hello World" message to be generated and signed. +2) HelloWorld contract receives the request and emits a NewTaskCreated event for the request. +3) All Operators who are registered to the AVS and has staked, delegated assets takes this request. Operator generates the requested message, hashes it, and signs the hash with their private key. +4) Each Operator submits their signed hash back to the HelloWorld AVS contract. +5) If the Operator is registered to the AVS and has the minimum needed stake, the submission is accepted. -Following global NodeJS packages: -1. [Typescript](https://github.com/microsoft/TypeScript) +That's it. This simple flow highlights some of the core mechanics of how AVSs work. -## Typescript instructions +## Local Devnet Deployment -### Automated deployment (uses existing state file) +The following instructions explain how to manually deploy the AVS from scratch including EigenLayer and AVS specific contracts using Foundry (forge) to a local anvil chain, and start Typescript Operator application and tasks. -1. Run `npm install` -2. Run `cp .env.local .env` -3. Run `make start-chain-with-contracts-deployed` - * This will build the contracts, start an Anvil chain, deploy the contracts to it, and leaves the chain running in the current terminal -4. Open new terminal tab and run `make start-operator` - * This will compile the AVS software and start monitering new tasks -5. Open new terminal tab and run `make spam-tasks` (Optional) - * This will spam the AVS with random names every 15 seconds +Install dependencies: -### Manual deployment +- [Node](https://nodejs.org/en/download/) +- [Typescript](https://www.typescriptlang.org/download) +- [ts-node](https://www.npmjs.com/package/ts-node) +- [tcs](https://www.npmjs.com/package/tcs#installation) +- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- [Foundry](https://getfoundry.sh/) +- [ethers](https://www.npmjs.com/package/ethers) -This walks you through how to manually deploy using Foundry (Anvil, Forge, and Cast) +### Start Anvil Chain -1. Run `npm install` to install the TypeScript dependencies -2. Run `cp .env.local .env` -3. Compile the contracts. +In terminal window #1, execute the following commands: ```sh -cd contracts && forge build -``` -4. Start Anvil by opening your terminal and running the following command: +# Install npm packages +npm install -```sh -anvil +# Start local anvil chain +npm run start:anvil ``` -5. In a separate terminal window, deploy the EigenLayer contracts. +### Deploy Contracts and Start Operator -To do so, change into `contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts` and run the following commands: +Open a separate terminal window #2, execute the following commands ```sh -forge script script/deploy/devnet/M2_Deploy_From_Scratch.s.sol --rpc-url http://localhost:8545 \ ---private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast \ ---sig "run(string memory configFile)" -- M2_deploy_from_scratch.anvil.config.json -``` +# Setup .env file +(cd contracts && cp .env.example .env && source .env) -6. In a separate terminal window, deploy the AVS contracts. +# Deploy the EigenLayer contracts +npm run deploy:core -```sh -cd contracts +# Deploy the Hello World AVS contracts +npm run deploy:hello-world -forge script script/HelloWorldDeployer.s.sol --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast -v -``` +# (Optional) Update ABIs +npm run extract:abis -7. Start the operator +# Start the Operator application +npm run start:operator -```sh -tsc && node dist/index.js ``` -8. In a separate window, start creating tasks +### Create Hello-World-AVS Tasks + +Open a separate terminal window #3, execute the following commands ```sh -tsc && node dist/createNewTasks.js +cp .env.example .env +source .env + +# Start the createNewTasks application +npm run start:traffic ``` -## Rust instructions +## Rust Operator instructions ### Automated deployment (uses existing state file) 1. Run `make start-chain-with-contracts-deployed` - * This will build the contracts, start an Anvil chain, deploy the contracts to it, and leaves the chain running in the current terminal + - This will build the contracts, start an Anvil chain, deploy the contracts to it, and leaves the chain running in the current terminal 2. Run `make start-rust-operator` @@ -114,41 +97,66 @@ Tests are supported in anvil only . Make sure to run the 1st command before runn cargo test --workspace ``` - -##### Holesky Testnet +## Existing Holesky Testnet Deployment | Contract Name | Holesky Address | | ------------- | ------------- | | Hello World Service Manager | [0x3361953F4a9628672dCBcDb29e91735fb1985390](https://holesky.etherscan.io/address/0x3361953F4a9628672dCBcDb29e91735fb1985390) | -| Delegation Manager | [0xA44151489861Fe9e3055d95adC98FbD462B948e7](https://holesky.etherscan.io/address/0xA44151489861Fe9e3055d95adC98FbD462B948e7) | -| Avs Directory | [0x055733000064333CaDDbC92763c58BF0192fFeBf](https://holesky.etherscan.io/address/0x055733000064333CaDDbC92763c58BF0192fFeBf) | -You don't need to run any script for holesky testnet. +Please see [Current Testnet Deployment](https://github.com/Layr-Labs/eigenlayer-contracts?tab=readme-ov-file#current-testnet-deployment) for additional deployed addresses. + +You don't need to run a deployment script for holesky testnet, the contracts are already deployed. 1. Use the HOLESKY_ namespace env parameters in the code , instead of normal parameters. 2. Run `make start-rust-operator` -3. Run `make spam-rust-tasks ` +3. Run `make spam-rust-tasks` + +# Appendix (Future Capabilities In Progress) +## Deployment on Tenderly Virtual Testnet -## Extensions +Follow the [Tenderly Virtual Testnet Setup Instructions](https://docs.tenderly.co/virtual-testnets/quickstart) to create a new virtual testnet. -- Operator needs a minimum stake amount to make submissions -- Add another strategy to the AVS -- Operator must respond within a certain number of blocks +Run the following commands: -## Deployment on Holesky +```sh -To deploy the Hello World AVS contracts to the Holesky network, follow these steps: +# todo: add instructions to create a wallet for testnet account and set private key in .env holesky vars -1. Ensure you have the necessary RPC URL and private key for the Holesky network. -2. Run the deployment script using Foundry: - ```bash - forge script script/HoleskyDeployer.s.sol:HoleskyDeployer --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv - ``` - Replace `$RPC_URL` with your Holesky RPC URL and `$PRIVATE_KEY` with your private key. +# Set env vars +cd contracts +source ../.env + +# Fund account using the tenderly rpc +curl $TENDERLY_RPC_ADMIN \ +-X POST \ +-H "Content-Type: application/json" \ +-d '{ + "jsonrpc": "2.0", + "method": "tenderly_setBalance", + "params": [ + [ + "'"${PUBLIC_KEY}"'" + ], + "0xDE0B6B3A7640000" + ], + "id": "1234" +}' + +# Deploy AVS contracts to Tenderly Holesky using Foundry +forge script script/HelloWorldDeployerHolesky.s.sol:HelloWorldDeployerHolesky \ + --rpc-url $TENDERLY_RPC_ADMIN --private-key $TENDERLY_PRIVATE_KEY --broadcast -vvv debug +``` ## Adding a New Strategy -To add a new strategy to the Hello World AVS, follow the guide provided in [`AddNewStrategy.md`](https://github.com/Layr-Labs/hello-world-avs/blob/master/AddNewStrategy.md). This guide walks you through the necessary steps to add and whitelist a new strategy for the AVS. +## Potential Enhancements to the AVS (for learning purposes) + +The architecture can be further enhanced via: + +- the nature of the request is more sophisticated than generating a constant string +- the operators might need to coordinate with each other +- the type of signature is different based on the constraints of the service +- the type and amount of security used to secure the AVS diff --git a/abis/ECDSAStakeRegistry.json b/abis/ECDSAStakeRegistry.json new file mode 100644 index 00000000..55b95e99 --- /dev/null +++ b/abis/ECDSAStakeRegistry.json @@ -0,0 +1,817 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_delegationManager", + "type": "address", + "internalType": "contract IDelegationManager" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deregisterOperator", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getLastCheckpointOperatorWeight", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastCheckpointThresholdWeight", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastCheckpointThresholdWeightAtBlock", + "inputs": [ + { + "name": "_blockNumber", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastCheckpointTotalWeight", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastCheckpointTotalWeightAtBlock", + "inputs": [ + { + "name": "_blockNumber", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastestOperatorSigningKey", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOperatorSigningKeyAtBlock", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + }, + { + "name": "_blockNumber", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOperatorWeight", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOperatorWeightAtBlock", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + }, + { + "name": "_blockNumber", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_serviceManager", + "type": "address", + "internalType": "address" + }, + { + "name": "_thresholdWeight", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_quorum", + "type": "tuple", + "internalType": "struct Quorum", + "components": [ + { + "name": "strategies", + "type": "tuple[]", + "internalType": "struct StrategyParams[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isValidSignature", + "inputs": [ + { + "name": "_dataHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_signatureData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "minimumWeight", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "operatorRegistered", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quorum", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct Quorum", + "components": [ + { + "name": "strategies", + "type": "tuple[]", + "internalType": "struct StrategyParams[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "registerOperatorWithSignature", + "inputs": [ + { + "name": "_operatorSignature", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithSaltAndExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "_signingKey", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateMinimumWeight", + "inputs": [ + { + "name": "_newMinimumWeight", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_operators", + "type": "address[]", + "internalType": "address[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateOperatorSigningKey", + "inputs": [ + { + "name": "_newSigningKey", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateOperators", + "inputs": [ + { + "name": "_operators", + "type": "address[]", + "internalType": "address[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateOperatorsForQuorum", + "inputs": [ + { + "name": "operatorsPerQuorum", + "type": "address[][]", + "internalType": "address[][]" + }, + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateQuorumConfig", + "inputs": [ + { + "name": "_quorum", + "type": "tuple", + "internalType": "struct Quorum", + "components": [ + { + "name": "strategies", + "type": "tuple[]", + "internalType": "struct StrategyParams[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ] + }, + { + "name": "_operators", + "type": "address[]", + "internalType": "address[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateStakeThreshold", + "inputs": [ + { + "name": "_thresholdWeight", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MinimumWeightUpdated", + "inputs": [ + { + "name": "_old", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "_new", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorDeregistered", + "inputs": [ + { + "name": "_operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "_avs", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorRegistered", + "inputs": [ + { + "name": "_operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "_avs", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorWeightUpdated", + "inputs": [ + { + "name": "_operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "QuorumUpdated", + "inputs": [ + { + "name": "_old", + "type": "tuple", + "indexed": false, + "internalType": "struct Quorum", + "components": [ + { + "name": "strategies", + "type": "tuple[]", + "internalType": "struct StrategyParams[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ] + }, + { + "name": "_new", + "type": "tuple", + "indexed": false, + "internalType": "struct Quorum", + "components": [ + { + "name": "strategies", + "type": "tuple[]", + "internalType": "struct StrategyParams[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SigningKeyUpdate", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "updateBlock", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "newSigningKey", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldSigningKey", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ThresholdWeightUpdated", + "inputs": [ + { + "name": "_thresholdWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TotalWeightUpdated", + "inputs": [ + { + "name": "oldTotalWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newTotalWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "UpdateMinimumWeight", + "inputs": [ + { + "name": "oldMinimumWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newMinimumWeight", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "InsufficientSignedStake", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientWeight", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidLength", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidQuorum", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidReferenceBlock", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSignature", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSignedWeight", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidThreshold", + "inputs": [] + }, + { + "type": "error", + "name": "LengthMismatch", + "inputs": [] + }, + { + "type": "error", + "name": "MustUpdateAllOperators", + "inputs": [] + }, + { + "type": "error", + "name": "NotSorted", + "inputs": [] + }, + { + "type": "error", + "name": "OperatorAlreadyRegistered", + "inputs": [] + }, + { + "type": "error", + "name": "OperatorNotRegistered", + "inputs": [] + } +] \ No newline at end of file diff --git a/abis/HelloWorldServiceManager.json b/abis/HelloWorldServiceManager.json new file mode 100644 index 00000000..61d70f6f --- /dev/null +++ b/abis/HelloWorldServiceManager.json @@ -0,0 +1,495 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_avsDirectory", + "type": "address", + "internalType": "address" + }, + { + "name": "_stakeRegistry", + "type": "address", + "internalType": "address" + }, + { + "name": "_delegationManager", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "allTaskHashes", + "inputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "allTaskResponses", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "avsDirectory", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "createAVSRewardsSubmission", + "inputs": [ + { + "name": "rewardsSubmissions", + "type": "tuple[]", + "internalType": "struct IRewardsCoordinator.RewardsSubmission[]", + "components": [ + { + "name": "strategiesAndMultipliers", + "type": "tuple[]", + "internalType": "struct IRewardsCoordinator.StrategyAndMultiplier[]", + "components": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "multiplier", + "type": "uint96", + "internalType": "uint96" + } + ] + }, + { + "name": "token", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startTimestamp", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "duration", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createNewTask", + "inputs": [ + { + "name": "name", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deregisterOperatorFromAVS", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getOperatorRestakedStrategies", + "inputs": [ + { + "name": "_operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address[]", + "internalType": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRestakeableStrategies", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address[]", + "internalType": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "latestTaskNum", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "operatorHasMinimumWeight", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "registerOperatorToAVS", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "operatorSignature", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithSaltAndExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "respondToTask", + "inputs": [ + { + "name": "task", + "type": "tuple", + "internalType": "struct IHelloWorldServiceManager.Task", + "components": [ + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "taskCreatedBlock", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "name": "referenceTaskIndex", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rewardsInitiator", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setRewardsInitiator", + "inputs": [ + { + "name": "newRewardsInitiator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "stakeRegistry", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateAVSMetadataURI", + "inputs": [ + { + "name": "_metadataURI", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NewTaskCreated", + "inputs": [ + { + "name": "taskIndex", + "type": "uint32", + "indexed": true, + "internalType": "uint32" + }, + { + "name": "task", + "type": "tuple", + "indexed": false, + "internalType": "struct IHelloWorldServiceManager.Task", + "components": [ + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "taskCreatedBlock", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RewardsInitiatorUpdated", + "inputs": [ + { + "name": "prevRewardsInitiator", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "newRewardsInitiator", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TaskResponded", + "inputs": [ + { + "name": "taskIndex", + "type": "uint32", + "indexed": true, + "internalType": "uint32" + }, + { + "name": "task", + "type": "tuple", + "indexed": false, + "internalType": "struct IHelloWorldServiceManager.Task", + "components": [ + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "taskCreatedBlock", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "name": "operator", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + } +] \ No newline at end of file diff --git a/abis/IAVSDirectory.json b/abis/IAVSDirectory.json new file mode 100644 index 00000000..06f1f4e6 --- /dev/null +++ b/abis/IAVSDirectory.json @@ -0,0 +1,178 @@ +[ + { + "type": "function", + "name": "OPERATOR_AVS_REGISTRATION_TYPEHASH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "calculateOperatorAVSRegistrationDigestHash", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "avs", + "type": "address", + "internalType": "address" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "deregisterOperatorFromAVS", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "operatorSaltIsSpent", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "registerOperatorToAVS", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "operatorSignature", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithSaltAndExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateAVSMetadataURI", + "inputs": [ + { + "name": "metadataURI", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "AVSMetadataURIUpdated", + "inputs": [ + { + "name": "avs", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "metadataURI", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorAVSRegistrationStatusUpdated", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "avs", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "status", + "type": "uint8", + "indexed": false, + "internalType": "enum IAVSDirectory.OperatorAVSRegistrationStatus" + } + ], + "anonymous": false + } +] \ No newline at end of file diff --git a/abis/IDelegationManager.json b/abis/IDelegationManager.json new file mode 100644 index 00000000..c3b846a3 --- /dev/null +++ b/abis/IDelegationManager.json @@ -0,0 +1,1241 @@ +[ + { + "type": "function", + "name": "DELEGATION_APPROVAL_TYPEHASH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DOMAIN_TYPEHASH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "STAKER_DELEGATION_TYPEHASH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "beaconChainETHStrategy", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IStrategy" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "calculateCurrentStakerDelegationDigestHash", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "calculateDelegationApprovalDigestHash", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "_delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "approverSalt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "calculateStakerDelegationDigestHash", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "_stakerNonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "calculateWithdrawalRoot", + "inputs": [ + { + "name": "withdrawal", + "type": "tuple", + "internalType": "struct IDelegationManager.Withdrawal", + "components": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "delegatedTo", + "type": "address", + "internalType": "address" + }, + { + "name": "withdrawer", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startBlock", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + }, + { + "name": "shares", + "type": "uint256[]", + "internalType": "uint256[]" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "completeQueuedWithdrawal", + "inputs": [ + { + "name": "withdrawal", + "type": "tuple", + "internalType": "struct IDelegationManager.Withdrawal", + "components": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "delegatedTo", + "type": "address", + "internalType": "address" + }, + { + "name": "withdrawer", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startBlock", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + }, + { + "name": "shares", + "type": "uint256[]", + "internalType": "uint256[]" + } + ] + }, + { + "name": "tokens", + "type": "address[]", + "internalType": "contract IERC20[]" + }, + { + "name": "middlewareTimesIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receiveAsTokens", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "completeQueuedWithdrawals", + "inputs": [ + { + "name": "withdrawals", + "type": "tuple[]", + "internalType": "struct IDelegationManager.Withdrawal[]", + "components": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "delegatedTo", + "type": "address", + "internalType": "address" + }, + { + "name": "withdrawer", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startBlock", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + }, + { + "name": "shares", + "type": "uint256[]", + "internalType": "uint256[]" + } + ] + }, + { + "name": "tokens", + "type": "address[][]", + "internalType": "contract IERC20[][]" + }, + { + "name": "middlewareTimesIndexes", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "receiveAsTokens", + "type": "bool[]", + "internalType": "bool[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "cumulativeWithdrawalsQueued", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "decreaseDelegatedShares", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "delegateTo", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "approverSignatureAndExpiry", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "approverSalt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "delegateToBySignature", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerSignatureAndExpiry", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "approverSignatureAndExpiry", + "type": "tuple", + "internalType": "struct ISignatureUtils.SignatureWithExpiry", + "components": [ + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "expiry", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "approverSalt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "delegatedTo", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "delegationApprover", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "delegationApproverSaltIsSpent", + "inputs": [ + { + "name": "_delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "domainSeparator", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOperatorShares", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getWithdrawalDelay", + "inputs": [ + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "increaseDelegatedShares", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isDelegated", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isOperator", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "minWithdrawalDelayBlocks", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "modifyOperatorDetails", + "inputs": [ + { + "name": "newOperatorDetails", + "type": "tuple", + "internalType": "struct IDelegationManager.OperatorDetails", + "components": [ + { + "name": "__deprecated_earningsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerOptOutWindowBlocks", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "operatorDetails", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IDelegationManager.OperatorDetails", + "components": [ + { + "name": "__deprecated_earningsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerOptOutWindowBlocks", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "operatorShares", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "queueWithdrawals", + "inputs": [ + { + "name": "queuedWithdrawalParams", + "type": "tuple[]", + "internalType": "struct IDelegationManager.QueuedWithdrawalParams[]", + "components": [ + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + }, + { + "name": "shares", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "withdrawer", + "type": "address", + "internalType": "address" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "registerAsOperator", + "inputs": [ + { + "name": "registeringOperatorDetails", + "type": "tuple", + "internalType": "struct IDelegationManager.OperatorDetails", + "components": [ + { + "name": "__deprecated_earningsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerOptOutWindowBlocks", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "name": "metadataURI", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "stakerNonce", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "stakerOptOutWindowBlocks", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "strategyWithdrawalDelayBlocks", + "inputs": [ + { + "name": "strategy", + "type": "address", + "internalType": "contract IStrategy" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "undelegate", + "inputs": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "withdrawalRoot", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateOperatorMetadataURI", + "inputs": [ + { + "name": "metadataURI", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "MinWithdrawalDelayBlocksSet", + "inputs": [ + { + "name": "previousValue", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newValue", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorDetailsModified", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOperatorDetails", + "type": "tuple", + "indexed": false, + "internalType": "struct IDelegationManager.OperatorDetails", + "components": [ + { + "name": "__deprecated_earningsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerOptOutWindowBlocks", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorMetadataURIUpdated", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "metadataURI", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorRegistered", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operatorDetails", + "type": "tuple", + "indexed": false, + "internalType": "struct IDelegationManager.OperatorDetails", + "components": [ + { + "name": "__deprecated_earningsReceiver", + "type": "address", + "internalType": "address" + }, + { + "name": "delegationApprover", + "type": "address", + "internalType": "address" + }, + { + "name": "stakerOptOutWindowBlocks", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorSharesDecreased", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "staker", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "strategy", + "type": "address", + "indexed": false, + "internalType": "contract IStrategy" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorSharesIncreased", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "staker", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "strategy", + "type": "address", + "indexed": false, + "internalType": "contract IStrategy" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StakerDelegated", + "inputs": [ + { + "name": "staker", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StakerForceUndelegated", + "inputs": [ + { + "name": "staker", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StakerUndelegated", + "inputs": [ + { + "name": "staker", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StrategyWithdrawalDelayBlocksSet", + "inputs": [ + { + "name": "strategy", + "type": "address", + "indexed": false, + "internalType": "contract IStrategy" + }, + { + "name": "previousValue", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newValue", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawalCompleted", + "inputs": [ + { + "name": "withdrawalRoot", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawalQueued", + "inputs": [ + { + "name": "withdrawalRoot", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "withdrawal", + "type": "tuple", + "indexed": false, + "internalType": "struct IDelegationManager.Withdrawal", + "components": [ + { + "name": "staker", + "type": "address", + "internalType": "address" + }, + { + "name": "delegatedTo", + "type": "address", + "internalType": "address" + }, + { + "name": "withdrawer", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startBlock", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "strategies", + "type": "address[]", + "internalType": "contract IStrategy[]" + }, + { + "name": "shares", + "type": "uint256[]", + "internalType": "uint256[]" + } + ] + } + ], + "anonymous": false + } +] \ No newline at end of file diff --git a/assets/hello-world-diagramv2.png b/assets/hello-world-diagramv2.png new file mode 100644 index 00000000..983fa777 Binary files /dev/null and b/assets/hello-world-diagramv2.png differ diff --git a/contracts/.env.example b/contracts/.env.example new file mode 100644 index 00000000..ada4ad43 --- /dev/null +++ b/contracts/.env.example @@ -0,0 +1,4 @@ +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +HOLESKY_PRIVATE_KEY= +HOLESKY_RPC_URL= +ETHERSCAN_API_KEY= diff --git a/contracts/.gitignore b/contracts/.gitignore index 85198aaa..8161a6cd 100644 --- a/contracts/.gitignore +++ b/contracts/.gitignore @@ -3,9 +3,7 @@ cache/ out/ # Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ +broadcast/* # Docs docs/ diff --git a/contracts/deployments/core/31337.json b/contracts/deployments/core/31337.json new file mode 100644 index 00000000..599d6d56 --- /dev/null +++ b/contracts/deployments/core/31337.json @@ -0,0 +1 @@ +{"lastUpdate":{"timestamp":"1726153650","block_number":"0"},"addresses":{"proxyAdmin":"0x5fbdb2315678afecb367f032d93f642f64180aa3","delegation":"0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0","delegationManagerImpl":"0x0b306bf915c4d645ff596e518faf3f9669b97016","avsDirectory":"0xdc64a140aa3e981100a9beca4e685f962f0cf6c9","avsDirectoryImpl":"0x959922be3caee4b8cd9a407cc3ac1c251c2007b1","strategyManager":"0x0165878a594ca255338adfa4d48449f69242eb8f","strategyManagerImpl":"0x9a9f2ccfde556a7e9ff0848998aa4a0cfd8863ae","eigenPodManager":"0x2279b7a0a67db372996a5fab50d91eaa73d2ebe6","eigenPodManagerImpl":"0x68b1d87f95878fe05b998f19b66f4baba5de1aed"}} \ No newline at end of file diff --git a/contracts/deployments/hello-world/31337.json b/contracts/deployments/hello-world/31337.json new file mode 100644 index 00000000..4a540864 --- /dev/null +++ b/contracts/deployments/hello-world/31337.json @@ -0,0 +1 @@ +{"lastUpdate":{"timestamp":"1726153695","block_number":"15"},"addresses":{"proxyAdmin":"0xe6e340d132b5f46d1e472debcd681b2abc16e57e","helloWorldServiceManager":"0x84ea74d481ee0a5332c457a4d796187f6ba67feb","helloWorldServiceManagerImpl":"0x851356ae760d987e095750cceb3bc6014560891c","stakeRegistry":"0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9","stakeRegistryImpl":"0x1613beb3b2c4f22ee086b2b38c1476a3ce7f78e8","wethStrategy":"0x00000000000000000000000000000000000001a4"}} \ No newline at end of file diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 0af8370d..bdb62433 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -2,7 +2,9 @@ src = "src" out = "out" libs = ["lib"] -fs_permissions = [{ access = "read-write", path = "./"}] +fs_permissions = [{ access = "read-write", path = "./" }] +solc = "0.8.26" +via-ir = true remappings = [ "@eigenlayer/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/", @@ -10,20 +12,25 @@ remappings = [ "@eigenlayer-middleware/=lib/eigenlayer-middleware/", "@openzeppelin/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/lib/openzeppelin-contracts/", "@openzeppelin-upgrades/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/lib/openzeppelin-contracts-upgradeable/", - "forge-std/=lib/forge-std/src/" + "forge-std/=lib/forge-std/src/", ] -gas_reports = ["*"] +[rpc_endpoints] +mainnet = "${MAINNET_RPC_URL}" +holesky = "${HOLESKY_RPC_URL}" +sepolia = "${SEPOLIA_RPC_URL}" +anvil = "${ANVIL_RPC_URL}" -# A list of ignored solc error codes +[etherscan] +mainnet = { key = "${ETHERSCAN_API_KEY}" } +sepolia = { key = "${ETHERSCAN_API_KEY}" } +holesky = { key = "${ETHERSCAN_API_KEY}" } -# Enables or disables the optimizer -optimizer = true -# The number of optimizer runs -optimizer_runs = 200 -# Whether or not to use the Yul intermediate representation compilation pipeline -via_ir = false -# Override the Solidity version (this overrides `auto_detect_solc`) -auto_detect_solc = true - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file +[fmt] +bracket_spacing = false +int_types = "long" +line_length = 100 +multiline_func_header = "params_first" +number_underscore = "thousands" +quote_style = "double" +tab_width = 4 diff --git a/contracts/lib/eigenlayer-middleware b/contracts/lib/eigenlayer-middleware index a23de118..74438b79 160000 --- a/contracts/lib/eigenlayer-middleware +++ b/contracts/lib/eigenlayer-middleware @@ -1 +1 @@ -Subproject commit a23de118e7d16081d350c7f83c24261d1421b0ba +Subproject commit 74438b7915c35ca5a0d312654716160c2499169d diff --git a/contracts/lib/forge-std b/contracts/lib/forge-std index 978ac6fa..58d30519 160000 --- a/contracts/lib/forge-std +++ b/contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 978ac6fadb62f5f0b723c996f64be52eddba6801 +Subproject commit 58d30519826c313ce47345abedfdc07679e944d1 diff --git a/contracts/lib/openzeppelin-contracts b/contracts/lib/openzeppelin-contracts deleted file mode 160000 index ecd2ca2c..00000000 --- a/contracts/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ecd2ca2cd7cac116f7a37d0e474bbb3d7d5e1c4d diff --git a/contracts/script/AddNewStrategy.s.sol b/contracts/script/AddNewStrategy.s.sol deleted file mode 100644 index 2afd981d..00000000 --- a/contracts/script/AddNewStrategy.s.sol +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.21; - -import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import "@eigenlayer/contracts/permissions/PauserRegistry.sol"; -import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; -import {IAVSDirectory} from "@eigenlayer/contracts/interfaces/IAVSDirectory.sol"; -import {IStrategyManager, IStrategy} from "@eigenlayer/contracts/interfaces/IStrategyManager.sol"; -import {ISlasher} from "@eigenlayer/contracts/interfaces/ISlasher.sol"; -import {StrategyBaseTVLLimits} from "@eigenlayer/contracts/strategies/StrategyBaseTVLLimits.sol"; -import "@eigenlayer/test/mocks/EmptyContract.sol"; -import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; -import {Quorum, StrategyParams} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; -import "@eigenlayer-middleware/src/OperatorStateRetriever.sol"; -import {HelloWorldServiceManager, IServiceManager} from "../src/HelloWorldServiceManager.sol"; -import "../src/ERC20Mock.sol"; -import {Utils} from "./utils/Utils.sol"; -import "forge-std/Script.sol"; -import "forge-std/StdJson.sol"; -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -contract AddStrategyScript is Script, Utils { - // Replace the placeholders with actual addresses or add them as inputs to the script - address eigenLayerProxyAdminAddr; - address eigenLayerPauserRegAddr; - address baseStrategyImplementationAddr; - address strategyManagerAddr; - address delegationManagerAddr; - address avsDirectoryAddr; - address helloWorldServiceManagerProxyAddr; - address stakeRegistryProxyAddr; - - function run() external { - ERC20Mock erc20Mock = new ERC20Mock(); - StrategyBaseTVLLimits erc20MockStrategy = _deployStrategy(erc20Mock); - _whitelistStrategy(erc20MockStrategy); - _updateHelloWorldAVS(erc20MockStrategy); - } - - function _deployStrategy(ERC20Mock erc20Mock) internal returns (StrategyBaseTVLLimits) { - ProxyAdmin eigenLayerProxyAdmin = ProxyAdmin(eigenLayerProxyAdminAddr); - PauserRegistry eigenLayerPauserReg = PauserRegistry(eigenLayerPauserRegAddr); - StrategyBaseTVLLimits baseStrategyImplementation = StrategyBaseTVLLimits(baseStrategyImplementationAddr); - - return StrategyBaseTVLLimits( - address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector( - StrategyBaseTVLLimits.initialize.selector, - 1 ether, // maxPerDeposit - 100 ether, // maxDeposits - IERC20(erc20Mock), - eigenLayerPauserReg - ) - ) - ) - ); - } - - function _whitelistStrategy(StrategyBaseTVLLimits erc20MockStrategy) internal { - IStrategyManager strategyManager = IStrategyManager(strategyManagerAddr); - - IStrategy[] memory strats = new IStrategy[](1); - strats[0] = erc20MockStrategy; - bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1); - thirdPartyTransfersForbiddenValues[0] = false; - strategyManager.addStrategiesToDepositWhitelist( - strats, - thirdPartyTransfersForbiddenValues - ); - } - - function _updateHelloWorldAVS(StrategyBaseTVLLimits erc20MockStrategy) internal { - IDelegationManager delegationManager = IDelegationManager(delegationManagerAddr); - IAVSDirectory avsDirectory = IAVSDirectory(avsDirectoryAddr); - HelloWorldServiceManager helloWorldServiceManagerProxy = HelloWorldServiceManager(helloWorldServiceManagerProxyAddr); - ECDSAStakeRegistry stakeRegistryProxy = ECDSAStakeRegistry(stakeRegistryProxyAddr); - - StrategyParams memory strategyParams = StrategyParams({ - strategy: erc20MockStrategy, - multiplier: 10_000 - }); - - StrategyParams[] memory strategies = new StrategyParams[](1); - strategies[0] = strategyParams; - - Quorum memory quorum = Quorum({ - strategies: strategies - }); - - stakeRegistryProxy.initialize( - address(helloWorldServiceManagerProxy), - 1, - quorum - ); - } -} diff --git a/contracts/script/DeployEigenLayerCore.s.sol b/contracts/script/DeployEigenLayerCore.s.sol new file mode 100644 index 00000000..fe698ef1 --- /dev/null +++ b/contracts/script/DeployEigenLayerCore.s.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "forge-std/Script.sol"; +import "forge-std/Test.sol"; + +import {CoreDeploymentLib} from "./utils/CoreDeploymentLib.sol"; +import {UpgradeableProxyLib} from "./utils/UpgradeableProxyLib.sol"; + +contract DeployEigenlayerCore is Script, Test { + using CoreDeploymentLib for *; + using UpgradeableProxyLib for address; + + address deployer; + address proxyAdmin; + CoreDeploymentLib.DeploymentData deploymentData; + CoreDeploymentLib.DeploymentConfigData configData; + + function setUp() public virtual { + deployer = vm.rememberKey(vm.envUint("PRIVATE_KEY")); + vm.label(deployer, "Deployer"); + string memory configPath = + "lib/eigenlayer-middleware/lib/eigenlayer-contracts/script/output/devnet/"; + string memory configFilename = "M2_from_scratch_deployment_data.json"; + + deploymentData = CoreDeploymentLib.readDeploymentJson(configPath, configFilename); + } + + function run() external { + vm.startBroadcast(deployer); + proxyAdmin = UpgradeableProxyLib.deployProxyAdmin(); + deploymentData = CoreDeploymentLib.deployContracts(proxyAdmin, configData); + vm.stopBroadcast(); + string memory deploymentPath = "deployments/core/"; + CoreDeploymentLib.writeDeploymentJson(deploymentPath, block.chainid, deploymentData); + } +} diff --git a/contracts/script/HelloWorldDeployer.s.sol b/contracts/script/HelloWorldDeployer.s.sol index 283cba5a..41578a25 100644 --- a/contracts/script/HelloWorldDeployer.s.sol +++ b/contracts/script/HelloWorldDeployer.s.sol @@ -1,296 +1,68 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; - -import "@eigenlayer/contracts/permissions/PauserRegistry.sol"; -import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; -import {IAVSDirectory} from "@eigenlayer/contracts/interfaces/IAVSDirectory.sol"; -import {IStrategyManager, IStrategy} from "@eigenlayer/contracts/interfaces/IStrategyManager.sol"; -import {ISlasher} from "@eigenlayer/contracts/interfaces/ISlasher.sol"; -import {StrategyBaseTVLLimits} from "@eigenlayer/contracts/strategies/StrategyBaseTVLLimits.sol"; -import "@eigenlayer/test/mocks/EmptyContract.sol"; - -import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; -import {Quorum, StrategyParams} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; -import "@eigenlayer-middleware/src/OperatorStateRetriever.sol"; - -import {HelloWorldServiceManager, IServiceManager} from "../src/HelloWorldServiceManager.sol"; -import "../src/ERC20Mock.sol"; +pragma solidity ^0.8.0; +import {Script} from "forge-std/Script.sol"; +import {console2} from "forge-std/Test.sol"; import {Utils} from "./utils/Utils.sol"; +import {HelloWorldDeploymentLib} from "./utils/HelloWorldDeploymentLib.sol"; +import {CoreDeploymentLib} from "./utils/CoreDeploymentLib.sol"; +import {UpgradeableProxyLib} from "./utils/UpgradeableProxyLib.sol"; -import "forge-std/Test.sol"; -import "forge-std/Script.sol"; -import "forge-std/StdJson.sol"; -import "forge-std/console.sol"; +import { + Quorum, + StrategyParams, + IStrategy +} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; // # To deploy and verify our contract // forge script script/HelloWorldDeployer.s.sol:HelloWorldDeployer --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv contract HelloWorldDeployer is Script, Utils { - // ERC20 and Strategy: we need to deploy this erc20, create a strategy for it, and whitelist this strategy in the strategymanager - - ERC20Mock public erc20Mock; - StrategyBaseTVLLimits public erc20MockStrategy; + using CoreDeploymentLib for *; + using UpgradeableProxyLib for address; - // Hello World contracts - ProxyAdmin public helloWorldProxyAdmin; - PauserRegistry public helloWorldPauserReg; - - ECDSAStakeRegistry public stakeRegistryProxy; - ECDSAStakeRegistry public stakeRegistryImplementation; - - HelloWorldServiceManager public helloWorldServiceManagerProxy; - HelloWorldServiceManager public helloWorldServiceManagerImplementation; - - function run() external { - // Eigenlayer contracts - string memory eigenlayerDeployedContracts = readOutput( - "eigenlayer_deployment_output" - ); - IStrategyManager strategyManager = IStrategyManager( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.strategyManager" - ) - ); - IDelegationManager delegationManager = IDelegationManager( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.delegation" - ) - ); - IAVSDirectory avsDirectory = IAVSDirectory( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.avsDirectory" - ) - ); - ProxyAdmin eigenLayerProxyAdmin = ProxyAdmin( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.eigenLayerProxyAdmin" - ) - ); - PauserRegistry eigenLayerPauserReg = PauserRegistry( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.eigenLayerPauserReg" - ) - ); - StrategyBaseTVLLimits baseStrategyImplementation = StrategyBaseTVLLimits( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.baseStrategyImplementation" - ) - ); + address private deployer; + address proxyAdmin; + CoreDeploymentLib.DeploymentData coreDeployment; + HelloWorldDeploymentLib.DeploymentData helloWorldDeployment; + Quorum internal quorum; - address helloWorldCommunityMultisig = msg.sender; - address helloWorldPauser = msg.sender; + function setUp() public virtual { + deployer = vm.rememberKey(vm.envUint("PRIVATE_KEY")); + vm.label(deployer, "Deployer"); - vm.startBroadcast(); - _deployErc20AndStrategyAndWhitelistStrategy( - eigenLayerProxyAdmin, - eigenLayerPauserReg, - baseStrategyImplementation, - strategyManager - ); - _deployHelloWorldContracts( - delegationManager, - avsDirectory, - erc20MockStrategy, - helloWorldCommunityMultisig, - helloWorldPauser - ); - vm.stopBroadcast(); - } + coreDeployment = CoreDeploymentLib.readDeploymentJson("deployments/core/", block.chainid); - function _deployErc20AndStrategyAndWhitelistStrategy( - ProxyAdmin eigenLayerProxyAdmin, - PauserRegistry eigenLayerPauserReg, - StrategyBaseTVLLimits baseStrategyImplementation, - IStrategyManager strategyManager - ) internal { - erc20Mock = new ERC20Mock(); - // TODO(samlaf): any reason why we are using the strategybase with tvl limits instead of just using strategybase? - // the maxPerDeposit and maxDeposits below are just arbitrary values. - erc20MockStrategy = StrategyBaseTVLLimits( - address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector( - StrategyBaseTVLLimits.initialize.selector, - 1 ether, // maxPerDeposit - 100 ether, // maxDeposits - IERC20(erc20Mock), - eigenLayerPauserReg - ) - ) - ) - ); - IStrategy[] memory strats = new IStrategy[](1); - strats[0] = erc20MockStrategy; - bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1); - thirdPartyTransfersForbiddenValues[0] = false; - strategyManager.addStrategiesToDepositWhitelist( - strats, - thirdPartyTransfersForbiddenValues + quorum.strategies.push( + StrategyParams({strategy: IStrategy(address(420)), multiplier: 10_000}) ); } - function _deployHelloWorldContracts( - IDelegationManager delegationManager, - IAVSDirectory avsDirectory, - IStrategy strat, - address helloWorldCommunityMultisig, - address helloWorldPauser - ) internal { - // Adding this as a temporary fix to make the rest of the script work with a single strategy - // since it was originally written to work with an array of strategies - IStrategy[1] memory deployedStrategyArray = [strat]; - uint numStrategies = deployedStrategyArray.length; - - // deploy proxy admin for ability to upgrade proxy contracts - helloWorldProxyAdmin = new ProxyAdmin(); - - // deploy pauser registry - { - address[] memory pausers = new address[](2); - pausers[0] = helloWorldPauser; - pausers[1] = helloWorldCommunityMultisig; - helloWorldPauserReg = new PauserRegistry( - pausers, - helloWorldCommunityMultisig - ); - } - - EmptyContract emptyContract = new EmptyContract(); - - // hard-coded inputs - - /** - * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are - * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. - */ - helloWorldServiceManagerProxy = HelloWorldServiceManager( - address( - new TransparentUpgradeableProxy( - address(emptyContract), - address(helloWorldProxyAdmin), - "" - ) - ) - ); - stakeRegistryProxy = ECDSAStakeRegistry( - address( - new TransparentUpgradeableProxy( - address(emptyContract), - address(helloWorldProxyAdmin), - "" - ) - ) - ); - - // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - { - stakeRegistryImplementation = new ECDSAStakeRegistry( - delegationManager - ); - - helloWorldProxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(stakeRegistryProxy))), - address(stakeRegistryImplementation) - ); - } - - { - StrategyParams[] - memory quorumsStrategyParams = new StrategyParams[]( - numStrategies - ); - - for (uint j = 0; j < numStrategies; j++) { - quorumsStrategyParams[j] = StrategyParams({ - strategy: deployedStrategyArray[j], - multiplier: 10_000 - }); - } - - Quorum memory quorum = Quorum( - quorumsStrategyParams - ); + function run() external { + vm.startBroadcast(deployer); + proxyAdmin = UpgradeableProxyLib.deployProxyAdmin(); - helloWorldProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy( - payable(address(stakeRegistryProxy)) - ), - address(stakeRegistryImplementation), - abi.encodeWithSelector( - ECDSAStakeRegistry.initialize.selector, - address(helloWorldServiceManagerProxy), - 1, - quorum - ) - ); - } + helloWorldDeployment = + HelloWorldDeploymentLib.deployContracts(proxyAdmin, coreDeployment, quorum); - helloWorldServiceManagerImplementation = new HelloWorldServiceManager( - address(avsDirectory), - address(stakeRegistryProxy), - address(delegationManager) - ); - // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. - helloWorldProxyAdmin.upgrade( - TransparentUpgradeableProxy( - payable(address(helloWorldServiceManagerProxy)) - ), - address(helloWorldServiceManagerImplementation) - ); + vm.stopBroadcast(); - // WRITE JSON DATA - string memory parent_object = "parent object"; + verifyDeployment(); + HelloWorldDeploymentLib.writeDeploymentJson(helloWorldDeployment); + } - string memory deployed_addresses = "addresses"; - vm.serializeAddress( - deployed_addresses, - "erc20Mock", - address(erc20Mock) - ); - vm.serializeAddress( - deployed_addresses, - "erc20MockStrategy", - address(erc20MockStrategy) + function verifyDeployment() internal view { + require( + helloWorldDeployment.stakeRegistry != address(0), "StakeRegistry address cannot be zero" ); - vm.serializeAddress( - deployed_addresses, - "HelloWorldServiceManagerProxy", - address(helloWorldServiceManagerProxy) + require( + helloWorldDeployment.helloWorldServiceManager != address(0), + "HelloWorldServiceManager address cannot be zero" ); - vm.serializeAddress( - deployed_addresses, - "HelloWorldServiceManagerImplementation", - address(helloWorldServiceManagerImplementation) + require(proxyAdmin != address(0), "ProxyAdmin address cannot be zero"); + require( + coreDeployment.delegationManager != address(0), + "DelegationManager address cannot be zero" ); - vm.serializeAddress( - deployed_addresses, - "ECDSAStakeRegistry", - address(stakeRegistryProxy) - ); - - string memory deployed_addresses_output = vm.serializeAddress( - deployed_addresses, - "ECDSAStakeRegistryImplementation", - address(stakeRegistryImplementation) - ); - - // serialize all the data - string memory finalJson = vm.serializeString( - parent_object, - deployed_addresses, - deployed_addresses_output - ); - - writeOutput(finalJson, "hello_world_avs_deployment_output"); + require(coreDeployment.avsDirectory != address(0), "AVSDirectory address cannot be zero"); } } diff --git a/contracts/script/HoleskyDeployer.s.sol b/contracts/script/HoleskyDeployer.s.sol deleted file mode 100644 index 88149f54..00000000 --- a/contracts/script/HoleskyDeployer.s.sol +++ /dev/null @@ -1,200 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import "@eigenlayer/contracts/permissions/PauserRegistry.sol"; -import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; -import {IAVSDirectory} from "@eigenlayer/contracts/interfaces/IAVSDirectory.sol"; -import {IStrategyManager, IStrategy} from "@eigenlayer/contracts/interfaces/IStrategyManager.sol"; -import {StrategyBase} from "@eigenlayer/contracts/strategies/StrategyBase.sol"; -import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; -import {Quorum, StrategyParams} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; -import {HelloWorldServiceManager} from "../src/HelloWorldServiceManager.sol"; -import "@eigenlayer/test/mocks/EmptyContract.sol"; -import "../src/ERC20Mock.sol"; -import "forge-std/Script.sol"; -import "forge-std/StdJson.sol"; -import "forge-std/console.sol"; -import {Utils} from "./utils/Utils.sol"; - -contract HoleskyDeployer is Script, Utils { - // ERC20 and Strategy: we need to deploy this erc20, create a strategy for it, and whitelist this strategy in the strategy manager - - ERC20Mock public erc20Mock; - StrategyBase public erc20MockStrategy; - - // Hello World contracts - ProxyAdmin public helloWorldProxyAdmin; - PauserRegistry public helloWorldPauserReg; - - ECDSAStakeRegistry public stakeRegistryProxy; - ECDSAStakeRegistry public stakeRegistryImplementation; - - HelloWorldServiceManager public helloWorldServiceManagerProxy; - HelloWorldServiceManager public helloWorldServiceManagerImplementation; - - function run() external { - // Manually pasted addresses of Eigenlayer contracts - address strategyManagerAddr = 0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6; - address delegationManagerAddr = 0xA44151489861Fe9e3055d95adC98FbD462B948e7; - address avsDirectoryAddr = 0x055733000064333CaDDbC92763c58BF0192fFeBf; - address eigenLayerProxyAdminAddr = 0xDB023566064246399b4AE851197a97729C93A6cf; - address eigenLayerPauserRegAddr = 0x85Ef7299F8311B25642679edBF02B62FA2212F06; - address baseStrategyImplementationAddr = 0xFb83e1D133D0157775eC4F19Ff81478Df1103305; - - IStrategyManager strategyManager = IStrategyManager(strategyManagerAddr); - IDelegationManager delegationManager = IDelegationManager(delegationManagerAddr); - IAVSDirectory avsDirectory = IAVSDirectory(avsDirectoryAddr); - ProxyAdmin eigenLayerProxyAdmin = ProxyAdmin(eigenLayerProxyAdminAddr); - PauserRegistry eigenLayerPauserReg = PauserRegistry(eigenLayerPauserRegAddr); - StrategyBase baseStrategyImplementation = StrategyBase(baseStrategyImplementationAddr); - - address helloWorldCommunityMultisig = msg.sender; - address helloWorldPauser = msg.sender; - - vm.startBroadcast(); - _deployHelloWorldContracts( - delegationManager, - avsDirectory, - baseStrategyImplementation, - helloWorldCommunityMultisig, - helloWorldPauser - ); - vm.stopBroadcast(); - } - - function _deployHelloWorldContracts( - IDelegationManager delegationManager, - IAVSDirectory avsDirectory, - IStrategy baseStrategyImplementation, - address helloWorldCommunityMultisig, - address helloWorldPauser - ) internal { - // Deploy proxy admin for ability to upgrade proxy contracts - helloWorldProxyAdmin = new ProxyAdmin(); - - // Deploy pauser registry - { - address[] memory pausers = new address[](2); - pausers[0] = helloWorldPauser; - pausers[1] = helloWorldCommunityMultisig; - helloWorldPauserReg = new PauserRegistry( - pausers, - helloWorldCommunityMultisig - ); - } - - EmptyContract emptyContract = new EmptyContract(); - - // First, deploy upgradeable proxy contracts that will point to the implementations. - helloWorldServiceManagerProxy = HelloWorldServiceManager( - address( - new TransparentUpgradeableProxy( - address(emptyContract), - address(helloWorldProxyAdmin), - "" - ) - ) - ); - stakeRegistryProxy = ECDSAStakeRegistry( - address( - new TransparentUpgradeableProxy( - address(emptyContract), - address(helloWorldProxyAdmin), - "" - ) - ) - ); - - // Second, deploy the implementation contracts, using the proxy contracts as inputs - { - stakeRegistryImplementation = new ECDSAStakeRegistry( - delegationManager - ); - - helloWorldProxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(stakeRegistryProxy))), - address(stakeRegistryImplementation) - ); - } - - { - // Create an array with one StrategyParams element - StrategyParams memory strategyParams = StrategyParams({ - strategy: baseStrategyImplementation, - multiplier: 10_000 - }); - - StrategyParams[] memory quorumsStrategyParams = new StrategyParams[](1); - quorumsStrategyParams[0] = strategyParams; - - Quorum memory quorum = Quorum( - quorumsStrategyParams - ); - - // Sort the array (though it has only one element, it's trivially sorted) - // If the array had more elements, you would need to ensure it is sorted by strategy address - - helloWorldProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy( - payable(address(stakeRegistryProxy)) - ), - address(stakeRegistryImplementation), - abi.encodeWithSelector( - ECDSAStakeRegistry.initialize.selector, - address(helloWorldServiceManagerProxy), - 1, - quorum - ) - ); - } - - helloWorldServiceManagerImplementation = new HelloWorldServiceManager( - address(avsDirectory), - address(stakeRegistryProxy), - address(delegationManager) - ); - // Upgrade the proxy contracts to use the correct implementation contracts and initialize them. - helloWorldProxyAdmin.upgrade( - TransparentUpgradeableProxy( - payable(address(helloWorldServiceManagerProxy)) - ), - address(helloWorldServiceManagerImplementation) - ); - - // WRITE JSON DATA - string memory parent_object = "parent object"; - - string memory deployed_addresses = "addresses"; - vm.serializeAddress( - deployed_addresses, - "HelloWorldServiceManagerProxy", - address(helloWorldServiceManagerProxy) - ); - vm.serializeAddress( - deployed_addresses, - "HelloWorldServiceManagerImplementation", - address(helloWorldServiceManagerImplementation) - ); - vm.serializeAddress( - deployed_addresses, - "ECDSAStakeRegistry", - address(stakeRegistryProxy) - ); - - string memory deployed_addresses_output = vm.serializeAddress( - deployed_addresses, - "ECDSAStakeRegistryImplementation", - address(stakeRegistryImplementation) - ); - - // Serialize all the data - string memory finalJson = vm.serializeString( - parent_object, - deployed_addresses, - deployed_addresses_output - ); - - writeOutput(finalJson, "hello_world_avs_holesky_deployment_output"); - } -} diff --git a/contracts/script/output/31337/eigenlayer_deployment_output.json b/contracts/script/output/31337/eigenlayer_deployment_output.json deleted file mode 100644 index eaaaa2a0..00000000 --- a/contracts/script/output/31337/eigenlayer_deployment_output.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "addresses": { - "avsDirectory": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", - "avsDirectoryImplementation": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", - "baseStrategyImplementation": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44", - "delayedWithdrawalRouter": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "delayedWithdrawalRouterImplementation": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", - "delegation": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", - "delegationImplementation": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "eigenLayerPauserReg": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", - "eigenLayerProxyAdmin": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "eigenPodBeacon": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "eigenPodImplementation": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - "eigenPodManager": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "eigenPodManagerImplementation": "0x0B306BF915C4d645ff596e518fAf3F9669b97016", - "emptyContract": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", - "slasher": "0x0165878A594ca255338adfa4d48449f69242Eb8F", - "slasherImplementation": "0x9A676e781A523b5d0C0e43731313A708CB607508", - "strategies": "", - "strategyManager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "strategyManagerImplementation": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" - }, - "chainInfo": { - "chainId": 31337, - "deploymentBlock": 0 - }, - "parameters": { - "executorMultisig": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "operationsMultisig": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - } -} \ No newline at end of file diff --git a/contracts/script/output/31337/hello_world_avs_deployment_output.json b/contracts/script/output/31337/hello_world_avs_deployment_output.json deleted file mode 100644 index 73739f86..00000000 --- a/contracts/script/output/31337/hello_world_avs_deployment_output.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "addresses": { - "ECDSAStakeRegistry": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "ECDSAStakeRegistryImplementation": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "HelloWorldServiceManagerImplementation": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "HelloWorldServiceManagerProxy": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", - "erc20Mock": "0x0000000000000000000000000000000000000000", - "erc20MockStrategy": "0x0000000000000000000000000000000000000000" - } -} \ No newline at end of file diff --git a/contracts/script/output/31337/hello_world_avs_holesky_deployment_output.json b/contracts/script/output/31337/hello_world_avs_holesky_deployment_output.json deleted file mode 100644 index 65870e7e..00000000 --- a/contracts/script/output/31337/hello_world_avs_holesky_deployment_output.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "addresses": { - "ECDSAStakeRegistry": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "ECDSAStakeRegistryImplementation": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "HelloWorldServiceManagerImplementation": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "HelloWorldServiceManagerProxy": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76" - } -} \ No newline at end of file diff --git a/contracts/script/utils/CoreDeploymentLib.sol b/contracts/script/utils/CoreDeploymentLib.sol new file mode 100644 index 00000000..33db918f --- /dev/null +++ b/contracts/script/utils/CoreDeploymentLib.sol @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; +import {console2} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; +import {stdJson} from "forge-std/StdJson.sol"; +import {DelegationManager} from "@eigenlayer/contracts/core/DelegationManager.sol"; +import {StrategyManager} from "@eigenlayer/contracts/core/StrategyManager.sol"; +import {AVSDirectory} from "@eigenlayer/contracts/core/AVSDirectory.sol"; +import {Slasher} from "@eigenlayer/contracts/core/Slasher.sol"; +import {EigenPodManager} from "@eigenlayer/contracts/pods/EigenPodManager.sol"; +import {RewardsCoordinator} from "@eigenlayer/contracts/core/RewardsCoordinator.sol"; +import {StrategyBase} from "@eigenlayer/contracts/strategies/StrategyBase.sol"; +import {EigenPod} from "@eigenlayer/contracts/pods/EigenPod.sol"; +import {IETHPOSDeposit} from "@eigenlayer/contracts/interfaces/IETHPOSDeposit.sol"; +import {StrategyBaseTVLLimits} from "@eigenlayer/contracts/strategies/StrategyBaseTVLLimits.sol"; +import {PauserRegistry} from "@eigenlayer/contracts/permissions/PauserRegistry.sol"; +import {IStrategy} from "@eigenlayer/contracts/interfaces/IStrategy.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ISignatureUtils} from "@eigenlayer/contracts/interfaces/ISignatureUtils.sol"; +import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; +import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; +import {IStrategyManager} from "@eigenlayer/contracts/interfaces/IStrategyManager.sol"; +import {ISlasher} from "@eigenlayer/contracts/interfaces/ISlasher.sol"; +import {IEigenPodManager} from "@eigenlayer/contracts/interfaces/IEigenPodManager.sol"; +import {IAVSDirectory} from "@eigenlayer/contracts/interfaces/IAVSDirectory.sol"; +import {IPauserRegistry} from "@eigenlayer/contracts/interfaces/IPauserRegistry.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; + +import {UpgradeableProxyLib} from "./UpgradeableProxyLib.sol"; + +library CoreDeploymentLib { + using stdJson for *; + using Strings for *; + using UpgradeableProxyLib for address; + + Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + struct StrategyManagerConfig { + uint256 initPausedStatus; + uint256 initWithdrawalDelayBlocks; + } + + struct SlasherConfig { + uint256 initPausedStatus; + } + + struct DelegationManagerConfig { + uint256 initPausedStatus; + uint256 withdrawalDelayBlocks; + } + + struct EigenPodManagerConfig { + uint256 initPausedStatus; + } + + struct RewardsCoordinatorConfig { + uint256 initPausedStatus; + uint256 maxRewardsDuration; + uint256 maxRetroactiveLength; + uint256 maxFutureLength; + uint256 genesisRewardsTimestamp; + address updater; + uint256 activationDelay; + uint256 calculationIntervalSeconds; + uint256 globalOperatorCommissionBips; + } + + struct DeploymentData { + address delegationManager; + address avsDirectory; + address wethStrategy; + address strategyManager; + address eigenPodManager; + address rewardsCoordinator; + address eigenPodBeacon; + address pauserRegistry; + } + + function deployContracts( + address proxyAdmin, + DeploymentConfigData memory configData + ) internal returns (DeploymentData memory) { + DeploymentData memory result; + + result.delegationManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.avsDirectory = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.strategyManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.eigenPodManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.rewardsCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.eigenPodBeacon = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.pauserRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + + // Deploy the implementation contracts, using the proxy contracts as inputs + address delegationManagerImpl = address( + new DelegationManager( + IStrategyManager(result.strategyManager), + ISlasher(address(0)), + IEigenPodManager(result.eigenPodManager) + ) + ); + address avsDirectoryImpl = + address(new AVSDirectory(IDelegationManager(result.delegationManager))); + + address strategyManagerImpl = address( + new StrategyManager( + IDelegationManager(result.delegationManager), + IEigenPodManager(result.eigenPodManager), + ISlasher(address(0)) + ) + ); + + address ethPOSDeposit; + if (block.chainid == 1) { + ethPOSDeposit = 0x00000000219ab540356cBB839Cbe05303d7705Fa; + } else { + // For non-mainnet chains, you might want to deploy a mock or read from a config + // This assumes you have a similar config setup as in M2_Deploy_From_Scratch.s.sol + /// TODO: Handle Eth pos + } + + address eigenPodManagerImpl = address( + new EigenPodManager( + IETHPOSDeposit(ethPOSDeposit), + IBeacon(result.eigenPodBeacon), + IStrategyManager(result.strategyManager), + ISlasher(address(0)), + IDelegationManager(result.delegationManager) + ) + ); + + /// TODO: Get actual values + uint32 CALCULATION_INTERVAL_SECONDS = 10 days; + uint32 MAX_REWARDS_DURATION = 10; + uint32 MAX_RETROACTIVE_LENGTH = 1; + uint32 MAX_FUTURE_LENGTH = 1; + uint32 GENESIS_REWARDS_TIMESTAMP = 100 days; + address rewardsCoordinatorImpl = address( + new RewardsCoordinator( + IDelegationManager(result.delegationManager), + IStrategyManager(result.strategyManager), + CALCULATION_INTERVAL_SECONDS, + MAX_REWARDS_DURATION, + MAX_RETROACTIVE_LENGTH, + MAX_FUTURE_LENGTH, + GENESIS_REWARDS_TIMESTAMP + ) + ); + + /// TODO: Get actual genesis time + uint64 GENESIS_TIME = 1_564_000; + + address eigenPodImpl = address( + new EigenPod( + IETHPOSDeposit(ethPOSDeposit), + IEigenPodManager(result.eigenPodManager), + GENESIS_TIME + ) + ); + address eigenPodBeaconImpl = address(new UpgradeableBeacon(eigenPodImpl)); + address baseStrategyImpl = + address(new StrategyBaseTVLLimits(IStrategyManager(result.strategyManager))); + /// TODO: PauserRegistry isn't upgradeable + address pauserRegistryImpl = address( + new PauserRegistry( + new address[](0), // Empty array for pausers + proxyAdmin // ProxyAdmin as the unpauser + ) + ); + // Upgrade contracts + /// TODO: Get from config + bytes memory upgradeCall = abi.encodeCall( + DelegationManager.initialize, + ( + proxyAdmin, // initialOwner + IPauserRegistry(result.pauserRegistry), // _pauserRegistry + configData.delegationManager.initPausedStatus, // initialPausedStatus + configData.delegationManager.withdrawalDelayBlocks, // _minWithdrawalDelayBlocks + new IStrategy[](0), // _strategies (empty array for now) + new uint256[](0) // _withdrawalDelayBlocks (empty array for now) + ) + ); + UpgradeableProxyLib.upgradeAndCall( + result.delegationManager, delegationManagerImpl, upgradeCall + ); + + // Upgrade StrategyManager contract + upgradeCall = abi.encodeCall( + StrategyManager.initialize, + ( + proxyAdmin, // initialOwner + address(this), // initialStrategyWhitelister + IPauserRegistry(result.pauserRegistry), // _pauserRegistry + configData.strategyManager.initPausedStatus // initialPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.strategyManager, strategyManagerImpl, upgradeCall); + + // Upgrade EigenPodManager contract + upgradeCall = abi.encodeCall( + EigenPodManager.initialize, + ( + proxyAdmin, // initialOwner + IPauserRegistry(result.pauserRegistry), // _pauserRegistry + configData.eigenPodManager.initPausedStatus // initialPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.eigenPodManager, eigenPodManagerImpl, upgradeCall); + + // Upgrade AVSDirectory contract + upgradeCall = abi.encodeCall( + AVSDirectory.initialize, + ( + proxyAdmin, // initialOwner + IPauserRegistry(result.pauserRegistry), // _pauserRegistry + 0 // TODO: AVS Missing configinitialPausedStatus + ) + ); + UpgradeableProxyLib.upgradeAndCall(result.avsDirectory, avsDirectoryImpl, upgradeCall); + + // Upgrade RewardsCoordinator contract + upgradeCall = abi.encodeCall( + RewardsCoordinator.initialize, + ( + proxyAdmin, // initialOwner + IPauserRegistry(result.pauserRegistry), // _pauserRegistry + configData.rewardsCoordinator.initPausedStatus, // initialPausedStatus + /// TODO: is there a setter and is this expected? + address(0), // rewards updater + uint32(configData.rewardsCoordinator.activationDelay), // _activationDelay + uint16(configData.rewardsCoordinator.globalOperatorCommissionBips) // _globalCommissionBips + ) + ); + UpgradeableProxyLib.upgradeAndCall( + result.rewardsCoordinator, rewardsCoordinatorImpl, upgradeCall + ); + + // Upgrade EigenPod contract + upgradeCall = abi.encodeCall( + EigenPod.initialize, + // TODO: Double check this + (address(result.eigenPodManager)) // _podOwner + ); + UpgradeableProxyLib.upgradeAndCall(result.eigenPodBeacon, eigenPodImpl, upgradeCall); + + return result; + } + + struct DeploymentConfigData { + StrategyManagerConfig strategyManager; + DelegationManagerConfig delegationManager; + SlasherConfig slasher; + EigenPodManagerConfig eigenPodManager; + RewardsCoordinatorConfig rewardsCoordinator; + } + // StrategyConfig[] strategies; + + function readDeploymentConfigValues( + string memory directoryPath, + string memory fileName + ) internal returns (DeploymentConfigData memory) { + string memory pathToFile = string.concat(directoryPath, fileName); + + require(vm.exists(pathToFile), "Deployment file does not exist"); + + string memory json = vm.readFile(pathToFile); + + DeploymentConfigData memory data; + + // StrategyManager start + data.strategyManager.initPausedStatus = json.readUint(".strategyManager.init_paused_status"); + data.strategyManager.initWithdrawalDelayBlocks = + uint32(json.readUint(".strategyManager.init_withdrawal_delay_blocks")); + // slasher config end + + // DelegationManager config start + data.delegationManager.initPausedStatus = json.readUint(".delegation.init_paused_status"); + data.delegationManager.withdrawalDelayBlocks = + json.readUint(".delegation.init_withdrawal_delay_blocks"); + // DelegationManager config end + + // Slasher config start + data.slasher.initPausedStatus = json.readUint(".slasher.init_paused_status"); + + // Slasher config end + + // EigenPodManager config start + data.eigenPodManager.initPausedStatus = json.readUint(".eigenPodManager.init_paused_status"); + // EigenPodManager config end + + // RewardsCoordinator config start + data.rewardsCoordinator.initPausedStatus = + json.readUint(".rewardsCoordinator.init_paused_status"); + data.rewardsCoordinator.maxRewardsDuration = + json.readUint(".rewardsCoordinator.MAX_REWARDS_DURATION"); + data.rewardsCoordinator.maxRetroactiveLength = + json.readUint(".rewardsCoordinator.MAX_RETROACTIVE_LENGTH"); + data.rewardsCoordinator.maxFutureLength = + json.readUint(".rewardsCoordinator.MAX_FUTURE_LENGTH"); + data.rewardsCoordinator.genesisRewardsTimestamp = + json.readUint(".rewardsCoordinator.GENESIS_REWARDS_TIMESTAMP"); + data.rewardsCoordinator.updater = + json.readAddress(".rewardsCoordinator.rewards_updater_address"); + data.rewardsCoordinator.activationDelay = + json.readUint(".rewardsCoordinator.activation_delay"); + data.rewardsCoordinator.calculationIntervalSeconds = + json.readUint(".rewardsCoordinator.calculation_interval_seconds"); + data.rewardsCoordinator.globalOperatorCommissionBips = + json.readUint(".rewardsCoordinator.global_operator_commission_bips"); + // RewardsCoordinator config end + + return data; + } + + function readDeploymentConfigValues( + string memory directoryPath, + uint256 chainId + ) internal returns (DeploymentConfigData memory) { + return + readDeploymentConfigValues(directoryPath, string.concat(vm.toString(chainId), ".json")); + } + + function readDeploymentJson( + string memory directoryPath, + uint256 chainId + ) internal returns (DeploymentData memory) { + return readDeploymentJson(directoryPath, string.concat(vm.toString(chainId), ".json")); + } + + function readDeploymentJson( + string memory path, + string memory fileName + ) internal returns (DeploymentData memory) { + string memory pathToFile = string.concat(path, fileName); + + require(vm.exists(pathToFile), "Deployment file does not exist"); + + string memory json = vm.readFile(pathToFile); + + DeploymentData memory data; + data.strategyManager = json.readAddress(".addresses.strategyManager"); + data.eigenPodManager = json.readAddress(".addresses.eigenPodManager"); + data.delegationManager = json.readAddress(".addresses.delegation"); + data.avsDirectory = json.readAddress(".addresses.avsDirectory"); + + return data; + } + + /// TODO: Need to be able to read json from eigenlayer-contracts repo for holesky/mainnet and output the json here + function writeDeploymentJson( + DeploymentData memory data + ) internal { + writeDeploymentJson("deployments/core/", block.chainid, data); + } + + function writeDeploymentJson( + string memory path, + uint256 chainId, + DeploymentData memory data + ) internal { + address proxyAdmin = address(UpgradeableProxyLib.getProxyAdmin(data.strategyManager)); + + string memory deploymentData = _generateDeploymentJson(data, proxyAdmin); + + string memory fileName = string.concat(path, vm.toString(chainId), ".json"); + if (!vm.exists(path)) { + vm.createDir(path, true); + } + + vm.writeFile(fileName, deploymentData); + console2.log("Deployment artifacts written to:", fileName); + } + + function _generateDeploymentJson( + DeploymentData memory data, + address proxyAdmin + ) private view returns (string memory) { + return string.concat( + '{"lastUpdate":{"timestamp":"', + vm.toString(block.timestamp), + '","block_number":"', + vm.toString(block.number), + '"},"addresses":', + _generateContractsJson(data, proxyAdmin), + "}" + ); + } + + function _generateContractsJson( + DeploymentData memory data, + address proxyAdmin + ) private view returns (string memory) { + /// TODO: namespace contracts -> {avs, core} + return string.concat( + '{"proxyAdmin":"', + proxyAdmin.toHexString(), + '","delegation":"', + data.delegationManager.toHexString(), + '","delegationManagerImpl":"', + data.delegationManager.getImplementation().toHexString(), + '","avsDirectory":"', + data.avsDirectory.toHexString(), + '","avsDirectoryImpl":"', + data.avsDirectory.getImplementation().toHexString(), + '","strategyManager":"', + data.strategyManager.toHexString(), + '","strategyManagerImpl":"', + data.strategyManager.getImplementation().toHexString(), + '","eigenPodManager":"', + data.eigenPodManager.toHexString(), + '","eigenPodManagerImpl":"', + data.eigenPodManager.getImplementation().toHexString(), + '"}' + ); + } +} diff --git a/contracts/script/utils/HelloWorldDeploymentLib.sol b/contracts/script/utils/HelloWorldDeploymentLib.sol new file mode 100644 index 00000000..874fa9f3 --- /dev/null +++ b/contracts/script/utils/HelloWorldDeploymentLib.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {Script} from "forge-std/Script.sol"; +import {console2} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; +import {stdJson} from "forge-std/StdJson.sol"; +import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; +import {HelloWorldServiceManager} from "../../src/HelloWorldServiceManager.sol"; +import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; +import {Quorum} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; +import {UpgradeableProxyLib} from "./UpgradeableProxyLib.sol"; +import {CoreDeploymentLib} from "./CoreDeploymentLib.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; + +library HelloWorldDeploymentLib { + using stdJson for *; + using Strings for *; + using UpgradeableProxyLib for address; + + Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + struct DeploymentData { + address helloWorldServiceManager; + address stakeRegistry; + address wethStrategy; + } + + function deployContracts( + address proxyAdmin, + CoreDeploymentLib.DeploymentData memory core, + Quorum memory quorum + ) internal returns (DeploymentData memory) { + DeploymentData memory result; + + // First, deploy upgradeable proxy contracts that will point to the implementations. + result.helloWorldServiceManager = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + result.stakeRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + // Deploy the implementation contracts, using the proxy contracts as inputs + address stakeRegistryImpl = + address(new ECDSAStakeRegistry(IDelegationManager(core.delegationManager))); + address helloWorldServiceManagerImpl = address( + new HelloWorldServiceManager( + core.avsDirectory, result.stakeRegistry, core.delegationManager + ) + ); + // Upgrade contracts + bytes memory upgradeCall = abi.encodeCall( + ECDSAStakeRegistry.initialize, (result.helloWorldServiceManager, 1, quorum) + ); + UpgradeableProxyLib.upgradeAndCall(result.stakeRegistry, stakeRegistryImpl, upgradeCall); + UpgradeableProxyLib.upgrade(result.helloWorldServiceManager, helloWorldServiceManagerImpl); + + result.wethStrategy = address(quorum.strategies[0].strategy); + + return result; + } + + function readDeploymentJson( + uint256 chainId + ) internal returns (DeploymentData memory) { + return readDeploymentJson("deployments/", chainId); + } + + function readDeploymentJson( + string memory directoryPath, + uint256 chainId + ) internal returns (DeploymentData memory) { + string memory fileName = string.concat(directoryPath, vm.toString(chainId), ".json"); + + require(vm.exists(fileName), "Deployment file does not exist"); + + string memory json = vm.readFile(fileName); + + DeploymentData memory data; + /// TODO: 2 Step for reading deployment json. Read to the core and the AVS data + data.helloWorldServiceManager = json.readAddress(".contracts.helloWorldServiceManager"); + data.stakeRegistry = json.readAddress(".contracts.stakeRegistry"); + data.wethStrategy = json.readAddress(".contracts.wethStrategy"); + + return data; + } + + /// write to default output path + function writeDeploymentJson( + DeploymentData memory data + ) internal { + writeDeploymentJson("deployments/hello-world/", block.chainid, data); + } + + function writeDeploymentJson( + string memory outputPath, + uint256 chainId, + DeploymentData memory data + ) internal { + address proxyAdmin = + address(UpgradeableProxyLib.getProxyAdmin(data.helloWorldServiceManager)); + + string memory deploymentData = _generateDeploymentJson(data, proxyAdmin); + + string memory fileName = string.concat(outputPath, vm.toString(chainId), ".json"); + if (!vm.exists(outputPath)) { + vm.createDir(outputPath, true); + } + + vm.writeFile(fileName, deploymentData); + console2.log("Deployment artifacts written to:", fileName); + } + + function _generateDeploymentJson( + DeploymentData memory data, + address proxyAdmin + ) private view returns (string memory) { + return string.concat( + '{"lastUpdate":{"timestamp":"', + vm.toString(block.timestamp), + '","block_number":"', + vm.toString(block.number), + '"},"addresses":', + _generateContractsJson(data, proxyAdmin), + "}" + ); + } + + function _generateContractsJson( + DeploymentData memory data, + address proxyAdmin + ) private view returns (string memory) { + return string.concat( + '{"proxyAdmin":"', + proxyAdmin.toHexString(), + '","helloWorldServiceManager":"', + data.helloWorldServiceManager.toHexString(), + '","helloWorldServiceManagerImpl":"', + data.helloWorldServiceManager.getImplementation().toHexString(), + '","stakeRegistry":"', + data.stakeRegistry.toHexString(), + '","stakeRegistryImpl":"', + data.stakeRegistry.getImplementation().toHexString(), + /// TODO: Should be quorum info vs hardcoding a strategy + '","wethStrategy":"', + data.wethStrategy.toHexString(), + '"}' + ); + } +} diff --git a/contracts/script/utils/UpgradeableProxyLib.sol b/contracts/script/utils/UpgradeableProxyLib.sol new file mode 100644 index 00000000..56bdae5d --- /dev/null +++ b/contracts/script/utils/UpgradeableProxyLib.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {Vm} from "forge-std/Vm.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {EmptyContract} from "@eigenlayer/test/mocks/EmptyContract.sol"; + +library UpgradeableProxyLib { + bytes32 internal constant IMPLEMENTATION_SLOT = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + bytes32 internal constant ADMIN_SLOT = + 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function deployProxyAdmin() internal returns (address) { + return address(new ProxyAdmin()); + } + + function setUpEmptyProxy( + address admin + ) internal returns (address) { + address emptyContract = address(new EmptyContract()); + return address(new TransparentUpgradeableProxy(emptyContract, admin, "")); + } + + function upgrade(address proxy, address impl) internal { + ProxyAdmin admin = getProxyAdmin(proxy); + admin.upgrade(TransparentUpgradeableProxy(payable(proxy)), impl); + } + + function upgradeAndCall(address proxy, address impl, bytes memory initData) internal { + ProxyAdmin admin = getProxyAdmin(proxy); + admin.upgradeAndCall(TransparentUpgradeableProxy(payable(proxy)), impl, initData); + } + + function getImplementation( + address proxy + ) internal view returns (address) { + bytes32 value = vm.load(proxy, IMPLEMENTATION_SLOT); + return address(uint160(uint256(value))); + } + + function getProxyAdmin( + address proxy + ) internal view returns (ProxyAdmin) { + bytes32 value = vm.load(proxy, ADMIN_SLOT); + return ProxyAdmin(address(uint160(uint256(value)))); + } +} diff --git a/contracts/script/utils/Utils.sol b/contracts/script/utils/Utils.sol index aeaa0f0b..2cf98704 100644 --- a/contracts/script/utils/Utils.sol +++ b/contracts/script/utils/Utils.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.12; import "@eigenlayer-middleware/src/interfaces/IRegistryCoordinator.sol"; import "@eigenlayer/contracts/strategies/StrategyBase.sol"; -import "../../src/ERC20Mock.sol"; +import "../../test/ERC20Mock.sol"; import "forge-std/Script.sol"; import "forge-std/StdJson.sol"; @@ -16,9 +16,8 @@ contract Utils is Script { uint256[] memory amounts ) internal { for (uint256 i = 0; i < tos.length; i++) { - ERC20Mock underlyingToken = ERC20Mock( - address(StrategyBase(strategyAddress).underlyingToken()) - ); + ERC20Mock underlyingToken = + ERC20Mock(address(StrategyBase(strategyAddress).underlyingToken())); underlyingToken.mint(tos[i], amounts[i]); } } @@ -36,18 +35,11 @@ contract Utils is Script { function convertOperatorStatusToString( IRegistryCoordinator.OperatorStatus operatorStatus ) public pure returns (string memory) { - if ( - operatorStatus == - IRegistryCoordinator.OperatorStatus.NEVER_REGISTERED - ) { + if (operatorStatus == IRegistryCoordinator.OperatorStatus.NEVER_REGISTERED) { return "NEVER_REGISTERED"; - } else if ( - operatorStatus == IRegistryCoordinator.OperatorStatus.REGISTERED - ) { + } else if (operatorStatus == IRegistryCoordinator.OperatorStatus.REGISTERED) { return "REGISTERED"; - } else if ( - operatorStatus == IRegistryCoordinator.OperatorStatus.DEREGISTERED - ) { + } else if (operatorStatus == IRegistryCoordinator.OperatorStatus.DEREGISTERED) { return "DEREGISTERED"; } else { return "UNKNOWN"; @@ -58,10 +50,7 @@ contract Utils is Script { function readInput( string memory inputFileName ) internal view returns (string memory) { - string memory inputDir = string.concat( - vm.projectRoot(), - "/script/input/" - ); + string memory inputDir = string.concat(vm.projectRoot(), "/script/input/"); string memory chainDir = string.concat(vm.toString(block.chainid), "/"); string memory file = string.concat(inputFileName, ".json"); return vm.readFile(string.concat(inputDir, chainDir, file)); @@ -70,30 +59,16 @@ contract Utils is Script { function readOutput( string memory outputFileName ) internal view returns (string memory) { - string memory inputDir = string.concat( - vm.projectRoot(), - "/script/output/" - ); + string memory inputDir = string.concat(vm.projectRoot(), "/script/output/"); string memory chainDir = string.concat(vm.toString(block.chainid), "/"); string memory file = string.concat(outputFileName, ".json"); return vm.readFile(string.concat(inputDir, chainDir, file)); } - function writeOutput( - string memory outputJson, - string memory outputFileName - ) internal { - string memory outputDir = string.concat( - vm.projectRoot(), - "/script/output/" - ); + function writeOutput(string memory outputJson, string memory outputFileName) internal { + string memory outputDir = string.concat(vm.projectRoot(), "/script/output/"); string memory chainDir = string.concat(vm.toString(block.chainid), "/"); - string memory outputFilePath = string.concat( - outputDir, - chainDir, - outputFileName, - ".json" - ); + string memory outputFilePath = string.concat(outputDir, chainDir, outputFileName, ".json"); vm.writeJson(outputJson, outputFilePath); } } diff --git a/contracts/src/HelloWorldServiceManager.sol b/contracts/src/HelloWorldServiceManager.sol index 6741bfac..b09d80d4 100644 --- a/contracts/src/HelloWorldServiceManager.sol +++ b/contracts/src/HelloWorldServiceManager.sol @@ -1,25 +1,19 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; -import "@eigenlayer/contracts/libraries/BytesLib.sol"; -import "@eigenlayer/contracts/core/DelegationManager.sol"; -import "@eigenlayer-middleware/src/unaudited/ECDSAServiceManagerBase.sol"; -import "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; -import "@openzeppelin-upgrades/contracts/utils/cryptography/ECDSAUpgradeable.sol"; -import "@eigenlayer/contracts/permissions/Pausable.sol"; -import {IRegistryCoordinator} from "@eigenlayer-middleware/src/interfaces/IRegistryCoordinator.sol"; -import "./IHelloWorldServiceManager.sol"; +import {ECDSAServiceManagerBase} from + "@eigenlayer-middleware/src/unaudited/ECDSAServiceManagerBase.sol"; +import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; +import {IServiceManager} from "@eigenlayer-middleware/src/interfaces/IServiceManager.sol"; +import {ECDSAUpgradeable} from + "@openzeppelin-upgrades/contracts/utils/cryptography/ECDSAUpgradeable.sol"; +import {IHelloWorldServiceManager} from "./IHelloWorldServiceManager.sol"; /** * @title Primary entrypoint for procuring services from HelloWorld. * @author Eigen Labs, Inc. */ -contract HelloWorldServiceManager is - ECDSAServiceManagerBase, - IHelloWorldServiceManager, - Pausable -{ - using BytesLib for bytes; +contract HelloWorldServiceManager is ECDSAServiceManagerBase, IHelloWorldServiceManager { using ECDSAUpgradeable for bytes32; /* STORAGE */ @@ -38,9 +32,7 @@ contract HelloWorldServiceManager is /* MODIFIERS */ modifier onlyOperator() { require( - ECDSAStakeRegistry(stakeRegistry).operatorRegistered(msg.sender) - == - true, + ECDSAStakeRegistry(stakeRegistry).operatorRegistered(msg.sender), "Operator must be the caller" ); _; @@ -59,7 +51,6 @@ contract HelloWorldServiceManager is ) {} - /* FUNCTIONS */ // NOTE: this function creates new task, assigns it a taskId function createNewTask( @@ -88,8 +79,7 @@ contract HelloWorldServiceManager is ); // check that the task is valid, hasn't been responsed yet, and is being responded in time require( - keccak256(abi.encode(task)) == - allTaskHashes[referenceTaskIndex], + keccak256(abi.encode(task)) == allTaskHashes[referenceTaskIndex], "supplied task does not match the one recorded in the contract" ); // some logical checks @@ -116,7 +106,10 @@ contract HelloWorldServiceManager is // HELPER - function operatorHasMinimumWeight(address operator) public view returns (bool) { - return ECDSAStakeRegistry(stakeRegistry).getOperatorWeight(operator) >= ECDSAStakeRegistry(stakeRegistry).minimumWeight(); + function operatorHasMinimumWeight( + address operator + ) public view returns (bool) { + return ECDSAStakeRegistry(stakeRegistry).getOperatorWeight(operator) + >= ECDSAStakeRegistry(stakeRegistry).minimumWeight(); } -} \ No newline at end of file +} diff --git a/contracts/src/IHelloWorldServiceManager.sol b/contracts/src/IHelloWorldServiceManager.sol index 33bc8855..22b51bb8 100644 --- a/contracts/src/IHelloWorldServiceManager.sol +++ b/contracts/src/IHelloWorldServiceManager.sol @@ -25,4 +25,4 @@ interface IHelloWorldServiceManager { uint32 referenceTaskIndex, bytes calldata signature ) external; -} \ No newline at end of file +} diff --git a/contracts/test/CoreDeploymentLib.t.sol b/contracts/test/CoreDeploymentLib.t.sol new file mode 100644 index 00000000..4ffa79ac --- /dev/null +++ b/contracts/test/CoreDeploymentLib.t.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {Test} from "forge-std/Test.sol"; +import {console2} from "forge-std/console2.sol"; +import {CoreDeploymentLib} from "../script/utils/CoreDeploymentLib.sol"; +import {UpgradeableProxyLib} from "../script/utils/UpgradeableProxyLib.sol"; + +contract CoreDeploymentLibTest is Test { + using CoreDeploymentLib for *; + using UpgradeableProxyLib for address; + + address proxyAdmin; + CoreDeploymentLib.DeploymentData deploymentData; + CoreDeploymentLib.DeploymentConfigData configData; + + function setUp() public { + proxyAdmin = UpgradeableProxyLib.deployProxyAdmin(); + } + + /// won't test specific functionality/values. Testing behavior of the library + function test_ReadConfig() public { + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/config/core/", 1337); + } + + function test_ReadConfig_Reverts() public { + vm.expectRevert(); + /// Incorrect path + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/deployments/core/", 1337); + } + + function test_ReadDeployment() public { + CoreDeploymentLib.readDeploymentJson("test/mockData/deployments/core/", 1337); + } + + function test_ReadDeployment_Reverts() public { + vm.expectRevert(); + /// Incorrect path + CoreDeploymentLib.readDeploymentJson("test/mockData/config/core/", 1337); + } + + function test_DeployContracts() public { + configData = + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/config/core/", 1337); + CoreDeploymentLib.DeploymentData memory data = + CoreDeploymentLib.deployContracts(proxyAdmin, configData); + + assertTrue(data.delegationManager != address(0), "DelegationManager not deployed"); + assertTrue(data.avsDirectory != address(0), "AVSDirectory not deployed"); + assertTrue(data.strategyManager != address(0), "StrategyManager not deployed"); + } + + function test_WriteDeploymentJson() public { + configData = + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/config/core/", 1337); + CoreDeploymentLib.DeploymentData memory data = + CoreDeploymentLib.deployContracts(proxyAdmin, configData); + + string memory scratchPath = "test/mockData/scratch/"; + CoreDeploymentLib.writeDeploymentJson(scratchPath, block.chainid, data); + + string memory fileName = string.concat(scratchPath, vm.toString(block.chainid), ".json"); + assertTrue(vm.exists(fileName), "Deployment file not created"); + } + + function test_WriteAndReadDeploymentJson() public { + configData = + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/config/core/", 1337); + CoreDeploymentLib.DeploymentData memory initialData = + CoreDeploymentLib.deployContracts(proxyAdmin, configData); + + string memory scratchPath = "test/mockData/scratch/"; + + CoreDeploymentLib.writeDeploymentJson(scratchPath, block.chainid, initialData); + + string memory fileName = string.concat(vm.toString(block.chainid), ".json"); + + CoreDeploymentLib.readDeploymentJson(scratchPath, fileName); + } + + function test_ReadConfigFromM2DeploymentData() public { + // Path to the M2 deployment data JSON file + string memory m2DeploymentDataPath = + "lib/eigenlayer-middleware/lib/eigenlayer-contracts/script/output/devnet/"; + string memory m2DeploymentFilename = "M2_from_scratch_deployment_data.json"; + + CoreDeploymentLib.readDeploymentJson(m2DeploymentDataPath, m2DeploymentFilename); + } +} diff --git a/contracts/src/ERC20Mock.sol b/contracts/test/ERC20Mock.sol similarity index 89% rename from contracts/src/ERC20Mock.sol rename to contracts/test/ERC20Mock.sol index 0fc4c3c1..ca4a9021 100644 --- a/contracts/src/ERC20Mock.sol +++ b/contracts/test/ERC20Mock.sol @@ -69,10 +69,7 @@ contract ERC20Mock is Context, IERC20 { * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ - function transfer( - address to, - uint256 amount - ) public virtual override returns (bool) { + function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; @@ -99,7 +96,7 @@ contract ERC20Mock is Context, IERC20 { * - `spender` cannot be the zero address. */ function approve( - address /*spender*/, + address, /*spender*/ uint256 /*amount*/ ) public virtual override returns (bool) { return true; @@ -144,20 +141,13 @@ contract ERC20Mock is Context, IERC20 { * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ - function _transfer( - address from, - address to, - uint256 amount - ) internal virtual { + function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); - require( - _balances[from] >= amount, - "ERC20: transfer amount exceeds balance" - ); + require(_balances[from] >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = _balances[from] - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by @@ -170,7 +160,8 @@ contract ERC20Mock is Context, IERC20 { _afterTokenTransfer(from, to, amount); } - /** @dev Creates `amount` tokens and assigns them to `account`, increasing + /** + * @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. @@ -232,11 +223,7 @@ contract ERC20Mock is Context, IERC20 { * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { + function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); @@ -252,17 +239,10 @@ contract ERC20Mock is Context, IERC20 { * * Might emit an {Approval} event. */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { + function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { - require( - currentAllowance >= amount, - "ERC20: insufficient allowance" - ); + require(currentAllowance >= amount, "ERC20: insufficient allowance"); } } @@ -280,11 +260,7 @@ contract ERC20Mock is Context, IERC20 { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes @@ -300,9 +276,5 @@ contract ERC20Mock is Context, IERC20 { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} + function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} } diff --git a/contracts/test/HelloWorldServiceManager.t.sol b/contracts/test/HelloWorldServiceManager.t.sol index 1bd25f57..3c44aebd 100644 --- a/contracts/test/HelloWorldServiceManager.t.sol +++ b/contracts/test/HelloWorldServiceManager.t.sol @@ -1,48 +1,91 @@ -// // SPDX-License-Identifier: UNLICENSED -// pragma solidity ^0.8.12; - -// import "../src/HelloWorldServiceManager.sol" as hwsm; -// import {HelloWorldTaskManager} from "../src/HelloWorldTaskManager.sol"; -// import {MockAVSDeployer} from "@eigenlayer-middleware/test/utils/MockAVSDeployer.sol"; -// import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -// contract HelloWorldTaskManagerTest is MockAVSDeployer { -// incsqsm.HelloWorldServiceManager sm; -// incsqsm.HelloWorldServiceManager smImplementation; -// HelloWorldTaskManager tm; -// HelloWorldTaskManager tmImplementation; - -// address operator = -// address(uint160(uint256(keccak256(abi.encodePacked("operator"))))); -// address generator = -// address(uint160(uint256(keccak256(abi.encodePacked("generator"))))); - -// function setUp() public { -// _setUpBLSMockAVSDeployer(); - -// tmImplementation = new HelloWorldTaskManager( -// incsqsm.IRegistryCoordinator(address(registryCoordinator)) -// ); - -// // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. -// tm = HelloWorldTaskManager( -// address( -// new TransparentUpgradeableProxy( -// address(tmImplementation), -// address(proxyAdmin), -// abi.encodeWithSelector( -// tm.initialize.selector, -// pauserRegistry, -// registryCoordinatorOwner -// ) -// ) -// ) -// ); -// } - -// function testCreateNewTask() public { -// cheats.prank(generator, generator); -// tm.createNewTask("world"); -// assertEq(tm.latestTaskNum(), 1); -// } -// } +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.12; + +import {HelloWorldServiceManager} from "../src/HelloWorldServiceManager.sol"; +import {MockAVSDeployer} from "@eigenlayer-middleware/test/utils/MockAVSDeployer.sol"; +import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStakeRegistry.sol"; +import {Vm} from "forge-std/Vm.sol"; +import {console2} from "forge-std/Test.sol"; +import {HelloWorldDeploymentLib} from "../script/utils/HelloWorldDeploymentLib.sol"; +import {CoreDeploymentLib} from "../script/utils/CoreDeploymentLib.sol"; +import {UpgradeableProxyLib} from "../script/utils/UpgradeableProxyLib.sol"; + +import { + Quorum, + StrategyParams, + IStrategy +} from "@eigenlayer-middleware/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; + +contract HelloWorldTaskManagerSetup is MockAVSDeployer { + Quorum internal quorum; + + struct Operator { + Vm.Wallet key; + Vm.Wallet signingKey; + } + + struct TrafficGenerator { + Vm.Wallet key; + } + + Operator[] internal operators; + TrafficGenerator internal generator; + + HelloWorldDeploymentLib.DeploymentData internal helloWorldDeployment; + CoreDeploymentLib.DeploymentData internal coreDeployment; + CoreDeploymentLib.DeploymentConfigData coreConfigData; + + function setUp() public virtual { + operators.push( + Operator({ + key: vm.createWallet("operator"), + signingKey: vm.createWallet("operator_signing_wallet") + }) + ); + + generator = TrafficGenerator({key: vm.createWallet("generator_wallet")}); + + address proxyAdmin = UpgradeableProxyLib.deployProxyAdmin(); + + coreConfigData = + CoreDeploymentLib.readDeploymentConfigValues("test/mockData/config/core/", 1337); // TODO: Fix this to correct path + coreDeployment = CoreDeploymentLib.deployContracts(proxyAdmin, coreConfigData); + + quorum.strategies.push( + StrategyParams({strategy: IStrategy(address(420)), multiplier: 10_000}) + ); + + helloWorldDeployment = + HelloWorldDeploymentLib.deployContracts(proxyAdmin, coreDeployment, quorum); + labelContracts(coreDeployment, helloWorldDeployment); + } + + function labelContracts( + CoreDeploymentLib.DeploymentData memory coreDeployment, + HelloWorldDeploymentLib.DeploymentData memory helloWorldDeployment + ) internal { + vm.label(coreDeployment.delegationManager, "DelegationManager"); + vm.label(coreDeployment.avsDirectory, "AVSDirectory"); + vm.label(coreDeployment.strategyManager, "StrategyManager"); + vm.label(coreDeployment.eigenPodManager, "EigenPodManager"); + vm.label(coreDeployment.rewardsCoordinator, "RewardsCoordinator"); + vm.label(coreDeployment.eigenPodBeacon, "EigenPodBeacon"); + vm.label(coreDeployment.pauserRegistry, "PauserRegistry"); + vm.label(coreDeployment.wethStrategy, "WETHStrategy"); + + vm.label(helloWorldDeployment.helloWorldServiceManager, "HelloWorldServiceManager"); + vm.label(helloWorldDeployment.stakeRegistry, "StakeRegistry"); + vm.label(helloWorldDeployment.wethStrategy, "WETHStrategy"); + } +} + +contract HelloWorldServiceManagerInitialization is HelloWorldTaskManagerSetup { + function testInitialization() public view { + assertTrue(helloWorldDeployment.stakeRegistry != address(0), "Not deployed"); + assertTrue(helloWorldDeployment.helloWorldServiceManager != address(0), "Not deployed"); + assertTrue(coreDeployment.delegationManager != address(0), "Not deployed"); + assertTrue(coreDeployment.avsDirectory != address(0), "Not deployed"); + assertTrue(coreDeployment.strategyManager != address(0), "Not deployed"); + assertTrue(coreDeployment.eigenPodManager != address(0), "Not deployed"); + } +} diff --git a/contracts/test/mockData/config/core/1337.json b/contracts/test/mockData/config/core/1337.json new file mode 100644 index 00000000..ac7e9710 --- /dev/null +++ b/contracts/test/mockData/config/core/1337.json @@ -0,0 +1,27 @@ +{ + "strategyManager": { + "init_paused_status": 0, + "init_withdrawal_delay_blocks": 50400 + }, + "delegation": { + "init_paused_status": 0, + "init_withdrawal_delay_blocks": 50400 + }, + "slasher": { + "init_paused_status": 0 + }, + "eigenPodManager": { + "init_paused_status": 0 + }, + "rewardsCoordinator": { + "init_paused_status": 0, + "MAX_REWARDS_DURATION": 864000, + "MAX_RETROACTIVE_LENGTH": 86400, + "MAX_FUTURE_LENGTH": 86400, + "GENESIS_REWARDS_TIMESTAMP": 1672531200, + "rewards_updater_address": "0x1234567890123456789012345678901234567890", + "activation_delay": 604800, + "calculation_interval_seconds": 86400, + "global_operator_commission_bips": 1000 + } +} diff --git a/contracts/test/mockData/config/hello-world/1337.json b/contracts/test/mockData/config/hello-world/1337.json new file mode 100644 index 00000000..e69de29b diff --git a/contracts/test/mockData/deployments/core/1337.json b/contracts/test/mockData/deployments/core/1337.json new file mode 100644 index 00000000..c01d27db --- /dev/null +++ b/contracts/test/mockData/deployments/core/1337.json @@ -0,0 +1,17 @@ +{ + "lastUpdate": { + "timestamp": "1688000000", + "block_number": "12345678" + }, + "addresses": { + "proxyAdmin": "0x1111111111111111111111111111111111111111", + "delegation": "0x2222222222222222222222222222222222222222", + "delegationManagerImpl": "0x3333333333333333333333333333333333333333", + "avsDirectory": "0x4444444444444444444444444444444444444444", + "avsDirectoryImpl": "0x5555555555555555555555555555555555555555", + "strategyManager": "0x7777777777777777777777777777777777777777", + "strategyManagerImpl": "0x8888888888888888888888888888888888888888", + "eigenPodManager": "0x9999999999999999999999999999999999999999", + "eigenPodManagerImpl": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } +} diff --git a/contracts/test/mockData/deployments/hello-world/1337.json b/contracts/test/mockData/deployments/hello-world/1337.json new file mode 100644 index 00000000..e69de29b diff --git a/contracts/test/mockData/scratch/31337.json b/contracts/test/mockData/scratch/31337.json new file mode 100644 index 00000000..208253c3 --- /dev/null +++ b/contracts/test/mockData/scratch/31337.json @@ -0,0 +1 @@ +{"lastUpdate":{"timestamp":"1","block_number":"1"},"addresses":{"proxyAdmin":"0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f","delegation":"0xf62849f9a0b5bf2913b396098f7c7019b51a820a","delegationManagerImpl":"0x96d3f6c20eed2697647f543fe6c08bc2fbf39758","avsDirectory":"0xc7183455a4c133ae270771860664b6b7ec320bb1","avsDirectoryImpl":"0x13aa49bac059d709dd0a18d6bb63290076a702d7","strategyManager":"0x1d1499e622d69689cdf9004d05ec547d650ff211","strategyManagerImpl":"0xdb25a7b768311de128bbda7b8426c3f9c74f3240","eigenPodManager":"0x03a6a84cd762d9707a21605b548aaab891562aab","eigenPodManagerImpl":"0x3381cd18e2fb4db236bf0525938ab6e43db0440f"}} \ No newline at end of file diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 00000000..5ac578f2 --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,11 @@ +FAQ About The Repo + +The goal is to be a list of random bespoke things that might not be immediately clear and if using an AI tool to ask questions about the repo can be a source for the AI to surface information to the user + +Typescript Notes: + +- We used ts-node in the repo as a dev dependency and dev commands use ts-node to run the typescript files so that there isn't an intermediate build step that the developer must call in the process to compile the typescript files to javascript and then separately use the output javascript. This allows us to directly run the typescript files which get compiled on the fly. We will still use tsc when creating production builds of our code but during development using ts-node has better UX and is more clear for developing + +Solidity Notes: + +- If you're running into low level errors with transactions being executed by ethers.js ie, code: BAD_DATA or returned with No Data related errors, then one solution to get more verbose errors is to compile and deploy your smart contracts with --revert-strings debug. This will insert verbose revert strings to catch before a low level revert would happen in an anvil instance. diff --git a/operator/abis/avsDirectoryABI.ts b/operator/abis/avsDirectoryABI.ts deleted file mode 100644 index 3c81d506..00000000 --- a/operator/abis/avsDirectoryABI.ts +++ /dev/null @@ -1,340 +0,0 @@ -export const avsDirectoryABI = [ - { - type: "constructor", - inputs: [ - { - name: "_delegation", - type: "address", - internalType: "contract IDelegationManager", - }, - ], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "DOMAIN_TYPEHASH", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "OPERATOR_AVS_REGISTRATION_TYPEHASH", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "avsOperatorStatus", - inputs: [ - { name: "", type: "address", internalType: "address" }, - { name: "", type: "address", internalType: "address" }, - ], - outputs: [ - { - name: "", - type: "uint8", - internalType: "enum IAVSDirectory.OperatorAVSRegistrationStatus", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "calculateOperatorAVSRegistrationDigestHash", - inputs: [ - { name: "operator", type: "address", internalType: "address" }, - { name: "avs", type: "address", internalType: "address" }, - { name: "salt", type: "bytes32", internalType: "bytes32" }, - { name: "expiry", type: "uint256", internalType: "uint256" }, - ], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "cancelSalt", - inputs: [{ name: "salt", type: "bytes32", internalType: "bytes32" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "delegation", - inputs: [], - outputs: [ - { - name: "", - type: "address", - internalType: "contract IDelegationManager", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "deregisterOperatorFromAVS", - inputs: [{ name: "operator", type: "address", internalType: "address" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "domainSeparator", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "initialize", - inputs: [ - { name: "initialOwner", type: "address", internalType: "address" }, - { - name: "_pauserRegistry", - type: "address", - internalType: "contract IPauserRegistry", - }, - { name: "initialPausedStatus", type: "uint256", internalType: "uint256" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "operatorSaltIsSpent", - inputs: [ - { name: "", type: "address", internalType: "address" }, - { name: "", type: "bytes32", internalType: "bytes32" }, - ], - outputs: [{ name: "", type: "bool", internalType: "bool" }], - stateMutability: "view", - }, - { - type: "function", - name: "owner", - inputs: [], - outputs: [{ name: "", type: "address", internalType: "address" }], - stateMutability: "view", - }, - { - type: "function", - name: "pause", - inputs: [ - { name: "newPausedStatus", type: "uint256", internalType: "uint256" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "pauseAll", - inputs: [], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "paused", - inputs: [{ name: "index", type: "uint8", internalType: "uint8" }], - outputs: [{ name: "", type: "bool", internalType: "bool" }], - stateMutability: "view", - }, - { - type: "function", - name: "paused", - inputs: [], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "pauserRegistry", - inputs: [], - outputs: [ - { name: "", type: "address", internalType: "contract IPauserRegistry" }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "registerOperatorToAVS", - inputs: [ - { name: "operator", type: "address", internalType: "address" }, - { - name: "operatorSignature", - type: "tuple", - internalType: "struct ISignatureUtils.SignatureWithSaltAndExpiry", - components: [ - { name: "signature", type: "bytes", internalType: "bytes" }, - { name: "salt", type: "bytes32", internalType: "bytes32" }, - { name: "expiry", type: "uint256", internalType: "uint256" }, - ], - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "renounceOwnership", - inputs: [], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setPauserRegistry", - inputs: [ - { - name: "newPauserRegistry", - type: "address", - internalType: "contract IPauserRegistry", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "transferOwnership", - inputs: [{ name: "newOwner", type: "address", internalType: "address" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unpause", - inputs: [ - { name: "newPausedStatus", type: "uint256", internalType: "uint256" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "updateAVSMetadataURI", - inputs: [{ name: "metadataURI", type: "string", internalType: "string" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "event", - name: "AVSMetadataURIUpdated", - inputs: [ - { name: "avs", type: "address", indexed: true, internalType: "address" }, - { - name: "metadataURI", - type: "string", - indexed: false, - internalType: "string", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Initialized", - inputs: [ - { name: "version", type: "uint8", indexed: false, internalType: "uint8" }, - ], - anonymous: false, - }, - { - type: "event", - name: "OperatorAVSRegistrationStatusUpdated", - inputs: [ - { - name: "operator", - type: "address", - indexed: true, - internalType: "address", - }, - { name: "avs", type: "address", indexed: true, internalType: "address" }, - { - name: "status", - type: "uint8", - indexed: false, - internalType: "enum IAVSDirectory.OperatorAVSRegistrationStatus", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "OwnershipTransferred", - inputs: [ - { - name: "previousOwner", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "newOwner", - type: "address", - indexed: true, - internalType: "address", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Paused", - inputs: [ - { - name: "account", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "newPausedStatus", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "PauserRegistrySet", - inputs: [ - { - name: "pauserRegistry", - type: "address", - indexed: false, - internalType: "contract IPauserRegistry", - }, - { - name: "newPauserRegistry", - type: "address", - indexed: false, - internalType: "contract IPauserRegistry", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Unpaused", - inputs: [ - { - name: "account", - type: "address", - indexed: true, - internalType: "address", - }, - { - name: "newPausedStatus", - type: "uint256", - indexed: false, - internalType: "uint256", - }, - ], - anonymous: false, - }, -]; diff --git a/operator/abis/contractABI.ts b/operator/abis/contractABI.ts deleted file mode 100644 index 09b87271..00000000 --- a/operator/abis/contractABI.ts +++ /dev/null @@ -1 +0,0 @@ -export const contractABI = [{"type":"constructor","inputs":[{"name":"_avsDirectory","type":"address","internalType":"contract IAVSDirectory"},{"name":"_registryCoordinator","type":"address","internalType":"contract IRegistryCoordinator"},{"name":"_stakeRegistry","type":"address","internalType":"contract IStakeRegistry"}],"stateMutability":"nonpayable"},{"type":"function","name":"allTaskHashes","inputs":[{"name":"","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"allTaskResponses","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"avsDirectory","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"createNewTask","inputs":[{"name":"name","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"deregisterOperatorFromAVS","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getOperatorRestakedStrategies","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"type":"function","name":"getRestakeableStrategies","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"type":"function","name":"latestTaskNum","inputs":[],"outputs":[{"name":"","type":"uint32","internalType":"uint32"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"pause","inputs":[{"name":"newPausedStatus","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"pauseAll","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"paused","inputs":[{"name":"index","type":"uint8","internalType":"uint8"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"paused","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"pauserRegistry","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IPauserRegistry"}],"stateMutability":"view"},{"type":"function","name":"payForRange","inputs":[{"name":"rangePayments","type":"tuple[]","internalType":"struct IPaymentCoordinator.RangePayment[]","components":[{"name":"strategiesAndMultipliers","type":"tuple[]","internalType":"struct IPaymentCoordinator.StrategyAndMultiplier[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]},{"name":"token","type":"address","internalType":"contract IERC20"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"startTimestamp","type":"uint32","internalType":"uint32"},{"name":"duration","type":"uint32","internalType":"uint32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"registerOperatorToAVS","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"operatorSignature","type":"tuple","internalType":"struct ISignatureUtils.SignatureWithSaltAndExpiry","components":[{"name":"signature","type":"bytes","internalType":"bytes"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"expiry","type":"uint256","internalType":"uint256"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"registryCoordinator","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IRegistryCoordinator"}],"stateMutability":"view"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"respondToTask","inputs":[{"name":"task","type":"tuple","internalType":"struct IHelloWorldServiceManager.Task","components":[{"name":"name","type":"string","internalType":"string"},{"name":"taskCreatedBlock","type":"uint32","internalType":"uint32"}]},{"name":"referenceTaskIndex","type":"uint32","internalType":"uint32"},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setPauserRegistry","inputs":[{"name":"newPauserRegistry","type":"address","internalType":"contract IPauserRegistry"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"unpause","inputs":[{"name":"newPausedStatus","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateAVSMetadataURI","inputs":[{"name":"_metadataURI","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"NewTaskCreated","inputs":[{"name":"taskIndex","type":"uint32","indexed":true,"internalType":"uint32"},{"name":"task","type":"tuple","indexed":false,"internalType":"struct IHelloWorldServiceManager.Task","components":[{"name":"name","type":"string","internalType":"string"},{"name":"taskCreatedBlock","type":"uint32","internalType":"uint32"}]}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"newPausedStatus","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PauserRegistrySet","inputs":[{"name":"pauserRegistry","type":"address","indexed":false,"internalType":"contract IPauserRegistry"},{"name":"newPauserRegistry","type":"address","indexed":false,"internalType":"contract IPauserRegistry"}],"anonymous":false},{"type":"event","name":"TaskResponded","inputs":[{"name":"taskIndex","type":"uint32","indexed":true,"internalType":"uint32"},{"name":"task","type":"tuple","indexed":false,"internalType":"struct IHelloWorldServiceManager.Task","components":[{"name":"name","type":"string","internalType":"string"},{"name":"taskCreatedBlock","type":"uint32","internalType":"uint32"}]},{"name":"operator","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"newPausedStatus","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false}]; \ No newline at end of file diff --git a/operator/abis/delegationABI.ts b/operator/abis/delegationABI.ts deleted file mode 100644 index 74c422c9..00000000 --- a/operator/abis/delegationABI.ts +++ /dev/null @@ -1 +0,0 @@ -export const delegationABI = [{"type":"function","name":"DELEGATION_APPROVAL_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"DOMAIN_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"STAKER_DELEGATION_TYPEHASH","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"beaconChainETHStrategy","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IStrategy"}],"stateMutability":"view"},{"type":"function","name":"calculateCurrentStakerDelegationDigestHash","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"},{"name":"expiry","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"calculateDelegationApprovalDigestHash","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"},{"name":"_delegationApprover","type":"address","internalType":"address"},{"name":"approverSalt","type":"bytes32","internalType":"bytes32"},{"name":"expiry","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"calculateStakerDelegationDigestHash","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"_stakerNonce","type":"uint256","internalType":"uint256"},{"name":"operator","type":"address","internalType":"address"},{"name":"expiry","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"calculateWithdrawalRoot","inputs":[{"name":"withdrawal","type":"tuple","internalType":"struct IDelegationManager.Withdrawal","components":[{"name":"staker","type":"address","internalType":"address"},{"name":"delegatedTo","type":"address","internalType":"address"},{"name":"withdrawer","type":"address","internalType":"address"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"startBlock","type":"uint32","internalType":"uint32"},{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"type":"function","name":"completeQueuedWithdrawal","inputs":[{"name":"withdrawal","type":"tuple","internalType":"struct IDelegationManager.Withdrawal","components":[{"name":"staker","type":"address","internalType":"address"},{"name":"delegatedTo","type":"address","internalType":"address"},{"name":"withdrawer","type":"address","internalType":"address"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"startBlock","type":"uint32","internalType":"uint32"},{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"}]},{"name":"tokens","type":"address[]","internalType":"contract IERC20[]"},{"name":"middlewareTimesIndex","type":"uint256","internalType":"uint256"},{"name":"receiveAsTokens","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"completeQueuedWithdrawals","inputs":[{"name":"withdrawals","type":"tuple[]","internalType":"struct IDelegationManager.Withdrawal[]","components":[{"name":"staker","type":"address","internalType":"address"},{"name":"delegatedTo","type":"address","internalType":"address"},{"name":"withdrawer","type":"address","internalType":"address"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"startBlock","type":"uint32","internalType":"uint32"},{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"}]},{"name":"tokens","type":"address[][]","internalType":"contract IERC20[][]"},{"name":"middlewareTimesIndexes","type":"uint256[]","internalType":"uint256[]"},{"name":"receiveAsTokens","type":"bool[]","internalType":"bool[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"cumulativeWithdrawalsQueued","inputs":[{"name":"staker","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"decreaseDelegatedShares","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"delegateTo","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approverSignatureAndExpiry","type":"tuple","internalType":"struct ISignatureUtils.SignatureWithExpiry","components":[{"name":"signature","type":"bytes","internalType":"bytes"},{"name":"expiry","type":"uint256","internalType":"uint256"}]},{"name":"approverSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"delegateToBySignature","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"},{"name":"stakerSignatureAndExpiry","type":"tuple","internalType":"struct ISignatureUtils.SignatureWithExpiry","components":[{"name":"signature","type":"bytes","internalType":"bytes"},{"name":"expiry","type":"uint256","internalType":"uint256"}]},{"name":"approverSignatureAndExpiry","type":"tuple","internalType":"struct ISignatureUtils.SignatureWithExpiry","components":[{"name":"signature","type":"bytes","internalType":"bytes"},{"name":"expiry","type":"uint256","internalType":"uint256"}]},{"name":"approverSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"delegatedTo","inputs":[{"name":"staker","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"delegationApprover","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"delegationApproverSaltIsSpent","inputs":[{"name":"_delegationApprover","type":"address","internalType":"address"},{"name":"salt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"domainSeparator","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"earningsReceiver","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getOperatorShares","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"type":"function","name":"getWithdrawalDelay","inputs":[{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"increaseDelegatedShares","inputs":[{"name":"staker","type":"address","internalType":"address"},{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isDelegated","inputs":[{"name":"staker","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"isOperator","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"migrateQueuedWithdrawals","inputs":[{"name":"withdrawalsToQueue","type":"tuple[]","internalType":"struct IStrategyManager.DeprecatedStruct_QueuedWithdrawal[]","components":[{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"},{"name":"staker","type":"address","internalType":"address"},{"name":"withdrawerAndNonce","type":"tuple","internalType":"struct IStrategyManager.DeprecatedStruct_WithdrawerAndNonce","components":[{"name":"withdrawer","type":"address","internalType":"address"},{"name":"nonce","type":"uint96","internalType":"uint96"}]},{"name":"withdrawalStartBlock","type":"uint32","internalType":"uint32"},{"name":"delegatedAddress","type":"address","internalType":"address"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"minWithdrawalDelayBlocks","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"modifyOperatorDetails","inputs":[{"name":"newOperatorDetails","type":"tuple","internalType":"struct IDelegationManager.OperatorDetails","components":[{"name":"earningsReceiver","type":"address","internalType":"address"},{"name":"delegationApprover","type":"address","internalType":"address"},{"name":"stakerOptOutWindowBlocks","type":"uint32","internalType":"uint32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"operatorDetails","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","internalType":"struct IDelegationManager.OperatorDetails","components":[{"name":"earningsReceiver","type":"address","internalType":"address"},{"name":"delegationApprover","type":"address","internalType":"address"},{"name":"stakerOptOutWindowBlocks","type":"uint32","internalType":"uint32"}]}],"stateMutability":"view"},{"type":"function","name":"operatorShares","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"strategy","type":"address","internalType":"contract IStrategy"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"queueWithdrawals","inputs":[{"name":"queuedWithdrawalParams","type":"tuple[]","internalType":"struct IDelegationManager.QueuedWithdrawalParams[]","components":[{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"},{"name":"withdrawer","type":"address","internalType":"address"}]}],"outputs":[{"name":"","type":"bytes32[]","internalType":"bytes32[]"}],"stateMutability":"nonpayable"},{"type":"function","name":"registerAsOperator","inputs":[{"name":"registeringOperatorDetails","type":"tuple","internalType":"struct IDelegationManager.OperatorDetails","components":[{"name":"earningsReceiver","type":"address","internalType":"address"},{"name":"delegationApprover","type":"address","internalType":"address"},{"name":"stakerOptOutWindowBlocks","type":"uint32","internalType":"uint32"}]},{"name":"metadataURI","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stakerNonce","inputs":[{"name":"staker","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"stakerOptOutWindowBlocks","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"strategyWithdrawalDelayBlocks","inputs":[{"name":"strategy","type":"address","internalType":"contract IStrategy"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"undelegate","inputs":[{"name":"staker","type":"address","internalType":"address"}],"outputs":[{"name":"withdrawalRoot","type":"bytes32[]","internalType":"bytes32[]"}],"stateMutability":"nonpayable"},{"type":"function","name":"updateOperatorMetadataURI","inputs":[{"name":"metadataURI","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"MinWithdrawalDelayBlocksSet","inputs":[{"name":"previousValue","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newValue","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OperatorDetailsModified","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"newOperatorDetails","type":"tuple","indexed":false,"internalType":"struct IDelegationManager.OperatorDetails","components":[{"name":"earningsReceiver","type":"address","internalType":"address"},{"name":"delegationApprover","type":"address","internalType":"address"},{"name":"stakerOptOutWindowBlocks","type":"uint32","internalType":"uint32"}]}],"anonymous":false},{"type":"event","name":"OperatorMetadataURIUpdated","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"metadataURI","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"OperatorRegistered","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"operatorDetails","type":"tuple","indexed":false,"internalType":"struct IDelegationManager.OperatorDetails","components":[{"name":"earningsReceiver","type":"address","internalType":"address"},{"name":"delegationApprover","type":"address","internalType":"address"},{"name":"stakerOptOutWindowBlocks","type":"uint32","internalType":"uint32"}]}],"anonymous":false},{"type":"event","name":"OperatorSharesDecreased","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"staker","type":"address","indexed":false,"internalType":"address"},{"name":"strategy","type":"address","indexed":false,"internalType":"contract IStrategy"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OperatorSharesIncreased","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"staker","type":"address","indexed":false,"internalType":"address"},{"name":"strategy","type":"address","indexed":false,"internalType":"contract IStrategy"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"StakerDelegated","inputs":[{"name":"staker","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"StakerForceUndelegated","inputs":[{"name":"staker","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"StakerUndelegated","inputs":[{"name":"staker","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"StrategyWithdrawalDelayBlocksSet","inputs":[{"name":"strategy","type":"address","indexed":false,"internalType":"contract IStrategy"},{"name":"previousValue","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newValue","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"WithdrawalCompleted","inputs":[{"name":"withdrawalRoot","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"WithdrawalMigrated","inputs":[{"name":"oldWithdrawalRoot","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"newWithdrawalRoot","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"WithdrawalQueued","inputs":[{"name":"withdrawalRoot","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"withdrawal","type":"tuple","indexed":false,"internalType":"struct IDelegationManager.Withdrawal","components":[{"name":"staker","type":"address","internalType":"address"},{"name":"delegatedTo","type":"address","internalType":"address"},{"name":"withdrawer","type":"address","internalType":"address"},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"startBlock","type":"uint32","internalType":"uint32"},{"name":"strategies","type":"address[]","internalType":"contract IStrategy[]"},{"name":"shares","type":"uint256[]","internalType":"uint256[]"}]}],"anonymous":false}] \ No newline at end of file diff --git a/operator/abis/registryABI.ts b/operator/abis/registryABI.ts deleted file mode 100644 index 624a0c7c..00000000 --- a/operator/abis/registryABI.ts +++ /dev/null @@ -1 +0,0 @@ -export const registryABI = [{"type":"constructor","inputs":[{"name":"_delegationManager","type":"address","internalType":"contract IDelegationManager"}],"stateMutability":"nonpayable"},{"type":"function","name":"deregisterOperator","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getLastCheckpointOperatorWeight","inputs":[{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastCheckpointThresholdWeight","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastCheckpointThresholdWeightAtBlock","inputs":[{"name":"_blockNumber","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastCheckpointTotalWeight","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastCheckpointTotalWeightAtBlock","inputs":[{"name":"_blockNumber","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastestOperatorSigningKey","inputs":[{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getOperatorSigningKeyAtBlock","inputs":[{"name":"_operator","type":"address","internalType":"address"},{"name":"_blockNumber","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getOperatorWeight","inputs":[{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getOperatorWeightAtBlock","inputs":[{"name":"_operator","type":"address","internalType":"address"},{"name":"_blockNumber","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_serviceManager","type":"address","internalType":"address"},{"name":"_thresholdWeight","type":"uint256","internalType":"uint256"},{"name":"_quorum","type":"tuple","internalType":"struct Quorum","components":[{"name":"strategies","type":"tuple[]","internalType":"struct StrategyParams[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isValidSignature","inputs":[{"name":"_dataHash","type":"bytes32","internalType":"bytes32"},{"name":"_signatureData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes4","internalType":"bytes4"}],"stateMutability":"view"},{"type":"function","name":"minimumWeight","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"operatorRegistered","inputs":[{"name":"_operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"quorum","inputs":[],"outputs":[{"name":"","type":"tuple","internalType":"struct Quorum","components":[{"name":"strategies","type":"tuple[]","internalType":"struct StrategyParams[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]}]}],"stateMutability":"view"},{"type":"function","name":"registerOperatorWithSignature","inputs":[{"name":"_operatorSignature","type":"tuple","internalType":"struct ISignatureUtils.SignatureWithSaltAndExpiry","components":[{"name":"signature","type":"bytes","internalType":"bytes"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"expiry","type":"uint256","internalType":"uint256"}]},{"name":"_signingKey","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateMinimumWeight","inputs":[{"name":"_newMinimumWeight","type":"uint256","internalType":"uint256"},{"name":"_operators","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateOperatorSigningKey","inputs":[{"name":"_newSigningKey","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateOperators","inputs":[{"name":"_operators","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateOperatorsForQuorum","inputs":[{"name":"operatorsPerQuorum","type":"address[][]","internalType":"address[][]"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateQuorumConfig","inputs":[{"name":"_quorum","type":"tuple","internalType":"struct Quorum","components":[{"name":"strategies","type":"tuple[]","internalType":"struct StrategyParams[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]}]},{"name":"_operators","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateStakeThreshold","inputs":[{"name":"_thresholdWeight","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"MinimumWeightUpdated","inputs":[{"name":"_old","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"_new","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OperatorDeregistered","inputs":[{"name":"_operator","type":"address","indexed":true,"internalType":"address"},{"name":"_avs","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OperatorRegistered","inputs":[{"name":"_operator","type":"address","indexed":true,"internalType":"address"},{"name":"_avs","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OperatorWeightUpdated","inputs":[{"name":"_operator","type":"address","indexed":true,"internalType":"address"},{"name":"oldWeight","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newWeight","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"QuorumUpdated","inputs":[{"name":"_old","type":"tuple","indexed":false,"internalType":"struct Quorum","components":[{"name":"strategies","type":"tuple[]","internalType":"struct StrategyParams[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]}]},{"name":"_new","type":"tuple","indexed":false,"internalType":"struct Quorum","components":[{"name":"strategies","type":"tuple[]","internalType":"struct StrategyParams[]","components":[{"name":"strategy","type":"address","internalType":"contract IStrategy"},{"name":"multiplier","type":"uint96","internalType":"uint96"}]}]}],"anonymous":false},{"type":"event","name":"SigningKeyUpdate","inputs":[{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"updateBlock","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"newSigningKey","type":"address","indexed":true,"internalType":"address"},{"name":"oldSigningKey","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"ThresholdWeightUpdated","inputs":[{"name":"_thresholdWeight","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"TotalWeightUpdated","inputs":[{"name":"oldTotalWeight","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newTotalWeight","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"UpdateMinimumWeight","inputs":[{"name":"oldMinimumWeight","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newMinimumWeight","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"InsufficientSignedStake","inputs":[]},{"type":"error","name":"InsufficientWeight","inputs":[]},{"type":"error","name":"InvalidLength","inputs":[]},{"type":"error","name":"InvalidQuorum","inputs":[]},{"type":"error","name":"InvalidReferenceBlock","inputs":[]},{"type":"error","name":"InvalidSignature","inputs":[]},{"type":"error","name":"InvalidSignedWeight","inputs":[]},{"type":"error","name":"InvalidThreshold","inputs":[]},{"type":"error","name":"LengthMismatch","inputs":[]},{"type":"error","name":"MustUpdateAllOperators","inputs":[]},{"type":"error","name":"NotSorted","inputs":[]},{"type":"error","name":"OperatorAlreadyRegistered","inputs":[]},{"type":"error","name":"OperatorNotRegistered","inputs":[]}] \ No newline at end of file diff --git a/operator/createNewTasks.ts b/operator/createNewTasks.ts index 192e56f0..b80ecd34 100644 --- a/operator/createNewTasks.ts +++ b/operator/createNewTasks.ts @@ -1,7 +1,7 @@ import { ethers } from 'ethers'; // Connect to the Ethereum network -const provider = new ethers.providers.JsonRpcProvider(`http://127.0.0.1:8545`); +const provider = new ethers.JsonRpcProvider(`http://127.0.0.1:8545`); // Replace with your own private key (ensure this is kept secret in real applications) const privateKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'; @@ -36,7 +36,7 @@ async function createNewTask(taskName: string) { // Wait for the transaction to be mined const receipt = await tx.wait(); - console.log(`Transaction successful with hash: ${receipt.transactionHash}`); + console.log(`Transaction successful with hash: ${receipt.hash}`); } catch (error) { console.error('Error sending transaction:', error); } diff --git a/operator/index.ts b/operator/index.ts index 55554fab..c3af7e8f 100644 --- a/operator/index.ts +++ b/operator/index.ts @@ -1,35 +1,56 @@ import { ethers } from "ethers"; import * as dotenv from "dotenv"; -import { delegationABI } from "./abis/delegationABI"; -import { contractABI } from './abis/contractABI'; -import { registryABI } from './abis/registryABI'; -import { avsDirectoryABI } from './abis/avsDirectoryABI'; +const fs = require('fs'); +const path = require('path'); dotenv.config(); -const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL); +// Check if the process.env object is empty +if (!Object.keys(process.env).length) { + throw new Error("process.env object is empty"); +} + +// Setup env variables +const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); +/// TODO: Hack +let chainId = 31337; + +const avsDeploymentData = JSON.parse(fs.readFileSync(path.resolve(__dirname, `../contracts/deployments/hello-world/${chainId}.json`), 'utf8')); +// Load core deployment data +const coreDeploymentData = JSON.parse(fs.readFileSync(path.resolve(__dirname, `../contracts/deployments/core/${chainId}.json`), 'utf8')); + + +const delegationManagerAddress = coreDeploymentData.addresses.delegation; // todo: reminder to fix the naming of this contract in the deployment file, change to delegationManager +const avsDirectoryAddress = coreDeploymentData.addresses.avsDirectory; +const helloWorldServiceManagerAddress = avsDeploymentData.addresses.helloWorldServiceManager; +const ecdsaStakeRegistryAddress = avsDeploymentData.addresses.stakeRegistry; -const delegationManagerAddress = process.env.DELEGATION_MANAGER_ADDRESS!; -const contractAddress = process.env.CONTRACT_ADDRESS!; -const stakeRegistryAddress = process.env.STAKE_REGISTRY_ADDRESS!; -const avsDirectoryAddress = process.env.AVS_DIRECTORY_ADDRESS!; -const delegationManager = new ethers.Contract(delegationManagerAddress, delegationABI, wallet); -const contract = new ethers.Contract(contractAddress, contractABI, wallet); -const registryContract = new ethers.Contract(stakeRegistryAddress, registryABI, wallet); + +// Load ABIs +const delegationManagerABI = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../abis/IDelegationManager.json'), 'utf8')); +const ecdsaRegistryABI = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../abis/ECDSAStakeRegistry.json'), 'utf8')); +const helloWorldServiceManagerABI = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../abis/HelloWorldServiceManager.json'), 'utf8')); +const avsDirectoryABI = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../abis/IAVSDirectory.json'), 'utf8')); + +// Initialize contract objects from ABIs +const delegationManager = new ethers.Contract(delegationManagerAddress, delegationManagerABI, wallet); +const helloWorldServiceManager = new ethers.Contract(helloWorldServiceManagerAddress, helloWorldServiceManagerABI, wallet); +const ecdsaRegistryContract = new ethers.Contract(ecdsaStakeRegistryAddress, ecdsaRegistryABI, wallet); const avsDirectory = new ethers.Contract(avsDirectoryAddress, avsDirectoryABI, wallet); + const signAndRespondToTask = async (taskIndex: number, taskCreatedBlock: number, taskName: string) => { const message = `Hello, ${taskName}`; - const messageHash = ethers.utils.solidityKeccak256(["string"], [message]); - const messageBytes = ethers.utils.arrayify(messageHash); + const messageHash = ethers.solidityPackedKeccak256(["string"], [message]); + const messageBytes = ethers.getBytes(messageHash); const signature = await wallet.signMessage(messageBytes); console.log( `Signing and responding to task ${taskIndex}` ) - const tx = await contract.respondToTask( + const tx = await helloWorldServiceManager.respondToTask( { name: taskName, taskCreatedBlock: taskCreatedBlock }, taskIndex, signature @@ -39,42 +60,62 @@ const signAndRespondToTask = async (taskIndex: number, taskCreatedBlock: number, }; const registerOperator = async () => { - console.log("check") - const tx1 = await delegationManager.registerAsOperator({ - earningsReceiver: await wallet.address, - delegationApprover: "0x0000000000000000000000000000000000000000", - stakerOptOutWindowBlocks: 0 - }, ""); - await tx1.wait(); - console.log("Operator registered on EL successfully"); - - const salt = ethers.utils.hexlify(ethers.utils.randomBytes(32)); + + // Registers as an Operator in EigenLayer. + try { + const tx1 = await delegationManager.registerAsOperator({ + __deprecated_earningsReceiver: await wallet.address, + delegationApprover: "0x0000000000000000000000000000000000000000", + stakerOptOutWindowBlocks: 0 + }, ""); + await tx1.wait(); + console.log("Operator registered to Core EigenLayer contracts"); + } catch (error) { + console.error("Error in registering as operator:", error); + } + + const salt = ethers.hexlify(ethers.randomBytes(32)); const expiry = Math.floor(Date.now() / 1000) + 3600; // Example expiry, 1 hour from now // Define the output structure - let operatorSignature = { - expiry: expiry, + let operatorSignatureWithSaltAndExpiry = { + signature: "", salt: salt, - signature: "" + expiry: expiry }; - // Calculate the digest hash using the avsDirectory's method - const digestHash = await avsDirectory.calculateOperatorAVSRegistrationDigestHash( + // Calculate the digest hash, which is a unique value representing the operator, avs, unique value (salt) and expiration date. + console.log(wallet.address); + console.log(await helloWorldServiceManager.getAddress()); + console.log(salt, "salt"); + console.log(expiry, "expiry"); + + const operatorDigestHash = await avsDirectory.calculateOperatorAVSRegistrationDigestHash( wallet.address, - contract.address, + await helloWorldServiceManager.getAddress(), salt, expiry ); - - // // Sign the digest hash with the operator's private key - const signingKey = new ethers.utils.SigningKey(process.env.PRIVATE_KEY!); - const signature = signingKey.signDigest(digestHash); + console.log(operatorDigestHash); - // // Encode the signature in the required format - operatorSignature.signature = ethers.utils.joinSignature(signature); + // Sign the digest hash with the operator's private key + console.log("Signing digest hash with operator's private key"); + const operatorSigningKey = new ethers.SigningKey(process.env.PRIVATE_KEY!); + const operatorSignedDigestHash = operatorSigningKey.sign(operatorDigestHash); - const tx2 = await registryContract.registerOperatorWithSignature( - operatorSignature, + // Encode the signature in the required format + operatorSignatureWithSaltAndExpiry.signature = ethers.Signature.from(operatorSignedDigestHash).serialized; + + console.log("Registering Operator to AVS Registry contract"); + + //Debugging + console.log('operatorSignatureWithSaltAndExpiry before processing:', operatorSignatureWithSaltAndExpiry); + console.log('wallet.address before processing:', wallet.address); + + // Register Operator to AVS + // Per release here: https://github.com/Layr-Labs/eigenlayer-middleware/blob/v0.2.1-mainnet-rewards/src/unaudited/ECDSAStakeRegistry.sol#L49 + const tx2 = await ecdsaRegistryContract.registerOperatorWithSignature( + operatorSignatureWithSaltAndExpiry, wallet.address ); await tx2.wait(); @@ -82,9 +123,10 @@ const registerOperator = async () => { }; const monitorNewTasks = async () => { - await contract.createNewTask("EigenWorld"); + console.log(`Creating new task "EigenWorld"`); + await helloWorldServiceManager.createNewTask("EigenWorld"); - contract.on("NewTaskCreated", async (taskIndex: number, task: any) => { + helloWorldServiceManager.on("NewTaskCreated", async (taskIndex: number, task: any) => { console.log(`New task detected: Hello, ${task.name}`); await signAndRespondToTask(taskIndex, task.taskCreatedBlock, task.name); }); diff --git a/package-lock.json b/package-lock.json index e908b572..01adff19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,736 +8,173 @@ "name": "hello-world-avs", "version": "1.0.0", "dependencies": { - "@types/node": "^20.12.12", - "bls-signatures": "^2.0.3", "dotenv": "^10.0.0", - "ethers": "^5.7.2" + "ethers": "^6.13.2" }, "devDependencies": { + "@types/node": "^20.12.12", + "ts-node": "^10.9.2", "typescript": "^5.4.5" } }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "20.12.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/binascii": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/binascii/-/binascii-0.0.2.tgz", - "integrity": "sha512-rA2CrUl1+6yKrn+XgLs8Hdy18OER1UW146nM+ixzhQXDY+Bd3ySkyIJGwF2a4I45JwbvF1mDL/nWkqBwpOcdBA==" + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/bls-signatures": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bls-signatures/-/bls-signatures-2.0.3.tgz", - "integrity": "sha512-6hp0od7VJkXthuANiABt+0z3nWbfGBKGu17JrzZR+mg6+hy3hpt1uwZS2xkK2eXwc1pz1jzVeYJxjMKNj4km+A==", + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "license": "MIT", "dependencies": { - "binascii": "0.0.2", - "core-js": "^3.33.2" + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" }, - "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, "node_modules/dotenv": { @@ -748,33 +185,14 @@ "node": ">=10" } }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.2.tgz", + "integrity": "sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg==", "funding": [ { "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "url": "https://github.com/sponsors/ethers-io/" }, { "type": "individual", @@ -782,81 +200,78 @@ } ], "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/typescript": { "version": "5.4.5", @@ -874,18 +289,26 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" }, "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -895,6 +318,16 @@ "optional": true } } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } } } } diff --git a/package.json b/package.json index c4266ebe..ddc30900 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,21 @@ "version": "1.0.0", "main": "index.js", "scripts": { - "start": "node dist/index.js" + "start:operator": "ts-node operator/index.ts", + "start:traffic": "ts-node operator/createNewTasks.ts", + "start:anvil": "anvil", + "deploy:core": "cd contracts && forge script script/DeployEigenlayerCore.s.sol:DeployEigenlayerCore --rpc-url http://localhost:8545 --broadcast", + "deploy:hello-world": "cd contracts && forge script script/HelloWorldDeployer.s.sol:HelloWorldDeployer --rpc-url http://localhost:8545 --broadcast", + "build": "cd contracts && forge build", + "extract:abis": "npm run build && node utils/abis.js" }, "dependencies": { - "@types/node": "^20.12.12", - "bls-signatures": "^2.0.3", "dotenv": "^10.0.0", - "ethers": "^5.7.2" + "ethers": "^6.13.2" }, "devDependencies": { + "@types/node": "^20.12.12", + "ts-node": "^10.9.2", "typescript": "^5.4.5" } } diff --git a/utils/abis.js b/utils/abis.js new file mode 100644 index 00000000..5fd9afec --- /dev/null +++ b/utils/abis.js @@ -0,0 +1,54 @@ +const fs = require('fs'); +const path = require('path'); + +const abiDir = 'abis'; +const contractsDir = 'contracts'; +const artifactsDir = path.join(contractsDir, 'out'); + +const contractsToExtract = [ + 'IAVSDirectory', + 'IDelegationManager', + 'ECDSAStakeRegistry', + 'HelloWorldServiceManager' +]; + +if (!fs.existsSync(abiDir)) { + fs.mkdirSync(abiDir); +} + +function checkArtifactsDirectory() { + if (!fs.existsSync(artifactsDir)) { + console.error(`The artifacts directory '${artifactsDir}' does not exist.`); + console.log('Please compile your contracts first using "forge build"'); + process.exit(1); + } + + const files = fs.readdirSync(artifactsDir); + if (files.length === 0) { + console.error(`The artifacts directory '${artifactsDir}' is empty.`); + console.log('Please compile your contracts first using "forge build" or confirm the path is correct.'); + process.exit(1); + } +} + +function extractAbi(contractName) { + const outputPath = path.join(artifactsDir, `${contractName}.sol`, `${contractName}.json`); + const abiOutputPath = path.join(abiDir, `${contractName}.json`); + + try { + const contractData = JSON.parse(fs.readFileSync(outputPath, 'utf8')); + const abi = JSON.stringify(contractData.abi, null, 2); + fs.writeFileSync(abiOutputPath, abi); + console.log(`Extracted ABI for ${contractName}`); + } catch (error) { + console.error(`Error extracting ABI for ${contractName}:`, error.message); + } +} + +checkArtifactsDirectory(); + +for (const contractName of contractsToExtract) { + extractAbi(contractName); +} + +console.log('ABI extraction complete. Check the "abis" directory for the output.'); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index f03f4bc3..00000000 --- a/yarn.lock +++ /dev/null @@ -1,506 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ethersproject/abi@^5.7.0", "@ethersproject/abi@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@^5.7.0", "@ethersproject/abstract-provider@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@^5.7.0", "@ethersproject/abstract-signer@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@^5.7.0", "@ethersproject/address@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@^5.7.0", "@ethersproject/base64@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@^5.7.0", "@ethersproject/basex@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@^5.7.0", "@ethersproject/bignumber@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@^5.7.0", "@ethersproject/bytes@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@^5.7.0", "@ethersproject/constants@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@^5.7.0", "@ethersproject/hash@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@^5.7.0", "@ethersproject/hdnode@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@^5.7.0", "@ethersproject/json-wallets@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@^5.7.0", "@ethersproject/keccak256@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@^5.7.0", "@ethersproject/logger@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@^5.7.0", "@ethersproject/networks@5.7.1": - version "5.7.1" - resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@^5.7.0", "@ethersproject/pbkdf2@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@^5.7.0", "@ethersproject/properties@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.2": - version "5.7.2" - resolved "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@^5.7.0", "@ethersproject/random@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@^5.7.0", "@ethersproject/rlp@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@^5.7.0", "@ethersproject/sha2@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@^5.7.0", "@ethersproject/signing-key@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@^5.7.0", "@ethersproject/strings@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@^5.7.0", "@ethersproject/transactions@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@^5.7.0", "@ethersproject/web@5.7.1": - version "5.7.1" - resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@^5.7.0", "@ethersproject/wordlists@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@types/node@^20.12.12": - version "20.12.12" - resolved "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz" - integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw== - dependencies: - undici-types "~5.26.4" - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -binascii@0.0.2: - version "0.0.2" - resolved "https://registry.npmjs.org/binascii/-/binascii-0.0.2.tgz" - integrity sha512-rA2CrUl1+6yKrn+XgLs8Hdy18OER1UW146nM+ixzhQXDY+Bd3ySkyIJGwF2a4I45JwbvF1mDL/nWkqBwpOcdBA== - -bls-signatures@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/bls-signatures/-/bls-signatures-2.0.3.tgz" - integrity sha512-6hp0od7VJkXthuANiABt+0z3nWbfGBKGu17JrzZR+mg6+hy3hpt1uwZS2xkK2eXwc1pz1jzVeYJxjMKNj4km+A== - dependencies: - binascii "0.0.2" - core-js "^3.33.2" - -bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -core-js@^3.33.2: - version "3.37.1" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz" - integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw== - -dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -elliptic@6.5.4: - version "6.5.4" - resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -ethers@^5.7.2: - version "5.7.2" - resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -hash.js@^1.0.0, hash.js@^1.0.3, hash.js@1.1.7: - version "1.1.7" - resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -scrypt-js@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -typescript@^5.4.5: - version "5.4.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" - integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== - -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==