Skip to content

Commit f34c9df

Browse files
authored
[sui 8/x] - finalize contracts, deploy scripts, address audit feedback (#783)
* state getters and setters, change Move.toml dependency to sui/integration_v2 * finish state.move * add new line to pyth * use deployer cap pattern for state module * sui pyth * update price feeds, dynamic object fields, Sui object PriceInfoObject * register price info object with pyth state after creation * sui governance * some newlines * error codes * update and comment * unit tests for pyth.move, add UpgradeCap to Pyth State (will be used for contract upgrades) * updates * test_get_update_fee test passes * fix test_get_update_fee and test_update_price_feeds_corrupt_vaa * test_update_price_feeds_invalid_data_source * test_create_and_update_price_feeds * test_create_and_update_price_feeds_success and test_create_and_update_price_feeds_price_info_object_not_found_failure * test_update_cache * update * test_update_cache_old_update * update_price_feeds_if_fresh * comment * contract upgrades start * contract upgradeability * update clock stuff * edits * use clone of sui/integration_v2 for stability * make contract_upgrade::execute a public(friend) fun, remove clock arg * E_INCORRECT_IDENTIFIER_LENGTH * comment and edit * add a single comment * upgradeability fixes, other fixes * update, migrate, state, pyth, setup, version_control * upgradeability, governance, LatestOnly * - state init_version, init_package_info - governance and contract ugpradeability stuff * make several functions public(friend), and friend the right modules in data_source.move * add comment * fix bug in from_u8, so that value <= TRANSFER_FEE * rename error message to E_MUST_USE_CONTRACT_UPGRADE_MODULE_TO_DO_UPGRADES * set_last_executed_governance_sequence * set pyth governance_module to 0000000000000000000000000000000000000000000000000000000000000001 * update README * Update README.md * Update README.md * delete comments * Update README.md * Update README.md * change Wormhole dependency to branch sui/mainnet, which has the latest update that includes VAA sequence number in DecreeReceipt do proper checking of sequence number when executing governance instructions, allow set_governance_data_source to update the sequence number to some initial_sequence. * state::set_last_executed_governance_sequence * rename error * add newline to setup.move * delete space * Update README.md * mark test module as well as some imports #[test_only] so sui move build works * scripts for Pyth contract testing and deployment remove required_version.move, as it is no longer being used for access control make init_and_share_state a public(friend) function * add build to Makefile * init pyth ts script * sui deploy and testing scripts * contract fixes, set_fee_recipient governance action, emit price update event only if fresh price update * init_pyth.ts, registry.ts, create_price_feed.ts * create price feeds * deploy script and Move.toml * some contract updates to compile with WH branch sui/mainnet deployment script updates * update README * update readme * rename TS scripts, edit readme * add rev for wormhole dependency, edit README * edit create_price_feed script * - add price_info::get function for getting PriceInfoObject ID from PriceIdentifier - add test for price_info::get * contract updates * script edits * contract upgrade in version_control.move and fix pyth_create_price_feed.ts * add get_price_info_object_id function to pyth::state * tests and build pass * update scripts * Pyth mainnet deploy, create all price feeds script * clean up script imports * add mainnet addresses to readme * correct Pyth Mainnet addresses * create price feeds on mainnet * use git dependency in Move.toml * edits * delete required contracts * get price info object ids * get price info object IDs * add json file containing price feed id to price info object id * comment * clean up scripts folder and imports * more script clean up (comments) * script updates * pre-commit run --all-files
1 parent 26f3fc3 commit f34c9df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+16121
-809
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ tsconfig.tsbuildinfo
1717
*~
1818
*mnemonic*
1919
.envrc
20-
.DS_Store
20+
*/*.sui.log*

target_chains/sui/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Pyth on Sui
2+
3+
## 1. Background
4+
5+
Pyth price feeds on Sui are uniquely represented in the global store as `PriceInfoObjects`. These objects have the `key` ability and serve as wrappers around the `PriceInfo` object, which in turn wraps around the `PriceFeed`, the arrival time of the latest price update, and the attestation time of the latest update.
6+
7+
`PriceInfoObject`s are central to Pyth on Sui, since they are in unique correspondence with each Pyth price feed and must be passed in to functions that act on price feeds, e.g.
8+
9+
- `update_price_feeds`
10+
- `update_price_feed_from_single_vaa`
11+
- `update_price_feeds_if_fresh`
12+
13+
## 2. How to Update and Consume Price Feeds
14+
15+
To update and then consume a price feed, one needs to build a Sui [programmable transaction](https://docs.sui.io/build/prog-trans-ts-sdk).
16+
17+
As with other chains, one first obtains a batch price attestation VAA (of type `vector<u8>`) off-chain for a Price Info Object whose feed is to be used. Assume the ID is `PRICE_INFO_OBJECT_ID`. Then, chain together the following sequence of function calls:
18+
19+
### 1. `wormhole::parse_and_verify`
20+
21+
Call `parse_and_verify` on the batch attestation VAA bytes to obtain a `VAA` hot potato object.
22+
23+
```Rust
24+
public fun parse_and_verify(
25+
wormhole_state: &State,
26+
buf: vector<u8>,
27+
the_clock: &Clock
28+
): VAA
29+
```
30+
31+
### 2.`pyth:update_price_feeds`
32+
33+
Vectorize the `VAA` from the previous step and pass it to `update_price_feeds`.
34+
35+
```Rust
36+
public fun update_price_feeds(
37+
pyth_state: &PythState,
38+
verified_vaas: vector<VAA>,
39+
price_info_objects: &mut vector<PriceInfoObject>,
40+
fee: Coin<SUI>,
41+
clock: &Clock
42+
)
43+
```
44+
45+
### 3. `pyth::get_price`
46+
47+
Finally, get the price of the updated price feed in `PriceInfoObject`.
48+
49+
```Rust
50+
public fun get_price(
51+
state: &PythState,
52+
price_info_object: &PriceInfoObject,
53+
clock: &Clock
54+
): Price
55+
```
56+
57+
Fetch the price of the updated Price Info Object.
58+
59+
## 3. Examples
60+
61+
See the `./scripts` folder for examples of programmable transactions for creating price feeds, updating price feeds, and deploying contracts.
62+
63+
To build and test the contracts, run the following
64+
65+
```
66+
$ make test
67+
$ make build
68+
```
69+
70+
## 4. Contracts Registry
71+
72+
## Pyth on Testnet
73+
74+
- PYTH_PACKAGE_ID: [0x7c017b047a3c9db5a8f4586d347c54869b761b6d6b0882a179823e8642faf7b9](https://explorer.sui.io/object/0x7c017b047a3c9db5a8f4586d347c54869b761b6d6b0882a179823e8642faf7b9)
75+
- PYTH_STATE_ID: [0x3fc17e66d5ced3bf62f3fe8289cb2cb78c311a1e1c9700727ecd278d242e9e88](https://explorer.sui.io/object/0x3fc17e66d5ced3bf62f3fe8289cb2cb78c311a1e1c9700727ecd278d242e9e88)
76+
77+
## Wormhole on Testnet
78+
79+
- WORMHOLE_PACKAGE_ID: [0x80c60bff35fe5026e319cf3d66ae671f2b4e12923c92c45df75eaf4de79e3ce7](https://explorer.sui.io/object/0x80c60bff35fe5026e319cf3d66ae671f2b4e12923c92c45df75eaf4de79e3ce7)
80+
- WORMHOLE_STATE_ID: [0x79ab4d569f7eb1efdcc1f25b532f8593cda84776206772e33b490694cb8fc07a](https://explorer.sui.io/object/0x79ab4d569f7eb1efdcc1f25b532f8593cda84776206772e33b490694cb8fc07a)
81+
82+
## Pyth on Mainnet
83+
84+
- PYTH_PACKAGE_ID: [0xa446c4a37c0bb69d03357c1a52d60da0b434048226d5f3feffdb693586bea861](https://explorer.sui.io/object/0xa446c4a37c0bb69d03357c1a52d60da0b434048226d5f3feffdb693586bea861?network=https%3A%2F%2Ffullnode.mainnet.sui.io%3A443)
85+
- PYTH_STATE_ID: [0x428b5795904d5256d1eea5991df672934315fb8dcf8f6111134c1a52afd005ca](https://explorer.sui.io/object/0x428b5795904d5256d1eea5991df672934315fb8dcf8f6111134c1a52afd005ca?network=https%3A%2F%2Ffullnode.mainnet.sui.io%3A443)
86+
87+
## Wormhole on Mainnet
88+
89+
- WORMHOLE_PACKAGE_ID: [0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a](https://explorer.sui.io/object/0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a)
90+
- WORMHOLE_STATE_ID: [0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c](https://explorer.sui.io/object/0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c)

target_chains/sui/contracts/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ TARGETS := test
33
.PHONY: test
44
test:
55
sui move test
6+
7+
.PHONY: build
8+
build:
9+
sui move build -d

target_chains/sui/contracts/Move.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ dependencies = [
1010

1111
[[move.package]]
1212
name = "MoveStdlib"
13-
source = { git = "https://github.com/MystenLabs/sui.git", rev = "81dbcf2b6cab07d623a1012bf31daf658963c765", subdir = "crates/sui-framework/packages/move-stdlib" }
13+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "09b2081498366df936abae26eea4b2d5cafb2788", subdir = "crates/sui-framework/packages/move-stdlib" }
1414

1515
[[move.package]]
1616
name = "Sui"
17-
source = { git = "https://github.com/MystenLabs/sui.git", rev = "81dbcf2b6cab07d623a1012bf31daf658963c765", subdir = "crates/sui-framework/packages/sui-framework" }
17+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "09b2081498366df936abae26eea4b2d5cafb2788", subdir = "crates/sui-framework/packages/sui-framework" }
1818

1919
dependencies = [
2020
{ name = "MoveStdlib" },
2121
]
2222

2323
[[move.package]]
2424
name = "Wormhole"
25-
source = { git = "https://github.com/wormhole-foundation/wormhole.git", rev = "sui/integration_v2", subdir = "sui/wormhole" }
25+
source = { git = "https://github.com/wormhole-foundation/wormhole.git", rev = "d050ad1d67a5b7da9fb65030aad12ef5d774ccad", subdir = "sui/wormhole" }
2626

2727
dependencies = [
2828
{ name = "Sui" },
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "Pyth"
3+
version = "0.0.1"
4+
5+
[dependencies.Sui]
6+
git = "https://github.com/MystenLabs/sui.git"
7+
subdir = "crates/sui-framework/packages/sui-framework"
8+
rev = "09b2081498366df936abae26eea4b2d5cafb2788"
9+
10+
[dependencies.Wormhole]
11+
local = "../../../../wormhole/sui/wormhole"
12+
13+
[addresses]
14+
pyth = "0x0"
15+
wormhole = "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a"
16+
17+
[dev-addresses]
18+
pyth = "0x100"
19+
wormhole = "0x200"

target_chains/sui/contracts/Move.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ version = "0.0.1"
55
[dependencies.Sui]
66
git = "https://github.com/MystenLabs/sui.git"
77
subdir = "crates/sui-framework/packages/sui-framework"
8-
rev = "a63f425b9999c7fdfe483598720a9effc0acdc9e"
8+
rev = "09b2081498366df936abae26eea4b2d5cafb2788"
99

1010
[dependencies.Wormhole]
1111
git = "https://github.com/wormhole-foundation/wormhole.git"
1212
subdir = "sui/wormhole"
13-
rev = "sui/integration_v2_stable"
13+
rev = "d050ad1d67a5b7da9fb65030aad12ef5d774ccad"
1414

1515
[addresses]
16-
pyth = "0x250"
17-
wormhole = "0x200"
16+
pyth = "0xa446c4a37c0bb69d03357c1a52d60da0b434048226d5f3feffdb693586bea861"
17+
wormhole = "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a"

target_chains/sui/contracts/sources/batch_price_attestation.move

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ module pyth::batch_price_attestation {
163163
#[test]
164164
#[expected_failure]
165165
fun test_deserialize_batch_price_attestation_invalid_magic() {
166-
use sui::test_scenario::{Self, take_shared, return_shared, ctx};
166+
use sui::test_scenario::{Self, ctx};
167167
let test = test_scenario::begin(@0x1234);
168168
let test_clock = clock::create_for_testing(ctx(&mut test));
169169
// A batch price attestation with a magic number of 0x50325749
@@ -175,7 +175,7 @@ module pyth::batch_price_attestation {
175175

176176
#[test]
177177
fun test_deserialize_batch_price_attestation() {
178-
use sui::test_scenario::{Self, take_shared, return_shared, ctx};
178+
use sui::test_scenario::{Self, ctx};
179179
// Set the arrival time
180180
let test = test_scenario::begin(@0x1234);
181181
let test_clock = clock::create_for_testing(ctx(&mut test));

target_chains/sui/contracts/sources/data_source.move

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ module pyth::data_source {
77

88
use wormhole::external_address::ExternalAddress;
99

10+
friend pyth::state;
11+
friend pyth::set_data_sources;
12+
friend pyth::pyth;
13+
friend pyth::set_governance_data_source;
14+
#[test_only]
15+
friend pyth::pyth_tests;
16+
1017
const KEY: vector<u8> = b"data_sources";
1118
const E_DATA_SOURCE_REGISTRY_ALREADY_EXISTS: u64 = 0;
1219
const E_DATA_SOURCE_ALREADY_REGISTERED: u64 = 1;
@@ -16,7 +23,7 @@ module pyth::data_source {
1623
emitter_address: ExternalAddress,
1724
}
1825

19-
public fun new_data_source_registry(parent_id: &mut UID, ctx: &mut TxContext) {
26+
public(friend) fun new_data_source_registry(parent_id: &mut UID, ctx: &mut TxContext) {
2027
assert!(
2128
!dynamic_field::exists_(parent_id, KEY),
2229
E_DATA_SOURCE_REGISTRY_ALREADY_EXISTS // TODO - add custom error type
@@ -28,7 +35,7 @@ module pyth::data_source {
2835
)
2936
}
3037

31-
public fun add(parent_id: &mut UID, data_source: DataSource) {
38+
public(friend) fun add(parent_id: &mut UID, data_source: DataSource) {
3239
assert!(
3340
!contains(parent_id, data_source),
3441
E_DATA_SOURCE_ALREADY_REGISTERED
@@ -39,7 +46,7 @@ module pyth::data_source {
3946
)
4047
}
4148

42-
public fun empty(parent_id: &mut UID){
49+
public(friend) fun empty(parent_id: &mut UID){
4350
set::empty<DataSource>(
4451
dynamic_field::borrow_mut(parent_id, KEY)
4552
)
@@ -50,10 +57,18 @@ module pyth::data_source {
5057
set::contains<DataSource>(ref, data_source)
5158
}
5259

53-
public fun new(emitter_chain: u64, emitter_address: ExternalAddress): DataSource {
60+
public(friend) fun new(emitter_chain: u64, emitter_address: ExternalAddress): DataSource {
5461
DataSource {
5562
emitter_chain: emitter_chain,
5663
emitter_address: emitter_address,
5764
}
5865
}
66+
67+
public fun emitter_chain(data_source: &DataSource): u64{
68+
data_source.emitter_chain
69+
}
70+
71+
public fun emitter_address(data_source: &DataSource): ExternalAddress{
72+
data_source.emitter_address
73+
}
5974
}

target_chains/sui/contracts/sources/deserialize.move

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module pyth::deserialize {
22
use wormhole::bytes::{Self};
3-
use wormhole::cursor::{take_rest, Cursor};
3+
use wormhole::cursor::{Cursor};
44
use pyth::i64::{Self, I64};
5+
#[test_only]
6+
use wormhole::cursor::{take_rest};
57

68
#[test_only]
79
use wormhole::cursor::{Self};

0 commit comments

Comments
 (0)