Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion x/tokenfactory/keeper/createdenom.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (k Keeper) chargeForCreateDenom(ctx sdk.Context, creatorAddr string, _ stri
return err
}

if types.IsCapabilityEnabled(k.enabledCapabilities, types.EnableCommunityPoolFeeFunding) {
if k.IsCapabilityEnabled(types.EnableCommunityPoolFeeFunding) {
if err := k.communityPoolKeeper.FundCommunityPool(ctx, params.DenomCreationFee, accAddr); err != nil {
return err
}
Expand Down
12 changes: 8 additions & 4 deletions x/tokenfactory/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type (
bankKeeper types.BankKeeper
communityPoolKeeper types.CommunityPoolKeeper

enabledCapabilities []string
enabledCapabilities *types.Set[string]

// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
Expand Down Expand Up @@ -59,7 +59,7 @@ func NewKeeper(

authority: authority,

enabledCapabilities: enabledCapabilities,
enabledCapabilities: types.NewSet[string](enabledCapabilities...),
}

return k
Expand All @@ -71,11 +71,11 @@ func (k Keeper) GetAuthority() string {
}

func (k Keeper) GetEnabledCapabilities() []string {
return k.enabledCapabilities
return k.enabledCapabilities.ToSlice()
}

func (k *Keeper) SetEnabledCapabilities(_ sdk.Context, newCapabilities []string) {
k.enabledCapabilities = newCapabilities
k.enabledCapabilities = types.NewSet[string](newCapabilities...)
}

// Logger returns a logger for the x/tokenfactory module
Expand All @@ -100,3 +100,7 @@ func (k Keeper) GetCreatorsPrefixStore(ctx sdk.Context) store.KVStore {
store := ctx.KVStore(k.storeKey)
return prefix.NewStore(store, types.GetCreatorsPrefix())
}

func (k Keeper) IsCapabilityEnabled(capability string) bool {
return k.enabledCapabilities.Contains(capability)
}
89 changes: 48 additions & 41 deletions x/tokenfactory/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,32 +52,34 @@ func (server msgServer) Mint(goCtx context.Context, msg *types.MsgMint) (*types.
var err error
ctx := sdk.UnwrapSDKContext(goCtx)

sudoEnabled := types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableSudoMint)
sa := SudoAdmins{Keeper: server.Keeper}
senderIsSudoAble := sa.IsSudoAdmin(goCtx, msg.Sender)
isSudo := sudoEnabled && senderIsSudoAble

if !isSudo {
// Standard user verification if they are not a Sudo admin
_, denomExists := server.bankKeeper.GetDenomMetaData(ctx, msg.Amount.Denom)
if !denomExists {
return nil, types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.Amount.Denom)
// verify that denom is an x/tokenfactory denom, and if it is not, then sudo mint capability must be enabled
if _, _, err = types.DeconstructDenom(msg.Amount.GetDenom()); err != nil {
sudoEnabled := server.IsCapabilityEnabled(types.EnableSudoMint)
if !sudoEnabled {
return nil, types.ErrCapabilityNotEnabled.Wrapf("the '%s' capability is NOT enabled", types.EnableSudoMint)
}

authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
sa := SudoAdmins{Keeper: server.Keeper}
senderIsSudoAble := sa.IsSudoAdmin(goCtx, msg.Sender)
isSudo := sudoEnabled && senderIsSudoAble
if !isSudo {
return nil, types.ErrUnauthorized.Wrapf("the '%s' sender does NOT have sudo admin credentials", msg.Sender)
}
}

if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
// Denomination *MUST* already exist:
_, denomExists := server.bankKeeper.GetDenomMetaData(ctx, msg.Amount.Denom)
if !denomExists {
return nil, types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.Amount.Denom)
}

// verify that denom is an x/tokenfactory denom
_, _, err = types.DeconstructDenom(msg.Amount.GetDenom())
if err != nil {
return nil, err
}
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
}

if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}

if msg.MintToAddress == "" {
Expand Down Expand Up @@ -111,31 +113,26 @@ func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.
isBurningOwn = true
}

if !(isBurningOwn && types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableBurnOwn)) {
if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableBurnFrom) {
if !(isBurningOwn && server.IsCapabilityEnabled(types.EnableBurnOwn)) {
if !server.IsCapabilityEnabled(types.EnableBurnFrom) {
return nil, types.ErrCapabilityNotEnabled
}

sudoEnabled := types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableSudoMint)
sa := SudoAdmins{Keeper: server.Keeper}
senderIsSudoAble := sa.IsSudoAdmin(goCtx, msg.Sender)
isSudo := sudoEnabled && senderIsSudoAble

if !isSudo {
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
// verify that denom is an x/tokenfactory denom, and if it is not, then sudo mint capability must be enabled
if _, _, err := types.DeconstructDenom(msg.Amount.GetDenom()); err != nil {
sudoEnabled := server.IsCapabilityEnabled(types.EnableSudoMint)
if !sudoEnabled {
return nil, err
}
}

if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
}

// verify that denom is an x/tokenfactory denom
_, _, err = types.DeconstructDenom(msg.Amount.GetDenom())
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
}

Expand All @@ -158,7 +155,7 @@ func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.
func (server msgServer) ForceTransfer(goCtx context.Context, msg *types.MsgForceTransfer) (*types.MsgForceTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableForceTransfer) {
if !server.IsCapabilityEnabled(types.EnableForceTransfer) {
return nil, types.ErrCapabilityNotEnabled
}

Expand Down Expand Up @@ -191,6 +188,11 @@ func (server msgServer) ForceTransfer(goCtx context.Context, msg *types.MsgForce
func (server msgServer) ChangeAdmin(goCtx context.Context, msg *types.MsgChangeAdmin) (*types.MsgChangeAdminResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// verify that denom is an x/tokenfactory denom
if _, _, err := types.DeconstructDenom(msg.Denom); err != nil {
return nil, err
}

authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Denom)
if err != nil {
return nil, err
Expand Down Expand Up @@ -218,7 +220,7 @@ func (server msgServer) ChangeAdmin(goCtx context.Context, msg *types.MsgChangeA
func (server msgServer) SetDenomMetadata(goCtx context.Context, msg *types.MsgSetDenomMetadata) (*types.MsgSetDenomMetadataResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableSetMetadata) {
if !server.IsCapabilityEnabled(types.EnableSetMetadata) {
return nil, types.ErrCapabilityNotEnabled
}

Expand All @@ -228,6 +230,11 @@ func (server msgServer) SetDenomMetadata(goCtx context.Context, msg *types.MsgSe
return nil, err
}

// verify that denom is an x/tokenfactory denom
if _, _, err := types.DeconstructDenom(msg.Metadata.Base); err != nil {
return nil, err
}

authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Metadata.Base)
if err != nil {
return nil, err
Expand Down
14 changes: 0 additions & 14 deletions x/tokenfactory/types/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,3 @@ const (
// This is useful for ICS chains, or networks who wish to just have the fee tokens burned (not gas fees, just the extra on top).
EnableCommunityPoolFeeFunding = "enable_community_pool_fee_funding"
)

func IsCapabilityEnabled(enabledCapabilities []string, capability string) bool {
if len(enabledCapabilities) == 0 {
return false
}

for _, v := range enabledCapabilities {
if v == capability {
return true
}
}

return false
}
Loading