PythTest.spec.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox";
  2. import { Cell, toNano } from "@ton/core";
  3. import "@ton/test-utils";
  4. import { compile } from "@ton/blueprint";
  5. import {
  6. HexString,
  7. parseAccumulatorUpdateData,
  8. Price,
  9. } from "@pythnetwork/price-service-sdk";
  10. import { PythTest, PythTestConfig } from "../wrappers/PythTest";
  11. import { HERMES_BTC_ETH_UPDATE } from "./utils/pyth";
  12. const PRICE_FEED_ID =
  13. "0x0000000000000000000000000000000000000000000000000000000000000000";
  14. const TIME_PERIOD = 60;
  15. const PRICE = new Price({
  16. price: "1",
  17. conf: "2",
  18. expo: 3,
  19. publishTime: 4,
  20. });
  21. const EMA_PRICE = new Price({
  22. price: "5",
  23. conf: "6",
  24. expo: 7,
  25. publishTime: 8,
  26. });
  27. const SINGLE_UPDATE_FEE = 1;
  28. describe("PythTest", () => {
  29. let code: Cell;
  30. beforeAll(async () => {
  31. code = await compile("PythTest");
  32. });
  33. let blockchain: Blockchain;
  34. let deployer: SandboxContract<TreasuryContract>;
  35. let pythTest: SandboxContract<PythTest>;
  36. beforeEach(async () => {
  37. blockchain = await Blockchain.create();
  38. deployer = await blockchain.treasury("deployer");
  39. });
  40. async function deployContract(
  41. priceFeedId: HexString = PRICE_FEED_ID,
  42. timePeriod: number = TIME_PERIOD,
  43. price: Price = PRICE,
  44. emaPrice: Price = EMA_PRICE,
  45. singleUpdateFee: number = SINGLE_UPDATE_FEE
  46. ) {
  47. const config: PythTestConfig = {
  48. priceFeedId,
  49. timePeriod,
  50. price,
  51. emaPrice,
  52. singleUpdateFee,
  53. };
  54. pythTest = blockchain.openContract(PythTest.createFromConfig(config, code));
  55. const deployResult = await pythTest.sendDeploy(
  56. deployer.getSender(),
  57. toNano("0.05")
  58. );
  59. expect(deployResult.transactions).toHaveTransaction({
  60. from: deployer.address,
  61. to: pythTest.address,
  62. deploy: true,
  63. success: true,
  64. });
  65. }
  66. it("should correctly get price unsafe", async () => {
  67. await deployContract();
  68. const result = await pythTest.getPriceUnsafe(PRICE_FEED_ID);
  69. expect(result.price).toBe(1);
  70. expect(result.conf).toBe(2);
  71. expect(result.expo).toBe(3);
  72. expect(result.publishTime).toBe(4);
  73. });
  74. it("should correctly get price no older than", async () => {
  75. const timeNow = Math.floor(Date.now() / 1000) - TIME_PERIOD + 5; // 5 seconds buffer
  76. const price = new Price({
  77. price: "1",
  78. conf: "2",
  79. expo: 3,
  80. publishTime: timeNow,
  81. });
  82. await deployContract(PRICE_FEED_ID, TIME_PERIOD, price, EMA_PRICE);
  83. const result = await pythTest.getPriceNoOlderThan(
  84. TIME_PERIOD,
  85. PRICE_FEED_ID
  86. );
  87. expect(result.price).toBe(1);
  88. expect(result.conf).toBe(2);
  89. expect(result.expo).toBe(3);
  90. expect(result.publishTime).toBe(timeNow);
  91. });
  92. it("should fail to get price no older than", async () => {
  93. await deployContract();
  94. await expect(
  95. pythTest.getPriceNoOlderThan(TIME_PERIOD, PRICE_FEED_ID)
  96. ).rejects.toThrow("Unable to execute get method. Got exit_code: 1020"); // ERROR_OUTDATED_PRICE = 1020
  97. });
  98. it("should correctly get ema price no older than", async () => {
  99. const timeNow = Math.floor(Date.now() / 1000) - TIME_PERIOD + 5; // 5 seconds buffer
  100. const emaPrice = new Price({
  101. price: "5",
  102. conf: "6",
  103. expo: 7,
  104. publishTime: timeNow,
  105. });
  106. await deployContract(PRICE_FEED_ID, TIME_PERIOD, PRICE, emaPrice);
  107. const result = await pythTest.getEmaPriceNoOlderThan(
  108. TIME_PERIOD,
  109. PRICE_FEED_ID
  110. );
  111. expect(result.price).toBe(5);
  112. expect(result.conf).toBe(6);
  113. expect(result.expo).toBe(7);
  114. expect(result.publishTime).toBe(timeNow);
  115. });
  116. it("should fail to get ema price no older than", async () => {
  117. await deployContract();
  118. await expect(
  119. pythTest.getEmaPriceNoOlderThan(TIME_PERIOD, PRICE_FEED_ID)
  120. ).rejects.toThrow("Unable to execute get method. Got exit_code: 1020"); // ERROR_OUTDATED_PRICE = 1020
  121. });
  122. it("should correctly get ema price unsafe", async () => {
  123. await deployContract();
  124. const result = await pythTest.getEmaPriceUnsafe(PRICE_FEED_ID);
  125. expect(result.price).toBe(5);
  126. expect(result.conf).toBe(6);
  127. expect(result.expo).toBe(7);
  128. expect(result.publishTime).toBe(8);
  129. });
  130. it("should correctly get update fee", async () => {
  131. await deployContract();
  132. const result = await pythTest.getUpdateFee(
  133. Buffer.from(HERMES_BTC_ETH_UPDATE, "hex")
  134. );
  135. expect(result).toBe(2);
  136. });
  137. });