[#2042] Wrong ERC20 decimal rounding in "Set max"

This commit is contained in:
andrey 2020-09-15 13:46:28 +02:00 committed by flexsurfer
parent 682722b973
commit 397ee840c6
5 changed files with 24 additions and 19 deletions

View File

@ -1 +1 @@
0.62.2 0.62.3

View File

@ -106,7 +106,7 @@ func (api *API) GetTransfersByAddress(ctx context.Context, address common.Addres
} }
// GetTokensBalances return mapping of token balances for every account. // GetTokensBalances return mapping of token balances for every account.
func (api *API) GetTokensBalances(ctx context.Context, accounts, tokens []common.Address) (map[common.Address]map[common.Address]*big.Int, error) { func (api *API) GetTokensBalances(ctx context.Context, accounts, tokens []common.Address) (map[common.Address]map[common.Address]*hexutil.Big, error) {
if api.s.client == nil { if api.s.client == nil {
return nil, ErrServiceNotInitialized return nil, ErrServiceNotInitialized
} }

View File

@ -2,10 +2,11 @@ package wallet
import ( import (
"context" "context"
"math/big"
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/common/hexutil"
"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/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
@ -14,11 +15,11 @@ import (
) )
// GetTokensBalances takes list of accounts and tokens and returns mapping of token balances for each account. // GetTokensBalances takes list of accounts and tokens and returns mapping of token balances for each account.
func GetTokensBalances(parent context.Context, client *ethclient.Client, accounts, tokens []common.Address) (map[common.Address]map[common.Address]*big.Int, error) { func GetTokensBalances(parent context.Context, client *ethclient.Client, accounts, tokens []common.Address) (map[common.Address]map[common.Address]*hexutil.Big, error) {
var ( var (
group = NewAtomicGroup(parent) group = NewAtomicGroup(parent)
mu sync.Mutex mu sync.Mutex
response = map[common.Address]map[common.Address]*big.Int{} response = map[common.Address]map[common.Address]*hexutil.Big{}
) )
// requested current head to request balance on the same block number // requested current head to request balance on the same block number
ctx, cancel := context.WithTimeout(parent, 3*time.Second) ctx, cancel := context.WithTimeout(parent, 3*time.Second)
@ -48,7 +49,7 @@ func GetTokensBalances(parent context.Context, client *ethclient.Client, account
mu.Lock() mu.Lock()
_, exist := response[account] _, exist := response[account]
if !exist { if !exist {
response[account] = map[common.Address]*big.Int{} response[account] = map[common.Address]*hexutil.Big{}
} }
response[account][token] = balance response[account][token] = balance
mu.Unlock() mu.Unlock()

View File

@ -6,6 +6,8 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -63,9 +65,9 @@ func (s *BalancesSuite) SetupTest() {
func (s *BalancesSuite) TestBalanceEqualPerToken() { func (s *BalancesSuite) TestBalanceEqualPerToken() {
base := big.NewInt(10) base := big.NewInt(10)
expected := map[common.Address]map[common.Address]*big.Int{} expected := map[common.Address]map[common.Address]*hexutil.Big{}
for _, account := range s.accounts { for _, account := range s.accounts {
expected[account] = map[common.Address]*big.Int{} expected[account] = map[common.Address]*hexutil.Big{}
for i, token := range s.tokens { for i, token := range s.tokens {
balance := new(big.Int).Add(base, big.NewInt(int64(i))) balance := new(big.Int).Add(base, big.NewInt(int64(i)))
transactor, err := erc20.NewERC20Transfer(token, s.client) transactor, err := erc20.NewERC20Transfer(token, s.client)
@ -74,7 +76,7 @@ func (s *BalancesSuite) TestBalanceEqualPerToken() {
s.Require().NoError(err) s.Require().NoError(err)
_, err = bind.WaitMined(context.Background(), s.client, tx) _, err = bind.WaitMined(context.Background(), s.client, tx)
s.Require().NoError(err) s.Require().NoError(err)
expected[account][token] = balance expected[account][token] = (*hexutil.Big)(balance)
} }
} }
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens) result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens)
@ -84,9 +86,9 @@ func (s *BalancesSuite) TestBalanceEqualPerToken() {
func (s *BalancesSuite) TestBalanceEqualPerAccount() { func (s *BalancesSuite) TestBalanceEqualPerAccount() {
base := big.NewInt(10) base := big.NewInt(10)
expected := map[common.Address]map[common.Address]*big.Int{} expected := map[common.Address]map[common.Address]*hexutil.Big{}
for i, account := range s.accounts { for i, account := range s.accounts {
expected[account] = map[common.Address]*big.Int{} expected[account] = map[common.Address]*hexutil.Big{}
for _, token := range s.tokens { for _, token := range s.tokens {
balance := new(big.Int).Add(base, big.NewInt(int64(i))) balance := new(big.Int).Add(base, big.NewInt(int64(i)))
transactor, err := erc20.NewERC20Transfer(token, s.client) transactor, err := erc20.NewERC20Transfer(token, s.client)
@ -95,7 +97,7 @@ func (s *BalancesSuite) TestBalanceEqualPerAccount() {
s.Require().NoError(err) s.Require().NoError(err)
_, err = bind.WaitMined(context.Background(), s.client, tx) _, err = bind.WaitMined(context.Background(), s.client, tx)
s.Require().NoError(err) s.Require().NoError(err)
expected[account][token] = balance expected[account][token] = (*hexutil.Big)(balance)
} }
} }
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens) result, err := GetTokensBalances(context.Background(), s.client, s.accounts, s.tokens)
@ -108,20 +110,20 @@ func (s *BalancesSuite) TestNoBalances() {
s.Require().NoError(err) s.Require().NoError(err)
for _, account := range s.accounts { for _, account := range s.accounts {
for _, token := range s.tokens { for _, token := range s.tokens {
s.Require().Equal(zero.Int64(), result[account][token].Int64()) s.Require().Equal(zero.Int64(), result[account][token].ToInt().Int64())
} }
} }
} }
func (s *BalancesSuite) TestNoTokens() { func (s *BalancesSuite) TestNoTokens() {
expected := map[common.Address]map[common.Address]*big.Int{} expected := map[common.Address]map[common.Address]*hexutil.Big{}
result, err := GetTokensBalances(context.Background(), s.client, s.accounts, nil) result, err := GetTokensBalances(context.Background(), s.client, s.accounts, nil)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(expected, result) s.Require().Equal(expected, result)
} }
func (s *BalancesSuite) TestNoAccounts() { func (s *BalancesSuite) TestNoAccounts() {
expected := map[common.Address]map[common.Address]*big.Int{} expected := map[common.Address]map[common.Address]*hexutil.Big{}
result, err := GetTokensBalances(context.Background(), s.client, nil, s.tokens) result, err := GetTokensBalances(context.Background(), s.client, nil, s.tokens)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(expected, result) s.Require().Equal(expected, result)

View File

@ -7,6 +7,8 @@ import (
"math/big" "math/big"
"strings" "strings"
"github.com/ethereum/go-ethereum/common/hexutil"
ethereum "github.com/ethereum/go-ethereum" ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -217,26 +219,26 @@ func (_IERC20 *IERC20CallerSession) Allowance(owner common.Address, spender comm
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
// //
// Solidity: function balanceOf(address account) constant returns(uint256) // Solidity: function balanceOf(address account) constant returns(uint256)
func (_IERC20 *IERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { func (_IERC20 *IERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*hexutil.Big, error) {
var ( var (
ret0 = new(*big.Int) ret0 = new(*big.Int)
) )
out := ret0 out := ret0
err := _IERC20.contract.Call(opts, out, "balanceOf", account) err := _IERC20.contract.Call(opts, out, "balanceOf", account)
return *ret0, err return (*hexutil.Big)(*ret0), err
} }
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
// //
// Solidity: function balanceOf(address account) constant returns(uint256) // Solidity: function balanceOf(address account) constant returns(uint256)
func (_IERC20 *IERC20Session) BalanceOf(account common.Address) (*big.Int, error) { func (_IERC20 *IERC20Session) BalanceOf(account common.Address) (*hexutil.Big, error) {
return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account)
} }
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
// //
// Solidity: function balanceOf(address account) constant returns(uint256) // Solidity: function balanceOf(address account) constant returns(uint256)
func (_IERC20 *IERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { func (_IERC20 *IERC20CallerSession) BalanceOf(account common.Address) (*hexutil.Big, error) {
return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account)
} }