Commit d7c2d167 authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

chequebook: remove erc20 bindings (#1362)

parent aa8e5d36
......@@ -135,7 +135,6 @@ func InitChequebookService(
overlayEthAddress,
chequeSigner,
chequebook.NewSimpleSwapBindings,
chequebook.NewERC20Bindings,
)
if err != nil {
return nil, fmt.Errorf("chequebook init: %w", err)
......
......@@ -26,15 +26,3 @@ type SimpleSwapBindingFunc = func(common.Address, bind.ContractBackend) (SimpleS
func NewSimpleSwapBindings(address common.Address, backend bind.ContractBackend) (SimpleSwapBinding, error) {
return simpleswapfactory.NewERC20SimpleSwap(address, backend)
}
// ERC20Binding is the interface for the generated go bindings for ERC20
type ERC20Binding interface {
BalanceOf(*bind.CallOpts, common.Address) (*big.Int, error)
}
type ERC20BindingFunc = func(common.Address, bind.ContractBackend) (ERC20Binding, error)
// NewERC20Bindings generates the default go bindings
func NewERC20Bindings(address common.Address, backend bind.ContractBackend) (ERC20Binding, error) {
return simpleswapfactory.NewERC20(address, backend)
}
......@@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/sw3-bindings/v3/simpleswapfactory"
......@@ -36,7 +37,6 @@ var (
chequebookABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20SimpleSwapABI)
chequeCashedEventType = chequebookABI.Events["ChequeCashed"]
chequeBouncedEventType = chequebookABI.Events["ChequeBounced"]
erc20ABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20ABI)
)
// Service is the main interface for interacting with the nodes chequebook.
......@@ -70,8 +70,7 @@ type service struct {
chequebookInstance SimpleSwapBinding
ownerAddress common.Address
erc20Address common.Address
erc20Instance ERC20Binding
erc20Service erc20.Service
store storage.StateStorer
chequeSigner ChequeSigner
......@@ -79,25 +78,19 @@ type service struct {
}
// New creates a new chequebook service for the provided chequebook contract.
func New(backend transaction.Backend, transactionService transaction.Service, address, erc20Address, ownerAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, simpleSwapBindingFunc SimpleSwapBindingFunc, erc20BindingFunc ERC20BindingFunc) (Service, error) {
func New(backend transaction.Backend, transactionService transaction.Service, address, ownerAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, erc20Service erc20.Service, simpleSwapBindingFunc SimpleSwapBindingFunc) (Service, error) {
chequebookInstance, err := simpleSwapBindingFunc(address, backend)
if err != nil {
return nil, err
}
erc20Instance, err := erc20BindingFunc(erc20Address, backend)
if err != nil {
return nil, err
}
return &service{
backend: backend,
transactionService: transactionService,
address: address,
chequebookInstance: chequebookInstance,
ownerAddress: ownerAddress,
erc20Address: erc20Address,
erc20Instance: erc20Instance,
erc20Service: erc20Service,
store: store,
chequeSigner: chequeSigner,
totalIssuedReserved: big.NewInt(0),
......@@ -111,9 +104,7 @@ func (s *service) Address() common.Address {
// Deposit starts depositing erc20 token into the chequebook. This returns once the transactions has been broadcast.
func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
balance, err := s.erc20Instance.BalanceOf(&bind.CallOpts{
Context: ctx,
}, s.ownerAddress)
balance, err := s.erc20Service.BalanceOf(ctx, s.ownerAddress)
if err != nil {
return common.Hash{}, err
}
......@@ -123,25 +114,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has
return common.Hash{}, ErrInsufficientFunds
}
callData, err := erc20ABI.Pack("transfer", s.address, amount)
if err != nil {
return common.Hash{}, err
}
request := &transaction.TxRequest{
To: &s.erc20Address,
Data: callData,
GasPrice: nil,
GasLimit: 0,
Value: big.NewInt(0),
}
txHash, err := s.transactionService.Send(ctx, request)
if err != nil {
return common.Hash{}, err
}
return txHash, nil
return s.erc20Service.Transfer(ctx, s.address, amount)
}
// Balance returns the token balance of the chequebook.
......
......@@ -7,6 +7,7 @@ package chequebook_test
import (
"context"
"errors"
"fmt"
"math/big"
"testing"
......@@ -14,6 +15,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
erc20mock "github.com/ethersphere/bee/pkg/settlement/swap/erc20/mock"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction/backendmock"
transactionmock "github.com/ethersphere/bee/pkg/settlement/swap/transaction/mock"
......@@ -26,20 +29,20 @@ func newTestChequebook(
backend transaction.Backend,
transactionService transaction.Service,
address,
erc20address,
ownerAdress common.Address,
store storage.StateStorer,
chequeSigner chequebook.ChequeSigner,
erc20 erc20.Service,
simpleSwapBinding chequebook.SimpleSwapBinding,
erc20Binding chequebook.ERC20Binding) (chequebook.Service, error) {
) (chequebook.Service, error) {
return chequebook.New(
backend,
transactionService,
address,
erc20address,
ownerAdress,
store,
chequeSigner,
erc20,
func(addr common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
if addr != address {
t.Fatalf("initialised binding with wrong address. wanted %x, got %x", address, addr)
......@@ -49,33 +52,23 @@ func newTestChequebook(
}
return simpleSwapBinding, nil
},
func(addr common.Address, b bind.ContractBackend) (chequebook.ERC20Binding, error) {
if addr != erc20address {
t.Fatalf("initialised binding with wrong address. wanted %x, got %x", erc20address, addr)
}
if b != backend {
t.Fatal("initialised binding with wrong backend")
}
return erc20Binding, nil
},
)
}
func TestChequebookAddress(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
chequebookService, err := newTestChequebook(
t,
backendmock.New(),
transactionmock.New(),
address,
erc20address,
ownerAdress,
nil,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -87,7 +80,6 @@ func TestChequebookAddress(t *testing.T) {
func TestChequebookBalance(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(10)
chequebookService, err := newTestChequebook(
......@@ -95,16 +87,16 @@ func TestChequebookBalance(t *testing.T) {
backendmock.New(),
transactionmock.New(),
address,
erc20address,
ownerAdress,
nil,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return balance, nil
},
},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -121,7 +113,6 @@ func TestChequebookBalance(t *testing.T) {
func TestChequebookDeposit(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30)
depositAmount := big.NewInt(20)
......@@ -129,31 +120,30 @@ func TestChequebookDeposit(t *testing.T) {
chequebookService, err := newTestChequebook(
t,
backendmock.New(),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != nil && *request.To != erc20address {
t.Fatalf("sending to wrong contract. wanted %x, got %x", erc20address, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
t.Fatal("sending ether to token contract")
}
return txHash, nil
}),
),
transactionmock.New(),
address,
erc20address,
ownerAdress,
nil,
&chequeSignerMock{},
&simpleSwapBindingMock{},
&erc20BindingMock{
balanceOf: func(b *bind.CallOpts, addr common.Address) (*big.Int, error) {
if addr != ownerAdress {
t.Fatalf("looking up balance of wrong account. wanted %x, got %x", ownerAdress, addr)
erc20mock.New(
erc20mock.WithBalanceOfFunc(func(ctx context.Context, address common.Address) (*big.Int, error) {
if address != ownerAdress {
return nil, errors.New("getting balance of wrong address")
}
return balance, nil
},
})
}),
erc20mock.WithTransferFunc(func(ctx context.Context, to common.Address, value *big.Int) (common.Hash, error) {
if to != address {
return common.Hash{}, fmt.Errorf("sending to wrong address. wanted %x, got %x", address, to)
}
if depositAmount.Cmp(value) != 0 {
return common.Hash{}, fmt.Errorf("sending wrong value. wanted %d, got %d", depositAmount, value)
}
return txHash, nil
}),
),
&simpleSwapBindingMock{},
)
if err != nil {
t.Fatal(err)
}
......@@ -170,7 +160,6 @@ func TestChequebookDeposit(t *testing.T) {
func TestChequebookWaitForDeposit(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
txHash := common.HexToHash("0xdddd")
chequebookService, err := newTestChequebook(
......@@ -187,12 +176,12 @@ func TestChequebookWaitForDeposit(t *testing.T) {
}),
),
address,
erc20address,
ownerAdress,
nil,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -205,7 +194,6 @@ func TestChequebookWaitForDeposit(t *testing.T) {
func TestChequebookWaitForDepositReverted(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
txHash := common.HexToHash("0xdddd")
chequebookService, err := newTestChequebook(
......@@ -222,12 +210,12 @@ func TestChequebookWaitForDepositReverted(t *testing.T) {
}),
),
address,
erc20address,
ownerAdress,
nil,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -243,7 +231,6 @@ func TestChequebookWaitForDepositReverted(t *testing.T) {
func TestChequebookIssue(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore()
......@@ -258,10 +245,10 @@ func TestChequebookIssue(t *testing.T) {
backendmock.New(),
transactionmock.New(),
address,
erc20address,
ownerAdress,
store,
chequeSigner,
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(100), nil
......@@ -270,7 +257,7 @@ func TestChequebookIssue(t *testing.T) {
return big.NewInt(0), nil
},
},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -396,7 +383,6 @@ func TestChequebookIssue(t *testing.T) {
func TestChequebookIssueErrorSend(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore()
......@@ -409,10 +395,10 @@ func TestChequebookIssueErrorSend(t *testing.T) {
backendmock.New(),
transactionmock.New(),
address,
erc20address,
ownerAdress,
store,
chequeSigner,
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return amount, nil
......@@ -421,7 +407,7 @@ func TestChequebookIssueErrorSend(t *testing.T) {
return big.NewInt(0), nil
},
},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -446,7 +432,6 @@ func TestChequebookIssueErrorSend(t *testing.T) {
func TestChequebookIssueOutOfFunds(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore()
......@@ -457,10 +442,10 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
backendmock.New(),
transactionmock.New(),
address,
erc20address,
ownerAdress,
store,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0), nil
......@@ -469,7 +454,7 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
return big.NewInt(0), nil
},
},
&erc20BindingMock{})
)
if err != nil {
t.Fatal(err)
}
......@@ -491,7 +476,6 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
func TestChequebookWithdraw(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30)
withdrawAmount := big.NewInt(20)
......@@ -512,10 +496,10 @@ func TestChequebookWithdraw(t *testing.T) {
}),
),
address,
erc20address,
ownerAdress,
store,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return balance, nil
......@@ -524,14 +508,7 @@ func TestChequebookWithdraw(t *testing.T) {
return big.NewInt(0), nil
},
},
&erc20BindingMock{
balanceOf: func(b *bind.CallOpts, addr common.Address) (*big.Int, error) {
if addr != ownerAdress {
t.Fatalf("looking up balance of wrong account. wanted %x, got %x", ownerAdress, addr)
}
return balance, nil
},
})
)
if err != nil {
t.Fatal(err)
}
......@@ -548,7 +525,6 @@ func TestChequebookWithdraw(t *testing.T) {
func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30)
withdrawAmount := big.NewInt(20)
......@@ -567,12 +543,15 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
}
return txHash, nil
}),
transactionmock.WithCallFunc(func(ctx context.Context, request *transaction.TxRequest) (result []byte, err error) {
return balance.FillBytes(make([]byte, 32)), nil
}),
),
address,
erc20address,
ownerAdress,
store,
&chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0), nil
......@@ -581,14 +560,7 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
return big.NewInt(0), nil
},
},
&erc20BindingMock{
balanceOf: func(b *bind.CallOpts, addr common.Address) (*big.Int, error) {
if addr != ownerAdress {
t.Fatalf("looking up balance of wrong account. wanted %x, got %x", ownerAdress, addr)
}
return balance, nil
},
})
)
if err != nil {
t.Fatal(err)
}
......
......@@ -36,14 +36,6 @@ func (m *simpleSwapBindingMock) PaidOut(o *bind.CallOpts, c common.Address) (*bi
return m.paidOut(o, c)
}
type erc20BindingMock struct {
balanceOf func(*bind.CallOpts, common.Address) (*big.Int, error)
}
func (m *erc20BindingMock) BalanceOf(o *bind.CallOpts, a common.Address) (*big.Int, error) {
return m.balanceOf(o, a)
}
type chequeSignerMock struct {
sign func(cheque *chequebook.Cheque) ([]byte, error)
}
......
......@@ -10,9 +10,9 @@ import (
"math/big"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/storage"
)
......@@ -20,6 +20,9 @@ import (
const (
chequebookKey = "swap_chequebook"
chequebookDeploymentKey = "swap_chequebook_transaction_deployment"
balanceCheckBackoffDuration = 20 * time.Second
balanceCheckMaxRetries = 10
)
func checkBalance(
......@@ -29,23 +32,12 @@ func checkBalance(
swapBackend transaction.Backend,
chainId int64,
overlayEthAddress common.Address,
erc20BindingFunc ERC20BindingFunc,
erc20Address common.Address,
backoffDuration time.Duration,
maxRetries uint64,
erc20Token erc20.Service,
) error {
timeoutCtx, cancel := context.WithTimeout(ctx, backoffDuration*time.Duration(maxRetries))
timeoutCtx, cancel := context.WithTimeout(ctx, balanceCheckBackoffDuration*time.Duration(balanceCheckMaxRetries))
defer cancel()
erc20Token, err := erc20BindingFunc(erc20Address, swapBackend)
if err != nil {
return err
}
for {
erc20Balance, err := erc20Token.BalanceOf(&bind.CallOpts{
Context: timeoutCtx,
}, overlayEthAddress)
erc20Balance, err := erc20Token.BalanceOf(timeoutCtx, overlayEthAddress)
if err != nil {
return err
}
......@@ -83,7 +75,7 @@ func checkBalance(
logger.Warningf("get your Goerli ETH and Goerli BZZ now via the bzzaar at https://bzz.ethswarm.org/?transaction=buy&amount=%d&slippage=30&receiver=0x%x", neededERC20, overlayEthAddress)
}
select {
case <-time.After(backoffDuration):
case <-time.After(balanceCheckBackoffDuration):
case <-timeoutCtx.Done():
if insufficientERC20 {
return fmt.Errorf("insufficient BZZ for initial deposit")
......@@ -111,7 +103,7 @@ func Init(
overlayEthAddress common.Address,
chequeSigner ChequeSigner,
simpleSwapBindingFunc SimpleSwapBindingFunc,
erc20BindingFunc ERC20BindingFunc) (chequebookService Service, err error) {
) (chequebookService Service, err error) {
// verify that the supplied factory is valid
err = chequebookFactory.VerifyBytecode(ctx)
if err != nil {
......@@ -123,6 +115,8 @@ func Init(
return nil, err
}
erc20Service := erc20.New(swapBackend, transactionService, erc20Address)
var chequebookAddress common.Address
err = stateStore.Get(chequebookKey, &chequebookAddress)
if err != nil {
......@@ -138,7 +132,7 @@ func Init(
if err == storage.ErrNotFound {
logger.Info("no chequebook found, deploying new one.")
if swapInitialDeposit.Cmp(big.NewInt(0)) != 0 {
err = checkBalance(ctx, logger, swapInitialDeposit, swapBackend, chainId, overlayEthAddress, erc20BindingFunc, erc20Address, 20*time.Second, 10)
err = checkBalance(ctx, logger, swapInitialDeposit, swapBackend, chainId, overlayEthAddress, erc20Service)
if err != nil {
return nil, err
}
......@@ -173,7 +167,7 @@ func Init(
return nil, err
}
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, erc20Address, overlayEthAddress, stateStore, chequeSigner, simpleSwapBindingFunc, erc20BindingFunc)
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service, simpleSwapBindingFunc)
if err != nil {
return nil, err
}
......@@ -194,7 +188,7 @@ func Init(
logger.Info("successfully deposited to chequebook")
}
} else {
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, erc20Address, overlayEthAddress, stateStore, chequeSigner, simpleSwapBindingFunc, erc20BindingFunc)
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service, simpleSwapBindingFunc)
if err != nil {
return nil, err
}
......
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package erc20
import (
"context"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/sw3-bindings/v3/simpleswapfactory"
)
var (
erc20ABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20ABI)
errDecodeABI = errors.New("could not decode abi data")
)
type Service interface {
BalanceOf(ctx context.Context, address common.Address) (*big.Int, error)
Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error)
}
type erc20Service struct {
backend transaction.Backend
transactionService transaction.Service
address common.Address
}
func New(backend transaction.Backend, transactionService transaction.Service, address common.Address) Service {
return &erc20Service{
backend: backend,
transactionService: transactionService,
address: address,
}
}
func (c *erc20Service) BalanceOf(ctx context.Context, address common.Address) (*big.Int, error) {
callData, err := erc20ABI.Pack("balanceOf", address)
if err != nil {
return nil, err
}
output, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.address,
Data: callData,
})
if err != nil {
return nil, err
}
results, err := erc20ABI.Unpack("balanceOf", output)
if err != nil {
return nil, err
}
if len(results) != 1 {
return nil, errDecodeABI
}
balance, ok := abi.ConvertType(results[0], new(big.Int)).(*big.Int)
if !ok || balance == nil {
return nil, errDecodeABI
}
return balance, nil
}
func (c *erc20Service) Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) {
callData, err := erc20ABI.Pack("transfer", address, value)
if err != nil {
return common.Hash{}, err
}
request := &transaction.TxRequest{
To: &c.address,
Data: callData,
GasPrice: nil,
GasLimit: 0,
Value: big.NewInt(0),
}
txHash, err := c.transactionService.Send(ctx, request)
if err != nil {
return common.Hash{}, err
}
return txHash, nil
}
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package erc20_test
import (
"context"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
backendmock "github.com/ethersphere/bee/pkg/settlement/swap/transaction/backendmock"
transactionmock "github.com/ethersphere/bee/pkg/settlement/swap/transaction/mock"
"github.com/ethersphere/sw3-bindings/v3/simpleswapfactory"
)
var (
erc20ABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20ABI)
)
func TestBalanceOf(t *testing.T) {
erc20Address := common.HexToAddress("00")
account := common.HexToAddress("01")
expectedBalance := big.NewInt(100)
erc20 := erc20.New(
backendmock.New(),
transactionmock.New(
transactionmock.WithABICall(
&erc20ABI,
expectedBalance.FillBytes(make([]byte, 32)),
"balanceOf",
account,
),
),
erc20Address,
)
balance, err := erc20.BalanceOf(context.Background(), account)
if err != nil {
t.Fatal(err)
}
if expectedBalance.Cmp(balance) != 0 {
t.Fatalf("got wrong balance. wanted %d, got %d", expectedBalance, balance)
}
}
func TestTransfer(t *testing.T) {
address := common.HexToAddress("0xabcd")
account := common.HexToAddress("01")
value := big.NewInt(20)
txHash := common.HexToHash("0xdddd")
erc20 := erc20.New(
backendmock.New(),
transactionmock.New(
transactionmock.WithABISend(&erc20ABI, txHash, address, big.NewInt(0), "transfer", account, value),
),
address,
)
returnedTxHash, err := erc20.Transfer(context.Background(), account, value)
if err != nil {
t.Fatal(err)
}
if txHash != returnedTxHash {
t.Fatalf("returned wrong transaction hash. wanted %v, got %v", txHash, returnedTxHash)
}
}
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mock
import (
"context"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
)
type Service struct {
balanceOfFunc func(ctx context.Context, address common.Address) (*big.Int, error)
transferFunc func(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error)
}
func WithBalanceOfFunc(f func(ctx context.Context, address common.Address) (*big.Int, error)) Option {
return optionFunc(func(s *Service) {
s.balanceOfFunc = f
})
}
func WithTransferFunc(f func(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error)) Option {
return optionFunc(func(s *Service) {
s.transferFunc = f
})
}
func New(opts ...Option) erc20.Service {
mock := new(Service)
for _, o := range opts {
o.apply(mock)
}
return mock
}
func (s *Service) BalanceOf(ctx context.Context, address common.Address) (*big.Int, error) {
if s.balanceOfFunc != nil {
return s.balanceOfFunc(ctx, address)
}
return big.NewInt(0), errors.New("Error")
}
func (s *Service) Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) {
if s.transferFunc != nil {
return s.transferFunc(ctx, address, value)
}
return common.Hash{}, errors.New("Error")
}
// Option is the option passed to the mock Chequebook service
type Option interface {
apply(*Service)
}
type optionFunc func(*Service)
func (f optionFunc) apply(r *Service) { f(r) }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment