2019-07-02 07:28:57 +00:00
|
|
|
package wallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
|
2020-09-15 11:46:28 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
|
|
|
2020-01-02 09:10:19 +00:00
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
|
2019-07-02 07:28:57 +00:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
2020-01-02 09:10:19 +00:00
|
|
|
|
2019-07-02 07:28:57 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/erc20"
|
|
|
|
"github.com/status-im/status-go/t/devtests/miner"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestBalancesSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(BalancesSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
type BalancesSuite struct {
|
|
|
|
suite.Suite
|
|
|
|
|
|
|
|
tokens []common.Address
|
|
|
|
accounts []common.Address
|
|
|
|
|
|
|
|
client *ethclient.Client
|
|
|
|
|
|
|
|
faucet *ecdsa.PrivateKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) SetupTest() {
|
|
|
|
var err error
|
|
|
|
s.faucet, err = crypto.GenerateKey()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
node, err := miner.NewDevNode(crypto.PubkeyToAddress(s.faucet.PublicKey))
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().NoError(miner.StartWithMiner(node))
|
|
|
|
|
|
|
|
client, err := node.Attach()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.client = ethclient.NewClient(client)
|
|
|
|
|
|
|
|
s.tokens = make([]common.Address, 3)
|
|
|
|
s.accounts = make([]common.Address, 5)
|
|
|
|
for i := range s.accounts {
|
|
|
|
key, err := crypto.GenerateKey()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.accounts[i] = crypto.PubkeyToAddress(key.PublicKey)
|
|
|
|
}
|
|
|
|
for i := range s.tokens {
|
|
|
|
token, tx, _, err := erc20.DeployERC20Transfer(bind.NewKeyedTransactor(s.faucet), s.client)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
_, err = bind.WaitMined(context.Background(), s.client, tx)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.tokens[i] = token
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestBalanceEqualPerToken() {
|
|
|
|
base := big.NewInt(10)
|
2020-09-15 11:46:28 +00:00
|
|
|
expected := map[common.Address]map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
for _, account := range s.accounts {
|
2020-09-15 11:46:28 +00:00
|
|
|
expected[account] = map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
for i, token := range s.tokens {
|
|
|
|
balance := new(big.Int).Add(base, big.NewInt(int64(i)))
|
|
|
|
transactor, err := erc20.NewERC20Transfer(token, s.client)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
tx, err := transactor.Transfer(bind.NewKeyedTransactor(s.faucet), account, balance)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
_, err = bind.WaitMined(context.Background(), s.client, tx)
|
|
|
|
s.Require().NoError(err)
|
2020-09-15 11:46:28 +00:00
|
|
|
expected[account][token] = (*hexutil.Big)(balance)
|
2019-07-02 07:28:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestBalanceEqualPerAccount() {
|
|
|
|
base := big.NewInt(10)
|
2020-09-15 11:46:28 +00:00
|
|
|
expected := map[common.Address]map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
for i, account := range s.accounts {
|
2020-09-15 11:46:28 +00:00
|
|
|
expected[account] = map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
for _, token := range s.tokens {
|
|
|
|
balance := new(big.Int).Add(base, big.NewInt(int64(i)))
|
|
|
|
transactor, err := erc20.NewERC20Transfer(token, s.client)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
tx, err := transactor.Transfer(bind.NewKeyedTransactor(s.faucet), account, balance)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
_, err = bind.WaitMined(context.Background(), s.client, tx)
|
|
|
|
s.Require().NoError(err)
|
2020-09-15 11:46:28 +00:00
|
|
|
expected[account][token] = (*hexutil.Big)(balance)
|
2019-07-02 07:28:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestNoBalances() {
|
|
|
|
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
for _, account := range s.accounts {
|
|
|
|
for _, token := range s.tokens {
|
2020-09-15 11:46:28 +00:00
|
|
|
s.Require().Equal(zero.Int64(), result[account][token].ToInt().Int64())
|
2019-07-02 07:28:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestNoTokens() {
|
2020-09-15 11:46:28 +00:00
|
|
|
expected := map[common.Address]map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, nil)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestNoAccounts() {
|
2020-09-15 11:46:28 +00:00
|
|
|
expected := map[common.Address]map[common.Address]*hexutil.Big{}
|
2019-07-02 07:28:57 +00:00
|
|
|
result, err := GetTokensBalances(context.Background(), s.client, nil, s.tokens)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestTokenNotDeployed() {
|
|
|
|
_, err := GetTokensBalances(context.Background(), s.client, s.accounts, []common.Address{{0x01}})
|
2020-10-05 09:01:39 +00:00
|
|
|
s.Require().NoError(err)
|
2019-07-02 07:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *BalancesSuite) TestInterrupted() {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
|
|
|
_, err := GetTokensBalances(ctx, s.client, s.accounts, s.tokens)
|
|
|
|
s.Require().EqualError(err, "context canceled")
|
|
|
|
}
|