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

IBC transfer precompile #1459

Closed
wants to merge 16 commits into from
Prev Previous commit
Next Next commit
add more tests/fixes
  • Loading branch information
dssei committed Mar 23, 2024
commit 8cd477e5943dce9a9447a6170416869a52f356c6
8 changes: 8 additions & 0 deletions precompiles/ibc/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"embed"
"errors"
"fmt"
"github.com/sei-protocol/sei-chain/precompiles/wasmd"

Check failure on line 8 in precompiles/ibc/ibc.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -63,12 +63,12 @@
evmKeeper: evmKeeper,
}

for name, m := range newAbi.Methods {
switch name {
case TransferMethod:
p.TransferID = m.ID
}
}

return p, nil
}
Expand Down Expand Up @@ -140,12 +140,20 @@
rerr = errors.New("port is not a string")
return
}
if port == "" {
rerr = errors.New("port cannot be empty")
return
}

channelID, ok := args[2].(string)
if !ok {
rerr = errors.New("channelID is not a string")
return
}
if channelID == "" {
rerr = errors.New("channelID cannot be empty")
return
}

denom := args[3].(string)
if denom == "" {
Expand Down
99 changes: 91 additions & 8 deletions precompiles/ibc/ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func TestPrecompile_Run(t *testing.T) {
wantBz []byte
wantRemainingGas uint64
wantErr bool
wantErrMsg string
}{
{
name: "successful transfer: with amount > 0 between EVM addresses",
Expand All @@ -95,11 +96,89 @@ func TestPrecompile_Run(t *testing.T) {
wantErr: false,
},
{
name: "failed transfer: internal error",
fields: fields{transferKeeper: &MockFailedTransferTransferKeeper{}},
args: commonArgs,
wantBz: nil,
wantErr: true,
name: "failed transfer: internal error",
fields: fields{transferKeeper: &MockFailedTransferTransferKeeper{}},
args: commonArgs,
wantBz: nil,
wantErr: true,
wantErrMsg: "failed to send transfer",
},
{
name: "failed transfer: caller not whitelisted",
fields: fields{transferKeeper: &MockTransferKeeper{}},
args: args{caller: senderEvmAddress, callingContract: common.Address{}, input: commonArgs.input, suppliedGas: 1000000, value: nil},
wantBz: nil,
wantErr: true,
wantErrMsg: "calling contract 0x0000000000000000000000000000000000000000 with code hash 0x0000000000000000000000000000000000000000000000000000000000000000 is not whitelisted for delegate calls",
},
{
name: "failed transfer: empty sourcePort",
fields: fields{transferKeeper: &MockTransferKeeper{}},
args: args{
caller: senderEvmAddress,
callingContract: senderEvmAddress,
input: &input{
receiverEvmAddr: receiverEvmAddress,
sourcePort: "", // empty sourcePort
sourceChannel: "sourceChannel",
denom: "denom",
amount: big.NewInt(100),
revisionNumber: 1,
revisionHeight: 1,
timeoutTimestamp: 1,
},
suppliedGas: uint64(1000000),
value: nil,
},
wantBz: nil,
wantErr: true,
wantErrMsg: "port cannot be empty",
},
{
name: "failed transfer: empty sourceChannel",
fields: fields{transferKeeper: &MockTransferKeeper{}},
args: args{
caller: senderEvmAddress,
callingContract: senderEvmAddress,
input: &input{
receiverEvmAddr: receiverEvmAddress,
sourcePort: "port",
sourceChannel: "",
denom: "denom",
amount: big.NewInt(100),
revisionNumber: 1,
revisionHeight: 1,
timeoutTimestamp: 1,
},
suppliedGas: uint64(1000000),
value: nil,
},
wantBz: nil,
wantErr: true,
wantErrMsg: "channelID cannot be empty",
},
{
name: "failed transfer: invalid denom",
fields: fields{transferKeeper: &MockTransferKeeper{}},
args: args{
caller: senderEvmAddress,
callingContract: senderEvmAddress,
input: &input{
receiverEvmAddr: receiverEvmAddress,
sourcePort: "port",
sourceChannel: "sourceChannel",
denom: "",
amount: big.NewInt(100),
revisionNumber: 1,
revisionHeight: 1,
timeoutTimestamp: 1,
},
suppliedGas: uint64(1000000),
value: nil,
},
wantBz: nil,
wantErr: true,
wantErrMsg: "invalid denom",
},
}
for _, tt := range tests {
Expand All @@ -120,16 +199,20 @@ func TestPrecompile_Run(t *testing.T) {
tt.args.input.sourcePort, tt.args.input.sourceChannel, tt.args.input.denom, tt.args.input.amount,
tt.args.input.revisionNumber, tt.args.input.revisionHeight, tt.args.input.timeoutTimestamp)
require.Nil(t, err)
gotBz, g, err := p.RunAndCalculateGas(&evm, tt.args.caller, tt.args.callingContract, append(p.TransferID, inputs...), tt.args.suppliedGas, tt.args.value)
gotBz, gotRemainingGas, err := p.RunAndCalculateGas(&evm, tt.args.caller, tt.args.callingContract, append(p.TransferID, inputs...), tt.args.suppliedGas, tt.args.value)
if (err != nil) != tt.wantErr {
t.Errorf("Run() error = %v, wantErr %v", err, tt.wantErr)
return
}
if err != nil {
require.Equal(t, tt.wantErrMsg, err.Error())
}

if !reflect.DeepEqual(gotBz, tt.wantBz) {
t.Errorf("Run() gotBz = %v, want %v", gotBz, tt.wantBz)
}
if !reflect.DeepEqual(g, tt.wantRemainingGas) {
t.Errorf("Run() gotRemainingGas = %v, want %v", g, tt.wantRemainingGas)
if !reflect.DeepEqual(gotRemainingGas, tt.wantRemainingGas) {
t.Errorf("Run() gotRemainingGas = %v, want %v", gotRemainingGas, tt.wantRemainingGas)
}
})
}
Expand Down
Loading