Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Stable token factory #269

Merged
merged 8 commits into from
Nov 14, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Introduce a new `x/stabletokenfactory` module for issuing [USDLR by Stable](https://withstable.com). ([#269](https://github.com/strangelove-ventures/noble/pull/269))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add multiple fee denom support to the `x/tariff` module. ([#269](https://github.com/strangelove-ventures/noble/pull/269))
79 changes: 53 additions & 26 deletions app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
fiattokenfactory "github.com/circlefin/noble-fiattokenfactory/x/fiattokenfactory/keeper"
fiattokenfactorytypes "github.com/circlefin/noble-fiattokenfactory/x/fiattokenfactory/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
stabletokenfactorykeeper "github.com/strangelove-ventures/noble/v4/x/stabletokenfactory/keeper"
stabletokenfactorytypes "github.com/strangelove-ventures/noble/v4/x/stabletokenfactory/types"
tokenfactory "github.com/strangelove-ventures/noble/v4/x/tokenfactory/keeper"
tokenfactorytypes "github.com/strangelove-ventures/noble/v4/x/tokenfactory/types"

Expand All @@ -21,22 +23,25 @@ import (

type HandlerOptions struct {
ante.HandlerOptions
tokenFactoryKeeper *tokenfactory.Keeper
fiatTokenFactoryKeeper *fiattokenfactory.Keeper
IBCKeeper *ibckeeper.Keeper
GlobalFeeSubspace paramtypes.Subspace
StakingSubspace paramtypes.Subspace
tokenFactoryKeeper *tokenfactory.Keeper
fiatTokenFactoryKeeper *fiattokenfactory.Keeper
stableTokenFactoryKeeper *stabletokenfactorykeeper.Keeper
IBCKeeper *ibckeeper.Keeper
GlobalFeeSubspace paramtypes.Subspace
StakingSubspace paramtypes.Subspace
}

type IsPausedDecorator struct {
tokenFactory *tokenfactory.Keeper
fiatTokenFactory *fiattokenfactory.Keeper
tokenFactory *tokenfactory.Keeper
fiatTokenFactory *fiattokenfactory.Keeper
stableTokenFactory *stabletokenfactorykeeper.Keeper
}

func NewIsPausedDecorator(tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper) IsPausedDecorator {
func NewIsPausedDecorator(tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper, stf *stabletokenfactorykeeper.Keeper) IsPausedDecorator {
return IsPausedDecorator{
tokenFactory: tf,
fiatTokenFactory: ctf,
tokenFactory: tf,
fiatTokenFactory: ctf,
stableTokenFactory: stf,
}
}

Expand All @@ -48,22 +53,22 @@ func (ad IsPausedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool
switch m := m.(type) {
case *banktypes.MsgSend:
for _, c := range m.Amount {
paused, err := checkPausedStatebyTokenFactory(ctx, c, ad.tokenFactory, ad.fiatTokenFactory)
paused, err := checkPausedStatebyTokenFactory(ctx, c, ad.tokenFactory, ad.fiatTokenFactory, ad.stableTokenFactory)
if paused {
return ctx, sdkerrors.Wrapf(err, "can not perform token transfers")
}
}
case *banktypes.MsgMultiSend:
for _, i := range m.Inputs {
for _, c := range i.Coins {
paused, err := checkPausedStatebyTokenFactory(ctx, c, ad.tokenFactory, ad.fiatTokenFactory)
paused, err := checkPausedStatebyTokenFactory(ctx, c, ad.tokenFactory, ad.fiatTokenFactory, ad.stableTokenFactory)
if paused {
return ctx, sdkerrors.Wrapf(err, "can not perform token transfers")
}
}
}
case *transfertypes.MsgTransfer:
paused, err := checkPausedStatebyTokenFactory(ctx, m.Token, ad.tokenFactory, ad.fiatTokenFactory)
paused, err := checkPausedStatebyTokenFactory(ctx, m.Token, ad.tokenFactory, ad.fiatTokenFactory, ad.stableTokenFactory)
if paused {
return ctx, sdkerrors.Wrapf(err, "can not perform token transfers")
}
Expand All @@ -77,7 +82,7 @@ func (ad IsPausedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool
return next(ctx, tx, simulate)
}

func checkPausedStatebyTokenFactory(ctx sdk.Context, c sdk.Coin, tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper) (bool, *sdkerrors.Error) {
func checkPausedStatebyTokenFactory(ctx sdk.Context, c sdk.Coin, tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper, stf *stabletokenfactorykeeper.Keeper) (bool, *sdkerrors.Error) {
tfMintingDenom := tf.GetMintingDenom(ctx)
if c.Denom == tfMintingDenom.Denom {
paused := tf.GetPaused(ctx)
Expand All @@ -92,18 +97,27 @@ func checkPausedStatebyTokenFactory(ctx sdk.Context, c sdk.Coin, tf *tokenfactor
return true, fiattokenfactorytypes.ErrPaused
}
}
stfMintingDenom := stf.GetMintingDenom(ctx)
if c.Denom == stfMintingDenom.Denom {
paused := stf.GetPaused(ctx)
if paused.Paused {
return true, stabletokenfactorytypes.ErrPaused
}
}
return false, nil
}

type IsBlacklistedDecorator struct {
tokenfactory *tokenfactory.Keeper
fiattokenfactory *fiattokenfactory.Keeper
tokenfactory *tokenfactory.Keeper
fiattokenfactory *fiattokenfactory.Keeper
stabletokenfactory *stabletokenfactorykeeper.Keeper
}

func NewIsBlacklistedDecorator(tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper) IsBlacklistedDecorator {
func NewIsBlacklistedDecorator(tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper, stf *stabletokenfactorykeeper.Keeper) IsBlacklistedDecorator {
return IsBlacklistedDecorator{
tokenfactory: tf,
fiattokenfactory: ctf,
tokenfactory: tf,
fiattokenfactory: ctf,
stabletokenfactory: stf,
}
}

Expand All @@ -116,7 +130,7 @@ func (ad IsBlacklistedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
case *banktypes.MsgSend:
for _, c := range m.Amount {
addresses := []string{m.ToAddress, m.FromAddress}
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory)
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory, ad.stabletokenfactory)
if blacklisted {
return ctx, sdkerrors.Wrapf(err, "an address (%s) is blacklisted and can not send or receive tokens", address)
}
Expand All @@ -128,7 +142,7 @@ func (ad IsBlacklistedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
for _, i := range m.Inputs {
for _, c := range i.Coins {
addresses := []string{i.Address}
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory)
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory, ad.stabletokenfactory)
if blacklisted {
return ctx, sdkerrors.Wrapf(err, "an address (%s) is blacklisted and can not send or receive tokens", address)
}
Expand All @@ -140,7 +154,7 @@ func (ad IsBlacklistedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
for _, o := range m.Outputs {
for _, c := range o.Coins {
addresses := []string{o.Address}
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory)
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, c, ad.tokenfactory, ad.fiattokenfactory, ad.stabletokenfactory)
if blacklisted {
return ctx, sdkerrors.Wrapf(err, "an address (%s) is blacklisted and can not send or receive tokens", address)
}
Expand All @@ -151,7 +165,7 @@ func (ad IsBlacklistedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
}
case *transfertypes.MsgTransfer:
addresses := []string{m.Sender, m.Receiver}
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, m.Token, ad.tokenfactory, ad.fiattokenfactory)
blacklisted, address, err := checkForBlacklistedAddressByTokenFactory(ctx, addresses, m.Token, ad.tokenfactory, ad.fiattokenfactory, ad.stabletokenfactory)
if blacklisted {
return ctx, sdkerrors.Wrapf(err, "an address (%s) is blacklisted and can not send or receive tokens", address)
}
Expand All @@ -168,7 +182,7 @@ func (ad IsBlacklistedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate

// checkForBlacklistedAddressByTokenFactory first checks if the denom being transacted is a mintable asset from a TokenFactory,
// if it is, it checks if the addresses involved in the tx are blacklisted by that specific TokenFactory.
func checkForBlacklistedAddressByTokenFactory(ctx sdk.Context, addresses []string, c sdk.Coin, tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper) (blacklisted bool, blacklistedAddress string, err error) {
func checkForBlacklistedAddressByTokenFactory(ctx sdk.Context, addresses []string, c sdk.Coin, tf *tokenfactory.Keeper, ctf *fiattokenfactory.Keeper, stf *stabletokenfactorykeeper.Keeper) (blacklisted bool, blacklistedAddress string, err error) {
tfMintingDenom := tf.GetMintingDenom(ctx)
if c.Denom == tfMintingDenom.Denom {
for _, address := range addresses {
Expand All @@ -195,6 +209,19 @@ func checkForBlacklistedAddressByTokenFactory(ctx sdk.Context, addresses []strin
}
}
}
stfMintingDenom := stf.GetMintingDenom(ctx)
if c.Denom == stfMintingDenom.Denom {
for _, address := range addresses {
_, addressBz, err := bech32.DecodeAndConvert(address)
if err != nil {
return false, address, err
}
_, found := stf.GetBlacklisted(ctx, addressBz)
if found {
return true, address, stabletokenfactorytypes.ErrUnauthorized
}
}
}
return false, "", nil
}

Expand Down Expand Up @@ -226,8 +253,8 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
ante.NewRejectExtensionOptionsDecorator(),
NewIsBlacklistedDecorator(options.tokenFactoryKeeper, options.fiatTokenFactoryKeeper),
NewIsPausedDecorator(options.tokenFactoryKeeper, options.fiatTokenFactoryKeeper),
NewIsBlacklistedDecorator(options.tokenFactoryKeeper, options.fiatTokenFactoryKeeper, options.stableTokenFactoryKeeper),
NewIsPausedDecorator(options.tokenFactoryKeeper, options.fiatTokenFactoryKeeper, options.stableTokenFactoryKeeper),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
Expand Down
Loading
Loading