forked from rocket-pool/rocketpool-go
/
staking.go
182 lines (164 loc) · 6.46 KB
/
staking.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package node
import (
"fmt"
"math/big"
"sync"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/PatriceVignola/rocketpool-go/rocketpool"
)
// Get the total RPL staked in the network
func GetTotalRPLStake(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
totalRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, totalRplStake, "getTotalRPLStake"); err != nil {
return nil, fmt.Errorf("Could not get total network RPL stake: %w", err)
}
return *totalRplStake, nil
}
// Get the effective RPL staked in the network
func GetTotalEffectiveRPLStake(rp *rocketpool.RocketPool, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
totalEffectiveRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, totalEffectiveRplStake, "getTotalEffectiveRPLStake"); err != nil {
return nil, fmt.Errorf("Could not get effective network RPL stake: %w", err)
}
return *totalEffectiveRplStake, nil
}
// Get a node's RPL stake
func GetNodeRPLStake(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
nodeRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, nodeRplStake, "getNodeRPLStake", nodeAddress); err != nil {
return nil, fmt.Errorf("Could not get total node RPL stake: %w", err)
}
return *nodeRplStake, nil
}
// Get a node's effective RPL stake
func GetNodeEffectiveRPLStake(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
nodeEffectiveRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, nodeEffectiveRplStake, "getNodeEffectiveRPLStake", nodeAddress); err != nil {
return nil, fmt.Errorf("Could not get effective node RPL stake: %w", err)
}
return *nodeEffectiveRplStake, nil
}
// Get a node's minimum RPL stake to collateralize their minipools
func GetNodeMinimumRPLStake(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
nodeMinimumRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, nodeMinimumRplStake, "getNodeMinimumRPLStake", nodeAddress); err != nil {
return nil, fmt.Errorf("Could not get minimum node RPL stake: %w", err)
}
return *nodeMinimumRplStake, nil
}
// Get a node's maximum RPL stake to collateralize their minipools
func GetNodeMaximumRPLStake(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
nodeMaximumRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, nodeMaximumRplStake, "getNodeMaximumRPLStake", nodeAddress); err != nil {
return nil, fmt.Errorf("Could not get maximum node RPL stake: %w", err)
}
return *nodeMaximumRplStake, nil
}
// Get the time a node last staked RPL
func GetNodeRPLStakedTime(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (uint64, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return 0, err
}
nodeRplStakedTime := new(*big.Int)
if err := rocketNodeStaking.Call(opts, nodeRplStakedTime, "getNodeRPLStakedTime", nodeAddress); err != nil {
return 0, fmt.Errorf("Could not get node RPL staked time: %w", err)
}
return (*nodeRplStakedTime).Uint64(), nil
}
// Get a node's minipool limit based on RPL stake
func GetNodeMinipoolLimit(rp *rocketpool.RocketPool, nodeAddress common.Address, opts *bind.CallOpts) (uint64, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return 0, err
}
minipoolLimit := new(*big.Int)
if err := rocketNodeStaking.Call(opts, minipoolLimit, "getNodeMinipoolLimit", nodeAddress); err != nil {
return 0, fmt.Errorf("Could not get node minipool limit: %w", err)
}
return (*minipoolLimit).Uint64(), nil
}
// Estimate the gas of Stake
func EstimateStakeGas(rp *rocketpool.RocketPool, rplAmount *big.Int, opts *bind.TransactOpts) (rocketpool.GasInfo, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return rocketpool.GasInfo{}, err
}
return rocketNodeStaking.GetTransactionGasInfo(opts, "stakeRPL", rplAmount)
}
// Stake RPL
func StakeRPL(rp *rocketpool.RocketPool, rplAmount *big.Int, opts *bind.TransactOpts) (common.Hash, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return common.Hash{}, err
}
hash, err := rocketNodeStaking.Transact(opts, "stakeRPL", rplAmount)
if err != nil {
return common.Hash{}, fmt.Errorf("Could not stake RPL: %w", err)
}
return hash, nil
}
// Estimate the gas of WithdrawRPL
func EstimateWithdrawRPLGas(rp *rocketpool.RocketPool, rplAmount *big.Int, opts *bind.TransactOpts) (rocketpool.GasInfo, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return rocketpool.GasInfo{}, err
}
return rocketNodeStaking.GetTransactionGasInfo(opts, "withdrawRPL", rplAmount)
}
// Withdraw staked RPL
func WithdrawRPL(rp *rocketpool.RocketPool, rplAmount *big.Int, opts *bind.TransactOpts) (common.Hash, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return common.Hash{}, err
}
hash, err := rocketNodeStaking.Transact(opts, "withdrawRPL", rplAmount)
if err != nil {
return common.Hash{}, fmt.Errorf("Could not withdraw staked RPL: %w", err)
}
return hash, nil
}
// Calculate total effective RPL stake
func CalculateTotalEffectiveRPLStake(rp *rocketpool.RocketPool, offset, limit, rplPrice *big.Int, opts *bind.CallOpts) (*big.Int, error) {
rocketNodeStaking, err := getRocketNodeStaking(rp)
if err != nil {
return nil, err
}
totalEffectiveRplStake := new(*big.Int)
if err := rocketNodeStaking.Call(opts, totalEffectiveRplStake, "calculateTotalEffectiveRPLStake", offset, limit, rplPrice); err != nil {
return nil, fmt.Errorf("Could not get total effective RPL stake: %w", err)
}
return *totalEffectiveRplStake, nil
}
// Get contracts
var rocketNodeStakingLock sync.Mutex
func getRocketNodeStaking(rp *rocketpool.RocketPool) (*rocketpool.Contract, error) {
rocketNodeStakingLock.Lock()
defer rocketNodeStakingLock.Unlock()
return rp.GetContract("rocketNodeStaking")
}