Skip to content

Commit

Permalink
feat: add Stable token factory (backport #269) (#272)
Browse files Browse the repository at this point in the history
Co-authored-by: John Letey <john@nobleassets.xyz>
  • Loading branch information
mergify[bot] and johnletey authored Nov 14, 2023
1 parent 60c6f1b commit e6fe594
Show file tree
Hide file tree
Showing 213 changed files with 24,134 additions and 708 deletions.
1 change: 1 addition & 0 deletions .changelog/unreleased/features/269-stable-token-factory.md
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

0 comments on commit e6fe594

Please sign in to comment.