Skip to content

Commit

Permalink
test: add test cases where contract returns an error (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
maximopalopoli authored Jan 21, 2025
1 parent 42729c2 commit a7fce28
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 30 deletions.
61 changes: 31 additions & 30 deletions chainio/clients/elcontracts/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,7 @@ func (r *ChainReader) IsOperatorRegistered(
return false, errors.New("DelegationManager contract not provided")
}

isOperator, err := r.delegationManager.IsOperator(
&bind.CallOpts{Context: ctx},
gethcommon.HexToAddress(operator.Address),
)
if err != nil {
return false, err
}

return isOperator, nil
return r.delegationManager.IsOperator(&bind.CallOpts{Context: ctx}, gethcommon.HexToAddress(operator.Address))
}

// GetStakerShares returns the amount of shares that a staker has in all of the strategies in which they have nonzero
Expand Down Expand Up @@ -140,6 +132,7 @@ func (r *ChainReader) GetOperatorDetails(
&bind.CallOpts{Context: ctx},
gethcommon.HexToAddress(operator.Address),
)
// This call should not fail since it's a getter
if err != nil {
return types.Operator{}, err
}
Expand All @@ -150,6 +143,7 @@ func (r *ChainReader) GetOperatorDetails(
},
gethcommon.HexToAddress(operator.Address),
)
// This call should not fail
if err != nil {
return types.Operator{}, err
}
Expand All @@ -174,6 +168,7 @@ func (r *ChainReader) GetStrategyAndUnderlyingToken(
strategyAddr gethcommon.Address,
) (*strategy.ContractIStrategy, gethcommon.Address, error) {
contractStrategy, err := strategy.NewContractIStrategy(strategyAddr, r.ethClient)
// This call should not fail since it's an init
if err != nil {
return nil, gethcommon.Address{}, utils.WrapError("Failed to fetch strategy contract", err)
}
Expand All @@ -191,6 +186,7 @@ func (r *ChainReader) GetStrategyAndUnderlyingERC20Token(
strategyAddr gethcommon.Address,
) (*strategy.ContractIStrategy, erc20.ContractIERC20Methods, gethcommon.Address, error) {
contractStrategy, err := strategy.NewContractIStrategy(strategyAddr, r.ethClient)
// This call should not fail since it's an init
if err != nil {
return nil, nil, gethcommon.Address{}, utils.WrapError("Failed to fetch strategy contract", err)
}
Expand All @@ -199,6 +195,7 @@ func (r *ChainReader) GetStrategyAndUnderlyingERC20Token(
return nil, nil, gethcommon.Address{}, utils.WrapError("Failed to fetch token contract", err)
}
contractUnderlyingToken, err := erc20.NewContractIERC20(underlyingTokenAddr, r.ethClient)
// This call should not fail, if the strategy does not have an underlying token then it would enter the if above
if err != nil {
return nil, nil, gethcommon.Address{}, utils.WrapError("Failed to fetch token contract", err)
}
Expand Down Expand Up @@ -334,13 +331,7 @@ func (r *ChainReader) GetOperatorAVSSplit(
return 0, errors.New("RewardsCoordinator contract not provided")
}

split, err := r.rewardsCoordinator.GetOperatorAVSSplit(&bind.CallOpts{Context: ctx}, operator, avs)

if err != nil {
return 0, err
}

return split, nil
return r.rewardsCoordinator.GetOperatorAVSSplit(&bind.CallOpts{Context: ctx}, operator, avs)
}

func (r *ChainReader) GetOperatorPISplit(
Expand All @@ -351,13 +342,7 @@ func (r *ChainReader) GetOperatorPISplit(
return 0, errors.New("RewardsCoordinator contract not provided")
}

split, err := r.rewardsCoordinator.GetOperatorPISplit(&bind.CallOpts{Context: ctx}, operator)

if err != nil {
return 0, err
}

return split, nil
return r.rewardsCoordinator.GetOperatorPISplit(&bind.CallOpts{Context: ctx}, operator)
}

func (r *ChainReader) GetAllocatableMagnitude(
Expand Down Expand Up @@ -398,6 +383,7 @@ func (r *ChainReader) GetAllocationInfo(
operatorAddress,
strategyAddress,
)
// This call should not fail since it's a getter
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -474,13 +460,15 @@ func (r *ChainReader) IsOperatorRegisteredWithOperatorSet(
if operatorSet.Id == 0 {
// this is an M2 AVS
status, err := r.avsDirectory.AvsOperatorStatus(&bind.CallOpts{Context: ctx}, operatorSet.Avs, operatorAddress)
// This call should not fail since it's a getter
if err != nil {
return false, err
}

return status == 1, nil
} else {
registeredOperatorSets, err := r.allocationManager.GetRegisteredSets(&bind.CallOpts{Context: ctx}, operatorAddress)
// This call should not fail since it's a getter
if err != nil {
return false, err
}
Expand Down Expand Up @@ -543,6 +531,7 @@ func (r *ChainReader) GetSlashableShares(
}

currentBlock, err := r.ethClient.BlockNumber(ctx)
// This call should not fail since it's a getter
if err != nil {
return nil, err
}
Expand All @@ -554,6 +543,7 @@ func (r *ChainReader) GetSlashableShares(
strategies,
uint32(currentBlock),
)
// This call should not fail since it's a getter
if err != nil {
return nil, err
}
Expand All @@ -578,6 +568,7 @@ func (r *ChainReader) GetSlashableSharesForOperatorSets(
operatorSets []allocationmanager.OperatorSet,
) ([]OperatorSetStakes, error) {
currentBlock, err := r.ethClient.BlockNumber(ctx)
// This call should not fail since it's a getter
if err != nil {
return nil, err
}
Expand All @@ -602,6 +593,7 @@ func (r *ChainReader) GetSlashableSharesForOperatorSetsBefore(
}

strategies, err := r.GetStrategiesForOperatorSet(ctx, operatorSet)
// If operator setId is 0 will fail on if above
if err != nil {
return nil, err
}
Expand All @@ -616,6 +608,7 @@ func (r *ChainReader) GetSlashableSharesForOperatorSetsBefore(
strategies,
futureBlock,
)
// This call should not fail since it's a getter
if err != nil {
return nil, err
}
Expand All @@ -639,6 +632,7 @@ func (r *ChainReader) GetAllocationDelay(
return 0, errors.New("AllocationManager contract not provided")
}
isSet, delay, err := r.allocationManager.GetAllocationDelay(&bind.CallOpts{Context: ctx}, operatorAddress)
// This call should not fail since it's a getter
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -672,8 +666,9 @@ func (r *ChainReader) CanCall(
target,
selector,
)
// This call should not fail since it's a getter
if err != nil {
return false, errors.New("call to permission controller failed: " + err.Error())
return false, utils.WrapError("call to permission controller failed", err)
}
return canCall, nil
}
Expand All @@ -690,8 +685,9 @@ func (r *ChainReader) ListAppointees(
target,
selector,
)
// This call should not fail since it's a getter
if err != nil {
return nil, errors.New("call to permission controller failed: " + err.Error())
return nil, utils.WrapError("call to permission controller failed", err)
}
return appointees, nil
}
Expand All @@ -706,8 +702,9 @@ func (r *ChainReader) ListAppointeePermissions(
accountAddress,
appointeeAddress,
)
// This call should not fail since it's a getter
if err != nil {
return nil, nil, errors.New("call to permission controller failed: " + err.Error())
return nil, nil, utils.WrapError("call to permission controller failed", err)
}
return targets, selectors, nil
}
Expand All @@ -717,8 +714,9 @@ func (r *ChainReader) ListPendingAdmins(
accountAddress gethcommon.Address,
) ([]gethcommon.Address, error) {
pendingAdmins, err := r.permissionController.GetPendingAdmins(&bind.CallOpts{Context: ctx}, accountAddress)
// This call should not fail since it's a getter
if err != nil {
return nil, errors.New("call to permission controller failed: " + err.Error())
return nil, utils.WrapError("call to permission controller failed", err)
}
return pendingAdmins, nil
}
Expand All @@ -728,8 +726,9 @@ func (r *ChainReader) ListAdmins(
accountAddress gethcommon.Address,
) ([]gethcommon.Address, error) {
pendingAdmins, err := r.permissionController.GetAdmins(&bind.CallOpts{Context: ctx}, accountAddress)
// This call should not fail since it's a getter
if err != nil {
return nil, errors.New("call to permission controller failed: " + err.Error())
return nil, utils.WrapError("call to permission controller failed", err)
}
return pendingAdmins, nil
}
Expand All @@ -744,8 +743,9 @@ func (r *ChainReader) IsPendingAdmin(
accountAddress,
pendingAdminAddress,
)
// This call should not fail since it's a getter
if err != nil {
return isPendingAdmin, errors.New("call to permission controller failed: " + err.Error())
return false, utils.WrapError("call to permission controller failed", err)
}
return isPendingAdmin, nil
}
Expand All @@ -756,8 +756,9 @@ func (r *ChainReader) IsAdmin(
adminAddress gethcommon.Address,
) (bool, error) {
isAdmin, err := r.permissionController.IsAdmin(&bind.CallOpts{Context: ctx}, accountAddress, adminAddress)
// This call should not fail since it's a getter
if err != nil {
return isAdmin, errors.New("call to permission controller failed: " + err.Error())
return false, utils.WrapError("call to permission controller failed", err)
}
return isAdmin, nil
}
38 changes: 38 additions & 0 deletions chainio/clients/elcontracts/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,44 @@ func TestAppointeesFunctions(t *testing.T) {
})
}

func TestContractErrorCases(t *testing.T) {
ctx := context.Background()

testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
require.NoError(t, err)

anvilHttpEndpoint, err := anvilC.Endpoint(context.Background(), "http")
require.NoError(t, err)
contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

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

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

strategyAddr := common.HexToAddress("34634374736473673643")

t.Run("GetStrategyAndUnderlyingToken", func(t *testing.T) {
strategy, undToken, err := chainReader.GetStrategyAndUnderlyingToken(ctx, strategyAddr)
assert.Zero(t, strategy)
assert.Zero(t, undToken)
assert.Error(t, err)
assert.Equal(t, err.Error(), "Failed to fetch token contract: no contract code at given address")
})

t.Run("GetStrategyAndUnderlyingERC20Token", func(t *testing.T) {
strategy, methods, undToken, err := chainReader.GetStrategyAndUnderlyingERC20Token(ctx, strategyAddr)
assert.Zero(t, strategy)
assert.Zero(t, methods)
assert.Zero(t, undToken)
assert.Error(t, err)
assert.Equal(t, err.Error(), "Failed to fetch token contract: no contract code at given address")
})
}

func TestOperatorSetsAndSlashableShares(t *testing.T) {
testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
Expand Down

0 comments on commit a7fce28

Please sign in to comment.