Skip to content

feat(target_chains/ton): add more tests for ton price_feeds contract #2008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 117 additions & 6 deletions target_chains/ton/contracts/tests/PythTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import {
PYTH_AUTHORIZE_GOVERNANCE_DATA_SOURCE_TRANSFER,
PYTH_REQUEST_GOVERNANCE_DATA_SOURCE_TRANSFER,
TEST_GUARDIAN_ADDRESS2,
ETH_PRICE_FEED_ID,
HERMES_BTC_PRICE,
HERMES_ETH_PRICE,
HERMES_ETH_PUBLISH_TIME,
HERMES_BTC_PUBLISH_TIME,
} from "./utils/pyth";
import { GUARDIAN_SET_0, MAINNET_UPGRADE_VAAS } from "./utils/wormhole";
import { DataSource } from "@pythnetwork/xc-admin-common";
Expand Down Expand Up @@ -235,6 +240,14 @@ describe("PythTest", () => {

await updateGuardianSets(pythTest, deployer);

// Check initial prices
const initialBtcPrice = await pythTest.getPriceUnsafe(BTC_PRICE_FEED_ID);
expect(initialBtcPrice.price).not.toBe(HERMES_BTC_PRICE);
// Expect an error for ETH price feed as it doesn't exist initially
await expect(pythTest.getPriceUnsafe(ETH_PRICE_FEED_ID)).rejects.toThrow(
"Unable to execute get method. Got exit_code: 1019"
); // ERROR_PRICE_FEED_NOT_FOUND = 1019

const updateData = Buffer.from(HERMES_BTC_ETH_UPDATE, "hex");
const updateFee = await pythTest.getUpdateFee(updateData);

Expand All @@ -250,10 +263,14 @@ describe("PythTest", () => {
success: true,
});

// Check if the price has been updated correctly
const updatedPrice = await pythTest.getPriceUnsafe(BTC_PRICE_FEED_ID);
expect(updatedPrice.price).not.toBe(Number(PRICE.price)); // Since we updated the price, it should not be the same as the initial price
expect(updatedPrice.publishTime).toBeGreaterThan(PRICE.publishTime);
// Check if both BTC and ETH prices have been updated
const updatedBtcPrice = await pythTest.getPriceUnsafe(BTC_PRICE_FEED_ID);
expect(updatedBtcPrice.price).toBe(HERMES_BTC_PRICE);
expect(updatedBtcPrice.publishTime).toBe(HERMES_BTC_PUBLISH_TIME);

const updatedEthPrice = await pythTest.getPriceUnsafe(ETH_PRICE_FEED_ID);
expect(updatedEthPrice.price).toBe(HERMES_ETH_PRICE);
expect(updatedEthPrice.publishTime).toBe(HERMES_ETH_PUBLISH_TIME);
});

it("should fail to get update fee with invalid data", async () => {
Expand Down Expand Up @@ -339,6 +356,21 @@ describe("PythTest", () => {
});
});

it("should correctly handle stale prices", async () => {
const staleTime = Math.floor(Date.now() / 1000) - TIME_PERIOD - 10; // 10 seconds past the allowed period
const stalePrice = new Price({
price: "1",
conf: "2",
expo: 3,
publishTime: staleTime,
});
await deployContract(BTC_PRICE_FEED_ID, TIME_PERIOD, stalePrice, EMA_PRICE);

await expect(
pythTest.getPriceNoOlderThan(TIME_PERIOD, BTC_PRICE_FEED_ID)
).rejects.toThrow("Unable to execute get method. Got exit_code: 1020"); // ERROR_OUTDATED_PRICE = 1020
});

it("should fail to update price feeds with insufficient gas", async () => {
await deployContract();
await updateGuardianSets(pythTest, deployer);
Expand Down Expand Up @@ -385,7 +417,7 @@ describe("PythTest", () => {
});
});

it("should fail to get price for non-existent price feed", async () => {
it("should fail to get prices for non-existent price feed", async () => {
await deployContract();

const nonExistentPriceFeedId =
Expand All @@ -394,6 +426,14 @@ describe("PythTest", () => {
await expect(
pythTest.getPriceUnsafe(nonExistentPriceFeedId)
).rejects.toThrow("Unable to execute get method. Got exit_code: 1019"); // ERROR_PRICE_FEED_NOT_FOUND = 1019

await expect(
pythTest.getPriceNoOlderThan(TIME_PERIOD, nonExistentPriceFeedId)
).rejects.toThrow("Unable to execute get method. Got exit_code: 1019"); // ERROR_PRICE_FEED_NOT_FOUND

await expect(
pythTest.getEmaPriceUnsafe(nonExistentPriceFeedId)
).rejects.toThrow("Unable to execute get method. Got exit_code: 1019"); // ERROR_PRICE_FEED_NOT_FOUND
});

it("should correctly get chain ID", async () => {
Expand Down Expand Up @@ -518,7 +558,7 @@ describe("PythTest", () => {
expect(result).toBe(SINGLE_UPDATE_FEE);
});

it("should execute set fee governance instruction", async () => {
it("should execute set data sources governance instruction", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test name was wrong, the test was actually testing set data sources

await deployContract(
BTC_PRICE_FEED_ID,
TIME_PERIOD,
Expand Down Expand Up @@ -572,6 +612,47 @@ describe("PythTest", () => {
expect(oldDataSourceIsValid).toBe(false);
});

it("should execute set fee governance instruction", async () => {
await deployContract(
BTC_PRICE_FEED_ID,
TIME_PERIOD,
PRICE,
EMA_PRICE,
SINGLE_UPDATE_FEE,
DATA_SOURCES,
0,
[TEST_GUARDIAN_ADDRESS1],
60051, // CHAIN_ID of starknet since we are using the test payload for starknet
1,
"0000000000000000000000000000000000000000000000000000000000000004",
TEST_GOVERNANCE_DATA_SOURCES[0]
);

// Get the initial fee
const initialFee = await pythTest.getSingleUpdateFee();
expect(initialFee).toBe(SINGLE_UPDATE_FEE);

// Execute the governance action
const result = await pythTest.sendExecuteGovernanceAction(
deployer.getSender(),
Buffer.from(PYTH_SET_FEE, "hex")
);
expect(result.transactions).toHaveTransaction({
from: deployer.address,
to: pythTest.address,
success: true,
});

// Get the new fee
const newFee = await pythTest.getSingleUpdateFee();
expect(newFee).toBe(4200); // The new fee value is 4200 in the PYTH_SET_FEE payload

// Verify that the new fee is used for updates
const updateData = Buffer.from(HERMES_BTC_ETH_UPDATE, "hex");
const updateFee = await pythTest.getUpdateFee(updateData);
expect(updateFee).toBe(8400); // There are two price updates in HERMES_BTC_ETH_UPDATE
});

it("should execute authorize governance data source transfer", async () => {
await deployContract(
BTC_PRICE_FEED_ID,
Expand Down Expand Up @@ -732,6 +813,36 @@ describe("PythTest", () => {
});
});

it("should fail to execute governance action with invalid chain ID", async () => {
const invalidChainId = 999;
await deployContract(
BTC_PRICE_FEED_ID,
TIME_PERIOD,
PRICE,
EMA_PRICE,
SINGLE_UPDATE_FEE,
DATA_SOURCES,
0,
[TEST_GUARDIAN_ADDRESS1],
invalidChainId,
1,
"0000000000000000000000000000000000000000000000000000000000000004",
TEST_GOVERNANCE_DATA_SOURCES[0]
);

const result = await pythTest.sendExecuteGovernanceAction(
deployer.getSender(),
Buffer.from(PYTH_SET_FEE, "hex")
);

expect(result.transactions).toHaveTransaction({
from: deployer.address,
to: pythTest.address,
success: false,
exitCode: 1034, // ERROR_INVALID_GOVERNANCE_TARGET
});
});

it("should successfully upgrade the contract", async () => {
// Compile the upgraded contract
const upgradedCode = await compile("PythTestUpgraded");
Expand Down
8 changes: 8 additions & 0 deletions target_chains/ton/contracts/tests/utils/pyth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@
export const HERMES_BTC_ETH_UPDATE =
"504e41550100000003b801000000040d00a0bb18e08c0a4152eba8293e88d0ed43084dfd4677fd5dc0ff48b05d065e25511ea12181325e92541290f28e00487a7ed852fdecbee414cab803dbe1dac2392201023e177888eba8922eac9b0668566f15c61e945cd47c10fa4ca2e4d472d7d216f149f3378b4edc5f8d802c3ef9b8156ca53c9ae2d4f75dd91f7713946b4108c5910003af26c2426a1bf19f24a171bcc990dad056b670f76894e3bdb9925b21b40b3904757d8e6175133b8608431d7435e29c5fcc2912349c2c8b5588803c06f203c73401048a30050ebafd161c3cfa5531896040b6da88502734c8e42ca3197d52ea08f6ec785a24f24bc9325c16ee7b6a9791bc523523f9086162ed4ccf746b55e1b0f192010886c5256df6ca2719fe97c10b79a4a8c8574fb70add9bfe0d879ae5f6c69b2459360b50b58c43a65e881081174cce56827880e0c330b5c5681294dc3fcb78a86d010a4e0ebb1992f0e48263f6188cb5f8e871cdcd7879f54fe7ad53bbd28d5e7ff70e73441836f0d11076bd7a791aceb05d501500f6878cf26e641fffa7c8fd143371000b3ad70bd80e52a82cd740ffbd4a080bd22523bc7ac2b1242169516d7aaf2753cd7ee5b500134ef32c02284e9d806fbeab2e055ea4a94be9cbfcfbc39b249b5e6b010c97d60c0f15b18c8fb2f36331ab0a1ce0efa13e9f2118c32140bd2118823d50f12deffc40b5d0c9642b4e44a6bd1cf4f38de471536a6610e698a942f049abef35010da2004619d8b31e33037ffed4afdd97459a241dfc7fa3bcc426f175461c938a182db560547dfcdd8ede345f0cc69da33fd588c30e912b7521c3ac1b0455882628000e81868d37eb16e1988451c26cfea8bb7969ce11c89488cedea30c80e3416dd2147c0554e9a9cce1a864eb0db625baa2cbb226ae2c2f1051f84b0a711c4bf69647010f02f18088ddbabd7c4528a1f7582f5fb11e60c5e434e9fd4ca2b33d6646e2ac6e6459c651778d1531711b44d2a1204a0d9c17e218aba5e60800e80aade9f1d90400108c783ad40f93184ad4f7e84229b207b17099e78b8bd93ddf2434cba21c99b4a904d74555ced9977e6becc34fa346c3cca9332b3598e66e58eb56f9ac700074e0001270a31d95bd5426ffe943dcc2b93f05b93f8301848f0b19c56e0dea51b7742c467b6bb557f6fc6762ef4600988c2dbcad0a2be84d4c6839fbae05d227e30ce5f50166cec2c600000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa71000000000493073601415557560000000000099e556100002710c0905b1576f0bb86fe861a51273f2bcc43d12dd702005500e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43000005634a12c5d50000000096b3a0ebfffffff80000000066cec2c60000000066cec2c600000566c715d5a000000000895abaa20a83db6da7dfbe7cc34f56265123320d7765dda3ae132c1518c53ead6cde500c139f68a894f564d817c0dfaeefa80d4ed93d36b82f7fcfe80e4092bb54d4dae770124803c592f17cb918c9ac381ce82bd6817041aa5ae95d917d75687b7a389a188846dd79bd55cb6cb9b9d0e1c0c040f1110362a8e1e87c74887326d66b213d19f7dcd1766b6f8505be50f5c98783c07ec08f913cbe38c20a31e440e42bb5a8883356dd19288e618e938ae4e7031d52d684f7bd1ddcf0d4ff63844800e14ff0c6888ff26626ea9874005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace000000396f6987dd00000000052fbd87fffffff80000000066cec2c60000000066cec2c6000000398c4513280000000006c9a0a10a5307d6b780c8c5579b4b61de5fe0f12a789efdc628f14603df77ba31734c5611291df9a86e51430b243b3b61ee716bd758360783bdb7ef2f96ab8e92d509d85940a832b3de426d243a6d52ccf1e538af48b1bfad061dec1e4293898ca9ca9f37d0050d7b9e6a54357e77e7d79156fa1c70d54484ce52df49e79ab3fde203359f760fd9cf78be10644a43b52a171026829814590e8ba4853f6c8f0a16ce0fe3b532bcc96ea72723ab7d19f700c153e7cfb950f4aaa691e731e6f1de4edf43a6b9dd532a8ee785f084";

export const HERMES_BTC_PRICE = 5924002645461;
export const HERMES_BTC_PUBLISH_TIME = 1724826310;
export const HERMES_ETH_PRICE = 246682322909;
export const HERMES_ETH_PUBLISH_TIME = 1724826310;

export const BTC_PRICE_FEED_ID =
"0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43";

export const ETH_PRICE_FEED_ID =
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace";

export const TEST_GUARDIAN_ADDRESS1 =
"0x686b9ea8e3237110eaaba1f1b7467559a3273819";

Expand Down
Loading