import { describe, expect, it } from 'vitest'; import { pegCryptoAmount } from '../src/peg'; import { priceToRateUnits } from '../src/rates'; describe('pegCryptoAmount', () => { it('converts $100 at rate 1.000000 to exactly 100 tokens', () => { expect(pegCryptoAmount('100', 1_000000n)).toBe(100_000000n); }); it('rounds UP so the merchant never receives less than invoiced ($100 at 0.9997)', () => { // 100 / 0.9997 = 100.030009…, must round up to 100.030010 expect(pegCryptoAmount('100', 999700n)).toBe(100_030010n); }); it('handles small amounts', () => { expect(pegCryptoAmount('0.01', 1_000000n)).toBe(10000n); }); it('rejects zero/negative inputs', () => { expect(() => pegCryptoAmount('0', 1_000000n)).toThrow(); expect(() => pegCryptoAmount('100', 0n)).toThrow(); }); }); describe('priceToRateUnits', () => { it('converts typical stablecoin prices', () => { expect(priceToRateUnits(1)).toBe(1_000000n); expect(priceToRateUnits(0.9997)).toBe(999700n); expect(priceToRateUnits(1.0002)).toBe(1_000200n); }); it('truncates precision beyond 6dp rather than rounding money upward', () => { expect(priceToRateUnits(0.99976543)).toBe(999765n); }); it('rejects non-positive or non-finite prices', () => { expect(() => priceToRateUnits(0)).toThrow(); expect(() => priceToRateUnits(-1)).toThrow(); expect(() => priceToRateUnits(Number.NaN)).toThrow(); }); });