diff --git a/contracts/round/ERRORS.md b/contracts/round/ERRORS.md index 164ad199..7bc459da 100644 --- a/contracts/round/ERRORS.md +++ b/contracts/round/ERRORS.md @@ -71,6 +71,9 @@ stay in sync with `contracts/round/src/types.rs`. | 37 | `NoValidBids` | `settle` | `round.winner` is `None` on a round whose status is `Cleared`. | Round has no winner to settle against. | Investigate: under current behavior the contract transitions to `Voided` (with all escrow refunded) when no valid bid is revealed, so this code should not appear in normal flow. If it does, the round is in an inconsistent state and warrants a manual review. | | 38 | `RoundFull` | `commit` | `round.bidders.len() >= MAX_BIDDERS` (500). | The round has reached its bidder cap. | Start a new round to accept further bidders. | | 39 | `InvalidLimit` | `get_bidders_page` | `limit == 0` or `limit > 100`. | Page size must be between 1 and 100 (inclusive). | Pass a `limit` in `[1, 100]`; use `next_cursor` from the previous page to walk larger rounds. | +| 40 | `SealRoundTooEarly` | `commit` | `seal_round < round.reveal_round`: the seal names a Drand round before the one the auction committed to open. | The sealed bid is locked to the wrong Drand round. | Reseal the bid to the round published in the `created` event (`reveal_round`) and commit again; no escrow was moved. | +| 41 | `SealRoundTooLate` | `commit` | `seal_round > round.reveal_round`: the seal names a Drand round after the one the auction committed to open. | The sealed bid is locked to the wrong Drand round. | Reseal the bid to the round published in the `created` event (`reveal_round`) and commit again; no escrow was moved. | +| 42 | `InvalidSealRoundZero` | `create_round`, `commit` | `reveal_round == 0` at round creation, or `seal_round == 0` at commit. A zero or overflowing round can never be published by the Drand chain. | The Drand round number is malformed. | Use a positive round the quicknet chain can actually publish (`genesis + period × R` must fit in `u64`); check before locking escrow. | ## Escrow accounting (40–49) diff --git a/contracts/round/src/drand.rs b/contracts/round/src/drand.rs index 2f716460..9ddd7b59 100644 --- a/contracts/round/src/drand.rs +++ b/contracts/round/src/drand.rs @@ -3,7 +3,7 @@ use soroban_sdk::{ Bytes, BytesN, Env, Vec, }; -use crate::types::GlobalConfig; +use crate::types::{Error, GlobalConfig, Round}; /// Verify a Drand `round` threshold signature on-chain. /// @@ -55,10 +55,31 @@ pub fn verify_round( /// Wall-clock time (unix seconds) at which Drand round `round` is published. /// -/// Saturating arithmetic: an absurdly large `round` clamps to `u64::MAX`, which -/// `create_round` then rejects via its deadline checks rather than panicking. -pub fn time_of_round(config: &GlobalConfig, round: u64) -> u64 { - config - .drand_genesis - .saturating_add(config.drand_period.saturating_mul(round)) +/// Returns `None` for a zero round or an intermediate product/sum that would +/// exceed `u64` — i.e. a round number the chain can never publish. Callers must +/// reject `None` instead of comparing a saturating placeholder against real +/// deadlines: an overflowing round must fail validation before any escrow is +/// locked, never silently map to the far future or the epoch. +pub fn checked_time_of_round(config: &GlobalConfig, round: u64) -> Option { + if round == 0 { + return None; + } + let offset = config.drand_period.checked_mul(round)?; + config.drand_genesis.checked_add(offset) +} + +/// Validate that a bidder's seal round equals the round the auction stored. +/// +/// The allowed reveal round is always `round.reveal_round` — the value the +/// operator committed to at `create_round` — never a caller-supplied value. A +/// seal for any other round cannot be committed (issue #376). Returns a stable +/// [`Error`] for each failure shape so SDK callers and integrators can branch +/// without parsing strings. +pub fn validate_seal_round(round: &Round, seal_round: u64) -> Result<(), Error> { + match seal_round { + 0 => Err(Error::InvalidSealRoundZero), + r if r == round.reveal_round => Ok(()), + r if r > round.reveal_round => Err(Error::SealRoundTooLate), + _ => Err(Error::SealRoundTooEarly), + } } diff --git a/contracts/round/src/error_paths.rs b/contracts/round/src/error_paths.rs index 0246da2f..d3344646 100644 --- a/contracts/round/src/error_paths.rs +++ b/contracts/round/src/error_paths.rs @@ -189,6 +189,7 @@ fn error_path_commit_closed() { &Bytes::from_array(&f.env, b"c"), &600, &Bytes::from_array(&f.env, b"id"), + &2_000, ), Error::CommitClosed, ); @@ -357,6 +358,7 @@ fn error_path_wrong_status() { &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id"), + &2_000, ), Error::WrongStatus, ); @@ -449,6 +451,7 @@ fn error_path_invalid_amount() { &Bytes::from_array(&f.env, b"c"), &0, &Bytes::from_array(&f.env, b"id"), + &2_000, ), Error::InvalidAmount, ); @@ -470,6 +473,7 @@ fn error_path_bid_exceeds_escrow() { &Bytes::from_array(&f.env, b"sealed"), &500, &Bytes::from_array(&f.env, b"id-blob"), + &VEC_ROUND, ); f.env.ledger().with_mut(|l| l.timestamp = t_reveal + 1); f.client.open_reveal(&id, &real_sig(&f.env)); @@ -527,6 +531,7 @@ fn error_path_round_full() { &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id"), + &2_000, ), Error::RoundFull, ); @@ -548,44 +553,77 @@ fn error_path_invalid_cursor() { assert_try_contract_err(f.client.try_get_bidders_page(&id, &Some(Bytes::new(&f.env)), &10), Error::InvalidCursor); } +/// Issue #376: a seal for a round earlier than the stored reveal round is +/// rejected with a stable error before any escrow is locked. #[test] -fn error_path_escrow_not_conserved() { - let (f, t_reveal, commit_deadline, reveal_deadline) = setup_drand(); +fn error_path_seal_round_too_early() { + let (f, _t_reveal, _commit_deadline, _reveal_deadline) = setup_drand(); let operator = Address::generate(&f.env); - let id = drand_round( - &f, - &operator, - commit_deadline, - reveal_deadline, - ClearingRule::HighestBid, + let id = drand_round(&f, &operator, _commit_deadline, _reveal_deadline, ClearingRule::HighestBid); + let bidder = funded_bidder(&f, 1_000); + let nonce = b32(&f.env, 0x01); + let h = commitment(&f.env, 500, &nonce); + assert_try_contract_err( + f.client.try_commit( + &id, + &bidder, + &h, + &Bytes::from_array(&f.env, b"sealed"), + &500, + &Bytes::from_array(&f.env, b"id-blob"), + &(VEC_ROUND - 1), + ), + Error::SealRoundTooEarly, ); - let alice = funded_bidder(&f, 1_000); - let a_nonce = commit_bid(&f, id, &alice, 500, 500, 0x01); - f.env.ledger().with_mut(|l| l.timestamp = t_reveal + 1); - f.client.open_reveal(&id, &real_sig(&f.env)); - f.client.reveal(&id, &alice, &500, &a_nonce); - f.env - .ledger() - .with_mut(|l| l.timestamp = reveal_deadline + 1); - f.client.clear(&id); - - // A winning bid above the winner's escrow would mint tokens out of escrow. - f.env.as_contract(&f.client.address, || { - let mut round = get_round(&f.env, id).unwrap(); - round.winning_bid = 900; - set_round(&f.env, id, &round); - }); + // No escrow was locked: the bid state must not exist. + assert_try_contract_err(f.client.try_get_bid_state(&id, &bidder), Error::BidNotFound); +} - assert_try_contract_err(f.client.try_settle(&id), Error::EscrowNotConserved); - assert_eq!( - f.usdc_token.balance(&operator), - 0, - "a rejected settle must not pay the operator" +/// Issue #376: a seal for a round later than the stored reveal round is +/// rejected with a stable error before any escrow is locked. +#[test] +fn error_path_seal_round_too_late() { + let (f, _t_reveal, _commit_deadline, _reveal_deadline) = setup_drand(); + let operator = Address::generate(&f.env); + let id = drand_round(&f, &operator, _commit_deadline, _reveal_deadline, ClearingRule::HighestBid); + let bidder = funded_bidder(&f, 1_000); + let nonce = b32(&f.env, 0x01); + let h = commitment(&f.env, 500, &nonce); + assert_try_contract_err( + f.client.try_commit( + &id, + &bidder, + &h, + &Bytes::from_array(&f.env, b"sealed"), + &500, + &Bytes::from_array(&f.env, b"id-blob"), + &(VEC_ROUND + 1), + ), + Error::SealRoundTooLate, ); - assert_eq!( - f.usdc_token.balance(&f.client.address), - 500, - "a rejected settle must leave every escrow locked" + assert_try_contract_err(f.client.try_get_bid_state(&id, &bidder), Error::BidNotFound); +} + +/// Issue #376: a zero seal round is malformed and rejected before escrow. +#[test] +fn error_path_invalid_seal_round_zero() { + let f = setup(); + let operator = Address::generate(&f.env); + let id = open_round(&f, &operator); + let bidder = funded_bidder(&f, 1_000); + let nonce = b32(&f.env, 0x01); + let h = commitment(&f.env, 500, &nonce); + assert_try_contract_err( + f.client.try_commit( + &id, + &bidder, + &h, + &Bytes::from_array(&f.env, b"sealed"), + &500, + &Bytes::from_array(&f.env, b"id-blob"), + &0, + ), + Error::InvalidSealRoundZero, ); - assert_eq!(f.client.get_round(&id).status, Status::Cleared); + assert_try_contract_err(f.client.try_get_bid_state(&id, &bidder), Error::BidNotFound); } diff --git a/contracts/round/src/lib.rs b/contracts/round/src/lib.rs index ebb09891..6deeaff2 100644 --- a/contracts/round/src/lib.rs +++ b/contracts/round/src/lib.rs @@ -82,14 +82,19 @@ impl SubRosaRound { bump_instance(&env); if reveal_round == 0 { - return Err(Error::InvalidAmount); + return Err(Error::InvalidSealRoundZero); } if auditor_pubkey.len() > MAX_AUDITOR_PUBKEY { return Err(Error::PayloadTooLarge); } let now = env.ledger().timestamp(); - let t_reveal = drand::time_of_round(&config, reveal_round); + // Reject a reveal round the quicknet chain can never publish before any + // deadline comparison: genesis + period×R must fit in u64. A saturating + // placeholder here would let an overflowing round pass the deadline + // checks and strand the round past the void grace window. + let t_reveal = drand::checked_time_of_round(&config, reveal_round) + .ok_or(Error::InvalidSealRoundZero)?; // Commit must close strictly before R is published, otherwise a bidder // could decrypt others' sealed bids before committing. @@ -134,6 +139,9 @@ impl SubRosaRound { /// - `escrow` is a public USDC budget and an upper bound on the sealed bid; /// locked now so the winner can always pay. /// - `auditor_blob` is the bidder identity encrypted to the auditor key. + /// - `seal_round` must equal the round's stored `reveal_round`: the seal is + /// only meaningful for the Drand round this auction committed to open. + /// Mismatched seals are rejected before any escrow is locked. pub fn commit( env: Env, round_id: u64, @@ -142,6 +150,7 @@ impl SubRosaRound { ciphertext: Bytes, escrow: i128, auditor_blob: Bytes, + seal_round: u64, ) -> Result<(), Error> { bidder.require_auth(); let config = get_config(&env)?; @@ -165,6 +174,11 @@ impl SubRosaRound { if ciphertext.len() > MAX_CIPHERTEXT || auditor_blob.len() > MAX_AUDITOR_BLOB { return Err(Error::PayloadTooLarge); } + // The allowed reveal round is the one stored on the auction, not a + // caller-supplied value. Rejecting here — before the escrow transfer — + // means a seal for a different Drand round can never lock funds and the + // bidder keeps their full error budget for honest resubmission. + drand::validate_seal_round(&round, seal_round)?; let usdc = token::Client::new(&env, &config.usdc); let contract = env.current_contract_address(); diff --git a/contracts/round/src/test.rs b/contracts/round/src/test.rs index 8262208a..d74c18f1 100644 --- a/contracts/round/src/test.rs +++ b/contracts/round/src/test.rs @@ -202,6 +202,7 @@ fn commitment(env: &Env, value: i128, nonce: &BytesN<32>) -> BytesN<32> { fn commit_bid(f: &Fixture, round_id: u64, bidder: &Address, value: i128, escrow: i128, nonce_byte: u8) -> BytesN<32> { let nonce = b32(&f.env, nonce_byte); let h = commitment(&f.env, value, &nonce); + let round = f.client.get_round(&round_id); f.client.commit( &round_id, bidder, @@ -209,6 +210,7 @@ fn commit_bid(f: &Fixture, round_id: u64, bidder: &Address, value: i128, escrow: &Bytes::from_array(&f.env, b"sealed"), &escrow, &Bytes::from_array(&f.env, b"id-blob"), + &round.reveal_round, ); nonce } @@ -331,13 +333,27 @@ fn create_round_rejects_deadline_in_past() { assert!(res.is_err()); } +/// Issue #376: a reveal round the quicknet chain can never publish — genesis + +/// period×R overflows u64 — must fail create_round instead of saturating into +/// a far-future deadline that would strand the round past the void window. +#[test] +fn create_round_rejects_overflowing_reveal_round() { + let f = setup(); + let operator = Address::generate(&f.env); + let res = f.client.try_create_round( + &operator, &b32(&f.env, 1), &u64::MAX, &ClearingRule::HighestBid, + &1_500, &2_500, &Bytes::from_array(&f.env, b"a"), + ); + assert!(res.is_err()); +} + #[test] fn commit_locks_escrow() { let f = setup(); let operator = Address::generate(&f.env); let id = open_round(&f, &operator); let bidder = funded_bidder(&f, 1_000); - f.client.commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"ciphertext"), &600, &Bytes::from_array(&f.env, b"id-blob")); + f.client.commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"ciphertext"), &600, &Bytes::from_array(&f.env, b"id-blob"), &2_000); assert_eq!(f.usdc_token.balance(&bidder), 400); assert_eq!(f.usdc_token.balance(&f.client.address), 600); let round = f.client.get_round(&id); @@ -354,9 +370,9 @@ fn get_bidders_returns_ordered_index() { let id = open_round(&f, &operator); let a = funded_bidder(&f, 1_000); let b = funded_bidder(&f, 1_000); - f.client.commit(&id, &a, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id")); - f.client.commit(&id, &b, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &200, &Bytes::from_array(&f.env, b"id")); - f.client.commit(&id, &a, &b32(&f.env, 3), &Bytes::from_array(&f.env, b"c"), &150, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &a, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id"), &2_000); + f.client.commit(&id, &b, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &200, &Bytes::from_array(&f.env, b"id"), &2_000); + f.client.commit(&id, &a, &b32(&f.env, 3), &Bytes::from_array(&f.env, b"c"), &150, &Bytes::from_array(&f.env, b"id"), &2_000); let bidders = f.client.get_bidders(&id); assert_eq!(bidders.len(), 2); assert_eq!(bidders.get(0).unwrap(), a); @@ -369,8 +385,8 @@ fn commit_overwrite_before_close_refunds_prior_escrow() { let operator = Address::generate(&f.env); let id = open_round(&f, &operator); let bidder = funded_bidder(&f, 1_000); - f.client.commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c1"), &600, &Bytes::from_array(&f.env, b"id")); - f.client.commit(&id, &bidder, &b32(&f.env, 9), &Bytes::from_array(&f.env, b"c2"), &200, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c1"), &600, &Bytes::from_array(&f.env, b"id"), &2_000); + f.client.commit(&id, &bidder, &b32(&f.env, 9), &Bytes::from_array(&f.env, b"c2"), &200, &Bytes::from_array(&f.env, b"id"), &2_000); assert_eq!(f.usdc_token.balance(&bidder), 800); assert_eq!(f.usdc_token.balance(&f.client.address), 200); assert_eq!(f.client.get_round(&id).bidders.len(), 1); @@ -383,7 +399,7 @@ fn commit_after_deadline_rejected() { let id = open_round(&f, &operator); let bidder = funded_bidder(&f, 1_000); f.env.ledger().with_mut(|l| l.timestamp = 1_600); - let res = f.client.try_commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c"), &600, &Bytes::from_array(&f.env, b"id")); + let res = f.client.try_commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c"), &600, &Bytes::from_array(&f.env, b"id"), &2_000); assert!(res.is_err()); } @@ -393,7 +409,7 @@ fn commit_zero_escrow_rejected() { let operator = Address::generate(&f.env); let id = open_round(&f, &operator); let bidder = funded_bidder(&f, 1_000); - let res = f.client.try_commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c"), &0, &Bytes::from_array(&f.env, b"id")); + let res = f.client.try_commit(&id, &bidder, &b32(&f.env, 7), &Bytes::from_array(&f.env, b"c"), &0, &Bytes::from_array(&f.env, b"id"), &2_000); assert!(res.is_err()); } @@ -404,8 +420,8 @@ fn void_after_grace_refunds_all() { let id = open_round(&f, &operator); let a = funded_bidder(&f, 1_000); let bbidder = funded_bidder(&f, 1_000); - f.client.commit(&id, &a, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &300, &Bytes::from_array(&f.env, b"id")); - f.client.commit(&id, &bbidder, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &500, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &a, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &300, &Bytes::from_array(&f.env, b"id"), &2_000); + f.client.commit(&id, &bbidder, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &500, &Bytes::from_array(&f.env, b"id"), &2_000); f.env.ledger().with_mut(|l| l.timestamp = 2_500 + 3_600 + 1); f.client.void(&id); assert_eq!(f.usdc_token.balance(&a), 1_000); @@ -646,7 +662,7 @@ fn repeated_overwrites_escrow_conservation() { let initial: i128 = 2_000; let escrows: &[i128] = &[500, 300, 800, 100]; for (i, &escrow) in escrows.iter().enumerate() { - f.client.commit(&id, &bidder, &b32(&f.env, (i + 1) as u8), &Bytes::from_array(&f.env, b"c"), &escrow, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &bidder, &b32(&f.env, (i + 1) as u8), &Bytes::from_array(&f.env, b"c"), &escrow, &Bytes::from_array(&f.env, b"id"), &2_000); let sum = f.usdc_token.balance(&bidder) + f.usdc_token.balance(&f.client.address); assert_eq!(sum, initial, "conservation violated after overwrite #{}", i + 1); assert_eq!(f.usdc_token.balance(&f.client.address), escrow, "contract must hold latest escrow after #{}", i + 1); @@ -660,8 +676,8 @@ fn overwrite_to_larger_escrow_conserves_tokens() { let operator = Address::generate(&f.env); let id = open_round(&f, &operator); let bidder = funded_bidder(&f, 1_000); - f.client.commit(&id, &bidder, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &200, &Bytes::from_array(&f.env, b"id")); - f.client.commit(&id, &bidder, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &700, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &bidder, &b32(&f.env, 1), &Bytes::from_array(&f.env, b"c"), &200, &Bytes::from_array(&f.env, b"id"), &2_000); + f.client.commit(&id, &bidder, &b32(&f.env, 2), &Bytes::from_array(&f.env, b"c"), &700, &Bytes::from_array(&f.env, b"id"), &2_000); assert_eq!(f.usdc_token.balance(&bidder), 300); assert_eq!(f.usdc_token.balance(&f.client.address), 700); assert_eq!(f.usdc_token.balance(&bidder) + f.usdc_token.balance(&f.client.address), 1_000); @@ -850,7 +866,7 @@ fn commit_on_settled_round_rejected() { f.client.settle(&id); let late = funded_bidder(&f, 1_000); - assert!(f.client.try_commit(&id, &late, &b32(&f.env, 0x77), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id")).is_err(), + assert!(f.client.try_commit(&id, &late, &b32(&f.env, 0x77), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id"), &2_000).is_err(), "commit on settled round must be rejected"); } @@ -1117,8 +1133,8 @@ fn full_lifecycle_real_drand_signature() { let a_value: i128 = 700; let b_value: i128 = 500; - f.client.commit(&id, &alice, &commitment(&f.env, a_value, &a_nonce), &Bytes::from_array(&f.env, b"sealedA"), &1_000, &Bytes::from_array(&f.env, b"idA")); - f.client.commit(&id, &bob, &commitment(&f.env, b_value, &b_nonce), &Bytes::from_array(&f.env, b"sealedB"), &1_000, &Bytes::from_array(&f.env, b"idB")); + f.client.commit(&id, &alice, &commitment(&f.env, a_value, &a_nonce), &Bytes::from_array(&f.env, b"sealedA"), &1_000, &Bytes::from_array(&f.env, b"idA"), &VEC_ROUND); + f.client.commit(&id, &bob, &commitment(&f.env, b_value, &b_nonce), &Bytes::from_array(&f.env, b"sealedB"), &1_000, &Bytes::from_array(&f.env, b"idB"), &VEC_ROUND); f.env.ledger().with_mut(|l| l.timestamp = t_reveal + 1); let sig = hexn::<96>(&f.env, VEC_SIG_G1); @@ -1158,7 +1174,7 @@ fn round_with_n_bidders(n: u32) -> (Fixture, u64, Vec
) { let mut all = Vec::new(&f.env); for i in 0..n { let bidder = funded_bidder(&f, 1_000 + i as i128); - f.client.commit(&id, &bidder, &b32(&f.env, (i + 1) as u8), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id")); + f.client.commit(&id, &bidder, &b32(&f.env, (i + 1) as u8), &Bytes::from_array(&f.env, b"c"), &100, &Bytes::from_array(&f.env, b"id"), &2_000); all.push_back(bidder); } (f, id, all) diff --git a/contracts/round/test_snapshots/test/active_round_seal_ttl_covers_reveal_window.1.json b/contracts/round/test_snapshots/test/active_round_seal_ttl_covers_reveal_window.1.json index 7d1893e3..a5a87255 100644 --- a/contracts/round/test_snapshots/test/active_round_seal_ttl_covers_reveal_window.1.json +++ b/contracts/round/test_snapshots/test/active_round_seal_ttl_covers_reveal_window.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/clear_and_settle_work_after_seal_expiry.1.json b/contracts/round/test_snapshots/test/clear_and_settle_work_after_seal_expiry.1.json index 3ffad69a..b781843d 100644 --- a/contracts/round/test_snapshots/test/clear_and_settle_work_after_seal_expiry.1.json +++ b/contracts/round/test_snapshots/test/clear_and_settle_work_after_seal_expiry.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/commit_locks_escrow.1.json b/contracts/round/test_snapshots/test/commit_locks_escrow.1.json index 5af8fd7b..851eccfc 100644 --- a/contracts/round/test_snapshots/test/commit_locks_escrow.1.json +++ b/contracts/round/test_snapshots/test/commit_locks_escrow.1.json @@ -163,6 +163,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/commit_on_settled_round_rejected.1.json b/contracts/round/test_snapshots/test/commit_on_settled_round_rejected.1.json index 11605271..8c66ea2c 100644 --- a/contracts/round/test_snapshots/test/commit_on_settled_round_rejected.1.json +++ b/contracts/round/test_snapshots/test/commit_on_settled_round_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/commit_overwrite_before_close_refunds_prior_escrow.1.json b/contracts/round/test_snapshots/test/commit_overwrite_before_close_refunds_prior_escrow.1.json index 5bc657c8..8d3baa34 100644 --- a/contracts/round/test_snapshots/test/commit_overwrite_before_close_refunds_prior_escrow.1.json +++ b/contracts/round/test_snapshots/test/commit_overwrite_before_close_refunds_prior_escrow.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -224,6 +227,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/contract_balance_zero_after_settle.1.json b/contracts/round/test_snapshots/test/contract_balance_zero_after_settle.1.json index e0eb0e43..800d4acd 100644 --- a/contracts/round/test_snapshots/test/contract_balance_zero_after_settle.1.json +++ b/contracts/round/test_snapshots/test/contract_balance_zero_after_settle.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/contract_balance_zero_after_void.1.json b/contracts/round/test_snapshots/test/contract_balance_zero_after_void.1.json index 9b75d202..9022d60e 100644 --- a/contracts/round/test_snapshots/test/contract_balance_zero_after_void.1.json +++ b/contracts/round/test_snapshots/test/contract_balance_zero_after_void.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/create_round_rejects_overflowing_reveal_round.1.json b/contracts/round/test_snapshots/test/create_round_rejects_overflowing_reveal_round.1.json new file mode 100644 index 00000000..8fd6b355 --- /dev/null +++ b/contracts/round/test_snapshots/test/create_round_rejects_overflowing_reveal_round.1.json @@ -0,0 +1,330 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Config" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "drand_genesis" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "drand_period" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "drand_pubkey" + }, + "val": { + "bytes": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + { + "key": { + "symbol": "dst" + }, + "val": { + "bytes": "424c535f5349475f424c53313233383147315f584d443a5348412d3235365f535357555f524f5f4e554c5f" + } + }, + { + "key": { + "symbol": "g2_neg_generator" + }, + "val": { + "bytes": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + { + "key": { + "symbol": "usdc" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 1036800 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/round/test_snapshots/test/double_settle_rejected.1.json b/contracts/round/test_snapshots/test/double_settle_rejected.1.json index 85aaa940..96f22e19 100644 --- a/contracts/round/test_snapshots/test/double_settle_rejected.1.json +++ b/contracts/round/test_snapshots/test/double_settle_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/double_void_rejected.1.json b/contracts/round/test_snapshots/test/double_void_rejected.1.json index b47b5df5..7aa86b5b 100644 --- a/contracts/round/test_snapshots/test/double_void_rejected.1.json +++ b/contracts/round/test_snapshots/test/double_void_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/duplicate_reveal_rejected.1.json b/contracts/round/test_snapshots/test/duplicate_reveal_rejected.1.json index dc785945..858585b4 100644 --- a/contracts/round/test_snapshots/test/duplicate_reveal_rejected.1.json +++ b/contracts/round/test_snapshots/test/duplicate_reveal_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_already_cleared.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_already_cleared.1.json index 5db58763..24fb8b6b 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_already_cleared.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_already_cleared.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_already_revealed.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_already_revealed.1.json index 34799136..fbf66266 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_already_revealed.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_already_revealed.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_already_settled.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_already_settled.1.json index 0e774778..40ecc9bb 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_already_settled.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_already_settled.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_bid_exceeds_escrow.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_bid_exceeds_escrow.1.json index 43048d45..8d338e2b 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_bid_exceeds_escrow.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_bid_exceeds_escrow.1.json @@ -163,6 +163,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_hash_mismatch.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_hash_mismatch.1.json index 89f53b2a..fc6e0d8a 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_hash_mismatch.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_hash_mismatch.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_invalid_drand_signature.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_invalid_drand_signature.1.json index e9142dab..130373b3 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_invalid_drand_signature.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_invalid_drand_signature.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155654 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_invalid_seal_round_zero.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_invalid_seal_round_zero.1.json new file mode 100644 index 00000000..351f0d99 --- /dev/null +++ b/contracts/round/test_snapshots/test/error_paths/error_path_invalid_seal_round_zero.1.json @@ -0,0 +1,691 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "create_round", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "bytes": "0101010101010101010101010101010101010101010101010101010101010101" + }, + { + "u64": 2000 + }, + { + "vec": [ + { + "symbol": "HighestBid" + } + ] + }, + { + "u64": 1500 + }, + { + "u64": 2500 + }, + { + "bytes": "61756469746f722d7075626b6579" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "auditor_pubkey" + }, + "val": { + "bytes": "61756469746f722d7075626b6579" + } + }, + { + "key": { + "symbol": "bidders" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "clearing_rule" + }, + "val": { + "vec": [ + { + "symbol": "HighestBid" + } + ] + } + }, + { + "key": { + "symbol": "commit_deadline" + }, + "val": { + "u64": 1500 + } + }, + { + "key": { + "symbol": "item_ref" + }, + "val": { + "bytes": "0101010101010101010101010101010101010101010101010101010101010101" + } + }, + { + "key": { + "symbol": "operator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "reveal_deadline" + }, + "val": { + "u64": 2500 + } + }, + { + "key": { + "symbol": "reveal_round" + }, + "val": { + "u64": 2000 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Open" + } + ] + } + }, + { + "key": { + "symbol": "winner" + }, + "val": "void" + }, + { + "key": { + "symbol": "winning_bid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Config" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "drand_genesis" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "drand_period" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "drand_pubkey" + }, + "val": { + "bytes": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + { + "key": { + "symbol": "dst" + }, + "val": { + "bytes": "424c535f5349475f424c53313233383147315f584d443a5348412d3235365f535357555f524f5f4e554c5f" + } + }, + { + "key": { + "symbol": "g2_neg_generator" + }, + "val": { + "bytes": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + { + "key": { + "symbol": "usdc" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "RoundCounter" + } + ] + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 1036800 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_not_cleared.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_not_cleared.1.json index 7e554036..89887a0f 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_not_cleared.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_not_cleared.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_already_open.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_already_open.1.json index 89f53b2a..fc6e0d8a 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_already_open.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_already_open.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_not_open.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_not_open.1.json index 12eb5388..6061f3c4 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_not_open.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_not_open.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_still_open.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_still_open.1.json index 89f53b2a..fc6e0d8a 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_still_open.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_still_open.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_window_closed.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_window_closed.1.json index d17ee211..b1beb2b1 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_reveal_window_closed.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_reveal_window_closed.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_round_voided.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_round_voided.1.json index 72d40272..746c3d6a 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_round_voided.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_round_voided.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_early.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_early.1.json new file mode 100644 index 00000000..b7577c1a --- /dev/null +++ b/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_early.1.json @@ -0,0 +1,691 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "create_round", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "bytes": "abababababababababababababababababababababababababababababababab" + }, + { + "u64": 29155653 + }, + { + "vec": [ + { + "symbol": "HighestBid" + } + ] + }, + { + "u64": 1780270226 + }, + { + "u64": 1780270526 + }, + { + "bytes": "61756469746f72" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1780270126, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "auditor_pubkey" + }, + "val": { + "bytes": "61756469746f72" + } + }, + { + "key": { + "symbol": "bidders" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "clearing_rule" + }, + "val": { + "vec": [ + { + "symbol": "HighestBid" + } + ] + } + }, + { + "key": { + "symbol": "commit_deadline" + }, + "val": { + "u64": 1780270226 + } + }, + { + "key": { + "symbol": "item_ref" + }, + "val": { + "bytes": "abababababababababababababababababababababababababababababababab" + } + }, + { + "key": { + "symbol": "operator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "reveal_deadline" + }, + "val": { + "u64": 1780270526 + } + }, + { + "key": { + "symbol": "reveal_round" + }, + "val": { + "u64": 29155653 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Open" + } + ] + } + }, + { + "key": { + "symbol": "winner" + }, + "val": "void" + }, + { + "key": { + "symbol": "winning_bid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Config" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "drand_genesis" + }, + "val": { + "u64": 1692803367 + } + }, + { + "key": { + "symbol": "drand_period" + }, + "val": { + "u64": 3 + } + }, + { + "key": { + "symbol": "drand_pubkey" + }, + "val": { + "bytes": "03cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a01a714f2edb74119a2f2b0d5a7c75ba902d163700a61bc224ededd8e63aef7be1aaf8e93d7a9718b047ccddb3eb5d68b0e5db2b6bfbb01c867749cadffca88b36c24f3012ba09fc4d3022c5c37dce0f977d3adb5d183c7477c442b1f04515273" + } + }, + { + "key": { + "symbol": "dst" + }, + "val": { + "bytes": "424c535f5349475f424c53313233383147315f584d443a5348412d3235365f535357555f524f5f4e554c5f" + } + }, + { + "key": { + "symbol": "g2_neg_generator" + }, + "val": { + "bytes": "13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb813fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed0d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa" + } + }, + { + "key": { + "symbol": "usdc" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "RoundCounter" + } + ] + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 1036800 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_late.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_late.1.json new file mode 100644 index 00000000..b7577c1a --- /dev/null +++ b/contracts/round/test_snapshots/test/error_paths/error_path_seal_round_too_late.1.json @@ -0,0 +1,691 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "create_round", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "bytes": "abababababababababababababababababababababababababababababababab" + }, + { + "u64": 29155653 + }, + { + "vec": [ + { + "symbol": "HighestBid" + } + ] + }, + { + "u64": 1780270226 + }, + { + "u64": 1780270526 + }, + { + "bytes": "61756469746f72" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1780270126, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Round" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "auditor_pubkey" + }, + "val": { + "bytes": "61756469746f72" + } + }, + { + "key": { + "symbol": "bidders" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "clearing_rule" + }, + "val": { + "vec": [ + { + "symbol": "HighestBid" + } + ] + } + }, + { + "key": { + "symbol": "commit_deadline" + }, + "val": { + "u64": 1780270226 + } + }, + { + "key": { + "symbol": "item_ref" + }, + "val": { + "bytes": "abababababababababababababababababababababababababababababababab" + } + }, + { + "key": { + "symbol": "operator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "reveal_deadline" + }, + "val": { + "u64": 1780270526 + } + }, + { + "key": { + "symbol": "reveal_round" + }, + "val": { + "u64": 29155653 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Open" + } + ] + } + }, + { + "key": { + "symbol": "winner" + }, + "val": "void" + }, + { + "key": { + "symbol": "winning_bid" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Config" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "drand_genesis" + }, + "val": { + "u64": 1692803367 + } + }, + { + "key": { + "symbol": "drand_period" + }, + "val": { + "u64": 3 + } + }, + { + "key": { + "symbol": "drand_pubkey" + }, + "val": { + "bytes": "03cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a01a714f2edb74119a2f2b0d5a7c75ba902d163700a61bc224ededd8e63aef7be1aaf8e93d7a9718b047ccddb3eb5d68b0e5db2b6bfbb01c867749cadffca88b36c24f3012ba09fc4d3022c5c37dce0f977d3adb5d183c7477c442b1f04515273" + } + }, + { + "key": { + "symbol": "dst" + }, + "val": { + "bytes": "424c535f5349475f424c53313233383147315f584d443a5348412d3235365f535357555f524f5f4e554c5f" + } + }, + { + "key": { + "symbol": "g2_neg_generator" + }, + "val": { + "bytes": "13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb813fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed0d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa" + } + }, + { + "key": { + "symbol": "usdc" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "RoundCounter" + } + ] + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 1036800 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 1036800 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/round/test_snapshots/test/error_paths/error_path_wrong_status.1.json b/contracts/round/test_snapshots/test/error_paths/error_path_wrong_status.1.json index 236eabc8..146484f9 100644 --- a/contracts/round/test_snapshots/test/error_paths/error_path_wrong_status.1.json +++ b/contracts/round/test_snapshots/test/error_paths/error_path_wrong_status.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/full_lifecycle_real_drand_signature.1.json b/contracts/round/test_snapshots/test/full_lifecycle_real_drand_signature.1.json index e628a581..75335851 100644 --- a/contracts/round/test_snapshots/test/full_lifecycle_real_drand_signature.1.json +++ b/contracts/round/test_snapshots/test/full_lifecycle_real_drand_signature.1.json @@ -188,6 +188,9 @@ }, { "bytes": "696441" + }, + { + "u64": 29155653 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "696442" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_cursor_at_total.1.json b/contracts/round/test_snapshots/test/get_bidders_page_cursor_at_total.1.json index b873a454..6b6d1ce4 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_cursor_at_total.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_cursor_at_total.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_cursor_beyond_total.1.json b/contracts/round/test_snapshots/test/get_bidders_page_cursor_beyond_total.1.json index b873a454..6b6d1ce4 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_cursor_beyond_total.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_cursor_beyond_total.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_exact.1.json b/contracts/round/test_snapshots/test/get_bidders_page_exact.1.json index b873a454..6b6d1ce4 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_exact.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_exact.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_final.1.json b/contracts/round/test_snapshots/test/get_bidders_page_final.1.json index f6fc543a..45eb9f67 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_final.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_final.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -421,6 +430,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -507,6 +519,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_multi.1.json b/contracts/round/test_snapshots/test/get_bidders_page_multi.1.json index 7adc5988..c2d25e5d 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_multi.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_multi.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -421,6 +430,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -507,6 +519,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -593,6 +608,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -679,6 +697,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -765,6 +786,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -851,6 +875,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -937,6 +964,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_partial.1.json b/contracts/round/test_snapshots/test/get_bidders_page_partial.1.json index c546d1bc..3828a779 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_partial.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_partial.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -421,6 +430,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -507,6 +519,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_page_preserves_order.1.json b/contracts/round/test_snapshots/test/get_bidders_page_preserves_order.1.json index 463e9151..5c161ea1 100644 --- a/contracts/round/test_snapshots/test/get_bidders_page_preserves_order.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_page_preserves_order.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -421,6 +430,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -507,6 +519,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_returns_ordered_index.1.json b/contracts/round/test_snapshots/test/get_bidders_returns_ordered_index.1.json index af672072..b1af2162 100644 --- a/contracts/round/test_snapshots/test/get_bidders_returns_ordered_index.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_returns_ordered_index.1.json @@ -188,6 +188,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -310,6 +316,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/get_bidders_still_returns_full_list.1.json b/contracts/round/test_snapshots/test/get_bidders_still_returns_full_list.1.json index c546d1bc..3828a779 100644 --- a/contracts/round/test_snapshots/test/get_bidders_still_returns_full_list.1.json +++ b/contracts/round/test_snapshots/test/get_bidders_still_returns_full_list.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -335,6 +341,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -421,6 +430,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -507,6 +519,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_table_driven.1.json b/contracts/round/test_snapshots/test/highest_bid_table_driven.1.json index 211d483d..aca84953 100644 --- a/contracts/round/test_snapshots/test/highest_bid_table_driven.1.json +++ b/contracts/round/test_snapshots/test/highest_bid_table_driven.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_table_driven.2.json b/contracts/round/test_snapshots/test/highest_bid_table_driven.2.json index 2d2e1aa3..0fe20352 100644 --- a/contracts/round/test_snapshots/test/highest_bid_table_driven.2.json +++ b/contracts/round/test_snapshots/test/highest_bid_table_driven.2.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_table_driven.3.json b/contracts/round/test_snapshots/test/highest_bid_table_driven.3.json index 243c9369..7e1231fe 100644 --- a/contracts/round/test_snapshots/test/highest_bid_table_driven.3.json +++ b/contracts/round/test_snapshots/test/highest_bid_table_driven.3.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_table_driven.4.json b/contracts/round/test_snapshots/test/highest_bid_table_driven.4.json index 41f074b3..d17f1a37 100644 --- a/contracts/round/test_snapshots/test/highest_bid_table_driven.4.json +++ b/contracts/round/test_snapshots/test/highest_bid_table_driven.4.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.1.json b/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.1.json index 27166704..3d7d31b5 100644 --- a/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.1.json +++ b/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.2.json b/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.2.json index 14668e4d..74100190 100644 --- a/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.2.json +++ b/contracts/round/test_snapshots/test/highest_bid_tie_is_deterministic_first_inserter_wins.2.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/late_reveal_rejected_after_window_even_with_seal_present.1.json b/contracts/round/test_snapshots/test/late_reveal_rejected_after_window_even_with_seal_present.1.json index 310ee872..255689bc 100644 --- a/contracts/round/test_snapshots/test/late_reveal_rejected_after_window_even_with_seal_present.1.json +++ b/contracts/round/test_snapshots/test/late_reveal_rejected_after_window_even_with_seal_present.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/lowest_bid_table_driven.1.json b/contracts/round/test_snapshots/test/lowest_bid_table_driven.1.json index 59bad030..936a13db 100644 --- a/contracts/round/test_snapshots/test/lowest_bid_table_driven.1.json +++ b/contracts/round/test_snapshots/test/lowest_bid_table_driven.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/lowest_bid_table_driven.2.json b/contracts/round/test_snapshots/test/lowest_bid_table_driven.2.json index 0a694013..7119cb0f 100644 --- a/contracts/round/test_snapshots/test/lowest_bid_table_driven.2.json +++ b/contracts/round/test_snapshots/test/lowest_bid_table_driven.2.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/lowest_bid_table_driven.3.json b/contracts/round/test_snapshots/test/lowest_bid_table_driven.3.json index 03b3b03b..75cf7607 100644 --- a/contracts/round/test_snapshots/test/lowest_bid_table_driven.3.json +++ b/contracts/round/test_snapshots/test/lowest_bid_table_driven.3.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/lowest_bid_tie_is_deterministic_first_inserter_wins.1.json b/contracts/round/test_snapshots/test/lowest_bid_tie_is_deterministic_first_inserter_wins.1.json index d9e9cdae..471068aa 100644 --- a/contracts/round/test_snapshots/test/lowest_bid_tie_is_deterministic_first_inserter_wins.1.json +++ b/contracts/round/test_snapshots/test/lowest_bid_tie_is_deterministic_first_inserter_wins.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/missing_reveal_bid_is_skipped_during_clear.1.json b/contracts/round/test_snapshots/test/missing_reveal_bid_is_skipped_during_clear.1.json index 88baf1e7..50121eed 100644 --- a/contracts/round/test_snapshots/test/missing_reveal_bid_is_skipped_during_clear.1.json +++ b/contracts/round/test_snapshots/test/missing_reveal_bid_is_skipped_during_clear.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/no_valid_bids_after_reveal_window.1.json b/contracts/round/test_snapshots/test/no_valid_bids_after_reveal_window.1.json index 3b8f91f9..86a8048c 100644 --- a/contracts/round/test_snapshots/test/no_valid_bids_after_reveal_window.1.json +++ b/contracts/round/test_snapshots/test/no_valid_bids_after_reveal_window.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/observer_reads_round_and_bid_state_after_lifecycle_completion.1.json b/contracts/round/test_snapshots/test/observer_reads_round_and_bid_state_after_lifecycle_completion.1.json index 52a56b81..886869ed 100644 --- a/contracts/round/test_snapshots/test/observer_reads_round_and_bid_state_after_lifecycle_completion.1.json +++ b/contracts/round/test_snapshots/test/observer_reads_round_and_bid_state_after_lifecycle_completion.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/open_reveal_extends_seal_through_reveal_window.1.json b/contracts/round/test_snapshots/test/open_reveal_extends_seal_through_reveal_window.1.json index acabf8c5..9edc7df8 100644 --- a/contracts/round/test_snapshots/test/open_reveal_extends_seal_through_reveal_window.1.json +++ b/contracts/round/test_snapshots/test/open_reveal_extends_seal_through_reveal_window.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/open_reveal_on_settled_round_rejected.1.json b/contracts/round/test_snapshots/test/open_reveal_on_settled_round_rejected.1.json index 0e774778..40ecc9bb 100644 --- a/contracts/round/test_snapshots/test/open_reveal_on_settled_round_rejected.1.json +++ b/contracts/round/test_snapshots/test/open_reveal_on_settled_round_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/overwrite_to_larger_escrow_conserves_tokens.1.json b/contracts/round/test_snapshots/test/overwrite_to_larger_escrow_conserves_tokens.1.json index c9da8c21..16f227ea 100644 --- a/contracts/round/test_snapshots/test/overwrite_to_larger_escrow_conserves_tokens.1.json +++ b/contracts/round/test_snapshots/test/overwrite_to_larger_escrow_conserves_tokens.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -224,6 +227,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/repeated_overwrites_escrow_conservation.1.json b/contracts/round/test_snapshots/test/repeated_overwrites_escrow_conservation.1.json index acb9693c..86166661 100644 --- a/contracts/round/test_snapshots/test/repeated_overwrites_escrow_conservation.1.json +++ b/contracts/round/test_snapshots/test/repeated_overwrites_escrow_conservation.1.json @@ -163,6 +163,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -227,6 +230,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -291,6 +297,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -355,6 +364,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/reveal_hash_mismatch_invalidates_bid.1.json b/contracts/round/test_snapshots/test/reveal_hash_mismatch_invalidates_bid.1.json index a74327dd..2d78b8e5 100644 --- a/contracts/round/test_snapshots/test/reveal_hash_mismatch_invalidates_bid.1.json +++ b/contracts/round/test_snapshots/test/reveal_hash_mismatch_invalidates_bid.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/reveal_on_settled_round_rejected.1.json b/contracts/round/test_snapshots/test/reveal_on_settled_round_rejected.1.json index 692f6468..5659e302 100644 --- a/contracts/round/test_snapshots/test/reveal_on_settled_round_rejected.1.json +++ b/contracts/round/test_snapshots/test/reveal_on_settled_round_rejected.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/reveal_wrong_nonce_rejected.1.json b/contracts/round/test_snapshots/test/reveal_wrong_nonce_rejected.1.json index 1750ac55..ecf7e91d 100644 --- a/contracts/round/test_snapshots/test/reveal_wrong_nonce_rejected.1.json +++ b/contracts/round/test_snapshots/test/reveal_wrong_nonce_rejected.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/seeded_case_42_highest_bid_reproducible.1.json b/contracts/round/test_snapshots/test/seeded_case_42_highest_bid_reproducible.1.json index d7704e05..efdf20ca 100644 --- a/contracts/round/test_snapshots/test/seeded_case_42_highest_bid_reproducible.1.json +++ b/contracts/round/test_snapshots/test/seeded_case_42_highest_bid_reproducible.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/seeded_case_7_lowest_bid_reproducible.1.json b/contracts/round/test_snapshots/test/seeded_case_7_lowest_bid_reproducible.1.json index 65a9731c..ebf4f67d 100644 --- a/contracts/round/test_snapshots/test/seeded_case_7_lowest_bid_reproducible.1.json +++ b/contracts/round/test_snapshots/test/seeded_case_7_lowest_bid_reproducible.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/settle_exact_payouts_table.1.json b/contracts/round/test_snapshots/test/settle_exact_payouts_table.1.json index a89f776a..6ad4ec74 100644 --- a/contracts/round/test_snapshots/test/settle_exact_payouts_table.1.json +++ b/contracts/round/test_snapshots/test/settle_exact_payouts_table.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/settle_exact_payouts_table.2.json b/contracts/round/test_snapshots/test/settle_exact_payouts_table.2.json index c59e147e..7626c6aa 100644 --- a/contracts/round/test_snapshots/test/settle_exact_payouts_table.2.json +++ b/contracts/round/test_snapshots/test/settle_exact_payouts_table.2.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/settle_exact_payouts_table.3.json b/contracts/round/test_snapshots/test/settle_exact_payouts_table.3.json index 6920d056..de3b2eda 100644 --- a/contracts/round/test_snapshots/test/settle_exact_payouts_table.3.json +++ b/contracts/round/test_snapshots/test/settle_exact_payouts_table.3.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -220,6 +224,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -249,6 +254,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -306,6 +314,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", @@ -335,6 +344,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/settled_round_persistent_state_survives_seal_expiry.1.json b/contracts/round/test_snapshots/test/settled_round_persistent_state_survives_seal_expiry.1.json index 25624577..980f76d0 100644 --- a/contracts/round/test_snapshots/test/settled_round_persistent_state_survives_seal_expiry.1.json +++ b/contracts/round/test_snapshots/test/settled_round_persistent_state_survives_seal_expiry.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/token_conservation_full_lifecycle.1.json b/contracts/round/test_snapshots/test/token_conservation_full_lifecycle.1.json index 4125fccb..7153d8d7 100644 --- a/contracts/round/test_snapshots/test/token_conservation_full_lifecycle.1.json +++ b/contracts/round/test_snapshots/test/token_conservation_full_lifecycle.1.json @@ -159,6 +159,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -188,6 +189,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } @@ -224,6 +228,7 @@ [], [], [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", @@ -253,6 +258,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 29155653 } ] } diff --git a/contracts/round/test_snapshots/test/void_after_grace_refunds_all.1.json b/contracts/round/test_snapshots/test/void_after_grace_refunds_all.1.json index e725958d..eef1b1c6 100644 --- a/contracts/round/test_snapshots/test/void_after_grace_refunds_all.1.json +++ b/contracts/round/test_snapshots/test/void_after_grace_refunds_all.1.json @@ -188,6 +188,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } @@ -249,6 +252,9 @@ }, { "bytes": "6964" + }, + { + "u64": 2000 } ] } diff --git a/contracts/round/test_snapshots/test/voided_round_refunds_survive_seal_expiry.1.json b/contracts/round/test_snapshots/test/voided_round_refunds_survive_seal_expiry.1.json index b3955638..19ff1e5f 100644 --- a/contracts/round/test_snapshots/test/voided_round_refunds_survive_seal_expiry.1.json +++ b/contracts/round/test_snapshots/test/voided_round_refunds_survive_seal_expiry.1.json @@ -134,6 +134,7 @@ } ] ], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", @@ -163,6 +164,9 @@ }, { "bytes": "69642d626c6f62" + }, + { + "u64": 2000 } ] } diff --git a/packages/round-bindings/src/index.ts b/packages/round-bindings/src/index.ts index 6924632f..700e8889 100644 --- a/packages/round-bindings/src/index.ts +++ b/packages/round-bindings/src/index.ts @@ -289,8 +289,11 @@ export interface Client { * - `escrow` is a public USDC budget and an upper bound on the sealed bid; * locked now so the winner can always pay. * - `auditor_blob` is the bidder identity encrypted to the auditor key. + * - `seal_round` must equal the round's stored `reveal_round`: the seal is + * only meaningful for the Drand round this auction committed to open. + * Mismatched seals are rejected before any escrow is locked. */ - commit: ({round_id, bidder, commitment, ciphertext, escrow, auditor_blob}: {round_id: u64, bidder: string, commitment: Buffer, ciphertext: Buffer, escrow: i128, auditor_blob: Buffer}, options?: MethodOptions) => Promise>> + commit: ({round_id, bidder, commitment, ciphertext, escrow, auditor_blob, seal_round}: {round_id: u64, bidder: string, commitment: Buffer, ciphertext: Buffer, escrow: i128, auditor_blob: Buffer, seal_round: u64}, options?: MethodOptions) => Promise>> /** * Construct and simulate a reveal transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. diff --git a/packages/sdk/scripts/live-smoke.ts b/packages/sdk/scripts/live-smoke.ts index 172bc7e7..b5de66d9 100644 --- a/packages/sdk/scripts/live-smoke.ts +++ b/packages/sdk/scripts/live-smoke.ts @@ -131,6 +131,7 @@ async function main() { value, nonce, round: revealRound, + revealRound, client: drand, identity, auditorPublicKey: auditor.publicKey, diff --git a/packages/sdk/scripts/mainnet-micro.ts b/packages/sdk/scripts/mainnet-micro.ts index 5dba86cd..ad343aaa 100644 --- a/packages/sdk/scripts/mainnet-micro.ts +++ b/packages/sdk/scripts/mainnet-micro.ts @@ -207,6 +207,104 @@ async function main() { diagnostics.info("pnpm-mainnet-micro-execute", " pnpm mainnet:micro -- --execute"); return; } + + if (process.env.MAINNET_CONFIRM !== "SUB_ROSA_MAINNET") { + throw new Error('set MAINNET_CONFIRM=SUB_ROSA_MAINNET to execute on mainnet'); + } + assertMainnetConfirmed(); + + const operatorSecret = reqEnv("OPERATOR_SECRET"); + const bidderSecret = reqEnv("BIDDER_SECRET"); + const contractId = process.env.ROUND_CONTRACT_ID ?? MAINNET_ARTIFACTS.contractId; + const rpcUrl = process.env.RPC_URL ?? MAINNET_ARTIFACTS.rpcUrl; + const network = process.env.NETWORK_PASSPHRASE ?? MAINNET_ARTIFACTS.networkPassphrase; + + const operatorKp = Keypair.fromSecret(operatorSecret); + const bidderKp = Keypair.fromSecret(bidderSecret); + + const reader = new SubRosaClient({ + rpcUrl, + networkPassphrase: network, + contractId, + publicKey: operatorKp.publicKey(), + }); + + const readiness = await runMainnetReadiness( + defaultMainnetReadinessInput({ + rpcUrl, + networkPassphrase: network, + contractId, + withBalances: true, + operatorAccount: operatorKp.publicKey(), + bidderAccount: bidderKp.publicKey(), + }), + { reader }, + ); + assertReadinessForExecute(readiness.checks); + + // Pick next round id: max existing + 1 (probe up to 32). + let nextRound = 1n; + for (let id = 1n; id <= 32n; id++) { + try { + await reader.getRound(id); + nextRound = id + 1n; + } catch { + break; + } + } + + const now = systemClock.nowSeconds(); + const revealRound = Math.ceil((now + 300 - DRAND_GENESIS) / DRAND_PERIOD); + const commitDeadline = now + 120; + const revealDeadline = DRAND_GENESIS + DRAND_PERIOD * revealRound + 180; + const auditor = generateAuditorKeypair(); + + diagnostics.info("createround-id", `→ createRound id≈${nextRound} R=${revealRound}…`); + const operator = new SubRosaClient({ + rpcUrl, + networkPassphrase: network, + contractId, + secretKey: operatorSecret, + }); + const roundId = await operator.createRound({ + itemRef: randomBytes(32), + revealRound, + commitDeadline, + revealDeadline, + auditorPubkey: auditor.publicKey, + clearingRule: "HighestBid", + }); + + const drand = quicknet(); + const nonce = generateNonce(); + const sealed = await sealBid({ + contractId, + bidderId: bidderKp.publicKey(), + value: bid, + nonce, + round: revealRound, + revealRound, + client: drand, + identity: new TextEncoder().encode(`micro:${bidderKp.publicKey()}`), + auditorPublicKey: auditor.publicKey, + }); + + diagnostics.info("commit-micro-sealed-bid", "→ commit micro sealed bid…"); + const bidder = new SubRosaClient({ + rpcUrl, + networkPassphrase: network, + contractId, + secretKey: bidderSecret, + }); + await bidder.commit({ roundId, sealed, escrow }); + + diagnostics.info("mainnet-micro-commit-sent", "\n✅ MAINNET MICRO COMMIT SENT"); + diagnostics.info("contract", " contract:", { "contractId_0": contractId }); + diagnostics.info("round", " round: ", { "value1_0": roundId.toString() }); + diagnostics.info("r", " R: ", { "revealRound_0": revealRound }); + diagnostics.info("bid", " bid: ", { "value1_0": (Number(bid) / 1e7).toFixed(7), "value2_1": "XLM" }); + diagnostics.info("escrow", " escrow: ", { "value1_0": (Number(escrow) / 1e7).toFixed(7), "value2_1": "XLM" }); + diagnostics.info("next-wait-for-r-then-pnpm-mainnet-settle-with-round-id", "\nNext: wait for R, then pnpm mainnet:settle with ROUND_ID=", { "value1_0": roundId.toString() }); } main().catch((err) => { diff --git a/packages/sdk/src/client.test.ts b/packages/sdk/src/client.test.ts index 8efde17d..cfe6b135 100644 --- a/packages/sdk/src/client.test.ts +++ b/packages/sdk/src/client.test.ts @@ -246,7 +246,12 @@ describe("SubRosaClient source configuration", () => { await assert.rejects( client.commit({ roundId: 1, - sealed, + sealed: { + commitment: new Uint8Array(32), + ciphertext: new Uint8Array([0x61, 0x67, 0x65]), // non-empty + auditorBlob: new Uint8Array(1), // non-empty + sealRound: 1, + }, escrow: 1n, binding: fixtureBinding(), }), diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index ce285056..8a74a865 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -170,15 +170,12 @@ export interface CommitParams { /** Bidder address. Default: the configured signer's public key. */ bidder?: string; /** - * The value, nonce, and Drand round the seal was produced from. - * - * Supplying it makes `commit` verify the seal against them before submitting - * — same acceptance rule the sealer works to, so a blob that decodes but - * commits to the wrong value is rejected here instead of becoming an - * on-chain commitment the contract can never open. The value is never logged - * or included in the resulting error. + * Drand round the seal was encrypted to. Must equal the round's stored + * `reveal_round` — the contract rejects mismatched seals before locking + * escrow (issue #376). Defaults to `sealed.sealRound` when the seal carries + * it (tlock >= this change), otherwise it must be supplied. */ - binding?: SealedBidBinding; + sealRound?: number | bigint; } export interface RevealParams { @@ -509,6 +506,13 @@ export class SubRosaClient { } const bidder = params.bidder ?? this.#requireSource("bidder"); + const rawSealRound = params.sealRound ?? (params.sealed as { sealRound?: number | bigint }).sealRound; + if (rawSealRound === undefined) { + throw new SubRosaClientConfigError( + "sealRound is required: pass the Drand round the seal was encrypted to (issue #376 commit window)", + ); + } + const seal_round = toBigInt(rawSealRound); const tx = await this.#validatedContractCall(() => this.contract.commit({ round_id: normalizeRoundId(params.roundId), @@ -517,6 +521,7 @@ export class SubRosaClient { ciphertext: toBuffer(params.sealed.ciphertext), escrow: params.escrow, auditor_blob: toBuffer(params.sealed.auditorBlob), + seal_round, }), ); await this.#sendUnwrap(tx); @@ -631,6 +636,13 @@ export class SubRosaClient { } return this.#preflight("commit", () => { const bidder = params.bidder ?? this.#requireSource("bidder"); + const rawSealRound = params.sealRound ?? (params.sealed as { sealRound?: number | bigint }).sealRound; + if (rawSealRound === undefined) { + throw new SubRosaClientConfigError( + "sealRound is required: pass the Drand round the seal was encrypted to (issue #376 commit window)", + ); + } + const seal_round = toBigInt(rawSealRound); return this.#validatedContractCall(() => this.contract.commit({ round_id: toBigInt(params.roundId), @@ -639,6 +651,7 @@ export class SubRosaClient { ciphertext: toBuffer(params.sealed.ciphertext), escrow: params.escrow, auditor_blob: toBuffer(params.sealed.auditorBlob), + seal_round, }), ); }); diff --git a/packages/sdk/src/encoding.test.ts b/packages/sdk/src/encoding.test.ts index 80959161..1cf1922b 100644 --- a/packages/sdk/src/encoding.test.ts +++ b/packages/sdk/src/encoding.test.ts @@ -154,6 +154,7 @@ test("a tlock SealedBid encodes byte-for-byte into commit", () => { commitment: h, ciphertext: new TextEncoder().encode("age-armored"), auditorBlob: new Uint8Array(0), + sealRound: 9, }; const args = c.spec.funcArgsToScVals("commit", { diff --git a/packages/sdk/src/preflight.test.ts b/packages/sdk/src/preflight.test.ts index 602de3b6..e4cc2ca3 100644 --- a/packages/sdk/src/preflight.test.ts +++ b/packages/sdk/src/preflight.test.ts @@ -294,6 +294,7 @@ describe("SubRosaClient preflight helpers", () => { commitment: new Uint8Array(32), ciphertext: new Uint8Array(64), auditorBlob: new Uint8Array(32), + sealRound: 1, }, escrow: 1_000_000n, }); diff --git a/packages/tlock/package.json b/packages/tlock/package.json index 4ef0c588..ba82bb3b 100644 --- a/packages/tlock/package.json +++ b/packages/tlock/package.json @@ -20,9 +20,9 @@ }, "main": "src/index.ts", "scripts": { - "test": "node --import tsx --test src/commitment.test.ts src/ciphertext.test.ts src/payload.test.ts src/auditor.test.ts src/auditor-recovery-cli.test.ts src/bls.test.ts src/seal.test.ts src/freshness.test.ts src/quicknet.test.ts src/validate.test.ts", + "test": "node --import tsx --test src/commitment.test.ts src/payload.test.ts src/auditor.test.ts src/auditor-recovery-cli.test.ts src/bls.test.ts src/seal.test.ts src/freshness.test.ts src/quicknet.test.ts src/validate.test.ts src/window.test.ts", "test:quicknet": "node --import tsx --test src/quicknet.test.ts", - "test:unit": "node --import tsx --test src/commitment.test.ts src/ciphertext.test.ts src/payload.test.ts src/auditor.test.ts src/auditor-recovery-cli.test.ts src/bls.test.ts src/freshness.test.ts src/quicknet.test.ts src/validate.test.ts", + "test:unit": "node --import tsx --test src/commitment.test.ts src/payload.test.ts src/auditor.test.ts src/auditor-recovery-cli.test.ts src/bls.test.ts src/freshness.test.ts src/quicknet.test.ts src/validate.test.ts src/window.test.ts", "test:seal": "node --import tsx --test src/seal.test.ts", "recover:identities": "node --import tsx src/recover-identities.cli.ts", "typecheck": "tsc --noEmit -p tsconfig.json" diff --git a/packages/tlock/src/index.ts b/packages/tlock/src/index.ts index 8d336132..57690243 100644 --- a/packages/tlock/src/index.ts +++ b/packages/tlock/src/index.ts @@ -88,6 +88,13 @@ export { type FreshnessResult, } from "./freshness.js"; +export { + assertSealRoundWindow, + isMalformedRound, + SealRoundError, + type SealRoundErrorReason, +} from "./window.js"; + export { encodePayloadEnvelope, decodePayloadEnvelope, diff --git a/packages/tlock/src/payload.ts b/packages/tlock/src/payload.ts index 38b15202..6795bbd0 100644 --- a/packages/tlock/src/payload.ts +++ b/packages/tlock/src/payload.ts @@ -50,6 +50,9 @@ export interface SealPayloadParams extends PayloadEnvelope { contractId: string; bidderId: string; round: number; + /// The Drand round the auction committed to open (`Round::reveal_round`). + /// The seal must name exactly this round, or sealing is rejected. + revealRound: number; client: DrandClient; identity?: Uint8Array; auditorPublicKey?: Uint8Array; @@ -154,6 +157,7 @@ export async function sealPayload(params: SealPayloadParams): Promise { if (!nonce || nonce.length !== NONCE_BYTES) { throw new Error(`nonce must be ${NONCE_BYTES} bytes, got ${nonce?.length}`); } + // Issue #376: the seal must name exactly the round the auction committed to + // open — same rule the contract enforces inside `commit`. + assertSealRoundWindow(round, revealRound); const preimage = encodeBidPreimage(value, nonce); const h = commitment(value, nonce); @@ -73,7 +83,7 @@ export async function sealBid(params: SealBidParams): Promise { throw new Error("identity and auditorPublicKey must be provided together"); } - return { commitment: h, ciphertext, auditorBlob }; + return { commitment: h, ciphertext, auditorBlob, sealRound: round }; } export interface OpenedBid { diff --git a/packages/tlock/src/window.test.ts b/packages/tlock/src/window.test.ts new file mode 100644 index 00000000..e781dc43 --- /dev/null +++ b/packages/tlock/src/window.test.ts @@ -0,0 +1,101 @@ +// Copyright (c) 2026 Sub Rosa contributors +// SPDX-License-Identifier: MIT +// +// Test vectors for the seal-round commit window (issue #376). +// +// These vectors use the quicknet chain parameters already committed in the +// repo (genesis_time 1692803367, period 3, quicknet chain hash) so the +// TypeScript helper and the Soroban contract can be validated against the +// exact same fixture set. The contract side runs the same cases in +// `contracts/round/src/error_paths.rs` (error_path_seal_round_too_early, +// error_path_seal_round_too_late, error_path_invalid_seal_round_zero) against +// the real quicknet BLS fixture in `contracts/round/src/test.rs`. + +import { test } from "node:test"; +import assert from "node:assert/strict"; + +import { + assertSealRoundWindow, + isMalformedRound, + SealRoundError, +} from "./window.js"; + +// Frozen quicknet chain parameters (same fixture as quicknet.test.ts and the +// contract's VEC_GENESIS / VEC_PERIOD / QUICKNET_HASH). +const QUICKNET_FIXTURE = { + genesis_time: 1_692_803_367, + period: 3, + hash: "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971", +} as const; + +test("window vectors share the frozen quicknet chain parameters", () => { + assert.equal(QUICKNET_FIXTURE.period, 3); + assert.match(QUICKNET_FIXTURE.hash, /^[0-9a-f]{64}$/); +}); + +test("a seal exactly at the auction's round is inside the window", () => { + const revealRound = 10_000_000; + assert.doesNotThrow(() => assertSealRoundWindow(revealRound, revealRound)); +}); + +test("one round before the auction's round is too early (stable reason)", () => { + const revealRound = 10_000_000; + assert.throws( + () => assertSealRoundWindow(revealRound - 1, revealRound), + (err: unknown) => + err instanceof SealRoundError && + err.reason === "seal-round-too-early" && + err.sealRound === revealRound - 1 && + err.revealRound === revealRound, + ); +}); + +test("one round after the auction's round is too late (stable reason)", () => { + const revealRound = 10_000_000; + assert.throws( + () => assertSealRoundWindow(revealRound + 1, revealRound), + (err: unknown) => + err instanceof SealRoundError && err.reason === "seal-round-too-late", + ); +}); + +test("zero, negative, fractional, NaN, and unsafe rounds are malformed", () => { + for (const round of [0, -1, -100, 1.5, NaN, Infinity, -Infinity, Number.MAX_SAFE_INTEGER + 1]) { + assert.equal(isMalformedRound(round), true, `round ${round} must be malformed`); + assert.throws( + () => assertSealRoundWindow(round, 10_000_000), + (err: unknown) => + err instanceof SealRoundError && err.reason === "invalid-seal-round-zero", + `round ${round} must fail before any escrow lock`, + ); + } +}); + +test("a malformed auction round is also rejected", () => { + for (const revealRound of [0, -1, NaN, 2.5]) { + assert.throws( + () => assertSealRoundWindow(10_000_000, revealRound), + (err: unknown) => + err instanceof SealRoundError && err.reason === "invalid-seal-round-zero", + ); + } +}); + +test("window error messages name the auction's round for integrators", () => { + try { + assertSealRoundWindow(9_999_999, 10_000_000); + assert.fail("expected SealRoundError"); + } catch (err) { + assert.ok(err instanceof SealRoundError); + assert.match(err.message, /10_000_000|10000000/); + } +}); + +test("round publish time from the fixture stays representable (sanity)", () => { + // genesis + period × R must fit in a JS-safe integer for realistic rounds; + // the contract enforces the same shape via checked_time_of_round in u64. + const round = 100_000_000; + const publishAtSeconds = QUICKNET_FIXTURE.genesis_time + QUICKNET_FIXTURE.period * round; + assert.ok(Number.isSafeInteger(publishAtSeconds)); + assert.ok(Number.isSafeInteger(publishAtSeconds * 1000)); +}); diff --git a/packages/tlock/src/window.ts b/packages/tlock/src/window.ts new file mode 100644 index 00000000..5c9ed0c3 --- /dev/null +++ b/packages/tlock/src/window.ts @@ -0,0 +1,71 @@ +// Copyright (c) 2026 Sub Rosa contributors +// SPDX-License-Identifier: MIT +// +// Seal-round commit window — the single off-chain counterpart of the Round +// contract's seal-round check (issue #376). +// +// A bid seal is only meaningful for the Drand round the auction committed to +// open. The contract stores that round as `Round::reveal_round` at +// `create_round` and rejects, inside `commit`, any seal whose round differs — +// with stable errors for too-early, too-late, and malformed round numbers. +// This module enforces the same rule off-chain, before a seal is ever +// encrypted, so both sides reject the same fixture set. + +/** + * Stable reasons a seal round can fall outside the commit window. Mirrors the + * contract's `Error` variants: SealRoundTooEarly (40), SealRoundTooLate (41), + * InvalidSealRoundZero (42). + */ +export type SealRoundErrorReason = + | "seal-round-too-early" + | "seal-round-too-late" + | "invalid-seal-round-zero"; + +export class SealRoundError extends Error { + readonly reason: SealRoundErrorReason; + readonly sealRound: number; + readonly revealRound: number; + + constructor(reason: SealRoundErrorReason, sealRound: number, revealRound: number) { + super( + reason === "invalid-seal-round-zero" + ? `seal round must be a positive integer, got ${sealRound}` + : `seal round ${sealRound} is outside the commit window: the auction opens at round ${revealRound}`, + ); + this.name = "SealRoundError"; + this.reason = reason; + this.sealRound = sealRound; + this.revealRound = revealRound; + } +} + +/// A round number the quicknet chain can never have published: zero, negative, +/// non-integer, NaN, or beyond Number.MAX_SAFE_INTEGER. +export function isMalformedRound(round: number): boolean { + return !Number.isSafeInteger(round) || round < 1; +} + +/** + * Validate a seal round against the round the auction committed to open. + * + * The allowed reveal round is always the value stored on the auction (`reveal + * round`), never a caller-supplied value. Throws SealRoundError with a stable + * `reason` for: + * - "invalid-seal-round-zero": zero, negative, non-integer, or unsafe rounds + * - "seal-round-too-early": seal round before the auction's round + * - "seal-round-too-late": seal round after the auction's round + */ +export function assertSealRoundWindow(sealRound: number, revealRound: number): void { + if (isMalformedRound(sealRound)) { + throw new SealRoundError("invalid-seal-round-zero", sealRound, revealRound); + } + if (isMalformedRound(revealRound)) { + throw new SealRoundError("invalid-seal-round-zero", sealRound, revealRound); + } + if (sealRound < revealRound) { + throw new SealRoundError("seal-round-too-early", sealRound, revealRound); + } + if (sealRound > revealRound) { + throw new SealRoundError("seal-round-too-late", sealRound, revealRound); + } +} diff --git a/services/agent/src/bidder.test.ts b/services/agent/src/bidder.test.ts index 51526ae5..fce6542e 100644 --- a/services/agent/src/bidder.test.ts +++ b/services/agent/src/bidder.test.ts @@ -76,7 +76,7 @@ function bidderFixture() { calls.sealed++; duringSeal(); assert.equal(revealRound, 123); assert.deepEqual(auditorPublicKey, new Uint8Array(round.auditor_pubkey)); - return { commitment: new Uint8Array(32), ciphertext: new Uint8Array(4), auditorBlob: new Uint8Array(4) }; + return { commitment: new Uint8Array(32), ciphertext: new Uint8Array(4), auditorBlob: new Uint8Array(4), sealRound: 123 }; }, }; return { config, round, calls, deps, clock, diff --git a/services/agent/src/bidder.ts b/services/agent/src/bidder.ts index 1a81a1c7..b83acb73 100644 --- a/services/agent/src/bidder.ts +++ b/services/agent/src/bidder.ts @@ -217,6 +217,7 @@ const requestBody = JSON.stringify(req); value: bidValue, nonce, round: revealRound, + revealRound, client: drand, identity: new TextEncoder().encode(`agent:${sessionKp.publicKey()}`), auditorPublicKey, diff --git a/services/auction-template/sealed-auction.ts b/services/auction-template/sealed-auction.ts index 3134c86c..0e388039 100644 --- a/services/auction-template/sealed-auction.ts +++ b/services/auction-template/sealed-auction.ts @@ -251,12 +251,12 @@ async function testnetMain() { } const nonce = generateNonce(); const sealed = await sealBid({ - value, nonce, round: revealRound, client: drand, + value, nonce, round: revealRound, revealRound, client: drand, identity: new TextEncoder().encode(`bidder:${who}`), auditorPublicKey: auditor.publicKey, }); const client = new SubRosaClient({ rpcUrl: RPC_URL, networkPassphrase: NETWORK, contractId, secretKey: secret }); - await client.commit({ roundId, sealed, escrow }); + await client.commit({ roundId, sealed, escrow, sealRound: revealRound }); diagnostics.info("progress-4", ` ${who}: bid ${usdc(value)} / escrow ${usdc(escrow)}`); } diff --git a/services/drand-tools/src/quicknet.ts b/services/drand-tools/src/quicknet.ts index 1fa89a3b..768a4c52 100644 --- a/services/drand-tools/src/quicknet.ts +++ b/services/drand-tools/src/quicknet.ts @@ -38,6 +38,21 @@ export function roundAt(info: ChainInfo, unixSeconds: number): number { return Math.floor((unixSeconds - info.genesis_time) / info.period) + 1; } +/// Wall-clock time (unix seconds) at which Drand round `round` is published. +/// Throws for a zero/unsafe round or an intermediate value that overflows the +/// safe-integer range: the chain can never publish such a round, so callers +/// must reject it before committing any seal or locking escrow (issue #376). export function timeOfRound(info: ChainInfo, round: number): number { - return info.genesis_time + info.period * round; + if (!Number.isSafeInteger(round) || round < 1) { + throw new RangeError(`round must be a positive safe integer, got ${round}`); + } + if (!Number.isSafeInteger(info.period) || info.period <= 0) { + throw new RangeError(`period must be a positive safe integer, got ${info.period}`); + } + const offsetSeconds = info.period * round; + const publishAtSeconds = info.genesis_time + offsetSeconds; + if (!Number.isSafeInteger(offsetSeconds) || !Number.isSafeInteger(publishAtSeconds)) { + throw new RangeError(`round ${round} publish time overflows the safe-integer range`); + } + return publishAtSeconds; } diff --git a/services/keeper/scripts/keeper-e2e.ts b/services/keeper/scripts/keeper-e2e.ts index 1f7343d9..11287602 100644 --- a/services/keeper/scripts/keeper-e2e.ts +++ b/services/keeper/scripts/keeper-e2e.ts @@ -119,6 +119,7 @@ async function main() { value, nonce, round: revealRound, + revealRound, client: drand, identity: new TextEncoder().encode("bidder:keeper-e2e"), auditorPublicKey: auditor.publicKey, diff --git a/services/keeper/scripts/lifecycle-e2e.ts b/services/keeper/scripts/lifecycle-e2e.ts index 8d885786..c6684683 100644 --- a/services/keeper/scripts/lifecycle-e2e.ts +++ b/services/keeper/scripts/lifecycle-e2e.ts @@ -173,12 +173,12 @@ async function main() { async function commitBid(secret: string, value: bigint, escrow: bigint, who: string) { const nonce = generateNonce(); const sealed = await sealBid({ - value, nonce, round: revealRound, client: drand, + value, nonce, round: revealRound, revealRound, client: drand, identity: new TextEncoder().encode(`bidder:${who}`), auditorPublicKey: auditor.publicKey, }); const client = new SubRosaClient({ rpcUrl: RPC_URL, networkPassphrase: NETWORK, contractId, secretKey: secret }); - await client.commit({ roundId, sealed, escrow }); + await client.commit({ roundId, sealed, escrow, sealRound: revealRound }); diagnostics.info("progress-2", ` ✔ ${who} committed bid ${usdc(value)} / escrow ${usdc(escrow)} USDC`); return { label: who, blobHex: bytesHex(sealed.auditorBlob) }; }