diff --git a/precompiles/bank/bank.go b/precompiles/bank/bank.go index b92b4a8217..63311ca8e7 100644 --- a/precompiles/bank/bank.go +++ b/precompiles/bank/bank.go @@ -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" @@ -53,7 +52,6 @@ type Contract struct { bankKeeper bank.Keeper fungibleKeeper fungiblekeeper.Keeper - zrc20ABI *abi.ABI cdc codec.Codec kvGasConfig storetypes.GasConfig } @@ -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, } diff --git a/precompiles/bank/method_deposit.go b/precompiles/bank/method_deposit.go index 76c21d926a..43ba2a492f 100644 --- a/precompiles/bank/method_deposit.go +++ b/precompiles/bank/method_deposit.go @@ -61,14 +61,7 @@ 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", @@ -76,13 +69,6 @@ func (c *Contract) deposit( } } - 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(), @@ -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(), diff --git a/precompiles/bank/method_withdraw.go b/precompiles/bank/method_withdraw.go index a1308146c1..24f83bf5e4 100644 --- a/precompiles/bank/method_withdraw.go +++ b/precompiles/bank/method_withdraw.go @@ -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(), @@ -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(), diff --git a/precompiles/staking/method_distribute.go b/precompiles/staking/method_distribute.go index 1fa7351505..c173517aeb 100644 --- a/precompiles/staking/method_distribute.go +++ b/precompiles/staking/method_distribute.go @@ -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(), diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go index 3408a2b09e..4d8115336a 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -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" @@ -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 } @@ -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, } diff --git a/x/fungible/keeper/zrc20_cosmos_coin_mapping_test.go b/x/fungible/keeper/zrc20_cosmos_coin_mapping_test.go index 16803a917c..c19866e217 100644 --- a/x/fungible/keeper/zrc20_cosmos_coin_mapping_test.go +++ b/x/fungible/keeper/zrc20_cosmos_coin_mapping_test.go @@ -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) }) @@ -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, @@ -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. @@ -97,7 +89,7 @@ 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") }) @@ -105,14 +97,14 @@ func Test_LockZRC20(t *testing.T) { 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()) }) @@ -122,7 +114,6 @@ func Test_LockZRC20(t *testing.T) { err = ts.fungibleKeeper.LockZRC20( ts.ctx, - zrc20ABI, ts.zrc20Address, locker, owner, @@ -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()) }) @@ -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()) }) @@ -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") }) @@ -248,7 +233,6 @@ func Test_CheckZRC20Allowance(t *testing.T) { err = ts.fungibleKeeper.CheckZRC20Allowance( ts.ctx, - zrc20ABI, owner, spender, ts.zrc20Address, @@ -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) }) @@ -270,7 +254,6 @@ func Test_CheckZRC20Allowance(t *testing.T) { err = ts.fungibleKeeper.CheckZRC20Allowance( ts.ctx, - zrc20ABI, owner, spender, ts.zrc20Address, diff --git a/x/fungible/keeper/zrc20_cosmos_coins_mapping.go b/x/fungible/keeper/zrc20_cosmos_coins_mapping.go index 7ac3d7ef22..ddf86c7531 100644 --- a/x/fungible/keeper/zrc20_cosmos_coins_mapping.go +++ b/x/fungible/keeper/zrc20_cosmos_coins_mapping.go @@ -6,7 +6,6 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/node/pkg/crypto" @@ -19,27 +18,26 @@ import ( // it has to be implemented by the caller of this function. func (k Keeper) LockZRC20( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, spender, owner, locker common.Address, amount *big.Int, ) error { // owner is the EOA owner of the ZRC20 tokens. // spender is the EOA allowed to spend ZRC20 on owner's behalf. // locker is the address that will lock the ZRC20 tokens, i.e: bank precompile. - if err := k.CheckZRC20Allowance(ctx, zrc20ABI, owner, spender, zrc20Address, amount); err != nil { + if err := k.CheckZRC20Allowance(ctx, owner, spender, zrc20Address, amount); err != nil { return errors.Wrap(err, "failed allowance check") } // Check amount_to_be_locked <= total_erc20_balance - already_locked // Max amount of ZRC20 tokens that exists in zEVM are the total supply. - totalSupply, err := k.ZRC20TotalSupply(ctx, zrc20ABI, zrc20Address) + totalSupply, err := k.ZRC20TotalSupply(ctx, zrc20Address) if err != nil { return errors.Wrap(err, "failed totalSupply check") } // The alreadyLocked amount is the amount of ZRC20 tokens that have been locked by the locker. // TODO: Implement list of whitelisted locker addresses (https://github.com/zeta-chain/node/issues/2991) - alreadyLocked, err := k.ZRC20BalanceOf(ctx, zrc20ABI, zrc20Address, locker) + alreadyLocked, err := k.ZRC20BalanceOf(ctx, zrc20Address, locker) if err != nil { return errors.Wrap(err, "failed getting the ZRC20 already locked amount") } @@ -50,7 +48,7 @@ func (k Keeper) LockZRC20( // Initiate a transferFrom the owner to the locker. This will lock the ZRC20 tokens. // locker has to initiate the transaction and have enough allowance from owner. - transferred, err := k.ZRC20TransferFrom(ctx, zrc20ABI, zrc20Address, spender, owner, locker, amount) + transferred, err := k.ZRC20TransferFrom(ctx, zrc20Address, spender, owner, locker, amount) if err != nil { return errors.Wrap(err, "failed executing transferFrom") } @@ -67,17 +65,16 @@ func (k Keeper) LockZRC20( // the owner has enough collateral (cosmos coins) to be exchanged (burnt) for the ZRC20 tokens. func (k Keeper) UnlockZRC20( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, owner, locker common.Address, amount *big.Int, ) error { // Check if the account locking the ZRC20 tokens has enough balance. - if err := k.CheckZRC20Balance(ctx, zrc20ABI, zrc20Address, locker, amount); err != nil { + if err := k.CheckZRC20Balance(ctx, zrc20Address, locker, amount); err != nil { return errors.Wrap(err, "failed balance check") } // transfer from the EOA locking the assets to the owner. - transferred, err := k.ZRC20Transfer(ctx, zrc20ABI, zrc20Address, locker, owner, amount) + transferred, err := k.ZRC20Transfer(ctx, zrc20Address, locker, owner, amount) if err != nil { return errors.Wrap(err, "failed executing transfer") } @@ -93,14 +90,9 @@ func (k Keeper) UnlockZRC20( // is equal or greater than the provided amount. func (k Keeper) CheckZRC20Allowance( ctx sdk.Context, - zrc20ABI *abi.ABI, owner, spender, zrc20Address common.Address, amount *big.Int, ) error { - if zrc20ABI == nil { - return fungibletypes.ErrZRC20NilABI - } - if amount.Sign() <= 0 || amount == nil { return fungibletypes.ErrInvalidAmount } @@ -113,7 +105,7 @@ func (k Keeper) CheckZRC20Allowance( return errors.Wrap(err, "ZRC20 is not valid") } - allowanceValue, err := k.ZRC20Allowance(ctx, zrc20ABI, zrc20Address, owner, spender) + allowanceValue, err := k.ZRC20Allowance(ctx, zrc20Address, owner, spender) if err != nil { return errors.Wrap(err, "failed while checking spender's allowance") } @@ -129,14 +121,9 @@ func (k Keeper) CheckZRC20Allowance( // is equal or greater than the provided amount. func (k Keeper) CheckZRC20Balance( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, owner common.Address, amount *big.Int, ) error { - if zrc20ABI == nil { - return fungibletypes.ErrZRC20NilABI - } - if amount.Sign() <= 0 || amount == nil { return fungibletypes.ErrInvalidAmount } @@ -151,7 +138,7 @@ func (k Keeper) CheckZRC20Balance( // Check the ZRC20 balance of a given account. // function balanceOf(address account) - balance, err := k.ZRC20BalanceOf(ctx, zrc20ABI, zrc20Address, owner) + balance, err := k.ZRC20BalanceOf(ctx, zrc20Address, owner) if err != nil { return errors.Wrap(err, "failed getting owner's ZRC20 balance") } diff --git a/x/fungible/keeper/zrc20_methods.go b/x/fungible/keeper/zrc20_methods.go index 5c9f2d4645..4d7c7f5174 100644 --- a/x/fungible/keeper/zrc20_methods.go +++ b/x/fungible/keeper/zrc20_methods.go @@ -6,8 +6,8 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" "github.com/zeta-chain/node/pkg/crypto" fungibletypes "github.com/zeta-chain/node/x/fungible/types" @@ -25,11 +25,11 @@ const ( // The allowance has to be previously approved by the ZRC20 tokens owner. func (k Keeper) ZRC20Allowance( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, owner, spender common.Address, ) (*big.Int, error) { - if zrc20ABI == nil { - return nil, fungibletypes.ErrZRC20NilABI + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err } if crypto.IsEmptyAddress(owner) || crypto.IsEmptyAddress(spender) { @@ -82,11 +82,11 @@ func (k Keeper) ZRC20Allowance( // ZRC20BalanceOf checks the ZRC20 balance of a given EOA. func (k Keeper) ZRC20BalanceOf( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, owner common.Address, ) (*big.Int, error) { - if zrc20ABI == nil { - return nil, fungibletypes.ErrZRC20NilABI + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err } if crypto.IsEmptyAddress(owner) { @@ -138,11 +138,11 @@ func (k Keeper) ZRC20BalanceOf( // ZRC20TotalSupply returns the total supply of a ZRC20 token. func (k Keeper) ZRC20TotalSupply( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address common.Address, ) (*big.Int, error) { - if zrc20ABI == nil { - return nil, fungibletypes.ErrZRC20NilABI + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err } if err := k.IsValidZRC20(ctx, zrc20Address); err != nil { @@ -189,12 +189,12 @@ func (k Keeper) ZRC20TotalSupply( // ZRC20Transfer transfers ZRC20 tokens from the sender to the recipient. func (k Keeper) ZRC20Transfer( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, from, to common.Address, amount *big.Int, ) (bool, error) { - if zrc20ABI == nil { - return false, fungibletypes.ErrZRC20NilABI + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return false, err } if crypto.IsEmptyAddress(from) || crypto.IsEmptyAddress(to) { @@ -249,12 +249,12 @@ func (k Keeper) ZRC20Transfer( // Requisite: the original EOA must have approved the spender to spend the tokens. func (k Keeper) ZRC20TransferFrom( ctx sdk.Context, - zrc20ABI *abi.ABI, zrc20Address, spender, from, to common.Address, amount *big.Int, ) (bool, error) { - if zrc20ABI == nil { - return false, fungibletypes.ErrZRC20NilABI + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return false, err } if crypto.IsEmptyAddress(from) || crypto.IsEmptyAddress(to) || crypto.IsEmptyAddress(spender) { diff --git a/x/fungible/keeper/zrc20_methods_test.go b/x/fungible/keeper/zrc20_methods_test.go index 7b124f3050..3d64a05928 100644 --- a/x/fungible/keeper/zrc20_methods_test.go +++ b/x/fungible/keeper/zrc20_methods_test.go @@ -14,23 +14,11 @@ import ( ) func Test_ZRC20Allowance(t *testing.T) { - // Instantiate the ZRC20 ABI only one time. - // This avoids instantiating it every time deposit or withdraw are called. - zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() - require.NoError(t, err) - ts := setupChain(t) - t.Run("should fail when ZRC20ABI is nil", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20Allowance(ts.ctx, nil, ts.zrc20Address, common.Address{}, common.Address{}) - require.Error(t, err) - require.ErrorAs(t, err, &fungibletypes.ErrZRC20NilABI) - }) - t.Run("should fail when owner is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Allowance( ts.ctx, - zrc20ABI, ts.zrc20Address, common.Address{}, sample.EthAddress(), @@ -42,7 +30,6 @@ func Test_ZRC20Allowance(t *testing.T) { t.Run("should fail when spender is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Allowance( ts.ctx, - zrc20ABI, ts.zrc20Address, sample.EthAddress(), common.Address{}, @@ -54,7 +41,6 @@ func Test_ZRC20Allowance(t *testing.T) { t.Run("should fail when zrc20 address is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Allowance( ts.ctx, - zrc20ABI, common.Address{}, sample.EthAddress(), fungibletypes.ModuleAddressEVM, @@ -66,7 +52,6 @@ func Test_ZRC20Allowance(t *testing.T) { t.Run("should pass with correct input", func(t *testing.T) { allowance, err := ts.fungibleKeeper.ZRC20Allowance( ts.ctx, - zrc20ABI, ts.zrc20Address, fungibletypes.ModuleAddressEVM, sample.EthAddress(), @@ -77,27 +62,16 @@ func Test_ZRC20Allowance(t *testing.T) { } func Test_ZRC20BalanceOf(t *testing.T) { - // Instantiate the ZRC20 ABI only one time. - // This avoids instantiating it every time deposit or withdraw are called. - zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() - require.NoError(t, err) - ts := setupChain(t) - t.Run("should fail when ZRC20ABI is nil", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, nil, ts.zrc20Address, common.Address{}) - require.Error(t, err) - require.ErrorAs(t, err, &fungibletypes.ErrZRC20NilABI) - }) - t.Run("should fail when owner is zero address", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, ts.zrc20Address, common.Address{}) + _, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, ts.zrc20Address, common.Address{}) require.Error(t, err) require.ErrorAs(t, err, &fungibletypes.ErrZeroAddress) }) t.Run("should fail when zrc20 address is zero address", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, zrc20ABI, common.Address{}, sample.EthAddress()) + _, err := ts.fungibleKeeper.ZRC20BalanceOf(ts.ctx, common.Address{}, sample.EthAddress()) require.Error(t, err) require.ErrorAs(t, err, &fungibletypes.ErrZRC20ZeroAddress) }) @@ -105,7 +79,6 @@ func Test_ZRC20BalanceOf(t *testing.T) { t.Run("should pass with correct input", func(t *testing.T) { balance, err := ts.fungibleKeeper.ZRC20BalanceOf( ts.ctx, - zrc20ABI, ts.zrc20Address, fungibletypes.ModuleAddressEVM, ) @@ -115,61 +88,31 @@ func Test_ZRC20BalanceOf(t *testing.T) { } func Test_ZRC20TotalSupply(t *testing.T) { - // Instantiate the ZRC20 ABI only one time. - // This avoids instantiating it every time deposit or withdraw are called. - zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() - require.NoError(t, err) - ts := setupChain(t) - t.Run("should fail when ZRC20ABI is nil", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20TotalSupply(ts.ctx, nil, ts.zrc20Address) - require.Error(t, err) - require.ErrorAs(t, err, &fungibletypes.ErrZRC20NilABI) - }) - t.Run("should fail when zrc20 address is zero address", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20TotalSupply(ts.ctx, zrc20ABI, common.Address{}) + _, err := ts.fungibleKeeper.ZRC20TotalSupply(ts.ctx, common.Address{}) require.Error(t, err) require.ErrorAs(t, err, &fungibletypes.ErrZRC20ZeroAddress) }) t.Run("should pass with correct input", func(t *testing.T) { - totalSupply, err := ts.fungibleKeeper.ZRC20TotalSupply(ts.ctx, zrc20ABI, ts.zrc20Address) + totalSupply, err := ts.fungibleKeeper.ZRC20TotalSupply(ts.ctx, ts.zrc20Address) require.NoError(t, err) require.Equal(t, uint64(10000000), totalSupply.Uint64()) }) } func Test_ZRC20Transfer(t *testing.T) { - // Instantiate the ZRC20 ABI only one time. - // This avoids instantiating it every time deposit or withdraw are called. - zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() - require.NoError(t, err) - ts := setupChain(t) // Make sure sample.EthAddress() exists as an ethermint account in state. accAddress := sdk.AccAddress(sample.EthAddress().Bytes()) ts.fungibleKeeper.GetAuthKeeper().SetAccount(ts.ctx, authtypes.NewBaseAccount(accAddress, nil, 0, 0)) - t.Run("should fail when ZRC20ABI is nil", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20Transfer( - ts.ctx, - nil, - ts.zrc20Address, - common.Address{}, - common.Address{}, - big.NewInt(0), - ) - require.Error(t, err) - require.ErrorAs(t, err, &fungibletypes.ErrZRC20NilABI) - }) - t.Run("should fail when owner is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Transfer( ts.ctx, - zrc20ABI, ts.zrc20Address, common.Address{}, sample.EthAddress(), @@ -182,7 +125,6 @@ func Test_ZRC20Transfer(t *testing.T) { t.Run("should fail when spender is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Transfer( ts.ctx, - zrc20ABI, ts.zrc20Address, sample.EthAddress(), common.Address{}, @@ -195,7 +137,6 @@ func Test_ZRC20Transfer(t *testing.T) { t.Run("should fail when zrc20 address is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20Transfer( ts.ctx, - zrc20ABI, common.Address{}, sample.EthAddress(), fungibletypes.ModuleAddressEVM, @@ -209,7 +150,6 @@ func Test_ZRC20Transfer(t *testing.T) { ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, fungibletypes.ModuleAddressEVM, big.NewInt(10)) transferred, err := ts.fungibleKeeper.ZRC20Transfer( ts.ctx, - zrc20ABI, ts.zrc20Address, fungibletypes.ModuleAddressEVM, sample.EthAddress(), @@ -232,24 +172,9 @@ func Test_ZRC20TransferFrom(t *testing.T) { accAddress := sdk.AccAddress(sample.EthAddress().Bytes()) ts.fungibleKeeper.GetAuthKeeper().SetAccount(ts.ctx, authtypes.NewBaseAccount(accAddress, nil, 0, 0)) - t.Run("should fail when ZRC20ABI is nil", func(t *testing.T) { - _, err := ts.fungibleKeeper.ZRC20TransferFrom( - ts.ctx, - nil, - ts.zrc20Address, - common.Address{}, - common.Address{}, - common.Address{}, - big.NewInt(0), - ) - require.Error(t, err) - require.ErrorAs(t, err, &fungibletypes.ErrZRC20NilABI) - }) - t.Run("should fail when from is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, ts.zrc20Address, sample.EthAddress(), common.Address{}, @@ -263,7 +188,6 @@ func Test_ZRC20TransferFrom(t *testing.T) { t.Run("should fail when to is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, ts.zrc20Address, sample.EthAddress(), sample.EthAddress(), @@ -277,7 +201,6 @@ func Test_ZRC20TransferFrom(t *testing.T) { t.Run("should fail when spender is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, ts.zrc20Address, common.Address{}, sample.EthAddress(), @@ -291,7 +214,6 @@ func Test_ZRC20TransferFrom(t *testing.T) { t.Run("should fail when zrc20 address is zero address", func(t *testing.T) { _, err := ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, common.Address{}, sample.EthAddress(), sample.EthAddress(), @@ -309,7 +231,6 @@ func Test_ZRC20TransferFrom(t *testing.T) { // Transferring the tokens with transferFrom without approval should fail. _, err = ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, ts.zrc20Address, fungibletypes.ModuleAddressEVM, sample.EthAddress(), @@ -329,7 +250,6 @@ func Test_ZRC20TransferFrom(t *testing.T) { // Transferring the tokens with transferFrom without approval should fail. _, err = ts.fungibleKeeper.ZRC20TransferFrom( ts.ctx, - zrc20ABI, ts.zrc20Address, fungibletypes.ModuleAddressEVM, sample.EthAddress(),