Skip to content

Commit

Permalink
fix(wevmos): make WEVMOS deposit and withdraw functions real no-ops a…
Browse files Browse the repository at this point in the history
…nd fix tests (#2329)

* fix: make WEVMOS deposit and withdraw functions real no-ops and modify tests

* CHANGELOG

* fix: add tests that confirm no events are emitted
  • Loading branch information
Vvaradinov committed Feb 8, 2024
1 parent 679d457 commit c4c4730
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 195 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (tests) [#2311](https://github.com/evmos/evmos/pull/2311) Fix post-upgrade transactions in automated upgrade tests.
- (build) [#2319](https://github.com/evmos/evmos/pull/2319) Bump go.mod golang version to v1.21.
- (ci) [#2321](https://github.com/evmos/evmos/pull/2321) Add build and markdown lint checker for `main` and `release` branches.
- (wevmos) [#2329](https://github.com/evmos/evmos/pull/2329) Make WEVMOS precompile `deposit` and `withdraw` functions no-ops.

## [v16.0.2](https://github.com/evmos/evmos/releases/tag/v16.0.2) - 2024-01-16

Expand Down
70 changes: 0 additions & 70 deletions precompiles/werc20/events.go

This file was deleted.

95 changes: 37 additions & 58 deletions precompiles/werc20/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ import (
. "github.com/onsi/gomega"
)

const (
// EventTypeDeposit defines the event type for the Deposit transaction.
EventTypeDeposit = "Deposit"
// EventTypeWithdrawal defines the event type for the Withdraw transaction.
EventTypeWithdrawal = "Withdrawal"
)

var _ = Describe("WEVMOS Extension -", func() {
var (
WERC20ContractAddr common.Address
Expand Down Expand Up @@ -93,19 +100,18 @@ var _ = Describe("WEVMOS Extension -", func() {

Context("WEVMOS specific functions", func() {
When("calling deposit correctly", func() {
It("should emit the Deposit event but not modify the balance", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
It("should not emit events", func() {
depositCheck := passCheck.WithExpPass(true)
txArgs, callArgs := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
txArgs.Amount = amount

_, _, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgs, callArgs, depositCheck)
_, ethRes, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgs, callArgs, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

s.checkBalances(failCheck, sender, contractData)
Expect(ethRes.Logs).To(BeEmpty(), "expected no events")
})

It("should spend the correct minimum gas", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
txArgs, callArgs := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
txArgs.Amount = amount

Expand All @@ -117,18 +123,18 @@ var _ = Describe("WEVMOS Extension -", func() {
})

When("calling withdraw correctly", func() {
It("should emit the Withdrawal event but not modify the balance", func() {
withdrawCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeWithdrawal)
It("should not emit events", func() {
depositCheck := passCheck.WithExpPass(true)
txArgs, callArgs := s.getTxAndCallArgs(erc20Call, contractData, werc20.WithdrawMethod, amount)
txArgs.Amount = amount

_, _, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgs, callArgs, withdrawCheck)
_, ethRes, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgs, callArgs, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

s.checkBalances(failCheck, sender, contractData)
Expect(ethRes.Logs).To(BeEmpty(), "expected no events")
})

It("should spend the correct minimum gas", func() {
withdrawCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeWithdrawal)
withdrawCheck := passCheck.WithExpPass(true)
txArgs, callArgs := s.getTxAndCallArgs(erc20Call, contractData, werc20.WithdrawMethod, amount)

_, ethRes, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgs, callArgs, withdrawCheck)
Expand All @@ -147,7 +153,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteContractCall(sender.Priv, txArgs, callArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand All @@ -163,7 +169,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteEthTx(sender.Priv, txArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand All @@ -179,7 +185,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteEthTx(sender.Priv, txArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand All @@ -193,7 +199,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteEthTx(sender.Priv, txArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand All @@ -208,7 +214,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteEthTx(sender.Priv, txArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand All @@ -223,7 +229,7 @@ var _ = Describe("WEVMOS Extension -", func() {
res, err := s.factory.ExecuteEthTx(sender.Priv, txArgs)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
depositCheck.Res = res
err = testutil.CheckLogs(depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
Expand Down Expand Up @@ -252,24 +258,8 @@ var _ = Describe("WEVMOS Extension -", func() {
})

When("calling deposit", func() {
It("should emit the Deposit event", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
txArgsPrecompile.Amount = amount

_, _, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsPrecompile, callArgsPrecompile, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

txArgsContract, callArgsContract := s.getTxAndCallArgs(erc20Call, contractDataOriginal, werc20.DepositMethod)
txArgsContract.Amount = amount
txArgsContract.GasLimit = 50_000

_, _, err = s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
})

It("should have exact gas consumption", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
txArgsPrecompile.Amount = amount

Expand All @@ -280,14 +270,15 @@ var _ = Describe("WEVMOS Extension -", func() {
txArgsContract.Amount = amount
txArgsContract.GasLimit = 50_000

_, ethResOriginal, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheck)
depositCheckContract := passCheck.WithExpPass(true).WithExpEvents(EventTypeDeposit)
_, ethResOriginal, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheckContract)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

Expect(ethResOriginal.GasUsed).To(Equal(ethResPrecompile.GasUsed), "expected exact gas used")
})

It("should return the same error", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
// Increase the amount to 9e18 to trigger the insufficient balance error
txArgsPrecompile.Amount = big.NewInt(9e18)
Expand All @@ -308,7 +299,7 @@ var _ = Describe("WEVMOS Extension -", func() {
})

It("should reflect the correct balances", func() {
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.DepositMethod)
txArgsPrecompile.Amount = amount

Expand All @@ -319,7 +310,8 @@ var _ = Describe("WEVMOS Extension -", func() {
txArgsContract.Amount = amount
txArgsContract.GasLimit = 50_000

_, _, errOriginal := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheck)
depositCheckContract := passCheck.WithExpPass(true).WithExpEvents(EventTypeDeposit)
_, _, errOriginal := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheckContract)
Expect(errOriginal).ToNot(HaveOccurred(), "unexpected result calling contract")

// Check balances after calling precompile
Expand All @@ -343,46 +335,33 @@ var _ = Describe("WEVMOS Extension -", func() {
When("calling withdraw", func() {
BeforeEach(func() {
// Deposit into the WEVMOS contract to have something to withdraw
depositCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeDeposit)
depositCheck := passCheck.WithExpPass(true).WithExpEvents(EventTypeDeposit)
txArgsContract, callArgsContract := s.getTxAndCallArgs(erc20Call, contractDataOriginal, werc20.DepositMethod)
txArgsContract.Amount = amount
txArgsContract.GasLimit = 50_000

_, _, err = s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
})

It("should emit the Withdraw event", func() {
withdrawCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeWithdrawal)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.WithdrawMethod, amount)

_, _, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsPrecompile, callArgsPrecompile, withdrawCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

txArgsContract, callArgsContract := s.getTxAndCallArgs(erc20Call, contractDataOriginal, werc20.WithdrawMethod, amount)
txArgsContract.GasLimit = 50_000

_, _, err = s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, withdrawCheck)
_, _, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, depositCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")
})

It("should have exact gas consumption", func() {
withdrawCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeWithdrawal)
withdrawCheck := passCheck.WithExpPass(true)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.WithdrawMethod, amount)

_, ethResPrecompile, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsPrecompile, callArgsPrecompile, withdrawCheck)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

txArgsContract, callArgsContract := s.getTxAndCallArgs(erc20Call, contractDataOriginal, werc20.WithdrawMethod, amount)

_, ethResOriginal, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, withdrawCheck)
withdrawCheckContract := passCheck.WithExpPass(true).WithExpEvents(EventTypeWithdrawal)
_, ethResOriginal, err := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsContract, callArgsContract, withdrawCheckContract)
Expect(err).ToNot(HaveOccurred(), "unexpected result calling contract")

Expect(ethResOriginal.GasUsed).To(Equal(ethResPrecompile.GasUsed), "expected exact gas used")
})

It("should return the same error", func() {
withdrawCheck := passCheck.WithExpPass(true).WithExpEvents(werc20.EventTypeWithdrawal)
withdrawCheck := passCheck.WithExpPass(true)
txArgsPrecompile, callArgsPrecompile := s.getTxAndCallArgs(erc20Call, contractData, werc20.WithdrawMethod)

_, _, errPrecompile := s.factory.CallContractAndCheckLogs(sender.Priv, txArgsPrecompile, callArgsPrecompile, withdrawCheck)
Expand Down
48 changes: 2 additions & 46 deletions precompiles/werc20/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@

package werc20

import (
"fmt"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/vm"
)

const (
// DepositMethod defines the ABI method name for the IWERC20 deposit
// transaction.
Expand All @@ -24,48 +15,13 @@ const (
// Deposit is a no-op and mock function that provides the same interface as the
// WETH contract to support equality between the native coin and its wrapped
// ERC-20 (eg. EVMOS and WEVMOS). It only emits the Deposit event.
func (p Precompile) Deposit(
ctx sdk.Context,
contract *vm.Contract,
stateDB vm.StateDB,
_ *abi.Method,
_ []interface{},
) ([]byte, error) {
dst := contract.Caller()
amount := contract.Value()

if err := p.EmitDepositEvent(ctx, stateDB, dst, amount); err != nil {
return nil, err
}

// NOTE: To avoid triggering the minting/burning mechanism we override the
// balances of the contract and the sender manually to perform a no-op so
// the balances are kept in sync.
stateDB.AddBalance(dst, amount)
stateDB.SubBalance(contract.Address(), amount)

func (p Precompile) Deposit() ([]byte, error) {
return nil, nil
}

// Withdraw is a no-op and mock function that provides the same interface as the
// WETH contract to support equality between the native coin and its wrapped
// ERC-20 (eg. EVMOS and WEVMOS). It only emits the Withdraw event.
func (p Precompile) Withdraw(
ctx sdk.Context,
contract *vm.Contract,
stateDB vm.StateDB,
_ *abi.Method,
args []interface{},
) ([]byte, error) {
src := contract.Caller()
amount, ok := args[0].(*big.Int)
if !ok {
return nil, fmt.Errorf("invalid argument type: %T", args[0])
}

if err := p.EmitWithdrawalEvent(ctx, stateDB, src, amount); err != nil {
return nil, err
}

func (p Precompile) Withdraw() ([]byte, error) {
return nil, nil
}
19 changes: 0 additions & 19 deletions precompiles/werc20/types.go

This file was deleted.

Loading

0 comments on commit c4c4730

Please sign in to comment.