diff --git a/.github/workflows/bindings.yml b/.github/workflows/bindings.yml new file mode 100644 index 00000000..c83d0dfa --- /dev/null +++ b/.github/workflows/bindings.yml @@ -0,0 +1,78 @@ +name: Bindings + +on: + push: + branches: + - dev + pull_request: + merge_group: + +permissions: + contents: read + +jobs: + generate_bindings: + name: Generate bindings + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install go1.21 + uses: actions/setup-go@v5 + with: + go-version: "1.21" + + - name: Add Ethereum PPA + run: sudo add-apt-repository -y ppa:ethereum/ethereum + + - name: Install Abigen + run: sudo apt-get update && sudo apt-get install ethereum + + - name: Show abigen version + run: abigen --version + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: v0.3.0 + + - name: Run make bindings + run: make bindings + + check_bindings: + name: Check bindings are up-to-date + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + # This step is needed to know if the contracts were changed. + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + contracts: + - 'contracts/lib/**' + - 'contracts/script/**' + - 'contracts/src/**' + bindings: + - 'contracts/bindings/**' + + + # This step runs only if some contract changed. + # It checks whether the bindings directory have changed. + # If there are no changes, then the bindings are outdated + # and therefore this step will fail. + - name: Check the bindings are up-to-date + if: steps.filter.outputs.contracts == 'true' + run: | + BINDINGS_UPDATED=${{ steps.filter.outputs.bindings }} + if [[ "$BINDINGS_UPDATED" == "false" ]]; then + echo "The bindings are outdated"; + exit 1 + fi diff --git a/.github/workflows/check-anvil-state.yml b/.github/workflows/check-anvil-state.yml new file mode 100644 index 00000000..663946be --- /dev/null +++ b/.github/workflows/check-anvil-state.yml @@ -0,0 +1,58 @@ +name: Check anvil state +on: + push: + branches: + - dev + pull_request: + merge_group: + +jobs: + generate-anvil-state: + name: generate anvil state + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: stable + + - name: Generate anvil state + run: make deploy-contracts-to-anvil-and-save-state + + check-anvil-state: + name: Check anvil dump is up-to-date + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # This step is needed to know if the contracts were changed. + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + contracts: + - 'contracts/lib/**' + - 'contracts/script/**' + - 'contracts/src/**' + anvil_state: + - 'contracts/anvil/contracts-deployed-anvil-state.json' + + # This step runs only if some contract changed. + # It checks whether the anvil state has changed. + # If there are no changes, then the anvil state is outdated + # and therefore this step will fail. + - name: Check the anvil state is up-to-date + if: steps.filter.outputs.contracts == 'true' + run: | + ANVIL_STATE_UPDATED=${{ steps.filter.outputs.anvil_state }} + if [[ "$ANVIL_STATE_UPDATED" == "false" ]]; then + echo "The anvil state is outdated"; + exit 1 + fi diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml new file mode 100644 index 00000000..ba932e2f --- /dev/null +++ b/.github/workflows/contracts.yml @@ -0,0 +1,40 @@ +name: Contracts CI + +on: + push: + branches: [main] + pull_request: + branches: [ '**' ] + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + strategy: + fail-fast: true + + name: Foundry project + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./contracts + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: stable + + - name: Show Forge version + run: forge --version + + - name: Run Forge fmt + run: forge fmt --check + + - name: Run Forge build + run: forge build diff --git a/chainio/clients/avsregistry/reader.go b/chainio/clients/avsregistry/reader.go index 382cb27b..c714364a 100644 --- a/chainio/clients/avsregistry/reader.go +++ b/chainio/clients/avsregistry/reader.go @@ -30,6 +30,8 @@ type Config struct { OperatorStateRetrieverAddress common.Address } +// The ChainReader provides methods to call the +// AVS registry contract's view functions. type ChainReader struct { logger logging.Logger blsApkRegistryAddr common.Address @@ -40,6 +42,7 @@ type ChainReader struct { ethClient eth.HttpBackend } +// Creates a new instance of the ChainReader. func NewChainReader( registryCoordinatorAddr common.Address, blsApkRegistryAddr common.Address, @@ -84,6 +87,7 @@ func NewReaderFromConfig( ), nil } +// Returns the total quorum count read from the RegistryCoordinator func (r *ChainReader) GetQuorumCount(opts *bind.CallOpts) (uint8, error) { if r.registryCoordinator == nil { return 0, errors.New("RegistryCoordinator contract not provided") @@ -91,6 +95,8 @@ func (r *ChainReader) GetQuorumCount(opts *bind.CallOpts) (uint8, error) { return r.registryCoordinator.QuorumCount(opts) } +// Returns, for each quorum in `quorumNumbers`, a vector of the operators registered for +// that quorum at the current block, containing each operator's `operatorId` and `stake`. func (r *ChainReader) GetOperatorsStakeInQuorumsAtCurrentBlock( opts *bind.CallOpts, quorumNumbers types.QuorumNums, @@ -130,6 +136,8 @@ func (r *ChainReader) GetOperatorsStakeInQuorumsAtBlock( return operatorStakes, nil } +// Returns, for each quorum in `quorumNumbers`, a vector of the addresses of the +// operators registered for that quorum at the current block. func (r *ChainReader) GetOperatorAddrsInQuorumsAtCurrentBlock( opts *bind.CallOpts, quorumNumbers types.QuorumNums, @@ -137,7 +145,6 @@ func (r *ChainReader) GetOperatorAddrsInQuorumsAtCurrentBlock( if r.operatorStateRetriever == nil { return nil, errors.New("OperatorStateRetriever contract not provided") } - if opts.Context == nil { opts.Context = context.Background() } @@ -169,6 +176,10 @@ func (r *ChainReader) GetOperatorAddrsInQuorumsAtCurrentBlock( } +// Returns a tuple containing +// - An array with the quorum IDs in which the given operator is registered at the given block +// - An array that contains, for each quorum, an array with the address, id and stake +// of each operator registered in that quorum. func (r *ChainReader) GetOperatorsStakeInQuorumsOfOperatorAtBlock( opts *bind.CallOpts, operatorId types.OperatorId, @@ -261,6 +272,8 @@ func (r *ChainReader) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock( return quorumStakes, nil } +// Returns a struct containing the indices of the quorum members that signed, +// and the ones that didn't. func (r *ChainReader) GetCheckSignaturesIndices( opts *bind.CallOpts, referenceBlockNumber uint32, @@ -293,6 +306,7 @@ func (r *ChainReader) GetCheckSignaturesIndices( return checkSignatureIndices, nil } +// Given an operator address, returns its ID. func (r *ChainReader) GetOperatorId( opts *bind.CallOpts, operatorAddress common.Address, @@ -311,6 +325,7 @@ func (r *ChainReader) GetOperatorId( return operatorId, nil } +// Given an operator ID, returns its address. func (r *ChainReader) GetOperatorFromId( opts *bind.CallOpts, operatorId types.OperatorId, @@ -329,6 +344,8 @@ func (r *ChainReader) GetOperatorFromId( return operatorAddress, nil } +// Returns an array of booleans, where the boolean at index i represents +// whether the operator is registered for the quorum i. func (r *ChainReader) QueryRegistrationDetail( opts *bind.CallOpts, operatorAddress common.Address, @@ -358,6 +375,7 @@ func (r *ChainReader) QueryRegistrationDetail( return quorums, nil } +// Returns true if the operator is registered, false otherwise. func (r *ChainReader) IsOperatorRegistered( opts *bind.CallOpts, operatorAddress common.Address, @@ -376,6 +394,9 @@ func (r *ChainReader) IsOperatorRegistered( return registeredWithAvs, nil } +// Queries existing operators for a particular block range. +// Returns two arrays. The first one contains the addresses +// of the operators, and the second contains their corresponding public keys. func (r *ChainReader) QueryExistingRegisteredOperatorPubKeys( ctx context.Context, startBlock *big.Int, @@ -475,6 +496,9 @@ func (r *ChainReader) QueryExistingRegisteredOperatorPubKeys( return operatorAddresses, operatorPubkeys, nil } +// Queries existing operator sockets for a particular block range. +// Returns a mapping containing operator IDs as keys and their +// corresponding sockets as values. func (r *ChainReader) QueryExistingRegisteredOperatorSockets( ctx context.Context, startBlock *big.Int, diff --git a/chainio/clients/avsregistry/subscriber_test.go b/chainio/clients/avsregistry/subscriber_test.go new file mode 100644 index 00000000..0cdf2aaa --- /dev/null +++ b/chainio/clients/avsregistry/subscriber_test.go @@ -0,0 +1,76 @@ +package avsregistry_test + +import ( + "context" + "testing" + "time" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/testutils" + "github.com/Layr-Labs/eigensdk-go/testutils/testclients" + "github.com/Layr-Labs/eigensdk-go/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSubscriberAvsRegistry(t *testing.T) { + client, _ := testclients.BuildTestClients(t) + chainSubscriber := client.AvsRegistryChainSubscriber + chainWriter := client.AvsRegistryChainWriter + + t.Run("subscribe to new pubkey registrations", func(t *testing.T) { + pubKeyRegistrationsC, event, err := chainSubscriber.SubscribeToNewPubkeyRegistrations() + require.NoError(t, err) + defer event.Unsubscribe() + + // Emit a NewPubkeyRegistration event creating a new operator + keypair, err := bls.NewKeyPairFromString("0x01") + require.NoError(t, err) + + ecdsaPrivateKey, err := crypto.HexToECDSA(testutils.ANVIL_FIRST_PRIVATE_KEY) + require.NoError(t, err) + + quorumNumbers := types.QuorumNums{0} + + receipt, err := chainWriter.RegisterOperator( + context.Background(), + ecdsaPrivateKey, + keypair, + quorumNumbers, + "", + true, + ) + require.NoError(t, err) + require.NotNil(t, receipt) + + select { + case newPubkeyRegistration := <-pubKeyRegistrationsC: + expectedOperator := crypto.PubkeyToAddress(ecdsaPrivateKey.PublicKey) + assert.Equal(t, expectedOperator, newPubkeyRegistration.Operator) + case <-time.After(10 * time.Second): + // Throw an error if the event is not received within 10 seconds, making the test fail + t.Fatal("Timed out waiting for NewPubkeyRegistration event") + } + }) + + t.Run("subscribe to operator socket updates", func(t *testing.T) { + socketC, event, err := chainSubscriber.SubscribeToOperatorSocketUpdates() + require.NoError(t, err) + defer event.Unsubscribe() + + // Emit a SocketUpdate event + socketUpdate := "socket-update" + receipt, err := chainWriter.UpdateSocket(context.Background(), types.Socket(socketUpdate), true) + require.NoError(t, err) + require.NotNil(t, receipt) + + select { + case operatorSocketUpdate := <-socketC: + assert.Equal(t, socketUpdate, operatorSocketUpdate.Socket) + case <-time.After(10 * time.Second): + // Throw an error if the event is not received within 10 seconds, making the test fail + t.Fatal("Timed out waiting for OperatorSocketUpdate event") + } + }) +} diff --git a/chainio/clients/avsregistry/writer.go b/chainio/clients/avsregistry/writer.go index 99e5ec1a..aa22d12d 100644 --- a/chainio/clients/avsregistry/writer.go +++ b/chainio/clients/avsregistry/writer.go @@ -35,6 +35,8 @@ type eLReader interface { ) ([32]byte, error) } +// The ChainWriter provides methods to call the +// AVS registry contract's state-changing functions. type ChainWriter struct { serviceManagerAddr gethcommon.Address registryCoordinator *regcoord.ContractRegistryCoordinator @@ -47,6 +49,7 @@ type ChainWriter struct { txMgr txmgr.TxManager } +// Returns a new instance of ChainWriter. func NewChainWriter( serviceManagerAddr gethcommon.Address, registryCoordinator *regcoord.ContractRegistryCoordinator, @@ -380,6 +383,8 @@ func (w *ChainWriter) UpdateStakesOfEntireOperatorSetForQuorums( } +// Updates the stakes of a the given `operators` for all the quorums. +// On success, returns the receipt of the transaction. func (w *ChainWriter) UpdateStakesOfOperatorSubsetForAllQuorums( ctx context.Context, operators []gethcommon.Address, @@ -408,6 +413,8 @@ func (w *ChainWriter) UpdateStakesOfOperatorSubsetForAllQuorums( return receipt, nil } +// Deregisters the caller from the quorums given by `quorumNumbers`. +// On success, returns the receipt of the transaction. func (w *ChainWriter) DeregisterOperator( ctx context.Context, quorumNumbers types.QuorumNums, @@ -435,6 +442,8 @@ func (w *ChainWriter) DeregisterOperator( return receipt, nil } +// Deregisters an operator from the given operator sets. +// On success, returns the receipt of the transaction. func (w *ChainWriter) DeregisterOperatorOperatorSets( ctx context.Context, operatorSetIds types.OperatorSetIds, @@ -465,6 +474,8 @@ func (w *ChainWriter) DeregisterOperatorOperatorSets( return receipt, nil } +// Updates the socket of the sender (if it is a registered operator). +// On success, returns the receipt of the transaction. func (w *ChainWriter) UpdateSocket( ctx context.Context, socket types.Socket, diff --git a/chainio/clients/eigenpod/bindings/IEigenPodManager.go b/chainio/clients/eigenpod/bindings/IEigenPodManager.go index 8fb2afa7..03326c77 100644 --- a/chainio/clients/eigenpod/bindings/IEigenPodManager.go +++ b/chainio/clients/eigenpod/bindings/IEigenPodManager.go @@ -31,7 +31,7 @@ var ( // IEigenPodManagerMetaData contains all meta data concerning the IEigenPodManager contract. var IEigenPodManagerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainSlashingFactor\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"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\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerDepositShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"prevRestakedBalanceWei\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"balanceDeltaWei\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeDepositShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"depositSharesToRemove\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"stakerDepositShares\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"depositShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainSlashingFactorDecreased\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"prevBeaconChainSlashingFactor\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newBeaconChainSlashingFactor\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTotalShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newTotalShares\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"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\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"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},{\"type\":\"error\",\"name\":\"CurrentlyPaused\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EigenPodAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InputAddressZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidNewPausedStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStrategy\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LegacyWithdrawalsNotCompleted\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyDelegationManager\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyEigenPod\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyPauser\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyUnpauser\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SharesNegative\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SharesNotMultipleOfGwei\",\"inputs\":[]}]", + ABI: "[{\"type\":\"function\",\"name\":\"addShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"beaconChainETHStrategy\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"beaconChainSlashingFactor\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burnableETHShares\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createPod\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eigenPodBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ethPOS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIETHPOSDeposit\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"increaseBurnableShares\",\"inputs\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"addedSharesToBurn\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"numPods\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerToPod\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIEigenPod\"}],\"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\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"podOwnerDepositShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recordBeaconChainETHBalanceUpdate\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"prevRestakedBalanceWei\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"balanceDeltaWei\",\"type\":\"int256\",\"internalType\":\"int256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeDepositShares\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"depositSharesToRemove\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[{\"name\":\"pubkey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"depositDataRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"stakerDepositShares\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"}],\"outputs\":[{\"name\":\"depositShares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawSharesAsTokens\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"shares\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BeaconChainETHDeposited\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainETHWithdrawalCompleted\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"delegatedAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconChainSlashingFactorDecreased\",\"inputs\":[{\"name\":\"staker\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"prevBeaconChainSlashingFactor\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"newBeaconChainSlashingFactor\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BurnableETHSharesIncreased\",\"inputs\":[{\"name\":\"shares\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTotalShares\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newTotalShares\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"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\":\"PodDeployed\",\"inputs\":[{\"name\":\"eigenPod\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PodSharesUpdated\",\"inputs\":[{\"name\":\"podOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sharesDelta\",\"type\":\"int256\",\"indexed\":false,\"internalType\":\"int256\"}],\"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},{\"type\":\"error\",\"name\":\"CurrentlyPaused\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EigenPodAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InputAddressZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidNewPausedStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStrategy\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LegacyWithdrawalsNotCompleted\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyDelegationManager\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyEigenPod\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyPauser\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyUnpauser\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SharesNegative\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SharesNotMultipleOfGwei\",\"inputs\":[]}]", } // IEigenPodManagerABI is the input ABI used to generate the binding from. @@ -242,6 +242,37 @@ func (_IEigenPodManager *IEigenPodManagerCallerSession) BeaconChainSlashingFacto return _IEigenPodManager.Contract.BeaconChainSlashingFactor(&_IEigenPodManager.CallOpts, staker) } +// BurnableETHShares is a free data retrieval call binding the contract method 0xf5d4fed3. +// +// Solidity: function burnableETHShares() view returns(uint256) +func (_IEigenPodManager *IEigenPodManagerCaller) BurnableETHShares(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IEigenPodManager.contract.Call(opts, &out, "burnableETHShares") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BurnableETHShares is a free data retrieval call binding the contract method 0xf5d4fed3. +// +// Solidity: function burnableETHShares() view returns(uint256) +func (_IEigenPodManager *IEigenPodManagerSession) BurnableETHShares() (*big.Int, error) { + return _IEigenPodManager.Contract.BurnableETHShares(&_IEigenPodManager.CallOpts) +} + +// BurnableETHShares is a free data retrieval call binding the contract method 0xf5d4fed3. +// +// Solidity: function burnableETHShares() view returns(uint256) +func (_IEigenPodManager *IEigenPodManagerCallerSession) BurnableETHShares() (*big.Int, error) { + return _IEigenPodManager.Contract.BurnableETHShares(&_IEigenPodManager.CallOpts) +} + // EigenPodBeacon is a free data retrieval call binding the contract method 0x292b7b2b. // // Solidity: function eigenPodBeacon() view returns(address) @@ -625,6 +656,27 @@ func (_IEigenPodManager *IEigenPodManagerTransactorSession) CreatePod() (*types. return _IEigenPodManager.Contract.CreatePod(&_IEigenPodManager.TransactOpts) } +// IncreaseBurnableShares is a paid mutator transaction binding the contract method 0xdebe1eab. +// +// Solidity: function increaseBurnableShares(address strategy, uint256 addedSharesToBurn) returns() +func (_IEigenPodManager *IEigenPodManagerTransactor) IncreaseBurnableShares(opts *bind.TransactOpts, strategy common.Address, addedSharesToBurn *big.Int) (*types.Transaction, error) { + return _IEigenPodManager.contract.Transact(opts, "increaseBurnableShares", strategy, addedSharesToBurn) +} + +// IncreaseBurnableShares is a paid mutator transaction binding the contract method 0xdebe1eab. +// +// Solidity: function increaseBurnableShares(address strategy, uint256 addedSharesToBurn) returns() +func (_IEigenPodManager *IEigenPodManagerSession) IncreaseBurnableShares(strategy common.Address, addedSharesToBurn *big.Int) (*types.Transaction, error) { + return _IEigenPodManager.Contract.IncreaseBurnableShares(&_IEigenPodManager.TransactOpts, strategy, addedSharesToBurn) +} + +// IncreaseBurnableShares is a paid mutator transaction binding the contract method 0xdebe1eab. +// +// Solidity: function increaseBurnableShares(address strategy, uint256 addedSharesToBurn) returns() +func (_IEigenPodManager *IEigenPodManagerTransactorSession) IncreaseBurnableShares(strategy common.Address, addedSharesToBurn *big.Int) (*types.Transaction, error) { + return _IEigenPodManager.Contract.IncreaseBurnableShares(&_IEigenPodManager.TransactOpts, strategy, addedSharesToBurn) +} + // Pause is a paid mutator transaction binding the contract method 0x136439dd. // // Solidity: function pause(uint256 newPausedStatus) returns() @@ -1202,6 +1254,140 @@ func (_IEigenPodManager *IEigenPodManagerFilterer) ParseBeaconChainSlashingFacto return event, nil } +// IEigenPodManagerBurnableETHSharesIncreasedIterator is returned from FilterBurnableETHSharesIncreased and is used to iterate over the raw logs and unpacked data for BurnableETHSharesIncreased events raised by the IEigenPodManager contract. +type IEigenPodManagerBurnableETHSharesIncreasedIterator struct { + Event *IEigenPodManagerBurnableETHSharesIncreased // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IEigenPodManagerBurnableETHSharesIncreasedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IEigenPodManagerBurnableETHSharesIncreased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IEigenPodManagerBurnableETHSharesIncreased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IEigenPodManagerBurnableETHSharesIncreasedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IEigenPodManagerBurnableETHSharesIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IEigenPodManagerBurnableETHSharesIncreased represents a BurnableETHSharesIncreased event raised by the IEigenPodManager contract. +type IEigenPodManagerBurnableETHSharesIncreased struct { + Shares *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBurnableETHSharesIncreased is a free log retrieval operation binding the contract event 0x1ed04b7fd262c0d9e50fa02957f32a81a151f03baaa367faeedc7521b001c4a4. +// +// Solidity: event BurnableETHSharesIncreased(uint256 shares) +func (_IEigenPodManager *IEigenPodManagerFilterer) FilterBurnableETHSharesIncreased(opts *bind.FilterOpts) (*IEigenPodManagerBurnableETHSharesIncreasedIterator, error) { + + logs, sub, err := _IEigenPodManager.contract.FilterLogs(opts, "BurnableETHSharesIncreased") + if err != nil { + return nil, err + } + return &IEigenPodManagerBurnableETHSharesIncreasedIterator{contract: _IEigenPodManager.contract, event: "BurnableETHSharesIncreased", logs: logs, sub: sub}, nil +} + +// WatchBurnableETHSharesIncreased is a free log subscription operation binding the contract event 0x1ed04b7fd262c0d9e50fa02957f32a81a151f03baaa367faeedc7521b001c4a4. +// +// Solidity: event BurnableETHSharesIncreased(uint256 shares) +func (_IEigenPodManager *IEigenPodManagerFilterer) WatchBurnableETHSharesIncreased(opts *bind.WatchOpts, sink chan<- *IEigenPodManagerBurnableETHSharesIncreased) (event.Subscription, error) { + + logs, sub, err := _IEigenPodManager.contract.WatchLogs(opts, "BurnableETHSharesIncreased") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IEigenPodManagerBurnableETHSharesIncreased) + if err := _IEigenPodManager.contract.UnpackLog(event, "BurnableETHSharesIncreased", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBurnableETHSharesIncreased is a log parse operation binding the contract event 0x1ed04b7fd262c0d9e50fa02957f32a81a151f03baaa367faeedc7521b001c4a4. +// +// Solidity: event BurnableETHSharesIncreased(uint256 shares) +func (_IEigenPodManager *IEigenPodManagerFilterer) ParseBurnableETHSharesIncreased(log types.Log) (*IEigenPodManagerBurnableETHSharesIncreased, error) { + event := new(IEigenPodManagerBurnableETHSharesIncreased) + if err := _IEigenPodManager.contract.UnpackLog(event, "BurnableETHSharesIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // IEigenPodManagerNewTotalSharesIterator is returned from FilterNewTotalShares and is used to iterate over the raw logs and unpacked data for NewTotalShares events raised by the IEigenPodManager contract. type IEigenPodManagerNewTotalSharesIterator struct { Event *IEigenPodManagerNewTotalShares // Event containing the contract specifics and raw log diff --git a/chainio/clients/eigenpod/generate.sh b/chainio/clients/eigenpod/generate.sh index ad8c97b7..78cd21ac 100755 --- a/chainio/clients/eigenpod/generate.sh +++ b/chainio/clients/eigenpod/generate.sh @@ -6,6 +6,8 @@ # of the EigenPods client, we need to generate the bindings for the contracts in the feat/partial-withdrawal-batching branch. # Once eigenlayer-contracts repo is stable and features are on single branch, we can move the bindings back to normal process +set -e + TMP_DIR=$(mktemp -d) BINDINGS_DIR=bindings @@ -16,7 +18,7 @@ cleanup_bindings_dir() { clone() { echo "Cloning the EigenLayer contracts repository" - git clone -b slashing-magnitudes --depth=1 git@github.com:Layr-Labs/eigenlayer-contracts.git "${TMP_DIR}" + git clone -b slashing-magnitudes --depth=1 https://github.com/Layr-Labs/eigenlayer-contracts.git "${TMP_DIR}" } generate_bindings() { @@ -56,4 +58,4 @@ main() { cleanup } -main \ No newline at end of file +main diff --git a/chainio/clients/elcontracts/writer.go b/chainio/clients/elcontracts/writer.go index e2726bd5..1e33e6d4 100644 --- a/chainio/clients/elcontracts/writer.go +++ b/chainio/clients/elcontracts/writer.go @@ -37,6 +37,8 @@ type Reader interface { ) (*strategy.ContractIStrategy, erc20.ContractIERC20Methods, gethcommon.Address, error) } +// The ChainWriter provides methods to call the +// EigenLayer core contract's state-changing functions. type ChainWriter struct { delegationManager *delegationmanager.ContractDelegationManager strategyManager *strategymanager.ContractStrategyManager @@ -51,6 +53,7 @@ type ChainWriter struct { txMgr txmgr.TxManager } +// Returns a new instance of ChainWriter. func NewChainWriter( delegationManager *delegationmanager.ContractDelegationManager, strategyManager *strategymanager.ContractStrategyManager, @@ -82,6 +85,7 @@ func NewChainWriter( } } +// Returns a new instance of ChainWriter from a given config. func NewWriterFromConfig( cfg Config, ethClient eth.HttpBackend, @@ -123,6 +127,8 @@ func NewWriterFromConfig( ), nil } +// Registers the caller as an operator in EigenLayer through the +// DelegationManager contract. func (w *ChainWriter) RegisterAsOperator( ctx context.Context, operator types.Operator, @@ -156,6 +162,9 @@ func (w *ChainWriter) RegisterAsOperator( return receipt, nil } +// Updates an operator's stored `delegationApprover` with +// the given `operator.DelegationApproverAddress` by calling +// the `modifyOperatorDetails` function in the DelegationManager contract. func (w *ChainWriter) UpdateOperatorDetails( ctx context.Context, operator types.Operator, @@ -195,6 +204,7 @@ func (w *ChainWriter) UpdateOperatorDetails( return receipt, nil } +// Updates the metadata URI for the given operator. func (w *ChainWriter) UpdateMetadataURI( ctx context.Context, operatorAddress gethcommon.Address, @@ -227,6 +237,8 @@ func (w *ChainWriter) UpdateMetadataURI( return receipt, nil } +// Deposits `amount` of the `strategyAddr` underlying token +// into the strategy given by `strategyAddr`. func (w *ChainWriter) DepositERC20IntoStrategy( ctx context.Context, strategyAddr gethcommon.Address, @@ -272,6 +284,9 @@ func (w *ChainWriter) DepositERC20IntoStrategy( return receipt, nil } +// Sets `claimer` as the claimer for the earner (in this case the +// earner is the caller). That means that `claimer` can call `processClaim` +// on behalf of the earner. func (w *ChainWriter) SetClaimerFor( ctx context.Context, claimer gethcommon.Address, @@ -298,6 +313,8 @@ func (w *ChainWriter) SetClaimerFor( return receipt, nil } +// Processes the given `claim` for rewards. +// The rewards are transferred to the given `recipientAddress`. func (w *ChainWriter) ProcessClaim( ctx context.Context, claim rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim, @@ -325,6 +342,10 @@ func (w *ChainWriter) ProcessClaim( return receipt, nil } +// Sets the split for a specific operator for a specific AVS. +// The caller must be a registered operator. +// The split has to be between 0 and 10000 bips (inclusive). +// The split will be activated after activation delay. func (w *ChainWriter) SetOperatorAVSSplit( ctx context.Context, operator gethcommon.Address, @@ -353,6 +374,10 @@ func (w *ChainWriter) SetOperatorAVSSplit( return receipt, nil } +// Sets the split for a specific operator for Programmatic Incentives. +// The caller must be a registered operator. +// The split has to be between 0 and 10000 bips (inclusive). +// The split will be activated after activation delay. func (w *ChainWriter) SetOperatorPISplit( ctx context.Context, operator gethcommon.Address, @@ -380,6 +405,8 @@ func (w *ChainWriter) SetOperatorPISplit( return receipt, nil } +// Processes the claims given by `claims`. +// The rewards are transferred to the given `recipientAddress`. func (w *ChainWriter) ProcessClaims( ctx context.Context, claims []rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim, @@ -411,6 +438,9 @@ func (w *ChainWriter) ProcessClaims( return receipt, nil } +// Deregisters an operator from each of the operator sets given by +// `operatorSetIds` for the given AVS, by calling the function +// `deregisterFromOperatorSets` in the AllocationManager. func (w *ChainWriter) ForceDeregisterFromOperatorSets( ctx context.Context, operator gethcommon.Address, @@ -448,6 +478,8 @@ func (w *ChainWriter) ForceDeregisterFromOperatorSets( return receipt, nil } +// Modifies the proportions of slashable stake allocated to an operator set +// from a list of strategies, for the given `operatorAddress`. func (w *ChainWriter) ModifyAllocations( ctx context.Context, operatorAddress gethcommon.Address, @@ -476,6 +508,10 @@ func (w *ChainWriter) ModifyAllocations( return receipt, nil } +// Sets the allocation delay for an operator. +// The allocation delay is the number of blocks between the operator +// allocating a magnitude to an operator set, and the magnitude becoming +// slashable. func (w *ChainWriter) SetAllocationDelay( ctx context.Context, operatorAddress gethcommon.Address, @@ -503,6 +539,9 @@ func (w *ChainWriter) SetAllocationDelay( return receipt, nil } +// Deregister an operator from one or more of the AVS's operator sets. +// If the operator has any slashable stake allocated to the AVS, +// it remains slashable until the deallocation delay has passed. func (w *ChainWriter) DeregisterFromOperatorSets( ctx context.Context, operator gethcommon.Address, @@ -536,6 +575,9 @@ func (w *ChainWriter) DeregisterFromOperatorSets( return receipt, nil } +// Register an operator for one or more operator sets for an AVS. +// If the operator has any stake allocated to these operator sets, +// it immediately becomes slashable. func (w *ChainWriter) RegisterForOperatorSets( ctx context.Context, registryCoordinatorAddr gethcommon.Address, @@ -584,6 +626,8 @@ func (w *ChainWriter) RegisterForOperatorSets( return receipt, nil } +// Removes permission of an appointee for a specific function +// (given by request.selector) on a target contract, given an account address. func (w *ChainWriter) RemovePermission( ctx context.Context, request RemovePermissionRequest, @@ -599,6 +643,7 @@ func (w *ChainWriter) RemovePermission( return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Builds a transaction for the PermissionController's removeAppointee function. func (w *ChainWriter) NewRemovePermissionTx( txOpts *bind.TransactOpts, request RemovePermissionRequest, @@ -616,6 +661,7 @@ func (w *ChainWriter) NewRemovePermissionTx( ) } +// Builds a transaction for the PermissionController's setAppointee function. func (w *ChainWriter) NewSetPermissionTx( txOpts *bind.TransactOpts, request SetPermissionRequest, @@ -632,6 +678,10 @@ func (w *ChainWriter) NewSetPermissionTx( ) } +// Set an appointee for a given account. +// Only the admin of the account can set an appointee. +// The appointee will be able to call the function given +// by `request.Selector` on the contract given by `request.Target`. func (w *ChainWriter) SetPermission( ctx context.Context, request SetPermissionRequest, @@ -649,6 +699,7 @@ func (w *ChainWriter) SetPermission( return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Builds a transaction for the PermissionController's acceptAdmin function. func (w *ChainWriter) NewAcceptAdminTx( txOpts *bind.TransactOpts, request AcceptAdminRequest, @@ -659,6 +710,8 @@ func (w *ChainWriter) NewAcceptAdminTx( return w.permissionController.AcceptAdmin(txOpts, request.AccountAddress) } +// Accept a pending admin for the account given by `request.AccountAddress`. +// The sender of the transaction must be the pending admin. func (w *ChainWriter) AcceptAdmin( ctx context.Context, request AcceptAdminRequest, @@ -675,6 +728,7 @@ func (w *ChainWriter) AcceptAdmin( return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Builds a transaction for the PermissionController's addPendingAdmin function. func (w *ChainWriter) NewAddPendingAdminTx( txOpts *bind.TransactOpts, request AddPendingAdminRequest, @@ -685,6 +739,9 @@ func (w *ChainWriter) NewAddPendingAdminTx( return w.permissionController.AddPendingAdmin(txOpts, request.AccountAddress, request.AdminAddress) } +// Set a pending admin. Multiple admins can be set for an account. +// The caller must be an admin. If the account does not have an admin, +// the caller must be the account. func (w *ChainWriter) AddPendingAdmin(ctx context.Context, request AddPendingAdminRequest) (*gethtypes.Receipt, error) { txOpts, err := w.txMgr.GetNoSendTxOpts() if err != nil { @@ -697,6 +754,7 @@ func (w *ChainWriter) AddPendingAdmin(ctx context.Context, request AddPendingAdm return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Builds a transaction for the PermissionController's removeAdmin function. func (w *ChainWriter) NewRemoveAdminTx( txOpts *bind.TransactOpts, request RemoveAdminRequest, @@ -707,6 +765,8 @@ func (w *ChainWriter) NewRemoveAdminTx( return w.permissionController.RemoveAdmin(txOpts, request.AccountAddress, request.AdminAddress) } +// Removes the admin given by `request.AdminAddress` from the account given +// by `request.AccountAddress`. The sender of the transaction must be an admin. func (w *ChainWriter) RemoveAdmin( ctx context.Context, request RemoveAdminRequest, @@ -723,6 +783,7 @@ func (w *ChainWriter) RemoveAdmin( return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Builds a transaction for the PermissionController's removePendingAdmin function. func (w *ChainWriter) NewRemovePendingAdminTx( txOpts *bind.TransactOpts, request RemovePendingAdminRequest, @@ -733,6 +794,8 @@ func (w *ChainWriter) NewRemovePendingAdminTx( return w.permissionController.RemovePendingAdmin(txOpts, request.AccountAddress, request.AdminAddress) } +// Remove pending admin given by `request.AdminAddress` from the account given +// by `request.AccountAddress`. Only the admin of the account can remove a pending admin. func (w *ChainWriter) RemovePendingAdmin( ctx context.Context, request RemovePendingAdminRequest, @@ -750,6 +813,7 @@ func (w *ChainWriter) RemovePendingAdmin( return w.txMgr.Send(ctx, tx, request.WaitForReceipt) } +// Returns the pubkey registration params for the operator given by `operatorAddress`. func getPubkeyRegistrationParams( ethClient bind.ContractBackend, registryCoordinatorAddr, operatorAddress gethcommon.Address, @@ -780,6 +844,7 @@ func getPubkeyRegistrationParams( return &pubkeyRegParams, nil } +// Returns the ABI encoding of the given registration params. func abiEncodeRegistrationParams( socket string, pubkeyRegistrationParams regcoord.IBLSApkRegistryPubkeyRegistrationParams, diff --git a/chainio/clients/elcontracts/writer_test.go b/chainio/clients/elcontracts/writer_test.go index 6be122b3..ab067949 100644 --- a/chainio/clients/elcontracts/writer_test.go +++ b/chainio/clients/elcontracts/writer_test.go @@ -1123,6 +1123,338 @@ func setTestRewardsCoordinatorActivationDelay( return receipt, err } +// TestInvalidConfig tests the behavior of the chainWriter when the config is invalid (e.g. missing addresses) +func TestInvalidConfigChainWriter(t *testing.T) { + testConfig := testutils.GetDefaultTestConfig() + anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName) + require.NoError(t, err) + + anvilHttpEndpoint, err := anvilC.Endpoint(context.Background(), "http") + require.NoError(t, err) + + contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint) + anvilFirstAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS) + + operatorAddr := testutils.ANVIL_FIRST_ADDRESS + operator := types.Operator{ + Address: operatorAddr, + } + + privateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY + + config := elcontracts.Config{} + chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, privateKeyHex, config) + require.NoError(t, err) + + t.Run("register as operator", func(t *testing.T) { + receipt, err := chainWriter.RegisterAsOperator( + context.Background(), + operator, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("update operator details", func(t *testing.T) { + receipt, err := chainWriter.UpdateOperatorDetails( + context.Background(), + operator, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("update metadata URI", func(t *testing.T) { + receipt, err := chainWriter.UpdateMetadataURI( + context.Background(), + anvilFirstAddr, + "https://0.0.0.0", + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("deposit erc20 into strategy", func(t *testing.T) { + receipt, err := chainWriter.DepositERC20IntoStrategy( + context.Background(), + contractAddrs.Erc20MockStrategy, + big.NewInt(1), + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("set claimer for", func(t *testing.T) { + receipt, err := chainWriter.SetClaimerFor( + context.Background(), + anvilFirstAddr, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("process claim and process claims", func(t *testing.T) { + rewardsCoordinatorAddr := contractAddrs.RewardsCoordinator + config := elcontracts.Config{ + DelegationManagerAddress: contractAddrs.DelegationManager, + RewardsCoordinatorAddress: rewardsCoordinatorAddr, + } + chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config) + require.NoError(t, err) + + activationDelay := uint32(0) + receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, privateKeyHex, activationDelay) + require.NoError(t, err) + require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status) + + cumulativeEarnings := int64(42) + claim, err := newTestClaim(chainReader, anvilHttpEndpoint, cumulativeEarnings, privateKeyHex) + require.NoError(t, err) + + receipt, err = chainWriter.ProcessClaim( + context.Background(), + *claim, + anvilFirstAddr, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + + receipt, err = chainWriter.ProcessClaims( + context.Background(), + []rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim{*claim}, + anvilFirstAddr, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("set operator AVS split", func(t *testing.T) { + receipt, err := chainWriter.SetOperatorAVSSplit( + context.Background(), + common.HexToAddress(operatorAddr), + anvilFirstAddr, + uint16(1), + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("set operator PI split", func(t *testing.T) { + receipt, err := chainWriter.SetOperatorPISplit( + context.Background(), + common.HexToAddress(operatorAddr), + uint16(1), + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("modify allocations", func(t *testing.T) { + strategyAddr := contractAddrs.Erc20MockStrategy + avsAddr := anvilFirstAddr + operatorSetId := uint32(1) + + operatorSet := allocationmanager.OperatorSet{ + Avs: avsAddr, + Id: operatorSetId, + } + newAllocation := uint64(100) + allocateParams := []allocationmanager.IAllocationManagerTypesAllocateParams{ + { + OperatorSet: operatorSet, + Strategies: []common.Address{strategyAddr}, + NewMagnitudes: []uint64{newAllocation}, + }, + } + + receipt, err := chainWriter.ModifyAllocations( + context.Background(), + common.HexToAddress(operatorAddr), + allocateParams, + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("set allocation delay", func(t *testing.T) { + receipt, err := chainWriter.SetAllocationDelay( + context.Background(), + common.HexToAddress(operatorAddr), + uint32(0), + true, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("deregister from operator sets", func(t *testing.T) { + avsAddress := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS) + operatorSetId := uint32(1) + deregistrationRequest := elcontracts.DeregistrationRequest{ + AVSAddress: avsAddress, + OperatorSetIds: []uint32{operatorSetId}, + WaitForReceipt: true, + } + + receipt, err := chainWriter.DeregisterFromOperatorSets( + context.Background(), + common.HexToAddress(operatorAddr), + deregistrationRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("register for operator sets", func(t *testing.T) { + operatorAddress := common.HexToAddress(testutils.ANVIL_SECOND_ADDRESS) + keypair, err := bls.NewKeyPairFromString("0x01") + require.NoError(t, err) + + avsAddress := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS) + operatorSetId := uint32(1) + + request := elcontracts.RegistrationRequest{ + OperatorAddress: operatorAddress, + AVSAddress: avsAddress, + OperatorSetIds: []uint32{operatorSetId}, + WaitForReceipt: true, + Socket: "socket", + BlsKeyPair: keypair, + } + + receipt, err := chainWriter.RegisterForOperatorSets( + context.Background(), + common.HexToAddress(operatorAddr), + request, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("remove permission", func(t *testing.T) { + accountAddress := anvilFirstAddr + appointeeAddress := common.HexToAddress(testutils.ANVIL_SECOND_ADDRESS) + target := common.HexToAddress(testutils.ANVIL_THIRD_ADDRESS) + selector := [4]byte{0, 1, 2, 3} + waitForReceipt := true + + removePermissionRequest := elcontracts.RemovePermissionRequest{ + AccountAddress: accountAddress, + AppointeeAddress: appointeeAddress, + Target: target, + Selector: selector, + WaitForReceipt: waitForReceipt, + } + + receipt, err := chainWriter.RemovePermission( + context.Background(), + removePermissionRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("set permission", func(t *testing.T) { + accountAddress := anvilFirstAddr + appointeeAddress := common.HexToAddress(testutils.ANVIL_SECOND_ADDRESS) + target := common.HexToAddress(testutils.ANVIL_THIRD_ADDRESS) + selector := [4]byte{0, 1, 2, 3} + waitForReceipt := true + + setPermissionRequest := elcontracts.SetPermissionRequest{ + AccountAddress: accountAddress, + AppointeeAddress: appointeeAddress, + Target: target, + Selector: selector, + WaitForReceipt: waitForReceipt, + } + + receipt, err := chainWriter.SetPermission( + context.Background(), + setPermissionRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("accept admin", func(t *testing.T) { + accountAddress := anvilFirstAddr + acceptAdminRequest := elcontracts.AcceptAdminRequest{ + AccountAddress: accountAddress, + WaitForReceipt: true, + } + + receipt, err := chainWriter.AcceptAdmin( + context.Background(), + acceptAdminRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("add pending admin", func(t *testing.T) { + accountAddress := anvilFirstAddr + admin1 := common.HexToAddress(testutils.ANVIL_SECOND_ADDRESS) + + addAdmin1Request := elcontracts.AddPendingAdminRequest{ + AccountAddress: accountAddress, + AdminAddress: admin1, + WaitForReceipt: true, + } + + receipt, err := chainWriter.AddPendingAdmin( + context.Background(), + addAdmin1Request, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("remove admin", func(t *testing.T) { + accountAddress := anvilFirstAddr + admin2 := common.HexToAddress(testutils.ANVIL_THIRD_ADDRESS) + + removeAdminRequest := elcontracts.RemoveAdminRequest{ + AccountAddress: accountAddress, + AdminAddress: admin2, + WaitForReceipt: true, + } + + receipt, err := chainWriter.RemoveAdmin( + context.Background(), + removeAdminRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) + + t.Run("remove pending admin", func(t *testing.T) { + pendingAdmin := common.HexToAddress("009440d62dc85c73dbf889b7ad1f4da8b231d2ef") + removePendingAdminRequest := elcontracts.RemovePendingAdminRequest{ + AccountAddress: common.HexToAddress(operatorAddr), + AdminAddress: pendingAdmin, + WaitForReceipt: true, + } + + receipt, err := chainWriter.RemovePendingAdmin( + context.Background(), + removePendingAdminRequest, + ) + assert.Error(t, err) + assert.Nil(t, receipt) + }) +} + // Returns a (test) claim for the given cumulativeEarnings, whose earner is // the account given by the testutils.ANVIL_FIRST_ADDRESS address. // This was taken from the eigensdk-rs diff --git a/contracts/script/DeployMockAvs.s.sol b/contracts/script/DeployMockAvs.s.sol index 892f8f9d..ecd0b4c8 100644 --- a/contracts/script/DeployMockAvs.s.sol +++ b/contracts/script/DeployMockAvs.s.sol @@ -13,17 +13,11 @@ contract DeployMockAvs is DeployMockAvsRegistries { ProxyAdmin public mockAvsProxyAdmin; function run() public virtual { - // The ContractsRegistry contract should always be deployed at this address on anvil // it's the address of the contract created at nonce 0 by the first anvil account (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266) - ContractsRegistry contractsRegistry = ContractsRegistry( - 0x5FbDB2315678afecb367f032d93F642f64180aa3 - ); - EigenlayerContracts - memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); - MockAvsOpsAddresses memory addressConfig = _loadAvsOpsAddresses( - "ops_addresses" - ); + ContractsRegistry contractsRegistry = ContractsRegistry(0x5FbDB2315678afecb367f032d93F642f64180aa3); + EigenlayerContracts memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); + MockAvsOpsAddresses memory addressConfig = _loadAvsOpsAddresses("ops_addresses"); vm.startBroadcast(); @@ -33,20 +27,10 @@ contract DeployMockAvs is DeployMockAvsRegistries { emptyContract = new EmptyContract(); mockAvsProxyAdmin = new ProxyAdmin(); mockAvsServiceManager = MockAvsServiceManager( - address( - new TransparentUpgradeableProxy( - address(emptyContract), - address(mockAvsProxyAdmin), - "" - ) - ) + address(new TransparentUpgradeableProxy(address(emptyContract), address(mockAvsProxyAdmin), "")) ); - MockAvsContracts - memory mockAvsContracts = _deploymockAvsRegistryContracts( - eigenlayerContracts, - addressConfig, - mockAvsServiceManager, - mockAvsServiceManagerImplementation + MockAvsContracts memory mockAvsContracts = _deploymockAvsRegistryContracts( + eigenlayerContracts, addressConfig, mockAvsServiceManager, mockAvsServiceManagerImplementation ); console.log("HERE16"); @@ -64,26 +48,14 @@ contract DeployMockAvs is DeployMockAvsRegistries { console.log("HERE17"); mockAvsProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy( - payable(address(mockAvsServiceManager)) - ), + TransparentUpgradeableProxy(payable(address(mockAvsServiceManager))), address(mockAvsServiceManagerImplementation), - abi.encodeWithSelector( - mockAvsServiceManager.initialize.selector, - addressConfig.communityMultisig - ) - ); - require( - Ownable(address(mockAvsServiceManager)).owner() != address(0), - "Owner uninitialized" + abi.encodeWithSelector(mockAvsServiceManager.initialize.selector, addressConfig.communityMultisig) ); + require(Ownable(address(mockAvsServiceManager)).owner() != address(0), "Owner uninitialized"); if (block.chainid == 31337 || block.chainid == 1337) { - _writeContractsToRegistry( - contractsRegistry, - eigenlayerContracts, - mockAvsContracts - ); + _writeContractsToRegistry(contractsRegistry, eigenlayerContracts, mockAvsContracts); } vm.stopBroadcast(); } diff --git a/contracts/script/DeployMockAvsRegistries.s.sol b/contracts/script/DeployMockAvsRegistries.s.sol index 9a01626f..963294d9 100644 --- a/contracts/script/DeployMockAvsRegistries.s.sol +++ b/contracts/script/DeployMockAvsRegistries.s.sol @@ -9,7 +9,12 @@ import {IStrategyManager, IStrategy} from "eigenlayer-contracts/src/contracts/in import "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import "eigenlayer-middleware/src/RegistryCoordinator.sol" as blsregcoord; import {IServiceManager} from "eigenlayer-middleware/src/interfaces/IServiceManager.sol"; -import {IBLSApkRegistry, IIndexRegistry, IStakeRegistry, StakeType} from "eigenlayer-middleware/src/RegistryCoordinator.sol"; +import { + IBLSApkRegistry, + IIndexRegistry, + IStakeRegistry, + StakeType +} from "eigenlayer-middleware/src/RegistryCoordinator.sol"; import {BLSApkRegistry} from "eigenlayer-middleware/src/BLSApkRegistry.sol"; import {IndexRegistry} from "eigenlayer-middleware/src/IndexRegistry.sol"; import {StakeRegistry} from "eigenlayer-middleware/src/StakeRegistry.sol"; @@ -75,11 +80,7 @@ contract DeployMockAvsRegistries is Script, ConfigsReadWriter, EigenlayerContrac require(Ownable(address(deployed.coordinator)).owner() != address(0), "Owner uninitialized"); _writeDeploymentOutput(manager, managerImpl); - return MockAvsContracts( - manager, - deployed.coordinator, - deployed.stateRetriever - ); + return MockAvsContracts(manager, deployed.coordinator, deployed.stateRetriever); } function _deployPauserRegistry(MockAvsOpsAddresses memory config) internal { @@ -103,31 +104,21 @@ contract DeployMockAvsRegistries is Script, ConfigsReadWriter, EigenlayerContrac } function _deployProxy() internal returns (address) { - return address( - new TransparentUpgradeableProxy( - address(deployed.emptyContract), - address(deployed.proxyAdmin), - "" - ) - ); + return + address(new TransparentUpgradeableProxy(address(deployed.emptyContract), address(deployed.proxyAdmin), "")); } - function _deployAndUpgradeImplementations( - EigenlayerContracts memory eigen, - MockAvsServiceManager manager - ) internal { + function _deployAndUpgradeImplementations(EigenlayerContracts memory eigen, MockAvsServiceManager manager) + internal + { registries.blsApkRegistryImplementation = new BLSApkRegistry(deployed.coordinator); _upgradeProxy(address(registries.blsApkRegistry), address(registries.blsApkRegistryImplementation)); registries.indexRegistryImplementation = new IndexRegistry(deployed.coordinator); _upgradeProxy(address(registries.indexRegistry), address(registries.indexRegistryImplementation)); - registries.stakeRegistryImplementation = new StakeRegistry( - deployed.coordinator, - eigen.delegationManager, - eigen.avsDirectory, - manager - ); + registries.stakeRegistryImplementation = + new StakeRegistry(deployed.coordinator, eigen.delegationManager, eigen.avsDirectory, manager); _upgradeProxy(address(registries.stakeRegistry), address(registries.stakeRegistryImplementation)); deployed.coordinatorImplementation = new blsregcoord.RegistryCoordinator( @@ -146,7 +137,8 @@ contract DeployMockAvsRegistries is Script, ConfigsReadWriter, EigenlayerContrac function _initializeRegistryCoordinator(MockAvsOpsAddresses memory config) internal { uint32 numQuorums = 0; - blsregcoord.RegistryCoordinator.OperatorSetParam[] memory params = new blsregcoord.RegistryCoordinator.OperatorSetParam[](numQuorums); + blsregcoord.RegistryCoordinator.OperatorSetParam[] memory params = + new blsregcoord.RegistryCoordinator.OperatorSetParam[](numQuorums); for (uint32 i = 0; i < numQuorums; i++) { params[i] = blsregcoord.IRegistryCoordinator.OperatorSetParam({ @@ -179,10 +171,7 @@ contract DeployMockAvsRegistries is Script, ConfigsReadWriter, EigenlayerContrac ); } - function _writeDeploymentOutput( - MockAvsServiceManager manager, - MockAvsServiceManager managerImpl - ) internal { + function _writeDeploymentOutput(MockAvsServiceManager manager, MockAvsServiceManager managerImpl) internal { string memory parent = "parent object"; string memory addresses = "addresses"; @@ -191,12 +180,10 @@ contract DeployMockAvsRegistries is Script, ConfigsReadWriter, EigenlayerContrac vm.serializeAddress(addresses, "mockAvsServiceManagerImplementation", address(managerImpl)); vm.serializeAddress(addresses, "registryCoordinator", address(deployed.coordinator)); vm.serializeAddress(addresses, "registryCoordinatorImplementation", address(deployed.coordinatorImplementation)); - string memory output = vm.serializeAddress(addresses, "operatorStateRetriever", address(deployed.stateRetriever)); + string memory output = + vm.serializeAddress(addresses, "operatorStateRetriever", address(deployed.stateRetriever)); - writeOutput( - vm.serializeString(parent, addresses, output), - "mockavs_deployment_output" - ); + writeOutput(vm.serializeString(parent, addresses, output), "mockavs_deployment_output"); } function _writeContractsToRegistry( diff --git a/contracts/script/DeployTokensStrategiesCreateQuorums.s.sol b/contracts/script/DeployTokensStrategiesCreateQuorums.s.sol index ce01fbe0..9f539881 100644 --- a/contracts/script/DeployTokensStrategiesCreateQuorums.s.sol +++ b/contracts/script/DeployTokensStrategiesCreateQuorums.s.sol @@ -19,24 +19,16 @@ import {ContractsRegistry} from "../src/ContractsRegistry.sol"; import "forge-std/Script.sol"; import "forge-std/StdJson.sol"; -contract DeployTokensStrategiesCreateQuorums is - Script, - EigenlayerContractsParser, - MockAvsContractsParser -{ - uint MINT_AMOUNT = 5_000 ether; +contract DeployTokensStrategiesCreateQuorums is Script, EigenlayerContractsParser, MockAvsContractsParser { + uint256 MINT_AMOUNT = 5_000 ether; function run() external { // hardcoded as first contract deployed by anvil's 0th account // (generated from mnemonic "test test test test test test test test test test test junk") // 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (sk = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80) - ContractsRegistry contractsRegistry = ContractsRegistry( - 0x5FbDB2315678afecb367f032d93F642f64180aa3 - ); - EigenlayerContracts - memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); - MockAvsContracts - memory mockAvsContracts = _loadMockAvsDeployedContracts(); + ContractsRegistry contractsRegistry = ContractsRegistry(0x5FbDB2315678afecb367f032d93F642f64180aa3); + EigenlayerContracts memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); + MockAvsContracts memory mockAvsContracts = _loadMockAvsDeployedContracts(); IStrategy strat; IERC20 mockToken; vm.startBroadcast(); @@ -47,13 +39,12 @@ contract DeployTokensStrategiesCreateQuorums is eigenlayerContracts.baseStrategyImplementation, eigenlayerContracts.strategyManager ); - contractsRegistry.registerContract( - "erc20MockStrategy", - address(strat) - ); + contractsRegistry.registerContract("erc20MockStrategy", address(strat)); } else if (block.chainid == 17000) { - strat = IStrategy(0x5C8b55722f421556a2AAfb7A3EA63d4c3e514312); /// Whitelisted stETH strat - mockToken = IERC20(0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034); /// stETH + strat = IStrategy(0x5C8b55722f421556a2AAfb7A3EA63d4c3e514312); + /// Whitelisted stETH strat + mockToken = IERC20(0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034); + /// stETH } else { revert("Configure Token and Strategy for Chain"); } @@ -90,54 +81,34 @@ contract DeployTokensStrategiesCreateQuorums is strats[0] = erc20MockStrategy; bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1); thirdPartyTransfersForbiddenValues[0] = false; - strategyManager.addStrategiesToDepositWhitelist( - strats - ); + strategyManager.addStrategiesToDepositWhitelist(strats); // WRITE JSON DATA // TODO: support more than one token/strategy pair string memory parent_object = "parent object"; string memory deployed_addresses = "addresses"; - vm.serializeAddress( - deployed_addresses, - "erc20mock", - address(mockERC20) - ); - string memory deployed_addresses_output = vm.serializeAddress( - deployed_addresses, - "erc20mockstrategy", - address(erc20MockStrategy) - ); - string memory finalJson = vm.serializeString( - parent_object, - deployed_addresses, - deployed_addresses_output - ); + vm.serializeAddress(deployed_addresses, "erc20mock", address(mockERC20)); + string memory deployed_addresses_output = + vm.serializeAddress(deployed_addresses, "erc20mockstrategy", address(erc20MockStrategy)); + string memory finalJson = vm.serializeString(parent_object, deployed_addresses, deployed_addresses_output); writeOutput(finalJson, "token_and_strategy_deployment_output"); return (IERC20(mockERC20), erc20MockStrategy); } - function _createQuorum( - regcoord.RegistryCoordinator mockAvsRegCoord, - IStrategy strat - ) internal { + function _createQuorum(regcoord.RegistryCoordinator mockAvsRegCoord, IStrategy strat) internal { // for each quorum to setup, we need to define // quorumsOperatorSetParams, quorumsMinimumStake, and quorumsStrategyParams - regcoord.RegistryCoordinator.OperatorSetParam - memory quorumOperatorSetParams = regcoord - .IRegistryCoordinator - .OperatorSetParam({ - // hardcoded for now - maxOperatorCount: 10000, - kickBIPsOfOperatorStake: 15000, - kickBIPsOfTotalStake: 100 - }); + regcoord.RegistryCoordinator.OperatorSetParam memory quorumOperatorSetParams = regcoord + .IRegistryCoordinator + .OperatorSetParam({ + // hardcoded for now + maxOperatorCount: 10000, + kickBIPsOfOperatorStake: 15000, + kickBIPsOfTotalStake: 100 + }); uint96 quorumMinimumStake = 0; - IStakeRegistry.StrategyParams[] - memory quorumStrategyParams = new IStakeRegistry.StrategyParams[]( - 1 - ); + IStakeRegistry.StrategyParams[] memory quorumStrategyParams = new IStakeRegistry.StrategyParams[](1); quorumStrategyParams[0] = IStakeRegistry.StrategyParams({ strategy: strat, // setting this to 1 ether since the divisor is also 1 ether @@ -148,9 +119,7 @@ contract DeployTokensStrategiesCreateQuorums is }); regcoord.RegistryCoordinator(address(mockAvsRegCoord)).createTotalDelegatedStakeQuorum( - quorumOperatorSetParams, - quorumMinimumStake, - quorumStrategyParams + quorumOperatorSetParams, quorumMinimumStake, quorumStrategyParams ); } } diff --git a/contracts/script/RegisterOperatorsWithEigenlayer.s.sol b/contracts/script/RegisterOperatorsWithEigenlayer.s.sol index bb7672be..38f7196b 100644 --- a/contracts/script/RegisterOperatorsWithEigenlayer.s.sol +++ b/contracts/script/RegisterOperatorsWithEigenlayer.s.sol @@ -12,11 +12,7 @@ import {ConfigsReadWriter} from "./parsers/ConfigsReadWriter.sol"; // This script registers a bunch of operators with eigenlayer // We don't register with eigencert/eigenda because events are not registered in saved anvil state, so we need to register // them at runtime whenver we start anvil for a test or localnet. -contract RegisterOperators is - ConfigsReadWriter, - EigenlayerContractsParser, - TokenAndStrategyContractsParser -{ +contract RegisterOperators is ConfigsReadWriter, EigenlayerContractsParser, TokenAndStrategyContractsParser { string internal mnemonic; uint256 internal numberOfOperators; @@ -30,25 +26,17 @@ contract RegisterOperators is } function run() external { - EigenlayerContracts - memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); - TokenAndStrategyContracts - memory tokenAndStrategy = _loadTokenAndStrategyContracts(); + EigenlayerContracts memory eigenlayerContracts = _loadEigenlayerDeployedContracts(); + TokenAndStrategyContracts memory tokenAndStrategy = _loadTokenAndStrategyContracts(); address[] memory operators = new address[](numberOfOperators); uint256[] memory operatorsETHAmount = new uint256[](numberOfOperators); - uint256[] memory operatorTokenAmounts = new uint256[]( - numberOfOperators - ); + uint256[] memory operatorTokenAmounts = new uint256[](numberOfOperators); for (uint256 i; i < numberOfOperators; i++) { - (address operator, ) = deriveRememberKey(mnemonic, uint32(i)); + (address operator,) = deriveRememberKey(mnemonic, uint32(i)); operators[i] = operator; operatorsETHAmount[i] = 5 ether; - operatorTokenAmounts[i] = bound( - uint256(keccak256(bytes.concat(bytes32(uint256(i))))), - 1 ether, - 10 ether - ); + operatorTokenAmounts[i] = bound(uint256(keccak256(bytes.concat(bytes32(uint256(i))))), 1 ether, 10 ether); } vm.startBroadcast(); @@ -56,11 +44,7 @@ contract RegisterOperators is _allocateEthOrErc20(address(0), operators, operatorsETHAmount); // Allocate tokens to operators - _allocateEthOrErc20( - address(tokenAndStrategy.token), - operators, - operatorTokenAmounts - ); + _allocateEthOrErc20(address(tokenAndStrategy.token), operators, operatorTokenAmounts); vm.stopBroadcast(); @@ -69,32 +53,19 @@ contract RegisterOperators is address delegationApprover = address(0); // anyone can delegate to this operator uint32 allocationDelay = 2; // 2 blocks uint32 stakerOptOutWindowBlocks = 100; - string memory metadataURI = string.concat( - "https://coolstuff.com/operator/", - vm.toString(i) - ); + string memory metadataURI = string.concat("https://coolstuff.com/operator/", vm.toString(i)); (, uint256 privateKey) = deriveRememberKey(mnemonic, uint32(i)); vm.startBroadcast(privateKey); - eigenlayerContracts.delegationManager.registerAsOperator( - delegationApprover, - allocationDelay, - metadataURI - ); + eigenlayerContracts.delegationManager.registerAsOperator(delegationApprover, allocationDelay, metadataURI); eigenlayerContracts.strategyManager.depositIntoStrategy( - tokenAndStrategy.strategy, - IERC20(tokenAndStrategy.token), - operatorTokenAmounts[i] + tokenAndStrategy.strategy, IERC20(tokenAndStrategy.token), operatorTokenAmounts[i] ); vm.stopBroadcast(); } } // setting token=address(0) will allocate eth - function _allocateEthOrErc20( - address token, - address[] memory tos, - uint256[] memory amounts - ) internal { + function _allocateEthOrErc20(address token, address[] memory tos, uint256[] memory amounts) internal { for (uint256 i = 0; i < tos.length; i++) { if (token == address(0)) { payable(tos[i]).transfer(amounts[i]); diff --git a/contracts/script/parsers/ConfigsReadWriter.sol b/contracts/script/parsers/ConfigsReadWriter.sol index 2a205dd0..97747545 100644 --- a/contracts/script/parsers/ConfigsReadWriter.sol +++ b/contracts/script/parsers/ConfigsReadWriter.sol @@ -10,45 +10,24 @@ import "forge-std/StdJson.sol"; contract ConfigsReadWriter is Script { // Forge scripts best practice: https://book.getfoundry.sh/tutorials/best-practices#scripts // inputFileName should not contain the .json extension, we add it automatically - function readInput( - string memory inputFileName - ) internal view returns (string memory) { - string memory inputDir = string.concat( - vm.projectRoot(), - "/script/input/" - ); + function readInput(string memory inputFileName) internal view returns (string memory) { + 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)); } - function readOutput( - string memory outputFileName - ) internal view returns (string memory) { - string memory inputDir = string.concat( - vm.projectRoot(), - "/script/output/" - ); + function readOutput(string memory outputFileName) internal view returns (string memory) { + 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/script/parsers/EigenlayerContractsParser.sol b/contracts/script/parsers/EigenlayerContractsParser.sol index ef435880..ade38097 100644 --- a/contracts/script/parsers/EigenlayerContractsParser.sol +++ b/contracts/script/parsers/EigenlayerContractsParser.sol @@ -13,9 +13,10 @@ import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/ import {ConfigsReadWriter} from "./ConfigsReadWriter.sol"; import "forge-std/StdJson.sol"; -import {IAllocationManager} from "../../lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IAllocationManager} from + "../../lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; - struct EigenlayerContracts { +struct EigenlayerContracts { ProxyAdmin eigenlayerProxyAdmin; PauserRegistry eigenlayerPauserReg; IStrategyManager strategyManager; @@ -27,75 +28,37 @@ import {IAllocationManager} from "../../lib/eigenlayer-middleware/lib/eigenlayer } contract EigenlayerContractsParser is ConfigsReadWriter { - function _loadEigenlayerDeployedContracts() - internal - view - returns (EigenlayerContracts memory) - { + function _loadEigenlayerDeployedContracts() internal view returns (EigenlayerContracts memory) { // Eigenlayer contracts - string memory eigenlayerDeployedContracts = readOutput( - "eigenlayer_deployment_output" - ); - ProxyAdmin eigenlayerProxyAdmin = ProxyAdmin( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.eigenLayerProxyAdmin" - ) - ); - PauserRegistry eigenlayerPauserReg = PauserRegistry( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.eigenLayerPauserReg" - ) - ); - IStrategyManager strategyManager = IStrategyManager( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.strategyManager" - ) - ); - IDelegationManager delegationManager = IDelegationManager( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.delegationManager" - ) - ); - IAVSDirectory avsDirectory = IAVSDirectory( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.avsDirectory" - ) - ); + string memory eigenlayerDeployedContracts = readOutput("eigenlayer_deployment_output"); + ProxyAdmin eigenlayerProxyAdmin = + ProxyAdmin(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.eigenLayerProxyAdmin")); + PauserRegistry eigenlayerPauserReg = + PauserRegistry(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.eigenLayerPauserReg")); + IStrategyManager strategyManager = + IStrategyManager(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.strategyManager")); + IDelegationManager delegationManager = + IDelegationManager(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.delegationManager")); + IAVSDirectory avsDirectory = + IAVSDirectory(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.avsDirectory")); StrategyBaseTVLLimits baseStrategyImplementation = StrategyBaseTVLLimits( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.baseStrategyImplementation" - ) - ); - - IRewardsCoordinator rewardsCoordinator = IRewardsCoordinator( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.rewardsCoordinator" - ) + stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.baseStrategyImplementation") ); - IAllocationManager allocationManager = IAllocationManager( - stdJson.readAddress( - eigenlayerDeployedContracts, - ".addresses.allocationManager" - ) + IRewardsCoordinator rewardsCoordinator = + IRewardsCoordinator(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.rewardsCoordinator")); + + IAllocationManager allocationManager = + IAllocationManager(stdJson.readAddress(eigenlayerDeployedContracts, ".addresses.allocationManager")); + return EigenlayerContracts( + eigenlayerProxyAdmin, + eigenlayerPauserReg, + strategyManager, + delegationManager, + avsDirectory, + rewardsCoordinator, + baseStrategyImplementation, + allocationManager ); - return - EigenlayerContracts( - eigenlayerProxyAdmin, - eigenlayerPauserReg, - strategyManager, - delegationManager, - avsDirectory, - rewardsCoordinator, - baseStrategyImplementation, - allocationManager - ); } } diff --git a/contracts/script/parsers/MockAvsContractsParser.sol b/contracts/script/parsers/MockAvsContractsParser.sol index a6820366..9744dfab 100644 --- a/contracts/script/parsers/MockAvsContractsParser.sol +++ b/contracts/script/parsers/MockAvsContractsParser.sol @@ -16,51 +16,23 @@ struct MockAvsContracts { } contract MockAvsContractsParser is ConfigsReadWriter { - function _loadMockAvsDeployedContracts() - internal - view - returns (MockAvsContracts memory) - { + function _loadMockAvsDeployedContracts() internal view returns (MockAvsContracts memory) { // Eigenlayer contracts - string memory mockAvsDeployedContracts = readOutput( - "mockavs_deployment_output" - ); - MockAvsServiceManager mockAvsServiceManager = MockAvsServiceManager( - stdJson.readAddress( - mockAvsDeployedContracts, - ".addresses.mockAvsServiceManager" - ) - ); - require( - address(mockAvsServiceManager) != address(0), - "MockAvsContractsParser: mockAvsServiceManager address is 0" - ); - RegistryCoordinator registryCoordinator = RegistryCoordinator( - stdJson.readAddress( - mockAvsDeployedContracts, - ".addresses.registryCoordinator" - ) - ); + string memory mockAvsDeployedContracts = readOutput("mockavs_deployment_output"); + MockAvsServiceManager mockAvsServiceManager = + MockAvsServiceManager(stdJson.readAddress(mockAvsDeployedContracts, ".addresses.mockAvsServiceManager")); require( - address(registryCoordinator) != address(0), - "MockAvsContractsParser: registryCoordinator address is 0" - ); - OperatorStateRetriever operatorStateRetriever = OperatorStateRetriever( - stdJson.readAddress( - mockAvsDeployedContracts, - ".addresses.operatorStateRetriever" - ) + address(mockAvsServiceManager) != address(0), "MockAvsContractsParser: mockAvsServiceManager address is 0" ); + RegistryCoordinator registryCoordinator = + RegistryCoordinator(stdJson.readAddress(mockAvsDeployedContracts, ".addresses.registryCoordinator")); + require(address(registryCoordinator) != address(0), "MockAvsContractsParser: registryCoordinator address is 0"); + OperatorStateRetriever operatorStateRetriever = + OperatorStateRetriever(stdJson.readAddress(mockAvsDeployedContracts, ".addresses.operatorStateRetriever")); require( - address(operatorStateRetriever) != address(0), - "MockAvsContractsParser: operatorStateRetriever address is 0" + address(operatorStateRetriever) != address(0), "MockAvsContractsParser: operatorStateRetriever address is 0" ); - return - MockAvsContracts( - mockAvsServiceManager, - registryCoordinator, - operatorStateRetriever - ); + return MockAvsContracts(mockAvsServiceManager, registryCoordinator, operatorStateRetriever); } } diff --git a/contracts/script/parsers/TokensAndStrategiesContractsParser.sol b/contracts/script/parsers/TokensAndStrategiesContractsParser.sol index 8a0a1bf0..d2981be5 100644 --- a/contracts/script/parsers/TokensAndStrategiesContractsParser.sol +++ b/contracts/script/parsers/TokensAndStrategiesContractsParser.sol @@ -14,22 +14,13 @@ struct TokenAndStrategyContracts { // TODO: support more than one token/strategy pair (dee deployTokensAndStrategies script) contract TokenAndStrategyContractsParser is ConfigsReadWriter { - function _loadTokenAndStrategyContracts() - internal - view - returns (TokenAndStrategyContracts memory) - { + function _loadTokenAndStrategyContracts() internal view returns (TokenAndStrategyContracts memory) { // Token and Strategy contracts - string memory tokenAndStrategyConfigFile = readOutput( - "token_and_strategy_deployment_output" - ); + string memory tokenAndStrategyConfigFile = readOutput("token_and_strategy_deployment_output"); - bytes memory tokensAndStrategiesConfigsRaw = stdJson.parseRaw( - tokenAndStrategyConfigFile, - ".addresses" - ); - TokenAndStrategyContracts memory tokensAndStrategiesContracts = abi - .decode(tokensAndStrategiesConfigsRaw, (TokenAndStrategyContracts)); + bytes memory tokensAndStrategiesConfigsRaw = stdJson.parseRaw(tokenAndStrategyConfigFile, ".addresses"); + TokenAndStrategyContracts memory tokensAndStrategiesContracts = + abi.decode(tokensAndStrategiesConfigsRaw, (TokenAndStrategyContracts)); return tokensAndStrategiesContracts; } diff --git a/contracts/src/ContractsRegistry.sol b/contracts/src/ContractsRegistry.sol index 1d7b81d1..df1733f8 100644 --- a/contracts/src/ContractsRegistry.sol +++ b/contracts/src/ContractsRegistry.sol @@ -9,8 +9,8 @@ pragma solidity ^0.8.12; // forge create src/ContractsRegistry.sol:ContractsRegistry --rpc-url $RPC_URL --private-key $PRIVATE_KEY contract ContractsRegistry { mapping(string => address) public contracts; - mapping(uint => string) public contractNames; - uint public contractCount; + mapping(uint256 => string) public contractNames; + uint256 public contractCount; function registerContract(string memory name, address _contract) public { // we treat redeploys as a bug since this is only meant to be used for testing. diff --git a/contracts/src/MockAvsServiceManager.sol b/contracts/src/MockAvsServiceManager.sol index 17d63d3a..65bfd8a5 100644 --- a/contracts/src/MockAvsServiceManager.sol +++ b/contracts/src/MockAvsServiceManager.sol @@ -9,7 +9,8 @@ import {IRegistryCoordinator} from "eigenlayer-middleware/src/interfaces/IRegist import {IBLSSignatureChecker} from "eigenlayer-middleware/src/interfaces/IBLSSignatureChecker.sol"; import {ServiceManagerBase} from "eigenlayer-middleware/src/ServiceManagerBase.sol"; import {BLSSignatureChecker} from "eigenlayer-middleware/src/BLSSignatureChecker.sol"; -import {IAllocationManager} from "../lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IAllocationManager} from + "../lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; contract MockAvsServiceManager is ServiceManagerBase, BLSSignatureChecker { constructor( diff --git a/contracts/src/MockERC20.sol b/contracts/src/MockERC20.sol index 349751a9..1b5cdcd9 100644 --- a/contracts/src/MockERC20.sol +++ b/contracts/src/MockERC20.sol @@ -9,11 +9,7 @@ contract MockERC20 is ERC20("Mock Token", "MCK") { } /// WARNING: Vulnerable, bypasses allowance check. Do not use in production! - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { + function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { super._transfer(from, to, amount); return true; } diff --git a/go.mod b/go.mod index dc8369b9..65e3637d 100644 --- a/go.mod +++ b/go.mod @@ -102,11 +102,11 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/tools v0.20.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/grpc v1.58.3 // indirect diff --git a/go.sum b/go.sum index 0cd10ba8..400e2d3c 100644 --- a/go.sum +++ b/go.sum @@ -304,8 +304,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -335,12 +335,12 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/signer/go.mod b/signer/go.mod index 58ba9627..2594f9d2 100644 --- a/signer/go.mod +++ b/signer/go.mod @@ -29,11 +29,11 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/supranational/blst v0.3.11 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/signer/go.sum b/signer/go.sum index 3d523201..39018373 100644 --- a/signer/go.sum +++ b/signer/go.sum @@ -118,17 +118,27 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=