diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a9d623..6e6ec9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,11 +58,13 @@ jobs: restore-keys: ${{ runner.os }}-cargo- - name: Build contracts - run: cargo build --target wasm32-unknown-unknown --release + run: | + cd contracts/escrow && cargo build --target wasm32-unknown-unknown --release - name: Upload WASM artifacts uses: actions/upload-artifact@v4 with: name: wasm-contracts - path: target/wasm32-unknown-unknown/release/*.wasm + path: | + contracts/*/target/wasm32-unknown-unknown/release/*.wasm retention-days: 7 diff --git a/.gitignore b/.gitignore index fedaa2b..cb624f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target .env +**/test_snapshots/ diff --git a/.kiro/settings/lsp.json b/.kiro/settings/lsp.json new file mode 100644 index 0000000..68dd045 --- /dev/null +++ b/.kiro/settings/lsp.json @@ -0,0 +1,198 @@ +{ + "languages": { + "rust": { + "name": "rust-analyzer", + "command": "rust-analyzer", + "args": [], + "file_extensions": [ + "rs" + ], + "project_patterns": [ + "Cargo.toml" + ], + "exclude_patterns": [ + "**/target/**" + ], + "multi_workspace": false, + "initialization_options": { + "cargo": { + "buildScripts": { + "enable": true + } + }, + "diagnostics": { + "enable": true, + "enableExperimental": true + }, + "workspace": { + "symbol": { + "search": { + "scope": "workspace" + } + } + } + }, + "request_timeout_secs": 60 + }, + "java": { + "name": "jdtls", + "command": "jdtls", + "args": [], + "file_extensions": [ + "java" + ], + "project_patterns": [ + "pom.xml", + "build.gradle", + "build.gradle.kts", + ".project" + ], + "exclude_patterns": [ + "**/target/**", + "**/build/**", + "**/.gradle/**" + ], + "multi_workspace": false, + "initialization_options": { + "settings": { + "java": { + "compile": { + "nullAnalysis": { + "mode": "automatic" + } + }, + "configuration": { + "annotationProcessing": { + "enabled": true + } + } + } + } + }, + "request_timeout_secs": 60 + }, + "go": { + "name": "gopls", + "command": "gopls", + "args": [], + "file_extensions": [ + "go" + ], + "project_patterns": [ + "go.mod", + "go.sum" + ], + "exclude_patterns": [ + "**/vendor/**" + ], + "multi_workspace": false, + "initialization_options": { + "usePlaceholders": true, + "completeUnimported": true + }, + "request_timeout_secs": 60 + }, + "ruby": { + "name": "solargraph", + "command": "solargraph", + "args": [ + "stdio" + ], + "file_extensions": [ + "rb" + ], + "project_patterns": [ + "Gemfile", + "Rakefile" + ], + "exclude_patterns": [ + "**/vendor/**", + "**/tmp/**" + ], + "multi_workspace": false, + "initialization_options": {}, + "request_timeout_secs": 60 + }, + "typescript": { + "name": "typescript-language-server", + "command": "typescript-language-server", + "args": [ + "--stdio" + ], + "file_extensions": [ + "ts", + "js", + "tsx", + "jsx" + ], + "project_patterns": [ + "package.json", + "tsconfig.json" + ], + "exclude_patterns": [ + "**/node_modules/**", + "**/dist/**" + ], + "multi_workspace": false, + "initialization_options": { + "preferences": { + "disableSuggestions": false + } + }, + "request_timeout_secs": 60 + }, + "python": { + "name": "pyright", + "command": "pyright-langserver", + "args": [ + "--stdio" + ], + "file_extensions": [ + "py" + ], + "project_patterns": [ + "pyproject.toml", + "setup.py", + "requirements.txt", + "pyrightconfig.json" + ], + "exclude_patterns": [ + "**/__pycache__/**", + "**/venv/**", + "**/.venv/**", + "**/.pytest_cache/**" + ], + "multi_workspace": false, + "initialization_options": {}, + "request_timeout_secs": 60 + }, + "cpp": { + "name": "clangd", + "command": "clangd", + "args": [ + "--background-index" + ], + "file_extensions": [ + "cpp", + "cc", + "cxx", + "c", + "h", + "hpp", + "hxx" + ], + "project_patterns": [ + "CMakeLists.txt", + "compile_commands.json", + "Makefile" + ], + "exclude_patterns": [ + "**/build/**", + "**/cmake-build-**/**" + ], + "multi_workspace": false, + "initialization_options": {}, + "request_timeout_secs": 60 + } + } +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5480842 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "kiroAgent.configureMCP": "Disabled" +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 6f87ca8..f791a9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -545,6 +545,7 @@ checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" name = "escrow" version = "0.1.0" dependencies = [ + "oracle", "soroban-sdk", ] @@ -846,6 +847,7 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" name = "oracle" version = "0.1.0" dependencies = [ + "escrow", "soroban-sdk", ] diff --git a/README.md b/README.md deleted file mode 100644 index 3ada41e..0000000 --- a/README.md +++ /dev/null @@ -1,217 +0,0 @@ -# Checkmate-Escrow β€” Competitive Chess Betting on Stellar - -A trustless chess wagering platform built on Stellar Soroban smart contracts. Players stake XLM or USDC before a match, and the winner is automatically paid out the moment the game ends β€” no middleman, no delays, no trust required. - -## 🎯 What is Checkmate-Escrow? - -Checkmate-Escrow combines competitive chess with Stellar's fast settlement to create a fully on-chain betting platform for casual and high-stakes matches. - -Players: - -- Stake XLM or USDC into a Soroban escrow contract before a match begins -- Play their game on Lichess or Chess.com as normal -- Receive automatic payouts the instant the match result is verified on-chain - -A custom Oracle bridges the Chess.com / Lichess API to the smart contract, verifying match results and triggering payouts without any manual intervention. - -This makes Checkmate-Escrow: - -βœ… Trustless (no platform can withhold or delay winnings) -βœ… Transparent (all stakes and payouts are verifiable on-chain) -βœ… Instant (Stellar's fast finality means payouts settle in seconds) -βœ… Accessible (anyone with a Stellar wallet can participate) - -## πŸš€ Features - -- **Create a Match**: Set stake amount, currency (XLM or USDC), and link a Lichess/Chess.com game ID -- **Escrow Stakes**: Both players deposit funds into the contract before the game starts -- **Oracle Integration**: Real-time result verification via Lichess/Chess.com APIs -- **Automatic Payouts**: Winner receives the full pot the moment the result is confirmed -- **Draw Handling**: Stakes are returned to both players in the event of a draw -- **Transparent**: All escrow balances and payout history are verifiable on-chain - -## πŸ› οΈ Quick Start - -### Prerequisites - -- Rust (1.70+) -- Soroban CLI -- Stellar CLI - -### Build - -```bash -./scripts/build.sh -``` - -### Test - -```bash -./scripts/test.sh -``` - -### Setup Environment - -Copy the example environment file: - -```bash -cp .env.example .env -``` - -Configure your environment variables in `.env`: - -```env -# Network configuration -STELLAR_NETWORK=testnet -STELLAR_RPC_URL=https://soroban-testnet.stellar.org - -# Contract addresses (after deployment) -CONTRACT_ESCROW= -CONTRACT_ORACLE= - -# Oracle configuration -LICHESS_API_TOKEN= -CHESSDOTCOM_API_KEY= - -# Frontend configuration -VITE_STELLAR_NETWORK=testnet -VITE_STELLAR_RPC_URL=https://soroban-testnet.stellar.org -``` - -Network configurations are defined in `environments.toml`: - -- `testnet` β€” Stellar testnet -- `mainnet` β€” Stellar mainnet -- `futurenet` β€” Stellar futurenet -- `standalone` β€” Local development - -### Deploy to Testnet - -```bash -# Configure your testnet identity first -stellar keys generate deployer --network testnet - -# Deploy -./scripts/deploy_testnet.sh -``` - -### Run Demo - -Follow the step-by-step guide in `demo/demo-script.md` - -## πŸ“– Documentation - -- [Architecture Overview](docs/architecture.md) -- [Oracle Design](docs/oracle.md) -- [Threat Model & Security](docs/security.md) -- [Roadmap](docs/roadmap.md) - -## πŸŽ“ Smart Contract API - -### Match Management - -``` -create_match(stake_amount, token, game_id, platform) -> u64 -get_match(match_id) -> Match -cancel_match(match_id) -``` - -### Escrow - -``` -deposit(match_id) -get_escrow_balance(match_id) -> i128 -is_funded(match_id) -> bool -``` - -### Oracle & Payouts - -``` -submit_result(match_id, winner) -verify_result(match_id) -> bool -execute_payout(match_id) -``` - -## πŸ§ͺ Testing - -Comprehensive test suite covering: - -βœ… Match creation and configuration -βœ… Deposit validation and escrow locking -βœ… Oracle result submission and verification -βœ… Winner payout and draw refund logic -βœ… Cancellation and edge cases -βœ… Error handling and security checks - -Run tests: - -```bash -cargo test -``` - -## 🌍 Why This Matters - -**The Problem**: Current chess betting and tournament prize payouts are slow and rely entirely on the platform's honesty. Players have no guarantee their winnings will be paid out fairly or on time. - -**The Solution**: By holding stakes in a Soroban smart contract and automating payouts via a verified Oracle, Checkmate-Escrow removes the need to trust any third party. - -**Blockchain Benefits**: - -- No platform can withhold or manipulate payouts -- Transparent stake and payout history for every match -- Programmable rules enforced by smart contracts -- Accessible to anyone with a Stellar wallet - -**Target Users**: - -- Competitive chess players looking for trustless wagering -- Chess clubs and tournament organizers -- Casual players wanting skin-in-the-game matches -- Developers building on Stellar/Soroban - -## πŸ—ΊοΈ Roadmap - -- **v1.0 (Current)**: XLM-only escrow, Lichess Oracle integration, basic match flow -- **v1.1**: USDC and custom token support, Chess.com Oracle -- **v2.0**: Multi-game tournaments, bracket payouts -- **v3.0**: Frontend UI with wallet integration -- **v4.0**: Mobile app, ELO-based matchmaking, leaderboards - -See [docs/roadmap.md](docs/roadmap.md) for details. - -## 🀝 Contributing - -We welcome contributions! Please: - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'Add amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request - -See our [Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing Guidelines](CONTRIBUTING.md). - -## 🌊 Drips Wave Contributors - -This project participates in Drips Wave β€” a contributor funding program! Check out: - -- [Wave Contributor Guide](docs/wave-guide.md) β€” How to earn funding for contributions -- [Wave-Ready Issues](https://github.com/issues?q=label%3Awave-ready) β€” Funded issues ready to tackle -- GitHub Issues labeled with `wave-ready` β€” Earn 100–200 points per issue - -Issues are categorized as: - -- `trivial` (100 points) β€” Documentation, simple tests, minor fixes -- `medium` (150 points) β€” Oracle helpers, validation logic, moderate features -- `high` (200 points) β€” Core escrow logic, Oracle integrations, security enhancements - -## πŸ“„ License - -This project is licensed under the MIT License β€” see the [LICENSE](LICENSE) file for details. - -## πŸ™ Acknowledgments - -- [Stellar Development Foundation](https://stellar.org) for Soroban -- [Lichess](https://lichess.org) for their open API -- [Chess.com](https://chess.com) for their developer platform -- Drips Wave for supporting public goods funding diff --git a/contracts/escrow/Cargo.toml b/contracts/escrow/Cargo.toml index f7b3c71..ef6d535 100644 --- a/contracts/escrow/Cargo.toml +++ b/contracts/escrow/Cargo.toml @@ -11,3 +11,4 @@ soroban-sdk = { workspace = true } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } +oracle = { path = "../oracle" } diff --git a/contracts/escrow/TODO.md b/contracts/escrow/TODO.md deleted file mode 100644 index 344cdbc..0000000 --- a/contracts/escrow/TODO.md +++ /dev/null @@ -1,13 +0,0 @@ -# Double-Initialize Fix TODO - -**Progress: Starting implementation** - -## Steps: -- [ ] 1. Add `AlreadyInitialized = 7,` to `Error` enum in `src/errors.rs` -- [ ] 2. Edit `initialize` in `src/lib.rs` to check `env.storage().instance().has(&DataKey::Oracle)` and panic with `Error::AlreadyInitialized` if exists, else set Oracle and MatchCount -- [ ] 3. Add `test_double_initialize_fails()` in `src/tests.rs` that calls initialize twice and asserts second panics -- [ ] 4. Run `cargo test` in contracts/escrow to verify and update snapshots if needed -- [x] 5. Update TODO.md after each step - -Current status: Files analyzed, plan approved. - diff --git a/contracts/escrow/src/errors.rs b/contracts/escrow/src/errors.rs index 5f427f6..1799e89 100644 --- a/contracts/escrow/src/errors.rs +++ b/contracts/escrow/src/errors.rs @@ -13,4 +13,11 @@ pub enum Error { Overflow = 8, ContractPaused = 9, InvalidAmount = 10, + MatchCancelled = 11, + MatchCompleted = 12, + DuplicateGameId = 13, + MatchNotExpired = 14, + InvalidGameId = 15, + ResultNotFound = 16, + InvalidToken = 17, } diff --git a/contracts/escrow/src/lib.rs b/contracts/escrow/src/lib.rs index 91a2110..c0d6b87 100644 --- a/contracts/escrow/src/lib.rs +++ b/contracts/escrow/src/lib.rs @@ -1,22 +1,43 @@ #![no_std] -mod errors; -mod types; +pub mod errors; +pub mod types; use errors::Error; -use soroban_sdk::{contract, contractimpl, symbol_short, token, Address, Env, String, Symbol}; -use types::{DataKey, Match, MatchState, Platform, Winner}; +use soroban_sdk::{ + contract, contractimpl, symbol_short, token, vec, Address, Env, IntoVal, String, Symbol, + TryFromVal, +}; +use types::{DataKey, Match, MatchState, OracleMatchResult, OracleResultEntry, Platform, Winner}; -/// ~30 days at 5s/ledger. Used as both the TTL threshold and the extend-to value. +/// ~30 days at 5s/ledger. Storage TTL only β€” controls how long match data is kept on-chain. const MATCH_TTL_LEDGERS: u32 = 518_400; +/// ~7 days at 5s/ledger. Business timeout β€” how long a Pending match may wait +/// for both deposits before anyone can call `expire_match`. +const MATCH_TIMEOUT_LEDGERS: u32 = 120_960; + +/// Maximum allowed byte length for a game_id string. +/// +/// Platform-specific formats: +/// - Lichess: 8 alphanumeric characters (e.g. `"abcd1234"`) +/// - Chess.com: numeric string, typically 7–12 digits (e.g. `"123456789"`) +/// +/// Both formats fit well within this limit. +const MAX_GAME_ID_LEN: u32 = 64; + #[contract] pub struct EscrowContract; #[contractimpl] impl EscrowContract { /// Initialize the contract with a trusted oracle address and an admin. - pub fn initialize(env: Env, oracle: Address, admin: Address) { + /// + /// Must be called by the deployer immediately after deployment. + /// The deployer address is passed as `deployer` and must authorize this call, + /// preventing any third party from front-running initialization. + pub fn initialize(env: Env, oracle: Address, admin: Address, deployer: Address) { + deployer.require_auth(); if env.storage().instance().has(&DataKey::Oracle) { panic!("Contract already initialized"); } @@ -24,6 +45,10 @@ impl EscrowContract { env.storage().instance().set(&DataKey::Admin, &admin); env.storage().instance().set(&DataKey::MatchCount, &0u64); env.storage().instance().set(&DataKey::Paused, &false); + env.events().publish( + (Symbol::new(&env, "admin"), symbol_short!("init")), + (oracle, admin), + ); } /// Pause the contract β€” admin only. Blocks create_match, deposit, and submit_result. @@ -35,6 +60,8 @@ impl EscrowContract { .ok_or(Error::Unauthorized)?; admin.require_auth(); env.storage().instance().set(&DataKey::Paused, &true); + env.events() + .publish((Symbol::new(&env, "admin"), symbol_short!("paused")), ()); Ok(()) } @@ -47,10 +74,55 @@ impl EscrowContract { .ok_or(Error::Unauthorized)?; admin.require_auth(); env.storage().instance().set(&DataKey::Paused, &false); + env.events() + .publish((Symbol::new(&env, "admin"), symbol_short!("unpaused")), ()); + Ok(()) + } + + /// Rotate the oracle address. Requires authorization from the current oracle or the admin. + pub fn update_oracle(env: Env, new_oracle: Address, caller: Address) -> Result<(), Error> { + let current_oracle: Address = env + .storage() + .instance() + .get(&DataKey::Oracle) + .ok_or(Error::Unauthorized)?; + let admin: Address = env + .storage() + .instance() + .get(&DataKey::Admin) + .ok_or(Error::Unauthorized)?; + + if caller != current_oracle && caller != admin { + return Err(Error::Unauthorized); + } + caller.require_auth(); + + env.storage().instance().set(&DataKey::Oracle, &new_oracle); + + env.events().publish( + (Symbol::new(&env, "admin"), symbol_short!("oracle_up")), + (current_oracle, new_oracle), + ); + Ok(()) } /// Create a new match. Both players must call `deposit` before the game starts. + /// + /// # Parameters + /// - `game_id`: The platform-specific game identifier. Must be ≀ 64 bytes. + /// - **Lichess**: 8-character alphanumeric string (e.g. `"abcd1234"`). + /// Taken from the game URL: `https://lichess.org/` + /// - **Chess.com**: numeric string, typically 7–12 digits (e.g. `"123456789"`). + /// Taken from the game URL: `https://www.chess.com/game/live/` + /// Passing an ID from the wrong platform or a malformed ID will not be + /// rejected on-chain, but the oracle will fail to verify the result. + /// - `platform`: Must match the platform the `game_id` was issued by. + /// Use `Platform::Lichess` or `Platform::ChessDotCom` accordingly. + /// + /// # Errors + /// Returns `Error::InvalidGameId` if `game_id` exceeds `MAX_GAME_ID_LEN` (64 bytes). + /// Returns `Error::DuplicateGameId` if the same `game_id` has already been used. pub fn create_match( env: Env, player1: Address, @@ -62,12 +134,44 @@ impl EscrowContract { ) -> Result { player1.require_auth(); - if env.storage().instance().get(&DataKey::Paused).unwrap_or(false) { + if env + .storage() + .instance() + .get(&DataKey::Paused) + .unwrap_or(false) + { return Err(Error::ContractPaused); } if stake_amount <= 0 { return Err(Error::InvalidAmount); } + if game_id.len() == 0 || game_id.len() > MAX_GAME_ID_LEN { + return Err(Error::InvalidGameId); + } + + if env + .storage() + .persistent() + .has(&DataKey::GameId(game_id.clone())) + { + return Err(Error::DuplicateGameId); + } + + // Validate that `token` implements the token interface by probing `balance`. + // An invalid address will cause try_invoke_contract to return Err, which we + // map to Error::InvalidToken rather than letting it panic at deposit time. + { + use soroban_sdk::IntoVal; + let args = vec![&env, env.current_contract_address().into_val(&env)]; + let probe: Result<_, _> = env.try_invoke_contract::( + &token, + &Symbol::new(&env, "balance"), + args, + ); + if probe.is_err() { + return Err(Error::InvalidToken); + } + } let id: u64 = env .storage() @@ -90,6 +194,8 @@ impl EscrowContract { state: MatchState::Pending, player1_deposited: false, player2_deposited: false, + created_ledger: env.ledger().sequence(), + winner: None, }; env.storage().persistent().set(&DataKey::Match(id), &m); @@ -100,9 +206,10 @@ impl EscrowContract { ); // Guard against u64 overflow in release mode where wrapping would occur silently let next_id = id.checked_add(1).ok_or(Error::Overflow)?; + env.storage().instance().set(&DataKey::MatchCount, &next_id); env.storage() - .instance() - .set(&DataKey::MatchCount, &next_id); + .persistent() + .set(&DataKey::GameId(m.game_id.clone()), &true); env.events().publish( (Symbol::new(&env, "match"), symbol_short!("created")), @@ -116,7 +223,12 @@ impl EscrowContract { pub fn deposit(env: Env, match_id: u64, player: Address) -> Result<(), Error> { player.require_auth(); - if env.storage().instance().get(&DataKey::Paused).unwrap_or(false) { + if env + .storage() + .instance() + .get(&DataKey::Paused) + .unwrap_or(false) + { return Err(Error::ContractPaused); } @@ -126,6 +238,12 @@ impl EscrowContract { .get(&DataKey::Match(match_id)) .ok_or(Error::MatchNotFound)?; + if m.state == MatchState::Cancelled { + return Err(Error::MatchCancelled); + } + if m.state == MatchState::Completed { + return Err(Error::MatchCompleted); + } if m.state != MatchState::Pending { return Err(Error::InvalidState); } @@ -154,6 +272,10 @@ impl EscrowContract { if m.player1_deposited && m.player2_deposited { m.state = MatchState::Active; + env.events().publish( + (Symbol::new(&env, "match"), symbol_short!("activated")), + match_id, + ); } env.storage() @@ -168,8 +290,13 @@ impl EscrowContract { } /// Oracle submits the verified match result and triggers payout. - pub fn submit_result(env: Env, match_id: u64, winner: Winner) -> Result<(), Error> { - if env.storage().instance().get(&DataKey::Paused).unwrap_or(false) { + pub fn submit_result(env: Env, match_id: u64, caller: Address) -> Result<(), Error> { + if env + .storage() + .instance() + .get(&DataKey::Paused) + .unwrap_or(false) + { return Err(Error::ContractPaused); } @@ -178,7 +305,11 @@ impl EscrowContract { .instance() .get(&DataKey::Oracle) .ok_or(Error::Unauthorized)?; - oracle.require_auth(); + + if caller != oracle { + return Err(Error::Unauthorized); + } + caller.require_auth(); let mut m: Match = env .storage() @@ -190,8 +321,13 @@ impl EscrowContract { return Err(Error::InvalidState); } + if !m.player1_deposited || !m.player2_deposited { + return Err(Error::NotFunded); + } + + let winner = Self::fetch_oracle_result(&env, &oracle, match_id, &m.game_id)?; let client = token::Client::new(&env, &m.token); - let pot = m.stake_amount * 2; + let pot = m.stake_amount.checked_mul(2).ok_or(Error::Overflow)?; match winner { Winner::Player1 => client.transfer(&env.current_contract_address(), &m.player1, &pot), @@ -203,6 +339,7 @@ impl EscrowContract { } m.state = MatchState::Completed; + m.winner = Some(winner.clone()); env.storage() .persistent() .set(&DataKey::Match(match_id), &m); @@ -218,6 +355,39 @@ impl EscrowContract { Ok(()) } + fn fetch_oracle_result( + env: &Env, + oracle: &Address, + match_id: u64, + expected_game_id: &String, + ) -> Result { + let args = vec![&env, match_id.into_val(env)]; + let symbol = Symbol::new(env, "get_result"); + let call_result: Result< + Result, + Result, + > = env.try_invoke_contract(oracle, &symbol, args); + + let value = match call_result { + Ok(Ok(val)) => val, + _ => return Err(Error::ResultNotFound), + }; + + let entry: OracleResultEntry = + OracleResultEntry::try_from_val(env, &value).map_err(|_| Error::ResultNotFound)?; + + if entry.game_id != *expected_game_id { + return Err(Error::InvalidGameId); + } + + let resolved = match entry.result { + OracleMatchResult::Player1Wins => Winner::Player1, + OracleMatchResult::Player2Wins => Winner::Player2, + OracleMatchResult::Draw => Winner::Draw, + }; + Ok(resolved) + } + /// Cancel a pending match and refund any deposits. /// Either player can cancel a pending match. pub fn cancel_match(env: Env, match_id: u64, caller: Address) -> Result<(), Error> { @@ -231,6 +401,11 @@ impl EscrowContract { return Err(Error::InvalidState); } + // Defensive: the contract itself must never be accepted as a valid caller. + if caller == env.current_contract_address() { + return Err(Error::Unauthorized); + } + // Either player1 or player2 can cancel a pending match let is_p1 = caller == m.player1; let is_p2 = caller == m.player2; @@ -268,12 +443,73 @@ impl EscrowContract { Ok(()) } + /// Expire a pending match that has not been fully funded within MATCH_TIMEOUT_LEDGERS. + /// Anyone can call this; funds are returned to whoever deposited. + pub fn expire_match(env: Env, match_id: u64) -> Result<(), Error> { + let mut m: Match = env + .storage() + .persistent() + .get(&DataKey::Match(match_id)) + .ok_or(Error::MatchNotFound)?; + + if m.state != MatchState::Pending { + return Err(Error::InvalidState); + } + + let elapsed = env.ledger().sequence().saturating_sub(m.created_ledger); + + if elapsed < MATCH_TIMEOUT_LEDGERS { + return Err(Error::MatchNotExpired); + } + + let client = token::Client::new(&env, &m.token); + + if m.player1_deposited { + client.transfer(&env.current_contract_address(), &m.player1, &m.stake_amount); + } + if m.player2_deposited { + client.transfer(&env.current_contract_address(), &m.player2, &m.stake_amount); + } + + m.state = MatchState::Expired; + env.storage() + .persistent() + .set(&DataKey::Match(match_id), &m); + env.storage().persistent().extend_ttl( + &DataKey::Match(match_id), + MATCH_TTL_LEDGERS, + MATCH_TTL_LEDGERS, + ); + + env.events().publish( + (Symbol::new(&env, "match"), symbol_short!("expired")), + match_id, + ); + + Ok(()) + } + + /// Return the admin address set at initialization. + pub fn get_admin(env: Env) -> Result { + env.storage() + .instance() + .get(&DataKey::Admin) + .ok_or(Error::Unauthorized) + } + /// Read a match by ID. pub fn get_match(env: Env, match_id: u64) -> Result { - env.storage() + let m = env + .storage() .persistent() .get(&DataKey::Match(match_id)) - .ok_or(Error::MatchNotFound) + .ok_or(Error::MatchNotFound)?; + env.storage().persistent().extend_ttl( + &DataKey::Match(match_id), + MATCH_TTL_LEDGERS, + MATCH_TTL_LEDGERS, + ); + Ok(m) } /// Check whether both players have deposited. @@ -283,18 +519,47 @@ impl EscrowContract { .persistent() .get(&DataKey::Match(match_id)) .ok_or(Error::MatchNotFound)?; + env.storage().persistent().extend_ttl( + &DataKey::Match(match_id), + MATCH_TTL_LEDGERS, + MATCH_TTL_LEDGERS, + ); Ok(m.player1_deposited && m.player2_deposited) } /// Return the total escrowed balance for a match (0, 1x, or 2x stake). + /// + /// Returns `Err(Error::MatchCompleted)` or `Err(Error::MatchCancelled)` for + /// terminal states so callers can distinguish them from an unfunded match. pub fn get_escrow_balance(env: Env, match_id: u64) -> Result { let m: Match = env .storage() .persistent() .get(&DataKey::Match(match_id)) .ok_or(Error::MatchNotFound)?; - let deposited = m.player1_deposited as i128 + m.player2_deposited as i128; - Ok(deposited * m.stake_amount) + env.storage().persistent().extend_ttl( + &DataKey::Match(match_id), + MATCH_TTL_LEDGERS, + MATCH_TTL_LEDGERS, + ); + if m.state == MatchState::Completed { + return Err(Error::MatchCompleted); + } + if m.state == MatchState::Cancelled { + return Err(Error::MatchCancelled); + } + // Count depositors explicitly β€” avoids fragile bool-to-integer casting. + let depositors: i128 = + if m.player1_deposited { 1 } else { 0 } + if m.player2_deposited { 1 } else { 0 }; + Ok(depositors * m.stake_amount) + } + + /// Return the total number of matches created. + pub fn get_match_count(env: Env) -> u64 { + env.storage() + .instance() + .get(&DataKey::MatchCount) + .unwrap_or(0) } } diff --git a/contracts/escrow/src/tests.rs b/contracts/escrow/src/tests.rs index 0dbca40..d0d4801 100644 --- a/contracts/escrow/src/tests.rs +++ b/contracts/escrow/src/tests.rs @@ -1,8 +1,7 @@ -#![cfg(test)] - use super::*; +use oracle::{MatchResult, OracleContract, OracleContractClient}; use soroban_sdk::{ - testutils::{storage::Persistent as _, Address as _, Events}, + testutils::{storage::Persistent as _, Address as _, Events, Ledger as _}, token::{Client as TokenClient, StellarAssetClient}, vec, Address, Env, IntoVal, String, Symbol, TryFromVal, }; @@ -12,7 +11,7 @@ fn setup() -> (Env, Address, Address, Address, Address, Address, Address) { env.mock_all_auths(); let admin = Address::generate(&env); - let oracle = Address::generate(&env); + let oracle_admin = Address::generate(&env); let player1 = Address::generate(&env); let player2 = Address::generate(&env); @@ -24,9 +23,47 @@ fn setup() -> (Env, Address, Address, Address, Address, Address, Address) { let contract_id = env.register(EscrowContract, ()); let client = EscrowContractClient::new(&env, &contract_id); - client.initialize(&oracle, &admin); - (env, contract_id, oracle, player1, player2, token_addr, admin) + let oracle_contract_id = env.register(OracleContract, ()); + let oracle_client = OracleContractClient::new(&env, &oracle_contract_id); + oracle_client.initialize(&oracle_admin, &oracle_admin); + + client.initialize(&oracle_contract_id, &admin, &admin); + + ( + env, + contract_id, + oracle_contract_id, + player1, + player2, + token_addr, + admin, + ) +} + +fn winner_to_match_result(winner: Winner) -> MatchResult { + match winner { + Winner::Player1 => MatchResult::Player1Wins, + Winner::Player2 => MatchResult::Player2Wins, + Winner::Draw => MatchResult::Draw, + } +} + +fn seed_oracle_result( + env: &Env, + oracle_contract: &Address, + match_id: u64, + game_id: &String, + winner: Winner, + escrow_contract: &Address, +) { + let client = OracleContractClient::new(env, oracle_contract); + client.submit_result( + &match_id, + game_id, + &winner_to_match_result(winner), + escrow_contract, + ); } #[test] @@ -48,6 +85,102 @@ fn test_create_match() { assert_eq!(m.state, MatchState::Pending); } +#[test] +fn test_get_match_count() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + assert_eq!(client.get_match_count(), 0); + + client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game1"), + &Platform::Lichess, + ); + assert_eq!(client.get_match_count(), 1); + + client.create_match( + &player1, + &player2, + &200, + &token, + &String::from_str(&env, "game2"), + &Platform::ChessDotCom, + ); + assert_eq!(client.get_match_count(), 2); +} + +#[test] +fn test_create_match_sets_created_ledger() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "ledger_test"), + &Platform::Lichess, + ); + + let m = client.get_match(&id); + // created_ledger must be set to the ledger sequence at creation time (non-zero + // in a real network; the test env starts at 0 but the field must be present and + // readable β€” future timeout logic will rely on it). + assert_eq!(m.created_ledger, env.ledger().sequence()); +} + +#[test] +fn test_get_match_returns_match_not_found_for_unknown_id() { + let (env, contract_id, _oracle, _player1, _player2, _token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let result = client.try_get_match(&999); + + assert!(matches!(result, Err(Ok(Error::MatchNotFound)))); +} + +#[test] +fn test_get_match_returns_correct_game_id() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "game_xyz_42"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + let m = client.get_match(&id); + assert_eq!(m.game_id, game_id); +} + +#[test] +fn test_get_match_returns_correct_platform() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game_platform_test"), + &Platform::ChessDotCom, + ); + + let m = client.get_match(&id); + assert_eq!(m.platform, Platform::ChessDotCom); +} + #[test] fn test_deposit_and_activate() { let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); @@ -70,50 +203,125 @@ fn test_deposit_and_activate() { } #[test] -fn test_payout_winner() { +fn test_deposit_emits_activated_event() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game_activated"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + // No activated event yet β€” only one deposit + let events_after_p1 = env.events().all(); + let activated_topics = vec![ + &env, + Symbol::new(&env, "match").into_val(&env), + soroban_sdk::symbol_short!("activated").into_val(&env), + ]; + assert!( + !events_after_p1 + .iter() + .any(|(_, topics, _)| topics == activated_topics), + "activated event must not fire after first deposit" + ); + + client.deposit(&id, &player2); + let events = env.events().all(); + let matched = events + .iter() + .find(|(_, topics, _)| *topics == activated_topics); + assert!( + matched.is_some(), + "match activated event not emitted on second deposit" + ); + + let (_, _, data) = matched.unwrap(); + let ev_id: u64 = TryFromVal::try_from_val(&env, &data).unwrap(); + assert_eq!(ev_id, id); +} + +#[test] +fn test_deposit_into_cancelled_match_returns_invalid_state() { let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "cancelled_deposit_test"), + &Platform::Lichess, + ); + + // Cancel the match before any deposits + client.cancel_match(&id, &player1); + assert_eq!(client.get_match(&id).state, MatchState::Cancelled); + + // Attempt to deposit into the cancelled match + let result = client.try_deposit(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::MatchCancelled)), + "deposit into cancelled match must return MatchCancelled" + ); +} + +#[test] +fn test_payout_winner() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); let token_client = TokenClient::new(&env, &token); + let game_id = String::from_str(&env, "game1"); let id = client.create_match( &player1, &player2, &100, &token, - &String::from_str(&env, "game1"), + &game_id, &Platform::Lichess, ); client.deposit(&id, &player1); client.deposit(&id, &player2); - client.submit_result(&id, &Winner::Player1); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); - // player1 started with 1000, deposited 100, won the 200 pot β†’ 1100 assert_eq!(token_client.balance(&player1), 1100); assert_eq!(client.get_match(&id).state, MatchState::Completed); } #[test] fn test_draw_refund() { - let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); let token_client = TokenClient::new(&env, &token); + let game_id = String::from_str(&env, "game2"); let id = client.create_match( &player1, &player2, &100, &token, - &String::from_str(&env, "game2"), + &game_id, &Platform::ChessDotCom, ); client.deposit(&id, &player1); client.deposit(&id, &player2); - client.submit_result(&id, &Winner::Draw); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Draw, &contract_id); + client.submit_result(&id, &oracle); assert_eq!(token_client.balance(&player1), 1000); assert_eq!(token_client.balance(&player2), 1000); + assert_eq!(token_client.balance(&contract_id), 0); } #[test] @@ -174,21 +382,23 @@ fn test_create_match_emits_event() { #[test] fn test_submit_result_emits_event() { - let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); + let game_id = String::from_str(&env, "game_evt"); let id = client.create_match( &player1, &player2, &100, &token, - &String::from_str(&env, "game_evt"), + &game_id, &Platform::Lichess, ); client.deposit(&id, &player1); client.deposit(&id, &player2); - client.submit_result(&id, &Winner::Player1); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); let events = env.events().all(); let expected_topics = vec![ @@ -206,6 +416,7 @@ fn test_submit_result_emits_event() { assert_eq!(decoded, (id, Winner::Player1)); } +/// Regression test (Issue #142): cancel with zero deposits must still emit the event. #[test] fn test_cancel_match_emits_event() { let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); @@ -231,13 +442,65 @@ fn test_cancel_match_emits_event() { let matched = events .iter() .find(|(_, topics, _)| *topics == expected_topics); - assert!(matched.is_some(), "match cancelled event not emitted"); + assert!( + matched.is_some(), + "match cancelled event not emitted (zero-deposit path)" + ); let (_, _, data) = matched.unwrap(); let ev_id: u64 = TryFromVal::try_from_val(&env, &data).unwrap(); assert_eq!(ev_id, id); } +/// Issue #142: cancel_match must emit ("match", "cancelled", match_id) even when +/// a deposit has already been made (partial-deposit path). +#[test] +fn test_cancel_match_emits_event_after_deposit() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game_cancel_after_deposit"), + &Platform::Lichess, + ); + + // player1 deposits β€” match stays Pending (only one deposit) + client.deposit(&id, &player1); + + client.cancel_match(&id, &player1); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "match").into_val(&env), + soroban_sdk::symbol_short!("cancelled").into_val(&env), + ]; + + // Verify the cancelled event is present and carries the correct match_id + let matched = events + .iter() + .find(|(_, topics, _)| *topics == expected_topics); + assert!( + matched.is_some(), + "match cancelled event not emitted after partial deposit (Issue #142)" + ); + + let (_, _, data) = matched.unwrap(); + let ev_id: u64 = TryFromVal::try_from_val(&env, &data).unwrap(); + assert_eq!(ev_id, id, "cancelled event must carry the correct match_id"); + + // Confirm the event sequence: last event in the list must be the cancelled one + let last = events.last().unwrap(); + assert_eq!( + last.1, expected_topics, + "cancelled must be the last event emitted" + ); +} + #[test] #[should_panic(expected = "Contract already initialized")] fn test_double_initialize_fails() { @@ -251,8 +514,72 @@ fn test_double_initialize_fails() { let contract_id = env.register(EscrowContract, ()); let client = EscrowContractClient::new(&env, &contract_id); - client.initialize(&oracle1, &admin); - client.initialize(&oracle2, &admin); + client.initialize(&oracle1, &admin, &admin); + client.initialize(&oracle2, &admin, &admin); +} + +// ── #216: initialize front-run guard ───────────────────────────────────────── + +/// A non-deployer must not be able to call initialize on the escrow contract. +#[test] +fn test_escrow_initialize_rejects_unauthorized_caller() { + let env = Env::default(); + env.mock_all_auths(); + + let deployer = Address::generate(&env); + let attacker = Address::generate(&env); + let oracle = Address::generate(&env); + let admin = Address::generate(&env); + + let contract_id = env.register(EscrowContract, ()); + let client = EscrowContractClient::new(&env, &contract_id); + + // Only authorize attacker β€” deployer.require_auth() must fail + use soroban_sdk::testutils::{MockAuth, MockAuthInvoke}; + env.set_auths(&[MockAuth { + address: &attacker, + invoke: &MockAuthInvoke { + contract: &contract_id, + fn_name: "initialize", + args: (&oracle, &admin, &deployer).into_val(&env), + sub_invokes: &[], + }, + } + .into()]); + + let result = client.try_initialize(&oracle, &admin, &deployer); + assert!(result.is_err(), "initialize must reject a non-deployer caller"); +} + +#[test] +fn test_initialize_emits_event() { + let env = Env::default(); + env.mock_all_auths(); + + let oracle = Address::generate(&env); + let admin = Address::generate(&env); + + let contract_id = env.register(EscrowContract, ()); + let client = EscrowContractClient::new(&env, &contract_id); + + client.initialize(&oracle, &admin); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "admin").into_val(&env), + symbol_short!("init").into_val(&env), + ]; + let matched = events + .iter() + .find(|(_, topics, _)| *topics == expected_topics); + assert!(matched.is_some(), "initialized event not emitted"); + + let (_, _, data) = matched.unwrap(); + let (emitted_oracle, emitted_admin): (Address, Address) = + TryFromVal::try_from_val(&env, &data).unwrap(); + assert_eq!(emitted_oracle, oracle); + assert_eq!(emitted_admin, admin); } #[test] @@ -270,7 +597,7 @@ fn test_admin_pause_blocks_create_match() { &String::from_str(&env, "paused_game"), &Platform::Lichess, ); - assert!(result.is_err()); + assert_eq!(result, Err(Ok(Error::ContractPaused))); } #[test] @@ -292,13 +619,42 @@ fn test_admin_unpause_allows_create_match() { assert_eq!(id, 0); } +#[test] +fn test_admin_pause_blocks_submit_result() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + // Create and fund a match + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "paused_submit_game"), + &Platform::Lichess, + ); + client.deposit(&id, &player1); + client.deposit(&id, &player2); + assert_eq!(client.get_match(&id).state, MatchState::Active); + + // Pause the contract + client.pause(); + + // Attempt to submit result on paused contract + let result = client.try_submit_result(&id, &oracle); + assert_eq!( + result, + Err(Ok(Error::ContractPaused)), + "submit_result must be blocked when contract is paused" + ); +} + #[test] #[should_panic(expected = "Error(Contract, #10)")] fn test_create_match_with_zero_stake_fails() { let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); - // This should fail because stake_amount is 0 let _id = client.create_match( &player1, &player2, @@ -323,7 +679,6 @@ fn test_player2_cancel_pending_match() { &Platform::Lichess, ); - // Player2 cancels the pending match client.cancel_match(&id, &player2); assert_eq!(client.get_match(&id).state, MatchState::Cancelled); @@ -343,11 +698,9 @@ fn test_player2_cancel_refunds_both_players() { &Platform::Lichess, ); - // Both players deposit - this changes state to Active client.deposit(&id, &player1); client.deposit(&id, &player2); - // Now the match is Active, not Pending - cancel should fail with InvalidState let result = client.try_cancel_match(&id, &player2); assert!(result.is_err()); } @@ -367,10 +720,7 @@ fn test_player2_cancel_only_player2_deposited() { &Platform::Lichess, ); - // Only player2 deposits (player1 abandoned) client.deposit(&id, &player2); - - // Player2 cancels and gets refund client.cancel_match(&id, &player2); assert_eq!(token_client.balance(&player2), 1000); @@ -378,7 +728,7 @@ fn test_player2_cancel_only_player2_deposited() { } #[test] -fn test_cancel_active_match_fails_with_invalid_state() { +fn test_non_oracle_cannot_submit_result() { let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); let token_client = TokenClient::new(&env, &token); @@ -388,37 +738,29 @@ fn test_cancel_active_match_fails_with_invalid_state() { &player2, &100, &token, - &String::from_str(&env, "game_active_cancel"), + &String::from_str(&env, "game_unauth_oracle"), &Platform::Lichess, ); - // Both players deposit β€” transitions match to Active client.deposit(&id, &player1); client.deposit(&id, &player2); - // Verify match is Active before attempting cancel - assert_eq!(client.get_match(&id).state, MatchState::Active); - - // Attempt to cancel an Active match β€” must return InvalidState (error code #5) - let result = client.try_cancel_match(&id, &player1); + let impostor = Address::generate(&env); + let result = client.try_submit_result(&id, &impostor); assert_eq!( result, - Err(Ok(Error::InvalidState)), - "expected InvalidState error when cancelling an Active match" + Err(Ok(Error::Unauthorized)), + "expected Unauthorized when non-oracle calls submit_result" ); - // Match must still be Active β€” no state change assert_eq!(client.get_match(&id).state, MatchState::Active); - - // Funds must remain in escrow β€” balances unchanged from post-deposit state assert_eq!(token_client.balance(&player1), 900); assert_eq!(token_client.balance(&player2), 900); } #[test] -#[should_panic(expected = "Error(Contract, #4)")] -fn test_unauthorized_player_cannot_cancel() { - let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); +fn test_submit_result_on_cancelled_match_returns_invalid_state() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); let id = client.create_match( @@ -426,34 +768,120 @@ fn test_unauthorized_player_cannot_cancel() { &player2, &100, &token, - &String::from_str(&env, "game_unauthorized"), + &String::from_str(&env, "cancelled_game"), &Platform::Lichess, ); - // Create a third party who is not part of the match - let unauthorized = Address::generate(&env); + // Cancel without any deposits β€” match goes straight to Cancelled + client.cancel_match(&id, &player1); + assert_eq!(client.get_match(&id).state, MatchState::Cancelled); - // This should panic with Unauthorized error - client.cancel_match(&id, &unauthorized); + let result = client.try_submit_result(&id, &oracle); + assert_eq!( + result, + Err(Ok(Error::InvalidState)), + "oracle must not be able to submit a result for a Cancelled match" + ); } #[test] -fn test_ttl_extended_on_create_match() { - let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); +fn test_submit_result_on_completed_match_returns_invalid_state() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); + let game_id = String::from_str(&env, "completed_game"); let id = client.create_match( &player1, &player2, &100, &token, - &String::from_str(&env, "ttl_game1"), + &game_id, &Platform::Lichess, ); - let ttl = env.as_contract(&contract_id, || { - env.storage().persistent().get_ttl(&DataKey::Match(id)) - }); + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); + assert_eq!(client.get_match(&id).state, MatchState::Completed); + + // Second submit on an already-Completed match must fail + let result = client.try_submit_result(&id, &oracle); + assert_eq!( + result, + Err(Ok(Error::InvalidState)), + "oracle must not be able to submit a result for an already Completed match" + ); +} + +#[test] +fn test_cancel_active_match_fails_with_invalid_state() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game_active_cancel"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + assert_eq!(client.get_match(&id).state, MatchState::Active); + + let result = client.try_cancel_match(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::InvalidState)), + "expected InvalidState error when cancelling an Active match" + ); + + assert_eq!(client.get_match(&id).state, MatchState::Active); + assert_eq!(token_client.balance(&player1), 900); + assert_eq!(token_client.balance(&player2), 900); +} + +#[test] +#[should_panic(expected = "Error(Contract, #4)")] +fn test_unauthorized_player_cannot_cancel() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "game_unauthorized"), + &Platform::Lichess, + ); + + let unauthorized = Address::generate(&env); + client.cancel_match(&id, &unauthorized); +} + +#[test] +fn test_ttl_extended_on_create_match() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "ttl_game1"), + &Platform::Lichess, + ); + + let ttl = env.as_contract(&contract_id, || { + env.storage().persistent().get_ttl(&DataKey::Match(id)) + }); assert_eq!(ttl, crate::MATCH_TTL_LEDGERS); } @@ -480,20 +908,22 @@ fn test_ttl_extended_on_deposit() { #[test] fn test_ttl_extended_on_submit_result() { - let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); let client = EscrowContractClient::new(&env, &contract_id); + let game_id = String::from_str(&env, "ttl_game3"); let id = client.create_match( &player1, &player2, &100, &token, - &String::from_str(&env, "ttl_game3"), + &game_id, &Platform::Lichess, ); client.deposit(&id, &player1); client.deposit(&id, &player2); - client.submit_result(&id, &Winner::Player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player2, &contract_id); + client.submit_result(&id, &oracle); let ttl = env.as_contract(&contract_id, || { env.storage().persistent().get_ttl(&DataKey::Match(id)) @@ -521,3 +951,1200 @@ fn test_ttl_extended_on_cancel() { }); assert_eq!(ttl, crate::MATCH_TTL_LEDGERS); } + +#[test] +fn test_ttl_extended_on_cancel_after_deposit() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "ttl_game5"), + &Platform::Lichess, + ); + client.deposit(&id, &player1); + client.cancel_match(&id, &player1); + + let ttl = env.as_contract(&contract_id, || { + env.storage().persistent().get_ttl(&DataKey::Match(id)) + }); + assert_eq!(ttl, crate::MATCH_TTL_LEDGERS); +} + +#[test] +fn test_ttl_refreshed_on_get_match() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "ttl_read_refresh"), + &Platform::Lichess, + ); + + // Let some time pass (advance ledger small amount to simulate partial TTL without archiving) + let ledgers_elapsed = 1000u32; + let current_ledger = env.ledger().sequence(); + env.ledger() + .set_sequence_number(current_ledger + ledgers_elapsed); + + // Extend instance TTLs to prevent archiving during test + env.as_contract(&contract_id, || { + env.storage() + .instance() + .extend_ttl(crate::MATCH_TTL_LEDGERS, crate::MATCH_TTL_LEDGERS); + }); + + // TTL should be partial + let ttl_before = env.as_contract(&contract_id, || { + env.storage().persistent().get_ttl(&DataKey::Match(id)) + }); + assert!(ttl_before < crate::MATCH_TTL_LEDGERS); + + // get_match refreshes TTL + let _m = client.get_match(&id); + + let ttl_after = env.as_contract(&contract_id, || { + env.storage().persistent().get_ttl(&DataKey::Match(id)) + }); + assert_eq!(ttl_after, crate::MATCH_TTL_LEDGERS); + + // Multiple reads keep it full + client.get_match(&id); + let ttl_final = env.as_contract(&contract_id, || { + env.storage().persistent().get_ttl(&DataKey::Match(id)) + }); + assert_eq!(ttl_final, crate::MATCH_TTL_LEDGERS); +} + +// ── Task 1: non-admin cannot call pause / unpause ──────────────────────────── + +#[test] +fn test_non_admin_cannot_pause() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let non_admin = Address::generate(&env); + let oracle = Address::generate(&env); + + let contract_id = env.register(EscrowContract, ()); + let client = EscrowContractClient::new(&env, &contract_id); + client.initialize(&oracle, &admin, &admin); + + // Replace mock_all_auths with a targeted mock that only authorises non_admin, + // so admin.require_auth() inside pause() will not find a matching authorisation + // and the call must fail. + use soroban_sdk::testutils::MockAuth; + use soroban_sdk::testutils::MockAuthInvoke; + env.set_auths(&[MockAuth { + address: &non_admin, + invoke: &MockAuthInvoke { + contract: &contract_id, + fn_name: "pause", + args: ().into_val(&env), + sub_invokes: &[], + }, + } + .into()]); + + let result = client.try_pause(); + assert!( + result.is_err(), + "non-admin should not be able to call pause()" + ); +} + +#[test] +fn test_non_admin_cannot_unpause() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let non_admin = Address::generate(&env); + let oracle = Address::generate(&env); + + let contract_id = env.register(EscrowContract, ()); + let client = EscrowContractClient::new(&env, &contract_id); + client.initialize(&oracle, &admin, &admin); + // Pause first (admin is mocked via mock_all_auths at this point) + client.pause(); + + use soroban_sdk::testutils::MockAuth; + use soroban_sdk::testutils::MockAuthInvoke; + env.set_auths(&[MockAuth { + address: &non_admin, + invoke: &MockAuthInvoke { + contract: &contract_id, + fn_name: "unpause", + args: ().into_val(&env), + sub_invokes: &[], + }, + } + .into()]); + + let result = client.try_unpause(); + assert!( + result.is_err(), + "non-admin should not be able to call unpause()" + ); +} + +// ── Task 2: cancel_match refund scenarios ──────────────────────────────────── + +/// Both players deposit β†’ match becomes Active β†’ cancel must return InvalidState. +#[test] +fn test_cancel_both_deposited_active_returns_invalid_state() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "both_dep_cancel"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + // Match is now Active β€” cancel must be rejected + assert_eq!(client.get_match(&id).state, MatchState::Active); + let result = client.try_cancel_match(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::InvalidState)), + "cancelling an Active match must return InvalidState" + ); + + // Funds must remain in escrow + assert_eq!(token_client.balance(&player1), 900); + assert_eq!(token_client.balance(&player2), 900); +} + +/// Only player1 deposits, then cancels β€” player1 is refunded, player2 unchanged. +#[test] +fn test_cancel_only_player1_deposited_refunds_player1() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "p1_only_cancel"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + // player2 has NOT deposited + assert_eq!(token_client.balance(&player1), 900); + assert_eq!(token_client.balance(&player2), 1000); + + client.cancel_match(&id, &player1); + + // player1 gets their stake back; player2 balance is untouched + assert_eq!( + token_client.balance(&player1), + 1000, + "player1 should be fully refunded" + ); + assert_eq!( + token_client.balance(&player2), + 1000, + "player2 balance must not change" + ); + assert_eq!(client.get_match(&id).state, MatchState::Cancelled); +} + +/// Only player2 deposits, then cancels β€” player2 is refunded, player1 unchanged. +#[test] +fn test_cancel_only_player2_deposited_refunds_player2() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "p2_only_cancel2"), + &Platform::Lichess, + ); + + client.deposit(&id, &player2); + // player1 has NOT deposited + assert_eq!(token_client.balance(&player1), 1000); + assert_eq!(token_client.balance(&player2), 900); + + client.cancel_match(&id, &player2); + + // player2 gets their stake back; player1 balance is untouched + assert_eq!( + token_client.balance(&player2), + 1000, + "player2 should be fully refunded" + ); + assert_eq!( + token_client.balance(&player1), + 1000, + "player1 balance must not change" + ); + assert_eq!(client.get_match(&id).state, MatchState::Cancelled); +} + +/// Cancel match immediately after creation with no deposits β€” get_escrow_balance +/// must return Err(MatchCancelled) for a cancelled match. +#[test] +fn test_get_escrow_balance_returns_cancelled_after_cancel_with_no_deposits() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "no_deposit_cancel"), + &Platform::Lichess, + ); + + // Cancel immediately without any deposits + client.cancel_match(&id, &player1); + + // get_escrow_balance must return MatchCancelled for a cancelled match + assert_eq!( + client.try_get_escrow_balance(&id), + Err(Ok(Error::MatchCancelled)) + ); + assert_eq!(client.get_match(&id).state, MatchState::Cancelled); +} + +// ── cancel_match on a Completed match ──────────────────────────────────────── + +/// Complete a match (create β†’ deposit Γ— 2 β†’ submit_result), then attempt to +/// cancel it. cancel_match checks `m.state != MatchState::Pending` and must +/// return `InvalidState`. The match state and token balances must be unchanged. +#[test] +fn test_cancel_completed_match_returns_invalid_state() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let game_id = String::from_str(&env, "completed_cancel_game"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); + + // Sanity-check: match is now Completed and payout has happened + assert_eq!(client.get_match(&id).state, MatchState::Completed); + assert_eq!(token_client.balance(&player1), 1100); + assert_eq!(token_client.balance(&player2), 900); + + // Attempting to cancel a Completed match must be rejected + let result = client.try_cancel_match(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::InvalidState)), + "cancel_match on a Completed match must return InvalidState" + ); + + // State and balances must be untouched after the failed cancel + assert_eq!(client.get_match(&id).state, MatchState::Completed); + assert_eq!(token_client.balance(&player1), 1100); + assert_eq!(token_client.balance(&player2), 900); +} + +// ── deposit on a Completed match ───────────────────────────────────────────── + +/// Complete a match via submit_result, then attempt to deposit into it. +/// deposit() guards on `m.state != MatchState::Pending` and must return +/// `Error::InvalidState`. Token balances must remain unchanged after the +/// failed deposit attempt. +#[test] +fn test_deposit_into_completed_match_returns_invalid_state() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let game_id = String::from_str(&env, "completed_deposit_game"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + // Both players deposit β†’ match becomes Active + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + // Oracle submits result β†’ match transitions to Completed, payout executed + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); + assert_eq!(client.get_match(&id).state, MatchState::Completed); + assert_eq!(token_client.balance(&player1), 1100); + assert_eq!(token_client.balance(&player2), 900); + + // Attempting to deposit into a Completed match must be rejected + let result = client.try_deposit(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::MatchCompleted)), + "deposit into a Completed match must return MatchCompleted" + ); + + // Balances must be untouched after the failed deposit + assert_eq!(token_client.balance(&player1), 1100); + assert_eq!(token_client.balance(&player2), 900); +} + +// ── From main: pause / unpause emit events ─────────────────────────────────── + +#[test] +fn test_pause_emits_event() { + let (env, contract_id, _oracle, _player1, _player2, _token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + client.pause(); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "admin").into_val(&env), + soroban_sdk::symbol_short!("paused").into_val(&env), + ]; + assert!( + events + .iter() + .any(|(_, topics, _)| topics == expected_topics), + "paused event not emitted" + ); +} + +#[test] +fn test_unpause_emits_event() { + let (env, contract_id, _oracle, _player1, _player2, _token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + client.pause(); + client.unpause(); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "admin").into_val(&env), + soroban_sdk::symbol_short!("unpaused").into_val(&env), + ]; + assert!( + events + .iter() + .any(|(_, topics, _)| topics == expected_topics), + "unpaused event not emitted" + ); +} + +#[test] +fn test_duplicate_game_id_rejected() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "unique_game_123"); + + client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + let result = client.try_create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + assert_eq!(result, Err(Ok(Error::DuplicateGameId))); +} + +#[test] +fn test_deposit_into_cancelled_match_returns_match_cancelled() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "cancelled_deposit"), + &Platform::Lichess, + ); + + client.cancel_match(&id, &player1); + + let result = client.try_deposit(&id, &player2); + assert_eq!(result, Err(Ok(Error::MatchCancelled))); +} + +#[test] +fn test_deposit_into_completed_match_returns_match_completed() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "completed_deposit"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); + + let result = client.try_deposit(&id, &player2); + assert_eq!(result, Err(Ok(Error::MatchCompleted))); +} + +#[test] +fn test_expire_match_before_timeout_fails() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "expire_early"), + &Platform::Lichess, + ); + + // Only player1 deposits β€” match stays Pending + client.deposit(&id, &player1); + + // Timeout has not elapsed yet β€” should fail + let result = client.try_expire_match(&id); + assert_eq!(result, Err(Ok(Error::MatchNotExpired))); +} + +#[test] +fn test_expire_match_refunds_depositor_after_timeout() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "expire_refund"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + let balance_before = token_client.balance(&player1); + + let new_seq = env.ledger().sequence() + MATCH_TIMEOUT_LEDGERS; + env.as_contract(&contract_id, || { + env.storage() + .instance() + .extend_ttl(MATCH_TTL_LEDGERS, MATCH_TTL_LEDGERS); + }); + env.as_contract(&token, || { + env.storage() + .instance() + .extend_ttl(MATCH_TTL_LEDGERS, MATCH_TTL_LEDGERS); + }); + env.ledger().set_sequence_number(new_seq); + + client.expire_match(&id); + + let m = client.get_match(&id); + assert_eq!(m.state, MatchState::Expired); + assert_eq!(token_client.balance(&player1), balance_before + 100); +} + +// ── get_escrow_balance at each deposit stage ───────────────────────────────── + +#[test] +fn test_get_escrow_balance_stages() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let stake = 100_i128; + let id = client.create_match( + &player1, + &player2, + &stake, + &token, + &String::from_str(&env, "balance_stages"), + &Platform::Lichess, + ); + + // Before any deposit: balance must be 0 + assert_eq!(client.get_escrow_balance(&id), 0); + + // After player1 deposits: balance must equal stake_amount + client.deposit(&id, &player1); + assert_eq!(client.get_escrow_balance(&id), stake); + + // After player2 deposits: balance must equal 2 * stake_amount + client.deposit(&id, &player2); + assert_eq!(client.get_escrow_balance(&id), 2 * stake); +} + +// ── Defensive: submit_result with insufficient escrow balance ──────────────── + +#[test] +fn test_submit_result_returns_not_funded_when_deposits_missing() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "not_funded_game"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + // Force the match into Active state without deposits. + env.as_contract(&contract_id, || { + let mut m: Match = env.storage().persistent().get(&DataKey::Match(id)).unwrap(); + m.state = MatchState::Active; + env.storage().persistent().set(&DataKey::Match(id), &m); + }); + + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + let result = client.try_submit_result(&id, &oracle); + assert_eq!( + result, + Err(Ok(Error::NotFunded)), + "submit_result must return NotFunded when deposits are missing despite Active state" + ); +} + +#[test] +fn test_expire_match_emits_expired_event() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "expire_event"), + &Platform::Lichess, + ); + + let new_seq = env.ledger().sequence() + MATCH_TIMEOUT_LEDGERS; + env.as_contract(&contract_id, || { + env.storage() + .instance() + .extend_ttl(MATCH_TTL_LEDGERS, MATCH_TTL_LEDGERS); + }); + env.ledger().set_sequence_number(new_seq); + client.expire_match(&id); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "match").into_val(&env), + soroban_sdk::symbol_short!("expired").into_val(&env), + ]; + assert!( + events + .iter() + .any(|(_, topics, _)| topics == expected_topics), + "expired event not emitted" + ); +} + +// ── game_id length validation ───────────────────────────────────────────────── + +#[test] +fn test_create_match_with_oversized_game_id_fails() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + // 65 characters β€” one over the MAX_GAME_ID_LEN of 64 + let oversized_id = String::from_str( + &env, + "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffffffff1", + ); + + let result = client.try_create_match( + &player1, + &player2, + &100, + &token, + &oversized_id, + &Platform::Lichess, + ); + + assert_eq!( + result, + Err(Ok(Error::InvalidGameId)), + "create_match must reject game_id longer than 64 characters" + ); +} + +#[test] +fn test_create_match_with_empty_game_id_rejected() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let result = client.try_create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, ""), + &Platform::Lichess, + ); + + assert_eq!( + result, + Err(Ok(Error::InvalidGameId)), + "create_match must reject an empty game_id" + ); +} + +// ── deposit blocked when contract is paused ─────────────────────────────────── + +#[test] +fn test_deposit_blocked_when_paused() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "paused_deposit_game"), + &Platform::Lichess, + ); + + client.pause(); + + let result = client.try_deposit(&id, &player1); + assert_eq!( + result, + Err(Ok(Error::ContractPaused)), + "deposit must return ContractPaused when the contract is paused" + ); +} + +#[test] +fn test_expire_active_match_fails() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "expire_active"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + let new_seq = env.ledger().sequence() + MATCH_TIMEOUT_LEDGERS; + env.as_contract(&contract_id, || { + env.storage() + .instance() + .extend_ttl(MATCH_TTL_LEDGERS, MATCH_TTL_LEDGERS); + }); + env.ledger().set_sequence_number(new_seq); + + let result = client.try_expire_match(&id); + assert_eq!(result, Err(Ok(Error::InvalidState))); +} + +// ── submit_result blocked when contract is paused ──────────────────────────── + +#[test] +fn test_submit_result_blocked_when_paused() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "paused_submit_game"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + client.pause(); + + let result = client.try_submit_result(&id, &oracle); + assert_eq!(result, Err(Ok(Error::ContractPaused))); +} + +#[test] +fn test_oracle_rotation_flow() { + let (env, contract_id, oracle, player1, player2, token, admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let intermediate_oracle = env.register(OracleContract, ()); + let intermediate_admin = Address::generate(&env); + let intermediate_client = OracleContractClient::new(&env, &intermediate_oracle); + intermediate_client.initialize(&intermediate_admin, &intermediate_admin); + + let final_oracle = env.register(OracleContract, ()); + let final_admin = Address::generate(&env); + let final_client = OracleContractClient::new(&env, &final_oracle); + final_client.initialize(&final_admin, &final_admin); + + let attacker = Address::generate(&env); + + // Current oracle may rotate itself first. + client.update_oracle(&intermediate_oracle, &oracle); + // Admin can also rotate the oracle. + client.update_oracle(&final_oracle, &admin); + + assert_eq!( + client.try_update_oracle(&final_oracle, &attacker), + Err(Ok(Error::Unauthorized)) + ); + + let game_id = String::from_str(&env, "oracle_rotation"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + assert_eq!( + client.try_submit_result(&id, &intermediate_oracle), + Err(Ok(Error::Unauthorized)) + ); + + seed_oracle_result( + &env, + &final_oracle, + id, + &game_id, + Winner::Player2, + &contract_id, + ); + client.submit_result(&id, &final_oracle); + + assert_eq!(client.get_match(&id).state, MatchState::Completed); +} + +#[test] +fn test_is_funded_false_after_only_player1_deposits() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "partial_funded_game"), + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + assert!( + !client.is_funded(&id), + "is_funded must be false after only player1 deposits" + ); + + client.deposit(&id, &player2); + assert!( + client.is_funded(&id), + "is_funded must be true after both players deposit" + ); +} + +// ── Deposit flag assertions ─────────────────────────────────────────────────── + +/// Verifies that `player1_deposited` and `player2_deposited` flags on the +/// `Match` struct are set correctly after each individual deposit. +/// +/// After player1 deposits: player1_deposited == true, player2_deposited == false +/// After player2 deposits: player1_deposited == true, player2_deposited == true +#[test] +fn test_deposit_flags_set_correctly_after_each_deposit() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "deposit_flags_test"), + &Platform::Lichess, + ); + + // Before any deposit: both flags must be false + let m = client.get_match(&id); + assert!( + !m.player1_deposited, + "player1_deposited must be false before any deposit" + ); + assert!( + !m.player2_deposited, + "player2_deposited must be false before any deposit" + ); + + // After player1 deposits: only player1_deposited flips to true + client.deposit(&id, &player1); + let m = client.get_match(&id); + assert!( + m.player1_deposited, + "player1_deposited must be true after player1 deposits" + ); + assert!( + !m.player2_deposited, + "player2_deposited must still be false after only player1 deposits" + ); + + // After player2 deposits: both flags must be true + client.deposit(&id, &player2); + let m = client.get_match(&id); + assert!( + m.player1_deposited, + "player1_deposited must remain true after player2 deposits" + ); + assert!( + m.player2_deposited, + "player2_deposited must be true after player2 deposits" + ); +} + +// ── Draw result: exact stake refund and zero escrow balance ────────────────── + +/// Submit Winner::Draw and verify: +/// 1. Each player receives exactly their original stake_amount back. +/// 2. The contract escrow balance for the match is 0 after payout. +#[test] +fn test_draw_refunds_exact_stake_and_zeroes_escrow_balance() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let token_client = TokenClient::new(&env, &token); + + let stake: i128 = 100; + + let game_id = String::from_str(&env, "draw_escrow_zero"); + let id = client.create_match( + &player1, + &player2, + &stake, + &token, + &game_id, + &Platform::Lichess, + ); + + // Both players deposit β€” escrow holds 2 * stake + client.deposit(&id, &player1); + client.deposit(&id, &player2); + assert_eq!(client.get_escrow_balance(&id), 2 * stake); + + // Record balances right before result submission + let p1_before = token_client.balance(&player1); + let p2_before = token_client.balance(&player2); + + // Oracle submits Draw result + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Draw, &contract_id); + client.submit_result(&id, &oracle); + + // Each player must receive exactly stake_amount back + assert_eq!( + token_client.balance(&player1), + p1_before + stake, + "player1 must receive exactly stake_amount on draw" + ); + assert_eq!( + token_client.balance(&player2), + p2_before + stake, + "player2 must receive exactly stake_amount on draw" + ); + + // Contract escrow balance must return MatchCompleted β€” no funds left behind + assert_eq!( + client.try_get_escrow_balance(&id), + Err(Ok(Error::MatchCompleted)), + "get_escrow_balance must return MatchCompleted after draw payout" + ); + + // Contract's actual token balance must also be zero + assert_eq!( + token_client.balance(&contract_id), + 0, + "contract token balance must be 0 after draw refunds" + ); + + // Match state must be Completed + assert_eq!(client.get_match(&id).state, MatchState::Completed); +} + +#[test] +fn test_oracle_result_drives_escrow_settlement() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + let oracle_client = OracleContractClient::new(&env, &oracle); + + let game_id = String::from_str(&env, "integration_flow"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player2, &contract_id); + + let stored = oracle_client.get_result(&id); + assert_eq!(stored.game_id, game_id); + assert_eq!(stored.result, MatchResult::Player2Wins); + + client.submit_result(&id, &oracle); + + let events = env.events().all(); + let expected_topics = vec![ + &env, + Symbol::new(&env, "match").into_val(&env), + soroban_sdk::symbol_short!("completed").into_val(&env), + ]; + let matched = events + .iter() + .find(|(_, topics, _)| *topics == expected_topics) + .expect("match completed event must fire"); + let (_, _, data) = matched; + let decoded: (u64, Winner) = <(u64, Winner)>::try_from_val(&env, &data).unwrap(); + assert_eq!(decoded, (id, Winner::Player2)); + assert_eq!(client.get_match(&id).state, MatchState::Completed); +} + +#[test] +fn test_get_escrow_balance_returns_match_not_found_for_nonexistent_id() { + let (env, contract_id, ..) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + // match_id 999 was never created β€” must return Error::MatchNotFound + let result = client.try_get_escrow_balance(&999u64); + assert_eq!( + result, + Err(Ok(Error::MatchNotFound)), + "get_escrow_balance must return MatchNotFound for a non-existent match_id" + ); +} + +// ── #219: get_escrow_balance terminal state errors ──────────────────────────── + +/// get_escrow_balance must return Err(MatchCompleted) for a completed match. +#[test] +fn test_submit_result_overflow_stake_returns_overflow() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + // stake_amount just above i128::MAX / 2 β€” doubling it overflows i128. + // Bypass real deposits (which would overflow the token contract) by + // injecting the match directly into storage in the Active + funded state. + let overflow_stake: i128 = i128::MAX / 2 + 1; + + let game_id = String::from_str(&env, "overflow_stake_game"); + + // create_match validates stake_amount > 0 but does not cap it, so we + // create with a normal stake first, then overwrite the stored match. + let id = client.create_match(&player1, &player2, &1, &token, &game_id, &Platform::Lichess); + + // Overwrite the match with the overflow stake in Active + fully-funded state. + env.as_contract(&contract_id, || { + let mut m: Match = env.storage().persistent().get(&DataKey::Match(id)).unwrap(); + m.stake_amount = overflow_stake; + m.state = MatchState::Active; + m.player1_deposited = true; + m.player2_deposited = true; + env.storage().persistent().set(&DataKey::Match(id), &m); + }); + + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + + let result = client.try_submit_result(&id, &oracle); + assert_eq!( + result, + Err(Ok(Error::Overflow)), + "submit_result must return Overflow for stake_amount near i128::MAX / 2" + ); +} + +// ── #186: get_match returns Completed state for all winner variants ─────────── + +/// After submit_result with Winner::Player1, get_match must return Completed. +#[test] +fn test_get_match_returns_completed_state_player1_wins() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "completed_p1"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player1, &contract_id); + client.submit_result(&id, &oracle); + + let m = client.get_match(&id); + assert_eq!( + m.state, + MatchState::Completed, + "get_match must return Completed after Player1 wins" + ); +} + +/// After submit_result with Winner::Player2, get_match must return Completed. +#[test] +fn test_get_match_returns_completed_state_player2_wins() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "completed_p2"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Player2, &contract_id); + client.submit_result(&id, &oracle); + + let m = client.get_match(&id); + assert_eq!( + m.state, + MatchState::Completed, + "get_match must return Completed after Player2 wins" + ); +} + +/// After submit_result with Winner::Draw, get_match must return Completed. +#[test] +fn test_get_match_returns_completed_state_draw() { + let (env, contract_id, oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "completed_draw"); + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + client.deposit(&id, &player1); + client.deposit(&id, &player2); + seed_oracle_result(&env, &oracle, id, &game_id, Winner::Draw, &contract_id); + client.submit_result(&id, &oracle); + + let m = client.get_match(&id); + assert_eq!( + m.state, + MatchState::Completed, + "get_match must return Completed after Draw" + ); +} + +// ── #191: cancel_match rejects the contract address as caller ───────────────── + +/// Passing env.current_contract_address() as the caller to cancel_match must +/// return Unauthorized β€” the contract itself is never a valid canceller. +#[test] +fn test_cancel_match_rejects_contract_as_caller() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &String::from_str(&env, "contract_caller_cancel"), + &Platform::Lichess, + ); + + let result = client.try_cancel_match(&id, &contract_id); + assert_eq!( + result, + Err(Ok(Error::Unauthorized)), + "cancel_match must reject the contract address as caller" + ); + + // Match must remain Pending β€” no state change from the rejected call + assert_eq!(client.get_match(&id).state, MatchState::Pending); +} diff --git a/contracts/escrow/src/types.rs b/contracts/escrow/src/types.rs index c3bdf4d..1ceb652 100644 --- a/contracts/escrow/src/types.rs +++ b/contracts/escrow/src/types.rs @@ -7,6 +7,7 @@ pub enum MatchState { Active, // both players deposited, game in progress Completed, // result submitted, payout executed Cancelled, // cancelled before activation + Expired, // timed out before both players deposited } #[contracttype] @@ -37,6 +38,10 @@ pub struct Match { pub state: MatchState, pub player1_deposited: bool, pub player2_deposited: bool, + /// Ledger sequence number at match creation. Used for timeout and ordering logic. + pub created_ledger: u32, + /// Set when the match reaches Completed state. + pub winner: Option, } #[contracttype] @@ -46,4 +51,20 @@ pub enum DataKey { Oracle, Admin, Paused, + GameId(String), +} + +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum OracleMatchResult { + Player1Wins, + Player2Wins, + Draw, +} + +#[contracttype] +#[derive(Clone, Debug)] +pub struct OracleResultEntry { + pub game_id: String, + pub result: OracleMatchResult, } diff --git a/contracts/escrow/test_snapshots/tests/test_admin_unpause_allows_create_match.1.json b/contracts/escrow/test_snapshots/tests/test_admin_unpause_allows_create_match.1.json index f722552..cfa36a9 100644 --- a/contracts/escrow/test_snapshots/tests/test_admin_unpause_allows_create_match.1.json +++ b/contracts/escrow/test_snapshots/tests/test_admin_unpause_allows_create_match.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", @@ -383,6 +385,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "unpaused_game" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "unpaused_game" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -420,6 +467,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -517,7 +572,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -576,7 +631,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -601,6 +656,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_active_match_fails_with_invalid_state.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_active_match_fails_with_invalid_state.1.json index 0291686..714df1d 100644 --- a/contracts/escrow/test_snapshots/tests/test_cancel_active_match_fails_with_invalid_state.1.json +++ b/contracts/escrow/test_snapshots/tests/test_cancel_active_match_fails_with_invalid_state.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -450,6 +452,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_active_cancel" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_active_cancel" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -487,6 +534,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -584,7 +639,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -643,7 +698,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -668,6 +723,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_payout_winner.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_both_deposited_active_returns_invalid_state.1.json similarity index 92% rename from contracts/escrow/test_snapshots/tests/test_payout_winner.1.json rename to contracts/escrow/test_snapshots/tests/test_cancel_both_deposited_active_returns_invalid_state.1.json index 8fa5752..973d01c 100644 --- a/contracts/escrow/test_snapshots/tests/test_payout_winner.1.json +++ b/contracts/escrow/test_snapshots/tests/test_cancel_both_deposited_active_returns_invalid_state.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -100,7 +102,7 @@ "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" }, { - "string": "game1" + "string": "both_dep_cancel" }, { "vec": [ @@ -208,32 +210,8 @@ } ] ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "submit_result", - "args": [ - { - "u64": 0 - }, - { - "vec": [ - { - "symbol": "Player1" - } - ] - } - ] - } - }, - "sub_invocations": [] - } - ] - ], + [], + [], [], [] ], @@ -377,10 +355,10 @@ [ { "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 8370022561469687789 + "nonce": 2032731177588607455 } }, "durability": "temporary" @@ -392,10 +370,10 @@ "data": { "contract_data": { "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 8370022561469687789 + "nonce": 2032731177588607455 } }, "durability": "temporary", @@ -413,7 +391,7 @@ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 2032731177588607455 + "nonce": 4837995959683129791 } }, "durability": "temporary" @@ -428,7 +406,7 @@ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 2032731177588607455 + "nonce": 4837995959683129791 } }, "durability": "temporary", @@ -443,10 +421,10 @@ [ { "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", "key": { "ledger_key_nonce": { - "nonce": 4837995959683129791 + "nonce": 4270020994084947596 } }, "durability": "temporary" @@ -458,10 +436,10 @@ "data": { "contract_data": { "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", "key": { "ledger_key_nonce": { - "nonce": 4837995959683129791 + "nonce": 4270020994084947596 } }, "durability": "temporary", @@ -476,13 +454,18 @@ [ { "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", "key": { - "ledger_key_nonce": { - "nonce": 4270020994084947596 - } + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "both_dep_cancel" + } + ] }, - "durability": "temporary" + "durability": "persistent" } }, [ @@ -491,19 +474,26 @@ "data": { "contract_data": { "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", "key": { - "ledger_key_nonce": { - "nonce": 4270020994084947596 - } + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "both_dep_cancel" + } + ] }, - "durability": "temporary", - "val": "void" + "durability": "persistent", + "val": { + "bool": true + } } }, "ext": "v0" }, - 6311999 + 4095 ] ], [ @@ -543,12 +533,20 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" }, "val": { - "string": "game1" + "string": "both_dep_cancel" } }, { @@ -621,7 +619,7 @@ "val": { "vec": [ { - "symbol": "Completed" + "symbol": "Active" } ] } @@ -640,7 +638,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -699,7 +697,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -724,6 +722,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -768,7 +811,7 @@ "val": { "i128": { "hi": 0, - "lo": 1100 + "lo": 900 } } }, @@ -914,7 +957,7 @@ "val": { "i128": { "hi": 0, - "lo": 0 + "lo": 200 } } }, diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_completed_match_returns_invalid_state.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_completed_match_returns_invalid_state.1.json new file mode 100644 index 0000000..27ab319 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_cancel_completed_match_returns_invalid_state.1.json @@ -0,0 +1,1314 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "completed_cancel_game" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "string": "completed_cancel_game" + }, + { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_cancel_game" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_cancel_game" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_cancel_game" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Completed" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_cancel_game" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1100 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_match_emits_event.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_match_emits_event.1.json index add3ad4..581c4ba 100644 --- a/contracts/escrow/test_snapshots/tests/test_cancel_match_emits_event.1.json +++ b/contracts/escrow/test_snapshots/tests/test_cancel_match_emits_event.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -342,6 +344,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_cancel" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_cancel" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -379,6 +426,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -476,7 +531,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -535,7 +590,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -560,6 +615,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_only_player1_deposited_refunds_player1.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_only_player1_deposited_refunds_player1.1.json new file mode 100644 index 0000000..ef1ad6b --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_cancel_only_player1_deposited_refunds_player1.1.json @@ -0,0 +1,1102 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "p1_only_cancel" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "cancel_match", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "p1_only_cancel" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "p1_only_cancel" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "p1_only_cancel" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_only_player2_deposited_refunds_player2.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_only_player2_deposited_refunds_player2.1.json new file mode 100644 index 0000000..c7a676a --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_cancel_only_player2_deposited_refunds_player2.1.json @@ -0,0 +1,1102 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "p2_only_cancel2" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "cancel_match", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "p2_only_cancel2" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "p2_only_cancel2" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "p2_only_cancel2" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_cancel_refunds_deposit.1.json b/contracts/escrow/test_snapshots/tests/test_cancel_refunds_deposit.1.json index ff536db..49551e3 100644 --- a/contracts/escrow/test_snapshots/tests/test_cancel_refunds_deposit.1.json +++ b/contracts/escrow/test_snapshots/tests/test_cancel_refunds_deposit.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -423,6 +425,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game3" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game3" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -460,6 +507,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -557,7 +612,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -616,7 +671,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -641,6 +696,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_create_match_emits_event.1.json b/contracts/escrow/test_snapshots/tests/test_create_match_emits_event.1.json index 674e690..47e9a9f 100644 --- a/contracts/escrow/test_snapshots/tests/test_create_match_emits_event.1.json +++ b/contracts/escrow/test_snapshots/tests/test_create_match_emits_event.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -287,6 +289,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_ev2" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_ev2" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -324,6 +371,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -421,7 +476,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -480,7 +535,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -505,6 +560,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_create_match_with_zero_stake_fails.1.json b/contracts/escrow/test_snapshots/tests/test_create_match_sets_created_ledger.1.json similarity index 65% rename from contracts/escrow/test_snapshots/tests/test_create_match_with_zero_stake_fails.1.json rename to contracts/escrow/test_snapshots/tests/test_create_match_sets_created_ledger.1.json index e3e3722..6781ac0 100644 --- a/contracts/escrow/test_snapshots/tests/test_create_match_with_zero_stake_fails.1.json +++ b/contracts/escrow/test_snapshots/tests/test_create_match_sets_created_ledger.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,49 @@ ], [], [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "ledger_test" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], [] ], "ledger": { @@ -214,6 +257,229 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ledger_test" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ledger_test" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ledger_test" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], [ { "contract_data": { @@ -258,7 +524,7 @@ ] }, "val": { - "u64": 0 + "u64": 1 } }, { @@ -270,7 +536,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -295,6 +561,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_deposit_and_activate.1.json b/contracts/escrow/test_snapshots/tests/test_deposit_and_activate.1.json index 2c6ac3f..3a701bb 100644 --- a/contracts/escrow/test_snapshots/tests/test_deposit_and_activate.1.json +++ b/contracts/escrow/test_snapshots/tests/test_deposit_and_activate.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -448,6 +450,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "abc123" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "abc123" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -485,6 +532,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -582,7 +637,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -641,7 +696,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -666,6 +721,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_deposit_emits_activated_event.1.json b/contracts/escrow/test_snapshots/tests/test_deposit_emits_activated_event.1.json new file mode 100644 index 0000000..2f89550 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_deposit_emits_activated_event.1.json @@ -0,0 +1,1177 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "game_activated" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_activated" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_activated" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "game_activated" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Active" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "d63a954726751a876d37290072af1ee723d7d761eec3bf4191849d2116acdc73", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 100 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000006", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "match" + }, + { + "symbol": "activated" + } + ], + "data": { + "u64": 0 + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_deposit_into_cancelled_match_returns_match_cancelled.1.json b/contracts/escrow/test_snapshots/tests/test_deposit_into_cancelled_match_returns_match_cancelled.1.json new file mode 100644 index 0000000..8e0ca29 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_deposit_into_cancelled_match_returns_match_cancelled.1.json @@ -0,0 +1,946 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "cancelled_deposit" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "cancel_match", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "cancelled_deposit" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "cancelled_deposit" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "cancelled_deposit" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_invalid_state.1.json b/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_invalid_state.1.json new file mode 100644 index 0000000..c772e43 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_invalid_state.1.json @@ -0,0 +1,1313 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "completed_deposit_game" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "string": "completed_deposit_game" + }, + { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_deposit_game" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_deposit_game" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_deposit_game" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Completed" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_deposit_game" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1100 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_match_completed.1.json b/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_match_completed.1.json new file mode 100644 index 0000000..15ee496 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_deposit_into_completed_match_returns_match_completed.1.json @@ -0,0 +1,1308 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "completed_deposit" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "string": "completed_deposit" + }, + { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_deposit" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "completed_deposit" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_deposit" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Completed" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "completed_deposit" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1100 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_double_initialize_fails.1.json b/contracts/escrow/test_snapshots/tests/test_double_initialize_fails.1.json deleted file mode 100644 index 9899119..0000000 --- a/contracts/escrow/test_snapshots/tests/test_double_initialize_fails.1.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0 - }, - "auth": [ - [], - [], - [] - ], - "ledger": { - "protocol_version": 22, - "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": [ - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "MatchCount" - } - ] - }, - "val": { - "u64": 0 - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Paused" - } - ] - }, - "val": { - "bool": false - } - } - ] - } - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_code": { - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - 4095 - ] - ] - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_draw_refund.1.json b/contracts/escrow/test_snapshots/tests/test_draw_refund.1.json index bf8b826..a4737c9 100644 --- a/contracts/escrow/test_snapshots/tests/test_draw_refund.1.json +++ b/contracts/escrow/test_snapshots/tests/test_draw_refund.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -214,18 +216,46 @@ { "function": { "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", "function_name": "submit_result", "args": [ { "u64": 0 }, + { + "string": "game2" + }, { "vec": [ { "symbol": "Draw" } ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } ] } @@ -235,6 +265,7 @@ ] ], [], + [], [] ], "ledger": { @@ -506,6 +537,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game2" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game2" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -543,6 +619,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -640,7 +724,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -699,7 +783,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -724,6 +808,150 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "game2" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Draw" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_duplicate_game_id_rejected.1.json b/contracts/escrow/test_snapshots/tests/test_duplicate_game_id_rejected.1.json new file mode 100644 index 0000000..0b240c1 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_duplicate_game_id_rejected.1.json @@ -0,0 +1,891 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "unique_game_123" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "unique_game_123" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "unique_game_123" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "unique_game_123" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_create_match.1.json b/contracts/escrow/test_snapshots/tests/test_is_funded_returns_false_on_fresh_match.1.json similarity index 95% rename from contracts/escrow/test_snapshots/tests/test_create_match.1.json rename to contracts/escrow/test_snapshots/tests/test_is_funded_returns_false_on_fresh_match.1.json index 18c982a..8f134bf 100644 --- a/contracts/escrow/test_snapshots/tests/test_create_match.1.json +++ b/contracts/escrow/test_snapshots/tests/test_is_funded_returns_false_on_fresh_match.1.json @@ -288,6 +288,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "abc123" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "abc123" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -422,7 +467,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ diff --git a/contracts/escrow/test_snapshots/tests/test_non_oracle_cannot_submit_result.1.json b/contracts/escrow/test_snapshots/tests/test_non_oracle_cannot_submit_result.1.json new file mode 100644 index 0000000..c41e99d --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_non_oracle_cannot_submit_result.1.json @@ -0,0 +1,1125 @@ +{ + "generators": { + "address": 8, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "game_unauth_oracle" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_unauth_oracle" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_unauth_oracle" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "game_unauth_oracle" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Active" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_player2_cancel_only_player2_deposited.1.json b/contracts/escrow/test_snapshots/tests/test_player2_cancel_only_player2_deposited.1.json index c91b292..fbb39d3 100644 --- a/contracts/escrow/test_snapshots/tests/test_player2_cancel_only_player2_deposited.1.json +++ b/contracts/escrow/test_snapshots/tests/test_player2_cancel_only_player2_deposited.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -423,6 +425,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_only" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_only" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -460,6 +507,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -557,7 +612,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -616,7 +671,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -641,6 +696,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_player2_cancel_pending_match.1.json b/contracts/escrow/test_snapshots/tests/test_player2_cancel_pending_match.1.json index 510ec3e..82a4ca0 100644 --- a/contracts/escrow/test_snapshots/tests/test_player2_cancel_pending_match.1.json +++ b/contracts/escrow/test_snapshots/tests/test_player2_cancel_pending_match.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -343,6 +345,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_cancel" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_cancel" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -380,6 +427,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -477,7 +532,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -536,7 +591,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -561,6 +616,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_player2_cancel_refunds_both_players.1.json b/contracts/escrow/test_snapshots/tests/test_player2_cancel_refunds_both_players.1.json index 64fa5b5..20fccac 100644 --- a/contracts/escrow/test_snapshots/tests/test_player2_cancel_refunds_both_players.1.json +++ b/contracts/escrow/test_snapshots/tests/test_player2_cancel_refunds_both_players.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -446,6 +448,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_cancel_refund" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_p2_cancel_refund" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -483,6 +530,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -580,7 +635,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -639,7 +694,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -664,6 +719,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_submit_result_emits_event.1.json b/contracts/escrow/test_snapshots/tests/test_submit_result_emits_event.1.json index 8d955db..b186ac4 100644 --- a/contracts/escrow/test_snapshots/tests/test_submit_result_emits_event.1.json +++ b/contracts/escrow/test_snapshots/tests/test_submit_result_emits_event.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -214,18 +216,46 @@ { "function": { "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", "function_name": "submit_result", "args": [ { "u64": 0 }, + { + "string": "game_evt" + }, { "vec": [ { - "symbol": "Player1" + "symbol": "Player1Wins" } ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } ] } @@ -504,6 +534,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_evt" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_evt" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -541,6 +616,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -638,7 +721,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -697,7 +780,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -722,6 +805,150 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "game_evt" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Player1Wins" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], [ { "contract_data": { diff --git a/contracts/escrow/test_snapshots/tests/test_submit_result_on_cancelled_match_returns_invalid_state.1.json b/contracts/escrow/test_snapshots/tests/test_submit_result_on_cancelled_match_returns_invalid_state.1.json new file mode 100644 index 0000000..9ed8346 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_submit_result_on_cancelled_match_returns_invalid_state.1.json @@ -0,0 +1,947 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "cancelled_game" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "cancel_match", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "cancelled_game" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "cancelled_game" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "cancelled_game" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_cancel.1.json b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_cancel.1.json new file mode 100644 index 0000000..2a7aaa4 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_cancel.1.json @@ -0,0 +1,946 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "ttl_game4" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "cancel_match", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game4" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ttl_game4" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Cancelled" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_admin_pause_blocks_create_match.1.json b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_create_match.1.json similarity index 69% rename from contracts/escrow/test_snapshots/tests/test_admin_pause_blocks_create_match.1.json rename to contracts/escrow/test_snapshots/tests/test_ttl_extended_on_create_match.1.json index aa10bfb..a5ad60e 100644 --- a/contracts/escrow/test_snapshots/tests/test_admin_pause_blocks_create_match.1.json +++ b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_create_match.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 6, + "address": 7, "nonce": 0 }, "auth": [ @@ -75,15 +75,43 @@ ], [], [], + [], + [], [ [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", { "function": { "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "pause", - "args": [] + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "ttl_game1" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] } }, "sub_invocations": [] @@ -202,7 +230,7 @@ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "key": { "ledger_key_nonce": { - "nonce": 4837995959683129791 + "nonce": 5541220902715666415 } }, "durability": "temporary" @@ -217,7 +245,7 @@ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "key": { "ledger_key_nonce": { - "nonce": 4837995959683129791 + "nonce": 5541220902715666415 } }, "durability": "temporary", @@ -232,10 +260,10 @@ [ { "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 5541220902715666415 + "nonce": 4837995959683129791 } }, "durability": "temporary" @@ -247,10 +275,10 @@ "data": { "contract_data": { "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", "key": { "ledger_key_nonce": { - "nonce": 5541220902715666415 + "nonce": 4837995959683129791 } }, "durability": "temporary", @@ -262,6 +290,196 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game1" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ttl_game1" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], [ { "contract_data": { @@ -306,7 +524,7 @@ ] }, "val": { - "u64": 0 + "u64": 1 } }, { @@ -318,7 +536,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -330,7 +548,52 @@ ] }, "val": { - "bool": true + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" } } ] diff --git a/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_deposit.1.json b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_deposit.1.json new file mode 100644 index 0000000..b928638 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_deposit.1.json @@ -0,0 +1,1043 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "ttl_game2" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game2" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game2" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ttl_game2" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_submit_result.1.json b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_submit_result.1.json new file mode 100644 index 0000000..cba7141 --- /dev/null +++ b/contracts/escrow/test_snapshots/tests/test_ttl_extended_on_submit_result.1.json @@ -0,0 +1,1308 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "create_match", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + }, + { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + }, + { + "string": "ttl_game3" + }, + { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "deposit", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "string": "ttl_game3" + }, + { + "vec": [ + { + "symbol": "Player2Wins" + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "submit_result", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 8370022561469687789 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4270020994084947596 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game3" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "ttl_game3" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "Match" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ttl_game3" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "platform" + }, + "val": { + "vec": [ + { + "symbol": "Lichess" + } + ] + } + }, + { + "key": { + "symbol": "player1" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "player1_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "player2" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "player2_deposited" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "stake_amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "state" + }, + "val": { + "vec": [ + { + "symbol": "Completed" + } + ] + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "MatchCount" + } + ] + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Oracle" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Paused" + } + ] + }, + "val": { + "bool": false + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "vec": [ + { + "symbol": "Result" + }, + { + "u64": 0 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "game_id" + }, + "val": { + "string": "ttl_game3" + } + }, + { + "key": { + "symbol": "result" + }, + "val": { + "vec": [ + { + "symbol": "Player2Wins" + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 6277191135259896685 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 900 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1100 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000005" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/tests/test_unauthorized_player_cannot_cancel.1.json b/contracts/escrow/test_snapshots/tests/test_unauthorized_player_cannot_cancel.1.json index 19b76be..a9ccb63 100644 --- a/contracts/escrow/test_snapshots/tests/test_unauthorized_player_cannot_cancel.1.json +++ b/contracts/escrow/test_snapshots/tests/test_unauthorized_player_cannot_cancel.1.json @@ -1,6 +1,6 @@ { "generators": { - "address": 7, + "address": 8, "nonce": 0 }, "auth": [ @@ -75,6 +75,8 @@ ], [], [], + [], + [], [ [ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", @@ -288,6 +290,51 @@ 6311999 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_unauthorized" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "vec": [ + { + "symbol": "GameId" + }, + { + "string": "game_unauthorized" + } + ] + }, + "durability": "persistent", + "val": { + "bool": true + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { @@ -325,6 +372,14 @@ "durability": "persistent", "val": { "map": [ + { + "key": { + "symbol": "created_ledger" + }, + "val": { + "u32": 0 + } + }, { "key": { "symbol": "game_id" @@ -422,7 +477,7 @@ }, "ext": "v0" }, - 4095 + 518400 ] ], [ @@ -481,7 +536,7 @@ ] }, "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" } }, { @@ -506,6 +561,51 @@ 4095 ] ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], [ { "contract_data": { diff --git a/contracts/oracle/Cargo.toml b/contracts/oracle/Cargo.toml index 6af5453..e73f99c 100644 --- a/contracts/oracle/Cargo.toml +++ b/contracts/oracle/Cargo.toml @@ -11,3 +11,4 @@ soroban-sdk = { workspace = true } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } +escrow = { path = "../escrow" } diff --git a/contracts/oracle/src/errors.rs b/contracts/oracle/src/errors.rs index cc84b94..166edd9 100644 --- a/contracts/oracle/src/errors.rs +++ b/contracts/oracle/src/errors.rs @@ -3,8 +3,20 @@ use soroban_sdk::contracterror; #[contracterror] #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Error { + /// Code 1 β€” The caller is not the authorised oracle admin. Unauthorized = 1, + + /// Code 2 β€” A result for this match ID has already been submitted; + /// results are immutable once recorded. AlreadySubmitted = 2, + + /// Code 3 β€” No result has been recorded for the requested match ID. ResultNotFound = 3, + + /// Code 4 β€” `initialize` has already been called on this contract; + /// it can only be called once. AlreadyInitialized = 4, + + /// Code 5 β€” The match ID referenced does not exist in the escrow contract. + MatchNotFound = 5, } diff --git a/contracts/oracle/src/lib.rs b/contracts/oracle/src/lib.rs index f8270a1..dcf3d2a 100644 --- a/contracts/oracle/src/lib.rs +++ b/contracts/oracle/src/lib.rs @@ -2,10 +2,11 @@ mod errors; mod types; +pub use types::MatchResult; use errors::Error; use soroban_sdk::{contract, contractimpl, symbol_short, Address, Env, String, Symbol}; -use types::{DataKey, MatchResult, ResultEntry}; +use types::{DataKey, ResultEntry}; /// ~30 days at 5s/ledger. const MATCH_TTL_LEDGERS: u32 = 518_400; @@ -16,19 +17,32 @@ pub struct OracleContract; #[contractimpl] impl OracleContract { /// Initialize with a trusted admin (the off-chain oracle service). - pub fn initialize(env: Env, admin: Address) { + /// + /// Must be called by the deployer immediately after deployment. + /// The deployer address is passed as `deployer` and must authorize this call, + /// preventing any third party from front-running initialization. + pub fn initialize(env: Env, admin: Address, deployer: Address) { + deployer.require_auth(); if env.storage().instance().has(&DataKey::Admin) { panic!("Contract already initialized"); } env.storage().instance().set(&DataKey::Admin, &admin); + env.events() + .publish((Symbol::new(&env, "oracle"), symbol_short!("init")), admin); } /// Admin submits a verified match result on-chain. + /// + /// `escrow` is the deployed escrow contract address. `match_id` must + /// correspond to a real match in that contract β€” if no such match exists, + /// `Error::MatchNotFound` is returned and nothing is stored, preventing + /// orphaned result entries from polluting storage. pub fn submit_result( env: Env, match_id: u64, game_id: String, result: MatchResult, + escrow: Address, ) -> Result<(), Error> { let admin: Address = env .storage() @@ -37,6 +51,19 @@ impl OracleContract { .ok_or(Error::Unauthorized)?; admin.require_auth(); + // Cross-contract call: verify the match exists in the escrow contract. + // get_match returns Err if the match_id is unknown; we map that to + // Error::MatchNotFound to prevent orphaned result entries. + use soroban_sdk::IntoVal; + let args = soroban_sdk::vec![&env, match_id.into_val(&env)]; + let call_result: Result< + Result, + Result, + > = env.try_invoke_contract(&escrow, &soroban_sdk::Symbol::new(&env, "get_match"), args); + if call_result.is_err() { + return Err(Error::MatchNotFound); + } + if env.storage().persistent().has(&DataKey::Result(match_id)) { return Err(Error::AlreadySubmitted); } @@ -71,54 +98,223 @@ impl OracleContract { } /// Check whether a result has been submitted for a match. + /// + /// # Access + /// This function is intentionally **public and unauthenticated**. It is a + /// read-only probe that returns a boolean β€” no result data is exposed. + /// + /// For most tournament contexts this is acceptable: knowing that *a* result + /// exists leaks no information about *who* won. If your use-case requires + /// keeping result existence private until an official announcement, use + /// [`has_result_admin`] instead, which requires admin authorisation. pub fn has_result(env: Env, match_id: u64) -> bool { env.storage().persistent().has(&DataKey::Result(match_id)) } + + /// Admin-gated variant of [`has_result`] for private-tournament contexts. + /// + /// Identical in behaviour to `has_result` but requires the stored admin to + /// authorise the call, preventing any third party from probing whether a + /// result has been submitted before the official announcement. + /// + /// # Errors + /// Returns [`Error::Unauthorized`] if the contract has not been initialised + /// or if the caller is not the current admin. + pub fn has_result_admin(env: Env, match_id: u64) -> Result { + let admin: Address = env + .storage() + .instance() + .get(&DataKey::Admin) + .ok_or(Error::Unauthorized)?; + admin.require_auth(); + Ok(env.storage().persistent().has(&DataKey::Result(match_id))) + } + + /// Rotate the admin to a new address. Requires current admin auth. + pub fn update_admin(env: Env, new_admin: Address) -> Result<(), Error> { + let current_admin: Address = env + .storage() + .instance() + .get(&DataKey::Admin) + .ok_or(Error::Unauthorized)?; + current_admin.require_auth(); + env.storage().instance().set(&DataKey::Admin, &new_admin); + Ok(()) + } } #[cfg(test)] mod tests { use super::*; + use escrow::{EscrowContract, EscrowContractClient}; use soroban_sdk::{ testutils::{storage::Persistent as _, Address as _, Events}, + token::StellarAssetClient, Address, Env, IntoVal, String, Symbol, }; - fn setup() -> (Env, Address) { + /// Returns (env, oracle_contract_id, escrow_contract_id, admin, player1, player2, token) + /// with a real escrow match (id=0) already created and both players deposited (Active). + fn setup() -> (Env, Address, Address, Address, Address, Address, Address) { let env = Env::default(); env.mock_all_auths(); + + let admin = Address::generate(&env); + let oracle_admin = Address::generate(&env); + let player1 = Address::generate(&env); + let player2 = Address::generate(&env); + + // Register token + let token_id = env.register_stellar_asset_contract_v2(admin.clone()); + let token_addr = token_id.address(); + let asset_client = StellarAssetClient::new(&env, &token_addr); + asset_client.mint(&player1, &1000); + asset_client.mint(&player2, &1000); + + // Register escrow contract and create + fund a match (id=0) + let escrow_id = env.register(EscrowContract, ()); + let escrow_client = EscrowContractClient::new(&env, &escrow_id); + escrow_client.initialize(&oracle_admin, &admin, &admin); + escrow_client.create_match( + &player1, + &player2, + &100, + &token_addr, + &String::from_str(&env, "test_game"), + &escrow::types::Platform::Lichess, + ); + escrow_client.deposit(&0u64, &player1); + escrow_client.deposit(&0u64, &player2); + + // Register oracle contract + let oracle_id = env.register(OracleContract, ()); + let oracle_client = OracleContractClient::new(&env, &oracle_id); + oracle_client.initialize(&oracle_admin, &oracle_admin); + + ( + env, + oracle_id, + escrow_id, + oracle_admin, + player1, + player2, + token_addr, + ) + } + + // ── has_result (public, unauthenticated) ───────────────────────────────── + + /// Confirms that any caller can invoke has_result without authentication. + /// Returns false before a result is submitted and true afterwards. + #[test] + fn test_has_result_is_public_and_unauthenticated() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + // Before submission β€” any caller can probe, no auth required + assert!(!client.has_result(&0u64)); + assert!(!client.has_result(&999u64)); + + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Player1Wins, + &escrow_id, + ); + + // After submission β€” still public, now returns true + assert!(client.has_result(&0u64)); + // Unrelated match_id still false + assert!(!client.has_result(&999u64)); + } + + // ── has_result_admin (admin-gated) ──────────────────────────────────────── + + /// Admin can probe result existence via the gated variant. + #[test] + fn test_has_result_admin_returns_false_before_submission() { + let (env, contract_id, _escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + assert!(!client.has_result_admin(&0u64)); + assert!(!client.has_result_admin(&999u64)); + } + + /// has_result_admin returns true after a result is submitted. + #[test] + fn test_has_result_admin_returns_true_after_submission() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Player1Wins, + &escrow_id, + ); + + assert!(client.has_result_admin(&0u64)); + } + + /// Non-admin callers must not be able to call has_result_admin. + #[test] + #[should_panic] + fn test_has_result_admin_rejects_non_admin() { + let env = Env::default(); + // Do NOT mock all auths β€” we want auth to actually be enforced let admin = Address::generate(&env); + let non_admin = Address::generate(&env); let contract_id = env.register(OracleContract, ()); let client = OracleContractClient::new(&env, &contract_id); - client.initialize(&admin); - (env, contract_id) + + env.mock_all_auths(); + client.initialize(&admin, &admin); + + // Only authorise non_admin β€” should fail + env.mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &non_admin, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &contract_id, + fn_name: "has_result_admin", + args: (0u64,).into_val(&env), + sub_invokes: &[], + }, + }]); + client.has_result_admin(&0u64); } #[test] fn test_submit_and_get_result() { - let (env, contract_id) = setup(); + let (env, contract_id, escrow_id, ..) = setup(); let client = OracleContractClient::new(&env, &contract_id); + // Before submission + assert!(!client.has_result(&0u64)); + client.submit_result( &0u64, - &String::from_str(&env, "abc123"), + &String::from_str(&env, "test_game"), &MatchResult::Player1Wins, + &escrow_id, ); + // After submission assert!(client.has_result(&0u64)); let entry = client.get_result(&0u64); assert_eq!(entry.result, MatchResult::Player1Wins); + assert_eq!(entry.game_id, String::from_str(&env, "test_game")); } #[test] fn test_submit_result_emits_event() { - let (env, contract_id) = setup(); + let (env, contract_id, escrow_id, ..) = setup(); let client = OracleContractClient::new(&env, &contract_id); client.submit_result( &0u64, - &String::from_str(&env, "abc123"), + &String::from_str(&env, "test_game"), &MatchResult::Player1Wins, + &escrow_id, ); let events = env.events().all(); @@ -142,12 +338,22 @@ mod tests { #[test] #[should_panic] fn test_duplicate_submit_fails() { - let (env, contract_id) = setup(); + let (env, contract_id, escrow_id, ..) = setup(); let client = OracleContractClient::new(&env, &contract_id); - client.submit_result(&0u64, &String::from_str(&env, "abc123"), &MatchResult::Draw); + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Draw, + &escrow_id, + ); // second submit should panic - client.submit_result(&0u64, &String::from_str(&env, "abc123"), &MatchResult::Draw); + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Draw, + &escrow_id, + ); } #[test] @@ -159,27 +365,195 @@ mod tests { let contract_id = env.register(OracleContract, ()); let client = OracleContractClient::new(&env, &contract_id); - client.initialize(&admin); - // second initialize should panic - client.initialize(&admin); + client.initialize(&admin, &admin); + client.initialize(&admin, &admin); } #[test] fn test_ttl_extended_on_submit_result() { - let (env, contract_id) = setup(); + let (env, contract_id, escrow_id, ..) = setup(); let client = OracleContractClient::new(&env, &contract_id); client.submit_result( &0u64, - &String::from_str(&env, "abc123"), + &String::from_str(&env, "test_game"), &MatchResult::Player1Wins, + &escrow_id, ); let ttl = env.as_contract(&contract_id, || { - env.storage() - .persistent() - .get_ttl(&DataKey::Result(0u64)) + env.storage().persistent().get_ttl(&DataKey::Result(0u64)) }); assert_eq!(ttl, crate::MATCH_TTL_LEDGERS); } + + #[test] + fn test_admin_rotation() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + let new_admin = Address::generate(&env); + + client.update_admin(&new_admin); + + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Player2Wins, + &escrow_id, + ); + assert!(client.has_result(&0u64)); + } + + #[test] + #[should_panic] + fn test_old_admin_cannot_act_after_rotation() { + let env = Env::default(); + let old_admin = Address::generate(&env); + let new_admin = Address::generate(&env); + let contract_id = env.register(OracleContract, ()); + let client = OracleContractClient::new(&env, &contract_id); + let escrow_id = env.register(EscrowContract, ()); + + env.mock_all_auths(); + client.initialize(&old_admin, &old_admin); + client.update_admin(&new_admin); + + env.mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &old_admin, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &contract_id, + fn_name: "submit_result", + args: ( + 1u64, + String::from_str(&env, "game_old"), + MatchResult::Player1Wins, + escrow_id.clone(), + ) + .into_val(&env), + sub_invokes: &[], + }, + }]); + client.submit_result( + &1u64, + &String::from_str(&env, "game_old"), + &MatchResult::Player1Wins, + &escrow_id, + ); + } + + // ── Non-existent match_id rejected ─────────────────────────────────────── + + /// Submitting a result for a match_id that does not exist in the escrow + /// contract must return Error::MatchNotFound and store nothing. + #[test] + fn test_submit_result_for_nonexistent_match_returns_match_not_found() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + // match_id 999 was never created in the escrow contract + let result = client.try_submit_result( + &999u64, + &String::from_str(&env, "ghost_game"), + &MatchResult::Player1Wins, + &escrow_id, + ); + + assert_eq!( + result, + Err(Ok(Error::MatchNotFound)), + "submit_result must return MatchNotFound for a non-existent match_id" + ); + + // Nothing should have been stored + assert!(!client.has_result(&999u64)); + } + + #[test] + fn test_initialize_emits_event() { + let env = Env::default(); + env.mock_all_auths(); + let admin = Address::generate(&env); + let contract_id = env.register(OracleContract, ()); + let client = OracleContractClient::new(&env, &contract_id); + + client.initialize(&admin, &admin); + + let events = env.events().all(); + let expected_topics = soroban_sdk::vec![ + &env, + Symbol::new(&env, "oracle").into_val(&env), + symbol_short!("init").into_val(&env), + ]; + let matched = events + .iter() + .find(|(_, topics, _)| *topics == expected_topics); + assert!(matched.is_some(), "oracle initialized event not emitted"); + + let (_, _, data) = matched.unwrap(); + let emitted_admin: Address = soroban_sdk::TryFromVal::try_from_val(&env, &data).unwrap(); + assert_eq!(emitted_admin, admin); + } + + #[test] + fn test_submit_draw_result_stores_correctly() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Draw, + &escrow_id, + ); + + let entry = client.get_result(&0u64); + assert_eq!(entry.result, MatchResult::Draw); + } + + #[test] + fn test_submit_player2wins_result_stores_correctly() { + let (env, contract_id, escrow_id, ..) = setup(); + let client = OracleContractClient::new(&env, &contract_id); + + client.submit_result( + &0u64, + &String::from_str(&env, "test_game"), + &MatchResult::Player2Wins, + &escrow_id, + ); + + let entry = client.get_result(&0u64); + assert_eq!(entry.result, MatchResult::Player2Wins); + } + + // ── #216: oracle initialize front-run guard ─────────────────────────────── + + /// A non-deployer must not be able to call initialize on the oracle contract. + #[test] + fn test_oracle_initialize_rejects_unauthorized_caller() { + let env = Env::default(); + env.mock_all_auths(); + + let deployer = Address::generate(&env); + let attacker = Address::generate(&env); + let admin = Address::generate(&env); + + let contract_id = env.register(OracleContract, ()); + let client = OracleContractClient::new(&env, &contract_id); + + use soroban_sdk::testutils::{MockAuth, MockAuthInvoke}; + env.set_auths(&[MockAuth { + address: &attacker, + invoke: &MockAuthInvoke { + contract: &contract_id, + fn_name: "initialize", + args: (&admin, &deployer).into_val(&env), + sub_invokes: &[], + }, + } + .into()]); + + let result = client.try_initialize(&admin, &deployer); + assert!(result.is_err(), "oracle initialize must reject a non-deployer caller"); + } } diff --git a/contracts/oracle/test_snapshots/tests/test_double_initialize_fails.1.json b/contracts/oracle/test_snapshots/tests/test_double_initialize_fails.1.json deleted file mode 100644 index fa021d4..0000000 --- a/contracts/oracle/test_snapshots/tests/test_double_initialize_fails.1.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "generators": { - "address": 2, - "nonce": 0 - }, - "auth": [ - [], - [], - [] - ], - "ledger": { - "protocol_version": 22, - "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": [ - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_code": { - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - 4095 - ] - ] - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/oracle/test_snapshots/tests/test_duplicate_submit_fails.1.json b/contracts/oracle/test_snapshots/tests/test_duplicate_submit_fails.1.json deleted file mode 100644 index 591bd33..0000000 --- a/contracts/oracle/test_snapshots/tests/test_duplicate_submit_fails.1.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "generators": { - "address": 2, - "nonce": 0 - }, - "auth": [ - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "function_name": "submit_result", - "args": [ - { - "u64": 0 - }, - { - "string": "abc123" - }, - { - "vec": [ - { - "symbol": "Draw" - } - ] - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [] - ], - "ledger": { - "protocol_version": 22, - "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": [ - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - 6311999 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "game_id" - }, - "val": { - "string": "abc123" - } - }, - { - "key": { - "symbol": "result" - }, - "val": { - "vec": [ - { - "symbol": "Draw" - } - ] - } - } - ] - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_code": { - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - 4095 - ] - ] - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/oracle/test_snapshots/tests/test_submit_and_get_result.1.json b/contracts/oracle/test_snapshots/tests/test_submit_and_get_result.1.json deleted file mode 100644 index 11f3673..0000000 --- a/contracts/oracle/test_snapshots/tests/test_submit_and_get_result.1.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "generators": { - "address": 2, - "nonce": 0 - }, - "auth": [ - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "function_name": "submit_result", - "args": [ - { - "u64": 0 - }, - { - "string": "abc123" - }, - { - "vec": [ - { - "symbol": "Player1Wins" - } - ] - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [] - ], - "ledger": { - "protocol_version": 22, - "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": [ - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - 6311999 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "game_id" - }, - "val": { - "string": "abc123" - } - }, - { - "key": { - "symbol": "result" - }, - "val": { - "vec": [ - { - "symbol": "Player1Wins" - } - ] - } - } - ] - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_code": { - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - 4095 - ] - ] - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/oracle/test_snapshots/tests/test_submit_result_emits_event.1.json b/contracts/oracle/test_snapshots/tests/test_submit_result_emits_event.1.json deleted file mode 100644 index b6d2c94..0000000 --- a/contracts/oracle/test_snapshots/tests/test_submit_result_emits_event.1.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "generators": { - "address": 2, - "nonce": 0 - }, - "auth": [ - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "function_name": "submit_result", - "args": [ - { - "u64": 0 - }, - { - "string": "abc123" - }, - { - "vec": [ - { - "symbol": "Player1Wins" - } - ] - } - ] - } - }, - "sub_invocations": [] - } - ] - ] - ], - "ledger": { - "protocol_version": 22, - "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": [ - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": { - "ledger_key_nonce": { - "nonce": 801925984706572462 - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - 6311999 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "vec": [ - { - "symbol": "Result" - }, - { - "u64": 0 - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "game_id" - }, - "val": { - "string": "abc123" - } - }, - { - "key": { - "symbol": "result" - }, - "val": { - "vec": [ - { - "symbol": "Player1Wins" - } - ] - } - } - ] - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_data": { - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - 4095 - ] - ], - [ - { - "contract_code": { - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - } - }, - [ - { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - 4095 - ] - ] - ] - }, - "events": [ - { - "event": { - "ext": "v0", - "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", - "type_": "contract", - "body": { - "v0": { - "topics": [ - { - "symbol": "oracle" - }, - { - "symbol": "result" - } - ], - "data": { - "vec": [ - { - "u64": 0 - }, - { - "vec": [ - { - "symbol": "Player1Wins" - } - ] - } - ] - } - } - } - }, - "failed_call": false - } - ] -} \ No newline at end of file diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..6978d47 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,96 @@ +# Deployment Sequence + +This document describes the required deployment order and initialization steps +for the Checkmate Escrow smart contracts. + +--- + +## Why Order Matters + +Both the `OracleContract` and `EscrowContract` expose an `initialize` function +that must be called exactly once after deployment. Prior to the fix for +[#216], these functions had no deployer guard, meaning any observer of the +deployment transaction could front-run the call and initialize the contract +with a malicious admin or oracle address. + +The fix requires the deployer address to be passed explicitly and to authorize +the `initialize` call via `deployer.require_auth()`. This means only the +account that deployed the contract can initialize it. + +--- + +## Deployment Steps + +### 1. Deploy OracleContract + +```bash +stellar contract deploy \ + --wasm target/wasm32-unknown-unknown/release/oracle.wasm \ + --source +# β†’ outputs ORACLE_CONTRACT_ID +``` + +### 2. Initialize OracleContract + +The `deployer` argument must be the same account used to deploy the contract. + +```bash +stellar contract invoke \ + --id $ORACLE_CONTRACT_ID \ + --source \ + -- initialize \ + --admin \ + --deployer +``` + +### 3. Deploy EscrowContract + +```bash +stellar contract deploy \ + --wasm target/wasm32-unknown-unknown/release/escrow.wasm \ + --source +# β†’ outputs ESCROW_CONTRACT_ID +``` + +### 4. Initialize EscrowContract + +The `oracle` argument must be the `ORACLE_CONTRACT_ID` from step 1. +The `deployer` argument must be the same account used to deploy the contract. + +```bash +stellar contract invoke \ + --id $ESCROW_CONTRACT_ID \ + --source \ + -- initialize \ + --oracle $ORACLE_CONTRACT_ID \ + --admin \ + --deployer +``` + +--- + +## Security Notes + +- Steps 2 and 4 must be executed **in the same transaction or immediately after + deployment** to eliminate the front-run window. Use a deployment script that + batches deploy + initialize atomically where possible. +- The `deployer` address passed to `initialize` must match the account signing + the transaction. Any mismatch will cause `require_auth` to fail. +- Once initialized, `initialize` cannot be called again (guarded by an + `AlreadyInitialized` check). + +--- + +## Verifying Initialization + +After initialization, confirm the stored admin and oracle addresses: + +```bash +# Escrow: read admin +stellar contract invoke --id $ESCROW_CONTRACT_ID -- get_admin + +# Oracle: verify a result can be submitted (requires oracle admin auth) +stellar contract invoke --id $ORACLE_CONTRACT_ID \ + --source \ + -- has_result_admin --match_id 0 +``` diff --git a/docs/error-codes.md b/docs/error-codes.md new file mode 100644 index 0000000..77edc1a --- /dev/null +++ b/docs/error-codes.md @@ -0,0 +1,78 @@ +# Error Code Reference + +This document maps the numeric error codes returned by the Checkmate smart +contracts to their meanings. Frontends and integrators can use this table to +display human-readable messages when a transaction fails. + +Soroban surfaces contract errors as a numeric `u32` value in the transaction +result. Match the value against the tables below to identify the cause. + +--- + +## EscrowContract Errors + +| Code | Variant | When it is returned | +|------|---------|---------------------| +| 1 | `MatchNotFound` | The requested match ID does not exist in storage. | +| 2 | `AlreadyFunded` | The calling player has already deposited into this match. | +| 3 | `NotFunded` | The match has not been fully funded yet; both players must deposit before this operation is allowed. | +| 4 | `Unauthorized` | The caller is not authorised to perform this operation (e.g. a non-player trying to cancel, or a non-oracle submitting a result). | +| 5 | `InvalidState` | The match is in a state that does not permit the requested operation (e.g. trying to deposit into an already-active match). | +| 6 | `AlreadyExists` | A generic "already exists" guard was triggered. | +| 7 | `AlreadyInitialized` | `initialize` has already been called; it can only be called once. | +| 8 | `Overflow` | An arithmetic operation would overflow. | +| 9 | `ContractPaused` | The contract is paused by the admin; no new matches can be created until it is unpaused. | +| 10 | `InvalidAmount` | The supplied stake amount is zero or otherwise invalid. | +| 11 | `MatchCancelled` | The match has been cancelled; the requested operation cannot be performed on a cancelled match. | +| 12 | `MatchCompleted` | The match has already been completed; the requested operation cannot be performed on a completed match. | +| 13 | `DuplicateGameId` | The `game_id` supplied to `create_match` has already been used by another match. | +| 14 | `MatchNotExpired` | The match has not yet expired; expiry-based operations (e.g. admin cancellation after timeout) are not yet permitted. | +| 15 | `InvalidGameId` | The `game_id` string is invalid (e.g. exceeds the maximum allowed length of 64 bytes). | +| 16 | `ResultNotFound` | No oracle result has been recorded for this match ID. | +| 17 | `InvalidToken` | The token address supplied is not the token this contract was initialised with. | + +--- + +## OracleContract Errors + +| Code | Variant | When it is returned | +|------|---------|---------------------| +| 1 | `Unauthorized` | The caller is not the authorised oracle admin. | +| 2 | `AlreadySubmitted` | A result for this match ID has already been submitted; results are immutable once recorded. | +| 3 | `ResultNotFound` | No result has been recorded for the requested match ID. | +| 4 | `AlreadyInitialized` | `initialize` has already been called; it can only be called once. | +| 5 | `MatchNotFound` | The match ID referenced does not exist in the escrow contract. | + +--- + +## Suggested Frontend Messages + +```js +const ESCROW_ERRORS = { + 1: "Match not found.", + 2: "You have already deposited into this match.", + 3: "Match is not fully funded yet.", + 4: "You are not authorised to perform this action.", + 5: "This action is not allowed in the current match state.", + 6: "Already exists.", + 7: "Contract is already initialised.", + 8: "Arithmetic overflow.", + 9: "Contract is currently paused.", + 10: "Invalid stake amount.", + 11: "Match has been cancelled.", + 12: "Match has already been completed.", + 13: "This game ID has already been used.", + 14: "Match has not expired yet.", + 15: "Invalid game ID.", + 16: "No result found for this match.", + 17: "Invalid token.", +}; + +const ORACLE_ERRORS = { + 1: "Unauthorised.", + 2: "Result already submitted for this match.", + 3: "No result found for this match.", + 4: "Contract is already initialised.", + 5: "Match not found.", +}; +``` diff --git a/docs/oracle.md b/docs/oracle.md new file mode 100644 index 0000000..c84481c --- /dev/null +++ b/docs/oracle.md @@ -0,0 +1,144 @@ +# Oracle Integration Guide + +This document describes how the off-chain oracle service interacts with the +Checkmate Escrow smart contracts, with a focus on the `game_id` field. + +--- + +## game_id Format + +The `game_id` field is a platform-specific string that uniquely identifies a +chess game. It is supplied when creating a match and must be passed to the +oracle when submitting a result. The oracle uses it to look up the game outcome +via the platform's public API. + +### Lichess + +Lichess game IDs are **8-character alphanumeric strings** (case-sensitive, +lowercase letters and digits). + +They appear in the game URL: + +``` +https://lichess.org/abcd1234 + ^^^^^^^^ + game_id = "abcd1234" +``` + +Example API call the oracle makes: + +``` +GET https://lichess.org/game/export/abcd1234 +``` + +Valid example: `"abcd1234"` +Invalid examples: `"ABCD1234"` (uppercase), `"abcd123"` (7 chars), `""` (empty) + +### Chess.com + +Chess.com game IDs are **numeric strings**, typically 7–12 digits, found in +the live game URL: + +``` +https://www.chess.com/game/live/123456789 + ^^^^^^^^^ + game_id = "123456789" +``` + +Example API call the oracle makes: + +``` +GET https://api.chess.com/pub/game/123456789 +``` + +Valid example: `"123456789"` +Invalid examples: `"abc"` (non-numeric), `""` (empty) + +--- + +## Validation Rules + +| Rule | Details | +|------|---------| +| Max length | 64 bytes (`MAX_GAME_ID_LEN`). Enforced on-chain β€” `create_match` returns `Error::InvalidGameId` if exceeded. | +| Uniqueness | Each `game_id` can only be used once. A duplicate returns `Error::DuplicateGameId`. | +| Format | Not validated on-chain. Passing a malformed ID will cause the oracle to fail result lookup off-chain. | +| Platform match | The `platform` field must match the source of the `game_id`. Mismatches are not caught on-chain but will cause oracle verification to fail. | + +--- + +## Submitting a Result + +Once a game is finished, the oracle calls `submit_result` on the escrow +contract with the `match_id`, `game_id`, and `Winner` enum: + +```rust +// Winner::Player1 | Winner::Player2 | Winner::Draw +escrow_client.submit_result(&match_id, &winner, &oracle_address); +``` + +The oracle also records the result independently via `OracleContract::submit_result`: + +```rust +oracle_client.submit_result(&match_id, &game_id, &MatchResult::Player1Wins); +``` + +--- + +## has_result vs has_result_admin + +The oracle contract exposes two ways to check whether a result has been +submitted for a given `match_id`. + +### `has_result` β€” public, unauthenticated + +```rust +oracle_client.has_result(&match_id); // β†’ bool +``` + +This is a read-only probe that returns `true` once a result has been stored. +It requires **no authentication** and can be called by anyone. + +This is intentional: the function exposes only the *existence* of a result, +not its content. For the majority of public tournament contexts this is +acceptable β€” knowing that *a* result exists leaks no information about *who* +won. + +### `has_result_admin` β€” admin-gated + +```rust +oracle_client.has_result_admin(&match_id); // β†’ Result +``` + +For private tournaments where even the existence of a result must remain +confidential until an official announcement, use this variant instead. It +requires the stored admin to authorise the call, preventing third-party +probing. + +Returns `Error::Unauthorized` if the caller is not the current admin. + +--- + +## Example: Full Match Lifecycle + +``` +1. player1 calls create_match( + player1, player2, + stake_amount = 100_000_000, + token = USDC_ADDRESS, + game_id = "abcd1234", // Lichess game ID + platform = Platform::Lichess + ) + +2. player1 calls deposit(match_id, player1) +3. player2 calls deposit(match_id, player2) + β†’ match state transitions to Active + +4. Game is played on Lichess. + +5. Oracle fetches result from https://lichess.org/game/export/abcd1234 + β†’ player1 wins + +6. Oracle calls escrow.submit_result(match_id, Winner::Player1, oracle_address) + β†’ player1 receives 2 Γ— stake_amount +``` diff --git a/issues.md b/issues.md deleted file mode 100644 index 8dec8b3..0000000 --- a/issues.md +++ /dev/null @@ -1,526 +0,0 @@ -## Fix: initialize can be called multiple times, overwriting oracle address -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -`initialize` in the escrow contract has no guard against being called twice. A second call silently overwrites the trusted oracle address, allowing an attacker to substitute a malicious oracle. - -**Tasks:** -- Check if `DataKey::Oracle` already exists before writing -- Return an error or panic if already initialized -- Add test for double-initialize rejection - ---- - -## Fix: oracle initialize can be called multiple times, overwriting admin -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -`OracleContract::initialize` has no guard against re-initialization. Any caller can overwrite the admin address after deployment. - -**Tasks:** -- Check if `DataKey::Admin` already exists before writing -- Panic with structured error if already initialized -- Add test for double-initialize rejection - ---- - -## Fix: create_match allows zero stake_amount -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -`create_match` accepts `stake_amount = 0`, creating a match with no economic value. Both players can deposit 0 tokens and the oracle will pay out 0, wasting ledger storage. - -**Tasks:** -- Add `if stake_amount <= 0 { return Err(Error::InvalidAmount) }` guard -- Add `InvalidAmount` error variant -- Add test for zero-stake rejection - ---- - -## Fix: cancel_match only allows player1 to cancel β€” player2 has no recourse -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 1 hour - -**Description:** -Only `player1` (the match creator) can cancel a pending match. If player1 abandons the match after player2 has deposited, player2's funds are locked with no way to recover them. - -**Tasks:** -- Allow either player to cancel if the match is still `Pending` -- Or allow player2 to cancel after a timeout if player1 has not deposited -- Add tests for player2-initiated cancellation - ---- - -## Fix: submit_result does not validate winner against match players -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 1 hour - -**Description:** -The oracle submits a `Winner` enum (`Player1`, `Player2`, `Draw`) but there is no cross-check that the oracle's `match_id` corresponds to the correct game. A compromised oracle could submit a result for the wrong match ID. - -**Tasks:** -- Include `game_id` in `submit_result` and verify it matches `m.game_id` -- Return `Error::GameIdMismatch` on mismatch -- Add test for mismatched game ID - ---- - -## Fix: get_escrow_balance uses boolean arithmetic that silently truncates -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Low -**Estimated Time:** 30 minutes - -**Description:** -`get_escrow_balance` computes `(player1_deposited as i128 + player2_deposited as i128) * stake_amount`. Casting `bool` to `i128` is non-obvious and fragile. If the type ever changes this silently breaks. - -**Tasks:** -- Replace with explicit match/if logic -- Add comment explaining the calculation -- Verify test coverage - ---- - -## Fix: deposit does not check match is not already Cancelled or Completed -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -`deposit` only checks `m.state != MatchState::Pending` and returns `InvalidState`. However the error message gives no indication of why. More importantly, a race condition could allow a deposit into a match being cancelled simultaneously. - -**Tasks:** -- Add explicit state checks with descriptive errors -- Add `Error::MatchCancelled` and `Error::MatchCompleted` variants -- Add tests for deposit into cancelled/completed match - ---- - -## Fix: oracle submit_result has no link back to escrow contract β€” results are siloed -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 2 hours - -**Description:** -The oracle contract stores results independently but the escrow contract's `submit_result` does not read from the oracle contract β€” it accepts the result directly from the oracle address. This means the oracle contract's stored results are never used by the escrow, making it redundant. - -**Tasks:** -- Decide on architecture: either escrow reads from oracle contract, or oracle calls escrow directly -- Implement the chosen integration -- Add integration test covering the full oracle β†’ escrow flow - ---- - -## Fix: MatchCount can overflow u64 with no guard -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Low -**Estimated Time:** 30 minutes - -**Description:** -`MatchCount` is incremented with `id + 1` and stored as `u64`. While overflow is practically unlikely, there is no checked arithmetic. In Soroban, integer overflow panics in debug but wraps in release. - -**Tasks:** -- Use `id.checked_add(1).ok_or(Error::Overflow)?` -- Add `Overflow` error variant -- Add comment documenting the guard - ---- - -## Fix: cancel_match does not require player2 auth when player2 has deposited -**Labels:** `bug`, `security` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 1 hour - -**Description:** -`cancel_match` only requires `player1.require_auth()`. If player2 has already deposited, player1 can cancel and trigger a refund to player2 without player2's consent. While the refund is correct, this could be used to grief player2 mid-game if the match state transitions are not atomic. - -**Tasks:** -- Document the intended cancellation authorization model -- If cancellation after player2 deposit should require both players, enforce it -- Add test for cancellation with both deposits present - ---- - -## Fix: Persistent storage entries have no TTL extension β€” data can expire -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 2 hours - -**Description:** -All `Match` and `Result` entries are written to persistent storage with no TTL extension calls. Soroban persistent storage entries expire after their TTL elapses. Expired match records would cause `MatchNotFound` errors for active matches. - -**Tasks:** -- Add `env.storage().persistent().extend_ttl(key, threshold, extend_to)` after every persistent write -- Define a `MATCH_TTL_LEDGERS` constant -- Add tests verifying TTL is set - ---- - -## Fix: submit_result in escrow does not emit an event -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 1 hour - -**Description:** -Payouts triggered by `submit_result` are not observable off-chain without polling storage. Off-chain indexers and frontends cannot detect match completions. - -**Tasks:** -- Add `env.events().publish` in `submit_result` after payout -- Define event topics: `(Symbol::new("match"), Symbol::new("completed"))` -- Include `match_id` and `winner` in event data -- Add test asserting event is emitted - ---- - -## Fix: create_match does not emit an event -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Match creation is not observable off-chain. Frontends must poll storage to discover new matches. - -**Tasks:** -- Add `env.events().publish` in `create_match` -- Include `match_id`, `player1`, `player2`, `stake_amount` in event data -- Add test asserting event is emitted - ---- - -## Fix: deposit does not emit an event -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Player deposits are not observable off-chain. Frontends cannot notify the opponent that funds are ready without polling. - -**Tasks:** -- Add `env.events().publish` in `deposit` -- Include `match_id` and `player` in event data -- Add test asserting event is emitted - ---- - -## Fix: cancel_match does not emit an event -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Match cancellations are silent on-chain. Players and frontends cannot detect cancellations without polling. - -**Tasks:** -- Add `env.events().publish` in `cancel_match` -- Include `match_id` in event data -- Add test asserting event is emitted - ---- - -## Fix: oracle submit_result does not emit an event -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Oracle result submissions are not observable off-chain. The escrow contract and external listeners cannot react to new results without polling. - -**Tasks:** -- Add `env.events().publish` in `OracleContract::submit_result` -- Include `match_id` and `result` in event data -- Add test asserting event is emitted - ---- - -## Fix: no mechanism to update oracle address post-deploy -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 1 hour - -**Description:** -The oracle address is set once at `initialize` and cannot be changed. If the oracle service is compromised or needs to be rotated, there is no way to update it without redeploying the entire escrow contract. - -**Tasks:** -- Add `update_oracle(new_oracle: Address)` admin function -- Require existing oracle or a separate admin address to authorize -- Add test for oracle rotation - ---- - -## Fix: no admin role in escrow contract β€” no emergency controls -**Labels:** `bug`, `security` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** High -**Estimated Time:** 2 hours - -**Description:** -The escrow contract has no admin address. There is no way to pause the contract, recover stuck funds, or respond to a critical vulnerability without a full redeploy. - -**Tasks:** -- Add `admin: Address` parameter to `initialize` -- Store admin in `DataKey::Admin` -- Add `pause()` / `unpause()` admin functions -- Add test for admin-only operations - ---- - -## Fix: create_match allows player1 == player2 (self-match) -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -There is no check that `player1 != player2`. A single address can create a match against itself, deposit twice, and receive the full pot back (minus any fees), wasting ledger resources. - -**Tasks:** -- Add `if player1 == player2 { return Err(Error::InvalidPlayers) }` guard -- Add `InvalidPlayers` error variant -- Add test for self-match rejection - ---- - -## Fix: game_id is not validated for uniqueness β€” same game can be used in multiple matches -**Labels:** `bug` -**Body:** -**Category:** Smart Contract - Bug -**Priority:** Medium -**Estimated Time:** 1 hour - -**Description:** -The same `game_id` can be used to create multiple matches. An attacker could create duplicate matches for the same game and collect payouts multiple times if the oracle submits results for each match ID. - -**Tasks:** -- Track used `game_id` values in a `DataKey::GameId(String)` set -- Reject `create_match` if `game_id` already exists -- Add test for duplicate game ID rejection - ---- - -## Add Test: deposit by non-player address should return Unauthorized -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -Verify that calling `deposit` with an address that is neither `player1` nor `player2` returns `Error::Unauthorized`. - -**Tasks:** -- Call `deposit` with a random third-party address -- Assert `Error::Unauthorized` is returned -- Add to test suite - ---- - -## Add Test: submit_result on Pending match (not yet Active) should return InvalidState -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -Verify that the oracle cannot submit a result for a match that has not yet reached `Active` state (i.e., both players haven't deposited). - -**Tasks:** -- Create match, do not deposit -- Call `submit_result` -- Assert `Error::InvalidState` is returned - ---- - -## Add Test: submit_result on already Completed match should return InvalidState -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -Verify that calling `submit_result` twice on the same match panics or returns `InvalidState` on the second call. - -**Tasks:** -- Complete a match with `submit_result` -- Call `submit_result` again on the same match -- Assert `Error::InvalidState` - ---- - -## Add Test: cancel_match on Active match should return InvalidState -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -Verify that a match cannot be cancelled once both players have deposited and it is `Active`. - -**Tasks:** -- Create match, both players deposit (match becomes Active) -- Call `cancel_match` -- Assert `Error::InvalidState` - ---- - -## Add Test: get_match on non-existent match_id should return MatchNotFound -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** Low -**Estimated Time:** 15 minutes - -**Description:** -Verify that `get_match` returns `Error::MatchNotFound` for an ID that was never created. - -**Tasks:** -- Call `get_match(999)` -- Assert `Error::MatchNotFound` - ---- - -## Add Test: is_funded returns false after only one player deposits -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Verify that `is_funded` returns `false` when only one of the two players has deposited. - -**Tasks:** -- Create match, only player1 deposits -- Assert `is_funded` returns `false` -- Deposit player2, assert `is_funded` returns `true` - ---- - -## Add Test: get_escrow_balance reflects correct amount at each deposit stage -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** Medium -**Estimated Time:** 30 minutes - -**Description:** -Verify `get_escrow_balance` returns `0`, `stake_amount`, and `2 * stake_amount` at the correct stages. - -**Tasks:** -- Assert balance is `0` before any deposit -- Assert balance is `stake_amount` after player1 deposits -- Assert balance is `2 * stake_amount` after player2 deposits - ---- - -## Add Test: Draw payout returns exact stake_amount to each player -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 1 hour - -**Description:** -Verify that in a draw, each player receives exactly their original `stake_amount` back and the contract balance returns to zero. - -**Tasks:** -- Record player balances before deposit -- Complete match with `Winner::Draw` -- Assert each player's balance equals pre-deposit balance -- Assert contract escrow balance is zero - ---- - -## Add Test: Non-oracle address calling submit_result should return Unauthorized -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** High -**Estimated Time:** 30 minutes - -**Description:** -Verify that only the registered oracle address can call `submit_result` on the escrow contract. - -**Tasks:** -- Call `submit_result` from a random address (not the oracle) -- Assert auth error or `Error::Unauthorized` - ---- - -## Add Test: oracle get_result on non-existent match_id should return ResultNotFound -**Labels:** `testing` -**Body:** -**Category:** Smart Contract - Testing -**Priority:** Low -**Estimated Time:** 15 minutes - -**Description:** -Verify that `OracleContract::get_result` returns `Error::ResultNotFound` for a match ID with no submitted result. - -**Tasks:** -- Call `get_result(999)` on a fresh oracle contract -- Assert `Error::ResultNotFound` - ---- - -## Add GitHub Actions CI β€” Run cargo test and cargo clippy on Every PR -**Labels:** `infrastructure` -**Body:** -**Category:** Infrastructure - CI/CD -**Priority:** High -**Estimated Time:** 1 hour - -**Description:** -There is no CI pipeline. Add a GitHub Actions workflow that runs `cargo test` and `cargo clippy -- -D warnings` on every pull request to prevent regressions and enforce lint standards. - -**Tasks:** -- Create `.github/workflows/ci.yml` -- Run `cargo test` on PR and push to `main` -- Run `cargo clippy -- -D warnings` -- Cache cargo dependencies for faster runs -- Add status badge to README