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
18 changes: 18 additions & 0 deletions bindings/dao/upgrades/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"golang.org/x/sync/errgroup"

"github.com/rocket-pool/smartnode/bindings/rocketpool"
Expand All @@ -25,6 +26,23 @@ type UpgradeProposalDetails struct {
UpgradeAbi string `json:"upgradeAbi"`
}

// On-chain upgrade types are stored as keccak256 of the type string
var upgradeProposalTypeNames = map[common.Hash]string{
crypto.Keccak256Hash([]byte("upgradeContract")): "UpgradeContract",
crypto.Keccak256Hash([]byte("addContract")): "AddContract",
crypto.Keccak256Hash([]byte("addABI")): "AddABI",
crypto.Keccak256Hash([]byte("upgradeABI")): "UpgradeABI",
}

// TypeName returns the interpreted upgrade type, or the type hash if unknown
func (p UpgradeProposalDetails) TypeName() string {
hash := common.Hash(p.Type)
if name, ok := upgradeProposalTypeNames[hash]; ok {
return name
}
return hash.Hex()
}

// Get all upgrade proposal details
func GetUpgradeProposals(rp *rocketpool.RocketPool, opts *bind.CallOpts) ([]UpgradeProposalDetails, error) {

Expand Down
20 changes: 20 additions & 0 deletions bindings/settings/protocol/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (
NetworkPDAOSharePath string = "network.pdao.share"
NetworkMaxNodeShareSecurityCouncilAdderPath string = "network.max.node.commission.share.council.adder"
NetworkMaxRethBalanceDeltaPath string = "network.max.reth.balance.delta"
NetworkRethDepositDelaySettingPath string = "network.reth.deposit.delay"
)

// The threshold of trusted nodes that must reach consensus on oracle data to commit it
Expand Down Expand Up @@ -519,6 +520,25 @@ func EstimateMaxRethDeltaGas(rp *rocketpool.RocketPool, value *big.Int, blockNum
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", NetworkMaxRethBalanceDeltaPath), NetworkSettingsContractName, NetworkMaxRethBalanceDeltaPath, value, blockNumber, treeNodes, opts)
}

// The number of blocks that must pass after a deposit before a user's rETH can be transferred
func GetRethDepositDelay(rp *rocketpool.RocketPool, opts *bind.CallOpts) (uint64, error) {
networkSettingsContract, err := getNetworkSettingsContract(rp, opts)
if err != nil {
return 0, err
}
value := new(*big.Int)
if err := networkSettingsContract.Call(opts, value, "getRethDepositDelay"); err != nil {
return 0, fmt.Errorf("error getting reth deposit delay: %w", err)
}
return (*value).Uint64(), nil
}
func ProposeRethDepositDelay(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", NetworkRethDepositDelaySettingPath), NetworkSettingsContractName, NetworkRethDepositDelaySettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeRethDepositDelayGas(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", NetworkRethDepositDelaySettingPath), NetworkSettingsContractName, NetworkRethDepositDelaySettingPath, value, blockNumber, treeNodes, opts)
}

// Get contracts
var networkSettingsContractLock sync.Mutex

Expand Down
40 changes: 40 additions & 0 deletions bindings/settings/protocol/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
MinimumLegacyRplStakePath string = "node.minimum.legacy.staked.rpl"
ReducedBondSettingPath string = "reduced.bond"
NodeUnstakingPeriodSettingPath string = "node.unstaking.period"
NodeWithdrawalCooldownSettingPath string = "node.withdrawal.cooldown"
MaximumStakeForVotingPowerSettingPath string = "node.voting.power.stake.maximum"
)

// Node registrations currently enabled
Expand Down Expand Up @@ -186,6 +188,44 @@ func EstimateProposeNodeUnstakingPeriod(rp *rocketpool.RocketPool, value *big.In
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", NodeUnstakingPeriodSettingPath), NodeSettingsContractName, NodeUnstakingPeriodSettingPath, value, blockNumber, treeNodes, opts)
}

// The period of time a node must wait after staking RPL before it can be withdrawn again
func GetWithdrawalCooldown(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
nodeSettingsContract, err := getNodeSettingsContract(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := nodeSettingsContract.Call(opts, value, "getWithdrawalCooldown"); err != nil {
return nil, fmt.Errorf("error getting the withdrawal cooldown: %w", err)
}
return *value, nil
}
func ProposeWithdrawalCooldown(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", NodeWithdrawalCooldownSettingPath), NodeSettingsContractName, NodeWithdrawalCooldownSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeWithdrawalCooldownGas(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", NodeWithdrawalCooldownSettingPath), NodeSettingsContractName, NodeWithdrawalCooldownSettingPath, value, blockNumber, treeNodes, opts)
}

// Maximum staked RPL that applies to voting power per minipool, as a fraction of assigned user ETH value (100%-500%)
func GetMaximumStakeForVotingPower(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
nodeSettingsContract, err := getNodeSettingsContract(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := nodeSettingsContract.Call(opts, value, "getMaximumStakeForVotingPower"); err != nil {
return nil, fmt.Errorf("error getting maximum stake for voting power: %w", err)
}
return *value, nil
}
func ProposeMaximumStakeForVotingPower(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", MaximumStakeForVotingPowerSettingPath), NodeSettingsContractName, MaximumStakeForVotingPowerSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeMaximumStakeForVotingPowerGas(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", MaximumStakeForVotingPowerSettingPath), NodeSettingsContractName, MaximumStakeForVotingPowerSettingPath, value, blockNumber, treeNodes, opts)
}

// Get contracts
var nodeSettingsContractLock sync.Mutex

Expand Down
40 changes: 40 additions & 0 deletions bindings/settings/protocol/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const (
SecurityProposalVoteTimeSettingPath string = "proposal.vote.time"
SecurityProposalExecuteTimeSettingPath string = "proposal.execute.time"
SecurityProposalActionTimeSettingPath string = "proposal.action.time"
SecurityUpgradeVetoQuorumSettingPath string = "upgradeveto.quorum"
SecurityUpgradeDelaySettingPath string = "upgrade.delay"
)

// Security council member quorum threshold that must be met for proposals to pass
Expand Down Expand Up @@ -120,6 +122,44 @@ func EstimateProposeSecurityProposalActionTimeGas(rp *rocketpool.RocketPool, val
return protocol.EstimateProposeSetUintGas(rp, fmt.Sprintf("set %s", SecurityProposalActionTimeSettingPath), SecuritySettingsContractName, SecurityProposalActionTimeSettingPath, value, blockNumber, treeNodes, opts)
}

// Security council quorum threshold that must be met to veto a protocol upgrade
func GetSecurityUpgradeVetoQuorum(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
securitySettingsContract, err := getSecuritySettingsContract(rp, opts)
if err != nil {
return nil, err
}
value := new(*big.Int)
if err := securitySettingsContract.Call(opts, value, "getUpgradeVetoQuorum"); err != nil {
return nil, fmt.Errorf("error getting security upgrade veto quorum: %w", err)
}
return *value, nil
}
func ProposeSecurityUpgradeVetoQuorum(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", SecurityUpgradeVetoQuorumSettingPath), SecuritySettingsContractName, SecurityUpgradeVetoQuorumSettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeSecurityUpgradeVetoQuorumGas(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", SecurityUpgradeVetoQuorumSettingPath), SecuritySettingsContractName, SecurityUpgradeVetoQuorumSettingPath, value, blockNumber, treeNodes, opts)
}

// How long after a protocol upgrade proposal passes that the security council has to veto it
func GetSecurityUpgradeDelay(rp *rocketpool.RocketPool, opts *bind.CallOpts) (time.Duration, error) {
securitySettingsContract, err := getSecuritySettingsContract(rp, opts)
if err != nil {
return 0, err
}
value := new(*big.Int)
if err := securitySettingsContract.Call(opts, value, "getUpgradeDelay"); err != nil {
return 0, fmt.Errorf("error getting security upgrade delay: %w", err)
}
return time.Second * time.Duration((*value).Uint64()), nil
}
func ProposeSecurityUpgradeDelay(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", SecurityUpgradeDelaySettingPath), SecuritySettingsContractName, SecurityUpgradeDelaySettingPath, value, blockNumber, treeNodes, opts)
}
func EstimateProposeSecurityUpgradeDelayGas(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", SecurityUpgradeDelaySettingPath), SecuritySettingsContractName, SecurityUpgradeDelaySettingPath, value, blockNumber, treeNodes, opts)
}

// Get contracts
var securitySettingsContractLock sync.Mutex

Expand Down
5 changes: 5 additions & 0 deletions bindings/settings/protocol/setting-types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ var pdaoSettingKinds = map[string]map[string]settingKind{
NetworkPDAOSharePath: settingKindUint256,
NetworkMaxNodeShareSecurityCouncilAdderPath: settingKindUint256,
NetworkMaxRethBalanceDeltaPath: settingKindUint256,
NetworkRethDepositDelaySettingPath: settingKindUint256,
},
NodeSettingsContractName: {
NodeRegistrationEnabledSettingPath: settingKindBool,
Expand All @@ -91,6 +92,8 @@ var pdaoSettingKinds = map[string]map[string]settingKind{
MinimumLegacyRplStakePath: settingKindUint256,
ReducedBondSettingPath: settingKindUint256,
NodeUnstakingPeriodSettingPath: settingKindUint256,
NodeWithdrawalCooldownSettingPath: settingKindUint256,
MaximumStakeForVotingPowerSettingPath: settingKindUint256,
},
ProposalsSettingsContractName: {
VotePhase1TimeSettingPath: settingKindUint256,
Expand All @@ -113,6 +116,8 @@ var pdaoSettingKinds = map[string]map[string]settingKind{
SecurityProposalVoteTimeSettingPath: settingKindUint256,
SecurityProposalExecuteTimeSettingPath: settingKindUint256,
SecurityProposalActionTimeSettingPath: settingKindUint256,
SecurityUpgradeVetoQuorumSettingPath: settingKindUint256,
SecurityUpgradeDelaySettingPath: settingKindUint256,
},
MegapoolSettingsContractName: {
MegapoolTimeBeforeDissolveSettingsPath: settingKindUint256,
Expand Down
14 changes: 4 additions & 10 deletions rocketpool-cli/odao/execute-upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"strconv"
"time"

"github.com/ethereum/go-ethereum/common"

"github.com/rocket-pool/smartnode/bindings/dao/upgrades"
"github.com/rocket-pool/smartnode/bindings/transactions/gaslimit"
"github.com/rocket-pool/smartnode/bindings/types"
Expand Down Expand Up @@ -34,17 +32,12 @@ func getUpgradeProposals() error {

fmt.Printf("Found %d upgrade proposals.\n\n", len(upgradeProposals.Proposals))

typeMap := make(map[string]string)
typeMap["0x529a09aed0ded46c4cc64a5f9a6cb6dbde240a9e9c966041749f311248110e11"] = "UpgradeContract"
typeMap["0x19f10da52b60efe9f5ee07f5d429a865c0bda23ae1482284927780c41b724cef"] = "AddContract"
typeMap["0x1ca99adef8e0f1a6fa2cbc2b46aedc54c66479f38df59bff3575de40893db660"] = "AddABI"
typeMap["0xbe19c295254203061a6ecbbdd7353a2134a6bae25c11f27532123ce4a4be1600"] = "UpgradeABI"
// Print upgrade proposals
for _, proposal := range upgradeProposals.Proposals {
fmt.Printf("Upgrade proposal %d: %s\n", proposal.ID, proposal.Name)
fmt.Printf(" State: %s\n", types.UpgradeProposalStates[types.UpgradeProposalState(proposal.State)])
fmt.Printf(" End time: %s\n", time.Unix(proposal.EndTime.Int64(), 0).Format(time.RFC3339))
fmt.Printf(" Type: %s\n", typeMap[common.BytesToHash([]byte(proposal.Type[:])).String()])
fmt.Printf(" Type: %s\n", proposal.TypeName())
fmt.Printf(" Upgrade address: %s\n", proposal.UpgradeAddress)
fmt.Printf(" Upgrade ABI: %s\n", proposal.UpgradeAbi)

Expand Down Expand Up @@ -92,6 +85,7 @@ func executeUpgrade(proposal string, yes bool) error {
fmt.Printf(" ID %d: %s\n", proposal.ID, proposal.Name)
fmt.Printf(" State: %s\n", types.UpgradeProposalStates[types.UpgradeProposalState(proposal.State)])
fmt.Printf(" End time: %s\n", time.Unix(proposal.EndTime.Int64(), 0).Format(time.RFC3339))
fmt.Printf(" Type: %s\n", proposal.TypeName())
fmt.Printf(" Upgrade address: %s\n", proposal.UpgradeAddress)
fmt.Printf(" Upgrade ABI: %s\n\n", proposal.UpgradeAbi)
}
Expand Down Expand Up @@ -134,7 +128,7 @@ func executeUpgrade(proposal string, yes bool) error {
options := make([]string, len(executableProposals)+1)
options[0] = "All available proposals"
for pi, proposal := range executableProposals {
options[pi+1] = fmt.Sprintf("proposal %d (name: '%s', type: '%s', upgrade address: '%s', upgrade ABI: '%s')", proposal.ID, proposal.Name, proposal.Type, proposal.UpgradeAddress, proposal.UpgradeAbi)
options[pi+1] = fmt.Sprintf("proposal %d (name: '%s', type: '%s', upgrade address: '%s', upgrade ABI: '%s')", proposal.ID, proposal.Name, proposal.TypeName(), proposal.UpgradeAddress, proposal.UpgradeAbi)
}
selected, _ := prompt.Select("Please select a proposal to execute:", options)

Expand Down Expand Up @@ -173,7 +167,7 @@ func executeUpgrade(proposal string, yes bool) error {
// Execute proposals
for _, proposal := range selectedProposals {
g.Assign(rp)
response, err := rp.ExecuteTNDAOProposal(proposal.ID)
response, err := rp.ExecuteUpgradeProposal(proposal.ID)
if err != nil {
fmt.Printf("Could not execute proposal %d: %s.\n", proposal.ID, err)
continue
Expand Down
Loading
Loading