Skip to content
This repository has been archived by the owner on Aug 15, 2023. It is now read-only.

Commit

Permalink
Fix zero usd price service exception (#102)
Browse files Browse the repository at this point in the history
* fix: remove thrown exception in validation
* test: update to cover amount down to 0 sats & cents
Co-authored-by: Sebastien Verreault <sebver@pm.me>
  • Loading branch information
sebastienverreault authored May 24, 2022
1 parent 65fb314 commit e22cad5
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 9 deletions.
104 changes: 104 additions & 0 deletions dealer/src/servers/price/sample_client_test_02.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { baseLogger } from "../../services/logger"
import { toCents, toSats } from "../../utils"
import { DealerPriceService } from "./client_service"
import { DealerPriceServiceError } from "./errors"

const priceService = DealerPriceService()
const fewMins = (2 * 60) as Seconds
export const run = async function () {
for (let sats = 100; sats >= 0; sats--) {
const someSats = toSats(sats)
const result = await priceService.getCentsFromSatsForImmediateBuy(someSats)
baseLogger.info(
{ someSats, result },
`GetCentsFromSatsForImmediateBuy({someSats}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let sats = 100; sats >= 0; sats--) {
const someSats = toSats(sats)
const result = await priceService.getCentsFromSatsForImmediateSell(someSats)
baseLogger.info(
{ someSats, result },
`GetCentsFromSatsForImmediateSell({someSats}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let sats = 100; sats >= 0; sats--) {
const someSats = toSats(sats)
const result = await priceService.getCentsFromSatsForFutureBuy(someSats, fewMins)
baseLogger.info(
{ someSats, fewMins, result },
`GetCentsFromSatsForFutureBuy({someSats}, {fewMins}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let sats = 100; sats >= 0; sats--) {
const someSats = toSats(sats)
const result = await priceService.getCentsFromSatsForFutureSell(someSats, fewMins)
baseLogger.info(
{ someSats, fewMins, result },
`getCentsFromSatsForFutureSell({someSats}, {fewMins}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}

for (let cents = 100; cents >= 0; cents--) {
const someUsd = toCents(cents)
const result = await priceService.getSatsFromCentsForImmediateBuy(someUsd)
baseLogger.info(
{ someUsd, result },
`getSatsFromCentsForImmediateBuy({someUsd}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let cents = 100; cents >= 0; cents--) {
const someUsd = toCents(cents)
const result = await priceService.getSatsFromCentsForImmediateSell(someUsd)
baseLogger.info(
{ someUsd, result },
`getSatsFromCentsForImmediateSell({someUsd}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let cents = 100; cents >= 0; cents--) {
const someUsd = toCents(cents)
const result = await priceService.getSatsFromCentsForFutureBuy(someUsd, fewMins)
baseLogger.info(
{ someUsd, fewMins, result },
`getSatsFromCentsForFutureBuy({someUsd}, {fewMins}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}
for (let cents = 100; cents >= 0; cents--) {
const someUsd = toCents(cents)
const result = await priceService.getSatsFromCentsForFutureSell(someUsd, fewMins)
baseLogger.info(
{ someUsd, fewMins, result },
`getSatsFromCentsForFutureSell({someUsd}, {fewMins}) returned: {result}`,
)
if (result instanceof DealerPriceServiceError) {
break
}
}

baseLogger.info(
`getCentsPerSatsExchangeMidRate from service: ${await priceService.getCentsPerSatsExchangeMidRate()}`,
)
}

run()
4 changes: 0 additions & 4 deletions dealer/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export const sat2btc = (sat: number) => {
}

export const toSats = (amount: number): Satoshis => {
// TODO: safety protection during dev. remove before prod (should not throw)
if (!(amount && amount > 0)) throw new Error("Invalid Sats Amount")
if (!Number.isInteger(amount))
throw new Error(`${amount} type ${typeof amount} is not an integer`)
return amount as Satoshis
Expand All @@ -39,8 +37,6 @@ export const cents2usd = (cents: UsdCents | number): number => {
}

export const toCents = (amount: number): UsdCents => {
// TODO: safety protection during dev. remove before prod (should not throw)
if (!(amount && amount > 0)) throw new Error("Invalid UsdCents Amount")
if (!Number.isInteger(amount))
throw new Error(`${amount} type ${typeof amount} is not an integer`)
return amount as UsdCents
Expand Down
141 changes: 136 additions & 5 deletions dealer/test/integration/DealerPriceService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
cents2usd,
sat2btc,
SATS_PER_BTC,
toCents,
toCentsPerSatsRatio,
toSats,
toSeconds,
Expand Down Expand Up @@ -31,13 +30,28 @@ describe("DealerPriceService", () => {
const maxExpectedAmountInCents = usd2cents(lastBidInUsdPerBtc * amountInBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const minExpectedAmountInCents = maxExpectedAmountInCents * feeRate
const minExpectedAmountInCents = Math.floor(maxExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForImmediateBuy(amountInSats)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThan(minExpectedAmountInCents)
})
it("should return amount down to zero sats & cents", async () => {
for (let sats = 100; sats >= 0; sats--) {
const amountInSats = toSats(sats)
const amountInBtc = sat2btc(amountInSats)
const maxExpectedAmountInCents = usd2cents(lastBidInUsdPerBtc * amountInBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const minExpectedAmountInCents = Math.floor(maxExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForImmediateBuy(amountInSats)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThanOrEqual(minExpectedAmountInCents)
}
})
})
describe("getCentsFromSatsForImmediateSell", () => {
it("should return amount within range", async () => {
Expand All @@ -46,13 +60,28 @@ describe("DealerPriceService", () => {
const minExpectedAmountInCents = usd2cents(lastAskInUsdPerBtc * amountInBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const maxExpectedAmountInCents = minExpectedAmountInCents * feeRate
const maxExpectedAmountInCents = Math.ceil(minExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForImmediateSell(amountInSats)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThan(minExpectedAmountInCents)
})
it("should return amount down to zero sats & cents", async () => {
for (let sats = 100; sats >= 0; sats--) {
const amountInSats = toSats(sats)
const amountInBtc = sat2btc(amountInSats)
const minExpectedAmountInCents = usd2cents(lastAskInUsdPerBtc * amountInBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const maxExpectedAmountInCents = Math.ceil(minExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForImmediateSell(amountInSats)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThanOrEqual(minExpectedAmountInCents)
}
})
})
describe("getCentsFromSatsForFutureBuy", () => {
it("should return amount within range", async () => {
Expand All @@ -61,7 +90,7 @@ describe("DealerPriceService", () => {
const maxExpectedAmountInCents = usd2cents(lastBidInUsdPerBtc * amountInBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const minExpectedAmountInCents = maxExpectedAmountInCents * feeRate
const minExpectedAmountInCents = Math.floor(maxExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForFutureBuy(
amountInSats,
Expand All @@ -71,6 +100,24 @@ describe("DealerPriceService", () => {
expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThan(minExpectedAmountInCents)
})
it("should return amount down to zero sats & cents", async () => {
for (let sats = 100; sats >= 0; sats--) {
const amountInSats = toSats(sats)
const amountInBtc = sat2btc(amountInSats)
const maxExpectedAmountInCents = usd2cents(lastBidInUsdPerBtc * amountInBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const minExpectedAmountInCents = Math.floor(maxExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForFutureBuy(
amountInSats,
defaultTimeToExpiryInSeconds,
)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThanOrEqual(minExpectedAmountInCents)
}
})
})
describe("getCentsFromSatsForFutureSell", () => {
it("should return amount within range", async () => {
Expand All @@ -79,7 +126,7 @@ describe("DealerPriceService", () => {
const minExpectedAmountInCents = usd2cents(lastAskInUsdPerBtc * amountInBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const maxExpectedAmountInCents = minExpectedAmountInCents * feeRate
const maxExpectedAmountInCents = Math.ceil(minExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForFutureSell(
amountInSats,
Expand All @@ -89,6 +136,24 @@ describe("DealerPriceService", () => {
expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThan(minExpectedAmountInCents)
})
it("should return amount down to zero sats & cents", async () => {
for (let sats = 100; sats >= 0; sats--) {
const amountInSats = toSats(sats)
const amountInBtc = sat2btc(amountInSats)
const minExpectedAmountInCents = usd2cents(lastAskInUsdPerBtc * amountInBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const maxExpectedAmountInCents = Math.ceil(minExpectedAmountInCents * feeRate)

const amountInCents = await dealer.getCentsFromSatsForFutureSell(
amountInSats,
defaultTimeToExpiryInSeconds,
)

expect(amountInCents).toBeLessThanOrEqual(maxExpectedAmountInCents)
expect(amountInCents).toBeGreaterThanOrEqual(minExpectedAmountInCents)
}
})
})
describe("getSatsFromCentsForImmediateBuy", () => {
it("should return amount within range", async () => {
Expand All @@ -104,6 +169,21 @@ describe("DealerPriceService", () => {
expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThan(minExpectedAmountInSats)
})
it("should return amount down to zero cents", async () => {
for (let cents = 100; cents >= 0; cents--) {
const amountInUsd = cents2usd(cents)
const amountInCents = usd2cents(amountInUsd)
const maxExpectedAmountInSats = btc2sat(amountInUsd / lastAskInUsdPerBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const minExpectedAmountInSats = maxExpectedAmountInSats / feeRate

const amountInSats = await dealer.getSatsFromCentsForImmediateBuy(amountInCents)

expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThanOrEqual(minExpectedAmountInSats)
}
})
})
describe("getSatsFromCentsForImmediateSell", () => {
it("should return amount within range", async () => {
Expand All @@ -119,6 +199,21 @@ describe("DealerPriceService", () => {
expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThan(minExpectedAmountInSats)
})
it("should return amount down to zero cents", async () => {
for (let cents = 100; cents >= 0; cents--) {
const amountInUsd = cents2usd(cents)
const amountInCents = usd2cents(amountInUsd)
const minExpectedAmountInSats = btc2sat(amountInUsd / lastBidInUsdPerBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const maxExpectedAmountInSats = minExpectedAmountInSats / feeRate

const amountInSats = await dealer.getSatsFromCentsForImmediateSell(amountInCents)

expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThanOrEqual(minExpectedAmountInSats)
}
})
})
describe("getSatsFromCentsForFutureBuy", () => {
it("should return amount within range", async () => {
Expand All @@ -137,6 +232,24 @@ describe("DealerPriceService", () => {
expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThan(minExpectedAmountInSats)
})
it("should return amount down to zero cents", async () => {
for (let cents = 100; cents >= 0; cents--) {
const amountInUsd = cents2usd(cents)
const amountInCents = usd2cents(amountInUsd)
const maxExpectedAmountInSats = btc2sat(amountInUsd / lastAskInUsdPerBtc)

const feeRate = 1 + MAX_EXPECTED_FEE
const minExpectedAmountInSats = maxExpectedAmountInSats / feeRate

const amountInSats = await dealer.getSatsFromCentsForFutureBuy(
amountInCents,
defaultTimeToExpiryInSeconds,
)

expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThanOrEqual(minExpectedAmountInSats)
}
})
})
describe("getSatsFromCentsForFutureSell", () => {
it("should return amount within range", async () => {
Expand All @@ -155,6 +268,24 @@ describe("DealerPriceService", () => {
expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThan(minExpectedAmountInSats)
})
it("should return amount down to zero cents", async () => {
for (let cents = 100; cents >= 0; cents--) {
const amountInUsd = cents2usd(cents)
const amountInCents = usd2cents(amountInUsd)
const minExpectedAmountInSats = btc2sat(amountInUsd / lastBidInUsdPerBtc)

const feeRate = 1 - MAX_EXPECTED_FEE
const maxExpectedAmountInSats = minExpectedAmountInSats / feeRate

const amountInSats = await dealer.getSatsFromCentsForFutureSell(
amountInCents,
defaultTimeToExpiryInSeconds,
)

expect(amountInSats).toBeLessThanOrEqual(maxExpectedAmountInSats)
expect(amountInSats).toBeGreaterThanOrEqual(minExpectedAmountInSats)
}
})
})
describe("getCentsPerSatsExchangeMidRate", () => {
it("should return mid", async () => {
Expand Down

0 comments on commit e22cad5

Please sign in to comment.