diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c09da6e..e3ac4c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,10 +29,16 @@ checkout until that file exists. Only re-run it after changing `contracts/tholos ```text contracts/ - tholos/ The assertion and dispute contract + tholos/ The assertion and dispute contract (v1, deployed and stable) src/ lib.rs Contract logic test.rs Unit tests (soroban-sdk testutils, mocked ledger and auth) + tholos-v2/ Stake-weighted resolution (v2), design in docs/src/V2_RESOLUTION.md; + a wholly separate contract from v1, never upgraded in place + src/ + lib.rs Contract logic, built up issue by issue per V2_RESOLUTION.md's + "Future implementation work" list + test.rs Unit tests, same conventions as contracts/tholos demo-consumer/ Minimal example contract that calls into Tholos src/ lib.rs Cross-contract call pattern from docs/src/INTEGRATION.md diff --git a/Cargo.lock b/Cargo.lock index bf2979a..0e26d48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1838,6 +1838,14 @@ dependencies = [ "soroban-sdk", ] +[[package]] +name = "tholos-v2" +version = "0.1.0" +dependencies = [ + "proptest", + "soroban-sdk", +] + [[package]] name = "time" version = "0.3.53" diff --git a/Cargo.toml b/Cargo.toml index b2dea63..d47f022 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["contracts/tholos", "contracts/demo-consumer", "contracts/asserter-consumer"] +members = ["contracts/tholos", "contracts/tholos-v2", "contracts/demo-consumer", "contracts/asserter-consumer"] [workspace.lints.rust] warnings = "deny" diff --git a/contracts/tholos-v2/Cargo.toml b/contracts/tholos-v2/Cargo.toml new file mode 100644 index 0000000..5b97f58 --- /dev/null +++ b/contracts/tholos-v2/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "tholos-v2" +version = "0.1.0" +edition = "2021" +license = "MIT" +publish = false + +[lib] +crate-type = ["cdylib", "rlib"] + +[lints] +workspace = true + +[dependencies] +soroban-sdk = "26.1.0" + +[dev-dependencies] +proptest = "1.11.0" +soroban-sdk = { version = "26.1.0", features = ["testutils"] } + +[features] +testutils = ["soroban-sdk/testutils"] diff --git a/contracts/tholos-v2/src/lib.rs b/contracts/tholos-v2/src/lib.rs new file mode 100644 index 0000000..3e1e8e5 --- /dev/null +++ b/contracts/tholos-v2/src/lib.rs @@ -0,0 +1,333 @@ +#![no_std] + +//! Tholos v2: stake-weighted resolution. Design in `docs/src/V2_RESOLUTION.md`. +//! Deployed as a wholly separate contract from v1 (`contracts/tholos`), never +//! upgraded in place: see the design doc's "Migration from existing v1 +//! deployments" section for why. +//! +//! This crate currently implements only #64's scope: the immutable +//! `PolicySnapshotV2` pinned at assertion creation, and the `AssertionV2` +//! record it lives on. Registration, reveal, outcome resolution, settlement, +//! and the freeze/cancel mechanism are separate issues (#65-#71) and land as +//! this crate grows. + +use soroban_sdk::{ + contract, contracterror, contractimpl, contracttype, xdr::ToXdr, Address, BytesN, Env, +}; + +/// Which weight rule this assertion's vote is decided under. A version marker +/// rather than a formula, so a future weight rule can be added without +/// reinterpreting already-pinned assertions under new math. +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum WeightRuleVersion { + /// `weight(address) = locked_bond(address)`, linear and unweighted by + /// anything but the amount actually escrowed. See "Voting weight" in + /// V2_RESOLUTION.md for why linear weight is deliberate. + LinearStakeV1, +} + +/// What happens if neither side reaches strict majority by the reveal +/// deadline. `AssertedOutcomeStands` is the only variant today (the +/// optimistic-default design decision), kept as an enum so a future +/// `Inconclusive`-style rule could be pinned per-deployment without touching +/// already-open assertions under the old rule. +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TimeoutDefaultRule { + AssertedOutcomeStands, +} + +/// Version marker for the settlement/payout formula (forfeiture distribution, +/// dust handling). Bumped independently of `WeightRuleVersion` since the two +/// can change on different schedules. +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PayoutRuleVersion { + ProRataV1, +} + +/// The lifecycle phase of an `AssertionV2`. `OutcomeLocked` (a strict majority +/// reached before the reveal deadline) is folded into `Reveal` for now: +/// distinguishing "revealing, outcome undecided" from "revealing, outcome +/// already locked" only matters once settlement exists, which is #69's scope. +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PhaseV2 { + Pending, + Registration, + Reveal, + Resolved, +} + +/// Why an assertion reached `Resolved`. Distinguishes a real vote outcome +/// from the optimistic default and from an admin cancellation, so history and +/// indexers never have to infer which rule actually decided the result. +/// +/// `NotYetDecided` stands in for `None`: the soroban-sdk 26.1.0 `contracttype` +/// derive doesn't generate an XDR `ScVal` conversion for `Option` +/// (only `Option` of built-in types like `Address`/`bool`), so `AssertionV2` +/// deriving `contracttype` fails to compile if `terminal_cause` is +/// `Option`. Same information, no SDK limitation. +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TerminalCause { + NotYetDecided, + StrictMajorityFor, + StrictMajorityAgainst, + OptimisticTimeout, + /// Set only by the freeze/cancel mechanism (#71), before any position + /// reveals. Reserved here so `AssertionV2.terminal_cause`'s type doesn't + /// need to change when #71 lands. + AdminCancelled, +} + +/// Pinned in full onto every `AssertionV2` at creation time, never mutated +/// afterward. Deployment-wide parameter changes (via a future `initialize`- +/// adjacent admin call) only affect assertions created after the change; an +/// already-open assertion always executes under the snapshot it was created +/// with. See "Policy is pinned when the assertion opens" in +/// V2_RESOLUTION.md. +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PolicySnapshotV2 { + pub token: Address, + pub base_bond: i128, + /// Always equal to `base_bond`: see the rationale on `initialize` below. + pub min_resolution_bond: i128, + pub registration_duration_secs: u64, + /// A qualifying late deposit pushes the soft registration cutoff out by + /// this much, never past `anti_snipe_hard_max_secs` total extension. + pub anti_snipe_extension_secs: u64, + pub anti_snipe_hard_max_secs: u64, + pub reveal_duration_secs: u64, + pub weight_rule: WeightRuleVersion, + pub timeout_default: TimeoutDefaultRule, + pub payout_rule: PayoutRuleVersion, + /// Upper bound on any single position's size, checked at deposit time so + /// settlement's forfeiture-distribution arithmetic (#69) can't overflow. + pub max_position: i128, + /// Upper bound on the frozen eligible total `W`, for the same reason. + pub max_total_weight: i128, +} + +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AssertionV2 { + pub id: u64, + pub asserter: Address, + /// Set once `dispute` (#66) opens registration. `None` while `Pending`. + pub disputer: Option
, + pub outcome: bool, + pub phase: PhaseV2, + pub policy: PolicySnapshotV2, + /// Hash of `policy`'s canonical encoding, computed once at creation and + /// stored alongside it. Lets a client or auditor confirm which exact + /// policy an assertion is bound to without re-deriving the encoding + /// themselves. + pub policy_hash: BytesN<32>, + /// `TerminalCause::NotYetDecided` until `phase == Resolved`. + pub terminal_cause: TerminalCause, + /// The authoritative resolved outcome. `None` until `phase == Resolved`. + /// Stored directly (not only in an event), unlike v1's `Assertion.outcome` + /// which always stays the original claim even after a dispute overturns + /// it, a sharp edge v1 needed a separate `final_outcome` field to fix. + pub final_outcome: Option, +} + +#[contracttype] +pub enum DataKey { + Admin, + Policy, + NextId, + AssertionV2(u64), +} + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub enum Error { + AlreadyInitialized = 1, + NotInitialized = 2, + AssertionNotFound = 3, + /// `base_bond` was not positive, or exceeded the interim safety bound + /// below. + InvalidBondAmount = 4, + InvalidRegistrationDuration = 5, + InvalidRevealDuration = 6, + /// `anti_snipe_extension_secs` exceeded `anti_snipe_hard_max_secs`, which + /// would let a single qualifying deposit blow past the deployment's own + /// stated hard cap in one step. + InvalidAntiSnipeParams = 7, + InvalidMaxPosition = 8, + InvalidMaxTotalWeight = 9, +} + +const DAY_IN_LEDGERS: u32 = 17280; +const INSTANCE_BUMP_AMOUNT: u32 = 30 * DAY_IN_LEDGERS; +const INSTANCE_LIFETIME_THRESHOLD: u32 = INSTANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; + +const MAX_REGISTRATION_DURATION_SECS: u64 = 7 * 24 * 60 * 60; +const MAX_REVEAL_DURATION_SECS: u64 = 7 * 24 * 60 * 60; + +/// Interim safety bound on `base_bond`, reused from v1's `MAX_BOND_AMOUNT` +/// derivation (i128::MAX bounded by the tighter of the dispute-balance-sum +/// and a reward-multiply overflow). V2's actual settlement formula +/// (`s_i * forfeited_pool / recipient_weight`, see #69) has different +/// overflow characteristics and needs its own derivation once that +/// arithmetic exists; this bound is deliberately conservative until then, +/// not a final answer. +const MAX_BOND_AMOUNT: i128 = i128::MAX / 1_000; + +#[contract] +pub struct TholosV2; + +#[contractimpl] +impl TholosV2 { + /// One-time setup, pinning the deployment-wide defaults every future + /// assertion's `PolicySnapshotV2` is built from. Requires `admin`'s + /// signature. Fails with `AlreadyInitialized` if called twice. + #[allow(clippy::too_many_arguments)] + pub fn initialize( + env: Env, + admin: Address, + token: Address, + base_bond: i128, + registration_duration_secs: u64, + anti_snipe_extension_secs: u64, + anti_snipe_hard_max_secs: u64, + reveal_duration_secs: u64, + max_position: i128, + max_total_weight: i128, + ) -> Result<(), Error> { + admin.require_auth(); + + if env.storage().instance().has(&DataKey::Admin) { + return Err(Error::AlreadyInitialized); + } + + if base_bond <= 0 || base_bond > MAX_BOND_AMOUNT { + return Err(Error::InvalidBondAmount); + } + if registration_duration_secs == 0 + || registration_duration_secs > MAX_REGISTRATION_DURATION_SECS + { + return Err(Error::InvalidRegistrationDuration); + } + if reveal_duration_secs == 0 || reveal_duration_secs > MAX_REVEAL_DURATION_SECS { + return Err(Error::InvalidRevealDuration); + } + if anti_snipe_extension_secs > anti_snipe_hard_max_secs { + return Err(Error::InvalidAntiSnipeParams); + } + // max_total_weight's own bounds must be checked before comparing + // max_position against it, otherwise a max_total_weight <= 0 always + // trips the max_position check first (no positive max_position can + // ever be <= a non-positive total), making InvalidMaxTotalWeight's + // <= 0 case unreachable. + if max_total_weight <= 0 || max_total_weight > MAX_BOND_AMOUNT { + return Err(Error::InvalidMaxTotalWeight); + } + // A position can't usefully exceed the frozen total it's part of. + if max_position <= 0 || max_position > max_total_weight { + return Err(Error::InvalidMaxPosition); + } + + let policy = PolicySnapshotV2 { + token, + base_bond, + // Equal to base_bond by design: a cheaper minimum would let a + // third party break an asserter/disputer tie for a fraction of + // what the original two parties risked. See #64/#66. + min_resolution_bond: base_bond, + registration_duration_secs, + anti_snipe_extension_secs, + anti_snipe_hard_max_secs, + reveal_duration_secs, + weight_rule: WeightRuleVersion::LinearStakeV1, + timeout_default: TimeoutDefaultRule::AssertedOutcomeStands, + payout_rule: PayoutRuleVersion::ProRataV1, + max_position, + max_total_weight, + }; + + env.storage().instance().set(&DataKey::Admin, &admin); + env.storage().instance().set(&DataKey::Policy, &policy); + env.storage().instance().set(&DataKey::NextId, &0u64); + env.storage() + .instance() + .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); + + Ok(()) + } + + /// Read-only lookup of the deployment-wide policy defaults new assertions + /// are currently pinned from. Fails with `NotInitialized` before + /// `initialize`. + pub fn get_policy(env: Env) -> Result { + env.storage() + .instance() + .get(&DataKey::Policy) + .ok_or(Error::NotInitialized) + } + + /// Read-only lookup of one assertion. Fails with `AssertionNotFound` if + /// the id doesn't exist. + pub fn get_assertion(env: Env, id: u64) -> Result { + env.storage() + .persistent() + .get(&DataKey::AssertionV2(id)) + .ok_or(Error::AssertionNotFound) + } + + /// Builds and stores a `Pending` `AssertionV2` with a freshly pinned + /// policy snapshot, without moving any tokens or requiring the + /// asserter's bond. Exists so this issue's policy-pinning behavior is + /// independently testable before #65 wires up the real, bond-transferring + /// `assert_outcome` entrypoint on top of this same helper. + /// + /// Not called from any `#[contractimpl]` fn yet, only from tests, hence + /// `allow(dead_code)`. #65 removes this allow when it adds the public + /// entrypoint that calls it for real. + #[allow(dead_code)] + fn create_pending_assertion(env: &Env, asserter: Address, outcome: bool) -> Result { + let policy: PolicySnapshotV2 = env + .storage() + .instance() + .get(&DataKey::Policy) + .ok_or(Error::NotInitialized)?; + + let id: u64 = env + .storage() + .instance() + .get(&DataKey::NextId) + .ok_or(Error::NotInitialized)?; + env.storage().instance().set(&DataKey::NextId, &(id + 1)); + + let policy_hash = env.crypto().sha256(&policy.clone().to_xdr(env)).into(); + + let assertion = AssertionV2 { + id, + asserter, + disputer: None, + outcome, + phase: PhaseV2::Pending, + policy, + policy_hash, + terminal_cause: TerminalCause::NotYetDecided, + final_outcome: None, + }; + + env.storage() + .persistent() + .set(&DataKey::AssertionV2(id), &assertion); + env.storage().persistent().extend_ttl( + &DataKey::AssertionV2(id), + INSTANCE_LIFETIME_THRESHOLD, + INSTANCE_BUMP_AMOUNT, + ); + + Ok(id) + } +} + +mod test; diff --git a/contracts/tholos-v2/src/test.rs b/contracts/tholos-v2/src/test.rs new file mode 100644 index 0000000..a2ddaae --- /dev/null +++ b/contracts/tholos-v2/src/test.rs @@ -0,0 +1,518 @@ +#![cfg(test)] + +use super::*; +use soroban_sdk::testutils::Address as _; + +const DEFAULT_BOND: i128 = 100; +const DEFAULT_REGISTRATION_SECS: u64 = 3600; +const DEFAULT_ANTI_SNIPE_EXT_SECS: u64 = 300; +const DEFAULT_ANTI_SNIPE_HARD_MAX_SECS: u64 = 1800; +const DEFAULT_REVEAL_SECS: u64 = 3600; +const DEFAULT_MAX_POSITION: i128 = 1_000_000; +const DEFAULT_MAX_TOTAL_WEIGHT: i128 = 10_000_000; + +/// A ready-to-use, already-initialized TholosV2 instance with default +/// parameters. Tests that need an *uninitialized* contract, or non-default +/// init parameters, call `initialize` directly instead. +struct Fixture { + env: Env, + contract_id: Address, + admin: Address, + token: Address, +} + +impl Fixture { + fn new() -> Self { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + .unwrap(); + }); + + Fixture { + env, + contract_id, + admin, + token, + } + } + + fn generate(&self) -> Address { + Address::generate(&self.env) + } +} + +#[test] +fn test_initialize_pins_expected_policy() { + let f = Fixture::new(); + + let policy = f.env.as_contract(&f.contract_id, || { + TholosV2::get_policy(f.env.clone()).unwrap() + }); + + assert_eq!(policy.token, f.token); + assert_eq!(policy.base_bond, DEFAULT_BOND); + // Decided in #64: minimum external resolution bond always equals the + // base bond, so a third party can't break a tie for less than the + // asserter/disputer risked. + assert_eq!(policy.min_resolution_bond, DEFAULT_BOND); + assert_eq!(policy.registration_duration_secs, DEFAULT_REGISTRATION_SECS); + assert_eq!( + policy.anti_snipe_extension_secs, + DEFAULT_ANTI_SNIPE_EXT_SECS + ); + assert_eq!( + policy.anti_snipe_hard_max_secs, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS + ); + assert_eq!(policy.reveal_duration_secs, DEFAULT_REVEAL_SECS); + assert_eq!(policy.weight_rule, WeightRuleVersion::LinearStakeV1); + assert_eq!( + policy.timeout_default, + TimeoutDefaultRule::AssertedOutcomeStands + ); + assert_eq!(policy.payout_rule, PayoutRuleVersion::ProRataV1); + assert_eq!(policy.max_position, DEFAULT_MAX_POSITION); + assert_eq!(policy.max_total_weight, DEFAULT_MAX_TOTAL_WEIGHT); +} + +#[test] +fn test_initialize_twice_fails() { + let f = Fixture::new(); + + let result = f.env.as_contract(&f.contract_id, || { + TholosV2::initialize( + f.env.clone(), + f.admin.clone(), + f.token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::AlreadyInitialized)); +} + +#[test] +fn test_get_policy_before_initialize_fails() { + let env = Env::default(); + let contract_id = env.register(TholosV2, ()); + + let result = env.as_contract(&contract_id, || TholosV2::get_policy(env.clone())); + + assert_eq!(result, Err(Error::NotInitialized)); +} + +fn init_with_bond( + env: &Env, + contract_id: &Address, + admin: &Address, + token: &Address, + bond: i128, +) -> Result<(), Error> { + env.as_contract(contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + bond, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }) +} + +#[test] +fn test_initialize_rejects_zero_bond() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = init_with_bond(&env, &contract_id, &admin, &token, 0); + assert_eq!(result, Err(Error::InvalidBondAmount)); +} + +#[test] +fn test_initialize_rejects_negative_bond() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = init_with_bond(&env, &contract_id, &admin, &token, -1); + assert_eq!(result, Err(Error::InvalidBondAmount)); +} + +#[test] +fn test_initialize_rejects_bond_over_max() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = init_with_bond(&env, &contract_id, &admin, &token, MAX_BOND_AMOUNT + 1); + assert_eq!(result, Err(Error::InvalidBondAmount)); +} + +#[test] +fn test_initialize_accepts_bond_at_max() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = init_with_bond(&env, &contract_id, &admin, &token, MAX_BOND_AMOUNT); + assert_eq!(result, Ok(())); +} + +#[test] +fn test_initialize_rejects_zero_registration_duration() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + 0, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidRegistrationDuration)); +} + +#[test] +fn test_initialize_rejects_registration_duration_over_max() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + MAX_REGISTRATION_DURATION_SECS + 1, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidRegistrationDuration)); +} + +#[test] +fn test_initialize_rejects_zero_reveal_duration() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + 0, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidRevealDuration)); +} + +#[test] +fn test_initialize_rejects_anti_snipe_extension_over_hard_max() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + // Extension bigger than its own hard max: a single qualifying + // deposit could blow past the deployment's stated cap in one step. + 2000, + 1800, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidAntiSnipeParams)); +} + +#[test] +fn test_initialize_accepts_anti_snipe_extension_equal_to_hard_max() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + 1800, + 1800, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Ok(())); +} + +#[test] +fn test_initialize_rejects_max_position_over_max_total_weight() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + // A single position that could exceed the entire frozen total + // it's supposedly part of is nonsensical. + DEFAULT_MAX_TOTAL_WEIGHT + 1, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidMaxPosition)); +} + +#[test] +fn test_initialize_rejects_zero_max_position() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + 0, + DEFAULT_MAX_TOTAL_WEIGHT, + ) + }); + + assert_eq!(result, Err(Error::InvalidMaxPosition)); +} + +#[test] +fn test_initialize_rejects_zero_max_total_weight() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + DEFAULT_MAX_POSITION, + 0, + ) + }); + + assert_eq!(result, Err(Error::InvalidMaxTotalWeight)); +} + +#[test] +fn test_initialize_rejects_max_total_weight_over_max_bond() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let admin = Address::generate(&env); + let token = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::initialize( + env.clone(), + admin.clone(), + token.clone(), + DEFAULT_BOND, + DEFAULT_REGISTRATION_SECS, + DEFAULT_ANTI_SNIPE_EXT_SECS, + DEFAULT_ANTI_SNIPE_HARD_MAX_SECS, + DEFAULT_REVEAL_SECS, + MAX_BOND_AMOUNT, + MAX_BOND_AMOUNT + 1, + ) + }); + + assert_eq!(result, Err(Error::InvalidMaxTotalWeight)); +} + +#[test] +fn test_create_pending_assertion_pins_policy_and_stores_assertion() { + let f = Fixture::new(); + let asserter = f.generate(); + + let id = f.env.as_contract(&f.contract_id, || { + TholosV2::create_pending_assertion(&f.env, asserter.clone(), true).unwrap() + }); + assert_eq!(id, 0); + + let assertion = f.env.as_contract(&f.contract_id, || { + TholosV2::get_assertion(f.env.clone(), id).unwrap() + }); + + assert_eq!(assertion.id, 0); + assert_eq!(assertion.asserter, asserter); + assert_eq!(assertion.disputer, None); + assert!(assertion.outcome); + assert_eq!(assertion.phase, PhaseV2::Pending); + assert_eq!(assertion.policy.base_bond, DEFAULT_BOND); + assert_eq!(assertion.terminal_cause, TerminalCause::NotYetDecided); + assert_eq!(assertion.final_outcome, None); +} + +#[test] +fn test_create_pending_assertion_ids_increment() { + let f = Fixture::new(); + let asserter = f.generate(); + + let (first, second) = f.env.as_contract(&f.contract_id, || { + let first = TholosV2::create_pending_assertion(&f.env, asserter.clone(), true).unwrap(); + let second = TholosV2::create_pending_assertion(&f.env, asserter.clone(), false).unwrap(); + (first, second) + }); + + assert_eq!(first, 0); + assert_eq!(second, 1); +} + +#[test] +fn test_create_pending_assertion_before_initialize_fails() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(TholosV2, ()); + let asserter = Address::generate(&env); + + let result = env.as_contract(&contract_id, || { + TholosV2::create_pending_assertion(&env, asserter, true) + }); + + assert_eq!(result, Err(Error::NotInitialized)); +} + +#[test] +fn test_get_assertion_not_found() { + let f = Fixture::new(); + + let result = f + .env + .as_contract(&f.contract_id, || TholosV2::get_assertion(f.env.clone(), 0)); + + assert_eq!(result, Err(Error::AssertionNotFound)); +} + +#[test] +fn test_policy_hash_is_deterministic_for_identical_policy() { + let f = Fixture::new(); + let asserter = f.generate(); + + // Two assertions created under the same unchanged deployment policy must + // hash to the same value: the hash is a function of policy content, not + // of which assertion it's attached to. + let (hash_a, hash_b) = f.env.as_contract(&f.contract_id, || { + let id_a = TholosV2::create_pending_assertion(&f.env, asserter.clone(), true).unwrap(); + let id_b = TholosV2::create_pending_assertion(&f.env, asserter.clone(), false).unwrap(); + let a = TholosV2::get_assertion(f.env.clone(), id_a).unwrap(); + let b = TholosV2::get_assertion(f.env.clone(), id_b).unwrap(); + (a.policy_hash, b.policy_hash) + }); + + assert_eq!(hash_a, hash_b); +} diff --git a/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_before_initialize_fails.1.json b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_before_initialize_fails.1.json new file mode 100644 index 0000000..896f45f --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_before_initialize_fails.1.json @@ -0,0 +1,61 @@ +{ + "generators": { + "address": 2, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_ids_increment.1.json b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_ids_increment.1.json new file mode 100644 index 0000000..5f859c9 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_ids_increment.1.json @@ -0,0 +1,668 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "AssertionV2" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "asserter" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "disputer" + }, + "val": "void" + }, + { + "key": { + "symbol": "final_outcome" + }, + "val": "void" + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "outcome" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "phase" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "policy" + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "policy_hash" + }, + "val": { + "bytes": "13d25a053dfbdd941e6a222312c76e8dfcc6a0826971754c9876d7a9e47538c8" + } + }, + { + "key": { + "symbol": "terminal_cause" + }, + "val": { + "vec": [ + { + "symbol": "NotYetDecided" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "AssertionV2" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "asserter" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "disputer" + }, + "val": "void" + }, + { + "key": { + "symbol": "final_outcome" + }, + "val": "void" + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "outcome" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "phase" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "policy" + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "policy_hash" + }, + "val": { + "bytes": "13d25a053dfbdd941e6a222312c76e8dfcc6a0826971754c9876d7a9e47538c8" + } + }, + { + "key": { + "symbol": "terminal_cause" + }, + "val": { + "vec": [ + { + "symbol": "NotYetDecided" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_pins_policy_and_stores_assertion.1.json b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_pins_policy_and_stores_assertion.1.json new file mode 100644 index 0000000..4f19660 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_create_pending_assertion_pins_policy_and_stores_assertion.1.json @@ -0,0 +1,456 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "AssertionV2" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "asserter" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "disputer" + }, + "val": "void" + }, + { + "key": { + "symbol": "final_outcome" + }, + "val": "void" + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "outcome" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "phase" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "policy" + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "policy_hash" + }, + "val": { + "bytes": "13d25a053dfbdd941e6a222312c76e8dfcc6a0826971754c9876d7a9e47538c8" + } + }, + { + "key": { + "symbol": "terminal_cause" + }, + "val": { + "vec": [ + { + "symbol": "NotYetDecided" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_get_assertion_not_found.1.json b/contracts/tholos-v2/test_snapshots/test/test_get_assertion_not_found.1.json new file mode 100644 index 0000000..0e41100 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_get_assertion_not_found.1.json @@ -0,0 +1,242 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_get_policy_before_initialize_fails.1.json b/contracts/tholos-v2/test_snapshots/test/test_get_policy_before_initialize_fails.1.json new file mode 100644 index 0000000..3a921a4 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_get_policy_before_initialize_fails.1.json @@ -0,0 +1,61 @@ +{ + "generators": { + "address": 1, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_anti_snipe_extension_equal_to_hard_max.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_anti_snipe_extension_equal_to_hard_max.1.json new file mode 100644 index 0000000..1a4f24a --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_anti_snipe_extension_equal_to_hard_max.1.json @@ -0,0 +1,241 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_bond_at_max.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_bond_at_max.1.json new file mode 100644 index 0000000..d707aa4 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_accepts_bond_at_max.1.json @@ -0,0 +1,241 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "170141183460469231731687303715884105" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "170141183460469231731687303715884105" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_pins_expected_policy.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_pins_expected_policy.1.json new file mode 100644 index 0000000..0e41100 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_pins_expected_policy.1.json @@ -0,0 +1,242 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_anti_snipe_extension_over_hard_max.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_anti_snipe_extension_over_hard_max.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_anti_snipe_extension_over_hard_max.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_bond_over_max.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_bond_over_max.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_bond_over_max.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_position_over_max_total_weight.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_position_over_max_total_weight.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_position_over_max_total_weight.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_total_weight_over_max_bond.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_total_weight_over_max_bond.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_max_total_weight_over_max_bond.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_negative_bond.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_negative_bond.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_negative_bond.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_registration_duration_over_max.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_registration_duration_over_max.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_registration_duration_over_max.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_bond.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_bond.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_bond.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_position.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_position.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_position.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_total_weight.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_total_weight.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_max_total_weight.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_registration_duration.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_registration_duration.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_registration_duration.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_reveal_duration.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_reveal_duration.1.json new file mode 100644 index 0000000..0a3e45b --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_rejects_zero_reveal_duration.1.json @@ -0,0 +1,95 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_initialize_twice_fails.1.json b/contracts/tholos-v2/test_snapshots/test/test_initialize_twice_fails.1.json new file mode 100644 index 0000000..d54d8be --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_initialize_twice_fails.1.json @@ -0,0 +1,276 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/tholos-v2/test_snapshots/test/test_policy_hash_is_deterministic_for_identical_policy.1.json b/contracts/tholos-v2/test_snapshots/test/test_policy_hash_is_deterministic_for_identical_policy.1.json new file mode 100644 index 0000000..5f859c9 --- /dev/null +++ b/contracts/tholos-v2/test_snapshots/test/test_policy_hash_is_deterministic_for_identical_policy.1.json @@ -0,0 +1,668 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 26, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "AssertionV2" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "asserter" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "disputer" + }, + "val": "void" + }, + { + "key": { + "symbol": "final_outcome" + }, + "val": "void" + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "outcome" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "phase" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "policy" + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "policy_hash" + }, + "val": { + "bytes": "13d25a053dfbdd941e6a222312c76e8dfcc6a0826971754c9876d7a9e47538c8" + } + }, + { + "key": { + "symbol": "terminal_cause" + }, + "val": { + "vec": [ + { + "symbol": "NotYetDecided" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "AssertionV2" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "asserter" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "disputer" + }, + "val": "void" + }, + { + "key": { + "symbol": "final_outcome" + }, + "val": "void" + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "outcome" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "phase" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "policy" + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "policy_hash" + }, + "val": { + "bytes": "13d25a053dfbdd941e6a222312c76e8dfcc6a0826971754c9876d7a9e47538c8" + } + }, + { + "key": { + "symbol": "terminal_cause" + }, + "val": { + "vec": [ + { + "symbol": "NotYetDecided" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Policy" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "anti_snipe_extension_secs" + }, + "val": { + "u64": "300" + } + }, + { + "key": { + "symbol": "anti_snipe_hard_max_secs" + }, + "val": { + "u64": "1800" + } + }, + { + "key": { + "symbol": "base_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "max_position" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "max_total_weight" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "min_resolution_bond" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "payout_rule" + }, + "val": { + "vec": [ + { + "symbol": "ProRataV1" + } + ] + } + }, + { + "key": { + "symbol": "registration_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "reveal_duration_secs" + }, + "val": { + "u64": "3600" + } + }, + { + "key": { + "symbol": "timeout_default" + }, + "val": { + "vec": [ + { + "symbol": "AssertedOutcomeStands" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "weight_rule" + }, + "val": { + "vec": [ + { + "symbol": "LinearStakeV1" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 518400 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/docs/src/CHANGELOG.md b/docs/src/CHANGELOG.md index 2d0d8b1..8ba6534 100644 --- a/docs/src/CHANGELOG.md +++ b/docs/src/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [Unreleased] + +### Added + +- `contracts/tholos-v2`: a new, wholly separate contract crate for protocol + v2 (stake-weighted resolution, design in `docs/src/V2_RESOLUTION.md`), + never upgraded in place from v1. This first issue (#64) implements the + immutable `PolicySnapshotV2` pinned at assertion creation and the + `AssertionV2` record it lives on, plus `initialize` and read-only lookups. + Registration, reveal, outcome resolution, settlement, and the freeze/cancel + mechanism are separate issues (#65-#71) landing as the crate grows. Closes #64. + ## [0.3.0] - 2026-08-08 ### Added