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

Block DEX for tokens with block_smart_contracts feature calling from the smart contracts. #1015

Merged
merged 7 commits into from
Nov 5, 2024
25 changes: 19 additions & 6 deletions x/asset/ft/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@
func (k Keeper) DEXIncreaseLimits(
ctx sdk.Context, addr sdk.AccAddress, lockCoin, reserveWhitelistingCoin sdk.Coin,
) error {
if err := k.dexChecksForDenoms(ctx, []string{lockCoin.Denom, reserveWhitelistingCoin.Denom}); err != nil {
if err := k.dexChecksForDenoms(ctx, addr, lockCoin.Denom, reserveWhitelistingCoin.Denom); err != nil {
return err
}

Expand Down Expand Up @@ -754,7 +754,7 @@
func (k Keeper) DEXChecksLimitsAndSend(
ctx sdk.Context, fromAddr, toAddr sdk.AccAddress, sendCoin, checkReserveWhitelistingCoin sdk.Coin,
) error {
if err := k.dexChecksForDenoms(ctx, []string{sendCoin.Denom, checkReserveWhitelistingCoin.Denom}); err != nil {
if err := k.dexChecksForDenoms(ctx, fromAddr, sendCoin.Denom, checkReserveWhitelistingCoin.Denom); err != nil {
return err
}

Expand Down Expand Up @@ -1631,7 +1631,10 @@
return nil
}

func (k Keeper) dexChecksForDenoms(ctx sdk.Context, denoms []string) error {
func (k Keeper) dexChecksForDenoms(
ctx sdk.Context, acc sdk.AccAddress, spendDenom, receiveDenom string,
) error {
denoms := []string{spendDenom, receiveDenom}
for _, denom := range denoms {
def, err := k.getDefinitionOrNil(ctx, denom)
if err != nil {
Expand All @@ -1642,15 +1645,25 @@
if def.ExtensionCWAddress != "" {
return sdkerrors.Wrapf(
types.ErrInvalidInput,
"failed to DEX lock %s, not supported for the tokens with extensions",
"usage of %s is not supported for DEX, the token has extensions",

Check warning on line 1648 in x/asset/ft/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/asset/ft/keeper/keeper.go#L1648

Added line #L1648 was not covered by tests
def.Denom,
)
}
if def.IsFeatureEnabled(types.Feature_dex_block) {
return sdkerrors.Wrapf(
cosmoserrors.ErrUnauthorized,
"locking coins for DEX disabled for %s",
def.Denom,
"usage of %s is not supported for DEX, the token has %s feature enabled",
def.Denom, types.Feature_dex_block.String(),
)
}

Check warning on line 1658 in x/asset/ft/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/asset/ft/keeper/keeper.go#L1655-L1658

Added lines #L1655 - L1658 were not covered by tests
// don't allow the smart contract to use the denom with Feature_block_smart_contracts if not admin
if def.IsFeatureEnabled(types.Feature_block_smart_contracts) &&
!def.HasAdminPrivileges(acc) &&
cwasmtypes.IsTriggeredBySmartContract(ctx) {
return sdkerrors.Wrapf(
cosmoserrors.ErrUnauthorized,
"usage of %s is not supported for DEX in smart contract, the token has %s feature enabled",
def.Denom, types.Feature_block_smart_contracts.String(),

Check warning on line 1666 in x/asset/ft/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/asset/ft/keeper/keeper.go#L1663-L1666

Added lines #L1663 - L1666 were not covered by tests
)
}
}
Expand Down
67 changes: 65 additions & 2 deletions x/asset/ft/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper_test

import (
"fmt"
cwasmtypes "github.com/CoreumFoundation/coreum/v5/x/wasm/types"
"math"
"slices"
"strings"
Expand Down Expand Up @@ -1952,7 +1953,69 @@ func TestKeeper_DEXLockAndUnlock(t *testing.T) {
requireT.NoError(bankKeeper.SendCoins(ctx, issuer, acc, sdk.NewCoins(extensionCoin)))
requireT.ErrorContains(
ftKeeper.DEXIncreaseLimits(ctx, acc, extensionCoin, sdk.NewInt64Coin(denom1, 1)),
"not supported for the tokens with extensions",
"the token has extensions",
)
}

func TestKeeper_DEXBlockSmartContracts(t *testing.T) {
requireT := require.New(t)

testApp := simapp.New()
ctx := testApp.BaseApp.NewContextLegacy(false, tmproto.Header{
Time: time.Now(),
AppHash: []byte("some-hash"),
})

ftKeeper := testApp.AssetFTKeeper
bankKeeper := testApp.BankKeeper

issuer := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
acc := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())

settings := types.IssueSettings{
Issuer: issuer,
Symbol: "DEFBLK",
Subunit: "defblk",
Precision: 6,
InitialAmount: sdkmath.NewIntWithDecimal(1, 10),
Features: []types.Feature{
types.Feature_block_smart_contracts,
},
}
denom, err := ftKeeper.Issue(ctx, settings)
requireT.NoError(err)
blockSmartContractCoin := sdk.NewInt64Coin(denom, 50)
requireT.NoError(bankKeeper.SendCoins(ctx, issuer, acc, sdk.NewCoins(blockSmartContractCoin)))
// triggered from native call
requireT.NoError(ftKeeper.DEXIncreaseLimits(ctx, acc, blockSmartContractCoin, sdk.NewInt64Coin(denom1, 1)))

ctxFromSmartContract := cwasmtypes.WithSmartContractSender(ctx, acc.String())
blockingErr := fmt.Sprintf("usage of %s is not supported for DEX in smart contract", denom)
requireT.ErrorContains(
ftKeeper.DEXIncreaseLimits(ctxFromSmartContract, acc, blockSmartContractCoin, sdk.NewInt64Coin(denom1, 1)),
blockingErr,
)
requireT.ErrorContains(
ftKeeper.DEXIncreaseLimits(ctxFromSmartContract, acc, sdk.NewInt64Coin(denom1, 1), blockSmartContractCoin),
blockingErr,
)
// same check for DEXChecksLimitsAndSend
requireT.ErrorContains(
ftKeeper.DEXChecksLimitsAndSend(ctxFromSmartContract, acc, acc, blockSmartContractCoin, sdk.NewInt64Coin(denom1, 1)),
blockingErr,
)
requireT.ErrorContains(
ftKeeper.DEXChecksLimitsAndSend(ctxFromSmartContract, acc, acc, sdk.NewInt64Coin(denom1, 1), blockSmartContractCoin),
blockingErr,
)

// but still allowed to lock by admin
testApp.MintAndSendCoin(t, ctxFromSmartContract, issuer, sdk.NewCoins(sdk.NewInt64Coin(denom1, 1)))
requireT.NoError(
ftKeeper.DEXChecksLimitsAndSend(ctxFromSmartContract, issuer, issuer, sdk.NewInt64Coin(denom1, 1), blockSmartContractCoin),
)
requireT.NoError(
ftKeeper.DEXIncreaseLimits(ctxFromSmartContract, issuer, sdk.NewInt64Coin(denom1, 1), blockSmartContractCoin),
)
}

Expand Down Expand Up @@ -1993,7 +2056,7 @@ func TestKeeper_DEXSettings_BlockDEX(t *testing.T) {
ft1Denom, err := ftKeeper.Issue(ctx, ft1Settings)
requireT.NoError(err)

errStr := fmt.Sprintf("locking coins for DEX disabled for %s", ft1Denom)
errStr := fmt.Sprintf("usage of %s is not supported for DEX, the token has dex_block", ft1Denom)
requireT.ErrorContains(ftKeeper.DEXIncreaseLimits(
ctx, acc, sdk.NewInt64Coin(ft1Denom, 50), sdk.NewInt64Coin(denom1, 1),
), errStr)
Expand Down
4 changes: 2 additions & 2 deletions x/dex/keeper/keeper_ft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestKeeper_PlaceOrderWithExtension(t *testing.T) {
require.NoError(t, testApp.BankKeeper.SendCoins(sdkCtx, issuer, acc, sdk.NewCoins(lockedBalance)))
fundOrderReserve(t, testApp, sdkCtx, acc)

require.ErrorContains(t, testApp.DEXKeeper.PlaceOrder(sdkCtx, order), "not supported for the tokens with extensions")
require.ErrorContains(t, testApp.DEXKeeper.PlaceOrder(sdkCtx, order), "is not supported for DEX, the token has extensions")
}

func TestKeeper_PlaceOrderWithDEXBlockFeature(t *testing.T) {
Expand Down Expand Up @@ -116,7 +116,7 @@ func TestKeeper_PlaceOrderWithDEXBlockFeature(t *testing.T) {
require.NoError(t, err)
require.NoError(t, testApp.BankKeeper.SendCoins(sdkCtx, issuer, acc, sdk.NewCoins(lockedBalance)))
fundOrderReserve(t, testApp, sdkCtx, acc)
errStr := fmt.Sprintf("locking coins for DEX disabled for %s", denomWithExtension)
errStr := fmt.Sprintf("usage of %s is not supported for DEX, the token has dex_block", denomWithExtension)
require.ErrorContains(t, testApp.DEXKeeper.PlaceOrder(sdkCtx, order), errStr)

// use the denomWithExtension as quote
Expand Down
4 changes: 1 addition & 3 deletions x/dex/types/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ const (
orderedBytesPriceSize = store.Int8OrderedBytesSize + store.Uint64OrderedBytesSize
)

var (
priceRegex = regexp.MustCompile(`^(([1-9])|([1-9]\d*[1-9]))(e-?[1-9]\d*)?$`)
)
var priceRegex = regexp.MustCompile(`^(([1-9])|([1-9]\d*[1-9]))(e-?[1-9]\d*)?$`)

// Price is the price type.
type Price struct {
Expand Down
Loading