Skip to content

Commit

Permalink
feat: Add bonds info
Browse files Browse the repository at this point in the history
  • Loading branch information
khalifaa55 committed Jul 26, 2024
1 parent a137743 commit a197f39
Show file tree
Hide file tree
Showing 5 changed files with 6,534 additions and 0 deletions.
1 change: 1 addition & 0 deletions internal/lido/contracts/csaccounting/CSAccounting.abi

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions internal/lido/contracts/csaccounting/CSAccounting.bin

Large diffs are not rendered by default.

6,362 changes: 6,362 additions & 0 deletions internal/lido/contracts/csaccounting/CSAccounting.go

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions internal/lido/contracts/csaccounting/bonds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package csaccounting

import (
"fmt"
"math/big"

"github.com/NethermindEth/sedge/configs"
"github.com/NethermindEth/sedge/internal/lido/contracts"
"github.com/ethereum/go-ethereum/common"
)

// BondInfo : Struct represent bond info of Node Operator
type BondInfo struct {
Current *big.Int
Required *big.Int
Excess *big.Int
Missed *big.Int
}

var deployedContractAddresses = map[string]string{
configs.NetworkHolesky: "0xc093e53e8F4b55A223c18A2Da6fA00e60DD5EFE1",
}

/*
BondSummary :
This function is responsible for:
retrieving bond info for Lido CSM node
params :-
network (string): The name of the network (e.g."holesky").
nodeID (*big.Int): Node Operator ID
returns :-
a. BondInfo
Struct that include bond info
b. error
Error if any
*/
func BondSummary(network string, nodeID *big.Int) (BondInfo, error) {
var bondsInfo BondInfo
contract, err := csAccountingContract(network)
if err != nil {
return bondsInfo, fmt.Errorf("failed to call csAccountingContract: %w", err)
}

result, err := contract.GetBondSummary(nil, nodeID)
if err != nil {
return bondsInfo, fmt.Errorf("failed to call GetBondSummary: %w", err)
}
bondsInfo.Current = result.Current
bondsInfo.Required = result.Required

// Calculate excess and missed bond amounts
excess := new(big.Int).Sub(bondsInfo.Current, bondsInfo.Required)
missed := new(big.Int).Sub(bondsInfo.Required, bondsInfo.Current)

// Set to zero if negative
if excess.Sign() < 0 {
excess.SetInt64(0)
}
if missed.Sign() < 0 {
missed.SetInt64(0)
}

bondsInfo.Excess = excess
bondsInfo.Missed = missed
return bondsInfo, nil
}

/*
BondShares :
This function is responsible for:
retrieving bond shares for Lido CSM node
params :-
network (string): The name of the network (e.g."holesky").
nodeID (*big.Int): Node Operator ID
returns :-
a. *big.Int
Struct that include keys status
b. error
Error if any
*/
func BondShares(network string, nodeID *big.Int) (*big.Int, error) {
var shares *big.Int
contract, err := csAccountingContract(network)
if err != nil {
return nil, fmt.Errorf("failed to call csAccountingContract: %w", err)
}

shares, err = contract.GetBondShares(nil, nodeID)
if err != nil {
return nil, fmt.Errorf("failed to call GetBondShares: %w", err)
}
return shares, nil
}

func csAccountingContract(network string) (*CSAccounting, error) {
client, err := contracts.ConnectClient(network)
if err != nil {
return nil, fmt.Errorf("failed to call ConnectContract: %w", err)
}
defer client.Close()

address := common.HexToAddress(deployedContractAddresses[network])
contract, err := NewCSAccounting(address, client)
if err != nil {
return nil, fmt.Errorf("failed to create CSAccounting instance: %w", err)
}
return contract, nil
}
62 changes: 62 additions & 0 deletions internal/lido/contracts/csaccounting/bonds_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package csaccounting

import (
"io"
"log"
"math/big"
"testing"
)

func TestBondSummary(t *testing.T) {
log.SetOutput(io.Discard)
tcs := []struct {
name string
network string
nodeID *big.Int
invalidId bool
}{
{
"BondSummary with valid ID, Holesky #1", "holesky", big.NewInt(2), false,
},
{
"BondSummary with valid ID, Holesky #2", "holesky", big.NewInt(14), false,
},
{
"BondSummary with invalid ID, Holesky ", "holesky", big.NewInt(-6), true,
},
}
var expectedExcess, expectedMissed *big.Int
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
bond, err := BondSummary(tc.network, tc.nodeID)
if err != nil {
t.Fatalf("failed to call BondsSummary: %v", err)
}
if tc.invalidId && bond.Current.Sign() > 0 {
t.Errorf("invalid current bond amount, expected %v, got: %v", big.NewInt(0), bond.Current)
}
if tc.invalidId && bond.Required.Sign() > 0 {
t.Errorf("invalid required bond amount, expected %v, got: %v", big.NewInt(0), bond.Required)
}

// if current amount is greater than required
if bond.Current.Cmp(bond.Required) == 1 {
expectedExcess = new(big.Int).Sub(bond.Current, bond.Required)
expectedMissed = big.NewInt(0)
} else if bond.Current.Cmp(bond.Required) == -1 {
expectedExcess = big.NewInt(0)
expectedMissed = new(big.Int).Sub(bond.Required, bond.Current)
} else {
expectedExcess = big.NewInt(0)
expectedMissed = big.NewInt(0)
}

if bond.Excess.Cmp(expectedExcess) != 0 {
t.Errorf("not same excess bond amount, expected %v, got: %v", expectedExcess, bond.Excess)
}
if bond.Missed.Cmp(expectedMissed) != 0 {
t.Errorf("not same missed bond amount, expected %v, got: %v", expectedMissed, bond.Missed)
}
})
}
}

0 comments on commit a197f39

Please sign in to comment.