github.com/InjectiveLabs/sdk-go@v1.53.0/chain/exchange/types/authz_common.go (about)

     1  package types
     2  
     3  import (
     4  	"context"
     5  
     6  	sdk "github.com/cosmos/cosmos-sdk/types"
     7  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
     8  	"github.com/cosmos/cosmos-sdk/x/authz"
     9  )
    10  
    11  func find(slice []string, val string) bool {
    12  	for _, item := range slice {
    13  		if item == val {
    14  			return true
    15  		}
    16  	}
    17  	return false
    18  }
    19  
    20  func reduceToSet(slice []string) []string {
    21  	set := map[string]bool{}
    22  	for _, s := range slice {
    23  		set[s] = true
    24  	}
    25  	output := make([]string, len(set))
    26  	i := 0
    27  	for k := range set {
    28  		output[i] = k
    29  		i += 1
    30  	}
    31  	return output
    32  }
    33  
    34  var (
    35  	_                      authz.Authorization = &BatchUpdateOrdersAuthz{}
    36  	AuthorizedMarketsLimit                     = 200
    37  )
    38  
    39  // BatchUpdateOrdersAuthz impl
    40  func (a BatchUpdateOrdersAuthz) MsgTypeURL() string {
    41  	return sdk.MsgTypeURL(&MsgBatchUpdateOrders{})
    42  }
    43  
    44  func (a BatchUpdateOrdersAuthz) Accept(ctx context.Context, msg sdk.Msg) (authz.AcceptResponse, error) {
    45  	ordersToUpdate, ok := msg.(*MsgBatchUpdateOrders)
    46  	if !ok {
    47  		return authz.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch")
    48  	}
    49  
    50  	// check authorized spot markets
    51  	for _, o := range ordersToUpdate.SpotOrdersToCreate {
    52  		if !find(a.SpotMarkets, o.MarketId) {
    53  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested spot market to create orders is unauthorized")
    54  		}
    55  		if o.OrderInfo.SubaccountId != a.SubaccountId {
    56  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
    57  		}
    58  	}
    59  	for _, o := range ordersToUpdate.SpotOrdersToCancel {
    60  		if !find(a.SpotMarkets, o.MarketId) {
    61  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested spot market to cancel orders is unauthorized")
    62  		}
    63  		if o.SubaccountId != a.SubaccountId {
    64  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
    65  		}
    66  	}
    67  	for _, id := range ordersToUpdate.SpotMarketIdsToCancelAll {
    68  		if !find(a.SpotMarkets, id) {
    69  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested spot market to cancel all orders is unauthorized")
    70  		}
    71  
    72  		if ordersToUpdate.SubaccountId != a.SubaccountId {
    73  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
    74  		}
    75  	}
    76  
    77  	// check authorized derivative markets
    78  	for _, o := range ordersToUpdate.DerivativeOrdersToCreate {
    79  		if !find(a.DerivativeMarkets, o.MarketId) {
    80  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested derivative market to create orders is unauthorized")
    81  		}
    82  		if o.OrderInfo.SubaccountId != a.SubaccountId {
    83  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
    84  		}
    85  	}
    86  	for _, o := range ordersToUpdate.DerivativeOrdersToCancel {
    87  		if !find(a.DerivativeMarkets, o.MarketId) {
    88  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested derivative market to cancel orders is unauthorized")
    89  		}
    90  		if o.SubaccountId != a.SubaccountId {
    91  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
    92  		}
    93  	}
    94  	for _, id := range ordersToUpdate.DerivativeMarketIdsToCancelAll {
    95  		if !find(a.DerivativeMarkets, id) {
    96  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested derivative market to cancel all orders is unauthorized")
    97  		}
    98  
    99  		if ordersToUpdate.SubaccountId != a.SubaccountId {
   100  			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("requested subaccount is unauthorized")
   101  		}
   102  	}
   103  
   104  	// TODO add check for BO markets?
   105  
   106  	return authz.AcceptResponse{Accept: true, Delete: false, Updated: nil}, nil
   107  }
   108  
   109  func (a BatchUpdateOrdersAuthz) ValidateBasic() error {
   110  	if !IsHexHash(a.SubaccountId) {
   111  		return sdkerrors.ErrLogic.Wrap("invalid subaccount id to authorize")
   112  	}
   113  	if len(a.SpotMarkets) == 0 && len(a.DerivativeMarkets) == 0 {
   114  		return sdkerrors.ErrLogic.Wrapf("invalid markets array length")
   115  	}
   116  	if len(a.SpotMarkets) > AuthorizedMarketsLimit || len(a.DerivativeMarkets) > AuthorizedMarketsLimit {
   117  		return sdkerrors.ErrLogic.Wrapf("invalid markets array length")
   118  	}
   119  	spotMarketsSet := reduceToSet(a.SpotMarkets)
   120  	derivativeMarketsSet := reduceToSet(a.DerivativeMarkets)
   121  	if len(a.SpotMarkets) != len(spotMarketsSet) || len(a.DerivativeMarkets) != len(derivativeMarketsSet) {
   122  		return sdkerrors.ErrLogic.Wrapf("cannot have duplicate markets")
   123  	}
   124  	for _, m := range a.SpotMarkets {
   125  		if !IsHexHash(m) {
   126  			return sdkerrors.ErrLogic.Wrap("invalid spot market id to authorize")
   127  		}
   128  	}
   129  	for _, m := range a.DerivativeMarkets {
   130  		if !IsHexHash(m) {
   131  			return sdkerrors.ErrLogic.Wrap("invalid derivative market id to authorize")
   132  		}
   133  	}
   134  	return nil
   135  }