From e0db927bca979e2ca13535c5cc0148f3c5a1dc4f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 10 Feb 2020 18:42:20 +0100 Subject: [PATCH] Add strict toErc20Amount converter --- packages/bcp/src/cosmwasmcodec.spec.ts | 2 +- packages/bcp/src/cosmwasmconnection.spec.ts | 2 +- packages/bcp/src/encode.spec.ts | 34 ++++++++++++++++++++- packages/bcp/src/encode.ts | 10 +++++- packages/bcp/types/encode.d.ts | 1 + 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/packages/bcp/src/cosmwasmcodec.spec.ts b/packages/bcp/src/cosmwasmcodec.spec.ts index d55a2939..2269887e 100644 --- a/packages/bcp/src/cosmwasmcodec.spec.ts +++ b/packages/bcp/src/cosmwasmcodec.spec.ts @@ -75,7 +75,7 @@ describe("CosmWasmCodec", () => { recipient: "cosmos1dddd" as Address, memo: "My first BASH payment", amount: { - fractionalDigits: 6, + fractionalDigits: 0, quantity: "345", tokenTicker: "BASH" as TokenTicker, }, diff --git a/packages/bcp/src/cosmwasmconnection.spec.ts b/packages/bcp/src/cosmwasmconnection.spec.ts index 769eb07a..6e28d6dc 100644 --- a/packages/bcp/src/cosmwasmconnection.spec.ts +++ b/packages/bcp/src/cosmwasmconnection.spec.ts @@ -477,7 +477,7 @@ describe("CosmWasmConnection", () => { memo: "My first payment", amount: { quantity: "75", - fractionalDigits: 3, // todo: BROKEN! + fractionalDigits: 0, tokenTicker: "BASH" as TokenTicker, }, }); diff --git a/packages/bcp/src/encode.spec.ts b/packages/bcp/src/encode.spec.ts index 9b5138bc..0e239aa4 100644 --- a/packages/bcp/src/encode.spec.ts +++ b/packages/bcp/src/encode.spec.ts @@ -20,6 +20,7 @@ import { encodeFee, encodeFullSignature, encodePubkey, + toErc20Amount, } from "./encode"; import { BankTokens, Erc20Token } from "./types"; @@ -75,6 +76,37 @@ describe("encode", () => { }); }); + describe("toErc20Amount", () => { + const [ash, bash] = defaultErc20Tokens; + + it("encodes an amount", () => { + const amount: Amount = { + quantity: "789", + fractionalDigits: 0, + tokenTicker: "BASH" as TokenTicker, + }; + expect(toErc20Amount(amount, bash)).toEqual("789"); + }); + + it("throws on ticker mismatch", () => { + const amount: Amount = { + quantity: "789", + fractionalDigits: 0, + tokenTicker: "BASH" as TokenTicker, + }; + expect(() => toErc20Amount(amount, ash)).toThrowError(/ticker mismatch/i); + }); + + it("throws on ticker mismatch", () => { + const amount: Amount = { + quantity: "789", + fractionalDigits: 2, + tokenTicker: "BASH" as TokenTicker, + }; + expect(() => toErc20Amount(amount, bash)).toThrowError(/fractional digits mismatch/i); + }); + }); + describe("amountToBankCoin", () => { it("encodes an amount", () => { expect(amountToBankCoin(defaultAmount, defaultTokens)).toEqual({ @@ -288,7 +320,7 @@ describe("encode", () => { recipient: "cosmos1dddd" as Address, memo: defaultMemo, amount: { - fractionalDigits: 6, + fractionalDigits: 0, quantity: "345", tokenTicker: "BASH" as TokenTicker, }, diff --git a/packages/bcp/src/encode.ts b/packages/bcp/src/encode.ts index e0446735..f1a61b65 100644 --- a/packages/bcp/src/encode.ts +++ b/packages/bcp/src/encode.ts @@ -33,6 +33,14 @@ export function encodePubkey(pubkey: PubkeyBundle): types.PubKey { } } +export function toErc20Amount(amount: Amount, erc20Token: Erc20Token): string { + if (amount.tokenTicker !== erc20Token.ticker) throw new Error("Ticker mismatch between amount and token"); + if (amount.fractionalDigits !== erc20Token.fractionalDigits) { + throw new Error("Fractional digits mismatch between amount and token"); + } + return amount.quantity; +} + export function amountToBankCoin(amount: Amount, tokens: BankTokens): types.Coin { const match = tokens.find(token => token.ticker === amount.tokenTicker); if (!match) throw Error(`unknown ticker: ${amount.tokenTicker}`); @@ -117,7 +125,7 @@ export function buildUnsignedTx( contract: matchingErc20Token.contractAddress, msg: { transfer: { - amount: tx.amount.quantity, + amount: toErc20Amount(tx.amount, matchingErc20Token), recipient: tx.recipient, }, }, diff --git a/packages/bcp/types/encode.d.ts b/packages/bcp/types/encode.d.ts index 8589e217..fe974fc0 100644 --- a/packages/bcp/types/encode.d.ts +++ b/packages/bcp/types/encode.d.ts @@ -2,6 +2,7 @@ import { types } from "@cosmwasm/sdk"; import { Amount, Fee, FullSignature, PubkeyBundle, SignedTransaction, UnsignedTransaction } from "@iov/bcp"; import { BankTokens, Erc20Token } from "./types"; export declare function encodePubkey(pubkey: PubkeyBundle): types.PubKey; +export declare function toErc20Amount(amount: Amount, erc20Token: Erc20Token): string; export declare function amountToBankCoin(amount: Amount, tokens: BankTokens): types.Coin; export declare function encodeFee(fee: Fee, tokens: BankTokens): types.StdFee; export declare function encodeFullSignature(fullSignature: FullSignature): types.StdSignature;