import { BigNumber as BN } from "ethers" ; import { ratioScale , DEFAULT_DECIMALS } from "./constants" ; export { BN } ; export const simpleToExactAmount = ( amount , decimals = DEFAULT_DECIMALS ) : BN => { let amountString = amount . toString ( ) ; const decimalsBN = BN . from ( decimals ) ; if ( decimalsBN . gt ( 100 ) ) { throw new Error ( `Invalid decimals amount` ) ; } const scale = BN . from ( 10 ) . pow ( decimals ) ; const scaleString = scale . toString ( ) ; const negative = amountString . substring ( 0 , 1 ) === "-" ; if ( negative ) { amountString = amountString . substring ( 1 ) ; } if ( amountString === "." ) { throw new Error ( `Error converting number ${ amountString } to precise unit, invalid value` ) ; } let [ whole , fraction , ... rest ] = amountString . split ( "." ) ; if ( rest . length > 0 ) { throw new Error ( `Error converting number ${ amountString } to precise unit, too many decimal points` ) ; } if ( ! whole ) { whole = "0" ; } if ( ! fraction ) { fraction = "0" ; } if ( fraction . length > scaleString . length - 1 ) { throw new Error ( `Error converting number ${ amountString } to precise unit, too many decimal places` ) ; } while ( fraction . length < scaleString . length - 1 ) { fraction += "0" ; } const wholeBN = BN . from ( whole ) ; const fractionBN = BN . from ( fraction ) ; let result = wholeBN . mul ( scale ) . add ( fractionBN ) ; if ( negative ) { result = result . mul ( "-1" ) ; } return result ; } ; export const applyDecimals = ( inputQuantity , decimals = DEFAULT_DECIMALS ) : BN => BN . from ( 10 ) . pow ( 18 - decimals ) . mul ( inputQuantity ) ; export const percentToWeight = ( percent ) : BN => simpleToExactAmount ( percent , 16 ) ; export const applyRatioMassetToBasset = ( input , ratio ) : BN => input . mul ( ratioScale ) . div ( ratio ) ; export const applyRatio = ( bAssetQ , ratio ) : BN => BN . from ( bAssetQ ) . mul ( ratio ) . div ( ratioScale ) ; export const applyRatioCeil = ( bAssetQ , ratio ) : BN => { const scaled = BN . from ( bAssetQ ) . mul ( ratio ) ; const ceil = BN . from ( scaled ) . add ( ratioScale . sub ( 1 ) ) ; return ceil . div ( ratioScale ) ; } ; export const createMultiple = ( decimals ) : BN => { const ratio = BN . from ( 10 ) . pow ( 18 - decimals ) ; return BN . from ( ratio ) . mul ( ratioScale ) ; } ; export const minimum = ( a , b ) : BN => ( a . lte ( b ) ? a : b ) ; export const maximum = ( a , b ) : BN => ( a . gte ( b ) ? a : b ) ; export const sqrt = ( value ) : BN => { const x = BN . from ( value ) ; let z = x . add ( 1 ) . div ( 2 ) ; let y = x ; while ( z . sub ( y ) . isNegative ( ) ) { y = z ; z = x . div ( z ) . add ( z ) . div ( 2 ) ; } return y ; } ; export const sum = ( a , b ) : BN => a . add ( b ) ;