Skip to content

Commit e4db9ca

Browse files
authored
[sui 3/x]: events, dynamic fields, update_price_feed, PriceInfoObject (#714)
* 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 * PriceFeedUpdateEvent
1 parent 111b0fa commit e4db9ca

File tree

8 files changed

+480
-44
lines changed

8 files changed

+480
-44
lines changed

target_chains/sui/contracts/Move.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ version = "0.0.1"
44

55
[dependencies.Sui]
66
git = "https://github.com/MystenLabs/sui.git"
7-
subdir = "crates/sui-framework"
8-
rev = "157ac72030d014f17d76cefe81f3915b4afab2c9"
7+
subdir = "crates/sui-framework/packages/sui-framework"
8+
rev = "82c9c80c11488858f1d3930f47ec9f335a566683"
99

1010
[dependencies.Wormhole]
1111
git = "https://github.com/wormhole-foundation/wormhole.git"

target_chains/sui/contracts/sources/batch_price_attestation.move

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ module pyth::batch_price_attestation {
153153
ema_timestamp = prev_publish_time;
154154
};
155155

156-
price_info::new(
156+
price_info::new_price_info(
157157
attestation_time,
158158
tx_context::epoch(ctx), //TODO - use Sui Clock to get timestamp in seconds
159159
price_feed::new(
@@ -172,7 +172,7 @@ module pyth::batch_price_attestation {
172172

173173
// A batch price attestation with a magic number of 0x50325749
174174
let bytes = x"5032574900030000000102000400951436e0be37536be96f0896366089506a59763d036728332d3e3038047851aea7c6c75c89f14810ec1c54c03ab8f1864a4c4032791f05747f560faec380a695d1000000000000049a0000000000000008fffffffb00000000000005dc0000000000000003000000000100000001000000006329c0eb000000006329c0e9000000006329c0e400000000000006150000000000000007215258d81468614f6b7e194c5d145609394f67b041e93e6695dcc616faadd0603b9551a68d01d954d6387aff4df1529027ffb2fee413082e509feb29cc4904fe000000000000041a0000000000000003fffffffb00000000000005cb0000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e4000000000000048600000000000000078ac9cf3ab299af710d735163726fdae0db8465280502eb9f801f74b3c1bd190333832fad6e36eb05a8972fe5f219b27b5b2bb2230a79ce79beb4c5c5e7ecc76d00000000000003f20000000000000002fffffffb00000000000005e70000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e40000000000000685000000000000000861db714e9ff987b6fedf00d01f9fea6db7c30632d6fc83b7bc9459d7192bc44a21a28b4c6619968bd8c20e95b0aaed7df2187fd310275347e0376a2cd7427db800000000000006cb0000000000000001fffffffb00000000000005e40000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e400000000000007970000000000000001";
175-
destroy(deserialize(bytes, ctx(&mut test)));
175+
let _ = destroy(deserialize(bytes, ctx(&mut test)));
176176
test_scenario::end(test);
177177
}
178178

@@ -198,42 +198,38 @@ module pyth::batch_price_attestation {
198198
attestation_count: 4,
199199
attestation_size: 149,
200200
price_infos: vector<PriceInfo>[
201-
price_info::new(
201+
price_info::new_price_info(
202202
1663680747,
203203
arrival_time,
204204
price_feed::new(
205205
price_identifier::from_byte_vec(x"c6c75c89f14810ec1c54c03ab8f1864a4c4032791f05747f560faec380a695d1"),
206206
price::new(i64::new(1557, false), 7, i64::new(5, true), 1663680740),
207207
price::new(i64::new(1500, false), 3, i64::new(5, true), 1663680740),
208-
),
209-
),
210-
price_info::new(
208+
) ),
209+
price_info::new_price_info(
211210
1663680747,
212211
arrival_time,
213212
price_feed::new(
214213
price_identifier::from_byte_vec(x"3b9551a68d01d954d6387aff4df1529027ffb2fee413082e509feb29cc4904fe"),
215214
price::new(i64::new(1050, false), 3, i64::new(5, true), 1663680745),
216215
price::new(i64::new(1483, false), 3, i64::new(5, true), 1663680745),
217-
),
218-
),
219-
price_info::new(
216+
) ),
217+
price_info::new_price_info(
220218
1663680747,
221219
arrival_time,
222220
price_feed::new(
223221
price_identifier::from_byte_vec(x"33832fad6e36eb05a8972fe5f219b27b5b2bb2230a79ce79beb4c5c5e7ecc76d"),
224222
price::new(i64::new(1010, false), 2, i64::new(5, true), 1663680745),
225223
price::new(i64::new(1511, false), 3, i64::new(5, true), 1663680745),
226-
),
227-
),
228-
price_info::new(
224+
) ),
225+
price_info::new_price_info(
229226
1663680747,
230227
arrival_time,
231228
price_feed::new(
232229
price_identifier::from_byte_vec(x"21a28b4c6619968bd8c20e95b0aaed7df2187fd310275347e0376a2cd7427db8"),
233230
price::new(i64::new(1739, false), 1, i64::new(5, true), 1663680745),
234231
price::new(i64::new(1508, false), 3, i64::new(5, true), 1663680745),
235-
),
236-
),
232+
) ),
237233
],
238234
};
239235

target_chains/sui/contracts/sources/data_source.move

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
11
module pyth::data_source {
2+
use sui::dynamic_field::{Self};
3+
use sui::object::{UID};
4+
use sui::tx_context::{TxContext};
5+
6+
use pyth::set::{Self};
7+
28
use wormhole::external_address::ExternalAddress;
39

10+
const KEY: vector<u8> = b"data_sources";
11+
412
struct DataSource has copy, drop, store {
513
emitter_chain: u64,
614
emitter_address: ExternalAddress,
715
}
816

17+
public fun new_data_source_registry(parent_id: &mut UID, ctx: &mut TxContext) {
18+
assert!(
19+
!dynamic_field::exists_(parent_id, KEY),
20+
0 // TODO - add custom error type
21+
);
22+
dynamic_field::add(
23+
parent_id,
24+
KEY,
25+
set::new<DataSource>(ctx)
26+
)
27+
}
28+
29+
public fun add(parent_id: &mut UID, data_source: DataSource) {
30+
assert!(
31+
!contains(parent_id, data_source),
32+
0 // TODO - add custom error message
33+
);
34+
set::add(
35+
dynamic_field::borrow_mut(parent_id, KEY),
36+
data_source
37+
)
38+
}
39+
40+
public fun empty(parent_id: &mut UID){
41+
set::empty<DataSource>(
42+
dynamic_field::borrow_mut(parent_id, KEY)
43+
)
44+
}
45+
46+
public fun contains(parent_id: &UID, data_source: DataSource): bool {
47+
let ref = dynamic_field::borrow(parent_id, KEY);
48+
set::contains<DataSource>(ref, data_source)
49+
}
50+
951
public fun new(emitter_chain: u64, emitter_address: ExternalAddress): DataSource {
1052
DataSource {
1153
emitter_chain: emitter_chain,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module pyth::event {
2+
use sui::event::{Self};
3+
use pyth::price_feed::{PriceFeed};
4+
5+
friend pyth::pyth;
6+
friend pyth::state;
7+
8+
struct PythInitializationEvent has copy, drop {}
9+
10+
/// Signifies that a price feed has been updated
11+
struct PriceFeedUpdateEvent has copy, store, drop {
12+
/// Value of the price feed
13+
price_feed: PriceFeed,
14+
/// Timestamp of the update
15+
timestamp: u64,
16+
}
17+
18+
public(friend) fun emit_price_feed_update(price_feed: PriceFeed, timestamp: u64) {
19+
event::emit(
20+
PriceFeedUpdateEvent {
21+
price_feed,
22+
timestamp,
23+
}
24+
);
25+
}
26+
27+
public(friend) fun emit_pyth_initialization_event() {
28+
event::emit(
29+
PythInitializationEvent {}
30+
);
31+
}
32+
33+
}

target_chains/sui/contracts/sources/price_feed.move

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,18 @@ module pyth::price_feed {
2323
}
2424
}
2525

26-
public fun get_price_identifier(price_feed: &PriceFeed): &PriceIdentifier {
27-
&price_feed.price_identifier
26+
public fun from(
27+
price_feed: &PriceFeed
28+
): PriceFeed {
29+
PriceFeed {
30+
price_identifier: price_feed.price_identifier,
31+
price: price_feed.price,
32+
ema_price: price_feed.ema_price,
33+
}
34+
}
35+
36+
public fun get_price_identifier(price_feed: &PriceFeed): PriceIdentifier {
37+
price_feed.price_identifier
2838
}
2939

3040
public fun get_price(price_feed: &PriceFeed): Price {

target_chains/sui/contracts/sources/price_info.move

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,104 @@
11
module pyth::price_info {
2-
use pyth::price_feed::PriceFeed;
2+
use sui::object::{Self, UID, ID};
3+
use sui::tx_context::{TxContext};
4+
use sui::dynamic_object_field::{Self};
5+
use sui::table::{Self};
36

7+
use pyth::price_feed::{Self, PriceFeed};
8+
use pyth::price_identifier::{PriceIdentifier};
9+
10+
const KEY: vector<u8> = b"price_info";
11+
12+
friend pyth::pyth;
13+
14+
/// Sui Object version of PriceInfo.
15+
/// Has a key and lives in global store.
16+
struct PriceInfoObject has key, store {
17+
id: UID,
18+
price_info: PriceInfo
19+
}
20+
21+
/// Copyable and droppable.
422
struct PriceInfo has copy, drop, store {
523
attestation_time: u64,
624
arrival_time: u64,
725
price_feed: PriceFeed,
826
}
927

10-
public fun new(attestation_time: u64, arrival_time: u64, price_feed: PriceFeed): PriceInfo {
28+
/// Creates a table which maps a PriceIdentifier to the
29+
/// UID (in bytes) of the corresponding Sui PriceInfoObject.
30+
public fun new_price_info_registry(parent_id: &mut UID, ctx: &mut TxContext) {
31+
assert!(
32+
!dynamic_object_field::exists_(parent_id, KEY),
33+
0 // TODO - add custom error message
34+
);
35+
dynamic_object_field::add(
36+
parent_id,
37+
KEY,
38+
table::new<PriceIdentifier, ID>(ctx)
39+
)
40+
}
41+
42+
public fun add(parent_id: &mut UID, price_identifier: PriceIdentifier, id: ID) {
43+
assert!(
44+
!contains(parent_id, price_identifier),
45+
0 // TODO - add custom error message
46+
);
47+
table::add(
48+
dynamic_object_field::borrow_mut(parent_id, KEY),
49+
price_identifier,
50+
id
51+
)
52+
}
53+
54+
public fun contains(parent_id: &UID, price_identifier: PriceIdentifier): bool {
55+
let ref = dynamic_object_field::borrow(parent_id, KEY);
56+
table::contains<PriceIdentifier, ID>(ref, price_identifier)
57+
}
58+
59+
public fun new_price_info_object(
60+
price_info: PriceInfo,
61+
ctx: &mut TxContext
62+
): PriceInfoObject {
63+
PriceInfoObject {
64+
id: object::new(ctx),
65+
price_info: price_info
66+
}
67+
}
68+
69+
public fun new_price_info(
70+
attestation_time: u64,
71+
arrival_time: u64,
72+
price_feed: PriceFeed,
73+
): PriceInfo {
1174
PriceInfo {
1275
attestation_time: attestation_time,
1376
arrival_time: arrival_time,
1477
price_feed: price_feed,
1578
}
1679
}
1780

81+
#[test_only]
82+
public fun destroy(price_info: PriceInfoObject){
83+
let PriceInfoObject {
84+
id: id,
85+
price_info: _,
86+
} = price_info;
87+
object::delete(id);
88+
}
89+
90+
public fun uid_to_inner(price_info: &PriceInfoObject): ID {
91+
object::uid_to_inner(&price_info.id)
92+
}
93+
94+
public fun get_price_info_from_price_info_object(price_info: &PriceInfoObject): PriceInfo {
95+
price_info.price_info
96+
}
97+
98+
public fun get_price_identifier(price_info: &PriceInfo): PriceIdentifier {
99+
price_feed::get_price_identifier(&price_info.price_feed)
100+
}
101+
18102
public fun get_price_feed(price_info: &PriceInfo): &PriceFeed {
19103
&price_info.price_feed
20104
}
@@ -26,4 +110,11 @@ module pyth::price_info {
26110
public fun get_arrival_time(price_info: &PriceInfo): u64 {
27111
price_info.arrival_time
28112
}
113+
114+
public(friend) fun update_price_info_object(
115+
price_info_object: &mut PriceInfoObject,
116+
price_info: PriceInfo
117+
) {
118+
price_info_object.price_info = price_info;
119+
}
29120
}

0 commit comments

Comments
 (0)