diff --git a/proto/umee/uibc/v1/genesis.proto b/proto/umee/uibc/v1/genesis.proto index 7b393bb6fe..f9e50cf2c4 100644 --- a/proto/umee/uibc/v1/genesis.proto +++ b/proto/umee/uibc/v1/genesis.proto @@ -17,7 +17,6 @@ message GenesisState { (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false ]; - // total_outflow_sum defines the total outflow sum of ibc-transfer in USD. string total_outflow_sum = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", @@ -31,4 +30,15 @@ message GenesisState { (gogoproto.jsontag) = "quota_duration,omitempty", (gogoproto.moretags) = "yaml:\"quota_expires\"" ]; + // inflows defines inflow amount of denoms + repeated cosmos.base.v1beta1.DecCoin inflows = 5 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; + // total_inflow_sum defines the total inflow sum of ibc-transfer in USD. + string total_inflow_sum = 6 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; } diff --git a/proto/umee/uibc/v1/quota.proto b/proto/umee/uibc/v1/quota.proto index 72fd7df2d5..a72d50f8d0 100644 --- a/proto/umee/uibc/v1/quota.proto +++ b/proto/umee/uibc/v1/quota.proto @@ -30,6 +30,12 @@ message Params { (gogoproto.jsontag) = "quota_duration,omitempty", (gogoproto.moretags) = "yaml:\"quota_duration\"" ]; + // total_inflow_quota defines the total inflow limit of ibc-transfer in USD + string total_inflow_quota = 5 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; } // IBCTransferStatus status of ibc-transfer quota check for inflow and outflow diff --git a/x/uibc/genesis.pb.go b/x/uibc/genesis.pb.go index 4c70dfdfe4..037e5411d9 100644 --- a/x/uibc/genesis.pb.go +++ b/x/uibc/genesis.pb.go @@ -38,6 +38,10 @@ type GenesisState struct { TotalOutflowSum github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=total_outflow_sum,json=totalOutflowSum,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_outflow_sum"` // quota_expires defines quota expire time (as unix timestamp) for ibc-transfer denom. QuotaExpires time.Time `protobuf:"bytes,4,opt,name=quota_expires,json=quotaExpires,proto3,stdtime" json:"quota_duration,omitempty" yaml:"quota_expires"` + // inflows defines inflow amount of denoms + Inflows github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,5,rep,name=inflows,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"inflows"` + // total_inflow_sum defines the total inflow sum of ibc-transfer in USD. + TotalInflowSum github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=total_inflow_sum,json=totalInflowSum,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_inflow_sum"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -80,35 +84,38 @@ func init() { func init() { proto.RegisterFile("umee/uibc/v1/genesis.proto", fileDescriptor_0196ecf2d08401fb) } var fileDescriptor_0196ecf2d08401fb = []byte{ - // 445 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x51, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xb6, 0x49, 0x55, 0x81, 0x1b, 0x84, 0xb0, 0x32, 0x98, 0x08, 0xd9, 0x51, 0x06, 0x14, 0x09, - 0x72, 0xa7, 0xa4, 0x12, 0x03, 0x62, 0x0a, 0x41, 0x8c, 0xa0, 0x94, 0x89, 0x25, 0x3a, 0xbb, 0x57, - 0xf7, 0xd4, 0x9c, 0x9f, 0xf1, 0xbd, 0x4b, 0x9b, 0x81, 0xff, 0xd0, 0x99, 0x9f, 0xc0, 0xcc, 0x8f, - 0xc8, 0x58, 0x31, 0x21, 0x06, 0x17, 0x92, 0x8d, 0x91, 0x5f, 0x80, 0x7c, 0x77, 0x41, 0xed, 0xc6, - 0x64, 0x7f, 0xef, 0x7b, 0xef, 0xbb, 0xef, 0x7d, 0x2f, 0xe8, 0x6a, 0xc9, 0x39, 0xd5, 0x22, 0xcd, - 0xe8, 0x72, 0x44, 0x73, 0x5e, 0x70, 0x25, 0x14, 0x29, 0x2b, 0x40, 0x08, 0xdb, 0x0d, 0x47, 0x1a, - 0x8e, 0x2c, 0x47, 0xdd, 0x4e, 0x0e, 0x39, 0x18, 0x82, 0x36, 0x7f, 0xb6, 0xa7, 0xfb, 0x28, 0x03, - 0x25, 0x41, 0xcd, 0x2d, 0x61, 0x81, 0xa3, 0x62, 0x8b, 0x68, 0xca, 0x14, 0xa7, 0xcb, 0x51, 0xca, - 0x91, 0x8d, 0x68, 0x06, 0xa2, 0x70, 0x7c, 0x92, 0x03, 0xe4, 0x0b, 0x4e, 0x0d, 0x4a, 0xf5, 0x09, - 0x45, 0x21, 0xb9, 0x42, 0x26, 0x4b, 0xd7, 0x10, 0xdd, 0xf2, 0xf6, 0x51, 0x03, 0x32, 0xcb, 0xf4, - 0x3f, 0xb7, 0x82, 0xf6, 0x1b, 0xeb, 0xf5, 0x08, 0x19, 0xf2, 0x70, 0x1c, 0xec, 0x97, 0xac, 0x62, - 0x52, 0x45, 0x7e, 0xcf, 0x1f, 0x1c, 0x8c, 0x3b, 0xe4, 0xa6, 0x77, 0xf2, 0xce, 0x70, 0x93, 0xbd, - 0x75, 0x9d, 0x78, 0x33, 0xd7, 0x19, 0xca, 0xe0, 0x2e, 0x68, 0x3c, 0x59, 0xc0, 0xb9, 0x8a, 0xee, - 0xf4, 0x5a, 0x83, 0x83, 0xf1, 0x63, 0xe2, 0x16, 0x68, 0x2c, 0x13, 0x67, 0x99, 0x4c, 0x79, 0xf6, - 0x0a, 0x44, 0x31, 0x39, 0x6c, 0xa6, 0xbf, 0x5c, 0x27, 0x4f, 0x73, 0x81, 0xa7, 0x3a, 0x25, 0x19, - 0x48, 0xb7, 0xb0, 0xfb, 0x0c, 0xd5, 0xf1, 0x19, 0xc5, 0x55, 0xc9, 0xd5, 0x6e, 0x46, 0xcd, 0xfe, - 0x3d, 0x11, 0x9e, 0x06, 0x0f, 0x11, 0x90, 0x2d, 0xe6, 0xae, 0x32, 0x57, 0x5a, 0x46, 0xad, 0x9e, - 0x3f, 0xb8, 0x37, 0x79, 0xd9, 0x28, 0xff, 0xa8, 0x93, 0x27, 0xff, 0xa7, 0xfc, 0xed, 0xeb, 0x30, - 0x70, 0x46, 0xa7, 0x3c, 0x9b, 0x3d, 0x30, 0xb2, 0x6f, 0xad, 0xea, 0x91, 0x96, 0xe1, 0xa7, 0xe0, - 0xbe, 0x09, 0x6b, 0xce, 0x2f, 0x4a, 0x51, 0x71, 0x15, 0xed, 0x99, 0x4c, 0xba, 0xc4, 0x06, 0x4e, - 0x76, 0x81, 0x93, 0xf7, 0xbb, 0xc0, 0xad, 0x83, 0xdf, 0x75, 0x12, 0xd9, 0xc1, 0x63, 0x5d, 0x31, - 0x14, 0x50, 0x3c, 0x03, 0x29, 0x90, 0xcb, 0x12, 0x57, 0x7f, 0xea, 0xa4, 0xb3, 0x62, 0x72, 0xf1, - 0xa2, 0x7f, 0x4b, 0xba, 0x7f, 0x79, 0x9d, 0xf8, 0xb3, 0xb6, 0xa9, 0xbd, 0xb6, 0xa5, 0xc9, 0x74, - 0xfd, 0x2b, 0xf6, 0xd6, 0x9b, 0xd8, 0xbf, 0xda, 0xc4, 0xfe, 0xcf, 0x4d, 0xec, 0x5f, 0x6e, 0x63, - 0xef, 0x6a, 0x1b, 0x7b, 0xdf, 0xb7, 0xb1, 0xf7, 0xe1, 0xe6, 0x8e, 0xcd, 0x8d, 0x86, 0x05, 0xc7, - 0x73, 0xa8, 0xce, 0x0c, 0xa0, 0xcb, 0xe7, 0xf4, 0xc2, 0x5c, 0x3c, 0xdd, 0x37, 0x2e, 0x0f, 0xff, - 0x06, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x24, 0x38, 0xc9, 0xa1, 0x02, 0x00, 0x00, + // 482 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x92, 0xbf, 0x8e, 0x13, 0x3d, + 0x14, 0xc5, 0x67, 0xbe, 0xcd, 0x17, 0xc0, 0x1b, 0xfe, 0x8d, 0x52, 0x0c, 0x11, 0x9a, 0x89, 0x52, + 0xa0, 0x48, 0x10, 0x5b, 0xc9, 0x4a, 0x14, 0x88, 0x2a, 0x04, 0x21, 0x2a, 0x50, 0x96, 0x8a, 0x26, + 0xf2, 0xcc, 0x3a, 0xb3, 0x56, 0xe2, 0xb9, 0xc3, 0xd8, 0xce, 0x6e, 0x0a, 0xde, 0x61, 0x9f, 0x83, + 0x9a, 0x87, 0x48, 0xb9, 0xa2, 0x42, 0x14, 0x59, 0x48, 0x3a, 0x1a, 0x24, 0x9e, 0x00, 0x8d, 0xed, + 0xa0, 0xdd, 0x8e, 0x02, 0xaa, 0x99, 0x7b, 0x8f, 0xef, 0xb9, 0xc7, 0x3f, 0x19, 0xb5, 0xb4, 0x60, + 0x8c, 0x68, 0x9e, 0xa4, 0x64, 0xd1, 0x27, 0x19, 0xcb, 0x99, 0xe4, 0x12, 0x17, 0x25, 0x28, 0x08, + 0x1a, 0x95, 0x86, 0x2b, 0x0d, 0x2f, 0xfa, 0xad, 0x66, 0x06, 0x19, 0x18, 0x81, 0x54, 0x7f, 0xf6, + 0x4c, 0xeb, 0x5e, 0x0a, 0x52, 0x80, 0x9c, 0x58, 0xc1, 0x16, 0x4e, 0x8a, 0x6c, 0x45, 0x12, 0x2a, + 0x19, 0x59, 0xf4, 0x13, 0xa6, 0x68, 0x9f, 0xa4, 0xc0, 0x73, 0xa7, 0xc7, 0x19, 0x40, 0x36, 0x67, + 0xc4, 0x54, 0x89, 0x9e, 0x12, 0xc5, 0x05, 0x93, 0x8a, 0x8a, 0xc2, 0x1d, 0x08, 0xaf, 0x64, 0x7b, + 0xa7, 0x41, 0x51, 0xab, 0x74, 0x7e, 0xd4, 0x50, 0xe3, 0x85, 0xcd, 0x7a, 0xa8, 0xa8, 0x62, 0xc1, + 0x00, 0xd5, 0x0b, 0x5a, 0x52, 0x21, 0x43, 0xbf, 0xed, 0x77, 0xf7, 0x07, 0x4d, 0x7c, 0x39, 0x3b, + 0x7e, 0x6d, 0xb4, 0x61, 0x6d, 0xb5, 0x8e, 0xbd, 0xb1, 0x3b, 0x19, 0x08, 0x74, 0x1d, 0xb4, 0x9a, + 0xce, 0xe1, 0x44, 0x86, 0xff, 0xb5, 0xf7, 0xba, 0xfb, 0x83, 0xfb, 0xd8, 0x5d, 0xa0, 0x8a, 0x8c, + 0x5d, 0x64, 0x3c, 0x62, 0xe9, 0x33, 0xe0, 0xf9, 0xf0, 0xa0, 0x9a, 0xfe, 0x70, 0x11, 0x3f, 0xcc, + 0xb8, 0x3a, 0xd6, 0x09, 0x4e, 0x41, 0xb8, 0x0b, 0xbb, 0x4f, 0x4f, 0x1e, 0xcd, 0x88, 0x5a, 0x16, + 0x4c, 0xee, 0x66, 0xe4, 0xf8, 0xf7, 0x8a, 0xe0, 0x18, 0xdd, 0x55, 0xa0, 0xe8, 0x7c, 0xe2, 0x3a, + 0x13, 0xa9, 0x45, 0xb8, 0xd7, 0xf6, 0xbb, 0x37, 0x86, 0x4f, 0x2b, 0xe7, 0x2f, 0xeb, 0xf8, 0xc1, + 0x9f, 0x39, 0x7f, 0xfa, 0xd8, 0x43, 0x2e, 0xe8, 0x88, 0xa5, 0xe3, 0xdb, 0xc6, 0xf6, 0x95, 0x75, + 0x3d, 0xd4, 0x22, 0x78, 0x8f, 0x6e, 0x1a, 0x58, 0x13, 0x76, 0x5a, 0xf0, 0x92, 0xc9, 0xb0, 0x66, + 0x98, 0xb4, 0xb0, 0x05, 0x8e, 0x77, 0xc0, 0xf1, 0x9b, 0x1d, 0x70, 0x9b, 0xe0, 0xfb, 0x3a, 0x0e, + 0xed, 0xe0, 0x91, 0x2e, 0xa9, 0xe2, 0x90, 0x3f, 0x02, 0xc1, 0x15, 0x13, 0x85, 0x5a, 0xfe, 0x5c, + 0xc7, 0xcd, 0x25, 0x15, 0xf3, 0x27, 0x9d, 0x2b, 0xd6, 0x9d, 0xb3, 0x8b, 0xd8, 0x1f, 0x37, 0x4c, + 0xef, 0xb9, 0x6d, 0x05, 0x33, 0x74, 0x8d, 0xe7, 0x16, 0xeb, 0xff, 0xff, 0x0a, 0xeb, 0x6e, 0x43, + 0x30, 0x45, 0x77, 0x2c, 0x55, 0xdb, 0x30, 0x50, 0xeb, 0x7f, 0x01, 0xea, 0x2d, 0xe3, 0xfa, 0x32, + 0x77, 0x4c, 0x87, 0xa3, 0xd5, 0xb7, 0xc8, 0x5b, 0x6d, 0x22, 0xff, 0x7c, 0x13, 0xf9, 0x5f, 0x37, + 0x91, 0x7f, 0xb6, 0x8d, 0xbc, 0xf3, 0x6d, 0xe4, 0x7d, 0xde, 0x46, 0xde, 0xdb, 0xcb, 0x3b, 0xaa, + 0x87, 0xd7, 0xcb, 0x99, 0x3a, 0x81, 0x72, 0x66, 0x0a, 0xb2, 0x78, 0x4c, 0x4e, 0xcd, 0x33, 0x4e, + 0xea, 0x06, 0xfd, 0xc1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x12, 0x4f, 0x6e, 0xd5, 0x76, 0x03, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -131,6 +138,30 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.TotalInflowSum.Size() + i -= size + if _, err := m.TotalInflowSum.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + if len(m.Inflows) > 0 { + for iNdEx := len(m.Inflows) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Inflows[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.QuotaExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.QuotaExpires):]) if err1 != nil { return 0, err1 @@ -205,6 +236,14 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.QuotaExpires) n += 1 + l + sovGenesis(uint64(l)) + if len(m.Inflows) > 0 { + for _, e := range m.Inflows { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + l = m.TotalInflowSum.Size() + n += 1 + l + sovGenesis(uint64(l)) return n } @@ -377,6 +416,74 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Inflows", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Inflows = append(m.Inflows, types.DecCoin{}) + if err := m.Inflows[len(m.Inflows)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalInflowSum", 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 + } + if err := m.TotalInflowSum.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/uibc/params.go b/x/uibc/params.go index 6d5d797d27..9f4726e258 100644 --- a/x/uibc/params.go +++ b/x/uibc/params.go @@ -10,10 +10,11 @@ import ( // DefaultParams returns default genesis params func DefaultParams() Params { return Params{ - IbcStatus: IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED, - TotalQuota: sdk.NewDec(1_000_000), - TokenQuota: sdk.NewDec(600_000), - QuotaDuration: time.Second * 60 * 60 * 24, // 24h + IbcStatus: IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED, + TotalQuota: sdk.NewDec(1_000_000), + TokenQuota: sdk.NewDec(600_000), + QuotaDuration: time.Second * 60 * 60 * 24, // 24h + TotalInflowQuota: sdk.NewDec(1_000_000), } } @@ -30,6 +31,9 @@ func (p Params) Validate() error { if err := validateQuota(p.TokenQuota, "quota per token"); err != nil { return err } + if err := validateQuota(p.TotalInflowQuota, "total inflow quota"); err != nil { + return err + } if p.TotalQuota.LT(p.TokenQuota) { return fmt.Errorf("token quota shouldn't be less than quota per denom") } diff --git a/x/uibc/quota.pb.go b/x/uibc/quota.pb.go index ef354af807..311b2a08e4 100644 --- a/x/uibc/quota.pb.go +++ b/x/uibc/quota.pb.go @@ -83,6 +83,8 @@ type Params struct { TokenQuota github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=token_quota,json=tokenQuota,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"token_quota"` // quota_duration defines quota expires for each ibc-transfer denom in seconds QuotaDuration time.Duration `protobuf:"bytes,4,opt,name=quota_duration,json=quotaDuration,proto3,stdduration" json:"quota_duration,omitempty" yaml:"quota_duration"` + // total_inflow_quota defines the total inflow limit of ibc-transfer in USD + TotalInflowQuota github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=total_inflow_quota,json=totalInflowQuota,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_inflow_quota"` } func (m *Params) Reset() { *m = Params{} } @@ -140,39 +142,40 @@ func init() { func init() { proto.RegisterFile("umee/uibc/v1/quota.proto", fileDescriptor_651be1a0280abcb6) } var fileDescriptor_651be1a0280abcb6 = []byte{ - // 502 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x3f, 0x6f, 0xd3, 0x4e, - 0x18, 0xc7, 0xed, 0xa4, 0xbf, 0x4a, 0xbd, 0xfe, 0xa8, 0x82, 0x05, 0x92, 0xdb, 0xc1, 0x0e, 0x81, - 0x46, 0xa1, 0x22, 0x67, 0xb5, 0x48, 0x0c, 0x08, 0x10, 0x76, 0xec, 0x4a, 0x96, 0x50, 0x9a, 0xfa, - 0xcf, 0x82, 0x84, 0x2c, 0xdb, 0xbd, 0x1a, 0x2b, 0xb1, 0x2f, 0xd8, 0xe7, 0x40, 0x26, 0x46, 0x18, - 0x19, 0x79, 0x21, 0xbc, 0x88, 0x8e, 0x15, 0x13, 0x62, 0x08, 0x28, 0xd9, 0x18, 0x79, 0x05, 0xc8, - 0x77, 0x8e, 0xda, 0x8a, 0x66, 0x63, 0xf2, 0x3d, 0xfe, 0x7e, 0xee, 0x73, 0x8f, 0x9e, 0xb3, 0x81, - 0x58, 0x24, 0x08, 0x29, 0x45, 0x1c, 0x84, 0xca, 0x64, 0x5f, 0x79, 0x53, 0x60, 0xe2, 0xc3, 0x71, - 0x86, 0x09, 0x16, 0xfe, 0x2f, 0x13, 0x58, 0x26, 0x70, 0xb2, 0xbf, 0x73, 0x2b, 0xc2, 0x11, 0xa6, - 0x81, 0x52, 0xae, 0x18, 0xb3, 0x23, 0x45, 0x18, 0x47, 0x23, 0xa4, 0xd0, 0x2a, 0x28, 0x4e, 0x95, - 0x93, 0x22, 0xf3, 0x49, 0x8c, 0xd3, 0x2a, 0xdf, 0x0e, 0x71, 0x9e, 0xe0, 0xdc, 0x63, 0x1b, 0x59, - 0xc1, 0xa2, 0xd6, 0x87, 0x3a, 0x58, 0x1f, 0xf8, 0x99, 0x9f, 0xe4, 0xc2, 0x33, 0x00, 0xe2, 0x20, - 0xf4, 0x72, 0xe2, 0x93, 0x22, 0x17, 0xf9, 0x26, 0xdf, 0xd9, 0x3a, 0x90, 0xe1, 0xe5, 0xe3, 0xa1, - 0xa9, 0xf5, 0x9c, 0xcc, 0x4f, 0xf3, 0x53, 0x94, 0xd9, 0x14, 0xb3, 0x36, 0xe2, 0x20, 0x64, 0x4b, - 0xe1, 0x15, 0xd8, 0x24, 0x98, 0xf8, 0x23, 0x8f, 0xb6, 0x2f, 0xd6, 0x9a, 0x7c, 0x67, 0x43, 0x7b, - 0x72, 0x36, 0x93, 0xb9, 0xef, 0x33, 0xb9, 0x1d, 0xc5, 0xe4, 0x75, 0x11, 0xc0, 0x10, 0x27, 0x55, - 0x03, 0xd5, 0xa3, 0x9b, 0x9f, 0x0c, 0x15, 0x32, 0x1d, 0xa3, 0x1c, 0xea, 0x28, 0xfc, 0xfa, 0xa5, - 0x0b, 0xaa, 0xfe, 0x74, 0x14, 0x5a, 0x80, 0x0a, 0x8f, 0x4b, 0x1f, 0xd3, 0x0f, 0x51, 0x5a, 0xe9, - 0xeb, 0xff, 0x46, 0x3f, 0x44, 0x29, 0xd3, 0xbf, 0x07, 0x5b, 0x54, 0xec, 0x2d, 0x67, 0x27, 0xae, - 0x35, 0xf9, 0xce, 0xe6, 0xc1, 0x36, 0x64, 0xc3, 0x85, 0xcb, 0xe1, 0x42, 0xbd, 0x02, 0xb4, 0xa7, - 0xe5, 0xe1, 0xbf, 0x66, 0xb2, 0x78, 0x75, 0xe3, 0x03, 0x9c, 0xc4, 0x04, 0x25, 0x63, 0x32, 0xfd, - 0x3d, 0x93, 0x6f, 0x4f, 0xfd, 0x64, 0xf4, 0xb8, 0x75, 0x95, 0x68, 0x7d, 0xfe, 0x21, 0xf3, 0xd6, - 0x0d, 0xfa, 0x72, 0x69, 0xdb, 0xfb, 0x58, 0x03, 0x37, 0xff, 0x9a, 0xaf, 0x70, 0x17, 0xc8, 0xa6, - 0xd6, 0xf3, 0x1c, 0x4b, 0xed, 0xdb, 0x87, 0x86, 0xe5, 0xd9, 0x8e, 0xea, 0xb8, 0xb6, 0xe7, 0xf6, - 0xed, 0x81, 0xd1, 0x33, 0x0f, 0x4d, 0x43, 0x6f, 0x70, 0x42, 0x1b, 0xb4, 0xae, 0x83, 0x8e, 0xdd, - 0x23, 0x47, 0xf5, 0x74, 0xd3, 0x56, 0xb5, 0x17, 0x86, 0xde, 0xe0, 0x85, 0x5d, 0x70, 0x67, 0x35, - 0x67, 0xf4, 0x19, 0x56, 0x13, 0xf6, 0x40, 0x7b, 0x35, 0x76, 0xe4, 0x3a, 0x17, 0xca, 0xba, 0x70, - 0x1f, 0xec, 0xae, 0x66, 0xcd, 0xfe, 0x05, 0xba, 0x26, 0x74, 0xc0, 0xbd, 0xeb, 0xd0, 0x65, 0x6d, - 0x7b, 0x03, 0xd5, 0xb5, 0x0d, 0xbd, 0xf1, 0x9f, 0xf6, 0xfc, 0x6c, 0x2e, 0xf1, 0xe7, 0x73, 0x89, - 0xff, 0x39, 0x97, 0xf8, 0x4f, 0x0b, 0x89, 0x3b, 0x5f, 0x48, 0xdc, 0xb7, 0x85, 0xc4, 0xbd, 0xbc, - 0x7c, 0xcf, 0xe5, 0x97, 0xd9, 0x4d, 0x11, 0x79, 0x8b, 0xb3, 0x21, 0x2d, 0x94, 0xc9, 0x23, 0xe5, - 0x1d, 0xfd, 0x89, 0x82, 0x75, 0x7a, 0x5b, 0x0f, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x90, - 0x20, 0x70, 0x58, 0x03, 0x00, 0x00, + // 524 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0x80, 0xe3, 0xa4, 0xad, 0xd4, 0x2b, 0x54, 0xe1, 0x04, 0x52, 0xda, 0xc1, 0x0e, 0x81, 0x46, + 0xa1, 0x22, 0x67, 0xb5, 0x48, 0x0c, 0x08, 0x10, 0x71, 0xec, 0x4a, 0x96, 0x50, 0x9a, 0xc6, 0xf6, + 0x82, 0x84, 0x2c, 0xdb, 0xbd, 0x18, 0x93, 0xd8, 0x17, 0xec, 0x73, 0x4a, 0x26, 0x56, 0x46, 0x46, + 0x7e, 0x08, 0x3f, 0xa2, 0x63, 0xc5, 0x84, 0x18, 0x02, 0x4a, 0x36, 0x46, 0xf8, 0x03, 0xc8, 0x77, + 0x8e, 0xda, 0xaa, 0xcd, 0xd6, 0xc9, 0xf7, 0xfc, 0xbe, 0xfb, 0xee, 0xbd, 0x67, 0x1f, 0xa8, 0xa4, + 0x21, 0xc6, 0x72, 0x1a, 0xb8, 0x9e, 0x3c, 0xde, 0x93, 0x3f, 0xa4, 0x84, 0x3a, 0x68, 0x14, 0x13, + 0x4a, 0xe0, 0xad, 0x2c, 0x83, 0xb2, 0x0c, 0x1a, 0xef, 0x6d, 0xdf, 0xf5, 0x89, 0x4f, 0x58, 0x42, + 0xce, 0x56, 0x9c, 0xd9, 0x16, 0x7d, 0x42, 0xfc, 0x21, 0x96, 0x59, 0xe4, 0xa6, 0x7d, 0xf9, 0x38, + 0x8d, 0x1d, 0x1a, 0x90, 0x28, 0xcf, 0x6f, 0x79, 0x24, 0x09, 0x49, 0x62, 0xf3, 0x8d, 0x3c, 0xe0, + 0xa9, 0xda, 0xbf, 0x12, 0x58, 0xeb, 0x3a, 0xb1, 0x13, 0x26, 0xf0, 0x25, 0x00, 0x81, 0xeb, 0xd9, + 0x09, 0x75, 0x68, 0x9a, 0x54, 0x84, 0xaa, 0xd0, 0xd8, 0xdc, 0x97, 0xd0, 0xc5, 0xe3, 0x91, 0xae, + 0xb4, 0xcd, 0xd8, 0x89, 0x92, 0x3e, 0x8e, 0x0d, 0x86, 0xf5, 0xd6, 0x03, 0xd7, 0xe3, 0x4b, 0xf8, + 0x16, 0x6c, 0x50, 0x42, 0x9d, 0xa1, 0xcd, 0xca, 0xaf, 0x14, 0xab, 0x42, 0x63, 0x5d, 0x79, 0x7e, + 0x3a, 0x95, 0x0a, 0x3f, 0xa7, 0x52, 0xdd, 0x0f, 0xe8, 0xbb, 0xd4, 0x45, 0x1e, 0x09, 0xf3, 0x02, + 0xf2, 0x47, 0x33, 0x39, 0x1e, 0xc8, 0x74, 0x32, 0xc2, 0x09, 0x52, 0xb1, 0xf7, 0xfd, 0x5b, 0x13, + 0xe4, 0xf5, 0xa9, 0xd8, 0xeb, 0x01, 0x26, 0x3c, 0xca, 0x7c, 0x5c, 0x3f, 0xc0, 0x51, 0xae, 0x2f, + 0xdd, 0x8c, 0x7e, 0x80, 0x23, 0xae, 0xff, 0x04, 0x36, 0x99, 0xd8, 0x5e, 0xcc, 0xae, 0xb2, 0x52, + 0x15, 0x1a, 0x1b, 0xfb, 0x5b, 0x88, 0x0f, 0x17, 0x2d, 0x86, 0x8b, 0xd4, 0x1c, 0x50, 0x5e, 0x64, + 0x87, 0xff, 0x99, 0x4a, 0x95, 0xcb, 0x1b, 0x1f, 0x93, 0x30, 0xa0, 0x38, 0x1c, 0xd1, 0xc9, 0xdf, + 0xa9, 0x74, 0x6f, 0xe2, 0x84, 0xc3, 0x67, 0xb5, 0xcb, 0x44, 0xed, 0xeb, 0x2f, 0x49, 0xe8, 0xdd, + 0x66, 0x2f, 0x17, 0x36, 0xf8, 0x1e, 0x40, 0x3e, 0xbe, 0x20, 0xea, 0x0f, 0xc9, 0x49, 0xde, 0xe6, + 0xea, 0x0d, 0xb4, 0x59, 0x66, 0x5e, 0x9d, 0x69, 0x59, 0xb3, 0xbb, 0x9f, 0x8b, 0xe0, 0xce, 0x95, + 0x6f, 0x09, 0x1f, 0x00, 0x49, 0x57, 0xda, 0xb6, 0xd9, 0x6b, 0x75, 0x8c, 0x03, 0xad, 0x67, 0x1b, + 0x66, 0xcb, 0xb4, 0x0c, 0xdb, 0xea, 0x18, 0x5d, 0xad, 0xad, 0x1f, 0xe8, 0x9a, 0x5a, 0x2e, 0xc0, + 0x3a, 0xa8, 0x5d, 0x07, 0x1d, 0x59, 0x87, 0x66, 0xcb, 0x56, 0x75, 0xa3, 0xa5, 0xbc, 0xd6, 0xd4, + 0xb2, 0x00, 0x77, 0xc0, 0xfd, 0xe5, 0x9c, 0xd6, 0xe1, 0x58, 0x11, 0xee, 0x82, 0xfa, 0x72, 0xec, + 0xd0, 0x32, 0xcf, 0x95, 0x25, 0xf8, 0x08, 0xec, 0x2c, 0x67, 0xf5, 0xce, 0x39, 0xba, 0x02, 0x1b, + 0xe0, 0xe1, 0x75, 0xe8, 0x22, 0x36, 0xec, 0x6e, 0xcb, 0x32, 0x34, 0xb5, 0xbc, 0xaa, 0xbc, 0x3a, + 0x9d, 0x89, 0xc2, 0xd9, 0x4c, 0x14, 0x7e, 0xcf, 0x44, 0xe1, 0xcb, 0x5c, 0x2c, 0x9c, 0xcd, 0xc5, + 0xc2, 0x8f, 0xb9, 0x58, 0x78, 0x73, 0x71, 0xd8, 0xd9, 0x2d, 0x68, 0x46, 0x98, 0x9e, 0x90, 0x78, + 0xc0, 0x02, 0x79, 0xfc, 0x54, 0xfe, 0xc8, 0x2e, 0xac, 0xbb, 0xc6, 0xfe, 0x8c, 0x27, 0xff, 0x03, + 0x00, 0x00, 0xff, 0xff, 0x88, 0xbe, 0x35, 0x75, 0xc4, 0x03, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -195,6 +198,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.TotalInflowQuota.Size() + i -= size + if _, err := m.TotalInflowQuota.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuota(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a n1, err1 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.QuotaDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.QuotaDuration):]) if err1 != nil { return 0, err1 @@ -257,6 +270,8 @@ func (m *Params) Size() (n int) { n += 1 + l + sovQuota(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.QuotaDuration) n += 1 + l + sovQuota(uint64(l)) + l = m.TotalInflowQuota.Size() + n += 1 + l + sovQuota(uint64(l)) return n } @@ -415,6 +430,40 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalInflowQuota", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuota + } + 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 ErrInvalidLengthQuota + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuota + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalInflowQuota.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuota(dAtA[iNdEx:]) diff --git a/x/uibc/quota/ibc_module.go b/x/uibc/quota/ibc_module.go index f68620f9f9..b7e7d46781 100644 --- a/x/uibc/quota/ibc_module.go +++ b/x/uibc/quota/ibc_module.go @@ -46,20 +46,19 @@ func (im ICS20Module) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, return channeltypes.NewErrorAcknowledgement(transfertypes.ErrReceiveDisabled) } - // TODO: re-enable inflow checks - // if params.IbcStatus.InflowQuotaEnabled() { - // var data transfertypes.FungibleTokenPacketData - // if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - // ackErr := sdkerrors.ErrInvalidType.Wrap("cannot unmarshal ICS-20 transfer packet data") - // return channeltypes.NewErrorAcknowledgement(ackErr) - // } - - // isSourceChain := transfertypes.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) - // ackErr := im.kb.Keeper(&ctx).CheckIBCInflow(ctx, packet, data.Denom, isSourceChain) - // if ackErr != nil { - // return ackErr - // } - // } + if params.IbcStatus.OutflowQuotaEnabled() { + var data transfertypes.FungibleTokenPacketData + if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + ackErr := sdkerrors.ErrInvalidType.Wrap("cannot unmarshal ICS-20 transfer packet data") + return channeltypes.NewErrorAcknowledgement(ackErr) + } + + isSourceChain := transfertypes.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) + ackErr := im.kb.Keeper(&ctx).CheckIBCInflow(ctx, packet, data.Denom, data.Amount, isSourceChain) + if ackErr != nil { + return ackErr + } + } return im.IBCModule.OnRecvPacket(ctx, packet, relayer) } diff --git a/x/uibc/quota/keeper/genesis.go b/x/uibc/quota/keeper/genesis.go index a710d6ac43..da94643824 100644 --- a/x/uibc/quota/keeper/genesis.go +++ b/x/uibc/quota/keeper/genesis.go @@ -14,7 +14,9 @@ func (kb Builder) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) { util.Panic(err) k.SetTokenOutflows(genState.Outflows) + k.SetTokenOutflows(genState.Inflows) k.SetTotalOutflowSum(genState.TotalOutflowSum) + k.SetTotalInflowSum(genState.TotalInflowSum) err = k.SetExpire(genState.QuotaExpires) util.Panic(err) @@ -25,6 +27,8 @@ func (kb Builder) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { k := kb.Keeper(&ctx) outflows, err := k.GetAllOutflows() util.Panic(err) + inflows, err := k.GetAllInflows() + util.Panic(err) quotaExpires, err := k.GetExpire() util.Panic(err) @@ -33,5 +37,7 @@ func (kb Builder) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { Outflows: outflows, TotalOutflowSum: k.GetTotalOutflow(), QuotaExpires: *quotaExpires, + Inflows: inflows, + TotalInflowSum: k.GetTotalInflow(), } } diff --git a/x/uibc/quota/keeper/keys.go b/x/uibc/quota/keeper/keys.go index 8eb9321fc6..0d644c9d4e 100644 --- a/x/uibc/quota/keeper/keys.go +++ b/x/uibc/quota/keeper/keys.go @@ -9,9 +9,16 @@ var ( keyTotalOutflows = []byte{0x02} keyParams = []byte{0x03} keyQuotaExpires = []byte{0x04} + keyPrefixDenomInflows = []byte{0x05} + keyTotalInflows = []byte{0x06} ) func KeyTotalOutflows(ibcDenom string) []byte { - // KeyPrefixDenomQuota | denom + // keyPrefixDenomOutflows | denom return util.ConcatBytes(0, keyPrefixDenomOutflows, []byte(ibcDenom)) } + +func KeyTotalInflows(ibcDenom string) []byte { + // keyPrefixDenomInflows | denom + return util.ConcatBytes(0, keyPrefixDenomInflows, []byte(ibcDenom)) +} diff --git a/x/uibc/quota/keeper/quota.go b/x/uibc/quota/keeper/quota.go index 2befc6ebed..99d31696ff 100644 --- a/x/uibc/quota/keeper/quota.go +++ b/x/uibc/quota/keeper/quota.go @@ -38,6 +38,25 @@ func (k Keeper) GetAllOutflows() (sdk.DecCoins, error) { return outflows, nil } +// GetAllInflows returns inflows of all registered tokens in USD value. +func (k Keeper) GetAllInflows() (sdk.DecCoins, error) { + var inflows sdk.DecCoins + // creating PrefixStore upfront will remove the prefix from the key when running the iterator. + store := k.PrefixStore(keyPrefixDenomOutflows) + iter := sdk.KVStorePrefixIterator(store, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + o := sdk.DecCoin{Denom: string(iter.Key())} + if err := o.Amount.Unmarshal(iter.Value()); err != nil { + return nil, err + } + inflows = append(inflows, o) + } + + return inflows, nil +} + // GetTokenOutflows returns sum of denom outflows in USD value in the DecCoin structure. func (k Keeper) GetTokenOutflows(denom string) sdk.DecCoin { amount, _ := store.GetDec(k.store, KeyTotalOutflows(denom), "total_outflow") @@ -52,6 +71,14 @@ func (k Keeper) SetTokenOutflows(outflows sdk.DecCoins) { } } +// SetTokenInflows saves provided updated IBC inflows as a pair: USD value, denom name in the +// DecCoin structure. +func (k Keeper) SetTokenInflows(inflows sdk.DecCoins) { + for _, q := range inflows { + k.SetTokenInflow(q) + } +} + // SetTokenOutflow save the outflows of denom into store. func (k Keeper) SetTokenOutflow(outflow sdk.DecCoin) { key := KeyTotalOutflows(outflow.Denom) @@ -59,6 +86,13 @@ func (k Keeper) SetTokenOutflow(outflow sdk.DecCoin) { util.Panic(err) } +// SetTokenInflow save the inflow of denom into store. +func (k Keeper) SetTokenInflow(inflow sdk.DecCoin) { + key := KeyTotalInflows(inflow.Denom) + err := store.SetDec(k.store, key, inflow.Amount, "total_inflow") + util.Panic(err) +} + // GetTotalOutflow returns the total outflow of ibc-transfer amount. func (k Keeper) GetTotalOutflow() sdk.Dec { // TODO: use store.Get/SetDec @@ -66,11 +100,23 @@ func (k Keeper) GetTotalOutflow() sdk.Dec { return sdk.MustNewDecFromStr(string(bz)) } +// GetTotalInflow returns the total inflow of ibc-transfer amount. +func (k Keeper) GetTotalInflow() sdk.Dec { + // TODO: use store.Get/SetDec + bz := k.store.Get(keyTotalInflows) + return sdk.MustNewDecFromStr(string(bz)) +} + // SetTotalOutflowSum save the total outflow of ibc-transfer amount. func (k Keeper) SetTotalOutflowSum(amount sdk.Dec) { k.store.Set(keyTotalOutflows, []byte(amount.String())) } +// SetTotalInflowSum save the total inflow of ibc-transfer amount. +func (k Keeper) SetTotalInflowSum(amount sdk.Dec) { + k.store.Set(keyTotalInflows, []byte(amount.String())) +} + // SetExpire save the quota expire time of ibc denom into. func (k Keeper) SetExpire(expires time.Time) error { return store.SetBinValue(k.store, keyQuotaExpires, &expires, "expire") @@ -93,6 +139,7 @@ func (k Keeper) ResetAllQuotas() error { if err != nil { return err } + // outflows k.SetTotalOutflowSum(zero) store := k.PrefixStore(keyPrefixDenomOutflows) iter := sdk.KVStorePrefixIterator(store, nil) @@ -100,6 +147,15 @@ func (k Keeper) ResetAllQuotas() error { for ; iter.Valid(); iter.Next() { store.Set(iter.Key(), zeroBz) } + + // inflows + k.SetTotalInflowSum(zero) + store = k.PrefixStore(keyPrefixDenomInflows) + iter = sdk.KVStorePrefixIterator(store, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + store.Set(iter.Key(), zeroBz) + } return nil } @@ -122,11 +178,20 @@ func (k Keeper) CheckAndUpdateQuota(denom string, newOutflow sdkmath.Int) error return uibc.ErrQuotaExceeded } + // Allow outflow either of two conditions + // 1. Total Outflow Sum <= Total Outflow Quota + // or + // 2 . Total Outflow Sum <= $1M + params.TotalInflowQuota * sum of all inflows totalOutflowSum := k.GetTotalOutflow().Add(exchangePrice) if !params.TotalQuota.IsZero() && totalOutflowSum.GT(params.TotalQuota) { return uibc.ErrQuotaExceeded } + totalInflowSum := k.GetTotalInflow() + if totalOutflowSum.GT(sdk.NewDec(10_000_000).Mul(totalInflowSum).Add(params.TotalInflowQuota)) { + return uibc.ErrQuotaExceeded + } + k.SetTokenOutflow(o) k.SetTotalOutflowSum(totalOutflowSum) return nil @@ -190,7 +255,7 @@ func (k Keeper) UndoUpdateQuota(denom string, amount sdkmath.Int) error { // CheckIBCInflow validates if inflow token is registered in x/leverage func (k Keeper) CheckIBCInflow(ctx sdk.Context, - packet channeltypes.Packet, dataDenom string, isSourceChain bool, + packet channeltypes.Packet, dataDenom, dataAmount string, isSourceChain bool, ) exported.Acknowledgement { // if chain is recevier and sender chain is source then we need create ibc_denom (ibc/hash(channel,denom)) to // check ibc_denom is exists in leverage token registry @@ -201,14 +266,27 @@ func (k Keeper) CheckIBCInflow(ctx sdk.Context, prefixedDenom := sourcePrefix + dataDenom // construct the denomination trace from the full raw denomination and get the ibc_denom ibcDenom := transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom() - _, err := k.leverage.GetTokenSettings(ctx, ibcDenom) + ts, err := k.leverage.GetTokenSettings(ctx, ibcDenom) if err != nil { + // skip if token is not a registered token on leverage if ltypes.ErrNotRegisteredToken.Is(err) { - return channeltypes.NewErrorAcknowledgement(err) + return nil } - // other leverage keeper error -> log the error and allow the inflow transfer. - ctx.Logger().Error("IBC inflows: can't load token registry", "err", err) } + + // get the exchange price (eg: UMEE) in USD from oracle using SYMBOL Denom eg: `UMEE` (uumee) + exchangeRate, err := k.oracle.Price(*k.ctx, strings.ToUpper(ts.SymbolDenom)) + if err != nil { + return channeltypes.NewErrorAcknowledgement(err) + } + // calculate total exchange rate + powerReduction := ten.Power(uint64(ts.Exponent)) + inflowinUSD := sdk.MustNewDecFromStr(dataAmount).Quo(powerReduction).Mul(exchangeRate) + + tokenInflow := sdk.NewDecCoinFromDec(ibcDenom, inflowinUSD) + k.SetTokenInflow(tokenInflow) + totalInflowSum := k.GetTotalInflow() + k.SetTotalInflowSum(totalInflowSum.Add(inflowinUSD)) } return nil diff --git a/x/uibc/quota/keeper/quota_test.go b/x/uibc/quota/keeper/quota_test.go index c1a6c87d5d..6d3a88f352 100644 --- a/x/uibc/quota/keeper/quota_test.go +++ b/x/uibc/quota/keeper/quota_test.go @@ -43,7 +43,9 @@ func TestUnitCheckAndUpdateQuota(t *testing.T) { // k.setQuotaParams(10, 100) k.SetTokenOutflow(sdk.NewInt64DecCoin(umee, 6)) + k.SetTokenInflow(sdk.NewInt64DecCoin(umee, 6)) k.SetTotalOutflowSum(sdk.NewDec(50)) + k.SetTotalInflowSum(sdk.NewDec(50)) err := k.CheckAndUpdateQuota(umee, sdk.NewInt(1)) require.NoError(t, err)