diff --git a/go.mod b/go.mod index f8af099e..9a1795e1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/CosmWasm/wasmd v0.45.0 github.com/CosmWasm/wasmvm v1.5.2 - github.com/OmniFlix/streampay/v2 v2.3.0 + github.com/OmniFlix/streampay/v2 v2.4.0 github.com/bianjieai/nft-transfer v1.1.3-ibc-v7.3.0 github.com/cometbft/cometbft v0.37.4 github.com/cometbft/cometbft-db v0.8.0 diff --git a/go.sum b/go.sum index f0738142..14f2a1dc 100644 --- a/go.sum +++ b/go.sum @@ -234,8 +234,8 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OmniFlix/streampay/v2 v2.3.0 h1:C2uK6bhGDLmluXf6awQ+P759Cc34Icv/TvoCNbE0bfs= -github.com/OmniFlix/streampay/v2 v2.3.0/go.mod h1:U1JTcIJ9GqnSoeNX87+qVUSS+BlYpri510hJEKnGU5I= +github.com/OmniFlix/streampay/v2 v2.4.0 h1:IqveswOwo+j5qUVx2Rr1LIWODerd/F2QAwXKoWFMyqs= +github.com/OmniFlix/streampay/v2 v2.4.0/go.mod h1:GMG8JQH7K/OrRB3mvxTUz765kYpeBRvLLZeAtqmPXes= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= diff --git a/x/marketplace/keeper/keeper.go b/x/marketplace/keeper/keeper.go index c826afaa..cbb31130 100644 --- a/x/marketplace/keeper/keeper.go +++ b/x/marketplace/keeper/keeper.go @@ -3,6 +3,8 @@ package keeper import ( "fmt" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + onfttypes "github.com/OmniFlix/omniflixhub/v3/x/onft/types" errorsmod "cosmossdk.io/errors" @@ -363,3 +365,16 @@ func (k Keeper) TransferRoyalty( } return nil } + +func (k Keeper) ValidateSplitShareAddresses(splitShares []types.WeightedAddress) error { + for _, share := range splitShares { + addr, err := sdk.AccAddressFromBech32(share.Address) + if err != nil { + return err + } + if k.bankKeeper.BlockedAddr(addr) { + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is blocked address, not allowed receive funds", addr) + } + } + return nil +} diff --git a/x/marketplace/keeper/msg_server.go b/x/marketplace/keeper/msg_server.go index fe62de53..17e5d4e4 100644 --- a/x/marketplace/keeper/msg_server.go +++ b/x/marketplace/keeper/msg_server.go @@ -59,6 +59,10 @@ func (m msgServer) ListNFT(goCtx context.Context, msg *types.MsgListNFT) (*types types.ErrNftNonTransferable, "non-transferable nfts not allowed to list in marketplace") } + if err := m.Keeper.ValidateSplitShareAddresses(msg.SplitShares); err != nil { + return nil, err + } + listing := types.NewListing(msg.Id, msg.NftId, msg.DenomId, msg.Price, owner, msg.SplitShares) err = m.Keeper.AddListing(ctx, listing) if err != nil { @@ -186,6 +190,11 @@ func (m msgServer) CreateAuction(goCtx context.Context, msg *types.MsgCreateAuct return nil, errorsmod.Wrapf( types.ErrNftNonTransferable, "non-transferable nfts not allowed to list in marketplace") } + + if err := m.Keeper.ValidateSplitShareAddresses(msg.SplitShares); err != nil { + return nil, err + } + var endTime *time.Time if msg.Duration != nil { maxAuctionDuration := m.Keeper.GetMaxAuctionDuration(ctx) @@ -215,7 +224,7 @@ func (m msgServer) CreateAuction(goCtx context.Context, msg *types.MsgCreateAuct }, nil } -// CancelAuction +// CancelAuction cancels an auction if auction creator want to cancel it, and it has no bids func (m msgServer) CancelAuction(goCtx context.Context, msg *types.MsgCancelAuction) (*types.MsgCancelAuctionResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -242,7 +251,7 @@ func (m msgServer) CancelAuction(goCtx context.Context, msg *types.MsgCancelAuct return &types.MsgCancelAuctionResponse{}, nil } -// PlaceBid +// PlaceBid places a bid on an active auction func (m msgServer) PlaceBid(goCtx context.Context, msg *types.MsgPlaceBid) (*types.MsgPlaceBidResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/x/marketplace/types/expected_keepers.go b/x/marketplace/types/expected_keepers.go index aac86a0d..41a21d00 100644 --- a/x/marketplace/types/expected_keepers.go +++ b/x/marketplace/types/expected_keepers.go @@ -16,6 +16,7 @@ type AccountKeeper interface { type BankKeeper interface { // Methods imported from bank should be defined here + BlockedAddr(recipient sdk.AccAddress) bool SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SendCoins(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, amount sdk.Coins) error SendCoinsFromModuleToAccount(ctx sdk.Context, formModule string, toAddr sdk.AccAddress, amt sdk.Coins) error diff --git a/x/onft/keeper/keeper.go b/x/onft/keeper/keeper.go index 73b8948f..489aa8b8 100644 --- a/x/onft/keeper/keeper.go +++ b/x/onft/keeper/keeper.go @@ -3,8 +3,11 @@ package keeper import ( "fmt" + errorsmod "cosmossdk.io/errors" + "github.com/cometbft/cometbft/libs/log" storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -61,3 +64,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) NFTkeeper() nftkeeper.Keeper { return k.nk } + +func (k Keeper) ValidateRoyaltyReceiverAddresses(splitShares []*types.WeightedAddress) error { + for _, share := range splitShares { + addr, err := sdk.AccAddressFromBech32(share.Address) + if err != nil { + return err + } + if k.bankKeeper.BlockedAddr(addr) { + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is a blocked address and not allowed receive funds", addr) + } + } + return nil +} diff --git a/x/onft/keeper/msg_server.go b/x/onft/keeper/msg_server.go index 3b01a9e9..1bab2484 100644 --- a/x/onft/keeper/msg_server.go +++ b/x/onft/keeper/msg_server.go @@ -46,6 +46,13 @@ func (m msgServer) CreateDenom(goCtx context.Context, msg *types.MsgCreateDenom) if m.Keeper.HasDenom(ctx, msg.Id) { return nil, errorsmod.Wrapf(types.ErrDenomIdExists, "denom id already exists %s", msg.Id) } + + if msg.RoyaltyReceivers != nil { + if err := m.Keeper.ValidateRoyaltyReceiverAddresses(msg.RoyaltyReceivers); err != nil { + return nil, err + } + } + denomCreationFee := m.Keeper.GetDenomCreationFee(ctx) if !msg.CreationFee.Equal(denomCreationFee) { if msg.CreationFee.Denom != denomCreationFee.Denom { @@ -100,6 +107,12 @@ func (m msgServer) UpdateDenom(goCtx context.Context, msg *types.MsgUpdateDenom) return nil, err } + if msg.RoyaltyReceivers != nil { + if err := m.Keeper.ValidateRoyaltyReceiverAddresses(msg.RoyaltyReceivers); err != nil { + return nil, err + } + } + ctx := sdk.UnwrapSDKContext(goCtx) err = m.Keeper.UpdateDenom(ctx, msg) if err != nil { diff --git a/x/onft/types/expected_keepers.go b/x/onft/types/expected_keepers.go index 16cdb70c..ea42d075 100644 --- a/x/onft/types/expected_keepers.go +++ b/x/onft/types/expected_keepers.go @@ -14,6 +14,7 @@ type AccountKeeper interface { // BankKeeper defines the expected interface needed to retrieve account balances. type BankKeeper interface { + BlockedAddr(addr sdk.AccAddress) bool GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins