/
erc20_query.go
75 lines (65 loc) · 1.53 KB
/
erc20_query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package keeper
import (
"fmt"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/fury-labs/fury-bridge/contract"
"github.com/fury-labs/fury-bridge/x/bridge/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
const (
erc20BalanceOfMethod = "balanceOf"
)
func (k Keeper) QueryERC20BalanceOf(
ctx sdk.Context,
contractAddr types.InternalEVMAddress,
account types.InternalEVMAddress,
) (*big.Int, error) {
res, err := k.CallEVM(
ctx,
contract.ERC20MintableBurnableContract.ABI,
types.ModuleEVMAddress,
contractAddr,
erc20BalanceOfMethod,
// balanceOf ERC20 args
account.Address,
)
if err != nil {
return nil, err
}
if res.Failed() {
if res.VmError == vm.ErrExecutionReverted.Error() {
// Unpacks revert
return nil, evmtypes.NewExecErrorWithReason(res.Ret)
}
return nil, status.Error(codes.Internal, res.VmError)
}
anyOutput, err := contract.ERC20MintableBurnableContract.ABI.Unpack(erc20BalanceOfMethod, res.Ret)
if err != nil {
return nil, fmt.Errorf(
"failed to unpack method %v response: %w",
erc20BalanceOfMethod,
err,
)
}
if len(anyOutput) != 1 {
return nil, fmt.Errorf(
"invalid ERC20 %v call return outputs %v, expected %v",
erc20BalanceOfMethod,
len(anyOutput),
1,
)
}
bal, ok := anyOutput[0].(*big.Int)
if !ok {
return nil, fmt.Errorf(
"invalid ERC20 return type %T, expected %T",
anyOutput[0],
&big.Int{},
)
}
return bal, nil
}