Skip to content
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
603 changes: 227 additions & 376 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions target_chains/ton/contracts/contracts/Main.fc
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@

;; * A 32-bit (big-endian) unsigned integer `op`, identifying the `operation` to be performed, or the `method` of the smart contract to be invoked.
int op = in_msg_body~load_uint(32);
;; * A 64-bit (big-endian) unsigned integer `query_id`, used in all query-response internal messages to indicate that a response is related to a query (the `query_id` of a response must be equal to the `query_id` of the corresponding query). If `op` is not a query-response method (e.g., it invokes a method that is not expected to send an answer), then `query_id` may be omitted.
int query_id = in_msg_body~load_uint(64);
cell data = in_msg_body~load_ref();
slice data_slice = data.begin_parse();

;; * The remainder of the message body is specific for each supported value of `op`.
if (op == OP_UPDATE_GUARDIAN_SET) {
update_guardian_set(in_msg_body);
update_guardian_set(data_slice);
} elseif (op == OP_EXECUTE_GOVERNANCE_ACTION) {
execute_governance_action(in_msg_body);
execute_governance_action(data_slice);
} elseif (op == OP_UPGRADE_CONTRACT) {
execute_upgrade_contract(data);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
25 changes: 21 additions & 4 deletions target_chains/ton/contracts/contracts/Pyth.fc
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,25 @@ int apply_decimal_expo(int value, int expo) {
return result;
}

() execute_upgrade_contract(slice payload) impure {
;; TODO: Implement
() execute_upgrade_contract(cell new_code) impure {
load_data();
int hash_code = cell_hash(new_code);
throw_unless(ERROR_INVALID_CODE_HASH, upgrade_code_hash == hash_code);

;; Set the new code
set_code(new_code);

;; Set the code continuation to the new code
set_c3(new_code.begin_parse().bless());

;; Throw an exception to end the current execution
;; The contract will be restarted with the new code
throw(0);
}

() execute_authorize_upgrade_contract(slice payload) impure {
int code_hash = payload~load_uint(256);
upgrade_code_hash = code_hash;
}

() execute_authorize_governance_data_source_transfer(slice payload) impure {
Expand Down Expand Up @@ -317,8 +334,8 @@ int apply_decimal_expo(int value, int expo) {
}

() execute_governance_payload(int action, slice payload) impure {
if (action == UPGRADE_CONTRACT) {
execute_upgrade_contract(payload);
if (action == AUTHORIZE_UPGRADE_CONTRACT) {
execute_authorize_upgrade_contract(payload);
} elseif (action == AUTHORIZE_GOVERNANCE_DATA_SOURCE_TRANSFER) {
execute_authorize_governance_data_source_transfer(payload);
} elseif (action == SET_DATA_SOURCES) {
Expand Down
3 changes: 2 additions & 1 deletion target_chains/ton/contracts/contracts/common/errors.fc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const int ERROR_OLD_GOVERNANCE_MESSAGE = 1033;
const int ERROR_INVALID_GOVERNANCE_TARGET = 1034;
const int ERROR_INVALID_GOVERNANCE_MAGIC = 1035;
const int ERROR_INVALID_GOVERNANCE_MODULE = 1036;
const int ERROR_INVALID_CODE_HASH = 1037;

;; Common
const int ERROR_INSUFFICIENT_GAS = 1037;
const int ERROR_INSUFFICIENT_GAS = 1038;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const int UPGRADE_CONTRACT = 0;
const int AUTHORIZE_UPGRADE_CONTRACT = 0;
const int AUTHORIZE_GOVERNANCE_DATA_SOURCE_TRANSFER = 1;
const int SET_DATA_SOURCES = 2;
const int SET_FEE = 3;
Expand Down
1 change: 1 addition & 0 deletions target_chains/ton/contracts/contracts/common/op.fc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const int OP_UPDATE_GUARDIAN_SET = 1;
const int OP_UPDATE_PRICE_FEEDS = 2;
const int OP_EXECUTE_GOVERNANCE_ACTION = 3;
const int OP_UPGRADE_CONTRACT = 4;
3 changes: 3 additions & 0 deletions target_chains/ton/contracts/contracts/common/storage.fc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ global int single_update_fee;
global cell data_sources; ;; Dictionary of DataSource tuples, keyed by u8
global int num_data_sources;
global cell is_valid_data_source; ;; Dictionary of int (0 as false, -1 as true), keyed by DataSource cell_hash
global int upgrade_code_hash; ;; 256-bit unsigned integer


;; Wormhole
Expand Down Expand Up @@ -54,6 +55,7 @@ global int governance_data_source_index; ;; u32
.store_ref(governance_data_source)
.store_uint(last_executed_governance_sequence, 64)
.store_uint(governance_data_source_index, 32)
.store_uint(upgrade_code_hash, 256)
.end_cell();

begin_cell()
Expand Down Expand Up @@ -94,6 +96,7 @@ global int governance_data_source_index; ;; u32
governance_data_source = governance_slice~load_ref();
last_executed_governance_sequence = governance_slice~load_uint(64);
governance_data_source_index = governance_slice~load_uint(32);
upgrade_code_hash = governance_slice~load_uint(256);

ds.end_parse();
}
9 changes: 6 additions & 3 deletions target_chains/ton/contracts/contracts/tests/PythTest.fc
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@

int op = in_msg_body~load_uint(32);
cell data = in_msg_body~load_ref();
slice data_slice = data.begin_parse();
if (op == OP_UPDATE_GUARDIAN_SET) {
update_guardian_set(data.begin_parse());
update_guardian_set(data_slice);
} elseif (op == OP_UPDATE_PRICE_FEEDS) {
update_price_feeds(msg_value, data.begin_parse());
update_price_feeds(msg_value, data_slice);
} elseif (op == OP_EXECUTE_GOVERNANCE_ACTION) {
execute_governance_action(data.begin_parse());
execute_governance_action(data_slice);
} elseif (op == OP_UPGRADE_CONTRACT) {
execute_upgrade_contract(data);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
78 changes: 78 additions & 0 deletions target_chains/ton/contracts/contracts/tests/PythTestUpgraded.fc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{-
This test contract is an upgraded version of PythTest.fc. This is used to test the upgrade functionality of the Pyth contract.
-}

#include "../imports/stdlib.fc";
#include "../Pyth.fc";
#include "../Wormhole.fc";
#include "../common/op.fc";

() recv_internal(int balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
if (in_msg_body.slice_empty?()) {
return ();
}

int op = in_msg_body~load_uint(32);
cell data = in_msg_body~load_ref();
slice data_slice = data.begin_parse();
if (op == OP_UPDATE_GUARDIAN_SET) {
update_guardian_set(data_slice);
} elseif (op == OP_UPDATE_PRICE_FEEDS) {
update_price_feeds(msg_value, data_slice);
} elseif (op == OP_EXECUTE_GOVERNANCE_ACTION) {
execute_governance_action(data_slice);
} elseif (op == OP_UPGRADE_CONTRACT) {
execute_upgrade_contract(data);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
}

(int, int, int, int) test_get_price_unsafe(int price_feed_id) method_id {
return get_price_unsafe(price_feed_id);
}

(int, int, int, int) test_get_price_no_older_than(int time_period, int price_feed_id) method_id {
return get_price_no_older_than(time_period, price_feed_id);
}

(int, int, int, int) test_get_ema_price_unsafe(int price_feed_id) method_id {
return get_ema_price_unsafe(price_feed_id);
}

(int, int, int, int) test_get_ema_price_no_older_than(int time_period, int price_feed_id) method_id {
return get_ema_price_no_older_than(time_period, price_feed_id);
}

(int) test_get_update_fee(slice in_msg_body) method_id {
return get_update_fee(in_msg_body);
}

(int) test_get_single_update_fee() method_id {
return get_single_update_fee();
}

(int) test_get_chain_id() method_id {
return get_chain_id();
}

(int) test_get_last_executed_governance_sequence() method_id {
return get_last_executed_governance_sequence();
}

(int) test_get_governance_data_source_index() method_id {
return get_governance_data_source_index();
}

(cell) test_get_governance_data_source() method_id {
return get_governance_data_source();
}

(int) test_get_is_valid_data_source(cell data_source) method_id {
return get_is_valid_data_source(data_source);
}

;; Add a new function to demonstrate the upgrade
(int) test_new_function() method_id {
return 1;
}
3 changes: 2 additions & 1 deletion target_chains/ton/contracts/contracts/tests/WormholeTest.fc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

int op = in_msg_body~load_uint(32);
cell data = in_msg_body~load_ref();
slice data_slice = data.begin_parse();
if (op == OP_UPDATE_GUARDIAN_SET) {
update_guardian_set(data.begin_parse());
update_guardian_set(data_slice);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
1 change: 1 addition & 0 deletions target_chains/ton/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@ton/ton": "^13.11.2",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.10",
"@wormhole-foundation/sdk-definitions": "^0.10.7",
"jest": "^29.7.0",
"prettier": "^3.3.2",
"ts-jest": "^29.2.0",
Expand Down
Loading
Loading