From da5068c12f05e4884a5e7449aade1fa188c5039b Mon Sep 17 00:00:00 2001
From: James Calfee <james@jcalfee.info>
Date: Wed, 12 Oct 2016 16:53:56 -0400
Subject: [PATCH] Validate all transfer amounts to at most 3 decimal places.
 (#466)

* Warning cleanup

* Validate all transfer amounts to at most 3 decimal places. close #461
---
 app/components/modules/Transfer.jsx   |  2 ++
 app/utils/ParsersAndFormatters.js     |  7 +++++++
 shared/serializer/src/number_utils.js | 24 ++++++++++++------------
 shared/serializer/src/types.js        | 15 ++++++---------
 4 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/app/components/modules/Transfer.jsx b/app/components/modules/Transfer.jsx
index 343665181..3299d0dc7 100644
--- a/app/components/modules/Transfer.jsx
+++ b/app/components/modules/Transfer.jsx
@@ -9,6 +9,7 @@ import {transferTips} from 'app/utils/Tips'
 import {powerTip, powerTip2, powerTip3} from 'app/utils/Tips'
 import {browserTests} from 'shared/ecc/test/BrowserTests'
 import {validate_account_name} from 'app/utils/ChainValidation';
+import {countDecimals} from 'app/utils/ParsersAndFormatters'
 
 /** Warning .. This is used for Power UP too. */
 class TransferForm extends Component {
@@ -76,6 +77,7 @@ class TransferForm extends Component {
                     ! values.amount ? 'Required' :
                     ! /^[0-9]*\.?[0-9]*/.test(values.amount) ? 'Amount is in the form 99999.999' :
                     insufficientFunds(values.asset, values.amount) ? 'Insufficient funds' :
+                    countDecimals(values.amount) > 3 ? 'Use only 3 digits of precison' :
                     null,
                 asset:
                     props.toVesting ? null :
diff --git a/app/utils/ParsersAndFormatters.js b/app/utils/ParsersAndFormatters.js
index 099674afe..3b43ba696 100644
--- a/app/utils/ParsersAndFormatters.js
+++ b/app/utils/ParsersAndFormatters.js
@@ -55,3 +55,10 @@ export const repLog10 = rep2 => {
     out = parseInt(out)
     return out
 }
+
+export function countDecimals(amount) {
+    if(amount == null) return amount
+    amount = String(amount).match(/[\d\.]+/g).join('') // just dots and digits
+    const parts = amount.split('.')
+    return parts.length > 2 ? undefined : parts.length === 1 ? 0 : parts[1].length
+}
\ No newline at end of file
diff --git a/shared/serializer/src/number_utils.js b/shared/serializer/src/number_utils.js
index 64c1db8e4..4520389de 100644
--- a/shared/serializer/src/number_utils.js
+++ b/shared/serializer/src/number_utils.js
@@ -2,35 +2,35 @@ import assert from "assert"
 
 /**
     Convert 12.34 with a precision of 3 into 12340
-    
+
     @arg {number|string} number - Use strings for large numbers.  This may contain one decimal but no sign
     @arg {number} precision - number of implied decimal places (usually causes right zero padding)
     @return {string} -
 */
 export function toImpliedDecimal(number, precision) {
-    
+
     if(typeof number === "number") {
         assert(number <= 9007199254740991, "overflow")
         number = ""+number;
     } else
         if( number.toString )
             number = number.toString()
-    
+
     assert(typeof number === "string", "number should be an actual number or string: " + (typeof number))
     number = number.trim()
     assert(/^[0-9]*\.?[0-9]*$/.test(number), "Invalid decimal number " + number)
-    
+
     let [ whole = "", decimal = ""] = number.split(".")
-    
+
     let padding = precision - decimal.length
     assert(padding >= 0, "Too many decimal digits in " + number + " to create an implied decimal of " + precision)
-    
+
     for(let i = 0; i < padding; i++)
         decimal += "0"
-        
+
     while(whole.charAt(0) === "0")
         whole = whole.substring(1)
-    
+
     return whole + decimal
 }
 
@@ -41,13 +41,13 @@ export function fromImpliedDecimal(number, precision) {
     } else
         if( number.toString )
             number = number.toString()
-    
+
     while(number.length < precision + 1)// 0.123
         number = "0" + number
-    
+
     // 44000 => 44.000
     let dec_string = number.substring(number.length - precision)
     return number.substring(0, number.length - precision) +
         (dec_string ? "." + dec_string : "")
-        
-}
\ No newline at end of file
+
+}
diff --git a/shared/serializer/src/types.js b/shared/serializer/src/types.js
index 206e4990a..f76bcea03 100644
--- a/shared/serializer/src/types.js
+++ b/shared/serializer/src/types.js
@@ -2,18 +2,15 @@
 
 // Low-level types that make up operations
 
-var ByteBuffer = require('bytebuffer');
-var Serializer = require('./serializer');
-var v = require('./validation');
-var ObjectId = require('./object_id')
-var fp = require('./fast_parser');
-var chain_types = require('./ChainTypes')
-var Long = ByteBuffer.Long
+const v = require('./validation');
+const ObjectId = require('./object_id')
+const fp = require('./fast_parser');
+const chain_types = require('./ChainTypes')
 
 import { PublicKey, Address, ecc_config } from "../../ecc"
-import { toImpliedDecimal, fromImpliedDecimal } from "./number_utils"
+import { fromImpliedDecimal } from "./number_utils"
 
-var Types = {}
+const Types = {}
 module.exports = Types
 
 const HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump
-- 
GitLab