From aa1e6347eb2ccf8c8cb1267cee987acbead1bd95 Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 6 Nov 2025 16:09:54 +0800 Subject: [PATCH 01/11] feat: remove werc20 precompile Closes: #807 changelog fix tests temp --- CHANGELOG.md | 4 + api/cosmos/evm/erc20/v1/genesis.pulsar.go | 189 +----- evmd/genesis.go | 1 - .../ics20_recursive_precompile_calls_test.go | 3 - .../werc20/precompile_werc20_test.go | 19 - precompiles/werc20/IWERC20.sol | 36 -- precompiles/werc20/README.md | 175 ------ precompiles/werc20/abi.json | 290 --------- precompiles/werc20/events.go | 79 --- precompiles/werc20/interfaces.go | 15 - precompiles/werc20/testdata/WEVMOS9.json | 288 --------- .../werc20/testdata/WEVMOS9TestCaller.json | 79 --- .../werc20/testdata/WEVMOS9TestCaller.sol | 34 -- precompiles/werc20/testdata/wevmos9.go | 12 - .../werc20/testdata/wevmos9_test_caller.go | 10 - precompiles/werc20/tx.go | 80 --- precompiles/werc20/werc20.go | 136 ----- proto/cosmos/evm/erc20/v1/genesis.proto | 4 +- .../precompiles/bank/test_integration.go | 33 +- .../precompiles/bank/test_query.go | 44 +- .../precompiles/bank/test_setup.go | 11 +- .../precompiles/erc20/test_approve.go | 68 --- .../precompiles/erc20/test_integration.go | 253 +------- .../precompiles/erc20/test_setup.go | 9 - .../precompiles/werc20/test_events.go | 211 ------- .../precompiles/werc20/test_integration.go | 573 ------------------ .../precompiles/werc20/test_utils.go | 227 ------- tests/integration/x/erc20/test_precompiles.go | 279 +-------- tests/integration/x/vm/test_call_evm.go | 150 ----- .../x/vm/test_iterate_contracts.go | 7 - .../precompiles/test/9_werc20/werc20.js | 226 ------- .../suites/precompiles/test/common.js | 2 - .../suites/revert_cases/test/common.js | 4 +- testutil/config/genesis.go | 4 - testutil/constants/constants.go | 24 +- .../evm/network/chain_id_modifiers.go | 33 - .../evm/network/example_contracts.go | 27 - testutil/integration/evm/network/setup.go | 8 +- testutil/integration/evm/utils/genesis.go | 2 - x/erc20/genesis.go | 6 - x/erc20/keeper/precompiles.go | 74 +-- x/erc20/types/genesis.go | 4 - x/erc20/types/genesis.pb.go | 109 +--- x/erc20/types/keys.go | 3 +- 44 files changed, 88 insertions(+), 3757 deletions(-) delete mode 100644 evmd/tests/integration/precompiles/werc20/precompile_werc20_test.go delete mode 100644 precompiles/werc20/IWERC20.sol delete mode 100644 precompiles/werc20/README.md delete mode 100644 precompiles/werc20/abi.json delete mode 100644 precompiles/werc20/events.go delete mode 100644 precompiles/werc20/interfaces.go delete mode 100644 precompiles/werc20/testdata/WEVMOS9.json delete mode 100644 precompiles/werc20/testdata/WEVMOS9TestCaller.json delete mode 100644 precompiles/werc20/testdata/WEVMOS9TestCaller.sol delete mode 100644 precompiles/werc20/testdata/wevmos9.go delete mode 100644 precompiles/werc20/testdata/wevmos9_test_caller.go delete mode 100644 precompiles/werc20/tx.go delete mode 100644 precompiles/werc20/werc20.go delete mode 100644 tests/integration/precompiles/werc20/test_events.go delete mode 100644 tests/integration/precompiles/werc20/test_integration.go delete mode 100644 tests/integration/precompiles/werc20/test_utils.go delete mode 100644 tests/integration/x/vm/test_call_evm.go delete mode 100644 tests/solidity/suites/precompiles/test/9_werc20/werc20.js delete mode 100644 testutil/integration/evm/network/example_contracts.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f4cac18..8ae830e49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ### DEPENDENCIES +### API-BREAKING + +- [\#808](https://github.com/cosmos/evm/pull/808) Remove werc20 precompile. + ### IMPROVEMENTS - [\#758](https://github.com/cosmos/evm/pull/758) Cleanup precompiles abi.json. diff --git a/api/cosmos/evm/erc20/v1/genesis.pulsar.go b/api/cosmos/evm/erc20/v1/genesis.pulsar.go index f10f894c9..e42b7d648 100644 --- a/api/cosmos/evm/erc20/v1/genesis.pulsar.go +++ b/api/cosmos/evm/erc20/v1/genesis.pulsar.go @@ -116,52 +116,6 @@ func (x *_GenesisState_3_list) IsValid() bool { return x.list != nil } -var _ protoreflect.List = (*_GenesisState_4_list)(nil) - -type _GenesisState_4_list struct { - list *[]string -} - -func (x *_GenesisState_4_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_GenesisState_4_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_GenesisState_4_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_GenesisState_4_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_GenesisState_4_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message GenesisState at list field NativePrecompiles as it is not of Message kind")) -} - -func (x *_GenesisState_4_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_GenesisState_4_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_GenesisState_4_list) IsValid() bool { - return x.list != nil -} - var _ protoreflect.List = (*_GenesisState_5_list)(nil) type _GenesisState_5_list struct { @@ -213,7 +167,6 @@ var ( fd_GenesisState_params protoreflect.FieldDescriptor fd_GenesisState_token_pairs protoreflect.FieldDescriptor fd_GenesisState_allowances protoreflect.FieldDescriptor - fd_GenesisState_native_precompiles protoreflect.FieldDescriptor fd_GenesisState_dynamic_precompiles protoreflect.FieldDescriptor ) @@ -223,7 +176,6 @@ func init() { fd_GenesisState_params = md_GenesisState.Fields().ByName("params") fd_GenesisState_token_pairs = md_GenesisState.Fields().ByName("token_pairs") fd_GenesisState_allowances = md_GenesisState.Fields().ByName("allowances") - fd_GenesisState_native_precompiles = md_GenesisState.Fields().ByName("native_precompiles") fd_GenesisState_dynamic_precompiles = md_GenesisState.Fields().ByName("dynamic_precompiles") } @@ -310,12 +262,6 @@ func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, return } } - if len(x.NativePrecompiles) != 0 { - value := protoreflect.ValueOfList(&_GenesisState_4_list{list: &x.NativePrecompiles}) - if !f(fd_GenesisState_native_precompiles, value) { - return - } - } if len(x.DynamicPrecompiles) != 0 { value := protoreflect.ValueOfList(&_GenesisState_5_list{list: &x.DynamicPrecompiles}) if !f(fd_GenesisState_dynamic_precompiles, value) { @@ -343,8 +289,6 @@ func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool return len(x.TokenPairs) != 0 case "cosmos.evm.erc20.v1.GenesisState.allowances": return len(x.Allowances) != 0 - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - return len(x.NativePrecompiles) != 0 case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": return len(x.DynamicPrecompiles) != 0 default: @@ -369,8 +313,6 @@ func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { x.TokenPairs = nil case "cosmos.evm.erc20.v1.GenesisState.allowances": x.Allowances = nil - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - x.NativePrecompiles = nil case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": x.DynamicPrecompiles = nil default: @@ -404,12 +346,6 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto } listValue := &_GenesisState_3_list{list: &x.Allowances} return protoreflect.ValueOfList(listValue) - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - if len(x.NativePrecompiles) == 0 { - return protoreflect.ValueOfList(&_GenesisState_4_list{}) - } - listValue := &_GenesisState_4_list{list: &x.NativePrecompiles} - return protoreflect.ValueOfList(listValue) case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": if len(x.DynamicPrecompiles) == 0 { return protoreflect.ValueOfList(&_GenesisState_5_list{}) @@ -446,10 +382,6 @@ func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value lv := value.List() clv := lv.(*_GenesisState_3_list) x.Allowances = *clv.list - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - lv := value.List() - clv := lv.(*_GenesisState_4_list) - x.NativePrecompiles = *clv.list case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": lv := value.List() clv := lv.(*_GenesisState_5_list) @@ -491,12 +423,6 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p } value := &_GenesisState_3_list{list: &x.Allowances} return protoreflect.ValueOfList(value) - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - if x.NativePrecompiles == nil { - x.NativePrecompiles = []string{} - } - value := &_GenesisState_4_list{list: &x.NativePrecompiles} - return protoreflect.ValueOfList(value) case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": if x.DynamicPrecompiles == nil { x.DynamicPrecompiles = []string{} @@ -525,9 +451,6 @@ func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) case "cosmos.evm.erc20.v1.GenesisState.allowances": list := []*Allowance{} return protoreflect.ValueOfList(&_GenesisState_3_list{list: &list}) - case "cosmos.evm.erc20.v1.GenesisState.native_precompiles": - list := []string{} - return protoreflect.ValueOfList(&_GenesisState_4_list{list: &list}) case "cosmos.evm.erc20.v1.GenesisState.dynamic_precompiles": list := []string{} return protoreflect.ValueOfList(&_GenesisState_5_list{list: &list}) @@ -616,12 +539,6 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { n += 1 + l + runtime.Sov(uint64(l)) } } - if len(x.NativePrecompiles) > 0 { - for _, s := range x.NativePrecompiles { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } if len(x.DynamicPrecompiles) > 0 { for _, s := range x.DynamicPrecompiles { l = len(s) @@ -666,15 +583,6 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { dAtA[i] = 0x2a } } - if len(x.NativePrecompiles) > 0 { - for iNdEx := len(x.NativePrecompiles) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.NativePrecompiles[iNdEx]) - copy(dAtA[i:], x.NativePrecompiles[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.NativePrecompiles[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } if len(x.Allowances) > 0 { for iNdEx := len(x.Allowances) - 1; iNdEx >= 0; iNdEx-- { encoded, err := options.Marshal(x.Allowances[iNdEx]) @@ -874,38 +782,6 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field NativePrecompiles", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.NativePrecompiles = append(x.NativePrecompiles, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex case 5: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DynamicPrecompiles", wireType) @@ -1462,8 +1338,6 @@ type GenesisState struct { TokenPairs []*TokenPair `protobuf:"bytes,2,rep,name=token_pairs,json=tokenPairs,proto3" json:"token_pairs,omitempty"` // allowances is a slice of the registered allowances at genesis Allowances []*Allowance `protobuf:"bytes,3,rep,name=allowances,proto3" json:"allowances,omitempty"` - // native_precompiles is a slice of registered native precompiles at genesis - NativePrecompiles []string `protobuf:"bytes,4,rep,name=native_precompiles,json=nativePrecompiles,proto3" json:"native_precompiles,omitempty"` // dynamic_precompiles is a slice of registered dynamic precompiles at genesis DynamicPrecompiles []string `protobuf:"bytes,5,rep,name=dynamic_precompiles,json=dynamicPrecompiles,proto3" json:"dynamic_precompiles,omitempty"` } @@ -1509,13 +1383,6 @@ func (x *GenesisState) GetAllowances() []*Allowance { return nil } -func (x *GenesisState) GetNativePrecompiles() []string { - if x != nil { - return x.NativePrecompiles - } - return nil -} - func (x *GenesisState) GetDynamicPrecompiles() []string { if x != nil { return x.DynamicPrecompiles @@ -1582,7 +1449,7 @@ var file_cosmos_evm_erc20_v1_genesis_proto_rawDesc = []byte{ 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xdb, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, + 0x74, 0x6f, 0x22, 0xa7, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, @@ -1596,35 +1463,31 @@ var file_cosmos_evm_erc20_v1_genesis_proto_rawDesc = []byte{ 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x12, 0x6e, 0x61, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, - 0x01, 0x52, 0x11, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x13, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, - 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x12, 0x64, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x73, - 0x22, 0x72, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x72, 0x63, 0x32, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x72, 0x63, 0x32, 0x30, 0x12, 0x3f, 0x0a, - 0x1b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x5f, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, - 0x08, 0x02, 0x10, 0x03, 0x42, 0xc4, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x76, 0x31, - 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x65, 0x72, - 0x63, 0x32, 0x30, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x72, 0x63, 0x32, 0x30, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x43, 0x45, 0x45, 0xaa, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, - 0x6d, 0x2e, 0x45, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x45, 0x72, 0x63, 0x32, 0x30, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x1f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x45, 0x72, - 0x63, 0x32, 0x30, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, - 0x3a, 0x3a, 0x45, 0x72, 0x63, 0x32, 0x30, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x13, 0x64, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, + 0x2a, 0x01, 0x52, 0x12, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x72, 0x65, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x72, 0x0a, 0x06, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x65, 0x72, 0x63, 0x32, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x45, 0x72, 0x63, 0x32, 0x30, 0x12, 0x3f, 0x0a, 0x1b, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x42, 0xc4, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x65, 0x76, 0x6d, 0x2e, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x65, 0x72, 0x63, 0x32, 0x30, 0x2f, + 0x76, 0x31, 0x3b, 0x65, 0x72, 0x63, 0x32, 0x30, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, 0x45, + 0xaa, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x45, 0x72, + 0x63, 0x32, 0x30, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, + 0x45, 0x76, 0x6d, 0x5c, 0x45, 0x72, 0x63, 0x32, 0x30, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1f, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x45, 0x72, 0x63, 0x32, 0x30, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x45, 0x72, + 0x63, 0x32, 0x30, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/evmd/genesis.go b/evmd/genesis.go index 27cc9837b..6fed003bf 100644 --- a/evmd/genesis.go +++ b/evmd/genesis.go @@ -39,7 +39,6 @@ func NewEVMGenesisState() *evmtypes.GenesisState { func NewErc20GenesisState() *erc20types.GenesisState { erc20GenState := erc20types.DefaultGenesisState() erc20GenState.TokenPairs = testconstants.ExampleTokenPairs - erc20GenState.NativePrecompiles = []string{testconstants.WEVMOSContractMainnet} return erc20GenState } diff --git a/evmd/tests/ibc/ics20_recursive_precompile_calls_test.go b/evmd/tests/ibc/ics20_recursive_precompile_calls_test.go index a99414d58..ecc189561 100644 --- a/evmd/tests/ibc/ics20_recursive_precompile_calls_test.go +++ b/evmd/tests/ibc/ics20_recursive_precompile_calls_test.go @@ -227,9 +227,6 @@ func (suite *ICS20RecursivePrecompileCallsTestSuite) SetupTest() { evmAppA.Erc20Keeper.GetTokenPair(suite.chainA.GetContext(), evmAppA.Erc20Keeper.GetTokenPairID(suite.chainA.GetContext(), bondDenom)) // evmAppA.Erc20Keeper.SetNativePrecompile(suite.chainA.GetContext(), werc20.Address()) - avail := evmAppA.Erc20Keeper.IsNativePrecompileAvailable(suite.chainA.GetContext(), common.HexToAddress("0xD4949664cD82660AaE99bEdc034a0deA8A0bd517")) - suite.Require().True(avail) - evmAppB := suite.chainB.App.(*evmd.EVMD) suite.chainBPrecompile = ics20.NewPrecompile( evmAppB.BankKeeper, diff --git a/evmd/tests/integration/precompiles/werc20/precompile_werc20_test.go b/evmd/tests/integration/precompiles/werc20/precompile_werc20_test.go deleted file mode 100644 index 011e605fb..000000000 --- a/evmd/tests/integration/precompiles/werc20/precompile_werc20_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package werc20 - -import ( - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/evm/evmd/tests/integration" - "github.com/cosmos/evm/tests/integration/precompiles/werc20" -) - -func TestWERC20PrecompileUnitTestSuite(t *testing.T) { - s := werc20.NewPrecompileUnitTestSuite(integration.CreateEvmd) - suite.Run(t, s) -} - -func TestWERC20PrecompileIntegrationTestSuite(t *testing.T) { - werc20.TestPrecompileIntegrationTestSuite(t, integration.CreateEvmd) -} diff --git a/precompiles/werc20/IWERC20.sol b/precompiles/werc20/IWERC20.sol deleted file mode 100644 index b369abe00..000000000 --- a/precompiles/werc20/IWERC20.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity >=0.8.18; - -import "./../erc20/IERC20Metadata.sol"; - -/** - * @author Evmos Team - * @title Wrapped ERC20 Interface - * @dev Interface for representing the native EVM token as a wrapped ERC20 standard. - */ -interface IWERC20 is IERC20Metadata { - /// @dev Emitted when the native tokens are deposited in exchange for the wrapped ERC20. - /// @param dst The account for which the deposit is made. - /// @param wad The amount of native tokens deposited. - event Deposit(address indexed dst, uint256 wad); - - /// @dev Emitted when the native token is withdrawn. - /// @param src The account for which the withdrawal is made. - /// @param wad The amount of native tokens withdrawn. - event Withdrawal(address indexed src, uint256 wad); - - /// @dev Default fallback payable function. Must call the deposit method in implementing contracts. - fallback() external payable; - - /// @dev Default receive payable function. Must call the deposit method in implementing contracts. - receive() external payable; - - /// @dev Deposits native tokens in exchange for wrapped ERC20 token. - /// @dev Emits a Deposit Event. - function deposit() external payable; - - /// @dev Withdraws native tokens from wrapped ERC20 token. - /// @dev Emits a Withdrawal Event. - /// @param wad The amount of native tokens to be withdrawn. - function withdraw(uint256 wad) external; -} diff --git a/precompiles/werc20/README.md b/precompiles/werc20/README.md deleted file mode 100644 index 224320020..000000000 --- a/precompiles/werc20/README.md +++ /dev/null @@ -1,175 +0,0 @@ -# WERC20 Precompile - -The WERC20 (Wrapped ERC20) precompile provides a wrapped ERC20 interface for the native EVM token, -similar to WETH on Ethereum. This allows the native token to be used in smart contracts that expect -ERC20 tokens, maintaining compatibility with DeFi protocols and other ERC20-based applications. - -## Interface - -The WERC20 precompile extends the standard ERC20 interface with additional deposit and withdraw functionality: - -### Inherited ERC20 Methods - -All standard ERC20 and ERC20Metadata methods are available: - -```solidity -// ERC20 Standard Methods -function totalSupply() external view returns (uint256); -function balanceOf(address account) external view returns (uint256); -function transfer(address to, uint256 amount) external returns (bool); -function allowance(address owner, address spender) external view returns (uint256); -function approve(address spender, uint256 amount) external returns (bool); -function transferFrom(address from, address to, uint256 amount) external returns (bool); - -// ERC20 Metadata -function name() external view returns (string memory); -function symbol() external view returns (string memory); -function decimals() external view returns (uint8); -``` - -### WERC20 Specific Methods - -```solidity -// Deposit native tokens to receive wrapped tokens -function deposit() external payable; - -// Withdraw wrapped tokens to receive native tokens (no-op for compatibility) -function withdraw(uint256 wad) external; - -// Fallback function - calls deposit() -fallback() external payable; - -// Receive function - calls deposit() -receive() external payable; -``` - -## Gas Costs - -| Method | Gas Cost | -|--------|----------| -| `deposit` | 23,878 | -| `withdraw` | 9,207 | -| ERC20 methods | Same as ERC20 precompile | - -## Implementation Details - -### Deposit Mechanism - -The deposit function has a unique implementation: - -1. Accepts native tokens via `msg.value` -2. Sends the native tokens back to the caller using the bank module -3. Adjusts EVM state balances to reflect the "wrapping" -4. Emits a `Deposit` event - -This approach ensures that the native tokens remain in the user's account while providing the wrapped token interface. - -### Withdraw Mechanism - -The withdraw function is implemented as a no-op that: - -1. Validates the user has sufficient balance -2. Emits a `Withdrawal` event -3. Does not actually perform any token transfers - -This maintains interface compatibility with WETH-style contracts while preserving the native token functionality. - -### Balance Representation - -- Native token balances are automatically reflected as wrapped token balances -- No actual wrapping occurs - the precompile provides a view over native balances -- All ERC20 operations work on the underlying native token - -### Extended Precision - -The precompile handles the extended precision of the native token -(18 decimals in EVM vs 6 decimals in Cosmos SDK) through internal conversion. - -## Events - -```solidity -// Emitted when native tokens are "deposited" -event Deposit(address indexed dst, uint256 wad); - -// Emitted when tokens are "withdrawn" -event Withdrawal(address indexed src, uint256 wad); - -// Standard ERC20 events -event Transfer(address indexed from, address indexed to, uint256 value); -event Approval(address indexed owner, address indexed spender, uint256 value); -``` - -## Security Considerations - -1. **No Lock-up**: Native tokens are never locked in the precompile -2. **Direct Integration**: Operations directly interact with the bank module -3. **Balance Consistency**: EVM and Cosmos SDK balances remain synchronized -4. **Fallback Protection**: Sending native tokens to the contract automatically triggers deposit - -## Usage Examples - -### Basic Deposit and Transfer - -```solidity -// Assume WERC20 is deployed at a specific address -IWERC20 wrappedToken = IWERC20(0x...); // WERC20 precompile address - -// Deposit native tokens (sent value is returned to sender as wrapped tokens) -wrappedToken.deposit{value: 1 ether}(); - -// Now you can use it as an ERC20 token -wrappedToken.transfer(recipient, 0.5 ether); - -// Check balance -uint256 balance = wrappedToken.balanceOf(msg.sender); -``` - -### Integration with DeFi Protocols - -```solidity -contract DeFiProtocol { - IWERC20 public wrappedNative; - - constructor(address _wrappedNative) { - wrappedNative = IWERC20(_wrappedNative); - } - - function depositCollateral() external payable { - // Automatically wraps native tokens - wrappedNative.deposit{value: msg.value}(); - - // Now treat it as ERC20 collateral - // The protocol can use standard ERC20 operations - } - - function swapTokens(IERC20 tokenIn, uint256 amountIn) external { - // Works seamlessly with wrapped native tokens - tokenIn.transferFrom(msg.sender, address(this), amountIn); - - // Perform swap logic... - } -} -``` - -### Fallback Handling - -```solidity -// Sending native tokens directly to the WERC20 address triggers deposit -address payable wrappedAddress = payable(0x...); // WERC20 address -wrappedAddress.transfer(1 ether); // Automatically deposits -``` - -## Differences from Traditional WETH - -1. **No Actual Wrapping**: Tokens remain as native tokens, only the interface changes -2. **No Lock-up**: Native tokens are not locked in the contract -3. **Automatic Reflection**: Native balance changes are immediately reflected -4. **Withdraw No-op**: Withdraw function exists for compatibility but doesn't transfer - -## Integration Notes - -- The WERC20 precompile address is determined by the token pair configuration -- Compatible with any protocol expecting ERC20 tokens -- Maintains full native token functionality -- Gas costs are comparable to standard ERC20 operations -- Ideal for DeFi protocols, DEXs, and other ERC20-based applications diff --git a/precompiles/werc20/abi.json b/precompiles/werc20/abi.json deleted file mode 100644 index 3f97434e8..000000000 --- a/precompiles/werc20/abi.json +++ /dev/null @@ -1,290 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "src", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "deposit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } -] diff --git a/precompiles/werc20/events.go b/precompiles/werc20/events.go deleted file mode 100644 index e60ae97d6..000000000 --- a/precompiles/werc20/events.go +++ /dev/null @@ -1,79 +0,0 @@ -package werc20 - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - - cmn "github.com/cosmos/evm/precompiles/common" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -const ( - // EventTypeDeposit is the key of the event type for the Deposit transaction. - EventTypeDeposit = "Deposit" - // EventTypeWithdrawal is the key of the event type for the Withdraw transaction. - EventTypeWithdrawal = "Withdrawal" -) - -// EmitDepositEvent creates a new Deposit event emitted after a Deposit transaction. -func (p Precompile) EmitDepositEvent( - ctx sdk.Context, - stateDB vm.StateDB, - caller common.Address, - amount *big.Int, -) error { - event := p.Events[EventTypeDeposit] - return p.createWERC20Event(ctx, stateDB, event, caller, amount) -} - -// EmitWithdrawalEvent creates a new Withdrawal event emitted after a Withdraw transaction. -func (p Precompile) EmitWithdrawalEvent( - ctx sdk.Context, - stateDB vm.StateDB, - src common.Address, - amount *big.Int, -) error { - event := p.Events[EventTypeWithdrawal] - return p.createWERC20Event(ctx, stateDB, event, src, amount) -} - -// createWERC20Event adds to the StateDB a log representing an event for the -// WERC20 precompile. -func (p Precompile) createWERC20Event( - ctx sdk.Context, - stateDB vm.StateDB, - event abi.Event, - address common.Address, - amount *big.Int, -) error { - // Prepare the event topics - topics := make([]common.Hash, 2) - - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(address) - if err != nil { - return err - } - - arguments := abi.Arguments{event.Inputs[1]} - packed, err := arguments.Pack(amount) - if err != nil { - return err - } - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: packed, - BlockNumber: uint64(ctx.BlockHeight()), //nolint:gosec // G115 - }) - - return nil -} diff --git a/precompiles/werc20/interfaces.go b/precompiles/werc20/interfaces.go deleted file mode 100644 index 9ebf87202..000000000 --- a/precompiles/werc20/interfaces.go +++ /dev/null @@ -1,15 +0,0 @@ -package werc20 - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type Erc20Keeper interface { - GetAllowance(ctx sdk.Context, erc20 common.Address, owner common.Address, spender common.Address) (*big.Int, error) - SetAllowance(ctx sdk.Context, erc20 common.Address, owner common.Address, spender common.Address, value *big.Int) error - DeleteAllowance(ctx sdk.Context, erc20 common.Address, owner common.Address, spender common.Address) error -} diff --git a/precompiles/werc20/testdata/WEVMOS9.json b/precompiles/werc20/testdata/WEVMOS9.json deleted file mode 100644 index 484cf6b5b..000000000 --- a/precompiles/werc20/testdata/WEVMOS9.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "WEVMOS9", - "sourceName": "solidity/precompiles/werc20/testdata/WEVMOS9.sol", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "guy", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "guy", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - } - ], - "bytecode": "0x60806040526040805190810160405280600d81526020017f577261707065642045766d6f73000000000000000000000000000000000000008152506000908051906020019061004f9291906100ca565b506040805190810160405280600681526020017f5745564d4f5300000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100ca565b506012600260006101000a81548160ff021916908360ff1602179055503480156100c457600080fd5b5061016f565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010b57805160ff1916838001178555610139565b82800160010185558215610139579182015b8281111561013857825182559160200191906001019061011d565b5b509050610146919061014a565b5090565b61016c91905b80821115610168576000816000905550600101610150565b5090565b90565b610c848061017e6000396000f3006080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014957806318160ddd146101ae57806323b872dd146101d95780632e1a7d4d1461025e578063313ce5671461028b57806370a08231146102bc57806395d89b4114610313578063a9059cbb146103a3578063d0e30db014610408578063dd62ed3e14610412575b6100b7610489565b005b3480156100c557600080fd5b506100ce610526565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010e5780820151818401526020810190506100f3565b50505050905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015557600080fd5b50610194600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105c4565b604051808215151515815260200191505060405180910390f35b3480156101ba57600080fd5b506101c36106b6565b6040518082815260200191505060405180910390f35b3480156101e557600080fd5b50610244600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106d5565b604051808215151515815260200191505060405180910390f35b34801561026a57600080fd5b5061028960048036038101908080359060200190929190505050610a22565b005b34801561029757600080fd5b506102a0610b55565b604051808260ff1660ff16815260200191505060405180910390f35b3480156102c857600080fd5b506102fd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b68565b6040518082815260200191505060405180910390f35b34801561031f57600080fd5b50610328610b80565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036857808201518184015260208101905061034d565b50505050905090810190601f1680156103955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103af57600080fd5b506103ee600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1e565b604051808215151515815260200191505060405180910390f35b610410610489565b005b34801561041e57600080fd5b50610473600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c33565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105bc5780601f10610591576101008083540402835291602001916105bc565b820191906000526020600020905b81548152906001019060200180831161059f57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561072557600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107fd57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156109185781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561088d57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7057600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610b03573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c165780601f10610beb57610100808354040283529160200191610c16565b820191906000526020600020905b815481529060010190602001808311610bf957829003601f168201915b505050505081565b6000610c2b3384846106d5565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820db857be5acdb9fff88465fff82532b1f9016393994729caa282163d5e3bd9da10029", - "deployedBytecode": "0x6080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014957806318160ddd146101ae57806323b872dd146101d95780632e1a7d4d1461025e578063313ce5671461028b57806370a08231146102bc57806395d89b4114610313578063a9059cbb146103a3578063d0e30db014610408578063dd62ed3e14610412575b6100b7610489565b005b3480156100c557600080fd5b506100ce610526565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010e5780820151818401526020810190506100f3565b50505050905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015557600080fd5b50610194600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105c4565b604051808215151515815260200191505060405180910390f35b3480156101ba57600080fd5b506101c36106b6565b6040518082815260200191505060405180910390f35b3480156101e557600080fd5b50610244600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106d5565b604051808215151515815260200191505060405180910390f35b34801561026a57600080fd5b5061028960048036038101908080359060200190929190505050610a22565b005b34801561029757600080fd5b506102a0610b55565b604051808260ff1660ff16815260200191505060405180910390f35b3480156102c857600080fd5b506102fd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b68565b6040518082815260200191505060405180910390f35b34801561031f57600080fd5b50610328610b80565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036857808201518184015260208101905061034d565b50505050905090810190601f1680156103955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103af57600080fd5b506103ee600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1e565b604051808215151515815260200191505060405180910390f35b610410610489565b005b34801561041e57600080fd5b50610473600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c33565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105bc5780601f10610591576101008083540402835291602001916105bc565b820191906000526020600020905b81548152906001019060200180831161059f57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561072557600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107fd57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156109185781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561088d57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7057600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610b03573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c165780601f10610beb57610100808354040283529160200191610c16565b820191906000526020600020905b815481529060010190602001808311610bf957829003601f168201915b505050505081565b6000610c2b3384846106d5565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820db857be5acdb9fff88465fff82532b1f9016393994729caa282163d5e3bd9da10029", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/precompiles/werc20/testdata/WEVMOS9TestCaller.json b/precompiles/werc20/testdata/WEVMOS9TestCaller.json deleted file mode 100644 index dfcd6ca3d..000000000 --- a/precompiles/werc20/testdata/WEVMOS9TestCaller.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "WEVMOS9TestCaller", - "sourceName": "solidity/precompiles/werc20/testdata/WEVMOS9TestCaller.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address payable", - "name": "_wrappedTokenAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "message", - "type": "string" - } - ], - "name": "Log", - "type": "event" - }, - { - "inputs": [], - "name": "WEVMOS", - "outputs": [ - { - "internalType": "address payable", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "counter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "before", - "type": "bool" - }, - { - "internalType": "bool", - "name": "aft", - "type": "bool" - } - ], - "name": "depositWithRevert", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ], - "bytecode": "0x60a03461007357601f6102b138819003918201601f19168301916001600160401b038311848410176100785780849260209460405283398101031261007357516001600160a01b03811681036100735760805260008055604051610222908161008f82396080518181816058015260e40152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604081815260048036101561001557600080fd5b600092833560e01c9182635dab6f8c146100a7575050806361bc221a1461008b57637cf5b4fc1461004557600080fd5b34610087578160031936011261008757517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b5034610087578160031936011261008757602091549051908152f35b90928092506003193601126101b557803580151581036101b1576024359384151585036101ad578554600019949085811461019a576001018755867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b156100875785848092630d0e30db60e41b825234905af1801561019057610162575b505061014a57835490811561014f575001825561014a5780f35b6101b9565b634e487b7160e01b855260119052602484fd5b67ffffffffffffffff829793971161017d5752933880610130565b634e487b7160e01b835260418452602483fd5b81513d89823e3d90fd5b634e487b7160e01b885260118552602488fd5b8580fd5b8480fd5b8380fd5b60405162461bcd60e51b815260206004820152600b60248201526a726576657274206865726560a81b6044820152606490fdfea2646970667358221220b32282c4091e7b1e0ef38cfff23aebf1e60aad8d2696f353a69484cad09862a964736f6c63430008140033", - "deployedBytecode": "0x6080604081815260048036101561001557600080fd5b600092833560e01c9182635dab6f8c146100a7575050806361bc221a1461008b57637cf5b4fc1461004557600080fd5b34610087578160031936011261008757517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b5034610087578160031936011261008757602091549051908152f35b90928092506003193601126101b557803580151581036101b1576024359384151585036101ad578554600019949085811461019a576001018755867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b156100875785848092630d0e30db60e41b825234905af1801561019057610162575b505061014a57835490811561014f575001825561014a5780f35b6101b9565b634e487b7160e01b855260119052602484fd5b67ffffffffffffffff829793971161017d5752933880610130565b634e487b7160e01b835260418452602483fd5b81513d89823e3d90fd5b634e487b7160e01b885260118552602488fd5b8580fd5b8480fd5b8380fd5b60405162461bcd60e51b815260206004820152600b60248201526a726576657274206865726560a81b6044820152606490fdfea2646970667358221220b32282c4091e7b1e0ef38cfff23aebf1e60aad8d2696f353a69484cad09862a964736f6c63430008140033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/precompiles/werc20/testdata/WEVMOS9TestCaller.sol b/precompiles/werc20/testdata/WEVMOS9TestCaller.sol deleted file mode 100644 index 327297c28..000000000 --- a/precompiles/werc20/testdata/WEVMOS9TestCaller.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity >=0.8.17; - -import "../IWERC20.sol"; - -contract WEVMOS9TestCaller { - address payable public immutable WEVMOS; - uint256 public counter; - - constructor(address payable _wrappedTokenAddress) { - WEVMOS = _wrappedTokenAddress; - counter = 0; - } - - event Log(string message); - - function depositWithRevert(bool before, bool aft) public payable { - counter++; - - uint amountIn = msg.value; - IWERC20(WEVMOS).deposit{value: amountIn}(); - - if (before) { - require(false, "revert here"); - } - - counter--; - - if (aft) { - require(false, "revert here"); - } - return; - } -} diff --git a/precompiles/werc20/testdata/wevmos9.go b/precompiles/werc20/testdata/wevmos9.go deleted file mode 100644 index 072df9d7d..000000000 --- a/precompiles/werc20/testdata/wevmos9.go +++ /dev/null @@ -1,12 +0,0 @@ -package testdata - -import ( - contractutils "github.com/cosmos/evm/contracts/utils" - evmtypes "github.com/cosmos/evm/x/vm/types" -) - -// LoadWEVMOS9Contract load the WEVMOS9 contract from the json representation of -// the Solidity contract. -func LoadWEVMOS9Contract() (evmtypes.CompiledContract, error) { - return contractutils.LoadContractFromJSONFile("WEVMOS9.json") -} diff --git a/precompiles/werc20/testdata/wevmos9_test_caller.go b/precompiles/werc20/testdata/wevmos9_test_caller.go deleted file mode 100644 index 16d1f19c3..000000000 --- a/precompiles/werc20/testdata/wevmos9_test_caller.go +++ /dev/null @@ -1,10 +0,0 @@ -package testdata - -import ( - contractutils "github.com/cosmos/evm/contracts/utils" - evmtypes "github.com/cosmos/evm/x/vm/types" -) - -func LoadWEVMOS9TestCaller() (evmtypes.CompiledContract, error) { - return contractutils.LoadContractFromJSONFile("WEVMOS9TestCaller.json") -} diff --git a/precompiles/werc20/tx.go b/precompiles/werc20/tx.go deleted file mode 100644 index 0b69f71da..000000000 --- a/precompiles/werc20/tx.go +++ /dev/null @@ -1,80 +0,0 @@ -package werc20 - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/core/vm" - - "github.com/cosmos/evm/x/precisebank/types" - evmtypes "github.com/cosmos/evm/x/vm/types" - - "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -const ( - // DepositMethod defines the ABI method name for the IWERC20 deposit - // transaction. - DepositMethod = "deposit" - // WithdrawMethod defines the ABI method name for the IWERC20 withdraw - // transaction. - WithdrawMethod = "withdraw" -) - -// Deposit handles the payable deposit function. It retrieves the deposited amount -// and sends it back to the sender using the bank keeper. -func (p Precompile) Deposit( - ctx sdk.Context, - contract *vm.Contract, - stateDB vm.StateDB, -) ([]byte, error) { - caller := contract.Caller() - depositedAmount := contract.Value() - - callerAccAddress := sdk.AccAddress(caller.Bytes()) - precompileAccAddr := sdk.AccAddress(p.Address().Bytes()) - - // Send the coins back to the sender - if err := p.BankKeeper.SendCoins( - ctx, - precompileAccAddr, - callerAccAddress, - sdk.NewCoins(sdk.Coin{ - Denom: evmtypes.GetEVMCoinExtendedDenom(), - Amount: math.NewIntFromBigInt(depositedAmount.ToBig()), - }), - ); err != nil { - return nil, err - } - - if err := p.EmitDepositEvent(ctx, stateDB, caller, depositedAmount.ToBig()); err != nil { - return nil, err - } - - return nil, nil -} - -// Withdraw is a no-op and mock function that provides the same interface as the -// WETH contract to support equality between the native coin and its wrapped -// ERC-20 (e.g. ATOM and WEVMOS). -func (p Precompile) Withdraw(ctx sdk.Context, contract *vm.Contract, stateDB vm.StateDB, args []interface{}) ([]byte, error) { - amount, ok := args[0].(*big.Int) - if !ok { - return nil, fmt.Errorf("invalid argument type: %T", args[0]) - } - amountInt := math.NewIntFromBigInt(amount) - - caller := contract.Caller() - callerAccAddress := sdk.AccAddress(caller.Bytes()) - nativeBalance := p.BankKeeper.SpendableCoin(ctx, callerAccAddress, evmtypes.GetEVMCoinDenom()) - if nativeBalance.Amount.Mul(types.ConversionFactor()).LT(amountInt) { - return nil, fmt.Errorf("account balance %v is lower than withdraw balance %v", nativeBalance.Amount, amountInt) - } - - if err := p.EmitWithdrawalEvent(ctx, stateDB, caller, amount); err != nil { - return nil, err - } - return nil, nil -} diff --git a/precompiles/werc20/werc20.go b/precompiles/werc20/werc20.go deleted file mode 100644 index f7c476f1b..000000000 --- a/precompiles/werc20/werc20.go +++ /dev/null @@ -1,136 +0,0 @@ -package werc20 - -import ( - "bytes" - "slices" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core/vm" - - _ "embed" - - ibcutils "github.com/cosmos/evm/ibc" - cmn "github.com/cosmos/evm/precompiles/common" - erc20 "github.com/cosmos/evm/precompiles/erc20" - erc20types "github.com/cosmos/evm/x/erc20/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -var ( - // Embed abi json file to the executable binary. Needed when importing as dependency. - // - //go:embed abi.json - f []byte - ABI abi.ABI -) - -func init() { - var err error - ABI, err = abi.JSON(bytes.NewReader(f)) - if err != nil { - panic(err) - } -} - -var _ vm.PrecompiledContract = &Precompile{} - -// Precompile defines the precompiled contract for WERC20. -type Precompile struct { - *erc20.Precompile -} - -const ( - // DepositRequiredGas defines the gas required for the Deposit transaction. - DepositRequiredGas uint64 = 23_878 - // WithdrawRequiredGas defines the gas required for the Withdraw transaction. - WithdrawRequiredGas uint64 = 9207 -) - -// NewPrecompile creates a new WERC20 Precompile instance implementing the -// PrecompiledContract interface. This type wraps around the ERC20 Precompile -// instance to provide additional methods. -func NewPrecompile( - tokenPair erc20types.TokenPair, - bankKeeper cmn.BankKeeper, - erc20Keeper Erc20Keeper, - transferKeeper ibcutils.TransferKeeper, -) *Precompile { - erc20Precompile := erc20.NewPrecompile(tokenPair, bankKeeper, erc20Keeper, transferKeeper) - - // use the IWERC20 ABI - erc20Precompile.ABI = ABI - - return &Precompile{ - Precompile: erc20Precompile, - } -} - -// RequiredGas calculates the contract gas use. -func (p Precompile) RequiredGas(input []byte) uint64 { - // TODO: these values were obtained from Remix using the WEVMOS9.sol. - // We should execute the transactions from Cosmos EVM testnet - // to ensure parity in the values. - - // If there is no method ID, then it's the fallback or receive case - if len(input) < 4 { - return DepositRequiredGas - } - - methodID := input[:4] - method, err := p.MethodById(methodID) - if err != nil { - return 0 - } - - switch method.Name { - case DepositMethod: - return DepositRequiredGas - case WithdrawMethod: - return WithdrawRequiredGas - default: - return p.Precompile.RequiredGas(input) - } -} - -func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { - return p.RunNativeAction(evm, contract, func(ctx sdk.Context) ([]byte, error) { - return p.Execute(ctx, evm.StateDB, contract, readonly) - }) -} - -func (p Precompile) Execute(ctx sdk.Context, stateDB vm.StateDB, contract *vm.Contract, readOnly bool) ([]byte, error) { - method, args, err := cmn.SetupABI(p.ABI, contract, readOnly, p.IsTransaction) - if err != nil { - return nil, err - } - - var bz []byte - - switch { - case method.Type == abi.Fallback, - method.Type == abi.Receive, - method.Name == DepositMethod: - bz, err = p.Deposit(ctx, contract, stateDB) - case method.Name == WithdrawMethod: - bz, err = p.Withdraw(ctx, contract, stateDB, args) - default: - // ERC20 transactions and queries - bz, err = p.HandleMethod(ctx, contract, stateDB, method, args) - } - - return bz, err -} - -// IsTransaction returns true if the given method name correspond to a -// transaction. Returns false otherwise. -func (p Precompile) IsTransaction(method *abi.Method) bool { - txMethodName := []string{DepositMethod, WithdrawMethod} - txMethodType := []abi.FunctionType{abi.Fallback, abi.Receive} - - if slices.Contains(txMethodName, method.Name) || slices.Contains(txMethodType, method.Type) { - return true - } - - return p.Precompile.IsTransaction(method) -} diff --git a/proto/cosmos/evm/erc20/v1/genesis.proto b/proto/cosmos/evm/erc20/v1/genesis.proto index cacf59283..c66ead44a 100644 --- a/proto/cosmos/evm/erc20/v1/genesis.proto +++ b/proto/cosmos/evm/erc20/v1/genesis.proto @@ -19,9 +19,7 @@ message GenesisState { // allowances is a slice of the registered allowances at genesis repeated Allowance allowances = 3 [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; - // native_precompiles is a slice of registered native precompiles at genesis - repeated string native_precompiles = 4 - [ (gogoproto.nullable) = true, (amino.dont_omitempty) = true ]; + reserved 4; // native precompiles field is deprecated // dynamic_precompiles is a slice of registered dynamic precompiles at genesis repeated string dynamic_precompiles = 5 [ (gogoproto.nullable) = true, (amino.dont_omitempty) = true ]; diff --git a/tests/integration/precompiles/bank/test_integration.go b/tests/integration/precompiles/bank/test_integration.go index c79f42c10..987d1f2f3 100644 --- a/tests/integration/precompiles/bank/test_integration.go +++ b/tests/integration/precompiles/bank/test_integration.go @@ -35,8 +35,8 @@ import ( type IntegrationTestSuite struct { suite.Suite - bondDenom, tokenDenom string - cosmosEVMAddr, xmplAddr common.Address + bondDenom, tokenDenom string + xmplAddr common.Address create network.CreateEvmApp options []network.ConfigOption @@ -86,17 +86,12 @@ func (is *IntegrationTestSuite) SetupTest() { is.keyring = keyring is.network = integrationNetwork - tokenPairID := is.network.App.GetErc20Keeper().GetTokenPairID(is.network.GetContext(), is.bondDenom) - tokenPair, found := is.network.App.GetErc20Keeper().GetTokenPair(is.network.GetContext(), tokenPairID) - Expect(found).To(BeTrue(), "failed to register token erc20 extension") - is.cosmosEVMAddr = common.HexToAddress(tokenPair.Erc20Address) - // Mint and register a second coin for testing purposes err = is.network.App.GetBankKeeper().MintCoins(is.network.GetContext(), minttypes.ModuleName, sdk.Coins{{Denom: is.tokenDenom, Amount: math.NewInt(1e18)}}) Expect(err).ToNot(HaveOccurred(), "failed to mint coin") - tokenPairID = is.network.App.GetErc20Keeper().GetTokenPairID(is.network.GetContext(), is.tokenDenom) - tokenPair, found = is.network.App.GetErc20Keeper().GetTokenPair(is.network.GetContext(), tokenPairID) + tokenPairID := is.network.App.GetErc20Keeper().GetTokenPairID(is.network.GetContext(), is.tokenDenom) + tokenPair, found := is.network.App.GetErc20Keeper().GetTokenPair(is.network.GetContext(), tokenPairID) Expect(found).To(BeTrue(), "failed to register token erc20 extension") is.xmplAddr = common.HexToAddress(tokenPair.Erc20Address) is.precompile = is.setupBankPrecompile() @@ -258,16 +253,6 @@ func TestIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ... }) Context("supplyOf query", func() { - It("should return the supply of Cosmos EVM", func() { - queryArgs, supplyArgs := getTxAndCallArgs(directCall, contractData, bank2.SupplyOfMethod, is.cosmosEVMAddr) - _, ethRes, err := is.factory.CallContractAndCheckLogs(sender.Priv, queryArgs, supplyArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - out, err := is.precompile.Unpack(bank2.SupplyOfMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack balances") - - Expect(out[0].(*big.Int).String()).To(Equal(cosmosEVMTotalSupply.String())) - }) It("should return the supply of XMPL", func() { queryArgs, supplyArgs := getTxAndCallArgs(directCall, contractData, bank2.SupplyOfMethod, is.xmplAddr) @@ -401,16 +386,6 @@ func TestIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ... }) Context("supplyOf query", func() { - It("should return the supply of Cosmos EVM", func() { - queryArgs, supplyArgs := getTxAndCallArgs(contractCall, contractData, SupplyOfFunction, is.cosmosEVMAddr) - _, ethRes, err := is.factory.CallContractAndCheckLogs(sender.Priv, queryArgs, supplyArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - out, err := is.precompile.Unpack(bank2.SupplyOfMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack balances") - - Expect(out[0].(*big.Int).String()).To(Equal(cosmosEVMTotalSupply.String())) - }) It("should return the supply of XMPL", func() { queryArgs, supplyArgs := getTxAndCallArgs(contractCall, contractData, SupplyOfFunction, is.xmplAddr) diff --git a/tests/integration/precompiles/bank/test_query.go b/tests/integration/precompiles/bank/test_query.go index d7dc3a0e4..5b7623a4c 100644 --- a/tests/integration/precompiles/bank/test_query.go +++ b/tests/integration/precompiles/bank/test_query.go @@ -16,7 +16,7 @@ import ( func (s *PrecompileTestSuite) TestBalances() { var ctx sdk.Context - // setup test in order to have s.precompile, s.cosmosEVMAddr and s.xmplAddr defined + // setup test in order to have s.precompile and s.xmplAddr defined s.SetupTest() method := s.precompile.Methods[bank.BalancesMethod] @@ -25,7 +25,7 @@ func (s *PrecompileTestSuite) TestBalances() { malleate func() []interface{} expPass bool errContains string - expBalances func(cosmosEVMAddr, xmplAddr common.Address) []bank.Balance + expBalances func(xmplAddr common.Address) []bank.Balance }{ { "fail - invalid number of arguments", @@ -58,7 +58,7 @@ func (s *PrecompileTestSuite) TestBalances() { }, true, "", - func(common.Address, common.Address) []bank.Balance { return []bank.Balance{} }, + func(common.Address) []bank.Balance { return []bank.Balance{} }, }, { "pass - Initial balances present", @@ -69,12 +69,8 @@ func (s *PrecompileTestSuite) TestBalances() { }, true, "", - func(cosmosEVMAddr, xmplAddr common.Address) []bank.Balance { + func(xmplAddr common.Address) []bank.Balance { return []bank.Balance{ - { - ContractAddress: cosmosEVMAddr, - Amount: network.PrefundedAccountInitialBalance.BigInt(), - }, { ContractAddress: xmplAddr, Amount: network.PrefundedAccountInitialBalance.BigInt(), @@ -92,11 +88,8 @@ func (s *PrecompileTestSuite) TestBalances() { }, true, "", - func(cosmosEVMAddr, xmplAddr common.Address) []bank.Balance { + func(xmplAddr common.Address) []bank.Balance { return []bank.Balance{{ - ContractAddress: cosmosEVMAddr, - Amount: network.PrefundedAccountInitialBalance.BigInt(), - }, { ContractAddress: xmplAddr, Amount: network.PrefundedAccountInitialBalance.Add(math.NewInt(1e18)).BigInt(), }} @@ -119,7 +112,7 @@ func (s *PrecompileTestSuite) TestBalances() { var balances []bank.Balance err = s.precompile.UnpackIntoInterface(&balances, method.Name, bz) s.Require().NoError(err) - s.Require().Equal(tc.expBalances(s.cosmosEVMAddr, s.xmplAddr), balances) + s.Require().Equal(tc.expBalances(s.xmplAddr), balances) } else { s.Require().Contains(err.Error(), tc.errContains) } @@ -135,24 +128,20 @@ func (s *PrecompileTestSuite) TestTotalSupply() { totSupplRes, err := s.grpcHandler.GetTotalSupply() s.Require().NoError(err) - cosmosEVMTotalSupply := totSupplRes.Supply.AmountOf(s.bondDenom) xmplTotalSupply := totSupplRes.Supply.AmountOf(s.tokenDenom) testcases := []struct { name string malleate func() - expSupply func(cosmosEVMAddr, xmplAddr common.Address) []bank.Balance + expSupply func(xmplAddr common.Address) []bank.Balance }{ { "pass - ATOM and XMPL total supply", func() { ctx = s.mintAndSendXMPLCoin(ctx, s.keyring.GetAccAddr(0), math.NewInt(1e18)) }, - func(cosmosEVMAddr, xmplAddr common.Address) []bank.Balance { + func(xmplAddr common.Address) []bank.Balance { return []bank.Balance{{ - ContractAddress: cosmosEVMAddr, - Amount: cosmosEVMTotalSupply.BigInt(), - }, { ContractAddress: xmplAddr, Amount: xmplTotalSupply.Add(math.NewInt(1e18)).BigInt(), }} @@ -174,19 +163,18 @@ func (s *PrecompileTestSuite) TestTotalSupply() { var balances []bank.Balance err = s.precompile.UnpackIntoInterface(&balances, method.Name, bz) s.Require().NoError(err) - s.Require().Equal(tc.expSupply(s.cosmosEVMAddr, s.xmplAddr), balances) + s.Require().Equal(tc.expSupply(s.xmplAddr), balances) }) } } func (s *PrecompileTestSuite) TestSupplyOf() { - // setup test in order to have s.precompile, s.cosmosEVMAddr and s.xmplAddr defined + // setup test in order to have s.precompile and s.xmplAddr defined s.SetupTest() method := s.precompile.Methods[bank.SupplyOfMethod] totSupplRes, err := s.grpcHandler.GetTotalSupply() s.Require().NoError(err) - cosmosEVMTotalSupply := totSupplRes.Supply.AmountOf(s.bondDenom) xmplTotalSupply := totSupplRes.Supply.AmountOf(s.tokenDenom) testcases := []struct { @@ -240,18 +228,6 @@ func (s *PrecompileTestSuite) TestSupplyOf() { "", xmplTotalSupply.BigInt(), }, - - { - "pass - ATOM total supply", - func() []interface{} { - return []interface{}{ - s.cosmosEVMAddr, - } - }, - false, - "", - cosmosEVMTotalSupply.BigInt(), - }, } for _, tc := range testcases { diff --git a/tests/integration/precompiles/bank/test_setup.go b/tests/integration/precompiles/bank/test_setup.go index cd7127bac..ebfdeccaa 100644 --- a/tests/integration/precompiles/bank/test_setup.go +++ b/tests/integration/precompiles/bank/test_setup.go @@ -68,19 +68,12 @@ func (s *PrecompileTestSuite) SetupTest() sdk.Context { s.keyring = keyring s.network = unitNetwork - tokenPairID := s.network.App.GetErc20Keeper().GetTokenPairID(s.network.GetContext(), s.bondDenom) - tokenPair, found := s.network.App.GetErc20Keeper().GetTokenPair(s.network.GetContext(), tokenPairID) - s.Require().True(found) - s.cosmosEVMAddr = common.HexToAddress(tokenPair.Erc20Address) - - s.cosmosEVMAddr = tokenPair.GetERC20Contract() - // Mint and register a second coin for testing purposes err = s.network.App.GetBankKeeper().MintCoins(s.network.GetContext(), minttypes.ModuleName, sdk.Coins{{Denom: "xmpl", Amount: math.NewInt(1e18)}}) s.Require().NoError(err) - tokenPairID = s.network.App.GetErc20Keeper().GetTokenPairID(s.network.GetContext(), s.tokenDenom) - tokenPair, found = s.network.App.GetErc20Keeper().GetTokenPair(s.network.GetContext(), tokenPairID) + tokenPairID := s.network.App.GetErc20Keeper().GetTokenPairID(s.network.GetContext(), s.tokenDenom) + tokenPair, found := s.network.App.GetErc20Keeper().GetTokenPair(s.network.GetContext(), tokenPairID) s.Require().True(found) s.xmplAddr = common.HexToAddress(tokenPair.Erc20Address) diff --git a/tests/integration/precompiles/erc20/test_approve.go b/tests/integration/precompiles/erc20/test_approve.go index a3cbec035..8b35a6fd3 100644 --- a/tests/integration/precompiles/erc20/test_approve.go +++ b/tests/integration/precompiles/erc20/test_approve.go @@ -73,41 +73,6 @@ func (s *PrecompileTestSuite) TestApprove() { }, errContains: "causes integer overflow", }, - { - name: "pass - approve to zero with existing allowance only for other denominations", - malleate: func() []interface{} { - // NOTE: We are setting up an allowance for a different denomination - // and then trying to approve an amount of zero for the token denomination - s.setAllowance( - s.precompile2.Address(), - s.keyring.GetPrivKey(0), - s.keyring.GetAddr(1), - big.NewInt(1), - ) - - return []interface{}{ - s.keyring.GetAddr(1), common.Big0, - } - }, - expPass: true, - postCheck: func() { - // Check that the allowance is zero - s.requireAllowance( - s.precompile.Address(), - s.keyring.GetAddr(0), - s.keyring.GetAddr(1), - big.NewInt(0), - ) - - // Check that the allowance for the other denomination was not deleted - s.requireAllowance( - s.precompile2.Address(), - s.keyring.GetAddr(0), - s.keyring.GetAddr(1), - big.NewInt(1), - ) - }, - }, { name: "pass - approve without existing allowance", malleate: func() []interface{} { @@ -149,39 +114,6 @@ func (s *PrecompileTestSuite) TestApprove() { ) }, }, - { - name: "pass - approve with existing allowance in different denomination", - malleate: func() []interface{} { - s.setAllowance( - s.precompile2.Address(), - s.keyring.GetPrivKey(0), - s.keyring.GetAddr(1), - big.NewInt(1), - ) - - return []interface{}{ - s.keyring.GetAddr(1), big.NewInt(amount), - } - }, - expPass: true, - postCheck: func() { - // Check that the allowance is set to the new amount - s.requireAllowance( - s.precompile.Address(), - s.keyring.GetAddr(0), - s.keyring.GetAddr(1), - big.NewInt(amount), - ) - - // Check that the allowance for the other denomination was not deleted - s.requireAllowance( - s.precompile2.Address(), - s.keyring.GetAddr(0), - s.keyring.GetAddr(1), - big.NewInt(1), - ) - }, - }, { name: "pass - delete existing allowance", malleate: func() []interface{} { diff --git a/tests/integration/precompiles/erc20/test_integration.go b/tests/integration/precompiles/erc20/test_integration.go index 43073db41..50b0d7406 100644 --- a/tests/integration/precompiles/erc20/test_integration.go +++ b/tests/integration/precompiles/erc20/test_integration.go @@ -19,7 +19,6 @@ import ( "github.com/cosmos/evm/precompiles/erc20" "github.com/cosmos/evm/precompiles/erc20/testdata" "github.com/cosmos/evm/precompiles/testutil" - testconstants "github.com/cosmos/evm/testutil/constants" "github.com/cosmos/evm/testutil/integration/evm/factory" "github.com/cosmos/evm/testutil/integration/evm/grpc" "github.com/cosmos/evm/testutil/integration/evm/network" @@ -250,10 +249,6 @@ func TestIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options execRevertedCheck = failCheck.WithErrContains("execution reverted") passCheck = failCheck.WithExpPass(true) - erc20Keeper := is.network.App.GetErc20Keeper() - available := erc20Keeper.IsNativePrecompileAvailable(is.network.GetContext(), common.HexToAddress(testconstants.WEVMOSContractMainnet)) - Expect(available).To(BeTrue()) - revertContractAddr, err = is.factory.DeployContract( sender.Priv, evmtypes.EvmTxArgs{}, // NOTE: passing empty struct to use default values @@ -261,7 +256,7 @@ func TestIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options Contract: revertCallerContract, // NOTE: we're passing the precompile address to the constructor because that initiates the contract // to make calls to the correct ERC20 precompile. - ConstructorArgs: []interface{}{common.HexToAddress(testconstants.WEVMOSContractMainnet)}, + ConstructorArgs: []interface{}{is.precompile.Address()}, }, ) Expect(err).ToNot(HaveOccurred(), "failed to deploy reverter contract") @@ -425,252 +420,6 @@ func TestIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options // Entry(" - through erc20 v5 contract", erc20V5Call), ) }) - When("calling reverter contract", func() { - Context("in a direct call to the WEVMOS contract", func() { - var ( - args testutiltypes.CallArgs - txArgs evmtypes.EvmTxArgs - ) - BeforeEach(func() { - args = testutiltypes.CallArgs{ - ContractABI: revertCallerContract.ABI, - } - - txArgs = evmtypes.EvmTxArgs{ - To: &revertContractAddr, - GasLimit: gasLimit, - GasPrice: gasPrice, - } - }) - It("should transfer tokens", func() { - sender := is.keyring.GetKey(0) - receiver := is.keyring.GetKey(1) - amountToSend := big.NewInt(100) - - balRes, err := is.handler.GetBalanceFromBank(receiver.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - denomInitialBalance := balRes.Balance - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderInitialBalance := balRes.Balance - - args.MethodName = "transferWithRevert" - args.Args = []interface{}{ - receiver.Addr, - amountToSend, - false, - false, - } - txArgs.Amount = amountToSend - - transferCheck := passCheck.WithExpEvents(erc20.EventTypeTransfer) - res, _, err := is.factory.CallContractAndCheckLogs(sender.Priv, txArgs, args, transferCheck) - Expect(err).To(BeNil()) - Expect(is.network.NextBlock()).To(BeNil()) - fees := math.NewIntFromBigInt(gasPrice).MulRaw(res.GasUsed) - - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "failed to advance block") - - balRes, err = is.handler.GetBalanceFromBank(receiver.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - denomFinalBalance := balRes.Balance - Expect(denomFinalBalance.Amount).To(Equal(denomInitialBalance.Amount.Add(math.NewInt(amountToSend.Int64())))) - - balRes, err = is.handler.GetBalanceFromBank(revertContractAddr.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - contractBalance := balRes.Balance - Expect(contractBalance.Amount).To(Equal(math.ZeroInt())) - - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderFinalBalance := balRes.Balance - denomSpent := fees.Add(math.NewIntFromBigInt(amountToSend)) - Expect(senderFinalBalance.Amount).To(Equal(senderInitialBalance.Amount.Sub(denomSpent))) - }, - ) - DescribeTable("it should revert token transfer from the WEVMOS contract", func(before bool, after bool) { - sender := is.keyring.GetKey(0) - receiver := is.keyring.GetAddr(1) - amountToSend := big.NewInt(100) - balRes, err := is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomInitialBalance := balRes.Balance - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderInitialBalance := balRes.Balance - - args.MethodName = "transferWithRevert" - args.Args = []interface{}{ - receiver, - amountToSend, - before, - after, - } - txArgs.Amount = amountToSend - - revertReasonCheck := execRevertedCheck.WithErrNested("revert here") - - res, _, err := is.factory.CallContractAndCheckLogs(sender.Priv, txArgs, args, revertReasonCheck) - Expect(err).To(BeNil()) - Expect(is.network.NextBlock()).To(BeNil()) - - fees := math.NewIntFromBigInt(gasPrice).MulRaw(res.GasUsed) - - // contract balance should remain unchanged - balRes, err = is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomFinalBalance := balRes.Balance - Expect(denomFinalBalance.Amount).To(Equal(denomInitialBalance.Amount)) - - balRes, err = is.handler.GetBalanceFromBank(revertContractAddr.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - contractBalance := balRes.Balance - Expect(contractBalance.Amount).To(Equal(math.ZeroInt())) - - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderFinalBalance := balRes.Balance - Expect(senderFinalBalance.Amount).To(Equal(senderInitialBalance.Amount.Sub(fees))) - }, - Entry("revert before", true, false), - Entry("revert after", false, true), - ) - It("it should send token transfer and send from WEVMOS contract", func() { - sender := is.keyring.GetKey(0) - receiver := is.keyring.GetAddr(1) - totalToSend := int64(350) - balRes, err := is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomInitialBalance := balRes.Balance - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderInitialBalance := balRes.Balance - - args.MethodName = "testTransferAndSend" - args.Args = []interface{}{ - receiver, - big.NewInt(100), - big.NewInt(100), - big.NewInt(150), - false, - false, - } - txArgs.Amount = big.NewInt(totalToSend) - - transferCheck := passCheck.WithExpEvents(erc20.EventTypeTransfer) - res, _, err := is.factory.CallContractAndCheckLogs(sender.Priv, txArgs, args, transferCheck) - Expect(err).To(BeNil()) - Expect(is.network.NextBlock()).To(BeNil()) - fees := math.NewIntFromBigInt(gasPrice).MulRaw(res.GasUsed) - - // contract balance should remain unchanged - balRes, err = is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomFinalBalance := balRes.Balance - Expect(denomFinalBalance.Amount).To(Equal(denomInitialBalance.Amount.Add(math.NewInt(totalToSend)))) - - balRes, err = is.handler.GetBalanceFromBank(revertContractAddr.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - contractBalance := balRes.Balance - Expect(contractBalance.Amount).To(Equal(math.ZeroInt())) - - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderFinalBalance := balRes.Balance - denomSpent := fees.AddRaw(totalToSend) - Expect(senderFinalBalance.Amount).To(Equal(senderInitialBalance.Amount.Sub(denomSpent))) - }, - ) - DescribeTable("it should revert token transfer and send from WEVMOS contract", func(before bool, after bool) { - sender := is.keyring.GetKey(0) - receiver := is.keyring.GetAddr(1) - balRes, err := is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomInitialBalance := balRes.Balance - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderInitialBalance := balRes.Balance - - args.MethodName = "testTransferAndSend" - args.Args = []interface{}{ - receiver, - big.NewInt(100), - big.NewInt(100), - big.NewInt(100), - before, - after, - } - txArgs.Amount = big.NewInt(300) - - revertReasonCheck := execRevertedCheck.WithErrNested("revert here") - - res, _, err := is.factory.CallContractAndCheckLogs(sender.Priv, txArgs, args, revertReasonCheck) - Expect(err).To(BeNil()) - Expect(is.network.NextBlock()).To(BeNil()) - fees := math.NewIntFromBigInt(gasPrice).MulRaw(res.GasUsed) - - // contract balance should remain unchanged - balRes, err = is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomFinalBalance := balRes.Balance - Expect(denomFinalBalance.Amount).To(Equal(denomInitialBalance.Amount)) - - balRes, err = is.handler.GetBalanceFromBank(revertContractAddr.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - contractBalance := balRes.Balance - Expect(contractBalance.Amount).To(Equal(math.ZeroInt())) - - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderFinalBalance := balRes.Balance - Expect(senderFinalBalance.Amount).To(Equal(senderInitialBalance.Amount.Sub(fees))) - }, - Entry("revert before", true, false), - Entry("revert after", false, true), - ) - It("revert when transfer with try", func() { - sender := is.keyring.GetKey(0) - receiver := is.keyring.GetAddr(1) - amountToSend := big.NewInt(100) - balRes, err := is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomInitialBalance := balRes.Balance - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderInitialBalance := balRes.Balance - - args.MethodName = "transfersWithTry" - args.Args = []interface{}{ - receiver, - amountToSend, - amountToSend, - } - txArgs.Amount = big.NewInt(200) - - transferCheck := passCheck.WithExpEvents(erc20.EventTypeTransfer) - res, _, err := is.factory.CallContractAndCheckLogs(sender.Priv, txArgs, args, transferCheck) - Expect(err).To(BeNil()) - Expect(is.network.NextBlock()).To(BeNil()) - fees := math.NewIntFromBigInt(gasPrice).MulRaw(res.GasUsed) - - balRes, err = is.handler.GetBalanceFromBank(receiver.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - denomFinalBalance := balRes.Balance - Expect(denomFinalBalance.Amount).To(Equal(denomInitialBalance.Amount.Add(math.NewInt(amountToSend.Int64())))) - - balRes, err = is.handler.GetBalanceFromBank(revertContractAddr.Bytes(), is.bondDenom) - Expect(err).To(BeNil()) - contractBalance := balRes.Balance - Expect(contractBalance.Amount.Int64()).To(Equal(amountToSend.Int64())) - - balRes, err = is.handler.GetBalanceFromBank(sender.AccAddr, is.bondDenom) - Expect(err).To(BeNil()) - senderFinalBalance := balRes.Balance - denomSpent := fees.AddRaw(amountToSend.Int64() + amountToSend.Int64()) - Expect(senderFinalBalance.Amount).To(Equal(senderInitialBalance.Amount.Sub(denomSpent))) - }) - }) - }) When("transferring tokens from another account", func() { Context("in a direct call to the token contract", func() { diff --git a/tests/integration/precompiles/erc20/test_setup.go b/tests/integration/precompiles/erc20/test_setup.go index a79ee864a..a5c8338d2 100644 --- a/tests/integration/precompiles/erc20/test_setup.go +++ b/tests/integration/precompiles/erc20/test_setup.go @@ -27,9 +27,6 @@ type PrecompileTestSuite struct { keyring testkeyring.Keyring precompile *erc20.Precompile - - // precompile2 is a second instance of the ERC20 precompile whose denom is bondDenom. - precompile2 *erc20.Precompile } func NewPrecompileTestSuite(create network.CreateEvmApp, options ...network.ConfigOption) *PrecompileTestSuite { @@ -67,10 +64,4 @@ func (s *PrecompileTestSuite) SetupTest() { s.tokenDenom = "xmpl" s.precompile, err = s.setupERC20Precompile(s.tokenDenom) s.Require().NoError(err) - - // Instantiate the precompile2 with the bond denom (the token pair was already set up in genesis). - tokenPairID := s.network.App.GetErc20Keeper().GetDenomMap(s.network.GetContext(), bondDenom) - tokenPair, found := s.network.App.GetErc20Keeper().GetTokenPair(s.network.GetContext(), tokenPairID) - s.Require().True(found) - s.precompile2 = erc20.NewPrecompile(tokenPair, s.network.App.GetBankKeeper(), s.network.App.GetErc20Keeper(), s.network.App.GetTransferKeeper()) } diff --git a/tests/integration/precompiles/werc20/test_events.go b/tests/integration/precompiles/werc20/test_events.go deleted file mode 100644 index 5f3308746..000000000 --- a/tests/integration/precompiles/werc20/test_events.go +++ /dev/null @@ -1,211 +0,0 @@ -package werc20 - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/suite" - - cmn "github.com/cosmos/evm/precompiles/common" - "github.com/cosmos/evm/precompiles/werc20" - testconstants "github.com/cosmos/evm/testutil/constants" - "github.com/cosmos/evm/testutil/integration/evm/factory" - "github.com/cosmos/evm/testutil/integration/evm/grpc" - "github.com/cosmos/evm/testutil/integration/evm/network" - "github.com/cosmos/evm/testutil/keyring" -) - -type PrecompileUnitTestSuite struct { - suite.Suite - - create network.CreateEvmApp - options []network.ConfigOption - network *network.UnitTestNetwork - factory factory.TxFactory - grpcHandler grpc.Handler - keyring keyring.Keyring - - // WEVMOS related fields - precompile *werc20.Precompile - precompileAddrHex string -} - -func NewPrecompileUnitTestSuite( - create network.CreateEvmApp, - options ...network.ConfigOption, -) *PrecompileUnitTestSuite { - return &PrecompileUnitTestSuite{ - create: create, - options: options, - } -} - -// SetupTest allows to configure the testing suite embedding a network with a -// custom chainID. This is important to check that the correct address is used -// for the precompile. -func (s *PrecompileUnitTestSuite) SetupTest(chainID testconstants.ChainID) { - keyring := keyring.New(2) - - options := []network.ConfigOption{ - network.WithChainID(chainID), - network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...), - } - options = append(options, s.options...) - integrationNetwork := network.NewUnitTestNetwork(s.create, options...) - grpcHandler := grpc.NewIntegrationHandler(integrationNetwork) - txFactory := factory.New(integrationNetwork, grpcHandler) - - s.network = integrationNetwork - s.factory = txFactory - s.grpcHandler = grpcHandler - s.keyring = keyring - - s.precompileAddrHex = network.GetWEVMOSContractHex(chainID) - - ctx := integrationNetwork.GetContext() - - tokenDenom, err := s.network.App.GetErc20Keeper().GetTokenDenom(ctx, common.HexToAddress(s.precompileAddrHex)) - s.Require().NoError(err, "failed to get token denom") - tokenPairID := s.network.App.GetErc20Keeper().GetTokenPairID(ctx, tokenDenom) - tokenPair, found := s.network.App.GetErc20Keeper().GetTokenPair(ctx, tokenPairID) - s.Require().True(found, "expected wevmos precompile to be registered in the tokens map") - s.Require().Equal(s.precompileAddrHex, tokenPair.Erc20Address, "expected a different address of the contract") - - precompile := werc20.NewPrecompile( - tokenPair, - s.network.App.GetBankKeeper(), - s.network.App.GetErc20Keeper(), - s.network.App.GetTransferKeeper(), - ) - s.Require().NotNil(precompile) - s.precompile = precompile -} - -type DepositEvent struct { - Dst common.Address - Wad *big.Int -} - -type WithdrawalEvent struct { - Src common.Address - Wad *big.Int -} - -//nolint:dupl -func (s *PrecompileUnitTestSuite) TestEmitDepositEvent() { - testCases := []struct { - name string - chainID testconstants.ChainID - }{ - { - name: "mainnet", - chainID: testconstants.ExampleChainID, - }, { - name: "six decimals", - chainID: testconstants.SixDecimalsChainID, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest(tc.chainID) - caller := s.keyring.GetAddr(0) - amount := new(big.Int).SetInt64(1_000) - - stateDB := s.network.GetStateDB() - - err := s.precompile.EmitDepositEvent( - s.network.GetContext(), - stateDB, - caller, - amount, - ) - s.Require().NoError(err, "expected deposit event to be emitted successfully") - - log := stateDB.Logs()[0] - - // Check on the address - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check on the topics - event := s.precompile.Events[werc20.EventTypeDeposit] - s.Require().Equal( - crypto.Keccak256Hash([]byte(event.Sig)), - common.HexToHash(log.Topics[0].Hex()), - ) - var adddressTopic common.Hash - copy(adddressTopic[common.HashLength-common.AddressLength:], caller[:]) - s.Require().Equal(adddressTopic, log.Topics[1]) - - s.Require().EqualValues(log.BlockNumber, s.network.GetContext().BlockHeight()) - - // Verify data - var depositEvent DepositEvent - err = cmn.UnpackLog(s.precompile.ABI, &depositEvent, werc20.EventTypeDeposit, *log) - s.Require().NoError(err, "unable to unpack log into deposit event") - - s.Require().Equal(caller, depositEvent.Dst, "expected different destination address") - s.Require().Equal(amount, depositEvent.Wad, "expected different amount") - }) - } -} - -//nolint:dupl -func (s *PrecompileUnitTestSuite) TestEmitWithdrawalEvent() { - testCases := []struct { - name string - chainID testconstants.ChainID - }{ - { - name: "mainnet", - chainID: testconstants.ExampleChainID, - }, { - name: "six decimals", - chainID: testconstants.SixDecimalsChainID, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest(tc.chainID) - caller := s.keyring.GetAddr(0) - amount := new(big.Int).SetInt64(1_000) - - stateDB := s.network.GetStateDB() - - err := s.precompile.EmitWithdrawalEvent( - s.network.GetContext(), - stateDB, - caller, - amount, - ) - s.Require().NoError(err, "expected withdrawal event to be emitted successfully") - - log := stateDB.Logs()[0] - - // Check on the address - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check on the topics - event := s.precompile.Events[werc20.EventTypeWithdrawal] - s.Require().Equal( - crypto.Keccak256Hash([]byte(event.Sig)), - common.HexToHash(log.Topics[0].Hex()), - ) - var adddressTopic common.Hash - copy(adddressTopic[common.HashLength-common.AddressLength:], caller[:]) - s.Require().Equal(adddressTopic, log.Topics[1]) - - s.Require().EqualValues(log.BlockNumber, s.network.GetContext().BlockHeight()) - - // Verify data - var withdrawalEvent WithdrawalEvent - err = cmn.UnpackLog(s.precompile.ABI, &withdrawalEvent, werc20.EventTypeWithdrawal, *log) - s.Require().NoError(err, "unable to unpack log into withdrawal event") - - s.Require().Equal(caller, withdrawalEvent.Src, "expected different source address") - s.Require().Equal(amount, withdrawalEvent.Wad, "expected different amount") - }) - } -} diff --git a/tests/integration/precompiles/werc20/test_integration.go b/tests/integration/precompiles/werc20/test_integration.go deleted file mode 100644 index ea5e1a0e5..000000000 --- a/tests/integration/precompiles/werc20/test_integration.go +++ /dev/null @@ -1,573 +0,0 @@ -package werc20 - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/ginkgo/v2" - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - "github.com/cosmos/evm/precompiles/erc20" - "github.com/cosmos/evm/precompiles/testutil" - "github.com/cosmos/evm/precompiles/werc20" - "github.com/cosmos/evm/precompiles/werc20/testdata" - testconstants "github.com/cosmos/evm/testutil/constants" - "github.com/cosmos/evm/testutil/integration/evm/factory" - "github.com/cosmos/evm/testutil/integration/evm/grpc" - "github.com/cosmos/evm/testutil/integration/evm/network" - "github.com/cosmos/evm/testutil/keyring" - utiltx "github.com/cosmos/evm/testutil/tx" - testutiltypes "github.com/cosmos/evm/testutil/types" - erc20types "github.com/cosmos/evm/x/erc20/types" - feemarkettypes "github.com/cosmos/evm/x/feemarket/types" - precisebanktypes "github.com/cosmos/evm/x/precisebank/types" - evmtypes "github.com/cosmos/evm/x/vm/types" - - "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ------------------------------------------------------------------------------------------------- -// Integration test suite -// ------------------------------------------------------------------------------------------------- - -type PrecompileIntegrationTestSuite struct { - network *network.UnitTestNetwork - factory factory.TxFactory - grpcHandler grpc.Handler - keyring keyring.Keyring - - wrappedCoinDenom string - - // WERC20 precompile instance and configuration - precompile *werc20.Precompile - precompileAddrHex string -} - -func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options ...network.ConfigOption) { - _ = DescribeTableSubtree("a user interact with the WEVMOS precompiled contract", func(chainId testconstants.ChainID) { - var ( - is *PrecompileIntegrationTestSuite - passCheck, failCheck testutil.LogCheckArgs - transferCheck, depositCheck, withdrawCheck testutil.LogCheckArgs - - callsData CallsData - - txSender, user keyring.Key - - revertContractAddr common.Address - - // Account balance tracking - accountBalances []*AccountBalanceInfo - precisebankRemainder *big.Int - ) - - // Configure deposit amounts with integer and fractional components to test - // precise balance handling across different decimal configurations - var conversionFactor *big.Int - switch chainId { - case testconstants.SixDecimalsChainID: - conversionFactor = big.NewInt(1e12) // For 6-decimal chains - case testconstants.TwelveDecimalsChainID: - conversionFactor = big.NewInt(1e6) // For 12-decimal chains - default: - conversionFactor = big.NewInt(1) // For 18-decimal chains - } - - // Create deposit with 1000 integer units + fractional part - depositAmount := big.NewInt(1000) - depositAmount = depositAmount.Mul(depositAmount, conversionFactor) // 1000 integer units - depositFractional := new(big.Int).Div(new(big.Int).Mul(conversionFactor, big.NewInt(3)), big.NewInt(10)) // 0.3 * conversion factor as fractional - depositAmount = depositAmount.Add(depositAmount, depositFractional) - - withdrawAmount := depositAmount - transferAmount := big.NewInt(10) // Start with 10 integer units - - // Helper function to get account balance info by type - balanceOf := func(accountType AccountType) *AccountBalanceInfo { - return GetAccountBalance(accountBalances, accountType) - } - - BeforeEach(func() { - is = new(PrecompileIntegrationTestSuite) - keyring := keyring.New(2) - - txSender = keyring.GetKey(0) - user = keyring.GetKey(1) - - // Set the base fee to zero to allow for zero cost tx. The final gas cost is - // not part of the logic tested here so this makes testing more easy. - customGenesis := network.CustomGenesisState{} - feemarketGenesis := feemarkettypes.DefaultGenesisState() - feemarketGenesis.Params.NoBaseFee = true - customGenesis[feemarkettypes.ModuleName] = feemarketGenesis - - // Reset evm config here for the standard case - configurator := evmtypes.NewEVMConfigurator() - configurator.ResetTestConfig() - Expect(configurator. - WithEVMCoinInfo(testconstants.ExampleChainCoinInfo[chainId]). - Configure()).To(BeNil(), "expected no error setting the evm configurator") - - opts := []network.ConfigOption{ - network.WithChainID(chainId), - network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...), - network.WithCustomGenesis(customGenesis), - } - opts = append(opts, options...) - integrationNetwork := network.NewUnitTestNetwork(create, opts...) - grpcHandler := grpc.NewIntegrationHandler(integrationNetwork) - txFactory := factory.New(integrationNetwork, grpcHandler) - - is.network = integrationNetwork - is.factory = txFactory - is.grpcHandler = grpcHandler - is.keyring = keyring - - is.wrappedCoinDenom = evmtypes.GetEVMCoinDenom() - is.precompileAddrHex = network.GetWEVMOSContractHex(testconstants.ChainID{ - ChainID: is.network.GetChainID(), - EVMChainID: is.network.GetEIP155ChainID().Uint64(), - }) - - ctx := integrationNetwork.GetContext() - - // Perform some check before adding the precompile to the suite. - - // Check that WEVMOS is part of the native precompiles. - available := is.network.App.GetErc20Keeper().IsNativePrecompileAvailable(is.network.GetContext(), common.HexToAddress(is.precompileAddrHex)) - Expect(available).To( - BeTrue(), - "expected wevmos to be in the native precompiles", - ) - _, found := is.network.App.GetBankKeeper().GetDenomMetaData(ctx, evmtypes.GetEVMCoinDenom()) - Expect(found).To(BeTrue(), "expected native token metadata to be registered") - - // Check that WEVMOS is registered in the token pairs map. - tokenPairID := is.network.App.GetErc20Keeper().GetTokenPairID(ctx, is.wrappedCoinDenom) - tokenPair, found := is.network.App.GetErc20Keeper().GetTokenPair(ctx, tokenPairID) - Expect(found).To(BeTrue(), "expected wevmos precompile to be registered in the tokens map") - Expect(tokenPair.Erc20Address).To(Equal(is.precompileAddrHex)) - - precompileAddr := common.HexToAddress(is.precompileAddrHex) - tokenPair = erc20types.NewTokenPair( - precompileAddr, - evmtypes.GetEVMCoinDenom(), - erc20types.OWNER_MODULE, - ) - - precompile := werc20.NewPrecompile( - tokenPair, - is.network.App.GetBankKeeper(), - is.network.App.GetErc20Keeper(), - is.network.App.GetTransferKeeper(), - ) - is.precompile = precompile - - // Setup of the contract calling into the precompile to tests revert - // edge cases and proper handling of snapshots. - revertCallerContract, err := testdata.LoadWEVMOS9TestCaller() - Expect(err).ToNot(HaveOccurred(), "failed to load werc20 reverter caller contract") - - txArgs := evmtypes.EvmTxArgs{} - txArgs.GasTipCap = new(big.Int).SetInt64(0) - txArgs.GasLimit = 1_000_000_000_000 - revertContractAddr, err = is.factory.DeployContract( - txSender.Priv, - txArgs, - testutiltypes.ContractDeploymentData{ - Contract: revertCallerContract, - ConstructorArgs: []interface{}{ - common.HexToAddress(is.precompileAddrHex), - }, - }, - ) - Expect(err).ToNot(HaveOccurred(), "failed to deploy werc20 reverter contract") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - - // Support struct used to simplify transactions creation. - callsData = CallsData{ - sender: txSender, - - precompileAddr: precompileAddr, - precompileABI: precompile.ABI, - - precompileReverterAddr: revertContractAddr, - precompileReverterABI: revertCallerContract.ABI, - } - - // Utility types used to check the different events emitted. - failCheck = testutil.LogCheckArgs{ABIEvents: is.precompile.Events} - passCheck = failCheck.WithExpPass(true) - withdrawCheck = passCheck.WithExpEvents(werc20.EventTypeWithdrawal) - depositCheck = passCheck.WithExpEvents(werc20.EventTypeDeposit) - transferCheck = passCheck.WithExpEvents(erc20.EventTypeTransfer) - - // Initialize and reset balance tracking state for each test - accountBalances = InitializeAccountBalances( - txSender.AccAddr, user.AccAddr, - callsData.precompileAddr, revertContractAddr, - ) - - // Reset expected balance change of accounts - ResetExpectedDeltas(accountBalances) - precisebankRemainder = big.NewInt(0) - }) - - // JustBeforeEach takes snapshots after individual test setup - JustBeforeEach(func() { - TakeBalanceSnapshots(accountBalances, is.grpcHandler) - }) - - // AfterEach verifies balance changes - AfterEach(func() { - VerifyBalanceChanges(accountBalances, is.grpcHandler, precisebankRemainder) - }) - - Context("calling a specific wrapped coin method", func() { - Context("and funds are part of the transaction", func() { - When("the method is deposit", func() { - It("it should return funds to sender and emit the event", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.DepositMethod) - txArgs.Amount = depositAmount - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.DepositMethod) - txArgs.Amount = depositAmount - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for deposit") - }) - }) - //nolint:dupl - When("no calldata is provided", func() { - It("it should call the receive which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.DepositMethod) - txArgs.Amount = depositAmount - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for receive") - }) - }) - When("the specified method is too short", func() { - It("it should call the fallback which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Short method is directly set in the input to skip ABI validation - txArgs.Input = []byte{1, 2, 3} - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Short method is directly set in the input to skip ABI validation - txArgs.Input = []byte{1, 2, 3} - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for fallback") - }) - }) - When("the specified method does not exist", func() { - It("it should call the fallback which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Wrong method is directly set in the input to skip ABI validation - txArgs.Input = []byte("nonExistingMethod") - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Wrong method is directly set in the input to skip ABI validation - txArgs.Input = []byte("nonExistingMethod") - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for fallback") - }) - }) - }) - Context("and funds are NOT part of the transaction", func() { - When("the method is withdraw", func() { - It("it should fail if user doesn't have enough funds", func() { - newUserAcc, newUserPriv := utiltx.NewAccAddressAndKey() - newUserBalance := sdk.Coins{sdk.Coin{ - Denom: evmtypes.GetEVMCoinDenom(), - Amount: math.NewIntFromBigInt(withdrawAmount).Quo(precisebanktypes.ConversionFactor()).SubRaw(1), - }} - err := is.network.App.GetBankKeeper().SendCoins(is.network.GetContext(), user.AccAddr, newUserAcc, newUserBalance) - Expect(err).ToNot(HaveOccurred(), "expected no error sending tokens") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.WithdrawMethod, withdrawAmount) - - _, _, err = is.factory.CallContractAndCheckLogs(newUserPriv, txArgs, callArgs, withdrawCheck) - Expect(err).To(HaveOccurred(), "expected an error because not enough funds") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should be a no-op and emit the event", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.WithdrawMethod, withdrawAmount) - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, withdrawCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the withdraw requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.WithdrawMethod, withdrawAmount) - - _, ethRes, _ := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, withdrawCheck) - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.WithdrawRequiredGas), "expected different gas used for withdraw") - }) - }) - //nolint:dupl - When("no calldata is provided", func() { - It("it should call the fallback which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.DepositMethod) - txArgs.Amount = depositAmount - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for receive") - }) - }) - When("the specified method is too short", func() { - It("it should call the fallback which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Short method is directly set in the input to skip ABI validation - txArgs.Input = []byte{1, 2, 3} - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Short method is directly set in the input to skip ABI validation - txArgs.Input = []byte{1, 2, 3} - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for fallback") - }) - }) - When("the specified method does not exist", func() { - It("it should call the fallback which behave like deposit", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Wrong method is directly set in the input to skip ABI validation - txArgs.Input = []byte("nonExistingMethod") - - _, _, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - It("it should consume at least the deposit requested gas", func() { - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, "") - txArgs.Amount = depositAmount - // Wrong method is directly set in the input to skip ABI validation - txArgs.Input = []byte("nonExistingMethod") - - _, ethRes, err := is.factory.CallContractAndCheckLogs(user.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - Expect(ethRes.GasUsed).To(BeNumerically(">=", werc20.DepositRequiredGas), "expected different gas used for fallback") - }) - }) - }) - }) - Context("calling a reverter contract", func() { - When("to call the deposit", func() { - It("it should return funds to the last sender and emit the event", func() { - borrow := big.NewInt(0) - if conversionFactor.Cmp(big.NewInt(1)) != 0 { // 18-decimal chain (conversionFactor = 1) - borrow = big.NewInt(1) - } - - balanceOf(Sender).IntegerDelta = new(big.Int).Sub(new(big.Int).Neg((new(big.Int).Quo(depositAmount, conversionFactor))), borrow) - balanceOf(Sender).FractionalDelta = new(big.Int).Mod(new(big.Int).Sub(conversionFactor, depositFractional), conversionFactor) - - balanceOf(Contract).IntegerDelta = new(big.Int).Quo(depositAmount, conversionFactor) - balanceOf(Contract).FractionalDelta = depositFractional - - balanceOf(PrecisebankModule).IntegerDelta = borrow - - txArgs, callArgs := callsData.getTxAndCallArgs(contractCall, "depositWithRevert", false, false) - txArgs.Amount = depositAmount - - _, _, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected error calling the precompile") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }) - }) - DescribeTable("to call the deposit", func(before, after bool) { - txArgs, callArgs := callsData.getTxAndCallArgs(contractCall, "depositWithRevert", before, after) - txArgs.Amount = depositAmount - - _, _, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, callArgs, depositCheck) - Expect(err).To(HaveOccurred(), "execution should have reverted") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock") - }, - Entry("it should not move funds and dont emit the event reverting before changing state", true, false), - Entry("it should not move funds and dont emit the event reverting after changing state", false, true), - ) - }) - Context("calling an erc20 method", func() { - When("transferring tokens", func() { - It("it should transfer tokens to a receiver using `transfer`", func() { - balanceOf(Sender).IntegerDelta = new(big.Int).Neg(transferAmount) - balanceOf(Sender).FractionalDelta = big.NewInt(0) - balanceOf(Receiver).IntegerDelta = transferAmount - balanceOf(Receiver).FractionalDelta = big.NewInt(0) - - // First, sender needs to deposit to get WERC20 tokens - // Use a larger deposit amount to ensure sufficient balance for transfer - depositForTransfer := new(big.Int).Mul(transferAmount, big.NewInt(10)) // 10x transfer amount - txArgs, callArgs := callsData.getTxAndCallArgs(directCall, werc20.DepositMethod) - txArgs.Amount = depositForTransfer - _, _, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, callArgs, depositCheck) - Expect(err).ToNot(HaveOccurred(), "failed to deposit before transfer") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock after deposit") - - // Now perform the transfer - txArgs, transferArgs := callsData.getTxAndCallArgs(directCall, erc20.TransferMethod, user.Addr, transferAmount) - - _, _, err = is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, transferArgs, transferCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock after transfer") - }) - It("it should fail to transfer tokens to a receiver using `transferFrom`", func() { - txArgs, transferArgs := callsData.getTxAndCallArgs(directCall, erc20.TransferFromMethod, txSender.Addr, user.Addr, transferAmount) - - insufficientAllowanceCheck := failCheck.WithErrContains(erc20.ErrInsufficientAllowance.Error()) - _, _, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, transferArgs, insufficientAllowanceCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - Expect(is.network.NextBlock()).ToNot(HaveOccurred(), "error on NextBlock after transfer") - }) - }) - When("querying information", func() { - Context("to retrieve a balance", func() { - It("should return the correct balance for an existing account", func() { - // Query the balance - txArgs, balancesArgs := callsData.getTxAndCallArgs(directCall, erc20.BalanceOfMethod, txSender.Addr) - - _, ethRes, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, balancesArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - // Get expected balance using grpcHandler for accurate state - expBalanceRes, err := is.grpcHandler.GetBalanceFromBank(txSender.AccAddr, is.wrappedCoinDenom) - Expect(err).ToNot(HaveOccurred(), "failed to get balance from grpcHandler") - - var balance *big.Int - err = is.precompile.UnpackIntoInterface(&balance, erc20.BalanceOfMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack result") - Expect(balance).To(Equal(expBalanceRes.Balance.Amount.BigInt()), "expected different balance") - }) - It("should return 0 for a new account", func() { - // Query the balance - txArgs, balancesArgs := callsData.getTxAndCallArgs(directCall, erc20.BalanceOfMethod, utiltx.GenerateAddress()) - - _, ethRes, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, balancesArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - var balance *big.Int - err = is.precompile.UnpackIntoInterface(&balance, erc20.BalanceOfMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack result") - Expect(balance.Int64()).To(Equal(int64(0)), "expected different balance") - }) - }) - It("should return the correct name", func() { - txArgs, nameArgs := callsData.getTxAndCallArgs(directCall, erc20.NameMethod) - - _, ethRes, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, nameArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - var name string - err = is.precompile.UnpackIntoInterface(&name, erc20.NameMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack result") - Expect(name).To(ContainSubstring("Cosmos EVM"), "expected different name") - }) - - It("should return the correct symbol", func() { - txArgs, symbolArgs := callsData.getTxAndCallArgs(directCall, erc20.SymbolMethod) - - _, ethRes, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, symbolArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - var symbol string - err = is.precompile.UnpackIntoInterface(&symbol, erc20.SymbolMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack result") - Expect(symbol).To(ContainSubstring("ATOM"), "expected different symbol") - }) - - It("should return the decimals", func() { - txArgs, decimalsArgs := callsData.getTxAndCallArgs(directCall, erc20.DecimalsMethod) - - _, ethRes, err := is.factory.CallContractAndCheckLogs(txSender.Priv, txArgs, decimalsArgs, passCheck) - Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract") - - var decimals uint8 - err = is.precompile.UnpackIntoInterface(&decimals, erc20.DecimalsMethod, ethRes.Ret) - Expect(err).ToNot(HaveOccurred(), "failed to unpack result") - - coinInfo := testconstants.ExampleChainCoinInfo[testconstants.ChainID{ - ChainID: is.network.GetChainID(), - EVMChainID: is.network.GetEIP155ChainID().Uint64(), - }] - Expect(decimals).To(Equal(uint8(coinInfo.Decimals)), "expected different decimals") //nolint:gosec // G115 - }, - ) - }) - }) - }, - Entry("6 decimals chain", testconstants.SixDecimalsChainID), - Entry("12 decimals chain", testconstants.TwelveDecimalsChainID), - Entry("18 decimals chain", testconstants.ExampleChainID), - ) - - // Run Ginkgo integration tests - RegisterFailHandler(Fail) - RunSpecs(t, "WEVMOS precompile test suite") -} diff --git a/tests/integration/precompiles/werc20/test_utils.go b/tests/integration/precompiles/werc20/test_utils.go deleted file mode 100644 index a82bd824c..000000000 --- a/tests/integration/precompiles/werc20/test_utils.go +++ /dev/null @@ -1,227 +0,0 @@ -package werc20 - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - "github.com/cosmos/evm/testutil/integration/evm/grpc" - "github.com/cosmos/evm/testutil/keyring" - testutiltypes "github.com/cosmos/evm/testutil/types" - precisebanktypes "github.com/cosmos/evm/x/precisebank/types" - evmtypes "github.com/cosmos/evm/x/vm/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -// callType constants to differentiate between -// the different types of call to the precompile. -type callType int - -const ( - directCall callType = iota - contractCall -) - -// CallsData is a helper struct to hold the addresses and ABIs for the -// different contract instances that are subject to testing here. -type CallsData struct { - // This field is used to perform transactions that are not relevant for - // testing purposes like query to the contract. - sender keyring.Key - - // precompileReverter is used to call into the werc20 interface and - precompileReverterAddr common.Address - precompileReverterABI abi.ABI - - precompileAddr common.Address - precompileABI abi.ABI -} - -// getTxCallArgs is a helper function to return the correct call arguments and -// transaction data for a given call type. -func (cd CallsData) getTxAndCallArgs( - callType callType, - methodName string, - args ...interface{}, -) (evmtypes.EvmTxArgs, testutiltypes.CallArgs) { - txArgs := evmtypes.EvmTxArgs{} - callArgs := testutiltypes.CallArgs{} - - switch callType { - case directCall: - txArgs.To = &cd.precompileAddr - callArgs.ContractABI = cd.precompileABI - case contractCall: - txArgs.To = &cd.precompileReverterAddr - callArgs.ContractABI = cd.precompileReverterABI - } - - callArgs.MethodName = methodName - callArgs.Args = args - - // Setting gas tip cap to zero to have zero gas price. - txArgs.GasTipCap = new(big.Int).SetInt64(0) - // Gas limit is added only to skip the estimate gas call - // that makes debugging more complex. - txArgs.GasLimit = 1_000_000_000_000 - - return txArgs, callArgs -} - -// ------------------------------------------------------------------------------------------------- -// Balance management utilities -// ------------------------------------------------------------------------------------------------- - -// AccountType represents different account types in the test -type AccountType int - -const ( - Sender AccountType = iota - Receiver - Precompile - Contract - PrecisebankModule -) - -// String returns the string representation of AccountType -func (at AccountType) String() string { - switch at { - case Sender: - return "sender" - case Receiver: - return "receiver" - case Precompile: - return "precompile" - case Contract: - return "contract" - case PrecisebankModule: - return "precisebank module" - default: - return "unknown" - } -} - -// BalanceSnapshot represents a snapshot of account balances for testing -type BalanceSnapshot struct { - IntegerBalance *big.Int - FractionalBalance *big.Int -} - -// AccountBalanceInfo holds balance tracking information for a test account -type AccountBalanceInfo struct { - AccountType AccountType - Address sdk.AccAddress - BeforeSnapshot *BalanceSnapshot - IntegerDelta *big.Int - FractionalDelta *big.Int -} - -// InitializeAccountBalances creates the account balance tracking slice with proper addresses -func InitializeAccountBalances( - senderAddr, receiverAddr sdk.AccAddress, - precompileAddr, contractAddr common.Address, -) []*AccountBalanceInfo { - precisebankModuleAddr := authtypes.NewModuleAddress(precisebanktypes.ModuleName) - return []*AccountBalanceInfo{ - {AccountType: Sender, Address: senderAddr}, - {AccountType: Receiver, Address: receiverAddr}, - {AccountType: Precompile, Address: precompileAddr.Bytes()}, - {AccountType: Contract, Address: contractAddr.Bytes()}, - {AccountType: PrecisebankModule, Address: precisebankModuleAddr}, - } -} - -// ResetExpectedDeltas resets all account balance deltas to zero -func ResetExpectedDeltas(accounts []*AccountBalanceInfo) { - for _, account := range accounts { - account.IntegerDelta = big.NewInt(0) - account.FractionalDelta = big.NewInt(0) - } -} - -// TakeBalanceSnapshots captures current balance states for all accounts -func TakeBalanceSnapshots(accounts []*AccountBalanceInfo, grpcHandler grpc.Handler) { - for _, account := range accounts { - snapshot, err := GetBalanceSnapshot(account.Address, grpcHandler) - Expect(err).ToNot(HaveOccurred(), "failed to take balance snapshots") - account.BeforeSnapshot = snapshot - } -} - -// VerifyBalanceChanges verifies expected balance changes for all accounts -func VerifyBalanceChanges( - accounts []*AccountBalanceInfo, - grpcHandler grpc.Handler, - expectedRemainder *big.Int, -) { - for _, account := range accounts { - ExpectBalanceChange(account.Address, account.BeforeSnapshot, - account.IntegerDelta, account.FractionalDelta, account.AccountType.String(), grpcHandler) - } - - res, err := grpcHandler.Remainder() - Expect(err).ToNot(HaveOccurred(), "failed to get precisebank module remainder") - actualRemainder := res.Remainder.Amount.BigInt() - Expect(actualRemainder).To(Equal(expectedRemainder)) -} - -// GetAccountBalance returns the AccountBalanceInfo for a given account type -func GetAccountBalance(accounts []*AccountBalanceInfo, accountType AccountType) *AccountBalanceInfo { - for _, account := range accounts { - if account.AccountType == accountType { - return account - } - } - return nil -} - -// GetBalanceSnapshot gets complete balance information using grpcHandler -func GetBalanceSnapshot(addr sdk.AccAddress, grpcHandler grpc.Handler) (*BalanceSnapshot, error) { - // Get integer balance (uatom) - intRes, err := grpcHandler.GetBalanceFromBank(addr, evmtypes.GetEVMCoinDenom()) - if err != nil { - return nil, fmt.Errorf("failed to get integer balance: %w", err) - } - - // Get fractional balance using the new grpcHandler method - fracRes, err := grpcHandler.FractionalBalance(addr) - if err != nil { - return nil, fmt.Errorf("failed to get fractional balance: %w", err) - } - - return &BalanceSnapshot{ - IntegerBalance: intRes.Balance.Amount.BigInt(), - FractionalBalance: fracRes.FractionalBalance.Amount.BigInt(), - }, nil -} - -// ExpectBalanceChange verifies expected balance changes after operations -func ExpectBalanceChange( - addr sdk.AccAddress, - beforeSnapshot *BalanceSnapshot, - expectedIntegerDelta *big.Int, - expectedFractionalDelta *big.Int, - description string, - grpcHandler grpc.Handler, -) { - afterSnapshot, err := GetBalanceSnapshot(addr, grpcHandler) - Expect(err).ToNot(HaveOccurred(), "failed to get balance snapshot for %s", description) - - actualIntegerDelta := new(big.Int).Sub(afterSnapshot.IntegerBalance, beforeSnapshot.IntegerBalance) - actualFractionalDelta := new(big.Int).Sub(afterSnapshot.FractionalBalance, beforeSnapshot.FractionalBalance) - - Expect(actualIntegerDelta.Cmp(expectedIntegerDelta)).To(Equal(0), - "integer balance delta mismatch for %s: expected %s, got %s", - description, expectedIntegerDelta.String(), actualIntegerDelta.String()) - - Expect(actualFractionalDelta.Cmp(expectedFractionalDelta)).To(Equal(0), - "fractional balance delta mismatch for %s: expected %s, got %s", - description, expectedFractionalDelta.String(), actualFractionalDelta.String()) -} diff --git a/tests/integration/x/erc20/test_precompiles.go b/tests/integration/x/erc20/test_precompiles.go index 502fce96d..2f54c3bd1 100644 --- a/tests/integration/x/erc20/test_precompiles.go +++ b/tests/integration/x/erc20/test_precompiles.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" - testconstants "github.com/cosmos/evm/testutil/constants" utiltx "github.com/cosmos/evm/testutil/tx" "github.com/cosmos/evm/x/erc20/types" @@ -44,30 +43,6 @@ func (s *KeeperTestSuite) TestGetERC20PrecompileInstance() { false, "", }, - { - "fail - precompile on params, but token pair doesn't exist", - func() { - err := s.network.App.GetErc20Keeper().EnableNativePrecompile(ctx, common.HexToAddress(newTokenHexAddr)) - s.Require().NoError(err) - err = s.network.App.GetErc20Keeper().EnableNativePrecompile(ctx, common.HexToAddress(nonExistendTokenHexAddr)) - s.Require().NoError(err) - }, - common.HexToAddress(nonExistendTokenHexAddr), - false, - true, - "precompiled contract not initialized", - }, - { - "success - precompile on params, and token pair exist", - func() { - err := s.network.App.GetErc20Keeper().EnableNativePrecompile(ctx, common.HexToAddress(tokenPair.Erc20Address)) - s.Require().NoError(err) - }, - common.HexToAddress(tokenPair.Erc20Address), - true, - false, - "", - }, } for _, tc := range testCases { s.Run(tc.name, func() { @@ -77,8 +52,8 @@ func (s *KeeperTestSuite) TestGetERC20PrecompileInstance() { err := s.network.App.GetErc20Keeper().SetToken(ctx, tokenPair) s.Require().NoError(err) tokenPairs = s.network.App.GetErc20Keeper().GetTokenPairs(ctx) - s.Require().True(len(tokenPairs) > 1, - "expected more than 1 token pair to be set; got %d", + s.Require().True(len(tokenPairs) == 1, + "expected 1 token pair to be set; got %d", len(tokenPairs), ) @@ -93,256 +68,6 @@ func (s *KeeperTestSuite) TestGetERC20PrecompileInstance() { } } -func (s *KeeperTestSuite) TestGetNativePrecompiles() { - var ctx sdk.Context - testAddr := utiltx.GenerateAddress() - defaultWEVMOSAddr := common.HexToAddress(testconstants.WEVMOSContractMainnet) - - testCases := []struct { - name string - malleate func() - expRes []string - }{ - { - "default native precompiles registered", - func() {}, - []string{defaultWEVMOSAddr.Hex()}, - }, - { - "no native precompiles registered", - func() { - s.network.App.GetErc20Keeper().DeleteNativePrecompile(ctx, defaultWEVMOSAddr) - }, - nil, - }, - { - "multiple native precompiles available", - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{defaultWEVMOSAddr.Hex(), testAddr.Hex()}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - ctx = s.network.GetContext() - tc.malleate() - - slices.Sort(tc.expRes) - res := s.network.App.GetErc20Keeper().GetNativePrecompiles(ctx) - s.Require().ElementsMatch(res, tc.expRes, tc.name) - }) - } -} - -func (s *KeeperTestSuite) TestSetNativePrecompile() { - var ctx sdk.Context - testAddr := utiltx.GenerateAddress() - defaultWEVMOSAddr := common.HexToAddress(testconstants.WEVMOSContractMainnet) - - testCases := []struct { - name string - addrs []common.Address - malleate func() - expRes []string - }{ - { - "set new native precompile", - []common.Address{testAddr}, - func() {}, - []string{defaultWEVMOSAddr.Hex(), testAddr.Hex()}, - }, - { - "set duplicate native precompile", - []common.Address{testAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{defaultWEVMOSAddr.Hex(), testAddr.Hex()}, - }, - { - "set non-eip55 native precompile variations", - []common.Address{ - common.HexToAddress(strings.ToLower(testAddr.Hex())), - common.HexToAddress(strings.ToUpper(testAddr.Hex())), - }, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{defaultWEVMOSAddr.Hex(), testAddr.Hex()}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - ctx = s.network.GetContext() - tc.malleate() - - slices.Sort(tc.expRes) - for _, addr := range tc.addrs { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, addr) - } - res := s.network.App.GetErc20Keeper().GetNativePrecompiles(ctx) - s.Require().ElementsMatch(res, tc.expRes, tc.name) - }) - } -} - -func (s *KeeperTestSuite) TestDeleteNativePrecompile() { - var ctx sdk.Context - testAddr := utiltx.GenerateAddress() - defaultWEVMOSAddr := common.HexToAddress(testconstants.WEVMOSContractMainnet) - unavailableAddr := common.HexToAddress("unavailable") - - testCases := []struct { - name string - addrs []common.Address - malleate func() - expRes []string - }{ - { - "delete all native precompiles", - []common.Address{defaultWEVMOSAddr, testAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - nil, - }, - { - "delete unavailable native precompile", - []common.Address{unavailableAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{defaultWEVMOSAddr.Hex(), testAddr.Hex()}, - }, - { - "delete default native precompile", - []common.Address{defaultWEVMOSAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{testAddr.Hex()}, - }, - { - "delete new native precompile", - []common.Address{testAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{defaultWEVMOSAddr.Hex()}, - }, - { - "delete with non-eip55 native precompile lower variation", - []common.Address{ - common.HexToAddress(strings.ToLower(defaultWEVMOSAddr.Hex())), - }, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{testAddr.Hex()}, - }, - { - "delete with non-eip55 native precompile upper variation", - []common.Address{ - common.HexToAddress(strings.ToUpper(defaultWEVMOSAddr.Hex())), - }, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{testAddr.Hex()}, - }, - { - "delete multiple of same native precompile", - []common.Address{ - defaultWEVMOSAddr, - defaultWEVMOSAddr, - defaultWEVMOSAddr, - }, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []string{testAddr.Hex()}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - ctx = s.network.GetContext() - tc.malleate() - - slices.Sort(tc.expRes) - for _, addr := range tc.addrs { - s.network.App.GetErc20Keeper().DeleteNativePrecompile(ctx, addr) - } - res := s.network.App.GetErc20Keeper().GetNativePrecompiles(ctx) - s.Require().ElementsMatch(res, tc.expRes, tc.name) - }) - } -} - -func (s *KeeperTestSuite) TestIsNativePrecompileAvailable() { - var ctx sdk.Context - testAddr := utiltx.GenerateAddress() - defaultWEVMOSAddr := common.HexToAddress(testconstants.WEVMOSContractMainnet) - unavailableAddr := common.HexToAddress("unavailable") - - testCases := []struct { - name string - addrs []common.Address - malleate func() - expRes []bool - }{ - { - "all native precompiles are available", - []common.Address{defaultWEVMOSAddr, testAddr}, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []bool{true, true}, - }, - { - "only default native precompile is available", - []common.Address{defaultWEVMOSAddr, testAddr}, - func() {}, - []bool{true, false}, - }, - { - "unavailable native precompile is unavailable", - []common.Address{unavailableAddr}, - func() {}, - []bool{false}, - }, - { - "non-eip55 native precompiles are available", - []common.Address{ - testAddr, - common.HexToAddress(strings.ToLower(testAddr.Hex())), - common.HexToAddress(strings.ToUpper(testAddr.Hex())), - }, - func() { - s.network.App.GetErc20Keeper().SetNativePrecompile(ctx, testAddr) - }, - []bool{true, true, true}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - ctx = s.network.GetContext() - tc.malleate() - - res := make([]bool, 0) - for _, x := range tc.addrs { - res = append(res, s.network.App.GetErc20Keeper().IsNativePrecompileAvailable(ctx, x)) - } - - s.Require().ElementsMatch(res, tc.expRes, tc.name) - }) - } -} - func (s *KeeperTestSuite) TestGetDynamicPrecompiles() { var ctx sdk.Context testAddr := utiltx.GenerateAddress() diff --git a/tests/integration/x/vm/test_call_evm.go b/tests/integration/x/vm/test_call_evm.go deleted file mode 100644 index 013b200f2..000000000 --- a/tests/integration/x/vm/test_call_evm.go +++ /dev/null @@ -1,150 +0,0 @@ -package vm - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - - "github.com/cosmos/evm/contracts" - testconstants "github.com/cosmos/evm/testutil/constants" - utiltx "github.com/cosmos/evm/testutil/tx" - "github.com/cosmos/evm/x/erc20/types" - evmtypes "github.com/cosmos/evm/x/vm/types" -) - -func (s *KeeperTestSuite) TestCallEVM() { - wcosmosEVMContract := common.HexToAddress(testconstants.WEVMOSContractMainnet) - testCases := []struct { - name string - method string - expPass bool - }{ - { - "unknown method", - "", - false, - }, - { - "pass", - "balanceOf", - true, - }, - } - for _, tc := range testCases { - s.SetupTest() // reset - - erc20 := contracts.ERC20MinterBurnerDecimalsContract.ABI - account := utiltx.GenerateAddress() - res, err := s.Network.App.GetEVMKeeper().CallEVM(s.Network.GetContext(), erc20, types.ModuleAddress, wcosmosEVMContract, false, nil, tc.method, account) - if tc.expPass { - s.Require().IsTypef(&evmtypes.MsgEthereumTxResponse{}, res, tc.name) - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - } -} - -func (s *KeeperTestSuite) TestCallEVMWithData() { - erc20 := contracts.ERC20MinterBurnerDecimalsContract.ABI - wcosmosEVMContract := common.HexToAddress(testconstants.WEVMOSContractMainnet) - testCases := []struct { - name string - from common.Address - malleate func() []byte - deploy bool - expPass bool - }{ - { - "pass with unknown method", - types.ModuleAddress, - func() []byte { - account := utiltx.GenerateAddress() - data, _ := erc20.Pack("", account) - return data - }, - false, - true, - }, - { - "pass", - types.ModuleAddress, - func() []byte { - account := utiltx.GenerateAddress() - data, _ := erc20.Pack("balanceOf", account) - return data - }, - false, - true, - }, - { - "pass with empty data", - types.ModuleAddress, - func() []byte { - return []byte{} - }, - false, - true, - }, - - { - "fail empty sender", - common.Address{}, - func() []byte { - return []byte{} - }, - false, - false, - }, - { - "deploy", - types.ModuleAddress, - func() []byte { - ctorArgs, _ := contracts.ERC20MinterBurnerDecimalsContract.ABI.Pack("", "test", "test", uint8(18)) - data := append(contracts.ERC20MinterBurnerDecimalsContract.Bin, ctorArgs...) //nolint:gocritic - return data - }, - true, - true, - }, - { - "fail deploy", - types.ModuleAddress, - func() []byte { - params := s.Network.App.GetEVMKeeper().GetParams(s.Network.GetContext()) - params.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypeRestricted, - } - _ = s.Network.App.GetEVMKeeper().SetParams(s.Network.GetContext(), params) - ctorArgs, _ := contracts.ERC20MinterBurnerDecimalsContract.ABI.Pack("", "test", "test", uint8(18)) - data := append(contracts.ERC20MinterBurnerDecimalsContract.Bin, ctorArgs...) //nolint:gocritic - return data - }, - true, - false, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset - - data := tc.malleate() - var res *evmtypes.MsgEthereumTxResponse - var err error - - if tc.deploy { - res, err = s.Network.App.GetEVMKeeper().CallEVMWithData(s.Network.GetContext(), tc.from, nil, data, true, nil) - } else { - res, err = s.Network.App.GetEVMKeeper().CallEVMWithData(s.Network.GetContext(), tc.from, &wcosmosEVMContract, data, false, nil) - } - - if tc.expPass { - s.Require().IsTypef(&evmtypes.MsgEthereumTxResponse{}, res, tc.name) - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - }) - } -} diff --git a/tests/integration/x/vm/test_iterate_contracts.go b/tests/integration/x/vm/test_iterate_contracts.go index 3c6cd5497..8745405df 100644 --- a/tests/integration/x/vm/test_iterate_contracts.go +++ b/tests/integration/x/vm/test_iterate_contracts.go @@ -1,14 +1,12 @@ package vm import ( - "bytes" "testing" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" "github.com/cosmos/evm/contracts" - testconstants "github.com/cosmos/evm/testutil/constants" "github.com/cosmos/evm/testutil/integration/evm/factory" "github.com/cosmos/evm/testutil/integration/evm/grpc" "github.com/cosmos/evm/testutil/integration/evm/network" @@ -56,11 +54,6 @@ func TestIterateContracts(t *testing.T, create network.CreateEvmApp, options ... ) network.App.GetEVMKeeper().IterateContracts(network.GetContext(), func(addr common.Address, codeHash common.Hash) bool { - // NOTE: we only care about the 2 contracts deployed above, not the ERC20 native precompile for the aatom denomination - if bytes.Equal(addr.Bytes(), common.HexToAddress(testconstants.WEVMOSContractMainnet).Bytes()) { - return false - } - foundAddrs = append(foundAddrs, addr) foundHashes = append(foundHashes, codeHash) addrToHash[addr] = codeHash diff --git a/tests/solidity/suites/precompiles/test/9_werc20/werc20.js b/tests/solidity/suites/precompiles/test/9_werc20/werc20.js deleted file mode 100644 index 8f4f39444..000000000 --- a/tests/solidity/suites/precompiles/test/9_werc20/werc20.js +++ /dev/null @@ -1,226 +0,0 @@ -const { expect } = require('chai'); -const hre = require('hardhat'); -const { WERC20_ADDRESS, DEFAULT_GAS_LIMIT, findEvent, waitWithTimeout, RETRY_DELAY_FUNC} = require('../common'); - -describe('WERC20 – deposit and withdraw', function () { - const GAS_LIMIT = DEFAULT_GAS_LIMIT; - - let werc20, signer; - - before(async function () { - [signer] = await hre.ethers.getSigners(); - werc20 = await hre.ethers.getContractAt('IWERC20', WERC20_ADDRESS); - }); - - describe('Deposit functionality', function () { - it('deposits native tokens successfully', async function () { - const depositAmount = hre.ethers.parseEther('1.0'); - - // Check balances before deposit - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Depositing', hre.ethers.formatEther(depositAmount), 'tokens'); - - const tx = await werc20.deposit({ - value: depositAmount, - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after deposit - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Deposit transaction hash:', receipt.hash); - console.log('Gas used:', receipt.gasUsed.toString()); - - // Check that transaction was successful - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - const gasFee = receipt.gasUsed * receipt.gasPrice; - - // Verify balance changes - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - - // Look for Deposit event - const parsed = findEvent(receipt.logs, werc20.interface, 'Deposit'); - console.log('Deposit event:', parsed.args); - expect(parsed.args.dst).to.equal(signer.address); - expect(parsed.args.wad).to.equal(depositAmount); - }); - - it('deposits with different amounts', async function () { - const amounts = [ - hre.ethers.parseEther('0.1'), // Small amount - hre.ethers.parseEther('5.0'), // Medium amount - hre.ethers.parseEther('10.0'), // Large amount - ]; - - for (const amount of amounts) { - // Check balances before deposit - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Depositing', hre.ethers.formatEther(amount), 'tokens'); - - const tx = await werc20.deposit({ - value: amount, - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after deposit - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Gas used for', hre.ethers.formatEther(amount), 'deposit:', receipt.gasUsed.toString()); - - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - const gasFee = receipt.gasUsed * receipt.gasPrice; - - // Verify balance changes - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - } - }); - - it('deposits via fallback function', async function () { - const depositAmount = hre.ethers.parseEther('0.5'); - - // Check balances before deposit - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Depositing via fallback function'); - - // Send ETH directly to the contract (should trigger fallback/receive) - const tx = await signer.sendTransaction({ - to: WERC20_ADDRESS, - value: depositAmount, - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after deposit - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Fallback deposit gas used:', receipt.gasUsed.toString()); - - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - const gasFee = receipt.gasUsed * receipt.gasPrice; - - // Verify balance changes - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - }); - }); - - describe('Withdraw functionality', function () { - it('withdraws tokens successfully', async function () { - const withdrawAmount = hre.ethers.parseEther('1.0'); - - // Check balances before withdrawal - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Withdrawing', hre.ethers.formatEther(withdrawAmount), 'tokens'); - - const tx = await werc20.withdraw(withdrawAmount, { - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after withdrawal - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Withdraw transaction hash:', receipt.hash); - console.log('Gas used:', receipt.gasUsed.toString()); - - // Check that transaction was successful - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - const gasFee = receipt.gasUsed * receipt.gasPrice; - - // Verify balance changes - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - - // Look for Withdrawal event - const parsed = findEvent(receipt.logs, werc20.interface, 'Withdrawal'); - console.log('Withdrawal event:', parsed.args); - expect(parsed.args.src).to.equal(signer.address); - expect(parsed.args.wad).to.equal(withdrawAmount); - }); - - it('withdraws different amounts', async function () { - const amounts = [ - hre.ethers.parseEther('0.05'), // Very small amount - hre.ethers.parseEther('0.5'), // Small amount - hre.ethers.parseEther('3.0'), // Medium amount - hre.ethers.parseEther('7.5'), // Large amount - ]; - - for (const amount of amounts) { - // Check balances before withdrawal - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Withdrawing', hre.ethers.formatEther(amount), 'tokens'); - - const tx = await werc20.withdraw(amount, { - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after withdrawal - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Gas used for', hre.ethers.formatEther(amount), 'withdrawal:', receipt.gasUsed.toString()); - - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - const gasFee = receipt.gasUsed * receipt.gasPrice; - - // Verify balance changes - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - } - }); - - it('withdraws zero amount (edge case)', async function () { - const zeroAmount = hre.ethers.parseEther('0'); - - // Check balances before withdrawal - const signerBalanceBefore = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceBefore = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Withdrawing zero amount'); - - const tx = await werc20.withdraw(zeroAmount, { - gasLimit: GAS_LIMIT - }); - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC); - - // Check balances after withdrawal - const signerBalanceAfter = await hre.ethers.provider.getBalance(signer.address); - const contractBalanceAfter = await hre.ethers.provider.getBalance(WERC20_ADDRESS); - - console.log('Gas used for zero withdrawal:', receipt.gasUsed.toString()); - - expect(receipt.status).to.equal(1); - expect(receipt.gasUsed).to.be.greaterThan(0); - - // Verify balance changes (should be no change for zero withdrawal except gas fees) - const gasFee = receipt.gasUsed * receipt.gasPrice; - expect(contractBalanceAfter).to.equal(contractBalanceBefore); - expect(signerBalanceAfter).to.equal(signerBalanceBefore - gasFee); - }); - }); -}); \ No newline at end of file diff --git a/tests/solidity/suites/precompiles/test/common.js b/tests/solidity/suites/precompiles/test/common.js index 8f8e518c2..c09e450db 100644 --- a/tests/solidity/suites/precompiles/test/common.js +++ b/tests/solidity/suites/precompiles/test/common.js @@ -7,7 +7,6 @@ const BANK_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000804' const GOV_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000805' const SLASHING_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000806' const P256_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000100' -const WERC20_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' // Default gas limits used across tests const DEFAULT_GAS_LIMIT = 1_000_000 @@ -88,7 +87,6 @@ module.exports = { GOV_PRECOMPILE_ADDRESS, SLASHING_PRECOMPILE_ADDRESS, P256_PRECOMPILE_ADDRESS, - WERC20_ADDRESS, DEFAULT_GAS_LIMIT, LARGE_GAS_LIMIT, RETRY_DELAY_FUNC, diff --git a/tests/solidity/suites/revert_cases/test/common.js b/tests/solidity/suites/revert_cases/test/common.js index 5291c324f..dfc312eb3 100644 --- a/tests/solidity/suites/revert_cases/test/common.js +++ b/tests/solidity/suites/revert_cases/test/common.js @@ -7,7 +7,6 @@ const BANK_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000804' const GOV_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000805' const SLASHING_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000806' const P256_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000000100' -const WERC20_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' // Default gas limits used across tests const DEFAULT_GAS_LIMIT = 1_000_000 @@ -27,7 +26,6 @@ module.exports = { GOV_PRECOMPILE_ADDRESS, SLASHING_PRECOMPILE_ADDRESS, P256_PRECOMPILE_ADDRESS, - WERC20_ADDRESS, // Gas limits DEFAULT_GAS_LIMIT, @@ -38,4 +36,4 @@ module.exports = { PANIC_ASSERT_0x01, PANIC_DIVISION_BY_ZERO_0x12, PANIC_ARRAY_OUT_OF_BOUND_0x32 -} \ No newline at end of file +} diff --git a/testutil/config/genesis.go b/testutil/config/genesis.go index fa528f9fd..ff0ed188d 100644 --- a/testutil/config/genesis.go +++ b/testutil/config/genesis.go @@ -32,13 +32,9 @@ func NewEVMGenesisState() *evmtypes.GenesisState { } // NewErc20GenesisState returns the default genesis state for the ERC20 module. -// -// NOTE: for the example chain implementation we are also adding a default token pair, -// which is the base denomination of the chain (i.e. the WEVMOS contract). func NewErc20GenesisState() *erc20types.GenesisState { erc20GenState := erc20types.DefaultGenesisState() erc20GenState.TokenPairs = testconstants.ExampleTokenPairs - erc20GenState.NativePrecompiles = []string{testconstants.WEVMOSContractMainnet} return erc20GenState } diff --git a/testutil/constants/constants.go b/testutil/constants/constants.go index 764ae4dbf..530880dad 100644 --- a/testutil/constants/constants.go +++ b/testutil/constants/constants.go @@ -4,8 +4,6 @@ import ( "github.com/cosmos/evm/server/config" erc20types "github.com/cosmos/evm/x/erc20/types" evmtypes "github.com/cosmos/evm/x/vm/types" - - "cosmossdk.io/math" ) const ( @@ -27,10 +25,6 @@ const ( // EighteenDecimalsChainID provides an example EIP-155 chain ID for use in tests EighteenDecimalsChainID = 9001 - // WEVMOSContractMainnet is the WEVMOS contract address for mainnet - WEVMOSContractMainnet = "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517" - // WEVMOSContractTestnet is the WEVMOS contract address for testnet - WEVMOSContractTestnet = "0xcc491f589b45d4a3c679016195b3fb87d7848210" // ExampleEvmAddress1 is the example EVM address ExampleEvmAddressAlice = "0x1e0DE5DB1a39F99cBc67B00fA3415181b3509e42" // ExampleEvmAddress2 is the example EVM address @@ -148,23 +142,9 @@ var ( // ExampleTokenPairs creates a slice of token pairs, that contains a pair for the native denom of the example chain // implementation. - ExampleTokenPairs = []erc20types.TokenPair{ - { - Erc20Address: WEVMOSContractMainnet, - Denom: ExampleAttoDenom, - Enabled: true, - ContractOwner: erc20types.OWNER_MODULE, - }, - } + ExampleTokenPairs = []erc20types.TokenPair{} // ExampleAllowances creates a slice of allowances, that contains an allowance for the native denom of the example chain // implementation. - ExampleAllowances = []erc20types.Allowance{ - { - Erc20Address: WEVMOSContractMainnet, - Owner: ExampleEvmAddressAlice, - Spender: ExampleEvmAddressBob, - Value: math.NewInt(100), - }, - } + ExampleAllowances = []erc20types.Allowance{} ) diff --git a/testutil/integration/evm/network/chain_id_modifiers.go b/testutil/integration/evm/network/chain_id_modifiers.go index 1bfc65c25..579579121 100644 --- a/testutil/integration/evm/network/chain_id_modifiers.go +++ b/testutil/integration/evm/network/chain_id_modifiers.go @@ -6,7 +6,6 @@ package network import ( testconstants "github.com/cosmos/evm/testutil/constants" - erc20types "github.com/cosmos/evm/x/erc20/types" evmtypes "github.com/cosmos/evm/x/vm/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -71,14 +70,6 @@ func GenerateBankGenesisMetadata(evmChainID uint64) []banktypes.Metadata { return metas } -// updateErc20GenesisStateForChainID modify the default genesis state for the -// erc20 module on the testing suite depending on the chainID. -func updateErc20GenesisStateForChainID(chainID testconstants.ChainID, erc20GenesisState erc20types.GenesisState) erc20types.GenesisState { - erc20GenesisState.TokenPairs = updateErc20TokenPairs(chainID, erc20GenesisState.TokenPairs) - - return erc20GenesisState -} - // updateErc20GenesisStateForChainID modify the default genesis state for the // erc20 module on the testing suite depending on the chainID. func updateVMGenesisStateForChainID(chainID testconstants.ChainID, vmGenesisState evmtypes.GenesisState) evmtypes.GenesisState { @@ -87,27 +78,3 @@ func updateVMGenesisStateForChainID(chainID testconstants.ChainID, vmGenesisStat return vmGenesisState } - -// updateErc20TokenPairs modifies the erc20 token pairs to use the correct -// WEVMOS depending on ChainID -func updateErc20TokenPairs(chainID testconstants.ChainID, tokenPairs []erc20types.TokenPair) []erc20types.TokenPair { - testnetAddress := GetWEVMOSContractHex(chainID) - coinInfo := testconstants.ExampleChainCoinInfo[chainID] - - mainnetAddress := GetWEVMOSContractHex(testconstants.ExampleChainID) - - updatedTokenPairs := make([]erc20types.TokenPair, len(tokenPairs)) - for i, tokenPair := range tokenPairs { - if tokenPair.Erc20Address == mainnetAddress { - updatedTokenPairs[i] = erc20types.TokenPair{ - Erc20Address: testnetAddress, - Denom: coinInfo.Denom, - Enabled: tokenPair.Enabled, - ContractOwner: tokenPair.ContractOwner, - } - } else { - updatedTokenPairs[i] = tokenPair - } - } - return updatedTokenPairs -} diff --git a/testutil/integration/evm/network/example_contracts.go b/testutil/integration/evm/network/example_contracts.go deleted file mode 100644 index ab3a3daba..000000000 --- a/testutil/integration/evm/network/example_contracts.go +++ /dev/null @@ -1,27 +0,0 @@ -package network - -import ( - testconstants "github.com/cosmos/evm/testutil/constants" -) - -// chainsWEVMOSHex is an utility map used to retrieve the WEVMOS contract -// address in hex format from the chain ID. -// -// TODO: refactor to define this in the example chain initialization and pass as function argument -var chainsWEVMOSHex = map[testconstants.ChainID]string{ - testconstants.ExampleChainID: testconstants.WEVMOSContractMainnet, -} - -// GetWEVMOSContractHex returns the hex format of address for the WEVMOS contract -// given the chainID. If the chainID is not found, it defaults to the mainnet -// address. -func GetWEVMOSContractHex(chainID testconstants.ChainID) string { - address, found := chainsWEVMOSHex[chainID] - - // default to mainnet address - if !found { - address = chainsWEVMOSHex[testconstants.ExampleChainID] - } - - return address -} diff --git a/testutil/integration/evm/network/setup.go b/testutil/integration/evm/network/setup.go index 5a7a74d98..8d019ae89 100644 --- a/testutil/integration/evm/network/setup.go +++ b/testutil/integration/evm/network/setup.go @@ -466,12 +466,7 @@ func setDefaultMintGenesisState(cosmosEVMApp evm.EvmApp, genesisState testutil.G func setDefaultErc20GenesisState(cosmosEVMApp evm.EvmApp, evmChainID uint64, genesisState testutil.GenesisState) testutil.GenesisState { // NOTE: here we are using the setup from the example chain erc20Gen := newErc20GenesisState() - updatedErc20Gen := updateErc20GenesisStateForChainID(testconstants.ChainID{ - ChainID: cosmosEVMApp.ChainID(), - EVMChainID: evmChainID, - }, *erc20Gen) - - genesisState[erc20types.ModuleName] = cosmosEVMApp.AppCodec().MustMarshalJSON(&updatedErc20Gen) + genesisState[erc20types.ModuleName] = cosmosEVMApp.AppCodec().MustMarshalJSON(erc20Gen) return genesisState } @@ -483,7 +478,6 @@ func setDefaultErc20GenesisState(cosmosEVMApp evm.EvmApp, evmChainID uint64, gen func newErc20GenesisState() *erc20types.GenesisState { erc20GenState := erc20types.DefaultGenesisState() erc20GenState.TokenPairs = testconstants.ExampleTokenPairs - erc20GenState.NativePrecompiles = []string{testconstants.WEVMOSContractMainnet} return erc20GenState } diff --git a/testutil/integration/evm/utils/genesis.go b/testutil/integration/evm/utils/genesis.go index 76c340fe5..b70efe868 100644 --- a/testutil/integration/evm/utils/genesis.go +++ b/testutil/integration/evm/utils/genesis.go @@ -70,7 +70,6 @@ func CreateGenesisWithTokenPairs(keyring testkeyring.Keyring, denoms ...string) // with the WEVMOS (default is mainnet) and 'xmpl' tokens in the erc20 params erc20GenesisState := erc20types.DefaultGenesisState() erc20GenesisState.TokenPairs = tokenPairs - erc20GenesisState.NativePrecompiles = []string{testconstants.WEVMOSContractMainnet} erc20GenesisState.DynamicPrecompiles = dynPrecAddr // Combine module genesis states @@ -87,7 +86,6 @@ func CreateGenesisWithTokenPairs(keyring testkeyring.Keyring, denoms ...string) func NewErc20GenesisState() *erc20types.GenesisState { erc20GenState := erc20types.DefaultGenesisState() erc20GenState.TokenPairs = testconstants.ExampleTokenPairs - erc20GenState.NativePrecompiles = []string{testconstants.WEVMOSContractMainnet} return erc20GenState } diff --git a/x/erc20/genesis.go b/x/erc20/genesis.go index 41146838b..9581332aa 100644 --- a/x/erc20/genesis.go +++ b/x/erc20/genesis.go @@ -37,11 +37,6 @@ func InitGenesis( } } - for _, precompile := range data.NativePrecompiles { - if err := k.EnableNativePrecompile(ctx, common.HexToAddress(precompile)); err != nil { - panic(fmt.Errorf("error registering native precompiles %s", err)) - } - } for _, precompile := range data.DynamicPrecompiles { if err := k.EnableDynamicPrecompile(ctx, common.HexToAddress(precompile)); err != nil { panic(fmt.Errorf("error registering dynamic precompiles %s", err)) @@ -66,7 +61,6 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { Params: k.GetParams(ctx), TokenPairs: k.GetTokenPairs(ctx), Allowances: k.GetAllowances(ctx), - NativePrecompiles: k.GetNativePrecompiles(ctx), DynamicPrecompiles: k.GetDynamicPrecompiles(ctx), } } diff --git a/x/erc20/keeper/precompiles.go b/x/erc20/keeper/precompiles.go index 95e40d8f0..23e2f6ec8 100644 --- a/x/erc20/keeper/precompiles.go +++ b/x/erc20/keeper/precompiles.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/cosmos/evm/precompiles/erc20" - "github.com/cosmos/evm/precompiles/werc20" "github.com/cosmos/evm/x/erc20/types" errorsmod "cosmossdk.io/errors" @@ -20,24 +19,18 @@ import ( type PrecompileType int -const ( - PrecompileTypeNative PrecompileType = iota - PrecompileTypeDynamic -) - // GetERC20PrecompileInstance returns the precompile instance for the given address. func (k Keeper) GetERC20PrecompileInstance( ctx sdk.Context, address common.Address, ) (contract vm.PrecompiledContract, found bool, err error) { - isNative := k.IsNativePrecompileAvailable(ctx, address) isDynamic := k.IsDynamicPrecompileAvailable(ctx, address) - if available := isNative || isDynamic; !available { + if available := isDynamic; !available { return nil, false, nil } - precompile, err := k.InstantiateERC20Precompile(ctx, address, isNative) + precompile, err := k.InstantiateERC20Precompile(ctx, address) if err != nil { return nil, false, errorsmod.Wrapf(err, "precompiled contract not initialized: %s", address.String()) } @@ -49,7 +42,7 @@ func (k Keeper) GetERC20PrecompileInstance( // contract address. // If the `hasWrappedMethods` boolean is true, the ERC20 instance returned // exposes methods for `withdraw` and `deposit` as it is common for wrapped tokens. -func (k Keeper) InstantiateERC20Precompile(ctx sdk.Context, contractAddr common.Address, hasWrappedMethods bool) (vm.PrecompiledContract, error) { +func (k Keeper) InstantiateERC20Precompile(ctx sdk.Context, contractAddr common.Address) (vm.PrecompiledContract, error) { address := contractAddr.String() // check if the precompile is an ERC20 contract id := k.GetTokenPairID(ctx, address) @@ -61,25 +54,12 @@ func (k Keeper) InstantiateERC20Precompile(ctx sdk.Context, contractAddr common. return nil, fmt.Errorf("token pair not found: %s", address) } - if hasWrappedMethods { - return werc20.NewPrecompile(pair, k.bankKeeper, k, *k.transferKeeper), nil - } - return erc20.NewPrecompile(pair, k.bankKeeper, k, *k.transferKeeper), nil } -// RegisterCodeHash checks if a new precompile already exists and registers the code hash it is not -func (k Keeper) RegisterCodeHash(ctx sdk.Context, addr common.Address, pType PrecompileType) error { - shouldRegister := false - switch pType { - case PrecompileTypeNative: - shouldRegister = !k.IsNativePrecompileAvailable(ctx, addr) - case PrecompileTypeDynamic: - shouldRegister = !k.IsDynamicPrecompileAvailable(ctx, addr) - default: - return fmt.Errorf("invalid precompile type: %v", pType) - } - +// RegisterPrecompileCodeHash checks if a new precompile already exists and registers the code hash it is not +func (k Keeper) RegisterPrecompileCodeHash(ctx sdk.Context, addr common.Address) error { + shouldRegister := !k.IsDynamicPrecompileAvailable(ctx, addr) if shouldRegister { if err := k.RegisterERC20CodeHash(ctx, addr); err != nil { return err @@ -89,50 +69,10 @@ func (k Keeper) RegisterCodeHash(ctx sdk.Context, addr common.Address, pType Pre return nil } -// EnableNativePrecompile adds the address of the given precompile to the prefix store -func (k Keeper) EnableNativePrecompile(ctx sdk.Context, addr common.Address) error { - k.Logger(ctx).Info("Added new precompiles", "addresses", addr) - if err := k.RegisterCodeHash(ctx, addr, PrecompileTypeNative); err != nil { - return err - } - k.SetNativePrecompile(ctx, addr) - return nil -} - -// Only to be used by ExportGenesis, not to be directly used -func (k Keeper) GetNativePrecompiles(ctx sdk.Context) []string { - iterator := storetypes.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.KeyPrefixNativePrecompiles) - defer iterator.Close() - - nps := make([]string, 0) - for ; iterator.Valid(); iterator.Next() { - key := iterator.Key()[len(types.KeyPrefixNativePrecompiles):] - nps = append(nps, string(key)) - } - - slices.Sort(nps) - return nps -} - -func (k Keeper) IsNativePrecompileAvailable(ctx sdk.Context, precompile common.Address) bool { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixNativePrecompiles) - return store.Has([]byte(precompile.Hex())) -} - -func (k Keeper) SetNativePrecompile(ctx sdk.Context, precompile common.Address) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixNativePrecompiles) - store.Set([]byte(precompile.Hex()), isTrue) -} - -func (k Keeper) DeleteNativePrecompile(ctx sdk.Context, precompile common.Address) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixNativePrecompiles) - store.Delete([]byte(precompile.Hex())) -} - // EnableDynamicPrecompile adds the address of the given precompile to the prefix store func (k Keeper) EnableDynamicPrecompile(ctx sdk.Context, address common.Address) error { k.Logger(ctx).Info("Added new precompiles", "addresses", address) - if err := k.RegisterCodeHash(ctx, address, PrecompileTypeDynamic); err != nil { + if err := k.RegisterPrecompileCodeHash(ctx, address); err != nil { return err } k.SetDynamicPrecompile(ctx, address) diff --git a/x/erc20/types/genesis.go b/x/erc20/types/genesis.go index 2908a794f..148f0c4ef 100644 --- a/x/erc20/types/genesis.go +++ b/x/erc20/types/genesis.go @@ -51,10 +51,6 @@ func (gs GenesisState) Validate() error { return fmt.Errorf("invalid dynamic precompiles on genesis: %w", err) } - if err := validatePrecompiles(gs.TokenPairs, gs.NativePrecompiles); err != nil { - return fmt.Errorf("invalid native precompiles on genesis: %w", err) - } - // Check if allowances are valid seenAllowance := make(map[string]bool) for _, a := range gs.Allowances { diff --git a/x/erc20/types/genesis.pb.go b/x/erc20/types/genesis.pb.go index b923d4379..d94c8fe2c 100644 --- a/x/erc20/types/genesis.pb.go +++ b/x/erc20/types/genesis.pb.go @@ -32,8 +32,6 @@ type GenesisState struct { TokenPairs []TokenPair `protobuf:"bytes,2,rep,name=token_pairs,json=tokenPairs,proto3" json:"token_pairs"` // allowances is a slice of the registered allowances at genesis Allowances []Allowance `protobuf:"bytes,3,rep,name=allowances,proto3" json:"allowances"` - // native_precompiles is a slice of registered native precompiles at genesis - NativePrecompiles []string `protobuf:"bytes,4,rep,name=native_precompiles,json=nativePrecompiles,proto3" json:"native_precompiles,omitempty"` // dynamic_precompiles is a slice of registered dynamic precompiles at genesis DynamicPrecompiles []string `protobuf:"bytes,5,rep,name=dynamic_precompiles,json=dynamicPrecompiles,proto3" json:"dynamic_precompiles,omitempty"` } @@ -92,13 +90,6 @@ func (m *GenesisState) GetAllowances() []Allowance { return nil } -func (m *GenesisState) GetNativePrecompiles() []string { - if m != nil { - return m.NativePrecompiles - } - return nil -} - func (m *GenesisState) GetDynamicPrecompiles() []string { if m != nil { return m.DynamicPrecompiles @@ -171,33 +162,32 @@ func init() { func init() { proto.RegisterFile("cosmos/evm/erc20/v1/genesis.proto", fileDescriptor_e964b7a0cc2cbbd5) } var fileDescriptor_e964b7a0cc2cbbd5 = []byte{ - // 401 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xcf, 0xaa, 0xd3, 0x40, - 0x14, 0xc6, 0x93, 0xe6, 0xde, 0xd2, 0x4e, 0xba, 0xb0, 0x53, 0x17, 0xa1, 0x85, 0xf4, 0x8f, 0x9b, - 0xe2, 0x22, 0xb1, 0x75, 0x23, 0x82, 0x8a, 0x05, 0x11, 0xbb, 0x2a, 0xd5, 0x95, 0x9b, 0x30, 0x8d, - 0x87, 0x38, 0x98, 0x99, 0x09, 0x33, 0x63, 0xb4, 0x6f, 0xe1, 0x63, 0xb8, 0xf4, 0x31, 0xba, 0xec, - 0x52, 0x10, 0x44, 0xda, 0x85, 0xaf, 0x21, 0x9d, 0x69, 0x69, 0x2a, 0xe5, 0x6e, 0xc2, 0xf0, 0xf1, - 0xfb, 0x7d, 0x39, 0x1c, 0x0e, 0x1a, 0xa6, 0x42, 0x31, 0xa1, 0x62, 0x28, 0x59, 0x0c, 0x32, 0x9d, - 0x3e, 0x8a, 0xcb, 0x49, 0x9c, 0x01, 0x07, 0x45, 0x55, 0x54, 0x48, 0xa1, 0x05, 0xee, 0x58, 0x24, - 0x82, 0x92, 0x45, 0x06, 0x89, 0xca, 0x49, 0xb7, 0x4d, 0x18, 0xe5, 0x22, 0x36, 0x5f, 0xcb, 0x75, - 0xfb, 0xd7, 0xaa, 0xac, 0x60, 0x81, 0xfb, 0x99, 0xc8, 0x84, 0x79, 0xc6, 0x87, 0x97, 0x4d, 0x47, - 0xbf, 0x6a, 0xa8, 0xf5, 0xda, 0xfe, 0xf0, 0xad, 0x26, 0x1a, 0xf0, 0x73, 0x54, 0x2f, 0x88, 0x24, - 0x4c, 0x05, 0xee, 0xc0, 0x1d, 0xfb, 0xd3, 0x5e, 0x74, 0x65, 0x80, 0x68, 0x61, 0x90, 0x59, 0x73, - 0xf3, 0xbb, 0xef, 0x7c, 0xff, 0xfb, 0xe3, 0xa1, 0xbb, 0x3c, 0x5a, 0x78, 0x8e, 0x7c, 0x2d, 0x3e, - 0x01, 0x4f, 0x0a, 0x42, 0xa5, 0x0a, 0x6a, 0x03, 0x6f, 0xec, 0x4f, 0xc3, 0xab, 0x25, 0xef, 0x0e, - 0xdc, 0x82, 0x50, 0x59, 0xed, 0x41, 0xfa, 0x94, 0x2a, 0xfc, 0x06, 0x21, 0x92, 0xe7, 0xe2, 0x0b, - 0xe1, 0x29, 0xa8, 0xc0, 0xbb, 0xa3, 0xea, 0xe5, 0x09, 0xbb, 0xa8, 0x3a, 0xcb, 0xf8, 0x09, 0xc2, - 0x9c, 0x68, 0x5a, 0x42, 0x52, 0x48, 0x48, 0x05, 0x2b, 0x68, 0x0e, 0x2a, 0xb8, 0x19, 0x78, 0xe3, - 0xa6, 0x51, 0x5c, 0xab, 0xb4, 0x2d, 0xb4, 0x38, 0x33, 0xf8, 0x29, 0xea, 0x7c, 0x58, 0x73, 0xc2, - 0x68, 0x7a, 0xa1, 0xde, 0xfe, 0xaf, 0xe2, 0x23, 0x55, 0x71, 0x47, 0x12, 0xd5, 0xed, 0xa6, 0xf0, - 0x10, 0xb5, 0x80, 0x93, 0x55, 0x0e, 0x89, 0x99, 0xd9, 0x2c, 0xb7, 0xb1, 0xf4, 0x6d, 0xf6, 0xea, - 0x10, 0xe1, 0x17, 0xa8, 0x57, 0x80, 0x64, 0x54, 0x29, 0x2a, 0x78, 0x0e, 0x4a, 0x25, 0x12, 0x32, - 0xaa, 0xb4, 0x24, 0x9a, 0x0a, 0x1e, 0xdc, 0x1a, 0xa3, 0x7b, 0x89, 0x2c, 0x2b, 0xc4, 0xfc, 0xa6, - 0x51, 0xbb, 0xe7, 0xcd, 0x9e, 0x6d, 0x76, 0xa1, 0xbb, 0xdd, 0x85, 0xee, 0x9f, 0x5d, 0xe8, 0x7e, - 0xdb, 0x87, 0xce, 0x76, 0x1f, 0x3a, 0x3f, 0xf7, 0xa1, 0xf3, 0xfe, 0x41, 0x46, 0xf5, 0xc7, 0xcf, - 0xab, 0x28, 0x15, 0x2c, 0xae, 0x5c, 0xcb, 0xd7, 0xe3, 0xbd, 0xe8, 0x75, 0x01, 0x6a, 0x55, 0x37, - 0x77, 0xf1, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x94, 0x48, 0x19, 0xb7, 0x9b, 0x02, 0x00, - 0x00, + // 389 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xcf, 0xae, 0x12, 0x31, + 0x18, 0xc5, 0x67, 0x18, 0x20, 0xd0, 0x61, 0x81, 0xc5, 0xc5, 0x04, 0x92, 0xe1, 0x8f, 0x1b, 0xe2, + 0x62, 0x46, 0x70, 0x67, 0xa2, 0x46, 0x12, 0x63, 0x64, 0x45, 0xd0, 0x95, 0x9b, 0x49, 0x19, 0xbf, + 0x8c, 0x8d, 0xd3, 0x76, 0xd2, 0xd6, 0x51, 0xde, 0xc2, 0xb7, 0xd0, 0xa5, 0x8f, 0xc1, 0x92, 0xa5, + 0x2b, 0x63, 0x60, 0x71, 0x5f, 0xe3, 0x86, 0x16, 0x02, 0x24, 0xe4, 0x6e, 0x9a, 0x2f, 0x27, 0xbf, + 0x73, 0xbe, 0xb6, 0x07, 0x0d, 0x53, 0xa1, 0x98, 0x50, 0x31, 0x94, 0x2c, 0x06, 0x99, 0x4e, 0x9f, + 0xc5, 0xe5, 0x24, 0xce, 0x80, 0x83, 0xa2, 0x2a, 0x2a, 0xa4, 0xd0, 0x02, 0x77, 0x2c, 0x12, 0x41, + 0xc9, 0x22, 0x83, 0x44, 0xe5, 0xa4, 0xfb, 0x88, 0x30, 0xca, 0x45, 0x6c, 0x4e, 0xcb, 0x75, 0xfb, + 0xb7, 0xa2, 0xac, 0xc1, 0x02, 0x8f, 0x33, 0x91, 0x09, 0x33, 0xc6, 0x87, 0xc9, 0xaa, 0xa3, 0x5f, + 0x15, 0xd4, 0x7a, 0x67, 0x17, 0x7e, 0xd0, 0x44, 0x03, 0x7e, 0x85, 0xea, 0x05, 0x91, 0x84, 0xa9, + 0xc0, 0x1d, 0xb8, 0x63, 0x7f, 0xda, 0x8b, 0x6e, 0x5c, 0x20, 0x5a, 0x18, 0x64, 0xd6, 0xdc, 0xfc, + 0xeb, 0x3b, 0xbf, 0xef, 0xfe, 0x3c, 0x75, 0x97, 0x47, 0x17, 0x9e, 0x23, 0x5f, 0x8b, 0xaf, 0xc0, + 0x93, 0x82, 0x50, 0xa9, 0x82, 0xca, 0xc0, 0x1b, 0xfb, 0xd3, 0xf0, 0x66, 0xc8, 0xc7, 0x03, 0xb7, + 0x20, 0x54, 0x5e, 0xe6, 0x20, 0x7d, 0x52, 0x15, 0x7e, 0x8f, 0x10, 0xc9, 0x73, 0xf1, 0x9d, 0xf0, + 0x14, 0x54, 0xe0, 0x3d, 0x10, 0xf5, 0xe6, 0x84, 0x5d, 0x45, 0x9d, 0xcd, 0xf8, 0x05, 0xea, 0x7c, + 0x5e, 0x73, 0xc2, 0x68, 0x9a, 0x14, 0x12, 0x52, 0xc1, 0x0a, 0x9a, 0x83, 0x0a, 0x6a, 0x03, 0x6f, + 0xdc, 0x34, 0x1e, 0xd7, 0x7a, 0xf0, 0x91, 0x5a, 0x9c, 0xa1, 0x79, 0xb5, 0x51, 0x6d, 0xd7, 0x46, + 0x12, 0xd5, 0xed, 0xab, 0xf1, 0x10, 0xb5, 0x80, 0x93, 0x55, 0x0e, 0x89, 0xd9, 0x6f, 0x3e, 0xaa, + 0xb1, 0xf4, 0xad, 0xf6, 0xf6, 0x20, 0xe1, 0xd7, 0xa8, 0x57, 0x80, 0x64, 0x54, 0x29, 0x2a, 0x78, + 0x0e, 0x4a, 0x25, 0x12, 0x32, 0xaa, 0xb4, 0x24, 0x9a, 0x0a, 0x1e, 0xd4, 0x8c, 0xa3, 0x7b, 0x8d, + 0x2c, 0x2f, 0x88, 0x79, 0xb5, 0x51, 0x69, 0x7b, 0xb3, 0x97, 0x9b, 0x5d, 0xe8, 0x6e, 0x77, 0xa1, + 0xfb, 0x7f, 0x17, 0xba, 0x3f, 0xf7, 0xa1, 0xb3, 0xdd, 0x87, 0xce, 0xdf, 0x7d, 0xe8, 0x7c, 0x7a, + 0x92, 0x51, 0xfd, 0xe5, 0xdb, 0x2a, 0x4a, 0x05, 0x8b, 0x2f, 0x9a, 0xff, 0x71, 0xec, 0x5e, 0xaf, + 0x0b, 0x50, 0xab, 0xba, 0xe9, 0xf8, 0xf9, 0x7d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x24, 0xc7, 0xe5, + 0x77, 0x67, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -229,15 +219,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x2a } } - if len(m.NativePrecompiles) > 0 { - for iNdEx := len(m.NativePrecompiles) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.NativePrecompiles[iNdEx]) - copy(dAtA[i:], m.NativePrecompiles[iNdEx]) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.NativePrecompiles[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } if len(m.Allowances) > 0 { for iNdEx := len(m.Allowances) - 1; iNdEx >= 0; iNdEx-- { { @@ -353,12 +334,6 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.NativePrecompiles) > 0 { - for _, s := range m.NativePrecompiles { - l = len(s) - n += 1 + l + sovGenesis(uint64(l)) - } - } if len(m.DynamicPrecompiles) > 0 { for _, s := range m.DynamicPrecompiles { l = len(s) @@ -519,38 +494,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NativePrecompiles", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NativePrecompiles = append(m.NativePrecompiles, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DynamicPrecompiles", wireType) diff --git a/x/erc20/types/keys.go b/x/erc20/types/keys.go index 98ae85a0f..a7de98927 100644 --- a/x/erc20/types/keys.go +++ b/x/erc20/types/keys.go @@ -32,7 +32,7 @@ const ( prefixTokenPairByDenom prefixSTRv2Addresses prefixAllowance - prefixNativePrecompiles + prefixNativePrecompiles // reserved prefixDynamicPrecompiles ) @@ -43,7 +43,6 @@ var ( KeyPrefixTokenPairByDenom = []byte{prefixTokenPairByDenom} KeyPrefixSTRv2Addresses = []byte{prefixSTRv2Addresses} KeyPrefixAllowance = []byte{prefixAllowance} - KeyPrefixNativePrecompiles = []byte{prefixNativePrecompiles} KeyPrefixDynamicPrecompiles = []byte{prefixDynamicPrecompiles} ) From 7f89c7f00c3ccd16d598dd3d49bb7c5bac1b1feb Mon Sep 17 00:00:00 2001 From: yihuang Date: Tue, 11 Nov 2025 13:55:56 +0800 Subject: [PATCH 02/11] fix bank tests --- precompiles/bank/query.go | 23 ++- .../ethereum/debug/trace_fallback.go | 1 - server/config/opendb.go | 1 - server/config/opendb_rocksdb.go | 5 +- .../precompiles/bank/test_integration.go | 5 +- .../precompiles/bank/test_setup.go | 6 +- .../precompiles/erc20/test_integration.go | 8 +- testutil/integration/evm/network/setup.go | 4 +- testutil/integration/evm/utils/bank.go | 1 + x/erc20/types/genesis_test.go | 159 ------------------ x/vm/types/config.go | 1 - x/vm/types/config_testing.go | 1 - x/vm/types/denom_config.go | 1 - x/vm/types/denom_config_testing.go | 1 - 14 files changed, 31 insertions(+), 186 deletions(-) diff --git a/precompiles/bank/query.go b/precompiles/bank/query.go index a7fc2e8f0..6a467de9d 100644 --- a/precompiles/bank/query.go +++ b/precompiles/bank/query.go @@ -5,8 +5,10 @@ import ( "math/big" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" sdk "github.com/cosmos/cosmos-sdk/types" + evmtypes "github.com/cosmos/evm/x/vm/types" ) const ( @@ -35,6 +37,7 @@ func (p Precompile) Balances( if err != nil { return nil, fmt.Errorf("error calling account balances in bank precompile: %s", err) } + fmt.Println("Bank Precompile Balances for account:", account.String()) i := 0 balances := make([]Balance, 0) @@ -48,9 +51,13 @@ func (p Precompile) Balances( ctx.GasMeter().ConsumeGas(GasBalances, "ERC-20 extension balances method") } - contractAddress, err := p.erc20Keeper.GetCoinAddress(ctx, coin.Denom) - if err != nil { - return false + // if denom is the evm native denom, use zero address + var contractAddress common.Address + if coin.Denom != evmtypes.GetEVMCoinDenom() { + contractAddress, err = p.erc20Keeper.GetCoinAddress(ctx, coin.Denom) + if err != nil { + return false + } } balances = append(balances, Balance{ @@ -77,6 +84,7 @@ func (p Precompile) TotalSupply( i := 0 totalSupply := make([]Balance, 0) + var err error p.bankKeeper.IterateTotalSupply(ctx, func(coin sdk.Coin) bool { defer func() { i++ }() @@ -86,9 +94,12 @@ func (p Precompile) TotalSupply( ctx.GasMeter().ConsumeGas(GasTotalSupply, "ERC-20 extension totalSupply method") } - contractAddress, err := p.erc20Keeper.GetCoinAddress(ctx, coin.Denom) - if err != nil { - return false + var contractAddress common.Address + if coin.Denom != evmtypes.GetEVMCoinDenom() { + contractAddress, err = p.erc20Keeper.GetCoinAddress(ctx, coin.Denom) + if err != nil { + return false + } } totalSupply = append(totalSupply, Balance{ diff --git a/rpc/namespaces/ethereum/debug/trace_fallback.go b/rpc/namespaces/ethereum/debug/trace_fallback.go index 9100dc46b..db3e8b237 100644 --- a/rpc/namespaces/ethereum/debug/trace_fallback.go +++ b/rpc/namespaces/ethereum/debug/trace_fallback.go @@ -15,7 +15,6 @@ // along with the go-ethereum library. If not, see . //go:build !go1.5 -// +build !go1.5 // no-op implementation of tracing methods for Go < 1.5. diff --git a/server/config/opendb.go b/server/config/opendb.go index af6de8dc3..1d0d99be7 100644 --- a/server/config/opendb.go +++ b/server/config/opendb.go @@ -1,5 +1,4 @@ //go:build !rocksdb -// +build !rocksdb package config diff --git a/server/config/opendb_rocksdb.go b/server/config/opendb_rocksdb.go index f81aa0271..fea6ebb95 100644 --- a/server/config/opendb_rocksdb.go +++ b/server/config/opendb_rocksdb.go @@ -1,5 +1,4 @@ //go:build rocksdb -// +build rocksdb package config @@ -8,9 +7,11 @@ import ( "runtime" "strings" + "github.com/linxGnu/grocksdb" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/server/types" - "github.com/linxGnu/grocksdb" ) // 3G block cache diff --git a/tests/integration/precompiles/bank/test_integration.go b/tests/integration/precompiles/bank/test_integration.go index 987d1f2f3..d173db429 100644 --- a/tests/integration/precompiles/bank/test_integration.go +++ b/tests/integration/precompiles/bank/test_integration.go @@ -1,6 +1,7 @@ package bank import ( + "fmt" "math/big" "testing" @@ -157,6 +158,7 @@ func TestIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ... xmplSupply := is.network.App.GetBankKeeper().GetSupply(is.network.GetContext(), is.tokenDenom) xmplTotalSupply = new(big.Int).Set(xmplSupply.Amount.BigInt()) + fmt.Println("XMPL total supply:", xmplTotalSupply.String(), cosmosEVMTotalSupply.String()) }) Context("Direct precompile queries", func() { @@ -247,13 +249,13 @@ func TestIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ... err = is.precompile.UnpackIntoInterface(&balances, bank2.TotalSupplyMethod, ethRes.Ret) Expect(err).ToNot(HaveOccurred(), "failed to unpack balances") + fmt.Println("Total supply from precompile:", balances[0].Amount.String(), balances[1].Amount.String()) Expect(balances[0].Amount.String()).To(Equal(cosmosEVMTotalSupply.String())) Expect(balances[1].Amount.String()).To(Equal(xmplTotalSupply.String())) }) }) Context("supplyOf query", func() { - It("should return the supply of XMPL", func() { queryArgs, supplyArgs := getTxAndCallArgs(directCall, contractData, bank2.SupplyOfMethod, is.xmplAddr) _, ethRes, err := is.factory.CallContractAndCheckLogs(sender.Priv, queryArgs, supplyArgs, passCheck) @@ -386,7 +388,6 @@ func TestIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ... }) Context("supplyOf query", func() { - It("should return the supply of XMPL", func() { queryArgs, supplyArgs := getTxAndCallArgs(contractCall, contractData, SupplyOfFunction, is.xmplAddr) _, ethRes, err := is.factory.CallContractAndCheckLogs(sender.Priv, queryArgs, supplyArgs, passCheck) diff --git a/tests/integration/precompiles/bank/test_setup.go b/tests/integration/precompiles/bank/test_setup.go index ebfdeccaa..bd84f01ca 100644 --- a/tests/integration/precompiles/bank/test_setup.go +++ b/tests/integration/precompiles/bank/test_setup.go @@ -22,9 +22,9 @@ import ( type PrecompileTestSuite struct { suite.Suite - create network.CreateEvmApp - bondDenom, tokenDenom string - cosmosEVMAddr, xmplAddr common.Address + create network.CreateEvmApp + bondDenom, tokenDenom string + xmplAddr common.Address // tokenDenom is the specific token denomination used in testing the ERC20 precompile. // This denomination is used to instantiate the precompile. diff --git a/tests/integration/precompiles/erc20/test_integration.go b/tests/integration/precompiles/erc20/test_integration.go index 50b0d7406..69c6080e7 100644 --- a/tests/integration/precompiles/erc20/test_integration.go +++ b/tests/integration/precompiles/erc20/test_integration.go @@ -93,11 +93,7 @@ func (is *IntegrationTestSuite) SetupTest() { is.precompileTwo = is.setupERC20Precompile(is.tokenDenomTwo, erc20Gen.TokenPairs) } -var ( - revertContractAddr common.Address - gasLimit = uint64(5000000) - gasPrice = big.NewInt(800_000_000) -) +var gasPrice = big.NewInt(800_000_000) func TestIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options ...network.ConfigOption) { is = NewIntegrationTestSuite(create, options...) @@ -249,7 +245,7 @@ func TestIntegrationTestSuite(t *testing.T, create network.CreateEvmApp, options execRevertedCheck = failCheck.WithErrContains("execution reverted") passCheck = failCheck.WithExpPass(true) - revertContractAddr, err = is.factory.DeployContract( + _, err = is.factory.DeployContract( sender.Priv, evmtypes.EvmTxArgs{}, // NOTE: passing empty struct to use default values testutiltypes.ContractDeploymentData{ diff --git a/testutil/integration/evm/network/setup.go b/testutil/integration/evm/network/setup.go index 8d019ae89..86cee8be4 100644 --- a/testutil/integration/evm/network/setup.go +++ b/testutil/integration/evm/network/setup.go @@ -463,7 +463,7 @@ func setDefaultMintGenesisState(cosmosEVMApp evm.EvmApp, genesisState testutil.G return genesisState } -func setDefaultErc20GenesisState(cosmosEVMApp evm.EvmApp, evmChainID uint64, genesisState testutil.GenesisState) testutil.GenesisState { +func setDefaultErc20GenesisState(cosmosEVMApp evm.EvmApp, genesisState testutil.GenesisState) testutil.GenesisState { // NOTE: here we are using the setup from the example chain erc20Gen := newErc20GenesisState() genesisState[erc20types.ModuleName] = cosmosEVMApp.AppCodec().MustMarshalJSON(erc20Gen) @@ -507,7 +507,7 @@ func newDefaultGenesisState(cosmosEVMApp evm.EvmApp, evmChainID uint64, params d genesisState = setDefaultFeeMarketGenesisState(cosmosEVMApp, genesisState, params.feemarket) genesisState = setDefaultSlashingGenesisState(cosmosEVMApp, genesisState, params.slashing) genesisState = setDefaultMintGenesisState(cosmosEVMApp, genesisState, params.mint) - genesisState = setDefaultErc20GenesisState(cosmosEVMApp, evmChainID, genesisState) + genesisState = setDefaultErc20GenesisState(cosmosEVMApp, genesisState) genesisState = setDefaultVMGenesisState(cosmosEVMApp, evmChainID, genesisState) return genesisState diff --git a/testutil/integration/evm/utils/bank.go b/testutil/integration/evm/utils/bank.go index edd91f31c..a28ed64d6 100644 --- a/testutil/integration/evm/utils/bank.go +++ b/testutil/integration/evm/utils/bank.go @@ -17,6 +17,7 @@ import ( // FundAccountWithBaseDenom funds the given account with the given amount of the network's // base denomination. func FundAccountWithBaseDenom(tf cmnfactory.CoreTxFactory, nw cmnnet.Network, sender keyring.Key, receiver sdk.AccAddress, amount math.Int) error { + fmt.Println("Funding account:", receiver.String(), "with amount:", amount.String(), nw.GetBaseDenom()) return tf.FundAccount(sender, receiver, sdk.NewCoins(sdk.NewCoin(nw.GetBaseDenom(), amount))) } diff --git a/x/erc20/types/genesis_test.go b/x/erc20/types/genesis_test.go index 10abb1373..b9a8b45c4 100644 --- a/x/erc20/types/genesis_test.go +++ b/x/erc20/types/genesis_test.go @@ -7,8 +7,6 @@ import ( testconstants "github.com/cosmos/evm/testutil/constants" "github.com/cosmos/evm/x/erc20/types" - - "cosmossdk.io/math" ) type GenesisTestSuite struct { @@ -59,11 +57,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Denom: "usdt", Enabled: true, }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, }, Allowances: testconstants.ExampleAllowances, }, @@ -84,11 +77,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Denom: "usdt", Enabled: true, }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, }, Allowances: testconstants.ExampleAllowances, }, @@ -109,11 +97,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Denom: "usdt2", Enabled: true, }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, }, Allowances: testconstants.ExampleAllowances, }, @@ -134,11 +117,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Denom: "usdt", Enabled: true, }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, }, Allowances: testconstants.ExampleAllowances, }, @@ -154,11 +132,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Denom: "bad", Enabled: true, }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, }, Allowances: testconstants.ExampleAllowances, }, @@ -179,138 +152,6 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { }, expPass: false, }, - { - name: "invalid genesis - duplicated allowances", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: testconstants.ExampleTokenPairs, - Allowances: []types.Allowance{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: testconstants.ExampleEvmAddressAlice, - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(100), - }, - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: testconstants.ExampleEvmAddressAlice, - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(100), - }, - }, - }, - expPass: false, - }, - { - name: "invalid genesis - invalid allowance erc20 address", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: []types.TokenPair{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, - }, - Allowances: []types.Allowance{ - { - Erc20Address: "bad", - Owner: testconstants.ExampleEvmAddressAlice, - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(-1), - }, - }, - }, - expPass: false, - }, - { - name: "invalid genesis - invalid allowance owner", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: []types.TokenPair{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, - }, - Allowances: []types.Allowance{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: "bad", - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(-1), - }, - }, - }, - expPass: false, - }, - { - name: "invalid genesis - invalid allowance spender", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: []types.TokenPair{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, - }, - Allowances: []types.Allowance{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: testconstants.ExampleEvmAddressAlice, - Spender: "bad", - Value: math.NewInt(-1), - }, - }, - }, - expPass: false, - }, - { - name: "invalid genesis - invalid allowance value", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: []types.TokenPair{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, - }, - Allowances: []types.Allowance{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: testconstants.ExampleEvmAddressAlice, - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(0), - }, - }, - }, - expPass: false, - }, - { - name: "invalid genesis - invalid allowance value", - genState: &types.GenesisState{ - Params: types.DefaultParams(), - TokenPairs: []types.TokenPair{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Denom: testconstants.ExampleAttoDenom, - Enabled: true, - }, - }, - Allowances: []types.Allowance{ - { - Erc20Address: testconstants.WEVMOSContractMainnet, - Owner: testconstants.ExampleEvmAddressAlice, - Spender: testconstants.ExampleEvmAddressBob, - Value: math.NewInt(-1), - }, - }, - }, - expPass: false, - }, { // Voting period cant be zero name: "empty genesis", diff --git a/x/vm/types/config.go b/x/vm/types/config.go index 4fc952a76..a8bbb9f18 100644 --- a/x/vm/types/config.go +++ b/x/vm/types/config.go @@ -3,7 +3,6 @@ // Its primary purpose is to be used during application initialization. //go:build !test -// +build !test package types diff --git a/x/vm/types/config_testing.go b/x/vm/types/config_testing.go index c84440aca..d955a181e 100644 --- a/x/vm/types/config_testing.go +++ b/x/vm/types/config_testing.go @@ -3,7 +3,6 @@ // Its primary purpose is to be used during application initialization. //go:build test -// +build test package types diff --git a/x/vm/types/denom_config.go b/x/vm/types/denom_config.go index ca731fc3a..8fb090edc 100644 --- a/x/vm/types/denom_config.go +++ b/x/vm/types/denom_config.go @@ -3,7 +3,6 @@ // Its primary purpose is to be used during application initialization. //go:build !test -// +build !test package types diff --git a/x/vm/types/denom_config_testing.go b/x/vm/types/denom_config_testing.go index fede6ffdb..233f9a1e7 100644 --- a/x/vm/types/denom_config_testing.go +++ b/x/vm/types/denom_config_testing.go @@ -3,7 +3,6 @@ // Its primary purpose is to be used during application initialization. //go:build test -// +build test package types From 77659103e4bda8d5537d17704768654eb8e3e84a Mon Sep 17 00:00:00 2001 From: yihuang Date: Tue, 11 Nov 2025 14:49:24 +0800 Subject: [PATCH 03/11] fix tests --- precompiles/bank/query.go | 3 ++- tests/integration/precompiles/bank/test_query.go | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/precompiles/bank/query.go b/precompiles/bank/query.go index 6a467de9d..1450004f0 100644 --- a/precompiles/bank/query.go +++ b/precompiles/bank/query.go @@ -7,8 +7,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - sdk "github.com/cosmos/cosmos-sdk/types" evmtypes "github.com/cosmos/evm/x/vm/types" + + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( diff --git a/tests/integration/precompiles/bank/test_query.go b/tests/integration/precompiles/bank/test_query.go index 5b7623a4c..70af7e0de 100644 --- a/tests/integration/precompiles/bank/test_query.go +++ b/tests/integration/precompiles/bank/test_query.go @@ -71,6 +71,10 @@ func (s *PrecompileTestSuite) TestBalances() { "", func(xmplAddr common.Address) []bank.Balance { return []bank.Balance{ + { + ContractAddress: common.Address{}, + Amount: network.PrefundedAccountInitialBalance.BigInt(), + }, { ContractAddress: xmplAddr, Amount: network.PrefundedAccountInitialBalance.BigInt(), @@ -90,6 +94,9 @@ func (s *PrecompileTestSuite) TestBalances() { "", func(xmplAddr common.Address) []bank.Balance { return []bank.Balance{{ + ContractAddress: common.Address{}, + Amount: network.PrefundedAccountInitialBalance.BigInt(), + }, { ContractAddress: xmplAddr, Amount: network.PrefundedAccountInitialBalance.Add(math.NewInt(1e18)).BigInt(), }} From f6c58edabab4be28c404ec378fb0a1d2ef967085 Mon Sep 17 00:00:00 2001 From: yihuang Date: Tue, 11 Nov 2025 16:15:16 +0800 Subject: [PATCH 04/11] fix test --- tests/integration/x/erc20/test_grpc_query.go | 2 +- .../integration/x/precisebank/test_genesis.go | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/tests/integration/x/erc20/test_grpc_query.go b/tests/integration/x/erc20/test_grpc_query.go index 138614b4b..a7bbb3f5b 100644 --- a/tests/integration/x/erc20/test_grpc_query.go +++ b/tests/integration/x/erc20/test_grpc_query.go @@ -30,7 +30,7 @@ func (s *KeeperTestSuite) TestTokenPairs() { req = &types.QueryTokenPairsRequest{} expRes = &types.QueryTokenPairsResponse{ Pagination: &query.PageResponse{ - Total: 1, + Total: 0, }, TokenPairs: testconstants.ExampleTokenPairs, } diff --git a/tests/integration/x/precisebank/test_genesis.go b/tests/integration/x/precisebank/test_genesis.go index 02f01e130..83c2026c0 100644 --- a/tests/integration/x/precisebank/test_genesis.go +++ b/tests/integration/x/precisebank/test_genesis.go @@ -70,12 +70,11 @@ func (s *GenesisTestSuite) TestInitGenesis() { { "valid - module balance matches non-zero amount", func() { - // The network setup creates an initial balance of 1, so we need to mint 1 more - // to get to the expected amount of 2 for this test case + // We need to mint 2 to get to the expected amount of 2 for this test case err := s.network.App.GetBankKeeper().MintCoins( s.network.GetContext(), types.ModuleName, - sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), + sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(2))), ) s.Require().NoError(err) }, @@ -105,14 +104,6 @@ func (s *GenesisTestSuite) TestInitGenesis() { { "invalid - module balance insufficient", func() { - // The network setup creates an initial balance of 1, so we need to burn that - // to get to 0 balance for this test case - err := s.network.App.GetBankKeeper().BurnCoins( - s.network.GetContext(), - types.ModuleName, - sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), - ) - s.Require().NoError(err) }, types.NewGenesisState( types.FractionalBalances{ @@ -128,12 +119,11 @@ func (s *GenesisTestSuite) TestInitGenesis() { { "invalid - module balance excessive", func() { - // The network setup creates an initial balance of 1, so we need to mint 99 more - // to get to 100 total balance for this test case + // We need to mint 100 to get to 100 total balance for this test case err := s.network.App.GetBankKeeper().MintCoins( s.network.GetContext(), types.ModuleName, - sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(99))), + sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(100))), ) s.Require().NoError(err) }, From 2a792c6377eccffdb648e721f2c52d78911e7df2 Mon Sep 17 00:00:00 2001 From: yihuang Date: Tue, 11 Nov 2025 20:49:55 +0800 Subject: [PATCH 05/11] fix test --- tests/integration/precompiles/bank/test_query.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/integration/precompiles/bank/test_query.go b/tests/integration/precompiles/bank/test_query.go index 70af7e0de..dd9471de9 100644 --- a/tests/integration/precompiles/bank/test_query.go +++ b/tests/integration/precompiles/bank/test_query.go @@ -136,6 +136,7 @@ func (s *PrecompileTestSuite) TestTotalSupply() { totSupplRes, err := s.grpcHandler.GetTotalSupply() s.Require().NoError(err) xmplTotalSupply := totSupplRes.Supply.AmountOf(s.tokenDenom) + cosmosTotalSupply := totSupplRes.Supply.AmountOf(s.bondDenom) testcases := []struct { name string @@ -148,10 +149,15 @@ func (s *PrecompileTestSuite) TestTotalSupply() { ctx = s.mintAndSendXMPLCoin(ctx, s.keyring.GetAccAddr(0), math.NewInt(1e18)) }, func(xmplAddr common.Address) []bank.Balance { - return []bank.Balance{{ - ContractAddress: xmplAddr, - Amount: xmplTotalSupply.Add(math.NewInt(1e18)).BigInt(), - }} + return []bank.Balance{ + { + ContractAddress: common.Address{}, + Amount: cosmosTotalSupply.BigInt(), + }, + { + ContractAddress: xmplAddr, + Amount: xmplTotalSupply.Add(math.NewInt(1e18)).BigInt(), + }} }, }, } From 4b09e4dda9a74b4eb475125800019de8224f3efc Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 13 Nov 2025 09:56:02 +0800 Subject: [PATCH 06/11] fix test --- tests/integration/x/vm/test_genesis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/x/vm/test_genesis.go b/tests/integration/x/vm/test_genesis.go index 06b266f54..ab2297a8d 100644 --- a/tests/integration/x/vm/test_genesis.go +++ b/tests/integration/x/vm/test_genesis.go @@ -243,7 +243,7 @@ func (s *GenesisTestSuite) TestExportGenesis() { genState := vm.ExportGenesis(s.network.GetContext(), s.network.App.GetEVMKeeper()) // Exported accounts 4 default preinstalls - s.Require().Len(genState.Accounts, 8) + s.Require().Len(genState.Accounts, 7) addrs := make([]string, len(genState.Accounts)) for i, acct := range genState.Accounts { From b903b47c8d51c331e3245574b914139af536d1a7 Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 13 Nov 2025 15:48:46 +0800 Subject: [PATCH 07/11] fix tests --- tests/integration/x/erc20/test_integration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/x/erc20/test_integration.go b/tests/integration/x/erc20/test_integration.go index c34c8d392..80bd5f078 100644 --- a/tests/integration/x/erc20/test_integration.go +++ b/tests/integration/x/erc20/test_integration.go @@ -103,7 +103,7 @@ func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmAp Expect(err).To(BeNil()) tokenPairs := res.TokenPairs - Expect(tokenPairs).To(HaveLen(2)) + Expect(tokenPairs).To(HaveLen(1)) for i, tokenPair := range tokenPairs { if tokenPair.Erc20Address == contract.Hex() { Expect(tokenPairs[i].ContractOwner).To(Equal(types.OWNER_EXTERNAL)) @@ -132,7 +132,7 @@ func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmAp Expect(err).To(BeNil()) tokenPairs := res.TokenPairs - Expect(tokenPairs).To(HaveLen(3)) + Expect(tokenPairs).To(HaveLen(2)) for i, tokenPair := range tokenPairs { if tokenPair.Erc20Address == contract2.Hex() { Expect(tokenPairs[i].ContractOwner).To(Equal(types.OWNER_EXTERNAL)) From 39734f20e8b7808a44cbbea39f732405ba83f5c1 Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 13 Nov 2025 18:14:30 +0800 Subject: [PATCH 08/11] fix tests --- .../integration/x/precisebank/test_genesis.go | 20 ++----------------- .../x/precisebank/test_view_integration.go | 4 ++-- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/tests/integration/x/precisebank/test_genesis.go b/tests/integration/x/precisebank/test_genesis.go index 83c2026c0..3e1a9c670 100644 --- a/tests/integration/x/precisebank/test_genesis.go +++ b/tests/integration/x/precisebank/test_genesis.go @@ -224,15 +224,7 @@ func (s *GenesisTestSuite) TestExportGenesis() { { "balances, no remainder", func() *types.GenesisState { - // Burn the initial balance created by network setup, then mint the expected amount - err := s.network.App.GetBankKeeper().BurnCoins( - s.network.GetContext(), - types.ModuleName, - sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), - ) - s.Require().NoError(err) - - err = s.network.App.GetBankKeeper().MintCoins( + err := s.network.App.GetBankKeeper().MintCoins( s.network.GetContext(), types.ModuleName, sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), @@ -251,15 +243,7 @@ func (s *GenesisTestSuite) TestExportGenesis() { { "balances, remainder", func() *types.GenesisState { - // Burn the initial balance created by network setup, then mint the expected amount - err := s.network.App.GetBankKeeper().BurnCoins( - s.network.GetContext(), - types.ModuleName, - sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), - ) - s.Require().NoError(err) - - err = s.network.App.GetBankKeeper().MintCoins( + err := s.network.App.GetBankKeeper().MintCoins( s.network.GetContext(), types.ModuleName, sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom(), sdkmath.NewInt(1))), diff --git a/tests/integration/x/precisebank/test_view_integration.go b/tests/integration/x/precisebank/test_view_integration.go index 48c877ef2..9aedfdff0 100644 --- a/tests/integration/x/precisebank/test_view_integration.go +++ b/tests/integration/x/precisebank/test_view_integration.go @@ -139,7 +139,7 @@ func (s *KeeperIntegrationTestSuite) TestKeeperHiddenReserve() { // Check underlying x/bank balance for reserve reserveIntCoin := s.network.App.GetBankKeeper().GetBalance(s.network.GetContext(), moduleAddr, types.IntegerCoinDenom()) s.Require().Equal( - sdkmath.NewInt(2), // Network setup creates 1, test mints 1 more = 2 total + sdkmath.NewInt(1), // test mints 1 more reserveIntCoin.Amount, "reserve should hold 2 integer coins (1 from network setup + 1 from test mint)", ) @@ -160,7 +160,7 @@ func (s *KeeperIntegrationTestSuite) TestKeeperHiddenReserve() { "reserve account - visible integer denom", moduleAddr, types.IntegerCoinDenom(), - sdkmath.NewInt(2), // Network setup creates 1, test mints 1 more = 2 total + sdkmath.NewInt(1), }, { "user account - visible extended denom", From 1e90043a626c08608b510e8ee224127a2c156a93 Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 13 Nov 2025 21:05:13 +0800 Subject: [PATCH 09/11] fix lint --- tests/integration/precompiles/bank/test_query.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/integration/precompiles/bank/test_query.go b/tests/integration/precompiles/bank/test_query.go index dd9471de9..c971b359a 100644 --- a/tests/integration/precompiles/bank/test_query.go +++ b/tests/integration/precompiles/bank/test_query.go @@ -157,7 +157,8 @@ func (s *PrecompileTestSuite) TestTotalSupply() { { ContractAddress: xmplAddr, Amount: xmplTotalSupply.Add(math.NewInt(1e18)).BigInt(), - }} + }, + } }, }, } From bff59754ee4a69162fa47ecac4a339e6d8df08d5 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 14 Nov 2025 09:26:25 +0800 Subject: [PATCH 10/11] remove native precompile from scripts --- local_node.sh | 3 --- tests/jsonrpc/scripts/evmd/start-evmd.sh | 4 ---- 2 files changed, 7 deletions(-) diff --git a/local_node.sh b/local_node.sh index c94f59993..3319cd5a7 100755 --- a/local_node.sh +++ b/local_node.sh @@ -244,9 +244,6 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state.erc20.native_precompiles=["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.app_state.erc20.token_pairs=[{contract_owner:1,erc20_address:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",denom:"atest",enabled:true}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" - jq '.consensus.params.block.max_gas="10000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" # Change proposal periods diff --git a/tests/jsonrpc/scripts/evmd/start-evmd.sh b/tests/jsonrpc/scripts/evmd/start-evmd.sh index 4d7f5286a..056b41e4a 100755 --- a/tests/jsonrpc/scripts/evmd/start-evmd.sh +++ b/tests/jsonrpc/scripts/evmd/start-evmd.sh @@ -108,10 +108,6 @@ jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x000000000000000 # Set EVM config jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$DATA_DIR/config/genesis.json" > "$DATA_DIR/config/tmp_genesis.json" && mv "$DATA_DIR/config/tmp_genesis.json" "$DATA_DIR/config/genesis.json" -# Enable native denomination as a token pair for STRv2 -jq '.app_state.erc20.native_precompiles=["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' "$DATA_DIR/config/genesis.json" > "$DATA_DIR/config/tmp_genesis.json" && mv "$DATA_DIR/config/tmp_genesis.json" "$DATA_DIR/config/genesis.json" -jq '.app_state.erc20.token_pairs=[{contract_owner:1,erc20_address:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",denom:"atest",enabled:true}]' "$DATA_DIR/config/genesis.json" > "$DATA_DIR/config/tmp_genesis.json" && mv "$DATA_DIR/config/tmp_genesis.json" "$DATA_DIR/config/genesis.json" - # Set gas limit in genesis jq '.consensus.params.block.max_gas="10000000"' "$DATA_DIR/config/genesis.json" > "$DATA_DIR/config/tmp_genesis.json" && mv "$DATA_DIR/config/tmp_genesis.json" "$DATA_DIR/config/genesis.json" From 4afd8b1770bb448269ccbbffa308bfca77c53b25 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 14 Nov 2025 14:57:20 +0800 Subject: [PATCH 11/11] fix solidity test --- .../suites/precompiles/test/3_erc20/erc20.js | 109 ------------------ .../suites/precompiles/test/bank/bank.js | 8 +- 2 files changed, 4 insertions(+), 113 deletions(-) delete mode 100644 tests/solidity/suites/precompiles/test/3_erc20/erc20.js diff --git a/tests/solidity/suites/precompiles/test/3_erc20/erc20.js b/tests/solidity/suites/precompiles/test/3_erc20/erc20.js deleted file mode 100644 index daedebc2b..000000000 --- a/tests/solidity/suites/precompiles/test/3_erc20/erc20.js +++ /dev/null @@ -1,109 +0,0 @@ -const { expect } = require('chai') -const hre = require('hardhat') -const { findEvent, waitWithTimeout, RETRY_DELAY_FUNC} = require('../common') - -describe('ERC20 Precompile', function () { - let erc20, owner, spender, recipient - const GAS_LIMIT = 1_000_000 // skip gas estimation for simplicity - - before(async function () { - [owner, spender, recipient] = await hre.ethers.getSigners() - erc20 = await hre.ethers.getContractAt( - 'IERC20Metadata', - '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' - ) - }) - - it('should return the name', async function () { - const name = await erc20.name() - expect(name).to.contain('Test Token') - }) - - it('should return the symbol', async function () { - const symbol = await erc20.symbol() - expect(symbol).to.contain('TEST') - }) - - it('should return the decimals', async function () { - const decimals = await erc20.decimals() - expect(decimals).to.equal(18) - }) - - it('should return the total supply', async function () { - const totalSupply = await erc20.totalSupply() - expect(totalSupply).to.be.gt(0n) - }) - - it('should return the balance of the owner', async function () { - const balance = await erc20.balanceOf(owner.address) - expect(balance).to.be.gt(0n) - }) - - it('should return zero allowance by default', async function () { - const allowance = await erc20.allowance(owner.address, spender.address) - expect(allowance).to.equal(0n) - }) - - it('should transfer tokens', async function () { - const amount = hre.ethers.parseEther('1') - const prev = await erc20.balanceOf(spender.address) - - const tx = await erc20.connect(owner).transfer(spender.address, amount) - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC) - - const transferEvent = findEvent(receipt.logs, erc20.interface, 'Transfer') - expect(transferEvent, 'Transfer event must be emitted').to.exist - expect(transferEvent.args.from).to.equal(owner.address) - expect(transferEvent.args.to).to.equal(spender.address) - expect(transferEvent.args.value).to.equal(amount) - - const after = await erc20.balanceOf(spender.address) - expect(after - prev).to.equal(amount) - }) - - it('should transfer tokens using transferFrom', async function () { - const amount = hre.ethers.parseEther('0.5') - - // owner gives spender permission to move amount - const approvalTx = await erc20. - connect(owner) - .approve(spender.address, amount, {gasLimit: GAS_LIMIT}) - const approvalReceipt = await waitWithTimeout(approvalTx, 20000, RETRY_DELAY_FUNC) - console.log(`Approval transaction hash: ${approvalTx.hash}`) - - const approvalEvent = findEvent(approvalReceipt.logs, erc20.interface, 'Approval') - expect(approvalEvent, 'Approval event must be emitted').to.exist - expect(approvalEvent.args.owner).to.equal(owner.address) - expect(approvalEvent.args.spender).to.equal(spender.address) - expect(approvalEvent.args.value).to.equal(amount) - - // record pre-transfer balances and allowance - const prevBalance = await erc20.balanceOf(recipient.address) - const prevAllowance = await erc20.allowance(owner.address, spender.address) - console.log(`Pre-transfer balance of recipient: ${prevBalance}`) - console.log(`Pre-transfer allowance of spender: ${prevAllowance}`) - - // spender pulls from owner → recipient - const tx = await erc20 - .connect(spender) - .transferFrom(owner.address, recipient.address, amount, {gasLimit: GAS_LIMIT}) - const receipt = await waitWithTimeout(tx, 20000, RETRY_DELAY_FUNC) - console.log(`Transfer transaction hash: ${tx.hash}`) - - const transferEvent = findEvent(receipt.logs, erc20.interface, 'Transfer') - expect(transferEvent, 'Transfer event must be emitted').to.exist - expect(transferEvent.args.from).to.equal(owner.address) - expect(transferEvent.args.to).to.equal(recipient.address) - expect(transferEvent.args.value).to.equal(amount) - - // post-transfer checks - const afterBalance = await erc20.balanceOf(recipient.address) - const afterAllowance = await erc20.allowance(owner.address, spender.address) - - // recipient should gain exactly `amount` - expect(afterBalance - prevBalance).to.equal(amount) - - // allowance should have decreased by `amount` - expect(afterAllowance).to.equal(prevAllowance - amount) - }) -}) diff --git a/tests/solidity/suites/precompiles/test/bank/bank.js b/tests/solidity/suites/precompiles/test/bank/bank.js index 664c587e5..f38cef72e 100644 --- a/tests/solidity/suites/precompiles/test/bank/bank.js +++ b/tests/solidity/suites/precompiles/test/bank/bank.js @@ -13,7 +13,7 @@ describe('Bank', function () { .staticCall(signer.address); console.log('Balances:', balances); expect(balances.length).to.be.greaterThan(0); - expect(balances[0][0]).to.be.eq('0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') + expect(balances[0][0]).to.be.eq('0x0000000000000000000000000000000000000000') expect(balances[0].amount).to.be.a('bigint'); }); @@ -32,9 +32,9 @@ describe('Bank', function () { 'IBank', '0x0000000000000000000000000000000000000804' ); - const wevmos = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - const supply = await bank.getFunction('supplyOf').staticCall(wevmos); + const native = '0x0000000000000000000000000000000000000000'; + const supply = await bank.getFunction('supplyOf').staticCall(native); console.log('Native token supply:', supply.toString()); expect(supply).to.be.a('bigint'); }); -}); \ No newline at end of file +});