Skip to content
Merged
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
13 changes: 13 additions & 0 deletions bindings/network/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ func GetRequestedEth(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int,
return *value, nil
}

// Get the current EIP-7002 exit fee in wei
func GetExitFee(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
rocketNetworkExit, err := getRocketNetworkExit(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := rocketNetworkExit.Call(opts, value, "getExitFee"); err != nil {
return nil, fmt.Errorf("error getting exit fee: %w", err)
}
return *value, nil
}

// Get the start of the cooperative exit phase for a Minipool
func GetMinipoolCooperativeExitStart(rp *rocketpool.RocketPool, minipoolAddress common.Address, opts *bind.CallOpts) (time.Time, error) {
rocketNetworkExit, err := getRocketNetworkExit(rp, opts)
Expand Down
64 changes: 29 additions & 35 deletions bindings/settings/protocol/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package protocol
import (
"fmt"
"math/big"
"sync"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -17,95 +16,90 @@ import (

// Config
const (
ExitSettingsContractName string = "rocketDAOProtocolSettingsExit"
CooperativeExitPhaseSettingPath string = "cooperative.exit.phase"
DidNotExitPenaltyBaseSettingPath string = "did.not.exit.penalty.base"
DidNotExitBaseSettingPath string = "did.not.exit.base"
DidNotExitBackoffSettingPath string = "did.not.exit.backoff"
// Exit settings are stored in the network settings contract.
CooperativeExitPhaseSettingPath string = "network.cooperative.exit.phase"
DidNotExitPenaltyBaseSettingPath string = "network.did.not.exit.penalty.base"
DidNotExitBaseSettingPath string = "network.did.not.exit.base"
DidNotExitBackoffSettingPath string = "network.did.not.exit.backoff"
)

// Minimum time a validator must remain exit-requested before triggered exit or penalty (hours)
// Minimum time a validator must remain exit-requested before triggered exit or penalty
func GetCooperativeExitPhase(rp *rocketpool.RocketPool, opts *bind.CallOpts) (time.Duration, error) {
exitSettingsContract, err := getExitSettingsContract(rp, opts)
networkSettingsContract, err := getNetworkSettingsContract(rp, opts)
if err != nil {
return 0, err
}
value := new(*big.Int)
if err := exitSettingsContract.Call(opts, value, "getCooperativeExitPhase"); err != nil {
if err := networkSettingsContract.Call(opts, value, "getCooperativeExitPhase"); err != nil {
return 0, fmt.Errorf("error getting cooperative exit phase: %w", err)
}
return time.Duration((*value).Int64()) * time.Hour, nil
return time.Duration((*value).Int64()) * time.Second, nil
}

// Propose the cooperative exit phase in seconds
func ProposeCooperativeExitPhase(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (uint64, common.Hash, error) {
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", CooperativeExitPhaseSettingPath), ExitSettingsContractName, CooperativeExitPhaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", CooperativeExitPhaseSettingPath), NetworkSettingsContractName, CooperativeExitPhaseSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeCooperativeExitPhaseGas(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (gaslimit.Limits, error) {
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", CooperativeExitPhaseSettingPath), ExitSettingsContractName, CooperativeExitPhaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", CooperativeExitPhaseSettingPath), NetworkSettingsContractName, CooperativeExitPhaseSettingPath, value, blockNumber, treeNodes, opts)
}

// Base penalty applied to a minipool that fails to exit when requested
func GetDidNotExitPenaltyBase(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
exitSettingsContract, err := getExitSettingsContract(rp, opts)
networkSettingsContract, err := getNetworkSettingsContract(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := exitSettingsContract.Call(opts, value, "getDidNotExitPenaltyBase"); err != nil {
if err := networkSettingsContract.Call(opts, value, "getDidNotExitPenaltyBase"); err != nil {
return nil, fmt.Errorf("error getting did not exit penalty base: %w", err)
}
return *value, nil
}
func ProposeDidNotExitPenaltyBase(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (uint64, common.Hash, error) {
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitPenaltyBaseSettingPath), ExitSettingsContractName, DidNotExitPenaltyBaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitPenaltyBaseSettingPath), NetworkSettingsContractName, DidNotExitPenaltyBaseSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeDidNotExitPenaltyBaseGas(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (gaslimit.Limits, error) {
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitPenaltyBaseSettingPath), ExitSettingsContractName, DidNotExitPenaltyBaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitPenaltyBaseSettingPath), NetworkSettingsContractName, DidNotExitPenaltyBaseSettingPath, value, blockNumber, treeNodes, opts)
}

// Initial window between consecutive did-not-exit penalties (days)
// Base delay after a failed cooperative exit before the protocol can try again
func GetDidNotExitBase(rp *rocketpool.RocketPool, opts *bind.CallOpts) (time.Duration, error) {
exitSettingsContract, err := getExitSettingsContract(rp, opts)
networkSettingsContract, err := getNetworkSettingsContract(rp, opts)
if err != nil {
return 0, err
}
value := new(*big.Int)
if err := exitSettingsContract.Call(opts, value, "getDidNotExitBase"); err != nil {
if err := networkSettingsContract.Call(opts, value, "getDidNotExitBase"); err != nil {
return 0, fmt.Errorf("error getting did not exit base: %w", err)
}
return time.Duration((*value).Int64()) * 24 * time.Hour, nil
return time.Duration((*value).Int64()) * time.Second, nil
}

// Propose the base delay in seconds
func ProposeDidNotExitBase(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (uint64, common.Hash, error) {
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitBaseSettingPath), ExitSettingsContractName, DidNotExitBaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitBaseSettingPath), NetworkSettingsContractName, DidNotExitBaseSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeDidNotExitBaseGas(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (gaslimit.Limits, error) {
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitBaseSettingPath), ExitSettingsContractName, DidNotExitBaseSettingPath, value, blockNumber, treeNodes, opts)
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitBaseSettingPath), NetworkSettingsContractName, DidNotExitBaseSettingPath, value, blockNumber, treeNodes, opts)
}

// Multiplier applied to the penalty window on each iteration (18-decimal fixed point):
// the i-th window is did_not_exit_base * did_not_exit_backoff ** i
func GetDidNotExitBackoff(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
exitSettingsContract, err := getExitSettingsContract(rp, opts)
networkSettingsContract, err := getNetworkSettingsContract(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := exitSettingsContract.Call(opts, value, "getDidNotExitBackoff"); err != nil {
if err := networkSettingsContract.Call(opts, value, "getDidNotExitBackoff"); err != nil {
return nil, fmt.Errorf("error getting did not exit backoff: %w", err)
}
return *value, nil
}
func ProposeDidNotExitBackoff(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (uint64, common.Hash, error) {
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitBackoffSettingPath), ExitSettingsContractName, DidNotExitBackoffSettingPath, value, blockNumber, treeNodes, opts)
return protocol.ProposeSetUint(rp, fmt.Sprintf("set %s", DidNotExitBackoffSettingPath), NetworkSettingsContractName, DidNotExitBackoffSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeDidNotExitBackoffGas(rp *rocketpool.RocketPool, value *big.Int, blockNumber uint32, treeNodes []types.VotingTreeNode, opts *bind.TransactOpts) (gaslimit.Limits, error) {
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitBackoffSettingPath), ExitSettingsContractName, DidNotExitBackoffSettingPath, value, blockNumber, treeNodes, opts)
}

// Get contracts
var exitSettingsContractLock sync.Mutex

func getExitSettingsContract(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*rocketpool.Contract, error) {
exitSettingsContractLock.Lock()
defer exitSettingsContractLock.Unlock()
return rp.GetContract(ExitSettingsContractName, opts)
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", DidNotExitBackoffSettingPath), NetworkSettingsContractName, DidNotExitBackoffSettingPath, value, blockNumber, treeNodes, opts)
}
10 changes: 4 additions & 6 deletions bindings/settings/protocol/setting-types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ var pdaoSettingKinds = map[string]map[string]settingKind{
MinipoolUserDistributeWindowLengthSettingPath: settingKindUint256,
},
NetworkSettingsContractName: {
CooperativeExitPhaseSettingPath: settingKindUint256,
DidNotExitPenaltyBaseSettingPath: settingKindUint256,
DidNotExitBaseSettingPath: settingKindUint256,
DidNotExitBackoffSettingPath: settingKindUint256,
NodeConsensusThresholdSettingPath: settingKindUint256,
SubmitBalancesEnabledSettingPath: settingKindBool,
SubmitBalancesFrequencySettingPath: settingKindUint256,
Expand Down Expand Up @@ -138,12 +142,6 @@ var pdaoSettingKinds = map[string]map[string]settingKind{
PerformanceChallengePeriodSettingPath: settingKindUint256,
PerformanceChallengeBondSettingPath: settingKindUint256,
},
ExitSettingsContractName: {
CooperativeExitPhaseSettingPath: settingKindUint256,
DidNotExitPenaltyBaseSettingPath: settingKindUint256,
DidNotExitBaseSettingPath: settingKindUint256,
DidNotExitBackoffSettingPath: settingKindUint256,
},
}

// GetProposalSettingType returns the on-chain type used by proposalSettingMulti
Expand Down
9 changes: 8 additions & 1 deletion rocketpool-cli/cli/saturn2-check.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ const Saturn2NotDeployedMessage = "This command is not available until Saturn 2
// IsSaturn2OnlySetting reports whether a protocol setting exists only after Saturn 2.
func IsSaturn2OnlySetting(contract, setting string) bool {
switch contract {
case protocol.PerformanceSettingsContractName, protocol.ExitSettingsContractName:
case protocol.PerformanceSettingsContractName:
return true
case protocol.NetworkSettingsContractName:
switch setting {
case protocol.CooperativeExitPhaseSettingPath, protocol.DidNotExitPenaltyBaseSettingPath,
protocol.DidNotExitBaseSettingPath, protocol.DidNotExitBackoffSettingPath:
return true
}
return false
case protocol.MegapoolSettingsContractName:
return setting == protocol.MegapoolPrestakeChallengePeriodPath
default:
Expand Down
9 changes: 4 additions & 5 deletions rocketpool-cli/pdao/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const (
floatMultiplierUsage string = "specify a multiplier (e.g., '1.5')"
epochCountUsage string = "specify a number, in epochs (eg., '100')"
hourCountUsage string = "specify a number, in hours (e.g., '72')"
dayCountUsage string = "specify a number, in days (e.g., '28')"
durationUsage string = "specify a duration using hours, minutes, and seconds (e.g., '20m' or '72h0m0s')"
addressListUsage string = "specify a list of one or more addresses separated by commas (e.g., '0x1a2b3c4d5e6f7890abcdef1234567890abcdef12,0xabcdefabcdefabcdefabcdefabcdefabcdefabcd')"
)
Expand Down Expand Up @@ -3571,7 +3570,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
{
Name: "cooperative-exit-phase",
Aliases: []string{"cep"},
Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol.CooperativeExitPhaseSettingPath, hourCountUsage),
Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol.CooperativeExitPhaseSettingPath, durationUsage),
UsageText: "rocketpool pdao propose setting exit cooperative-exit-phase value",
Flags: []cli.Flag{
&cli.BoolFlag{
Expand All @@ -3590,7 +3589,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
if err := cliutils.ValidateArgCount(c, 1); err != nil {
return err
}
value, err := cliutils.ValidatePositiveUint("value", c.Args().Get(0))
value, err := cliutils.ValidateDuration("value", c.Args().Get(0))
if err != nil {
return err
}
Expand Down Expand Up @@ -3641,7 +3640,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
{
Name: "did-not-exit-base",
Aliases: []string{"dneb"},
Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol.DidNotExitBaseSettingPath, dayCountUsage),
Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol.DidNotExitBaseSettingPath, durationUsage),
UsageText: "rocketpool pdao propose setting exit did-not-exit-base value",
Flags: []cli.Flag{
&cli.BoolFlag{
Expand All @@ -3660,7 +3659,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
if err := cliutils.ValidateArgCount(c, 1); err != nil {
return err
}
value, err := cliutils.ValidatePositiveUint("value", c.Args().Get(0))
value, err := cliutils.ValidateDuration("value", c.Args().Get(0))
if err != nil {
return err
}
Expand Down
16 changes: 8 additions & 8 deletions rocketpool-cli/pdao/propose-settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,24 +400,24 @@ func proposeSettingPerformanceChallengeBond(value *big.Int, yes bool, toJson str
return proposeSetting(protocol.PerformanceSettingsContractName, protocol.PerformanceChallengeBondSettingPath, trueValue, yes, toJson)
}

func proposeSettingCooperativeExitPhase(value uint64, yes bool, toJson string) error {
trueValue := fmt.Sprint(value)
return proposeSetting(protocol.ExitSettingsContractName, protocol.CooperativeExitPhaseSettingPath, trueValue, yes, toJson)
func proposeSettingCooperativeExitPhase(value time.Duration, yes bool, toJson string) error {
trueValue := fmt.Sprint(uint64(value.Seconds()))
return proposeSetting(protocol.NetworkSettingsContractName, protocol.CooperativeExitPhaseSettingPath, trueValue, yes, toJson)
}

func proposeSettingDidNotExitPenaltyBase(value *big.Int, yes bool, toJson string) error {
trueValue := value.String()
return proposeSetting(protocol.ExitSettingsContractName, protocol.DidNotExitPenaltyBaseSettingPath, trueValue, yes, toJson)
return proposeSetting(protocol.NetworkSettingsContractName, protocol.DidNotExitPenaltyBaseSettingPath, trueValue, yes, toJson)
}

func proposeSettingDidNotExitBase(value uint64, yes bool, toJson string) error {
trueValue := fmt.Sprint(value)
return proposeSetting(protocol.ExitSettingsContractName, protocol.DidNotExitBaseSettingPath, trueValue, yes, toJson)
func proposeSettingDidNotExitBase(value time.Duration, yes bool, toJson string) error {
trueValue := fmt.Sprint(uint64(value.Seconds()))
return proposeSetting(protocol.NetworkSettingsContractName, protocol.DidNotExitBaseSettingPath, trueValue, yes, toJson)
}

func proposeSettingDidNotExitBackoff(value *big.Int, yes bool, toJson string) error {
trueValue := value.String()
return proposeSetting(protocol.ExitSettingsContractName, protocol.DidNotExitBackoffSettingPath, trueValue, yes, toJson)
return proposeSetting(protocol.NetworkSettingsContractName, protocol.DidNotExitBackoffSettingPath, trueValue, yes, toJson)
}

func proposeSettingNodeCommissionShare(value *big.Int, yes bool, toJson string) error {
Expand Down
Loading
Loading