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
11 changes: 0 additions & 11 deletions precompiles/bank/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol"

precompiletypes "github.com/zeta-chain/node/precompiles/types"
fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper"
Expand Down Expand Up @@ -53,7 +52,6 @@ type Contract struct {

bankKeeper bank.Keeper
fungibleKeeper fungiblekeeper.Keeper
zrc20ABI *abi.ABI
cdc codec.Codec
kvGasConfig storetypes.GasConfig
}
Expand All @@ -70,19 +68,10 @@ func NewIBankContract(
fungibleKeeper.GetAuthKeeper().SetAccount(ctx, authtypes.NewBaseAccount(accAddress, nil, 0, 0))
}

// Instantiate the ZRC20 ABI only one time.
// This avoids instantiating it every time deposit or withdraw are called.
zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi()
if err != nil {
ctx.Logger().Error("bank contract failed to get ZRC20 ABI", "error", err)
return nil
}

return &Contract{
BaseContract: precompiletypes.NewBaseContract(ContractAddress),
bankKeeper: bankKeeper,
fungibleKeeper: fungibleKeeper,
zrc20ABI: zrc20ABI,
cdc: cdc,
kvGasConfig: kvGasConfig,
}
Expand Down
18 changes: 2 additions & 16 deletions precompiles/bank/method_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,14 @@ func (c *Contract) deposit(

// Check for enough balance.
// function balanceOf(address account) public view virtual override returns (uint256)
resBalanceOf, err := c.CallContract(
ctx,
&c.fungibleKeeper,
c.zrc20ABI,
zrc20Addr,
"balanceOf",
[]interface{}{caller},
)
balance, err := c.fungibleKeeper.ZRC20BalanceOf(ctx, zrc20Addr, caller)
if err != nil {
return nil, &precompiletypes.ErrUnexpected{
When: "balanceOf",
Got: err.Error(),
}
}

balance, ok := resBalanceOf[0].(*big.Int)
if !ok {
return nil, &precompiletypes.ErrUnexpected{
Got: "ZRC20 balanceOf returned an unexpected type",
}
}

if balance.Cmp(amount) < 0 || balance.Cmp(big.NewInt(0)) <= 0 {
return nil, &precompiletypes.ErrInvalidAmount{
Got: balance.String(),
Expand All @@ -100,7 +86,7 @@ func (c *Contract) deposit(
}

// 2. Effect: subtract balance.
if err := c.fungibleKeeper.LockZRC20(ctx, c.zrc20ABI, zrc20Addr, c.Address(), caller, c.Address(), amount); err != nil {
if err := c.fungibleKeeper.LockZRC20(ctx, zrc20Addr, c.Address(), caller, c.Address(), amount); err != nil {
return nil, &precompiletypes.ErrUnexpected{
When: "LockZRC20InBank",
Got: err.Error(),
Expand Down
4 changes: 2 additions & 2 deletions precompiles/bank/method_withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (c *Contract) withdraw(
}

// Check if bank address has enough ZRC20 balance.
if err := c.fungibleKeeper.CheckZRC20Balance(ctx, c.zrc20ABI, zrc20Addr, c.Address(), amount); err != nil {
if err := c.fungibleKeeper.CheckZRC20Balance(ctx, zrc20Addr, c.Address(), amount); err != nil {
return nil, &precompiletypes.ErrInsufficientBalance{
Requested: amount.String(),
Got: err.Error(),
Expand All @@ -108,7 +108,7 @@ func (c *Contract) withdraw(
}

// 3. Interactions: send ZRC20.
if err := c.fungibleKeeper.UnlockZRC20(ctx, c.zrc20ABI, zrc20Addr, caller, c.Address(), amount); err != nil {
if err := c.fungibleKeeper.UnlockZRC20(ctx, zrc20Addr, caller, c.Address(), amount); err != nil {
return nil, &precompiletypes.ErrUnexpected{
When: "UnlockZRC20InBank",
Got: err.Error(),
Expand Down
2 changes: 1 addition & 1 deletion precompiles/staking/method_distribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (c *Contract) distribute(
// - spender is the staking contract address (c.Address()).
// - owner is the caller address.
// - locker is the bank address. Assets are locked under this address to prevent liquidity fragmentation.
if err := c.fungibleKeeper.LockZRC20(ctx, c.zrc20ABI, zrc20Addr, c.Address(), caller, bank.ContractAddress, amount); err != nil {
if err := c.fungibleKeeper.LockZRC20(ctx, zrc20Addr, c.Address(), caller, bank.ContractAddress, amount); err != nil {
return nil, &precompiletypes.ErrUnexpected{
When: "LockZRC20InBank",
Got: err.Error(),
Expand Down
11 changes: 0 additions & 11 deletions precompiles/staking/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol"

precompiletypes "github.com/zeta-chain/node/precompiles/types"
fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper"
Expand Down Expand Up @@ -66,7 +65,6 @@ type Contract struct {
stakingKeeper stakingkeeper.Keeper
fungibleKeeper fungiblekeeper.Keeper
bankKeeper bankkeeper.Keeper
zrc20ABI *abi.ABI
cdc codec.Codec
kvGasConfig storetypes.GasConfig
}
Expand All @@ -84,20 +82,11 @@ func NewIStakingContract(
fungibleKeeper.GetAuthKeeper().SetAccount(ctx, authtypes.NewBaseAccount(accAddress, nil, 0, 0))
}

// Instantiate the ZRC20 ABI only one time.
// This avoids instantiating it every time deposit or withdraw are called.
zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi()
if err != nil {
ctx.Logger().Error("staking contract failed to get ZRC20 ABI", "error", err)
return nil
}

return &Contract{
BaseContract: precompiletypes.NewBaseContract(ContractAddress),
stakingKeeper: *stakingKeeper,
fungibleKeeper: fungibleKeeper,
bankKeeper: bankKeeper,
zrc20ABI: zrc20ABI,
cdc: cdc,
kvGasConfig: kvGasConfig,
}
Expand Down
59 changes: 21 additions & 38 deletions x/fungible/keeper/zrc20_cosmos_coin_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,21 @@ func Test_LockZRC20(t *testing.T) {

t.Run("should fail when trying to lock zero amount", func(t *testing.T) {
// Check lock with zero amount.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, locker, owner, locker, big.NewInt(0))
err = ts.fungibleKeeper.LockZRC20(ts.ctx, ts.zrc20Address, locker, owner, locker, big.NewInt(0))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrInvalidAmount)
})

t.Run("should fail when ZRC20 ABI is not properly initialized", func(t *testing.T) {
// Check lock with nil ABI.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, nil, ts.zrc20Address, locker, owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20NilABI)
})

t.Run("should fail when trying to lock a zero address ZRC20", func(t *testing.T) {
// Check lock with ZRC20 zero address.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, common.Address{}, locker, owner, locker, big.NewInt(10))
err = ts.fungibleKeeper.LockZRC20(ts.ctx, common.Address{}, locker, owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20ZeroAddress)
})

t.Run("should fail when trying to lock a non whitelisted ZRC20", func(t *testing.T) {
// Check lock with non whitelisted ZRC20.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, sample.EthAddress(), locker, owner, locker, big.NewInt(10))
err = ts.fungibleKeeper.LockZRC20(ts.ctx, sample.EthAddress(), locker, owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20NotWhiteListed)
})
Expand All @@ -70,7 +63,6 @@ func Test_LockZRC20(t *testing.T) {
// Check lock with higher amount than totalSupply.
err = ts.fungibleKeeper.LockZRC20(
ts.ctx,
zrc20ABI,
ts.zrc20Address,
locker,
owner,
Expand All @@ -85,7 +77,7 @@ func Test_LockZRC20(t *testing.T) {
approveAllowance(t, ts, zrc20ABI, owner, locker, big.NewInt(1001))

// Check allowance smaller, equal and bigger than the amount.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, locker, owner, locker, big.NewInt(1001))
err = ts.fungibleKeeper.LockZRC20(ts.ctx, ts.zrc20Address, locker, owner, locker, big.NewInt(1001))
require.Error(t, err)

// We do not check in LockZRC20 explicitly if the amount is bigger than the balance.
Expand All @@ -97,22 +89,22 @@ func Test_LockZRC20(t *testing.T) {
approveAllowance(t, ts, zrc20ABI, owner, locker, allowanceTotal)

// Check allowance smaller, equal and bigger than the amount.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, locker, owner, locker, higherThanAllowance)
err = ts.fungibleKeeper.LockZRC20(ts.ctx, ts.zrc20Address, locker, owner, locker, higherThanAllowance)
require.Error(t, err)
require.Contains(t, err.Error(), "invalid allowance, got 100")
})

t.Run("should pass when trying to lock a valid approved amount", func(t *testing.T) {
approveAllowance(t, ts, zrc20ABI, owner, locker, allowanceTotal)

err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, locker, owner, locker, allowanceTotal)
err = ts.fungibleKeeper.LockZRC20(ts.ctx, ts.zrc20Address, locker, owner, locker, allowanceTotal)
require.NoError(t, err)

ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, owner)
ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, owner)
require.NoError(t, err)
require.Equal(t, uint64(900), ownerBalance.Uint64())

lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, locker)
lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, locker)
require.NoError(t, err)
require.Equal(t, uint64(100), lockerBalance.Uint64())
})
Expand All @@ -122,7 +114,6 @@ func Test_LockZRC20(t *testing.T) {

err = ts.fungibleKeeper.LockZRC20(
ts.ctx,
zrc20ABI,
ts.zrc20Address,
locker,
owner,
Expand All @@ -132,11 +123,11 @@ func Test_LockZRC20(t *testing.T) {
require.NoError(t, err)

// Note that balances are cumulative for all tests. That's why we check 801 and 199 here.
ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, owner)
ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, owner)
require.NoError(t, err)
require.Equal(t, uint64(801), ownerBalance.Uint64())

lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, locker)
lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, locker)
require.NoError(t, err)
require.Equal(t, uint64(199), lockerBalance.Uint64())
})
Expand Down Expand Up @@ -164,48 +155,42 @@ func Test_UnlockZRC20(t *testing.T) {
approveAllowance(t, ts, zrc20ABI, owner, locker, allowanceTotal)

// Lock 100 ZRC20.
err = ts.fungibleKeeper.LockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, locker, owner, locker, allowanceTotal)
err = ts.fungibleKeeper.LockZRC20(ts.ctx, ts.zrc20Address, locker, owner, locker, allowanceTotal)
require.NoError(t, err)

t.Run("should fail when trying to unlock zero amount", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, owner, locker, big.NewInt(0))
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, ts.zrc20Address, owner, locker, big.NewInt(0))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrInvalidAmount)
})

t.Run("should fail when ZRC20 ABI is not properly initialized", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, nil, ts.zrc20Address, owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20NilABI)
})

t.Run("should fail when trying to unlock a zero address ZRC20", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, zrc20ABI, common.Address{}, owner, locker, big.NewInt(10))
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, common.Address{}, owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20ZeroAddress)
})

t.Run("should fail when trying to unlock a non whitelisted ZRC20", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, zrc20ABI, sample.EthAddress(), owner, locker, big.NewInt(10))
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, sample.EthAddress(), owner, locker, big.NewInt(10))
require.Error(t, err)
require.ErrorIs(t, err, fungibletypes.ErrZRC20NotWhiteListed)
})

t.Run("should fail when trying to unlock an amount bigger than locker's balance", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, owner, locker, big.NewInt(1001))
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, ts.zrc20Address, owner, locker, big.NewInt(1001))
require.Error(t, err)
require.Contains(t, err.Error(), "invalid balance, got 100")
})

t.Run("should pass when trying to unlock a correct amount", func(t *testing.T) {
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, zrc20ABI, ts.zrc20Address, owner, locker, allowanceTotal)
err = ts.fungibleKeeper.UnlockZRC20(ts.ctx, ts.zrc20Address, owner, locker, allowanceTotal)
require.NoError(t, err)

ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, owner)
ownerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, owner)
require.NoError(t, err)
require.Equal(t, uint64(1000), ownerBalance.Uint64())

lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, locker)
lockerBalance, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, locker)
require.NoError(t, err)
require.Equal(t, uint64(0), lockerBalance.Uint64())
})
Expand All @@ -232,13 +217,13 @@ func Test_CheckZRC20Allowance(t *testing.T) {
ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, fungibletypes.ModuleAddressEVM, depositTotal)

t.Run("should fail when checking zero amount", func(t *testing.T) {
err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, zrc20ABI, owner, spender, ts.zrc20Address, big.NewInt(0))
err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, owner, spender, ts.zrc20Address, big.NewInt(0))
require.Error(t, err)
require.ErrorAs(t, err, &fungibletypes.ErrInvalidAmount)
})

t.Run("should fail when allowance is not approved", func(t *testing.T) {
err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, zrc20ABI, owner, spender, ts.zrc20Address, big.NewInt(10))
err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, owner, spender, ts.zrc20Address, big.NewInt(10))
require.Error(t, err)
require.Contains(t, err.Error(), "invalid allowance, got 0")
})
Expand All @@ -248,7 +233,6 @@ func Test_CheckZRC20Allowance(t *testing.T) {

err = ts.fungibleKeeper.CheckZRC20Allowance(
ts.ctx,
zrc20ABI,
owner,
spender,
ts.zrc20Address,
Expand All @@ -261,7 +245,7 @@ func Test_CheckZRC20Allowance(t *testing.T) {
t.Run("should pass when checking the same amount as approved", func(t *testing.T) {
approveAllowance(t, ts, zrc20ABI, owner, spender, allowanceTotal)

err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, zrc20ABI, owner, spender, ts.zrc20Address, allowanceTotal)
err = ts.fungibleKeeper.CheckZRC20Allowance(ts.ctx, owner, spender, ts.zrc20Address, allowanceTotal)
require.NoError(t, err)
})

Expand All @@ -270,7 +254,6 @@ func Test_CheckZRC20Allowance(t *testing.T) {

err = ts.fungibleKeeper.CheckZRC20Allowance(
ts.ctx,
zrc20ABI,
owner,
spender,
ts.zrc20Address,
Expand Down
Loading