I am quite new to JavaScript and Uniswap. I am using Uniswap V3 to fetch the price from the DAI/USDC pool. My "main" function looks as follows:
async function main() {
const [immutables, state] = await Promise.all([
getPoolImmutables(),
getPoolState(),
]);
const DAI = new Token(1, immutables.token0, 18, "DAI", "Stablecoin");
const USDC = new Token(1, immutables.token1, 6, "USDC", "USD Coin");
const DAI_USDC_POOL = new Pool(
DAI,
USDC,
immutables.fee,
state.sqrtPriceX96.toString(),
state.liquidity.toString(),
state.tick
);
const token0Price = DAI_USDC_POOL.token0Price;
console.log("The price is: ", token0Price);
}
And I am getting the following output:
The price is: Price {
numerator: JSBI(6) [
435696740,
805184612,
508287463,
671994784,
427409972,
4,
sign: false
],
denominator: JSBI(7) [ 0, 0, 0, 0, 0, 0, 4096, sign: false ],
baseCurrency: Token {
chainId: 1,
decimals: 18,
symbol: 'DAI',
name: 'Stablecoin',
isNative: false,
isToken: true,
address: '0x6B175474E89094C44Da98b954EedeAC495271d0F'
},
quoteCurrency: Token {
chainId: 1,
decimals: 6,
symbol: 'USDC',
name: 'USD Coin',
isNative: false,
isToken: true,
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
},
scalar: Fraction {
numerator: JSBI(2) [ 660865024, 931322574, sign: false ],
denominator: JSBI(1) [ 1000000, sign: false ]
}
}
The USDC price seems to make some sense (denominator, 1000000), however I am not sure how to interpret the DAI price from the output. If anyone can provide any hints or point me to a resource that explains the output, I would highly appreciate it. Thanks!
JSBI stands for JavaScript BigInt:
a pure-JavaScript implementation of the ECMAScript BigInt proposal.
It's a large integer represented through an array. To see it's decimal form, use String(jsbi) or jsbi.toString(). For calculations you have to use methods of the module:
| Mathematical Operation | JSBI Operation |
|---|---|
| Addition | c = JSBI.add(a, b) |
| Subtraction | c = JSBI.subtract(a, b) |
| Multiplication | c = JSBI.multiply(a, b) |
| Division | c = JSBI.divide(a, b) |
Using the values of your example we can calculate
(async function asyncFnOnlyForAwait() {
const { default: JSBI } = await import ('https://cdn.skypack.dev/jsbi')
window.JSBI = JSBI;
window.priceJSBI = {
numerator: [435696740, 805184612, 508287463, 671994784, 427409972, 4,],
denominator: [0, 0, 0, 0, 0, 0, 4096, ],
scalarNumerator: [660865024, 931322574, ],
scalarDenominator: [1000000, ]
};
window.price = {};
// convert arrays to JSBI
for (const [prop, val] of Object.entries(priceJSBI))
priceJSBI[prop] = JSBI.from(val)
// calculate using JSBI methods
priceJSBI.value = JSBI.divide(priceJSBI.numerator, priceJSBI.denominator)
priceJSBI.scalarValue = JSBI.divide(priceJSBI.scalarNumerator, priceJSBI.scalarDenominator)
// convert JSBIs to numbers, losing precicion
for (const [prop, val] of Object.entries(priceJSBI))
price[prop] = JSBI.toNumber(val)
price.valueByNumbers = price.numerator / price.denominator
console.table(price)
document.write('<pre>price = '+JSON.stringify(price, null, 4))
}).call();
// In devtools console on this question, select the right iframe as scope to access these variables
// In Chromium browsers there's a dropdown for JS scopes next to the "console clear" button
It is odd that Uniswap ships JSBI on Desktop. It is actually meant as a fallback for older/mobile browsers and only complicates things. BigInts are supported on all major browsers and use normal arithemtic operators. JSBI should actually be transpiled away for environments with BigInts.