Skip to content

Instantly share code, notes, and snippets.

@robstryker
Created August 30, 2021 18:31
Show Gist options
  • Save robstryker/53d8876dcf532d0f5db6a2980eea07a8 to your computer and use it in GitHub Desktop.
Save robstryker/53d8876dcf532d0f5db6a2980eea07a8 to your computer and use it in GitHub Desktop.
This will demonstrate that somehow, the off-by-half or 2x error is our fault, somewhere in our code.
This simulates an actual run from the wbtc-ust pair.
When using 18, 8, or 6 as the decimals, there's a very interesting relationship in the output.
I know this logic was copied from somewhere, and it's likely in use in several places.
const priceA = 3283.5;
const priceB = 1;
const numAInPairBN : any = BigNumber.from("41935433629656933949394");
const numBInPairBN : any = BigNumber.from("137139741167483");
const numAInPair : any = numAInPairBN / Math.pow(10, 18);
const numBInPair_3 = numBInPairBN / Math.pow(10, 18);
const numBInPair_2 = numBInPairBN / Math.pow(10, 8);
const numBInPair_1 = numBInPairBN / Math.pow(10, 6);
let reserveUSD3 = priceA * numAInPair + priceB * numBInPair_3;
let reserveUSD2 = priceA * numAInPair + priceB * numBInPair_2;
let reserveUSD1 = priceA * numAInPair + priceB * numBInPair_1;
const totalSupply = 1.7005415359817144;
const pricePerToken3 = reserveUSD3 / totalSupply;
const pricePerToken2 = reserveUSD2 / totalSupply;
const pricePerToken1 = reserveUSD1 / totalSupply;
console.log("ustInPair3: " + numBInPair_3 + ", reserveUSD3: " + reserveUSD3 + ", pricePerToken3: " + pricePerToken3);
console.log("ustInPair2: " + numBInPair_2 + ", reserveUSD2: " + reserveUSD2 + ", pricePerToken2: " + pricePerToken2);
console.log("ustInPair1: " + numBInPair_1 + ", reserveUSD1: " + reserveUSD1 + ", pricePerToken1: " + pricePerToken1);
The output of this is:
ustInPair3: 0.000137139741167483, reserveUSD3: 137694996.32311568, pricePerToken3: 80971263.21799898
ustInPair2: 1371397.41167483, reserveUSD2: 139066393.73465335, pricePerToken2: 81777710.68342121
ustInPair1: 137139741.167483, reserveUSD1: 274834737.4904615, pricePerToken1: 161616009.76820642
You can see that despite the ustInPair versions being wildly far apart from each other
(factor of 10^2 through 10^10 difference), the reserveUSD calculations show almost exactly half,
as do the pricePerToken calculations.
What this means is, if some logic has forgotten to use the correct decimals
(say, using 18 or 8 when 6 is most appropriate, or, using 6 when 8 or 18 would be appropriate),
the result will be half or double of the intended value.
The cause is likely numBInPairBN / Math.pow(10, 18); , or, doing math directly against a bignumber.
pickle-api/service/index/handler.js seems to do this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment