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

tests(erc20): add IsTransactions and RequiredGas tests #2037

Merged
merged 5 commits into from
Nov 13, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (osmosis-outpost) [#2017](https://github.com/evmos/evmos/pull/2017) Refactor types, errors and precompile struct.
- (erc20) [#2023](https://github.com/evmos/evmos/pull/2023) Add tests for ERC20 precompile queries.
- (osmosis-outpost) [#2025](https://github.com/evmos/evmos/pull/2025) Use a struct to wrap parsed parameters from Solidity.
- (erc20) [#2037](https://github.com/evmos/evmos/pull/2037) Add IsTransactions and RequiredGas tests for the ERC20 extension.

### Bug Fixes

Expand Down
39 changes: 26 additions & 13 deletions precompiles/erc20/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,21 @@ import (
transferkeeper "github.com/evmos/evmos/v15/x/ibc/transfer/keeper"
)

// abiPath defines the path to the ERC-20 precompile ABI JSON file.
const abiPath = "abi.json"
const (
// abiPath defines the path to the ERC-20 precompile ABI JSON file.
abiPath = "abi.json"

GasTransfer = 3_000_000
GasApprove = 30_956
GasIncreaseAllowance = 34_605
GasDecreaseAllowance = 34_519
GasName = 3_421
GasSymbol = 3_464
GasDecimals = 427
GasTotalSupply = 2_477
GasBalanceOf = 2_851
GasAllowance = 3_246
)

// Embed abi json file to the executable binary. Needed when importing as dependency.
//
Expand Down Expand Up @@ -90,28 +103,28 @@ func (p Precompile) RequiredGas(input []byte) uint64 {
switch method.Name {
// ERC-20 transactions
case TransferMethod:
return 3_000_000
return GasTransfer
case TransferFromMethod:
return 3_000_000
return GasTransfer
case auth.ApproveMethod:
return 30_956
return GasApprove
case auth.IncreaseAllowanceMethod:
return 34_605
return GasIncreaseAllowance
case auth.DecreaseAllowanceMethod:
return 34_519
return GasDecreaseAllowance
// ERC-20 queries
case NameMethod:
return 3_421
return GasName
case SymbolMethod:
return 3_464
return GasSymbol
case DecimalsMethod:
return 427
return GasDecimals
case TotalSupplyMethod:
return 2_477
return GasTotalSupply
case BalanceOfMethod:
return 2_851
return GasBalanceOf
case auth.AllowanceMethod:
return 3_246
return GasAllowance
default:
return 0
}
Expand Down
163 changes: 163 additions & 0 deletions precompiles/erc20/erc20_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright Tharsis Labs Ltd.(Evmos)
// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)

package erc20_test

import (
"math/big"

auth "github.com/evmos/evmos/v15/precompiles/authorization"
"github.com/evmos/evmos/v15/precompiles/erc20"
)

func (s *PrecompileTestSuite) TestIsTransaction() {
s.SetupTest()

// Queries
s.Require().False(s.precompile.IsTransaction(erc20.BalanceOfMethod))
s.Require().False(s.precompile.IsTransaction(erc20.DecimalsMethod))
s.Require().False(s.precompile.IsTransaction(erc20.NameMethod))
s.Require().False(s.precompile.IsTransaction(erc20.SymbolMethod))
s.Require().False(s.precompile.IsTransaction(erc20.TotalSupplyMethod))

// Transactions
s.Require().True(s.precompile.IsTransaction(auth.ApproveMethod))
s.Require().True(s.precompile.IsTransaction(auth.IncreaseAllowanceMethod))
s.Require().True(s.precompile.IsTransaction(auth.DecreaseAllowanceMethod))
s.Require().True(s.precompile.IsTransaction(erc20.TransferMethod))
s.Require().True(s.precompile.IsTransaction(erc20.TransferFromMethod))
}

func (s *PrecompileTestSuite) TestRequiredGas() {
s.SetupTest()

testcases := []struct {
name string
malleate func() []byte
expGas uint64
}{
{
name: erc20.BalanceOfMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.BalanceOfMethod, s.keyring.GetAddr(0))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasBalanceOf,
},
{
name: erc20.DecimalsMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.DecimalsMethod)
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasDecimals,
},
{
name: erc20.NameMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.NameMethod)
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasName,
},
{
name: erc20.SymbolMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.SymbolMethod)
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasSymbol,
},
{
name: erc20.TotalSupplyMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.TotalSupplyMethod)
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasTotalSupply,
},
{
name: auth.ApproveMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(auth.ApproveMethod, s.keyring.GetAddr(0), big.NewInt(1))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasApprove,
},
{
name: auth.IncreaseAllowanceMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(auth.IncreaseAllowanceMethod, s.keyring.GetAddr(0), big.NewInt(1))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasIncreaseAllowance,
},
{
name: auth.DecreaseAllowanceMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(auth.DecreaseAllowanceMethod, s.keyring.GetAddr(0), big.NewInt(1))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasDecreaseAllowance,
},
{
name: erc20.TransferMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.TransferMethod, s.keyring.GetAddr(0), big.NewInt(1))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasTransfer,
},
{
name: erc20.TransferFromMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(erc20.TransferFromMethod, s.keyring.GetAddr(0), s.keyring.GetAddr(0), big.NewInt(1))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasTransfer,
},
{
name: auth.AllowanceMethod,
malleate: func() []byte {
bz, err := s.precompile.ABI.Pack(auth.AllowanceMethod, s.keyring.GetAddr(0), s.keyring.GetAddr(0))
s.Require().NoError(err, "expected no error packing ABI")
return bz
},
expGas: erc20.GasAllowance,
},
{
name: "invalid method",
malleate: func() []byte {
return []byte("invalid method")
},
expGas: 0,
},
{
name: "input bytes too short",
malleate: func() []byte {
return []byte{0x00, 0x00, 0x00}
},
expGas: 0,
},
}

for _, tc := range testcases {
s.Run(tc.name, func() {
tc := tc

input := tc.malleate()

s.Require().Equal(tc.expGas, s.precompile.RequiredGas(input))
})
}
}