diff --git a/api/gateway/chain/internal/service/gateway/commands/transfer/fee.go b/api/gateway/chain/internal/service/gateway/commands/transfer/fee.go index 992e152..f622f8d 100644 --- a/api/gateway/chain/internal/service/gateway/commands/transfer/fee.go +++ b/api/gateway/chain/internal/service/gateway/commands/transfer/fee.go @@ -199,11 +199,17 @@ func erc20Decimals(ctx context.Context, client *rpc.Client, token common.Address if err := client.CallContext(ctx, &hexResp, "eth_call", call, "latest"); err != nil { return 0, merrors.Internal("decimals call failed: " + err.Error()) } - val, err := hexutil.DecodeUint64(hexResp) + val, err := hexutil.DecodeBig(hexResp) if err != nil { return 0, merrors.Internal("decimals decode failed: " + err.Error()) } - return uint8(val), nil + if val == nil { + return 0, merrors.Internal("decimals decode failed: empty response") + } + if val.BitLen() > 8 { + return 0, merrors.Internal("decimals decode failed: value out of range") + } + return uint8(val.Uint64()), nil } func toBaseUnits(amount string, decimals uint8) (*big.Int, error) { diff --git a/api/gateway/chain/internal/service/gateway/commands/wallet/onchain_balance.go b/api/gateway/chain/internal/service/gateway/commands/wallet/onchain_balance.go index 8452237..61c1cdb 100644 --- a/api/gateway/chain/internal/service/gateway/commands/wallet/onchain_balance.go +++ b/api/gateway/chain/internal/service/gateway/commands/wallet/onchain_balance.go @@ -104,11 +104,17 @@ func readDecimals(ctx context.Context, client *rpc.Client, token string) (uint8, if err := client.CallContext(ctx, &hexResp, "eth_call", call, "latest"); err != nil { return 0, merrors.Internal("decimals call failed: " + err.Error()) } - val, err := hexutil.DecodeUint64(hexResp) + val, err := hexutil.DecodeBig(hexResp) if err != nil { return 0, merrors.Internal("decimals decode failed: " + err.Error()) } - return uint8(val), nil + if val == nil { + return 0, merrors.Internal("decimals decode failed: empty response") + } + if val.BitLen() > 8 { + return 0, merrors.Internal("decimals decode failed: value out of range") + } + return uint8(val.Uint64()), nil } func readBalanceOf(ctx context.Context, client *rpc.Client, token string, wallet string) (*big.Int, error) { diff --git a/api/gateway/chain/internal/service/gateway/executor.go b/api/gateway/chain/internal/service/gateway/executor.go index bc5e25d..a76222e 100644 --- a/api/gateway/chain/internal/service/gateway/executor.go +++ b/api/gateway/chain/internal/service/gateway/executor.go @@ -315,11 +315,17 @@ func erc20Decimals(ctx context.Context, client *rpc.Client, token common.Address if err := client.CallContext(ctx, &hexResp, "eth_call", call, "latest"); err != nil { return 0, executorInternal("decimals call failed", err) } - val, err := hexutil.DecodeUint64(hexResp) + val, err := hexutil.DecodeBig(hexResp) if err != nil { return 0, executorInternal("decimals decode failed", err) } - return uint8(val), nil + if val == nil { + return 0, executorInternal("decimals decode failed", errors.New("empty response")) + } + if val.BitLen() > 8 { + return 0, executorInternal("decimals decode failed", errors.New("value out of range")) + } + return uint8(val.Uint64()), nil } func toBaseUnits(amount string, decimals uint8) (*big.Int, error) {