Skip to content
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
18 changes: 18 additions & 0 deletions testutil/keeper/mocks/fungible/bank.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions x/fungible/keeper/deposits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ func TestKeeper_DepositCoinZeta(t *testing.T) {
b := sdkk.BankKeeper.GetBalance(ctx, zetaToAddress, config.BaseDenom)
require.Equal(t, int64(0), b.Amount.Int64())
errorMint := errors.New("", 1, "error minting coins")

bankMock.On("GetSupply", ctx, mock.Anything, mock.Anything).
Return(sdk.NewCoin(config.BaseDenom, sdk.NewInt(0))).
Once()
bankMock.On("MintCoins", ctx, types.ModuleName, mock.Anything).Return(errorMint).Once()
err := k.DepositCoinZeta(ctx, to, amount)
require.ErrorIs(t, err, errorMint)
Expand Down
27 changes: 27 additions & 0 deletions x/fungible/keeper/zeta.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"fmt"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -9,9 +10,17 @@ import (
"github.com/zeta-chain/node/x/fungible/types"
)

// ZETAMaxSupplyStr is the maximum mintable ZETA in the fungible module
// 1.85 billion ZETA
const ZETAMaxSupplyStr = "1850000000000000000000000000"

// MintZetaToEVMAccount mints ZETA (gas token) to the given address
// NOTE: this method should be used with a temporary context, and it should not be committed if the method returns an error
func (k *Keeper) MintZetaToEVMAccount(ctx sdk.Context, to sdk.AccAddress, amount *big.Int) error {
if err := k.validateZetaSupply(ctx, amount); err != nil {
return err
}

coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(amount)))
// Mint coins
if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins); err != nil {
Expand All @@ -23,7 +32,25 @@ func (k *Keeper) MintZetaToEVMAccount(ctx sdk.Context, to sdk.AccAddress, amount
}

func (k *Keeper) MintZetaToFungibleModule(ctx sdk.Context, amount *big.Int) error {
if err := k.validateZetaSupply(ctx, amount); err != nil {
return err
}

coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(amount)))
// Mint coins
return k.bankKeeper.MintCoins(ctx, types.ModuleName, coins)
}

// validateZetaSupply checks if the minted ZETA amount exceeds the maximum supply
func (k *Keeper) validateZetaSupply(ctx sdk.Context, amount *big.Int) error {
zetaMaxSupply, ok := sdk.NewIntFromString(ZETAMaxSupplyStr)
if !ok {
return fmt.Errorf("failed to parse ZETA max supply: %s", ZETAMaxSupplyStr)
}

supply := k.bankKeeper.GetSupply(ctx, config.BaseDenom)
if supply.Amount.Add(sdk.NewIntFromBigInt(amount)).GT(zetaMaxSupply) {
return types.ErrMaxSupplyReached
}
return nil
}
78 changes: 78 additions & 0 deletions x/fungible/keeper/zeta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper_test

import (
"errors"
"github.com/stretchr/testify/mock"
"math/big"
"testing"

Expand All @@ -11,6 +12,7 @@ import (
"github.com/zeta-chain/node/cmd/zetacored/config"
testkeeper "github.com/zeta-chain/node/testutil/keeper"
"github.com/zeta-chain/node/testutil/sample"
"github.com/zeta-chain/node/x/fungible/keeper"
"github.com/zeta-chain/node/x/fungible/types"
)

Expand All @@ -29,13 +31,56 @@ func TestKeeper_MintZetaToEVMAccount(t *testing.T) {
require.True(t, bal.Amount.Equal(sdk.NewInt(42)))
})

t.Run("mint the token to reach max supply", func(t *testing.T) {
k, ctx, sdkk, _ := testkeeper.FungibleKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

acc := sample.Bech32AccAddress()
bal := sdkk.BankKeeper.GetBalance(ctx, acc, config.BaseDenom)
require.True(t, bal.IsZero())

zetaMaxSupply, ok := sdk.NewIntFromString(keeper.ZETAMaxSupplyStr)
require.True(t, ok)

supply := sdkk.BankKeeper.GetSupply(ctx, config.BaseDenom).Amount

newAmount := zetaMaxSupply.Sub(supply)

err := k.MintZetaToEVMAccount(ctx, acc, newAmount.BigInt())
require.NoError(t, err)
bal = sdkk.BankKeeper.GetBalance(ctx, acc, config.BaseDenom)
require.True(t, bal.Amount.Equal(newAmount))
})

t.Run("can't mint more than max supply", func(t *testing.T) {
k, ctx, sdkk, _ := testkeeper.FungibleKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

acc := sample.Bech32AccAddress()
bal := sdkk.BankKeeper.GetBalance(ctx, acc, config.BaseDenom)
require.True(t, bal.IsZero())

zetaMaxSupply, ok := sdk.NewIntFromString(keeper.ZETAMaxSupplyStr)
require.True(t, ok)

supply := sdkk.BankKeeper.GetSupply(ctx, config.BaseDenom).Amount

newAmount := zetaMaxSupply.Sub(supply).Add(sdk.NewInt(1))

err := k.MintZetaToEVMAccount(ctx, acc, newAmount.BigInt())
require.ErrorIs(t, err, types.ErrMaxSupplyReached)
})

coins42 := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewInt(42)))

t.Run("should fail if minting fail", func(t *testing.T) {
k, ctx := testkeeper.FungibleKeeperAllMocks(t)

mockBankKeeper := testkeeper.GetFungibleBankMock(t, k)

mockBankKeeper.On("GetSupply", ctx, mock.Anything, mock.Anything).
Return(sdk.NewCoin(config.BaseDenom, sdk.NewInt(0))).
Once()
mockBankKeeper.On(
"MintCoins",
ctx,
Expand All @@ -55,6 +100,9 @@ func TestKeeper_MintZetaToEVMAccount(t *testing.T) {

mockBankKeeper := testkeeper.GetFungibleBankMock(t, k)

mockBankKeeper.On("GetSupply", ctx, mock.Anything, mock.Anything).
Return(sdk.NewCoin(config.BaseDenom, sdk.NewInt(0))).
Once()
mockBankKeeper.On(
"MintCoins",
ctx,
Expand All @@ -76,3 +124,33 @@ func TestKeeper_MintZetaToEVMAccount(t *testing.T) {
mockBankKeeper.AssertExpectations(t)
})
}

func TestKeeper_MintZetaToFungibleModule(t *testing.T) {
t.Run("should mint the token in the specified balance", func(t *testing.T) {
k, ctx, sdkk, _ := testkeeper.FungibleKeeper(t)
acc := k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName).GetAddress()

bal := sdkk.BankKeeper.GetBalance(ctx, acc, config.BaseDenom)
require.True(t, bal.IsZero())

err := k.MintZetaToEVMAccount(ctx, acc, big.NewInt(42))
require.NoError(t, err)
bal = sdkk.BankKeeper.GetBalance(ctx, acc, config.BaseDenom)
require.True(t, bal.Amount.Equal(sdk.NewInt(42)))
})

t.Run("can't mint more than max supply", func(t *testing.T) {
k, ctx, sdkk, _ := testkeeper.FungibleKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

zetaMaxSupply, ok := sdk.NewIntFromString(keeper.ZETAMaxSupplyStr)
require.True(t, ok)

supply := sdkk.BankKeeper.GetSupply(ctx, config.BaseDenom).Amount

newAmount := zetaMaxSupply.Sub(supply).Add(sdk.NewInt(1))

err := k.MintZetaToFungibleModule(ctx, newAmount.BigInt())
require.ErrorIs(t, err, types.ErrMaxSupplyReached)
})
}
6 changes: 6 additions & 0 deletions x/fungible/keeper/zevm_message_passing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ func TestKeeper_ZEVMDepositAndCallContract(t *testing.T) {
})
require.NoError(t, err)
errorMint := errors.New("", 10, "error minting coins")
bankMock.On("GetSupply", ctx, mock.Anything, mock.Anything).
Return(sdk.NewCoin(config.BaseDenom, sdk.NewInt(0))).
Once()
bankMock.On("MintCoins", ctx, types.ModuleName, mock.Anything).Return(errorMint).Once()

_, err = k.ZETADepositAndCallContract(
Expand Down Expand Up @@ -296,6 +299,9 @@ func TestKeeper_ZEVMRevertAndCallContract(t *testing.T) {
})
require.NoError(t, err)
errorMint := errors.New("", 101, "error minting coins")
bankMock.On("GetSupply", ctx, mock.Anything, mock.Anything).
Return(sdk.NewCoin(config.BaseDenom, sdk.NewInt(0))).
Once()
bankMock.On("MintCoins", ctx, types.ModuleName, mock.Anything).Return(errorMint).Once()

_, err = k.ZETARevertAndCallContract(
Expand Down
1 change: 1 addition & 0 deletions x/fungible/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ var (
ErrZRC20NilABI = cosmoserrors.Register(ModuleName, 1132, "ZRC20 ABI is nil")
ErrZeroAddress = cosmoserrors.Register(ModuleName, 1133, "address cannot be zero")
ErrInvalidAmount = cosmoserrors.Register(ModuleName, 1134, "invalid amount")
ErrMaxSupplyReached = cosmoserrors.Register(ModuleName, 1135, "max supply reached")
)
1 change: 1 addition & 0 deletions x/fungible/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type BankKeeper interface {
amt sdk.Coins,
) error
MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error
GetSupply(ctx sdk.Context, denom string) sdk.Coin
}

type ObserverKeeper interface {
Expand Down