Skip to content

Commit 9ba5f61

Browse files
feat: get slashable stake from contract call (#265)
1 parent 9aed8b7 commit 9ba5f61

File tree

6 files changed

+93
-30
lines changed

6 files changed

+93
-30
lines changed

.github/workflows/integration-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
with:
2424
repository: layr-labs/eigensdk-go
2525
token: ${{ github.token }}
26-
ref: 525ebfea245aadbd0497a5be2999c3b19dbbd68b
26+
ref: 7d3c828d8b48fd334d1805c2ecc27cddb7b20487
2727

2828
- name: Run anvil chain
2929
run: |
@@ -96,7 +96,7 @@ jobs:
9696
with:
9797
repository: layr-labs/eigensdk-go
9898
token: ${{ github.token }}
99-
ref: 525ebfea245aadbd0497a5be2999c3b19dbbd68b
99+
ref: 7d3c828d8b48fd334d1805c2ecc27cddb7b20487
100100
- name: Run anvil chain
101101
run: |
102102
nohup make start-anvil-with-contracts-deployed > nohup.out 2>&1 &

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/Layr-Labs/eigenlayer-contracts v0.3.2-mainnet-rewards
88
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12
99
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e
10-
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241216183922-525ebfea245a
10+
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241217185241-7d3c828d8b48
1111
github.com/blang/semver/v4 v4.0.0
1212
github.com/consensys/gnark-crypto v0.12.1
1313
github.com/ethereum/go-ethereum v1.14.5

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12 h1:G5Q1SnLmFbEjhOkky3vIHk
1212
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12/go.mod h1:OlJd1QjqEW53wfWG/lJyPCGvrXwWVEjPQsP4TV+gttQ=
1313
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e h1:DvW0/kWHV9mZsbH2KOjEHKTSIONNPUj6X05FJvUohy4=
1414
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e/go.mod h1:T7tYN8bTdca2pkMnz9G2+ZwXYWw5gWqQUIu4KLgC/vM=
15-
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241213014620-7831a35a43a7 h1:58JjbKZs0oaGRQv/AU+XtqWvD3+dyKM4NIbqjACANN0=
16-
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241213014620-7831a35a43a7/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
17-
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241216183922-525ebfea245a h1:SW/dP6D6YjN3y/vXC++TBmekXo/fDGcPXoYHitARz/I=
18-
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241216183922-525ebfea245a/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
15+
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241217185241-7d3c828d8b48 h1:tAuh8CCvqAY9tf8WUhAMdUFx2UiSqWfwrjmNB4prRfQ=
16+
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241217185241-7d3c828d8b48/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
1917
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
2018
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
2119
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=

pkg/operator/allocations/show.go

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package allocations
22

33
import (
4+
"context"
45
"fmt"
56
"math/big"
67
"sort"
@@ -132,7 +133,7 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error {
132133
}
133134

134135
/*
135-
5. Get the operator scaled shares for all strategies
136+
5. Get the operator shares for all strategies
136137
*/
137138
operatorDelegatedSharesMap := make(map[string]*big.Int)
138139
shares, err := elReader.GetOperatorShares(ctx, config.operatorAddress, config.strategyAddresses)
@@ -144,24 +145,43 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error {
144145
}
145146

146147
/*
147-
6. Using all of the above, calculate SlashableMagnitudeHolders object
148-
for displaying the allocation state of the operator
148+
6. Using all of the above, get Slashable Shares for the operator
149+
*/
150+
slashableSharesMap, err := getSlashableShares(
151+
ctx,
152+
config.operatorAddress,
153+
registeredOperatorSets,
154+
config.strategyAddresses,
155+
elReader,
156+
)
157+
if err != nil {
158+
return eigenSdkUtils.WrapError("failed to get slashable shares", err)
159+
}
160+
161+
/*
162+
7. Using all of the above, calculate SlashableMagnitudeHolders object
163+
for displaying the allocation state of the operator
149164
*/
150165
slashableMagnitudeHolders := make(SlashableMagnitudeHolders, 0)
151166
dergisteredOpsets := make(DeregsiteredOperatorSets, 0)
152167
for strategy, allocations := range allAllocations {
153168
logger.Debugf("Strategy: %s, Allocations: %v", strategy, allocations)
154169
strategyShares := operatorDelegatedSharesMap[strategy]
170+
totalMagnitude := totalMagnitudeMap[strategy]
155171
for _, alloc := range allocations {
156-
currentShares, currentSharesPercentage := getSharesFromMagnitude(
157-
strategyShares,
158-
alloc.CurrentMagnitude.Uint64(),
159-
)
172+
currentShares := slashableSharesMap[gethcommon.HexToAddress(strategy)][getUniqueKey(alloc.AvsAddress, alloc.OperatorSetId)]
173+
currentSharesPercentage := getSharePercentage(currentShares, strategyShares)
174+
160175
newMagnitudeBigInt := big.NewInt(0)
161176
if alloc.PendingDiff.Cmp(big.NewInt(0)) != 0 {
162177
newMagnitudeBigInt = big.NewInt(0).Add(alloc.CurrentMagnitude, alloc.PendingDiff)
163178
}
164-
newShares, newSharesPercentage := getSharesFromMagnitude(strategyShares, newMagnitudeBigInt.Uint64())
179+
180+
newShares, newSharesPercentage := getSharesFromMagnitude(
181+
strategyShares,
182+
newMagnitudeBigInt.Uint64(),
183+
totalMagnitude,
184+
)
165185

166186
// Check if the operator set is not registered and add it to the unregistered list
167187
// Then skip the rest of the loop
@@ -235,36 +255,65 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error {
235255
return nil
236256
}
237257

238-
func getSharesFromMagnitude(totalScaledShare *big.Int, magnitude uint64) (*big.Int, *big.Float) {
258+
func getSharePercentage(shares *big.Int, totalShares *big.Int) *big.Float {
259+
percentageShares := big.NewInt(1)
260+
percentageShares = percentageShares.Mul(shares, big.NewInt(100))
261+
percentageSharesFloat := new(
262+
big.Float,
263+
).Quo(new(big.Float).SetInt(percentageShares), new(big.Float).SetInt(totalShares))
264+
return percentageSharesFloat
265+
}
266+
267+
func getSlashableShares(
268+
ctx context.Context,
269+
operatorAddress gethcommon.Address,
270+
opSets []allocationmanager.OperatorSet,
271+
strategyAddresses []gethcommon.Address,
272+
reader elChainReader,
273+
) (map[gethcommon.Address]map[string]*big.Int, error) {
274+
result := make(map[gethcommon.Address]map[string]*big.Int)
275+
for _, opSet := range opSets {
276+
slashableSharesMap, err := reader.GetSlashableShares(ctx, operatorAddress, opSet, strategyAddresses)
277+
if err != nil {
278+
return nil, err
279+
}
239280

281+
for strat, shares := range slashableSharesMap {
282+
if _, ok := result[strat]; !ok {
283+
result[strat] = make(map[string]*big.Int)
284+
}
285+
result[strat][getUniqueKey(opSet.Avs, opSet.Id)] = shares
286+
}
287+
}
288+
return result, nil
289+
}
290+
291+
func getSharesFromMagnitude(totalShare *big.Int, magnitude uint64, totalMagnitude uint64) (*big.Int, *big.Float) {
240292
/*
241-
* shares = totalScaledShare * magnitude / PrecisionFactor
242-
* percentageShares = (shares / totalScaledShare) * 100
293+
* shares = totalShare * magnitude / totalMagnitude
294+
* percentageShares = (shares / totalShare) * 100
243295
*/
244296
// Check for zero magnitude or totalScaledShare to avoid divide-by-zero errors
245-
if magnitude == 0 || totalScaledShare.Cmp(big.NewInt(0)) == 0 {
297+
if magnitude == 0 || totalShare.Cmp(big.NewInt(0)) == 0 {
246298
return big.NewInt(0), big.NewFloat(0)
247299
}
248300

249-
slashableMagBigInt := big.NewInt(1)
250-
slashableMagBigInt = slashableMagBigInt.SetUint64(magnitude)
251-
252-
scaledOpShares := big.NewInt(1)
253-
scaledOpShares = scaledOpShares.Set(totalScaledShare)
254-
scaledOpShares = scaledOpShares.Div(scaledOpShares, PrecisionFactor)
255-
shares := scaledOpShares.Mul(scaledOpShares, slashableMagBigInt)
301+
opShares := big.NewInt(1)
302+
opShares = opShares.Set(totalShare)
303+
shares := opShares.Mul(opShares, big.NewInt(int64(magnitude)))
304+
shares = shares.Div(shares, big.NewInt(int64(totalMagnitude)))
256305

257306
percentageShares := big.NewInt(1)
258-
percentageShares = percentageShares.Mul(scaledOpShares, big.NewInt(100))
307+
percentageShares = percentageShares.Mul(opShares, big.NewInt(100))
259308
percentageSharesFloat := new(
260309
big.Float,
261-
).Quo(new(big.Float).SetInt(percentageShares), new(big.Float).SetInt(totalScaledShare))
310+
).Quo(new(big.Float).SetInt(percentageShares), new(big.Float).SetInt(totalShare))
262311

263312
return shares, percentageSharesFloat
264313
}
265314

266-
func getUniqueKey(strategyAddress gethcommon.Address, opSetId uint32) string {
267-
return fmt.Sprintf("%s-%d", strategyAddress.String(), opSetId)
315+
func getUniqueKey(avsAddress gethcommon.Address, opSetId uint32) string {
316+
return fmt.Sprintf("%s-%d", avsAddress.String(), opSetId)
268317
}
269318

270319
func readAndValidateShowConfig(cCtx *cli.Context, logger *logging.Logger) (*showConfig, error) {

pkg/operator/allocations/update.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type elChainReader interface {
3737
operator gethcommon.Address,
3838
strategy gethcommon.Address,
3939
) (uint64, error)
40+
GetSlashableShares(
41+
ctx context.Context,
42+
operatorAddress gethcommon.Address,
43+
operatorSet allocationmanager.OperatorSet,
44+
strategies []gethcommon.Address,
45+
) (map[gethcommon.Address]*big.Int, error)
4046
}
4147

4248
func UpdateCmd(p utils.Prompter) *cli.Command {

pkg/operator/allocations/update_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"math"
7+
"math/big"
78
"os"
89
"testing"
910

@@ -76,6 +77,15 @@ func (f *fakeElChainReader) GetAllocatableMagnitude(
7677
return magnitude, nil
7778
}
7879

80+
func (f *fakeElChainReader) GetSlashableShares(
81+
ctx context.Context,
82+
operatorAddress gethcommon.Address,
83+
operatorSet allocationmanager.OperatorSet,
84+
strategies []gethcommon.Address,
85+
) (map[gethcommon.Address]*big.Int, error) {
86+
return nil, errors.New("not implemented")
87+
}
88+
7989
func TestGenerateAllocationsParams(t *testing.T) {
8090
avsAddress := testutils.GenerateRandomEthereumAddressString()
8191
strategyAddress := testutils.GenerateRandomEthereumAddressString()

0 commit comments

Comments
 (0)