Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
swap-v2-sdk
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
swap-v2-sdk
Commits
3249027e
Unverified
Commit
3249027e
authored
Jun 03, 2019
by
Noah Zinsmeister
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
address edge cases around decimals and rounding
parent
a56aa056
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
120 additions
and
68 deletions
+120
-68
computation.ts
src/__tests__/computation.ts
+8
-23
computation.ts
src/computation.ts
+44
-11
index.ts
src/constants/index.ts
+1
-2
data.ts
src/data.ts
+3
-3
format.ts
src/format.ts
+56
-27
index.ts
src/index.ts
+6
-2
index.ts
src/types/index.ts
+2
-0
No files found.
src/__tests__/computation.ts
View file @
3249027e
...
@@ -36,18 +36,13 @@ function testMarketRates(
...
@@ -36,18 +36,13 @@ function testMarketRates(
})
})
describe
(
'
manually inverted
'
,
():
void
=>
{
describe
(
'
manually inverted
'
,
():
void
=>
{
const
tradeTypeInverted
=
const
tradeTypeInverted
=
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
TRADE_TYPE
.
TOKEN_TO_ETH
:
TRADE_TYPE
.
ETH_TO_TOKEN
tradeType
===
TRADE_TYPE
.
TOKEN_TO_TOKEN
?
TRADE_TYPE
.
TOKEN_TO_TOKEN
:
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
TRADE_TYPE
.
TOKEN_TO_ETH
:
TRADE_TYPE
.
ETH_TO_TOKEN
test
(
'
not inverted
'
,
():
void
=>
{
test
(
'
not inverted
'
,
():
void
=>
{
const
manuallyInvertedMarketRate
:
BigNumber
=
getMarketRate
(
const
manuallyInvertedMarketRate
:
BigNumber
=
getMarketRate
(
outputTokenReserves
,
outputTokenReserves
,
inputTokenReserves
,
inputTokenReserves
,
tradeTypeInverted
,
tradeType
===
TRADE_TYPE
.
TOKEN_TO_TOKEN
?
TRADE_TYPE
.
TOKEN_TO_TOKEN
:
tradeType
Inverted
,
false
false
)
)
...
@@ -58,7 +53,7 @@ function testMarketRates(
...
@@ -58,7 +53,7 @@ function testMarketRates(
const
manuallyInvertedInvertedMarketRate
:
BigNumber
=
getMarketRate
(
const
manuallyInvertedInvertedMarketRate
:
BigNumber
=
getMarketRate
(
outputTokenReserves
,
outputTokenReserves
,
inputTokenReserves
,
inputTokenReserves
,
tradeTypeInverted
,
tradeType
===
TRADE_TYPE
.
TOKEN_TO_TOKEN
?
TRADE_TYPE
.
TOKEN_TO_TOKEN
:
tradeType
Inverted
,
true
true
)
)
...
@@ -74,11 +69,10 @@ describe('getMarketRate', (): void => {
...
@@ -74,11 +69,10 @@ describe('getMarketRate', (): void => {
'
4039700561005906883487
'
,
'
4039700561005906883487
'
,
'
1094055210563660633471343
'
'
1094055210563660633471343
'
)
)
const
expectedMarketRate
=
'
0.003692410147130181
'
const
expectedMarketRate
=
'
270.825818409480102284
'
const
expectedMarketRateInverted
=
'
270.825818409480102284
'
const
expectedMarketRateInverted
=
'
0.003692410147130181
'
testMarketRates
(
null
,
tokenReserves
,
TRADE_TYPE
.
ETH_TO_TOKEN
,
expectedMarketRate
,
expectedMarketRateInverted
)
testMarketRates
(
null
,
tokenReserves
,
TRADE_TYPE
.
ETH_TO_TOKEN
,
expectedMarketRate
,
expectedMarketRateInverted
)
testMarketRates
(
tokenReserves
,
null
,
TRADE_TYPE
.
TOKEN_TO_ETH
,
expectedMarketRateInverted
,
expectedMarketRate
)
})
})
describe
(
'
dummy ETH/USDC and USDC/ETH
'
,
():
void
=>
{
describe
(
'
dummy ETH/USDC and USDC/ETH
'
,
():
void
=>
{
...
@@ -86,8 +80,7 @@ describe('getMarketRate', (): void => {
...
@@ -86,8 +80,7 @@ describe('getMarketRate', (): void => {
const
expectedMarketRate
=
'
0.003678674143683891
'
const
expectedMarketRate
=
'
0.003678674143683891
'
const
expectedMarketRateInverted
=
'
271.837069808684359442
'
const
expectedMarketRateInverted
=
'
271.837069808684359442
'
testMarketRates
(
null
,
tokenReserves
,
TRADE_TYPE
.
ETH_TO_TOKEN
,
expectedMarketRate
,
expectedMarketRateInverted
)
testMarketRates
(
tokenReserves
,
null
,
TRADE_TYPE
.
TOKEN_TO_ETH
,
expectedMarketRate
,
expectedMarketRateInverted
)
testMarketRates
(
tokenReserves
,
null
,
TRADE_TYPE
.
TOKEN_TO_ETH
,
expectedMarketRateInverted
,
expectedMarketRate
)
})
})
describe
(
'
dummy DAI/USDC and USDC/DAI
'
,
():
void
=>
{
describe
(
'
dummy DAI/USDC and USDC/DAI
'
,
():
void
=>
{
...
@@ -97,8 +90,8 @@ describe('getMarketRate', (): void => {
...
@@ -97,8 +90,8 @@ describe('getMarketRate', (): void => {
'
1094055210563660633471343
'
'
1094055210563660633471343
'
)
)
const
USDCTokenReserves
:
TokenReserves
=
constructTokenReserves
(
6
,
'
1076592291503763426634
'
,
'
292657693901
'
)
const
USDCTokenReserves
:
TokenReserves
=
constructTokenReserves
(
6
,
'
1076592291503763426634
'
,
'
292657693901
'
)
const
expectedMarketRate
=
'
0.996279935624983178
'
const
expectedMarketRate
=
'
1.003733954927721392
'
const
expectedMarketRateInverted
=
'
1.003733954927721499
'
const
expectedMarketRateInverted
=
'
0.996279935624983143
'
testMarketRates
(
testMarketRates
(
DAITokenReserves
,
DAITokenReserves
,
...
@@ -107,13 +100,5 @@ describe('getMarketRate', (): void => {
...
@@ -107,13 +100,5 @@ describe('getMarketRate', (): void => {
expectedMarketRate
,
expectedMarketRate
,
expectedMarketRateInverted
expectedMarketRateInverted
)
)
testMarketRates
(
USDCTokenReserves
,
DAITokenReserves
,
TRADE_TYPE
.
TOKEN_TO_TOKEN
,
expectedMarketRateInverted
,
expectedMarketRate
)
})
})
})
})
src/computation.ts
View file @
3249027e
...
@@ -37,14 +37,19 @@ export function getOutputPrice(outputAmount: BigNumber, inputReserve: BigNumber,
...
@@ -37,14 +37,19 @@ export function getOutputPrice(outputAmount: BigNumber, inputReserve: BigNumber,
return
inputAmount
return
inputAmount
}
}
function
_getMarketRate
(
tokenReserves
:
TokenReservesOptional
,
tradeType
:
TRADE_TYPE
,
invert
:
boolean
):
BigNumber
{
// returns [numerator, decimal scalar, denominator]
function
getRawMarketRate
(
tokenReserves
:
TokenReservesOptional
,
tradeType
:
TRADE_TYPE
,
invert
:
boolean
):
[
BigNumber
,
BigNumber
,
BigNumber
]
{
if
(
tokenReserves
===
null
)
{
if
(
tokenReserves
===
null
)
{
throw
Error
(
'
outputTokenReserves must be non-null.
'
)
throw
Error
(
'
outputTokenReserves must be non-null.
'
)
}
else
{
}
else
{
const
numerator
:
TokenAmount
=
const
numerator
:
TokenAmount
=
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
tokenReserves
.
ethReserve
:
tokenReserves
.
tokenReserve
const
denominator
:
TokenAmount
=
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
tokenReserves
.
tokenReserve
:
tokenReserves
.
ethReserve
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
tokenReserves
.
tokenReserve
:
tokenReserves
.
ethReserve
const
denominator
:
TokenAmount
=
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
tokenReserves
.
ethReserve
:
tokenReserves
.
tokenReserve
const
numeratorAmount
:
BigNumber
=
normalizeBigNumberish
(
numerator
.
amount
)
const
numeratorAmount
:
BigNumber
=
normalizeBigNumberish
(
numerator
.
amount
)
const
denominatorAmount
:
BigNumber
=
normalizeBigNumberish
(
denominator
.
amount
)
const
denominatorAmount
:
BigNumber
=
normalizeBigNumberish
(
denominator
.
amount
)
...
@@ -55,15 +60,29 @@ function _getMarketRate(tokenReserves: TokenReservesOptional, tradeType: TRADE_T
...
@@ -55,15 +60,29 @@ function _getMarketRate(tokenReserves: TokenReservesOptional, tradeType: TRADE_T
ensureAllUInt8
([
numeratorDecimals
,
denominatorDecimals
])
ensureAllUInt8
([
numeratorDecimals
,
denominatorDecimals
])
if
(
!
invert
)
{
if
(
!
invert
)
{
const
decimalScalar
=
_10
.
exponentiatedBy
(
denominatorDecimals
-
numeratorDecimals
)
const
decimalScalar
:
BigNumber
=
_10
.
exponentiatedBy
(
denominatorDecimals
-
numeratorDecimals
)
return
numeratorAmount
.
multipliedBy
(
decimalScalar
).
div
(
denominatorAmount
)
return
[
numeratorAmount
,
decimalScalar
,
denominatorAmount
]
}
else
{
}
else
{
const
decimalScalar
=
_10
.
exponentiatedBy
(
numeratorDecimals
-
denominatorDecimals
)
const
decimalScalar
:
BigNumber
=
_10
.
exponentiatedBy
(
numeratorDecimals
-
denominatorDecimals
)
return
denominatorAmount
.
multipliedBy
(
decimalScalar
).
div
(
numeratorAmount
)
return
[
denominatorAmount
,
decimalScalar
,
numeratorAmount
]
}
}
}
}
}
}
function
getRawMarketRateOneSided
(
tokenReserves
:
TokenReservesOptional
,
tradeType
:
TRADE_TYPE
,
invert
:
boolean
):
BigNumber
{
const
[
numerator
,
decimalScalar
,
denominator
]:
[
BigNumber
,
BigNumber
,
BigNumber
]
=
getRawMarketRate
(
tokenReserves
,
tradeType
,
invert
)
return
numerator
.
multipliedBy
(
decimalScalar
).
dividedBy
(
denominator
)
}
// rounds output rates to 18 decimal places
export
function
getMarketRate
(
export
function
getMarketRate
(
inputTokenReserves
:
TokenReservesOptional
,
inputTokenReserves
:
TokenReservesOptional
,
outputTokenReserves
:
TokenReservesOptional
,
outputTokenReserves
:
TokenReservesOptional
,
...
@@ -74,12 +93,26 @@ export function getMarketRate(
...
@@ -74,12 +93,26 @@ export function getMarketRate(
if
(
inputTokenReserves
===
null
||
outputTokenReserves
===
null
)
{
if
(
inputTokenReserves
===
null
||
outputTokenReserves
===
null
)
{
throw
Error
(
'
Both inputTokenReserves and outputTokenReserves must be non-null.
'
)
throw
Error
(
'
Both inputTokenReserves and outputTokenReserves must be non-null.
'
)
}
else
{
}
else
{
const
inputMarketRate
:
BigNumber
=
_getMarketRate
(
inputTokenReserves
,
TRADE_TYPE
.
TOKEN_TO_ETH
,
invert
)
const
[
inputNumerator
,
inputDecimalScalar
,
inputDenominator
]:
[
const
outputMarketRate
:
BigNumber
=
_getMarketRate
(
outputTokenReserves
,
TRADE_TYPE
.
ETH_TO_TOKEN
,
invert
)
BigNumber
,
return
inputMarketRate
.
multipliedBy
(
outputMarketRate
)
BigNumber
,
BigNumber
]
=
getRawMarketRate
(
inputTokenReserves
,
TRADE_TYPE
.
TOKEN_TO_ETH
,
invert
)
const
[
outputNumerator
,
outputDecimalScalar
,
outputDenominator
]:
[
BigNumber
,
BigNumber
,
BigNumber
]
=
getRawMarketRate
(
outputTokenReserves
,
TRADE_TYPE
.
ETH_TO_TOKEN
,
invert
)
return
inputNumerator
.
multipliedBy
(
inputDecimalScalar
)
.
multipliedBy
(
outputNumerator
)
.
multipliedBy
(
outputDecimalScalar
)
.
dividedBy
(
inputDenominator
.
multipliedBy
(
outputDenominator
))
}
}
}
else
{
}
else
{
return
_getMarketRate
(
return
getRawMarketRateOneSided
(
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
outputTokenReserves
:
inputTokenReserves
,
tradeType
===
TRADE_TYPE
.
ETH_TO_TOKEN
?
outputTokenReserves
:
inputTokenReserves
,
tradeType
,
tradeType
,
invert
invert
...
...
src/constants/index.ts
View file @
3249027e
...
@@ -34,8 +34,7 @@ export enum TRADE_EXACT {
...
@@ -34,8 +34,7 @@ export enum TRADE_EXACT {
export
enum
FIXED_UNDERFLOW_BEHAVIOR
{
export
enum
FIXED_UNDERFLOW_BEHAVIOR
{
ZERO
=
'
ZERO
'
,
ZERO
=
'
ZERO
'
,
LESS_THAN
=
'
LESS_THAN
'
,
LESS_THAN
=
'
LESS_THAN
'
,
ONE_DIGIT
=
'
ONE_DIGIT
'
,
ONE_DIGIT
=
'
ONE_DIGIT
'
MAX_DECIMAL_PLACES
=
'
MAX_DECIMAL_PLACES
'
}
}
//// constants for internal use
//// constants for internal use
...
...
src/data.ts
View file @
3249027e
...
@@ -2,7 +2,7 @@ import { ethers } from 'ethers'
...
@@ -2,7 +2,7 @@ import { ethers } from 'ethers'
import
{
ETH
,
CHAIN_ID_NAME
,
ERC20_ABI
,
FACTORY_ADDRESS
,
FACTORY_ABI
}
from
'
./constants
'
import
{
ETH
,
CHAIN_ID_NAME
,
ERC20_ABI
,
FACTORY_ADDRESS
,
FACTORY_ABI
}
from
'
./constants
'
import
{
ChainIdOrProvider
,
ChainIdAndProvider
,
Token
,
TokenReserves
}
from
'
./types
'
import
{
ChainIdOrProvider
,
ChainIdAndProvider
,
Token
,
TokenReserves
}
from
'
./types
'
import
{
normalizeAddress
}
from
'
./utils
'
import
{
normalizeAddress
,
normalizeBigNumberish
}
from
'
./utils
'
// abstraction to get contracts
// abstraction to get contracts
function
_getContract
(
address
:
string
,
ABI
:
string
,
provider
:
ethers
.
providers
.
BaseProvider
):
ethers
.
Contract
{
function
_getContract
(
address
:
string
,
ABI
:
string
,
provider
:
ethers
.
providers
.
BaseProvider
):
ethers
.
Contract
{
...
@@ -80,8 +80,8 @@ export async function getTokenReserves(
...
@@ -80,8 +80,8 @@ export async function getTokenReserves(
ethers
.
utils
.
BigNumber
ethers
.
utils
.
BigNumber
]
=
await
Promise
.
all
([
ethTokenPromise
,
tokenPromise
,
exchangeTokenPromise
,
ethBalancePromise
,
tokenBalancePromise
])
]
=
await
Promise
.
all
([
ethTokenPromise
,
tokenPromise
,
exchangeTokenPromise
,
ethBalancePromise
,
tokenBalancePromise
])
const
ethReserve
=
{
token
:
ethToken
,
amount
:
ethBalance
}
const
ethReserve
=
{
token
:
ethToken
,
amount
:
normalizeBigNumberish
(
ethBalance
)
}
const
tokenReserve
=
{
token
,
amount
:
tokenBalance
}
const
tokenReserve
=
{
token
,
amount
:
normalizeBigNumberish
(
tokenBalance
)
}
return
{
token
,
exchange
:
exchangeToken
,
ethReserve
,
tokenReserve
}
return
{
token
,
exchange
:
exchangeToken
,
ethReserve
,
tokenReserve
}
}
}
src/format.ts
View file @
3249027e
import
BigNumber
from
'
bignumber.js
'
import
BigNumber
from
'
bignumber.js
'
import
{
MAX_DECIMAL_PLACES
,
ROUNDING_MODE
,
FIXED_UNDERFLOW_BEHAVIOR
,
_0
}
from
'
./constants
'
import
{
MAX_DECIMAL_PLACES
,
ROUNDING_MODE
,
FIXED_UNDERFLOW_BEHAVIOR
,
_0
,
_10
}
from
'
./constants
'
import
{
BigNumberish
,
FlexibleFormat
,
FormatSignificantOptions
,
FormatFixedOptions
}
from
'
./types
'
import
{
BigNumberish
,
FlexibleFormat
,
FormatSignificantOptions
,
FormatFixedOptions
}
from
'
./types
'
import
{
normalizeBigNumberish
,
ensureBoundedInteger
}
from
'
./utils
'
import
{
normalizeBigNumberish
,
ensureBoundedInteger
,
ensureAllUInt256
,
ensureAllUInt8
}
from
'
./utils
'
function
_format
(
bigNumber
:
BigNumber
,
format
:
FlexibleFormat
,
decimalPlaces
:
number
):
string
{
function
_format
(
bigNumber
:
BigNumber
,
decimalPlaces
:
number
,
roundingMode
:
BigNumber
.
RoundingMode
=
ROUNDING_MODE
,
format
:
FlexibleFormat
):
string
{
return
typeof
format
===
'
boolean
'
&&
format
===
false
return
typeof
format
===
'
boolean
'
&&
format
===
false
?
bigNumber
.
toFixed
(
decimalPlaces
)
?
bigNumber
.
toFixed
(
decimalPlaces
,
roundingMode
)
:
bigNumber
.
toFormat
(
:
bigNumber
.
toFormat
(
decimalPlaces
,
decimalPlaces
,
ROUNDING_MODE
,
roundingMode
,
typeof
format
===
'
boolean
'
&&
format
===
true
?
undefined
:
format
typeof
format
===
'
boolean
'
&&
format
===
true
?
undefined
:
format
)
)
}
}
// bignumberish is converted to significantDigits, then cast back as a bignumber and formatted, dropping trailing 0s
// bignumberish is converted to significantDigits, then cast back as a bignumber and formatted, dropping trailing 0s
export
function
formatSignificant
(
export
function
formatSignificant
(
bigNumberish
:
BigNumberish
,
options
?:
FormatSignificantOptions
):
string
{
bigNumberish
:
BigNumberish
,
const
{
significantDigits
=
6
,
forceIntegerSignificance
=
true
,
roundingMode
=
ROUNDING_MODE
,
format
=
false
}
=
{
significantDigits
=
6
,
forceIntegerSignificance
=
false
,
format
=
false
}:
FormatSignificantOptions
options
||
{}
):
string
{
const
bigNumber
:
BigNumber
=
normalizeBigNumberish
(
bigNumberish
)
const
bigNumber
:
BigNumber
=
normalizeBigNumberish
(
bigNumberish
)
ensureBoundedInteger
(
significantDigits
,
[
1
,
MAX_DECIMAL_PLACES
])
ensureBoundedInteger
(
significantDigits
,
[
1
,
MAX_DECIMAL_PLACES
])
...
@@ -27,38 +32,33 @@ export function formatSignificant(
...
@@ -27,38 +32,33 @@ export function formatSignificant(
bigNumber
.
toPrecision
(
Math
.
max
(
minimumSignificantDigits
,
significantDigits
))
bigNumber
.
toPrecision
(
Math
.
max
(
minimumSignificantDigits
,
significantDigits
))
)
)
return
_format
(
preciseBigNumber
,
format
,
preciseBigNumber
.
decimalPlaces
()
)
return
_format
(
preciseBigNumber
,
preciseBigNumber
.
decimalPlaces
(),
roundingMode
,
format
)
}
}
export
function
formatFixed
(
export
function
formatFixed
(
bigNumberish
:
BigNumberish
,
options
?:
FormatFixedOptions
):
string
{
bigNumberish
:
BigNumberish
,
const
{
{
decimalPlaces
=
4
,
decimalPlaces
=
4
,
roundingMode
=
ROUNDING_MODE
,
dropTrailingZeros
=
true
,
dropTrailingZeros
=
true
,
format
=
false
,
underflowBehavior
=
FIXED_UNDERFLOW_BEHAVIOR
.
ONE_DIGIT
,
underflowBehavior
=
FIXED_UNDERFLOW_BEHAVIOR
.
ONE_DIGIT
format
=
false
}
:
FormatFixedOptions
}
=
options
||
{}
):
string
{
const
bigNumber
:
BigNumber
=
normalizeBigNumberish
(
bigNumberish
)
const
bigNumber
:
BigNumber
=
normalizeBigNumberish
(
bigNumberish
)
ensureBoundedInteger
(
decimalPlaces
,
MAX_DECIMAL_PLACES
)
ensureBoundedInteger
(
decimalPlaces
,
MAX_DECIMAL_PLACES
)
// this works because we've specified the rounding mode
const
minimumNonZeroValue
:
BigNumber
=
new
BigNumber
(
decimalPlaces
===
0
?
'
0.5
'
:
`0.
${
'
0
'
.
repeat
(
decimalPlaces
)}
5`
)
const
minimumNonZeroValue
:
BigNumber
=
new
BigNumber
(
decimalPlaces
===
0
?
'
0.5
'
:
`0.
${
'
0
'
.
repeat
(
decimalPlaces
)}
5`
)
if
(
bigNumber
.
isLessThan
(
minimumNonZeroValue
))
{
if
(
bigNumber
.
isLessThan
(
minimumNonZeroValue
))
{
switch
(
underflowBehavior
)
{
switch
(
underflowBehavior
)
{
case
FIXED_UNDERFLOW_BEHAVIOR
.
ZERO
:
{
case
FIXED_UNDERFLOW_BEHAVIOR
.
ZERO
:
{
return
_format
(
_0
,
format
,
dropTrailingZeros
?
0
:
decimalPlaces
)
return
_format
(
_0
,
dropTrailingZeros
?
0
:
decimalPlaces
,
undefined
,
format
)
}
}
case
FIXED_UNDERFLOW_BEHAVIOR
.
LESS_THAN
:
{
case
FIXED_UNDERFLOW_BEHAVIOR
.
LESS_THAN
:
{
return
`<
${
_format
(
minimumNonZeroValue
,
format
,
minimumNonZeroValue
.
decimalPlaces
()
)}
`
return
`<
${
_format
(
minimumNonZeroValue
,
minimumNonZeroValue
.
decimalPlaces
(),
undefined
,
format
)}
`
}
}
case
FIXED_UNDERFLOW_BEHAVIOR
.
ONE_DIGIT
:
{
case
FIXED_UNDERFLOW_BEHAVIOR
.
ONE_DIGIT
:
{
const
newBigNumber
=
new
BigNumber
(
bigNumber
.
toPrecision
(
1
))
const
newBigNumber
=
new
BigNumber
(
bigNumber
.
toPrecision
(
1
))
return
_format
(
newBigNumber
,
format
,
newBigNumber
.
decimalPlaces
())
return
_format
(
newBigNumber
,
newBigNumber
.
decimalPlaces
(),
undefined
,
format
)
}
case
FIXED_UNDERFLOW_BEHAVIOR
.
MAX_DECIMAL_PLACES
:
{
const
newBigNumber
=
new
BigNumber
(
bigNumber
.
toFixed
(
MAX_DECIMAL_PLACES
))
return
_format
(
newBigNumber
,
format
,
dropTrailingZeros
?
newBigNumber
.
decimalPlaces
()
:
MAX_DECIMAL_PLACES
)
}
}
default
:
{
default
:
{
throw
Error
(
`Passed FIXED_UNDERFLOW_BEHAVIOR
${
underflowBehavior
}
is not valid.`
)
throw
Error
(
`Passed FIXED_UNDERFLOW_BEHAVIOR
${
underflowBehavior
}
is not valid.`
)
...
@@ -66,9 +66,38 @@ export function formatFixed(
...
@@ -66,9 +66,38 @@ export function formatFixed(
}
}
}
else
{
}
else
{
const
newDecimalPlaces
=
dropTrailingZeros
const
newDecimalPlaces
=
dropTrailingZeros
?
new
BigNumber
(
bigNumber
.
toFixed
(
decimalPlaces
)).
decimalPlaces
()
?
new
BigNumber
(
bigNumber
.
toFixed
(
decimalPlaces
,
roundingMode
)).
decimalPlaces
()
:
decimalPlaces
:
decimalPlaces
return
_format
(
bigNumber
,
format
,
newDecimalPlaces
)
return
_format
(
bigNumber
,
newDecimalPlaces
,
roundingMode
,
format
)
}
}
}
}
function
decimalize
(
bigNumberish
:
BigNumberish
,
decimals
:
number
):
BigNumber
{
const
bigNumber
:
BigNumber
=
normalizeBigNumberish
(
bigNumberish
)
ensureAllUInt256
([
bigNumber
])
ensureAllUInt8
([
decimals
])
if
(
decimals
>
MAX_DECIMAL_PLACES
)
{
throw
Error
(
`This function does not support decimals greater than
${
MAX_DECIMAL_PLACES
}
.`
)
}
return
bigNumber
.
dividedBy
(
_10
.
exponentiatedBy
(
decimals
))
}
export
function
formatSignificantDecimals
(
bigNumberish
:
BigNumberish
,
decimals
:
number
,
options
?:
FormatSignificantOptions
):
string
{
return
formatSignificant
(
decimalize
(
bigNumberish
,
decimals
),
options
)
}
export
function
formatFixedDecimals
(
bigNumberish
:
BigNumberish
,
decimals
:
number
,
options
?:
FormatFixedOptions
):
string
{
return
formatFixed
(
decimalize
(
bigNumberish
,
decimals
),
options
)
}
src/index.ts
View file @
3249027e
export
*
from
'
./data
'
import
BigNumber
from
'
bignumber.js
'
export
*
from
'
./computation
'
export
{
BigNumber
}
export
{
export
{
ETH
,
ETH
,
...
@@ -9,3 +9,7 @@ export {
...
@@ -9,3 +9,7 @@ export {
TRADE_EXACT
,
TRADE_EXACT
,
FIXED_UNDERFLOW_BEHAVIOR
FIXED_UNDERFLOW_BEHAVIOR
}
from
'
./constants
'
}
from
'
./constants
'
export
*
from
'
./data
'
export
*
from
'
./computation
'
export
*
from
'
./format
'
src/types/index.ts
View file @
3249027e
...
@@ -46,11 +46,13 @@ export type FlexibleFormat = boolean | BigNumber.Format
...
@@ -46,11 +46,13 @@ export type FlexibleFormat = boolean | BigNumber.Format
export
interface
FormatSignificantOptions
{
export
interface
FormatSignificantOptions
{
significantDigits
:
number
significantDigits
:
number
roundingMode
:
BigNumber
.
RoundingMode
forceIntegerSignificance
:
boolean
forceIntegerSignificance
:
boolean
format
:
FlexibleFormat
format
:
FlexibleFormat
}
}
export
interface
FormatFixedOptions
{
export
interface
FormatFixedOptions
{
decimalPlaces
:
number
decimalPlaces
:
number
roundingMode
:
BigNumber
.
RoundingMode
dropTrailingZeros
:
boolean
dropTrailingZeros
:
boolean
underflowBehavior
:
FIXED_UNDERFLOW_BEHAVIOR
underflowBehavior
:
FIXED_UNDERFLOW_BEHAVIOR
format
:
FlexibleFormat
format
:
FlexibleFormat
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment