Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(stride): Update Redeem method, types and tests. #1935

Merged
merged 15 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (stride-outpost) [#1926](https://github.com/evmos/evmos/pull/1926) Refactor event names and definitions.
- (stride-outpost) [#1931](https://github.com/evmos/evmos/pull/1931) Add Stride unit testing setup.
- (stride-outpost) [#1932](https://github.com/evmos/evmos/pull/1932) Add transaction implementation and events unit tests.
- (stride-outpost) [#1935](https://github.com/evmos/evmos/pull/1935) Refactor RedeemStake method.

### Bug Fixes

Expand Down
22 changes: 13 additions & 9 deletions precompiles/outposts/stride/IStrideOutpost.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ interface IStrideOutpost {

/// @dev Emitted on a Redeem transaction.
/// @param sender The address of the sender.
/// @param receiver The address of the receiver on the Evmos chain.
/// @param token The token to be un-luquid staked.
/// @param receiver The bech32-formatted address of the receiver on the Stride chain.
/// @param strideForwarder The bech32-formatted address of the receiver on the Stride chain.
/// @param amount The amount of tokens to unstake.
event Redeem(
event RedeemStake(
address indexed sender,
address indexed receiver,
address indexed token,
Vvaradinov marked this conversation as resolved.
Show resolved Hide resolved
string receiver,
string strideForwarder,
uint256 amount
);

Expand All @@ -61,7 +63,7 @@ interface IStrideOutpost {
/// @param token The hex ERC20 address of the token pair.
/// @param amount The amount that will be liquid staked.
/// @param receiver The bech32 address of the receiver.
/// @return nextSequence sequence number of the transfer packet sent
/// @return nextSequence The sequence number of the transfer packet sent
/// @return success True if the ICS20 transfer was successful.
function liquidStake(
address sender,
Expand All @@ -73,15 +75,17 @@ interface IStrideOutpost {
/// @dev This method unstakes the LSD Coin (ex. stEvmos, stAtom) and redeems
/// the native Coin by sending an ICS20 Transfer to the specified chain.
/// @param sender The sender of the redeem transaction.
/// @param receiver the address of the receiver on Evmos.
/// @param token The hex address of the token to be redeemed.
/// @param amount The amount of tokens unstaked.
/// @param receiver The bech32-formatted address of the receiver on Stride.
/// @return nextSequence sequence number of the transfer packet sent
/// @param strideForwarder The bech32-formatted address of the receiver on Stride.
/// @return nextSequence The sequence number of the transfer packet sent
/// @return success The boolean value indicating whether the operation succeeded.
function redeem(
function redeemStake(
address sender,
address receiver,
address token,
uint256 amount,
string calldata receiver
string calldata strideForwarder,
uint256 amount
) external returns (uint64 nextSequence, bool success);
}
27 changes: 19 additions & 8 deletions precompiles/outposts/stride/abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
Expand All @@ -91,7 +97,7 @@
{
"indexed": false,
"internalType": "string",
"name": "receiver",
"name": "strideForwarder",
"type": "string"
},
{
Expand All @@ -101,7 +107,7 @@
"type": "uint256"
}
],
"name": "Redeem",
"name": "RedeemStake",
"type": "event"
},
{
Expand Down Expand Up @@ -152,21 +158,26 @@
},
{
"internalType": "address",
"name": "token",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "string",
"name": "receiver",
"name": "strideForwarder",
"type": "string"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "redeem",
"name": "redeemStake",
"outputs": [
{
"internalType": "uint64",
Expand Down
28 changes: 17 additions & 11 deletions precompiles/outposts/stride/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
const (
// EventTypeLiquidStake is the event type emitted on a liquidStake transaction to Autopilot on Stride.
EventTypeLiquidStake = "LiquidStake"
// EventTypeRedeem is the event type emitted on a redeem transaction to Autopilot on Stride.
EventTypeRedeem = "Redeem"
// EventTypeRedeemStake is the event type emitted on a redeem transaction to Autopilot on Stride.
EventTypeRedeemStake = "RedeemStake"
)

// EmitLiquidStakeEvent creates a new LiquidStake event on the EVM stateDB.
Expand Down Expand Up @@ -64,18 +64,18 @@
return nil
}

// EmitRedeemEvent creates a new Redeem event on the EVM stateDB.
func (p Precompile) EmitRedeemEvent(
// EmitRedeemStakeEvent creates a new RedeemStake event on the EVM stateDB.
func (p Precompile) EmitRedeemStakeEvent(
ctx sdk.Context,
stateDB vm.StateDB,
sender,
token common.Address,
receiver string,
token, receiver common.Address,
strideForwarder string,
amount *big.Int,
) error {
// Prepare the event topics
event := p.ABI.Events[EventTypeRedeem]
topics := make([]common.Hash, 3)
event := p.ABI.Events[EventTypeRedeemStake]
topics := make([]common.Hash, 4)

// The first topic is always the signature of the event.
topics[0] = event.ID
Expand All @@ -86,14 +86,20 @@
if err != nil {
return err
}
topics[2], err = cmn.MakeTopic(token)

topics[2], err = cmn.MakeTopic(receiver)
if err != nil {
return err
}

Check warning on line 93 in precompiles/outposts/stride/events.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/events.go#L92-L93

Added lines #L92 - L93 were not covered by tests

topics[3], err = cmn.MakeTopic(token)
if err != nil {
return err
}

// Prepare the event data: receiver, amount
arguments := abi.Arguments{event.Inputs[2], event.Inputs[3]}
packed, err := arguments.Pack(receiver, amount)
arguments := abi.Arguments{event.Inputs[3], event.Inputs[4]}
packed, err := arguments.Pack(strideForwarder, amount)
if err != nil {
return err
}
Expand Down
10 changes: 5 additions & 5 deletions precompiles/outposts/stride/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ func (s *PrecompileTestSuite) TestLiquidStakeEvent() {
tokenPair, ok := s.app.Erc20Keeper.GetTokenPair(s.ctx, denomID)
s.Require().True(ok, "expected token pair to be found")

//nolint:dupl
testCases := []struct {
name string
postCheck func()
Expand Down Expand Up @@ -68,7 +67,6 @@ func (s *PrecompileTestSuite) TestRedeemEvent() {
tokenPair, ok := s.app.Erc20Keeper.GetTokenPair(s.ctx, denomID)
s.Require().True(ok, "expected token pair to be found")

//nolint:dupl
testCases := []struct {
name string
postCheck func()
Expand All @@ -79,15 +77,17 @@ func (s *PrecompileTestSuite) TestRedeemEvent() {
redeemLog := s.stateDB.Logs()[0]
s.Require().Equal(redeemLog.Address, s.precompile.Address())
// Check event signature matches the one emitted
event := s.precompile.ABI.Events[stride.EventTypeRedeem]
event := s.precompile.ABI.Events[stride.EventTypeRedeemStake]
s.Require().Equal(event.ID, common.HexToHash(redeemLog.Topics[0].Hex()))
s.Require().Equal(redeemLog.BlockNumber, uint64(s.ctx.BlockHeight()))

var redeemEvent stride.EventRedeem
err := cmn.UnpackLog(s.precompile.ABI, &redeemEvent, stride.EventTypeRedeem, *redeemLog)
err := cmn.UnpackLog(s.precompile.ABI, &redeemEvent, stride.EventTypeRedeemStake, *redeemLog)
s.Require().NoError(err)
s.Require().Equal(common.BytesToAddress(s.address.Bytes()), redeemEvent.Sender)
s.Require().Equal(common.HexToAddress(tokenPair.Erc20Address), redeemEvent.Token)
s.Require().Equal(s.address, redeemEvent.Receiver)
s.Require().Equal(receiver, redeemEvent.StrideForwarder)
s.Require().Equal(big.NewInt(1e18), redeemEvent.Amount)
},
},
Expand All @@ -97,7 +97,7 @@ func (s *PrecompileTestSuite) TestRedeemEvent() {
s.Run(tc.name, func() {
s.SetupTest()

err := s.precompile.EmitRedeemEvent(s.ctx, s.stateDB, s.address, common.HexToAddress(tokenPair.Erc20Address), receiver, big.NewInt(1e18))
err := s.precompile.EmitRedeemStakeEvent(s.ctx, s.stateDB, s.address, common.HexToAddress(tokenPair.Erc20Address), s.address, receiver, big.NewInt(1e18))
s.Require().NoError(err)
tc.postCheck()
})
Expand Down
6 changes: 3 additions & 3 deletions precompiles/outposts/stride/stride.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@
// Stride Outpost Methods:
case LiquidStakeMethod:
bz, err = p.LiquidStake(ctx, evm.Origin, stateDB, contract, method, args)
case RedeemMethod:
bz, err = p.Redeem(ctx, evm.Origin, stateDB, contract, method, args)
case RedeemStakeMethod:
bz, err = p.RedeemStake(ctx, evm.Origin, stateDB, contract, method, args)

Check warning on line 118 in precompiles/outposts/stride/stride.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/stride.go#L117-L118

Added lines #L117 - L118 were not covered by tests
default:
return nil, fmt.Errorf(cmn.ErrUnknownMethod, method.Name)
}
Expand All @@ -136,7 +136,7 @@
// IsTransaction checks if the given method name corresponds to a transaction or query.
func (Precompile) IsTransaction(method string) bool {
switch method {
case LiquidStakeMethod, RedeemMethod:
case LiquidStakeMethod, RedeemStakeMethod:

Check warning on line 139 in precompiles/outposts/stride/stride.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/stride.go#L139

Added line #L139 was not covered by tests
return true
default:
return false
Expand Down
26 changes: 14 additions & 12 deletions precompiles/outposts/stride/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
const (
// LiquidStakeMethod is the name of the liquidStake method
LiquidStakeMethod = "liquidStake"
// RedeemMethod is the name of the redeem method
RedeemMethod = "redeem"
// RedeemStakeMethod is the name of the redeem method
RedeemStakeMethod = "redeemStake"
// LiquidStakeAction is the action name needed in the memo field
LiquidStakeAction = "LiquidStake"
// RedeemAction is the action name needed in the memo field
RedeemAction = "Redeem"
// RedeemStakeAction is the action name needed in the memo field
RedeemStakeAction = "RedeemStake"
// NoReceiver is the string used in the memo field when the receiver is not needed
NoReceiver = ""
)

// LiquidStake is a transaction that liquid stakes tokens using
Expand Down Expand Up @@ -69,7 +71,7 @@
coin := sdk.Coin{Denom: tokenPair.Denom, Amount: sdk.NewIntFromBigInt(amount)}

// Create the memo for the ICS20 transfer packet
memo, err := CreateMemo(LiquidStakeAction, receiver)
memo, err := CreateMemo(LiquidStakeAction, receiver, NoReceiver)

Check warning on line 74 in precompiles/outposts/stride/tx.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/tx.go#L74

Added line #L74 was not covered by tests
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -131,18 +133,18 @@
return method.Outputs.Pack(res.Sequence, true)
}

// Redeem is a transaction that redeems the native tokens using the liquid stake
// RedeemStake is a transaction that redeems the native tokens using the liquid stake
// tokens. It executes a ICS20 transfer with a custom memo field that will
// trigger Stride's Autopilot middleware
func (p Precompile) Redeem(
func (p Precompile) RedeemStake(
ctx sdk.Context,
origin common.Address,
stateDB vm.StateDB,
contract *vm.Contract,
method *abi.Method,
args []interface{},
) ([]byte, error) {
sender, token, amount, receiver, err := parseLiquidStakeArgs(args)
sender, receiver, token, strideForwarder, amount, err := parseRedeemStakeArgs(args)

Check warning on line 147 in precompiles/outposts/stride/tx.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/tx.go#L147

Added line #L147 was not covered by tests
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -175,7 +177,7 @@
coin := sdk.Coin{Denom: tokenPair.Denom, Amount: sdk.NewIntFromBigInt(amount)}

// Create the memo for the ICS20 transfer
memo, err := CreateMemo(RedeemAction, receiver)
memo, err := CreateMemo(RedeemStakeAction, strideForwarder, sdk.AccAddress(receiver.Bytes()).String())

Check warning on line 180 in precompiles/outposts/stride/tx.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/tx.go#L180

Added line #L180 was not covered by tests
if err != nil {
return nil, err
}
Expand All @@ -186,7 +188,7 @@
p.channelID,
coin,
sdk.AccAddress(sender.Bytes()).String(),
receiver,
strideForwarder,

Check warning on line 191 in precompiles/outposts/stride/tx.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/tx.go#L191

Added line #L191 was not covered by tests
p.timeoutHeight,
0,
memo,
Expand Down Expand Up @@ -229,8 +231,8 @@
return nil, err
}

// Emit the custom Redeem Event
if err := p.EmitRedeemEvent(ctx, stateDB, sender, token, receiver, amount); err != nil {
// Emit the custom RedeemStake Event
if err := p.EmitRedeemStakeEvent(ctx, stateDB, sender, token, receiver, strideForwarder, amount); err != nil {

Check warning on line 235 in precompiles/outposts/stride/tx.go

View check run for this annotation

Codecov / codecov/patch

precompiles/outposts/stride/tx.go#L235

Added line #L235 was not covered by tests
return nil, err
}

Expand Down