Code Monkey home page Code Monkey logo

zmath's Introduction

zmath

Wrapper for exact-math purposed for use with Solidity!

Problem - Solution

The general idea here is that it can be preferable to avoid BigInt, BigNumber, and even the number datatype when working with or simulating smart contract code.

We would instead favor string representation for all numbers and mathematical operation. This results in less conversion code and a greater degree of human-readability and debug-ability while authoring and debugging our projects.
We like the simplicity and predictability afforded us by working with strings.

When we begin to work this way, we tend to discover a propensity to lean all the way in to it.

Zmath aims to be the perfect utility for leaning completely into string math dependency.

Tersity

To reduce cognitive load in our implementations, zmath's function names are short and shorthandy, and import individually rather than under a namespace.

Sanitization

Zmath internally applies a custom sanitizer to most operations which automatically handles basic type/format conversions, and prettifies and corrects values, within reason. This lends to a graceful DX that keeps us moving.

For example:

  • 0 becomes "0" (numbers and BigNumbers always convert to string)
  • ".0" becomes "0.0" (leading decimal prefixed with 0)
  • "0." becomes "0" (trailing decimal removed)
  • "00100.00100" becomes "100.001"
  • "11.22.33" throws an error
  • ,_$% characters are always removed

Error Reporting

Zmath has pretty good error reporting when it decides we've gone too far off the rails, and the solidity series of functions adds more checks and reporting on top.

Include

Zmath supports both CommonJS require() and ESM imports

import {
  sAdd,sSub,sMul,sDiv,sAddRay,_Add,_Sub,_Mul,_Div,_AddRay,_Chk,sSanitize,
  sRnd,sAbs,_Flr,sFlr,sPow,sFla,sExp,sHR,hrExp,sNewtonSqRt,sChg,sScaleToPcts,
  sIs,sIs0,sIsGT,sIsLT,sIsGTorEq,sIsLTorEq,sIsEq,sIsNotEq,
  k0,num,sEthToWei,first4,last4,surr4s,inTenMinutes,weiToUSD,usdToWei,
  sGetLR,abbrvNum,balToHrTuple,getAmountOut,adjustBrightness,
  sUint256max,sPpow2_128,sJsMaxSafeInt,
} from '@tdurica/zmath';

/* - OR - */

const {
  sAdd,sSub,sMul,sDiv,sAddRay,_Add,_Sub,_Mul,_Div,_AddRay,_Chk,sSanitize,
  sRnd,sAbs,_Flr,sFlr,sPow,sFla,sExp,sHR,hrExp,sNewtonSqRt,sChg,sScaleToPcts,
  sIs,sIs0,sIsGT,sIsLT,sIsGTorEq,sIsLTorEq,sIsEq,sIsNotEq,
  k0,num,sEthToWei,first4,last4,surr4s,inTenMinutes,weiToUSD,usdToWei,
  sGetLR,abbrvNum,balToHrTuple,getAmountOut,adjustBrightness,
  sUint256max,sPpow2_128,sJsMaxSafeInt,
} = require('@tdurica/zmath');

Usages

// useful constants
sUint256max; // "115792089237316195423570985008687907853269984665640564039457584007913129639935"
sPpow2_128; // "340282366920938463463374607431768211456" //TODO: doublecheck or explain var name
sJsMaxSafeInt; // "9007199254740991"

// general utilities
k0({ key: 'value' }); // "key" //TODO: rename, extend implementation
num('42'); // 42
sEthToWei('1.5'); // "1500000000000000000"
first4('123456789'); // "1234"
last4('123456789'); // "6789"
surr4s('1234567890'); // "1234...7890"
inTenMinutes(); // string epoch timestamp 10 minutes from Date.now()

// core series
sAdd('1.01', '1.02'); // "2.03"
sSub('5', '2'); // "3"
sMul('2.5', '1.5'); // "3.75"
sDiv('6', '2'); // "3"
sAddRay('1', '2', '3'); // "6"

// underscore series adds Solidity boundary checking & reporting
_Add('1.5', '2.3'); // "3.8"
_Sub('5', '2'); // "3"
_Mul('2.5', '1.5'); // "3.75"
_Div('6', '2'); // "3"
_AddRay('1', '2', '3'); // "6"
//_Chk - checks a number for solidity boundary violations
_Chk('12345.12345') // "12345.12345"
_Chk('-12345.12345') // throws math underflow warning
_Chk(sAdd(sUint256max,'1')) // throws math overflow warning

// eccentric series
sRnd('1.23456', -2); // "1.23" //TODO: expand explanation
sAbs('-7.89'); // "7.89"
sPow('2', '3'); // "8"
//sFla: "formula" same as exactMath.formula() with config matching rest of zmath
sFla('2e+3'); // "2000"
//sFlr: "floor" 
sFlr('1.23456', -3) // 
_Flr('1.23456') //1 (solidity 
//sExp (expand x by y^10) moves decimal left or right 
// TODO: perhaps rename to sDec
// "expand 10 negatively by 2 powers of 10" 
sExp('10', '-2'); // "0.1"
// "expand 10 positively by 2 powers of 10" 
sExp('10', '2'); // "1000"

// "hr" shorthand denotes "human readable" formatting
sHR('1234567890.123456'); // "1_234_567_890.1234"
sExpHR('1234567890.123456', 3); // "1_234_567_890.123"
sNewtonSqRt('25'); // "5"

// comparator series
sIs('5', '>', '3'); // true
sIs0('0'); // true
sIsGT('5', '3'); // true
sIsLT('2', '4'); // true
sIsGTorEq('5', '5'); // true
sIsLTorEq('3', '3'); // true
sIsEq('7', '7'); // true
sIsNotEq('6', '7'); // true

// change series - track change between values
sChg('10', '15'); // "-5"
sChg.ba('10', '15'); // { before: "10", after: "15", change: "5" }
sChg.hr('10', '15', 2); // "5.00"
sChg.pct('10', '15'); // "+50%"
sChg.pct('10', '5'); // "-50%"
sChg.bahr('10', '15', 2); // { before: "10.00 (10)", after: "15.00 (15)", change: "5.00 (5)", changePct: "+50%" }
sChg.full('10', '15', 2); // { before: "10.00 (10)", after: "15.00 (15)", change: "5.00 (5)", changePct: "+50%" }

// color utils
lightenDarkenColor('#00F', 10); // "#a0a190"
lightenDarkenColor('00F', 10); // "a0a190"

TODOs:

v1 patches

  • new utilities for BigNumber, BigInt, and Hex
  • existing function support for BigInt
  • add jsdoc and/or typescript for all functions
  • expand color operations support
  • support more uniswap router operations Eg. getAmountOut et al
  • support chaining of operations

for 2.0

  • rethink some naming conventions

zmath's People

Contributors

tdurica avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.