Skip to content

Commit

Permalink
test: add reader test coverage (#429)
Browse files Browse the repository at this point in the history
Co-authored-by: ricomateo <[email protected]>
Co-authored-by: Tomás Grüner <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2025
1 parent 3bfa0a6 commit fda56ad
Showing 1 changed file with 312 additions and 0 deletions.
312 changes: 312 additions & 0 deletions chainio/clients/elcontracts/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (

"github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts"
erc20 "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IERC20"
rewardscoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IRewardsCoordinator"
"github.com/Layr-Labs/eigensdk-go/testutils"
"github.com/Layr-Labs/eigensdk-go/testutils/testclients"
"github.com/Layr-Labs/eigensdk-go/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -114,6 +116,316 @@ func TestChainReader(t *testing.T) {
assert.NoError(t, err)
assert.NotEmpty(t, digest)
})

t.Run("get staker shares", func(t *testing.T) {
strategies, shares, err := read_clients.ElChainReader.GetStakerShares(
ctx,
common.HexToAddress(operator.Address),
)
assert.NotZero(t, len(strategies), "Strategies has at least one element")
assert.NotZero(t, len(shares), "Shares has at least one element")
assert.Equal(t, len(strategies), len(shares), "Strategies has the same ammount of elements as shares")
assert.NoError(t, err)
})

t.Run("get delegated operator", func(t *testing.T) {
val := big.NewInt(0)
address, err := read_clients.ElChainReader.GetDelegatedOperator(
ctx,
common.HexToAddress(operator.Address),
val,
)

assert.NoError(t, err)
// The delegated operator of an operator is the operator itself
assert.Equal(t, address.String(), operator.Address)
})

}

func TestGetCurrentClaimableDistributionRoot(t *testing.T) {
// Verifies GetCurrentClaimableDistributionRoot returns 0 if no root and the root if there's one
_, anvilHttpEndpoint := testclients.BuildTestClients(t)
ctx := context.Background()

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

root := [32]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
}

rewardsCoordinatorAddr := contractAddrs.RewardsCoordinator
config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
RewardsCoordinatorAddress: rewardsCoordinatorAddr,
}

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

// Create and configure rewards coordinator
ethClient, err := ethclient.Dial(anvilHttpEndpoint)
require.NoError(t, err)
rewardsCoordinator, err := rewardscoordinator.NewContractIRewardsCoordinator(rewardsCoordinatorAddr, ethClient)
require.NoError(t, err)

ecdsaPrivKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY

// Set delay to zero to inmediatly operate with coordinator
receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, ecdsaPrivKeyHex, uint32(0))
require.NoError(t, err)
require.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

// Create txManager to send transactions to the Ethereum node
txManager, err := testclients.NewTestTxManager(anvilHttpEndpoint, ecdsaPrivKeyHex)
require.NoError(t, err)
noSendTxOpts, err := txManager.GetNoSendTxOpts()
require.NoError(t, err)

rewardsUpdater := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)

// Change the rewards updater to be able to submit the new root
tx, err := rewardsCoordinator.SetRewardsUpdater(noSendTxOpts, rewardsUpdater)
require.NoError(t, err)

waitForReceipt := true
_, err = txManager.Send(context.Background(), tx, waitForReceipt)
require.NoError(t, err)

// Check that if there is no root submitted the result is zero
distr_root, err := chainReader.GetCurrentClaimableDistributionRoot(
ctx,
)
assert.NoError(t, err)
assert.Zero(t, distr_root.Root)

currRewardsCalculationEndTimestamp, err := chainReader.CurrRewardsCalculationEndTimestamp(context.Background())
require.NoError(t, err)

tx, err = rewardsCoordinator.SubmitRoot(noSendTxOpts, root, currRewardsCalculationEndTimestamp+1)
require.NoError(t, err)

_, err = txManager.Send(context.Background(), tx, waitForReceipt)
require.NoError(t, err)

// Check that if there is a root submitted the result is that root
distr_root, err = chainReader.GetCurrentClaimableDistributionRoot(
ctx,
)
assert.NoError(t, err)
assert.Equal(t, distr_root.Root, root)
}

func TestGetRootIndexFromRootHash(t *testing.T) {
_, anvilHttpEndpoint := testclients.BuildTestClients(t)
ctx := context.Background()

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

rewardsCoordinatorAddr := contractAddrs.RewardsCoordinator
config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
RewardsCoordinatorAddress: rewardsCoordinatorAddr,
}

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

// Create and configure rewards coordinator
ethClient, err := ethclient.Dial(anvilHttpEndpoint)
require.NoError(t, err)
rewardsCoordinator, err := rewardscoordinator.NewContractIRewardsCoordinator(rewardsCoordinatorAddr, ethClient)
require.NoError(t, err)
ecdsaPrivKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY

// Set delay to zero to inmediatly operate with coordinator
receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, ecdsaPrivKeyHex, uint32(0))
require.NoError(t, err)
require.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

// Create txManager to send transactions to the Ethereum node
txManager, err := testclients.NewTestTxManager(anvilHttpEndpoint, ecdsaPrivKeyHex)
require.NoError(t, err)
noSendTxOpts, err := txManager.GetNoSendTxOpts()
require.NoError(t, err)

rewardsUpdater := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)

// Change the rewards updater to be able to submit the new root
tx, err := rewardsCoordinator.SetRewardsUpdater(noSendTxOpts, rewardsUpdater)
require.NoError(t, err)

waitForReceipt := true
_, err = txManager.Send(context.Background(), tx, waitForReceipt)
require.NoError(t, err)

root := [32]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
}

// Check that if there is no root submitted the result is an InvalidRoot error
root_index, err := chainReader.GetRootIndexFromHash(
ctx,
root,
)
assert.Error(t, err)
assert.Equal(t, err.Error(), "execution reverted: custom error 0x504570e3",
"GetRootIndexFromHash should return an InvalidRoot() error",
)
assert.Zero(t, root_index)

currRewardsCalculationEndTimestamp, err := chainReader.CurrRewardsCalculationEndTimestamp(context.Background())
require.NoError(t, err)

tx, err = rewardsCoordinator.SubmitRoot(noSendTxOpts, root, currRewardsCalculationEndTimestamp+1)
require.NoError(t, err)

_, err = txManager.Send(context.Background(), tx, waitForReceipt)
require.NoError(t, err)

root2 := [32]byte{
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
}

currRewardsCalculationEndTimestamp2, err := chainReader.CurrRewardsCalculationEndTimestamp(context.Background())
require.NoError(t, err)

tx, err = rewardsCoordinator.SubmitRoot(noSendTxOpts, root2, currRewardsCalculationEndTimestamp2+1)
require.NoError(t, err)

_, err = txManager.Send(context.Background(), tx, waitForReceipt)
require.NoError(t, err)

// Check that the first root inserted is the first indexed (zero)
root_index, err = chainReader.GetRootIndexFromHash(
ctx,
root,
)
assert.NoError(t, err)
assert.Equal(t, root_index, uint32(0))

// Check that the second root inserted is the second indexed (zero)
root_index, err = chainReader.GetRootIndexFromHash(
ctx,
root2,
)
assert.NoError(t, err)
assert.Equal(t, root_index, uint32(1))
}

func TestGetCumulativeClaimedRewards(t *testing.T) {
clients, anvilHttpEndpoint := testclients.BuildTestClients(t)
ctx := context.Background()

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

rewardsCoordinatorAddr := contractAddrs.RewardsCoordinator
config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
RewardsCoordinatorAddress: rewardsCoordinatorAddr,
}
privateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY

// Create ChainWriter
chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, privateKeyHex, config)
require.NoError(t, err)

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

activationDelay := uint32(0)
// Set activation delay to zero so that the earnings can be claimed right after submitting the root
receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, privateKeyHex, activationDelay)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

strategyAddr := contractAddrs.Erc20MockStrategy
strategy, contractUnderlyingToken, underlyingTokenAddr, err := clients.ElChainReader.GetStrategyAndUnderlyingERC20Token(
ctx,
strategyAddr,
)
assert.NoError(t, err)
assert.NotNil(t, strategy)
assert.NotEqual(t, common.Address{}, underlyingTokenAddr)
assert.NotNil(t, contractUnderlyingToken)

anvil_address := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)

// This tests that without claims result is zero
claimed, err := chainReader.GetCumulativeClaimed(ctx, anvil_address, underlyingTokenAddr)
assert.Zero(t, claimed.Cmp(big.NewInt(0)))
assert.NoError(t, err)

cumulativeEarnings := int64(45)
claim, err := newTestClaim(chainReader, anvilHttpEndpoint, cumulativeEarnings, privateKeyHex)
require.NoError(t, err)

receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, rewardsCoordinatorAddr, true)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

// This tests that with a claim result is cumulativeEarnings
claimed, err = chainReader.GetCumulativeClaimed(ctx, anvil_address, underlyingTokenAddr)
assert.Equal(t, claimed, big.NewInt(cumulativeEarnings))
assert.NoError(t, err)
}

func TestCheckClaim(t *testing.T) {
clients, anvilHttpEndpoint := testclients.BuildTestClients(t)
ctx := context.Background()

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

rewardsCoordinatorAddr := contractAddrs.RewardsCoordinator
config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
RewardsCoordinatorAddress: rewardsCoordinatorAddr,
}
privateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY

// Create ChainWriter and chain reader
chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, privateKeyHex, config)
require.NoError(t, err)

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

activationDelay := uint32(0)
// Set activation delay to zero so that the earnings can be claimed right after submitting the root
receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, privateKeyHex, activationDelay)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

cumulativeEarnings := int64(45)
claim, err := newTestClaim(chainReader, anvilHttpEndpoint, cumulativeEarnings, privateKeyHex)
require.NoError(t, err)

receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, rewardsCoordinatorAddr, true)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

strategyAddr := contractAddrs.Erc20MockStrategy
strategy, contractUnderlyingToken, underlyingTokenAddr, err := clients.ElChainReader.GetStrategyAndUnderlyingERC20Token(
ctx,
strategyAddr,
)
assert.NoError(t, err)
assert.NotNil(t, strategy)
assert.NotEqual(t, common.Address{}, underlyingTokenAddr)
assert.NotNil(t, contractUnderlyingToken)

checked, err := chainReader.CheckClaim(ctx, *claim)
require.NoError(t, err)
assert.True(t, checked)
}

func TestAdminFunctions(t *testing.T) {
Expand Down

0 comments on commit fda56ad

Please sign in to comment.