Skip to content

Commit

Permalink
add redelegate unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
skosito committed Aug 28, 2024
1 parent f5dc0c3 commit 758864d
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 16 deletions.
2 changes: 1 addition & 1 deletion precompiles/staking/IStaking.abi
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
{
"internalType": "string",
"name": "validatorSrd",
"name": "validatorSrc",
"type": "string"
},
{
Expand Down
20 changes: 10 additions & 10 deletions precompiles/staking/IStaking.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion precompiles/staking/IStaking.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
{
"internalType": "string",
"name": "validatorSrd",
"name": "validatorSrc",
"type": "string"
},
{
Expand Down
4 changes: 2 additions & 2 deletions precompiles/staking/IStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ interface IStaking {

/// @dev Redelegate coins from validatorSrd to validatorDst
/// @param delegator Delegator address
/// @param validatorSrd Validator from address
/// @param validatorSrc Validator from address
/// @param validatorDst Validator to address
/// @param amount Coins amount
/// @return completionTime Time when redelegation is done
function redelegate(
address delegator,
string memory validatorSrd,
string memory validatorSrc,
string memory validatorDst,
uint256 amount
) external returns (int64 completionTime);
Expand Down
2 changes: 0 additions & 2 deletions precompiles/staking/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,6 @@ func (c *Contract) Redelegate(
return nil, err
}

fmt.Println("redelegate res", res)

return method.Outputs.Pack(res.GetCompletionTime().UTC().Unix())
}

Expand Down
267 changes: 267 additions & 0 deletions precompiles/staking/staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,3 +536,270 @@ func Test_Undelegate(t *testing.T) {
require.Error(t, err)
})
}

func Test_Redelegate(t *testing.T) {
var encoding ethermint.EncodingConfig
appCodec := encoding.Codec

cdc := keeper.NewCodec()

db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
sdkKeepers := keeper.NewSDKKeepers(cdc, db, stateStore)
gasConfig := storetypes.TransientGasConfig()
ctx := keeper.NewContext(stateStore)
require.NoError(t, stateStore.LoadLatestVersion())

stakingGenesisState := stakingtypes.DefaultGenesisState()
stakingGenesisState.Params.BondDenom = config.BaseDenom
sdkKeepers.StakingKeeper.InitGenesis(ctx, stakingGenesisState)

contract := NewIStakingContract(&sdkKeepers.StakingKeeper, appCodec, gasConfig)
require.NotNil(t, contract, "NewIStakingContract() should not return a nil contract")

abi := contract.Abi()
require.NotNil(t, abi, "contract ABI should not be nil")

methodID := abi.Methods[RedelegateMethodName]

t.Run("should fail if validator dest doesn't exist", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.Error(t, err)
})

t.Run("should redelegate", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// redelegate to validator dest
_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.NoError(t, err)
})

t.Run("should fail if delegator is invalid arg", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{42, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.Error(t, err)
})

t.Run("should fail if validator src is invalid arg", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, 42, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.Error(t, err)
})

t.Run("should fail if validator dest is invalid arg", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.NoError(t, err)
})

t.Run("should fail if amount is invalid arg", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Uint64()}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.Error(t, err)
})

t.Run("should fail if wrong args amount", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress}

_, err = contract.Redelegate(ctx, delegatorAddr, &methodID, argsRedelegate)
require.Error(t, err)
})

t.Run("should fail if origin is not delegator", func(t *testing.T) {
r := rand.New(rand.NewSource(42))
validatorSrc := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc)
validatorDest := sample.Validator(t, r)
sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest)

delegator := sample.Bech32AccAddress()
delegatorEthAddr := common.BytesToAddress(delegator.Bytes())
coins := sample.Coins()
err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins())
require.NoError(t, err)
err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, delegator, coins)
require.NoError(t, err)

delegatorAddr := common.BytesToAddress(delegator.Bytes())

argsDelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

// delegate to validator src
delegateMethodID := abi.Methods[DelegateMethodName]
_, err = contract.Delegate(ctx, delegatorAddr, &delegateMethodID, argsDelegate)
require.NoError(t, err)

argsRedelegate := []interface{}{delegatorEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress, coins.AmountOf(config.BaseDenom).Int64()}

originEthAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes())
_, err = contract.Redelegate(ctx, originEthAddr, &methodID, argsRedelegate)
require.ErrorContains(t, err, "origin is not delegator")
})
}

0 comments on commit 758864d

Please sign in to comment.