Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1452d3c4d7 |
@@ -1687,12 +1687,9 @@ view would leave a wallet one click from deletion.
|
|||||||
- "Review" (valid inputs, ENS resolved) → **ConfirmTx**
|
- "Review" (valid inputs, ENS resolved) → **ConfirmTx**
|
||||||
- "Review" with an unresolvable ENS name or an invalid amount → flash
|
- "Review" with an unresolvable ENS name or an invalid amount → flash
|
||||||
message, no screen change. An amount is valid when it is a number above
|
message, no screen change. An amount is valid when it is a number above
|
||||||
zero, written as digits with at most one decimal point, with nothing but
|
zero written as digits with at most one decimal point, with no more
|
||||||
zeros after the token's last decimal place. ETH has 18 places, and a token
|
decimal places than the token has and never more than 18 (ETH's own),
|
||||||
with more, or with an unknown number, is held to 18. Zeros past those
|
which is also the check ConfirmTx makes before anything can be sent
|
||||||
places leave the amount unchanged, so `1.0000000` of a 6-place token
|
|
||||||
passes and is sent as exactly 1. ConfirmTx makes the same check before
|
|
||||||
anything can be sent
|
|
||||||
- "Back" → previous screen (Home, AddressDetail, or AddressToken)
|
- "Back" → previous screen (Home, AddressDetail, or AddressToken)
|
||||||
|
|
||||||
#### ConfirmTx (`confirm-tx`)
|
#### ConfirmTx (`confirm-tx`)
|
||||||
|
|||||||
@@ -89,16 +89,13 @@ function toFixedPoint(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Whether `amount` can be sent: a number above zero, written as digits with
|
// Whether `amount` can be sent: a number above zero, written as digits with
|
||||||
// at most one decimal point ("0.5", "12", ".5"), with nothing but zeros after
|
// at most one decimal point ("0.5", "12", ".5"), with no more decimal places
|
||||||
// the token's last decimal place, `tokenDecimals`, and nothing but zeros after
|
// than `tokenDecimals`, a token's own, and never more than the 18 the
|
||||||
// the 18th, the places the arithmetic here works in, which are ETH's. ETH, and
|
// arithmetic here works in, which are ETH's. ETH, and a token whose decimal
|
||||||
// a token whose decimal places are unknown, pass null and are held to the 18
|
// places are unknown, pass null and are held to the 18 (the confirmation
|
||||||
// (the confirmation screen refuses to send such a token anyway). Zeros past
|
// screen refuses to send such a token anyway). Refuses "1e-3", "1abc", "0"
|
||||||
// those places are accepted because parseUnits() drops them here and again
|
// and "-1". The Send screen checks it before the confirmation screen opens,
|
||||||
// when the transfer is encoded, so "1.0000000" of a 6-place token is exactly
|
// and validateTransfer() checks it again there.
|
||||||
// 1 everywhere. Refuses "1e-3", "1abc", "0" and "-1". The Send screen checks
|
|
||||||
// it before the confirmation screen opens, and validateTransfer() checks it
|
|
||||||
// again there.
|
|
||||||
function isValidAmount(amount, tokenDecimals = null) {
|
function isValidAmount(amount, tokenDecimals = null) {
|
||||||
if (typeof amount !== "string") return false;
|
if (typeof amount !== "string") return false;
|
||||||
const places = Math.min(tokenDecimals ?? SCALE_DECIMALS, SCALE_DECIMALS);
|
const places = Math.min(tokenDecimals ?? SCALE_DECIMALS, SCALE_DECIMALS);
|
||||||
|
|||||||
@@ -194,9 +194,6 @@ describe.each([
|
|||||||
["0.5", "TOK"],
|
["0.5", "TOK"],
|
||||||
// Exactly the 6 decimal places the token has.
|
// Exactly the 6 decimal places the token has.
|
||||||
["0.000001", "TOK"],
|
["0.000001", "TOK"],
|
||||||
// Only zeros past the token's 6 places, and past ETH's 18.
|
|
||||||
["1.0000000", "TOK"],
|
|
||||||
["0.5000000000000000000", "ETH"],
|
|
||||||
])("%s %s", (amount, symbol) => {
|
])("%s %s", (amount, symbol) => {
|
||||||
const token = TOKEN_BY_SYMBOL[symbol];
|
const token = TOKEN_BY_SYMBOL[symbol];
|
||||||
|
|
||||||
|
|||||||
@@ -116,12 +116,6 @@ describe("transferAmountUnits", () => {
|
|||||||
expect(() => transferAmountUnits("0.0000001", 6, 6n)).toThrow();
|
expect(() => transferAmountUnits("0.0000001", 6, 6n)).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("encodes zeros past the token's scale as the amount typed", () => {
|
|
||||||
// The Send screen accepts "1.0000000" for a 6-place token, so the
|
|
||||||
// transfer must move exactly 1 of it.
|
|
||||||
expect(transferAmountUnits("1.0000000", 6, 6n)).toBe(1000000n);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("every refusal is a full sentence", () => {
|
test("every refusal is a full sentence", () => {
|
||||||
const messages = [];
|
const messages = [];
|
||||||
for (const args of [
|
for (const args of [
|
||||||
|
|||||||
@@ -54,20 +54,13 @@ describe("isValidAmount", () => {
|
|||||||
expect(isValidAmount(undefined)).toBe(false);
|
expect(isValidAmount(undefined)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("refuses a digit other than 0 past the token's places", () => {
|
test("refuses more decimal places than the token has", () => {
|
||||||
expect(isValidAmount("0.000001", 6)).toBe(true);
|
expect(isValidAmount("0.000001", 6)).toBe(true);
|
||||||
expect(isValidAmount("0.0000001", 6)).toBe(false);
|
expect(isValidAmount("0.0000001", 6)).toBe(false);
|
||||||
expect(isValidAmount("5", 0)).toBe(true);
|
expect(isValidAmount("5", 0)).toBe(true);
|
||||||
expect(isValidAmount("0.5", 0)).toBe(false);
|
expect(isValidAmount("0.5", 0)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("accepts zeros past the token's places, which leave the amount unchanged", () => {
|
|
||||||
expect(isValidAmount("1.0000000", 6)).toBe(true);
|
|
||||||
expect(isValidAmount("5.0", 0)).toBe(true);
|
|
||||||
expect(isValidAmount("1.0000000000000000000")).toBe(true);
|
|
||||||
expect(isValidAmount("0.0000000", 6)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("holds ETH, a token of unknown places, and any token to 18 places", () => {
|
test("holds ETH, a token of unknown places, and any token to 18 places", () => {
|
||||||
const nineteen = "0.0000000000000000001";
|
const nineteen = "0.0000000000000000001";
|
||||||
expect(isValidAmount(nineteen)).toBe(false);
|
expect(isValidAmount(nineteen)).toBe(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user