Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: slashing commands #205

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ operator-config.yaml.old
operator.yaml
operator.yaml.old
config/*
updates.csv

# build
dist/
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/Layr-Labs/eigenlayer-contracts v0.3.2-mainnet-rewards
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20241023023134-a285de543731
github.com/blang/semver/v4 v4.0.0
github.com/consensys/gnark-crypto v0.12.1
github.com/ethereum/go-ethereum v1.14.5
Expand All @@ -19,6 +19,7 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.27.2
github.com/wagslane/go-password-validator v0.3.0
github.com/wk8/go-ordered-map/v2 v2.1.8
go.uber.org/mock v0.4.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
Expand Down Expand Up @@ -100,7 +101,6 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/wealdtech/go-merkletree/v2 v2.5.2-0.20240302222400-69219c450662 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
Expand Down
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12 h1:G5Q1SnLmFbEjhOkky3vIHk
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12/go.mod h1:OlJd1QjqEW53wfWG/lJyPCGvrXwWVEjPQsP4TV+gttQ=
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e h1:DvW0/kWHV9mZsbH2KOjEHKTSIONNPUj6X05FJvUohy4=
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e/go.mod h1:T7tYN8bTdca2pkMnz9G2+ZwXYWw5gWqQUIu4KLgC/vM=
github.com/Layr-Labs/eigensdk-go v0.1.11/go.mod h1:XcLVDtlB1vOPj63D236b451+SC75B8gwgkpNhYHSxNs=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610 h1:lGy4uSImJyOiaM8vSx0CEbsL3rbVfw0uEIuhGey/ubc=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610/go.mod h1:bA21qMfmUFZcUe+a1RsDeOGm25xZO802Kfll2GlS8Us=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20241023023134-a285de543731 h1:8F/wlaQoZG1+BcuP9cWhqKNbYgw4CphZFwp8SjMkW9A=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20241023023134-a285de543731/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
Expand Down
12 changes: 12 additions & 0 deletions pkg/internal/common/contracts.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"context"
"errors"
"math/big"

Expand Down Expand Up @@ -57,3 +58,14 @@ func GetELWriter(

return eLWriter, nil
}

func IsSmartContractAddress(address gethcommon.Address, ethClient *ethclient.Client) bool {
code, err := ethClient.CodeAt(context.Background(), address, nil)
if err != nil {
// We return true here because we want to treat the address as a smart contract
// This is only used to gas estimation and creating unsigned transactions
// So it's fine if eth client return an error
return true
}
return len(code) > 0
}
46 changes: 46 additions & 0 deletions pkg/internal/common/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package common
import (
"fmt"
"math/big"
"strconv"
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

Expand Down Expand Up @@ -46,3 +48,47 @@ func GetTxFeeDetails(tx *types.Transaction) *TxFeeDetails {
GasFeeCapGwei: gasFeeCapGwei,
}
}

func ConvertStringSliceToGethAddressSlice(addresses []string) []common.Address {
gethAddresses := make([]common.Address, 0, len(addresses))
for _, address := range addresses {
parsed := common.HexToAddress(address)
gethAddresses = append(gethAddresses, parsed)
}
return gethAddresses
}

func ShortEthAddress(address common.Address) string {
return fmt.Sprintf("%s...%s", address.Hex()[:6], address.Hex()[len(address.Hex())-4:])
}

func Uint64ToString(num uint64) string {
return strconv.FormatUint(num, 10)
}

func FormatNumberWithUnderscores(numStr string) string {

// If the number is less than 1000, no formatting is needed
if len(numStr) <= 3 {
return numStr
}

// Calculate the number of groups of 3 digits
groups := (len(numStr) - 1) / 3

// Create a slice to hold the result
result := make([]byte, len(numStr)+groups)

// Fill the result slice from right to left
resultIndex := len(result) - 1
for i := len(numStr) - 1; i >= 0; i-- {
if (len(numStr)-i-1)%3 == 0 && i != len(numStr)-1 {
result[resultIndex] = '_'
resultIndex--
}
result[resultIndex] = numStr[i]
resultIndex--
}

return string(result)
}
40 changes: 40 additions & 0 deletions pkg/internal/common/flags/avs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package flags

import "github.com/urfave/cli/v2"

var (
AVSAddressesFlag = cli.StringSliceFlag{
Name: "avs-addresses",
Usage: "AVS addresses",
Aliases: []string{"aa"},
EnvVars: []string{"AVS_ADDRESSES"},
}

AVSAddressFlag = cli.StringFlag{
Name: "avs-address",
Usage: "AVS addresses",
Aliases: []string{"aa"},
EnvVars: []string{"AVS_ADDRESS"},
}

StrategyAddressesFlag = cli.StringSliceFlag{
Name: "strategy-addresses",
Usage: "Strategy addresses",
Aliases: []string{"sa"},
EnvVars: []string{"STRATEGY_ADDRESSES"},
}

StrategyAddressFlag = cli.StringFlag{
Name: "strategy-address",
Usage: "Strategy addresses",
Aliases: []string{"sa"},
EnvVars: []string{"STRATEGY_ADDRESS"},
}

OperatorSetIdFlag = cli.Uint64Flag{
Name: "operator-set-id",
Usage: "Operator set ID",
Aliases: []string{"osid"},
EnvVars: []string{"OPERATOR_SET_ID"},
}
)
21 changes: 21 additions & 0 deletions pkg/internal/common/flags/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,25 @@ var (
Usage: "Suppress unnecessary output",
EnvVars: []string{"SILENT"},
}

OperatorAddressFlag = cli.StringFlag{
Name: "operator-address",
Aliases: []string{"oa", "operator"},
Usage: "Operator address",
EnvVars: []string{"OPERATOR_ADDRESS"},
}

CSVFileFlag = cli.StringFlag{
Name: "csv-file",
Aliases: []string{"csv"},
Usage: "CSV file to read data from",
EnvVars: []string{"CSV_FILE"},
}

EnvironmentFlag = cli.StringFlag{
Name: "environment",
Aliases: []string{"env"},
Usage: "environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network",
EnvVars: []string{"ENVIRONMENT"},
}
)
21 changes: 21 additions & 0 deletions pkg/internal/common/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,16 @@ func GetAVSDirectoryAddress(chainID *big.Int) (string, error) {
}
}

func GetDelegationManagerAddress(chainID *big.Int) (string, error) {
chainIDInt := chainID.Int64()
chainMetadata, ok := ChainMetadataMap[chainIDInt]
if !ok {
return "", fmt.Errorf("chain ID %d not supported", chainIDInt)
} else {
return chainMetadata.ELDelegationManagerAddress, nil
}
}

func GetTransactionLink(txHash string, chainId *big.Int) string {
chainIDInt := chainId.Int64()
chainMetadata, ok := ChainMetadataMap[chainIDInt]
Expand Down Expand Up @@ -479,3 +489,14 @@ func GetNoSendTxOpts(from common.Address) *bind.TransactOpts {
func Trim0x(s string) string {
return strings.TrimPrefix(s, "0x")
}

func GetEnvFromNetwork(network string) string {
switch network {
case utils.HoleskyNetworkName:
return "testnet"
case utils.MainnetNetworkName:
return "mainnet"
default:
return "local"
}
}
1 change: 1 addition & 0 deletions pkg/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func OperatorCmd(p utils.Prompter) *cli.Command {
operator.StatusCmd(p),
operator.UpdateCmd(p),
operator.UpdateMetadataURICmd(p),
operator.AllocationsCmd(p),
},
}

Expand Down
21 changes: 21 additions & 0 deletions pkg/operator/allocations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package operator

import (
"github.com/Layr-Labs/eigenlayer-cli/pkg/operator/allocations"
"github.com/Layr-Labs/eigenlayer-cli/pkg/utils"
"github.com/urfave/cli/v2"
)

func AllocationsCmd(p utils.Prompter) *cli.Command {
var allocationsCmd = &cli.Command{
Name: "allocations",
Usage: "Stake allocation commands for operators",
Subcommands: []*cli.Command{
allocations.ShowCmd(p),
allocations.UpdateCmd(p),
allocations.InitializeDelayCmd(p),
},
}

return allocationsCmd
}
75 changes: 75 additions & 0 deletions pkg/operator/allocations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## Allocations Command
### Initialize Delay
```bash
eigenlayer operator allocations initialize-delay --help
NAME:
eigenlayer operator allocations initialize-delay - Initialize the allocation delay for operator

USAGE:
initialize-delay [flags] <delay>

DESCRIPTION:
Initializes the allocation delay for operator. This is a one time command. You can not change the allocation delay once

OPTIONS:
--broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST]
--ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY]
--environment value, --env value environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT]
--eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL]
--fireblocks-api-key value, --ff value Fireblocks API key [$FIREBLOCKS_API_KEY]
--fireblocks-aws-region value, --fa value AWS region if secret is stored in AWS KMS (default: "us-east-1") [$FIREBLOCKS_AWS_REGION]
--fireblocks-base-url value, --fb value Fireblocks base URL [$FIREBLOCKS_BASE_URL]
--fireblocks-secret-key value, --fs value Fireblocks secret key. If you are using AWS Secret Manager, this should be the secret name. [$FIREBLOCKS_SECRET_KEY]
--fireblocks-secret-storage-type value, --fst value Fireblocks secret storage type. Supported values are 'plaintext' and 'aws_secret_manager' [$FIREBLOCKS_SECRET_STORAGE_TYPE]
--fireblocks-timeout value, --ft value Fireblocks timeout (default: 30) [$FIREBLOCKS_TIMEOUT]
--fireblocks-vault-account-name value, --fv value Fireblocks vault account name [$FIREBLOCKS_VAULT_ACCOUNT_NAME]
--network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK]
--operator-address value, --oa value, --operator value Operator address [$OPERATOR_ADDRESS]
--output-file value, -o value Output file to write the data [$OUTPUT_FILE]
--output-type value, --ot value Output format of the command. One of 'pretty', 'json' or 'calldata' (default: "pretty") [$OUTPUT_TYPE]
--path-to-key-store value, -k value Path to the key store used to send transactions [$PATH_TO_KEY_STORE]
--verbose, -v Enable verbose logging (default: false) [$VERBOSE]
--web3signer-url value, -w value URL of the Web3Signer [$WEB3SIGNER_URL]
--help, -h show help
```

### Update allocations
```bash
eigenlayer operator allocations update --help
NAME:
eigenlayer operator allocations update - Update allocations

USAGE:
update

DESCRIPTION:

Command to update allocations


OPTIONS:
--avs-address value, --aa value AVS addresses [$AVS_ADDRESS]
--bips-to-allocate value, --bta value, --bips value, --bps value Bips to allocate to the strategy (default: 0) [$BIPS_TO_ALLOCATE]
--broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST]
--csv-file value, --csv value CSV file to read data from [$CSV_FILE]
--ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY]
--environment value, --env value environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT]
--eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL]
--fireblocks-api-key value, --ff value Fireblocks API key [$FIREBLOCKS_API_KEY]
--fireblocks-aws-region value, --fa value AWS region if secret is stored in AWS KMS (default: "us-east-1") [$FIREBLOCKS_AWS_REGION]
--fireblocks-base-url value, --fb value Fireblocks base URL [$FIREBLOCKS_BASE_URL]
--fireblocks-secret-key value, --fs value Fireblocks secret key. If you are using AWS Secret Manager, this should be the secret name. [$FIREBLOCKS_SECRET_KEY]
--fireblocks-secret-storage-type value, --fst value Fireblocks secret storage type. Supported values are 'plaintext' and 'aws_secret_manager' [$FIREBLOCKS_SECRET_STORAGE_TYPE]
--fireblocks-timeout value, --ft value Fireblocks timeout (default: 30) [$FIREBLOCKS_TIMEOUT]
--fireblocks-vault-account-name value, --fv value Fireblocks vault account name [$FIREBLOCKS_VAULT_ACCOUNT_NAME]
--network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK]
--operator-address value, --oa value, --operator value Operator address [$OPERATOR_ADDRESS]
--operator-set-id value, --osid value Operator set ID (default: 0) [$OPERATOR_SET_ID]
--output-file value, -o value Output file to write the data [$OUTPUT_FILE]
--output-type value, --ot value Output format of the command. One of 'pretty', 'json' or 'calldata' (default: "pretty") [$OUTPUT_TYPE]
--path-to-key-store value, -k value Path to the key store used to send transactions [$PATH_TO_KEY_STORE]
--strategy-address value, --sa value Strategy addresses [$STRATEGY_ADDRESS]
--verbose, -v Enable verbose logging (default: false) [$VERBOSE]
--web3signer-url value, -w value URL of the Web3Signer [$WEB3SIGNER_URL]
--help, -h show help
```
19 changes: 19 additions & 0 deletions pkg/operator/allocations/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package allocations

import "github.com/urfave/cli/v2"

var (
BipsToAllocateFlag = cli.Uint64Flag{
Name: "bips-to-allocate",
Aliases: []string{"bta", "bips", "bps"},
Usage: "Bips to allocate to the strategy",
EnvVars: []string{"BIPS_TO_ALLOCATE"},
}

EnvironmentFlag = cli.StringFlag{
Name: "environment",
Aliases: []string{"env"},
Usage: "environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network",
EnvVars: []string{"ENVIRONMENT"},
}
)
Loading