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( ...@@ -135,7 +135,6 @@ func InitChequebookService(
overlayEthAddress, overlayEthAddress,
chequeSigner, chequeSigner,
chequebook.NewSimpleSwapBindings, chequebook.NewSimpleSwapBindings,
chequebook.NewERC20Bindings,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("chequebook init: %w", err) return nil, fmt.Errorf("chequebook init: %w", err)
......
...@@ -26,15 +26,3 @@ type SimpleSwapBindingFunc = func(common.Address, bind.ContractBackend) (SimpleS ...@@ -26,15 +26,3 @@ type SimpleSwapBindingFunc = func(common.Address, bind.ContractBackend) (SimpleS
func NewSimpleSwapBindings(address common.Address, backend bind.ContractBackend) (SimpleSwapBinding, error) { func NewSimpleSwapBindings(address common.Address, backend bind.ContractBackend) (SimpleSwapBinding, error) {
return simpleswapfactory.NewERC20SimpleSwap(address, backend) 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 ( ...@@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "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/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/sw3-bindings/v3/simpleswapfactory" "github.com/ethersphere/sw3-bindings/v3/simpleswapfactory"
...@@ -36,7 +37,6 @@ var ( ...@@ -36,7 +37,6 @@ var (
chequebookABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20SimpleSwapABI) chequebookABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20SimpleSwapABI)
chequeCashedEventType = chequebookABI.Events["ChequeCashed"] chequeCashedEventType = chequebookABI.Events["ChequeCashed"]
chequeBouncedEventType = chequebookABI.Events["ChequeBounced"] chequeBouncedEventType = chequebookABI.Events["ChequeBounced"]
erc20ABI = transaction.ParseABIUnchecked(simpleswapfactory.ERC20ABI)
) )
// Service is the main interface for interacting with the nodes chequebook. // Service is the main interface for interacting with the nodes chequebook.
...@@ -70,8 +70,7 @@ type service struct { ...@@ -70,8 +70,7 @@ type service struct {
chequebookInstance SimpleSwapBinding chequebookInstance SimpleSwapBinding
ownerAddress common.Address ownerAddress common.Address
erc20Address common.Address erc20Service erc20.Service
erc20Instance ERC20Binding
store storage.StateStorer store storage.StateStorer
chequeSigner ChequeSigner chequeSigner ChequeSigner
...@@ -79,25 +78,19 @@ type service struct { ...@@ -79,25 +78,19 @@ type service struct {
} }
// New creates a new chequebook service for the provided chequebook contract. // 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) chequebookInstance, err := simpleSwapBindingFunc(address, backend)
if err != nil { if err != nil {
return nil, err return nil, err
} }
erc20Instance, err := erc20BindingFunc(erc20Address, backend)
if err != nil {
return nil, err
}
return &service{ return &service{
backend: backend, backend: backend,
transactionService: transactionService, transactionService: transactionService,
address: address, address: address,
chequebookInstance: chequebookInstance, chequebookInstance: chequebookInstance,
ownerAddress: ownerAddress, ownerAddress: ownerAddress,
erc20Address: erc20Address, erc20Service: erc20Service,
erc20Instance: erc20Instance,
store: store, store: store,
chequeSigner: chequeSigner, chequeSigner: chequeSigner,
totalIssuedReserved: big.NewInt(0), totalIssuedReserved: big.NewInt(0),
...@@ -111,9 +104,7 @@ func (s *service) Address() common.Address { ...@@ -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. // 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) { func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
balance, err := s.erc20Instance.BalanceOf(&bind.CallOpts{ balance, err := s.erc20Service.BalanceOf(ctx, s.ownerAddress)
Context: ctx,
}, s.ownerAddress)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
...@@ -123,25 +114,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has ...@@ -123,25 +114,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has
return common.Hash{}, ErrInsufficientFunds return common.Hash{}, ErrInsufficientFunds
} }
callData, err := erc20ABI.Pack("transfer", s.address, amount) return s.erc20Service.Transfer(ctx, 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
} }
// Balance returns the token balance of the chequebook. // Balance returns the token balance of the chequebook.
......
...@@ -7,6 +7,7 @@ package chequebook_test ...@@ -7,6 +7,7 @@ package chequebook_test
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"math/big" "math/big"
"testing" "testing"
...@@ -14,6 +15,8 @@ import ( ...@@ -14,6 +15,8 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook" "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"
"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" transactionmock "github.com/ethersphere/bee/pkg/settlement/swap/transaction/mock"
...@@ -26,20 +29,20 @@ func newTestChequebook( ...@@ -26,20 +29,20 @@ func newTestChequebook(
backend transaction.Backend, backend transaction.Backend,
transactionService transaction.Service, transactionService transaction.Service,
address, address,
erc20address,
ownerAdress common.Address, ownerAdress common.Address,
store storage.StateStorer, store storage.StateStorer,
chequeSigner chequebook.ChequeSigner, chequeSigner chequebook.ChequeSigner,
erc20 erc20.Service,
simpleSwapBinding chequebook.SimpleSwapBinding, simpleSwapBinding chequebook.SimpleSwapBinding,
erc20Binding chequebook.ERC20Binding) (chequebook.Service, error) { ) (chequebook.Service, error) {
return chequebook.New( return chequebook.New(
backend, backend,
transactionService, transactionService,
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
chequeSigner, chequeSigner,
erc20,
func(addr common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) { func(addr common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
if addr != address { if addr != address {
t.Fatalf("initialised binding with wrong address. wanted %x, got %x", address, addr) t.Fatalf("initialised binding with wrong address. wanted %x, got %x", address, addr)
...@@ -49,33 +52,23 @@ func newTestChequebook( ...@@ -49,33 +52,23 @@ func newTestChequebook(
} }
return simpleSwapBinding, nil 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) { func TestChequebookAddress(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
chequebookService, err := newTestChequebook( chequebookService, err := newTestChequebook(
t, t,
backendmock.New(), backendmock.New(),
transactionmock.New(), transactionmock.New(),
address, address,
erc20address,
ownerAdress, ownerAdress,
nil, nil,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{}, &simpleSwapBindingMock{},
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -87,7 +80,6 @@ func TestChequebookAddress(t *testing.T) { ...@@ -87,7 +80,6 @@ func TestChequebookAddress(t *testing.T) {
func TestChequebookBalance(t *testing.T) { func TestChequebookBalance(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(10) balance := big.NewInt(10)
chequebookService, err := newTestChequebook( chequebookService, err := newTestChequebook(
...@@ -95,16 +87,16 @@ func TestChequebookBalance(t *testing.T) { ...@@ -95,16 +87,16 @@ func TestChequebookBalance(t *testing.T) {
backendmock.New(), backendmock.New(),
transactionmock.New(), transactionmock.New(),
address, address,
erc20address,
ownerAdress, ownerAdress,
nil, nil,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return balance, nil return balance, nil
}, },
}, },
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -121,7 +113,6 @@ func TestChequebookBalance(t *testing.T) { ...@@ -121,7 +113,6 @@ func TestChequebookBalance(t *testing.T) {
func TestChequebookDeposit(t *testing.T) { func TestChequebookDeposit(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30) balance := big.NewInt(30)
depositAmount := big.NewInt(20) depositAmount := big.NewInt(20)
...@@ -129,31 +120,30 @@ func TestChequebookDeposit(t *testing.T) { ...@@ -129,31 +120,30 @@ func TestChequebookDeposit(t *testing.T) {
chequebookService, err := newTestChequebook( chequebookService, err := newTestChequebook(
t, t,
backendmock.New(), backendmock.New(),
transactionmock.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
}),
),
address, address,
erc20address,
ownerAdress, ownerAdress,
nil, nil,
&chequeSignerMock{}, &chequeSignerMock{},
&simpleSwapBindingMock{}, erc20mock.New(
&erc20BindingMock{ erc20mock.WithBalanceOfFunc(func(ctx context.Context, address common.Address) (*big.Int, error) {
balanceOf: func(b *bind.CallOpts, addr common.Address) (*big.Int, error) { if address != ownerAdress {
if addr != ownerAdress { return nil, errors.New("getting balance of wrong address")
t.Fatalf("looking up balance of wrong account. wanted %x, got %x", ownerAdress, addr)
} }
return balance, nil 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -170,7 +160,6 @@ func TestChequebookDeposit(t *testing.T) { ...@@ -170,7 +160,6 @@ func TestChequebookDeposit(t *testing.T) {
func TestChequebookWaitForDeposit(t *testing.T) { func TestChequebookWaitForDeposit(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
txHash := common.HexToHash("0xdddd") txHash := common.HexToHash("0xdddd")
chequebookService, err := newTestChequebook( chequebookService, err := newTestChequebook(
...@@ -187,12 +176,12 @@ func TestChequebookWaitForDeposit(t *testing.T) { ...@@ -187,12 +176,12 @@ func TestChequebookWaitForDeposit(t *testing.T) {
}), }),
), ),
address, address,
erc20address,
ownerAdress, ownerAdress,
nil, nil,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{}, &simpleSwapBindingMock{},
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -205,7 +194,6 @@ func TestChequebookWaitForDeposit(t *testing.T) { ...@@ -205,7 +194,6 @@ func TestChequebookWaitForDeposit(t *testing.T) {
func TestChequebookWaitForDepositReverted(t *testing.T) { func TestChequebookWaitForDepositReverted(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
txHash := common.HexToHash("0xdddd") txHash := common.HexToHash("0xdddd")
chequebookService, err := newTestChequebook( chequebookService, err := newTestChequebook(
...@@ -222,12 +210,12 @@ func TestChequebookWaitForDepositReverted(t *testing.T) { ...@@ -222,12 +210,12 @@ func TestChequebookWaitForDepositReverted(t *testing.T) {
}), }),
), ),
address, address,
erc20address,
ownerAdress, ownerAdress,
nil, nil,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{}, &simpleSwapBindingMock{},
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -243,7 +231,6 @@ func TestChequebookWaitForDepositReverted(t *testing.T) { ...@@ -243,7 +231,6 @@ func TestChequebookWaitForDepositReverted(t *testing.T) {
func TestChequebookIssue(t *testing.T) { func TestChequebookIssue(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd") beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore() store := storemock.NewStateStore()
...@@ -258,10 +245,10 @@ func TestChequebookIssue(t *testing.T) { ...@@ -258,10 +245,10 @@ func TestChequebookIssue(t *testing.T) {
backendmock.New(), backendmock.New(),
transactionmock.New(), transactionmock.New(),
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
chequeSigner, chequeSigner,
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(100), nil return big.NewInt(100), nil
...@@ -270,7 +257,7 @@ func TestChequebookIssue(t *testing.T) { ...@@ -270,7 +257,7 @@ func TestChequebookIssue(t *testing.T) {
return big.NewInt(0), nil return big.NewInt(0), nil
}, },
}, },
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -396,7 +383,6 @@ func TestChequebookIssue(t *testing.T) { ...@@ -396,7 +383,6 @@ func TestChequebookIssue(t *testing.T) {
func TestChequebookIssueErrorSend(t *testing.T) { func TestChequebookIssueErrorSend(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd") beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore() store := storemock.NewStateStore()
...@@ -409,10 +395,10 @@ func TestChequebookIssueErrorSend(t *testing.T) { ...@@ -409,10 +395,10 @@ func TestChequebookIssueErrorSend(t *testing.T) {
backendmock.New(), backendmock.New(),
transactionmock.New(), transactionmock.New(),
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
chequeSigner, chequeSigner,
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return amount, nil return amount, nil
...@@ -421,7 +407,7 @@ func TestChequebookIssueErrorSend(t *testing.T) { ...@@ -421,7 +407,7 @@ func TestChequebookIssueErrorSend(t *testing.T) {
return big.NewInt(0), nil return big.NewInt(0), nil
}, },
}, },
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -446,7 +432,6 @@ func TestChequebookIssueErrorSend(t *testing.T) { ...@@ -446,7 +432,6 @@ func TestChequebookIssueErrorSend(t *testing.T) {
func TestChequebookIssueOutOfFunds(t *testing.T) { func TestChequebookIssueOutOfFunds(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
beneficiary := common.HexToAddress("0xdddd") beneficiary := common.HexToAddress("0xdddd")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
store := storemock.NewStateStore() store := storemock.NewStateStore()
...@@ -457,10 +442,10 @@ func TestChequebookIssueOutOfFunds(t *testing.T) { ...@@ -457,10 +442,10 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
backendmock.New(), backendmock.New(),
transactionmock.New(), transactionmock.New(),
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0), nil return big.NewInt(0), nil
...@@ -469,7 +454,7 @@ func TestChequebookIssueOutOfFunds(t *testing.T) { ...@@ -469,7 +454,7 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
return big.NewInt(0), nil return big.NewInt(0), nil
}, },
}, },
&erc20BindingMock{}) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -491,7 +476,6 @@ func TestChequebookIssueOutOfFunds(t *testing.T) { ...@@ -491,7 +476,6 @@ func TestChequebookIssueOutOfFunds(t *testing.T) {
func TestChequebookWithdraw(t *testing.T) { func TestChequebookWithdraw(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30) balance := big.NewInt(30)
withdrawAmount := big.NewInt(20) withdrawAmount := big.NewInt(20)
...@@ -512,10 +496,10 @@ func TestChequebookWithdraw(t *testing.T) { ...@@ -512,10 +496,10 @@ func TestChequebookWithdraw(t *testing.T) {
}), }),
), ),
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return balance, nil return balance, nil
...@@ -524,14 +508,7 @@ func TestChequebookWithdraw(t *testing.T) { ...@@ -524,14 +508,7 @@ func TestChequebookWithdraw(t *testing.T) {
return big.NewInt(0), nil 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -548,7 +525,6 @@ func TestChequebookWithdraw(t *testing.T) { ...@@ -548,7 +525,6 @@ func TestChequebookWithdraw(t *testing.T) {
func TestChequebookWithdrawInsufficientFunds(t *testing.T) { func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
address := common.HexToAddress("0xabcd") address := common.HexToAddress("0xabcd")
erc20address := common.HexToAddress("0xefff")
ownerAdress := common.HexToAddress("0xfff") ownerAdress := common.HexToAddress("0xfff")
balance := big.NewInt(30) balance := big.NewInt(30)
withdrawAmount := big.NewInt(20) withdrawAmount := big.NewInt(20)
...@@ -567,12 +543,15 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) { ...@@ -567,12 +543,15 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
} }
return txHash, nil return txHash, nil
}), }),
transactionmock.WithCallFunc(func(ctx context.Context, request *transaction.TxRequest) (result []byte, err error) {
return balance.FillBytes(make([]byte, 32)), nil
}),
), ),
address, address,
erc20address,
ownerAdress, ownerAdress,
store, store,
&chequeSignerMock{}, &chequeSignerMock{},
erc20mock.New(),
&simpleSwapBindingMock{ &simpleSwapBindingMock{
balance: func(*bind.CallOpts) (*big.Int, error) { balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0), nil return big.NewInt(0), nil
...@@ -581,14 +560,7 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) { ...@@ -581,14 +560,7 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
return big.NewInt(0), nil 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -36,14 +36,6 @@ func (m *simpleSwapBindingMock) PaidOut(o *bind.CallOpts, c common.Address) (*bi ...@@ -36,14 +36,6 @@ func (m *simpleSwapBindingMock) PaidOut(o *bind.CallOpts, c common.Address) (*bi
return m.paidOut(o, c) 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 { type chequeSignerMock struct {
sign func(cheque *chequebook.Cheque) ([]byte, error) sign func(cheque *chequebook.Cheque) ([]byte, error)
} }
......
...@@ -10,9 +10,9 @@ import ( ...@@ -10,9 +10,9 @@ import (
"math/big" "math/big"
"time" "time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/logging" "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/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
) )
...@@ -20,6 +20,9 @@ import ( ...@@ -20,6 +20,9 @@ import (
const ( const (
chequebookKey = "swap_chequebook" chequebookKey = "swap_chequebook"
chequebookDeploymentKey = "swap_chequebook_transaction_deployment" chequebookDeploymentKey = "swap_chequebook_transaction_deployment"
balanceCheckBackoffDuration = 20 * time.Second
balanceCheckMaxRetries = 10
) )
func checkBalance( func checkBalance(
...@@ -29,23 +32,12 @@ func checkBalance( ...@@ -29,23 +32,12 @@ func checkBalance(
swapBackend transaction.Backend, swapBackend transaction.Backend,
chainId int64, chainId int64,
overlayEthAddress common.Address, overlayEthAddress common.Address,
erc20BindingFunc ERC20BindingFunc, erc20Token erc20.Service,
erc20Address common.Address,
backoffDuration time.Duration,
maxRetries uint64,
) error { ) error {
timeoutCtx, cancel := context.WithTimeout(ctx, backoffDuration*time.Duration(maxRetries)) timeoutCtx, cancel := context.WithTimeout(ctx, balanceCheckBackoffDuration*time.Duration(balanceCheckMaxRetries))
defer cancel() defer cancel()
erc20Token, err := erc20BindingFunc(erc20Address, swapBackend)
if err != nil {
return err
}
for { for {
erc20Balance, err := erc20Token.BalanceOf(&bind.CallOpts{ erc20Balance, err := erc20Token.BalanceOf(timeoutCtx, overlayEthAddress)
Context: timeoutCtx,
}, overlayEthAddress)
if err != nil { if err != nil {
return err return err
} }
...@@ -83,7 +75,7 @@ func checkBalance( ...@@ -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) 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 { select {
case <-time.After(backoffDuration): case <-time.After(balanceCheckBackoffDuration):
case <-timeoutCtx.Done(): case <-timeoutCtx.Done():
if insufficientERC20 { if insufficientERC20 {
return fmt.Errorf("insufficient BZZ for initial deposit") return fmt.Errorf("insufficient BZZ for initial deposit")
...@@ -111,7 +103,7 @@ func Init( ...@@ -111,7 +103,7 @@ func Init(
overlayEthAddress common.Address, overlayEthAddress common.Address,
chequeSigner ChequeSigner, chequeSigner ChequeSigner,
simpleSwapBindingFunc SimpleSwapBindingFunc, simpleSwapBindingFunc SimpleSwapBindingFunc,
erc20BindingFunc ERC20BindingFunc) (chequebookService Service, err error) { ) (chequebookService Service, err error) {
// verify that the supplied factory is valid // verify that the supplied factory is valid
err = chequebookFactory.VerifyBytecode(ctx) err = chequebookFactory.VerifyBytecode(ctx)
if err != nil { if err != nil {
...@@ -123,6 +115,8 @@ func Init( ...@@ -123,6 +115,8 @@ func Init(
return nil, err return nil, err
} }
erc20Service := erc20.New(swapBackend, transactionService, erc20Address)
var chequebookAddress common.Address var chequebookAddress common.Address
err = stateStore.Get(chequebookKey, &chequebookAddress) err = stateStore.Get(chequebookKey, &chequebookAddress)
if err != nil { if err != nil {
...@@ -138,7 +132,7 @@ func Init( ...@@ -138,7 +132,7 @@ func Init(
if err == storage.ErrNotFound { if err == storage.ErrNotFound {
logger.Info("no chequebook found, deploying new one.") logger.Info("no chequebook found, deploying new one.")
if swapInitialDeposit.Cmp(big.NewInt(0)) != 0 { 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -173,7 +167,7 @@ func Init( ...@@ -173,7 +167,7 @@ func Init(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -194,7 +188,7 @@ func Init( ...@@ -194,7 +188,7 @@ func Init(
logger.Info("successfully deposited to chequebook") logger.Info("successfully deposited to chequebook")
} }
} else { } 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 { if err != nil {
return nil, err 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