diff --git a/rocketpool-cli/commands/node/stake-rpl.go b/rocketpool-cli/commands/node/stake-rpl.go index 0452d5c89..9b1be902c 100644 --- a/rocketpool-cli/commands/node/stake-rpl.go +++ b/rocketpool-cli/commands/node/stake-rpl.go @@ -128,7 +128,10 @@ func nodeStakeRpl(c *cli.Context) error { // Run the stake TX validated, err := tx.HandleTx(c, rp, stakeResponse.Data.StakeTxInfo, - fmt.Sprintf("Are you sure you want to stake %.6f RPL? You will not be able to unstake this RPL until you exit your validators and close your minipools, or reach over 100%% collateral!", math.RoundDown(eth.WeiToEth(amountWei), 6)), + fmt.Sprintf("Are you sure you want to stake %.6f RPL? You will not be able to unstake this RPL until you exit your validators and close your minipools, or reach %.6f staked RPL (%.0f%% of bonded eth)!", + math.RoundDown(eth.WeiToEth(amountWei), 6), + math.RoundDown(eth.WeiToEth(status.Data.MaximumRplStake), 6), + eth.WeiToEth(status.Data.MaximumStakeFraction)*100), "staking RPL", "Staking RPL...", ) diff --git a/rocketpool-daemon/api/node/stake-rpl.go b/rocketpool-daemon/api/node/stake-rpl.go index 912044255..0ca8de00c 100644 --- a/rocketpool-daemon/api/node/stake-rpl.go +++ b/rocketpool-daemon/api/node/stake-rpl.go @@ -10,12 +10,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/gorilla/mux" batch "github.com/rocket-pool/batch-query" + "github.com/rocket-pool/rocketpool-go/v2/dao/protocol" "github.com/rocket-pool/rocketpool-go/v2/node" "github.com/rocket-pool/rocketpool-go/v2/rocketpool" "github.com/rocket-pool/rocketpool-go/v2/tokens" "github.com/rocket-pool/node-manager-core/api/server" "github.com/rocket-pool/node-manager-core/api/types" + "github.com/rocket-pool/node-manager-core/eth" "github.com/rocket-pool/node-manager-core/utils/input" "github.com/rocket-pool/smartnode/v2/rocketpool-daemon/common/utils" "github.com/rocket-pool/smartnode/v2/shared/types/api" @@ -60,6 +62,7 @@ type nodeStakeRplContext struct { node *node.Node balance *big.Int allowance *big.Int + pSettings *protocol.ProtocolDaoSettings } func (c *nodeStakeRplContext) Initialize() (types.ResponseStatus, error) { @@ -86,6 +89,11 @@ func (c *nodeStakeRplContext) Initialize() (types.ResponseStatus, error) { if err != nil { return types.ResponseStatus_Error, fmt.Errorf("error creating RocketNodeStaking binding: %w", err) } + pMgr, err := protocol.NewProtocolDaoManager(c.rp) + if err != nil { + return types.ResponseStatus_Error, fmt.Errorf("error creating pDAO manager binding: %w", err) + } + c.pSettings = pMgr.Settings c.nsAddress = rns.Address return types.ResponseStatus_Success, nil } @@ -93,12 +101,17 @@ func (c *nodeStakeRplContext) Initialize() (types.ResponseStatus, error) { func (c *nodeStakeRplContext) GetState(mc *batch.MultiCaller) { c.rpl.BalanceOf(mc, &c.balance, c.nodeAddress) c.rpl.GetAllowance(mc, &c.allowance, c.nodeAddress, c.nsAddress) + eth.AddQueryablesToMulticall(mc, + c.node.MaximumRplStake, + ) } func (c *nodeStakeRplContext) PrepareData(data *api.NodeStakeRplData, opts *bind.TransactOpts) (types.ResponseStatus, error) { data.InsufficientBalance = (c.amount.Cmp(c.balance) > 0) data.Allowance = c.allowance data.CanStake = !(data.InsufficientBalance) + data.MaximumStakeFraction = c.pSettings.Node.MaximumPerMinipoolStake.Raw() + data.MaximumRplStake = c.node.MaximumRplStake.Get() if data.CanStake { if c.allowance.Cmp(c.amount) < 0 { diff --git a/shared/types/api/node.go b/shared/types/api/node.go index db751f790..9d7416be9 100644 --- a/shared/types/api/node.go +++ b/shared/types/api/node.go @@ -151,11 +151,13 @@ type NodeSwapRplData struct { } type NodeStakeRplData struct { - CanStake bool `json:"canStake"` - InsufficientBalance bool `json:"insufficientBalance"` - Allowance *big.Int `json:"allowance"` - ApproveTxInfo *eth.TransactionInfo `json:"approveTxInfo"` - StakeTxInfo *eth.TransactionInfo `json:"stakeTxInfo"` + CanStake bool `json:"canStake"` + InsufficientBalance bool `json:"insufficientBalance"` + Allowance *big.Int `json:"allowance"` + ApproveTxInfo *eth.TransactionInfo `json:"approveTxInfo"` + StakeTxInfo *eth.TransactionInfo `json:"stakeTxInfo"` + MaximumStakeFraction *big.Int `json:"maximumStakeFraction"` + MaximumRplStake *big.Int `json:"maximumRplStake"` } type NodeSetStakeRplForAllowedData struct {