Skip to content

Commit b8a45a8

Browse files
authored
Merge pull request #3266 from matej-douro/matej/sui-contract-fixes
2 parents 8f238a2 + 17d5cd1 commit b8a45a8

File tree

6 files changed

+182
-143
lines changed

6 files changed

+182
-143
lines changed

lazer/contracts/sui/sources/i16.move

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public fun get_magnitude_if_negative(in: &I16): u64 {
4949

5050
public fun from_u16(from: u16): I16 {
5151
// Use the MSB to determine whether the number is negative or not.
52-
let from_u64 = (from as u64);
52+
let from_u64 = from as u64;
5353
let negative = (from_u64 >> 15) == 1;
5454
let magnitude = parse_magnitude(from_u64, negative);
5555

@@ -71,7 +71,7 @@ fun parse_magnitude(from: u64, negative: bool): u64 {
7171
#[test]
7272
fun test_max_positive_magnitude() {
7373
new(0x7FFF, false); // 32767
74-
assert!(&new((1<<15) - 1, false) == &from_u16(((1<<15) - 1) as u16), 1);
74+
assert!(&new((1 << 15) - 1, false) == &from_u16((1 << 15) - 1), 1);
7575
}
7676

7777
#[test]
@@ -83,7 +83,7 @@ fun test_magnitude_too_large_positive() {
8383
#[test]
8484
fun test_max_negative_magnitude() {
8585
new(0x8000, true); // 32768
86-
assert!(&new(1<<15, true) == &from_u16((1<<15) as u16), 1);
86+
assert!(&new(1 << 15, true) == &from_u16(1 << 15), 1);
8787
}
8888

8989
#[test]

lazer/contracts/sui/sources/i64.move

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fun parse_magnitude(from: u64, negative: bool): u64 {
7070
#[test]
7171
fun test_max_positive_magnitude() {
7272
new(0x7FFFFFFFFFFFFFFF, false);
73-
assert!(&new(1<<63 - 1, false) == &from_u64(1<<63 - 1), 1);
73+
assert!(&new((1 << 63) - 1, false) == &from_u64((1 << 63) - 1), 1);
7474
}
7575

7676
#[test]
@@ -82,7 +82,7 @@ fun test_magnitude_too_large_positive() {
8282
#[test]
8383
fun test_max_negative_magnitude() {
8484
new(0x8000000000000000, true);
85-
assert!(&new(1<<63, true) == &from_u64(1<<63), 1);
85+
assert!(&new(1 << 63, true) == &from_u64(1 << 63), 1);
8686
}
8787

8888
#[test]

lazer/contracts/sui/sources/pyth_lazer.move

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ public(package) fun verify_le_ecdsa_message(
5454
let pubkey = secp256k1_ecrecover(signature, payload, 0);
5555

5656
// Check if the recovered pubkey is in the trusted signers list
57-
let trusted_signers = state::get_trusted_signers(s);
57+
let trusted_signers = s.get_trusted_signers();
5858
let mut maybe_idx = state::find_signer_index(trusted_signers, &pubkey);
5959

6060
if (option::is_some(&maybe_idx)) {
6161
let idx = option::extract(&mut maybe_idx);
6262
let found_signer = &trusted_signers[idx];
63-
let expires_at = state::expires_at(found_signer);
64-
assert!(clock.timestamp_ms() < expires_at, ESignerExpired);
63+
let expires_at_ms = found_signer.expires_at_ms();
64+
assert!(clock.timestamp_ms() < expires_at_ms, ESignerExpired);
6565
} else {
6666
abort ESignerNotTrusted
6767
}
@@ -100,8 +100,8 @@ public fun parse_and_verify_le_ecdsa_update(s: &State, clock: &Clock, update: ve
100100
let payload_len = cursor.peel_u16();
101101
let payload = cursor.into_remainder_bytes();
102102

103-
// Validate expectedpayload length
104-
assert!((payload_len as u64) == payload.length(), EInvalidPayloadLength);
103+
// Validate expected payload length
104+
assert!(payload_len as u64 == payload.length(), EInvalidPayloadLength);
105105

106106
// Parse payload
107107
let mut payload_cursor = bcs::new(payload);

lazer/contracts/sui/sources/state.move

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module pyth_lazer::state;
22

3-
use pyth_lazer::admin::{Self, AdminCap};
3+
#[test_only]
4+
use pyth_lazer::admin;
5+
use pyth_lazer::admin::AdminCap;
46

57
const SECP256K1_COMPRESSED_PUBKEY_LEN: u64 = 33;
68
const EInvalidPubkeyLen: u64 = 1;
@@ -35,9 +37,9 @@ public fun public_key(info: &TrustedSignerInfo): &vector<u8> {
3537
&info.public_key
3638
}
3739

38-
/// Get the trusted signer's expiry timestamp (seconds since Unix epoch)
39-
public fun expires_at(info: &TrustedSignerInfo): u64 {
40-
info.expires_at
40+
/// Get the trusted signer's expiry timestamp, converted to milliseconds
41+
public fun expires_at_ms(info: &TrustedSignerInfo): u64 {
42+
info.expires_at * 1000
4143
}
4244

4345
/// Get the list of trusted signers
@@ -50,43 +52,42 @@ public fun get_trusted_signers(s: &State): &vector<TrustedSignerInfo> {
5052
/// - If the expired_at is set to zero, the trusted signer will be removed.
5153
/// - If the pubkey isn't found, it is added as a new trusted signer with the given expires_at.
5254
public fun update_trusted_signer(_: &AdminCap, s: &mut State, pubkey: vector<u8>, expires_at: u64) {
53-
assert!(vector::length(&pubkey) as u64 == SECP256K1_COMPRESSED_PUBKEY_LEN, EInvalidPubkeyLen);
55+
assert!(pubkey.length() == SECP256K1_COMPRESSED_PUBKEY_LEN, EInvalidPubkeyLen);
5456

5557
let mut maybe_idx = find_signer_index(&s.trusted_signers, &pubkey);
5658
if (expires_at == 0) {
57-
if (option::is_some(&maybe_idx)) {
58-
let idx = option::extract(&mut maybe_idx);
59+
if (maybe_idx.is_some()) {
60+
let idx = maybe_idx.extract();
5961
// Remove by swapping with last (order not preserved), discard removed value
60-
let _ = vector::swap_remove(&mut s.trusted_signers, idx);
62+
let _ = s.trusted_signers.swap_remove(idx);
6163
} else {
62-
option::destroy_none(maybe_idx);
64+
maybe_idx.destroy_none();
6365
abort ESignerNotFound
6466
};
6567
return
6668
};
6769

68-
if (option::is_some(&maybe_idx)) {
69-
let idx = option::extract(&mut maybe_idx);
70-
let info_ref = vector::borrow_mut(&mut s.trusted_signers, idx);
70+
if (maybe_idx.is_some()) {
71+
let idx = maybe_idx.extract();
72+
let info_ref = &mut s.trusted_signers[idx];
7173
info_ref.expires_at = expires_at
7274
} else {
73-
option::destroy_none(maybe_idx);
74-
vector::push_back(
75-
&mut s.trusted_signers,
76-
TrustedSignerInfo { public_key: pubkey, expires_at },
77-
)
75+
maybe_idx.destroy_none();
76+
s.trusted_signers.push_back(
77+
TrustedSignerInfo { public_key: pubkey, expires_at }
78+
);
7879
}
7980
}
8081

8182
public fun find_signer_index(
8283
signers: &vector<TrustedSignerInfo>,
8384
public_key: &vector<u8>,
8485
): Option<u64> {
85-
let len = vector::length(signers);
86+
let len = signers.length();
8687
let mut i: u64 = 0;
87-
while (i < (len as u64)) {
88-
let info_ref = vector::borrow(signers, i);
89-
if (*public_key(info_ref) == *public_key) {
88+
while (i < len) {
89+
let signer = &signers[i];
90+
if (signer.public_key() == public_key) {
9091
return option::some(i)
9192
};
9293
i = i + 1
@@ -106,7 +107,7 @@ public fun new_for_test(ctx: &mut TxContext): State {
106107
public fun destroy_for_test(s: State) {
107108
let State { id, trusted_signers } = s;
108109
let _ = trusted_signers;
109-
object::delete(id);
110+
id.delete();
110111
}
111112

112113
#[test]
@@ -120,16 +121,15 @@ public fun test_add_new_signer() {
120121

121122
update_trusted_signer(&admin_cap, &mut s, pk, expiry);
122123

123-
let signers_ref = get_trusted_signers(&s);
124-
assert!(vector::length(signers_ref) == 1, 100);
125-
let info = vector::borrow(signers_ref, 0);
126-
assert!(expires_at(info) == 123, 101);
127-
let got_pk = public_key(info);
128-
assert!(vector::length(got_pk) == (SECP256K1_COMPRESSED_PUBKEY_LEN as u64), 102);
129-
let State { id, trusted_signers } = s;
130-
let _ = trusted_signers;
131-
object::delete(id);
132-
admin::destroy_for_test(admin_cap);
124+
let signers_ref = s.get_trusted_signers();
125+
assert!(signers_ref.length() == 1, 100);
126+
let info = &signers_ref[0];
127+
assert!(info.expires_at == 123, 101);
128+
let got_pk = info.public_key();
129+
assert!(got_pk.length() == SECP256K1_COMPRESSED_PUBKEY_LEN, 102);
130+
131+
s.destroy_for_test();
132+
admin_cap.destroy_for_test();
133133
}
134134

135135
#[test]
@@ -151,14 +151,13 @@ public fun test_update_existing_signer_expiry() {
151151
2000,
152152
);
153153

154-
let signers_ref = get_trusted_signers(&s);
155-
assert!(vector::length(signers_ref) == 1, 110);
156-
let info = vector::borrow(signers_ref, 0);
157-
assert!(expires_at(info) == 2000, 111);
158-
let State { id, trusted_signers } = s;
159-
let _ = trusted_signers;
160-
object::delete(id);
161-
admin::destroy_for_test(admin_cap);
154+
let signers_ref = s.get_trusted_signers();
155+
assert!(signers_ref.length() == 1, 110);
156+
let info = &signers_ref[0];
157+
assert!(info.expires_at == 2000, 111);
158+
159+
s.destroy_for_test();
160+
admin_cap.destroy_for_test();
162161
}
163162

164163
#[test]
@@ -180,12 +179,11 @@ public fun test_remove_signer_by_zero_expiry() {
180179
0,
181180
);
182181

183-
let signers_ref = get_trusted_signers(&s);
184-
assert!(vector::length(signers_ref) == 0, 120);
185-
let State { id, trusted_signers } = s;
186-
let _ = trusted_signers;
187-
object::delete(id);
188-
admin::destroy_for_test(admin_cap);
182+
let signers_ref = s.get_trusted_signers();
183+
assert!(signers_ref.length() == 0, 120);
184+
185+
s.destroy_for_test();
186+
admin_cap.destroy_for_test();
189187
}
190188

191189
#[test, expected_failure(abort_code = EInvalidPubkeyLen)]
@@ -196,10 +194,9 @@ public fun test_invalid_pubkey_length_rejected() {
196194

197195
let short_pk = x"010203";
198196
update_trusted_signer(&admin_cap, &mut s, short_pk, 1);
199-
let State { id, trusted_signers } = s;
200-
let _ = trusted_signers;
201-
object::delete(id);
202-
admin::destroy_for_test(admin_cap);
197+
198+
s.destroy_for_test();
199+
admin_cap.destroy_for_test();
203200
}
204201

205202
#[test, expected_failure(abort_code = ESignerNotFound)]
@@ -215,8 +212,7 @@ public fun test_remove_nonexistent_signer_fails() {
215212
x"03aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
216213
0,
217214
);
218-
let State { id, trusted_signers } = s;
219-
let _ = trusted_signers;
220-
object::delete(id);
221-
admin::destroy_for_test(admin_cap);
215+
216+
s.destroy_for_test();
217+
admin_cap.destroy_for_test();
222218
}

lazer/contracts/sui/sources/update.move

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,40 @@ public fun channel(update: &Update): Channel {
2727
update.channel
2828
}
2929

30-
/// Get a reference to the feeds vector of the update
30+
/// Get a copy of the feeds vector of the update
3131
public fun feeds(update: &Update): vector<Feed> {
3232
update.feeds
3333
}
3434

35+
/// Get a reference to the feeds vector of the update
36+
public fun feeds_ref(update: &Update): &vector<Feed> {
37+
&update.feeds
38+
}
39+
3540
/// Parse the update from a BCS cursor containing the payload data
3641
/// This assumes the payload magic has already been validated and consumed
3742
public(package) fun parse_from_cursor(mut cursor: bcs::BCS): Update {
3843
// Parse timestamp
3944
let timestamp = cursor.peel_u64();
40-
45+
4146
// Parse channel
4247
let channel_value = cursor.peel_u8();
4348
let channel = channel::from_u8(channel_value);
44-
49+
4550
// Parse feeds
4651
let feed_count = cursor.peel_u8();
4752
let mut feeds = vector::empty<Feed>();
4853
let mut feed_i = 0;
49-
54+
5055
while (feed_i < feed_count) {
5156
let feed = feed::parse_from_cursor(&mut cursor);
5257
vector::push_back(&mut feeds, feed);
5358
feed_i = feed_i + 1;
5459
};
55-
60+
5661
// Verify no remaining bytes
5762
let remaining_bytes = cursor.into_remainder_bytes();
5863
assert!(remaining_bytes.length() == 0, EInvalidPayload);
59-
64+
6065
Update { timestamp, channel, feeds }
6166
}

0 commit comments

Comments
 (0)