diff --git a/app/onchain/README.md b/app/onchain/README.md index cfa2f965..7043070e 100644 --- a/app/onchain/README.md +++ b/app/onchain/README.md @@ -81,6 +81,7 @@ Events use stable topic identifiers (struct name in snake_case) so indexers and | `disburse(id)` | Admin manually sends package funds to recipient | `admin` | | `revoke(id)` / `cancel_package(id)` | Cancels an active package and unlocks funds | `admin` | | `refund(id)` | Returns funds from an expired/cancelled package to admin | `admin` | +| `expire_if_past_due(id)` | Transitions a past-due package to `Expired` and releases its locked funds | None | | `extend_expiration(id, additional_time)` | Extends the expiration of a package | `admin` | | `withdraw_surplus(to, amount, token)` | Withdraws unallocated (non-locked) funds | `admin` | | `add_distributor(addr)` | Grants distributor rights to an address | `admin` | diff --git a/app/onchain/contracts/aid_escrow/BOUNDARY_VALIDATION_BEHAVIOR.md b/app/onchain/contracts/aid_escrow/BOUNDARY_VALIDATION_BEHAVIOR.md index cc34569b..79662cfe 100644 --- a/app/onchain/contracts/aid_escrow/BOUNDARY_VALIDATION_BEHAVIOR.md +++ b/app/onchain/contracts/aid_escrow/BOUNDARY_VALIDATION_BEHAVIOR.md @@ -2,7 +2,7 @@ ## Overview -This document describes the expected behavior of claim timing validation on the ChainForge platform, specifically for Testnet ledgers. It covers claim start time boundaries, expiry boundaries, and auto-expiry logic. +This document describes the expected behavior of claim timing validation on the ChainForge platform, specifically for Testnet ledgers. It covers claim start time boundaries, expiry boundaries, and late-claim expiry-sweep behavior. ## Onchain Contract Behavior (Soroban) @@ -26,18 +26,18 @@ The onchain contract enforces the following timing rules: - **Validation**: - If `expires_at > 0`, must be > `created_at` - Must respect `config.max_expires_in` if configured -- **Claim Validation**: Claim attempts where `expires_at > 0 && now > expires_at` trigger auto-expiry +- **Claim Validation**: Claim attempts where `expires_at > 0 && now > expires_at` return `Error::PackageExpired` without mutating state #### 3. Late Claim Behavior -**Important**: When a claim is attempted after expiry, the contract returns an error but does **NOT** automatically update the package status to `Expired`. The package status remains `Created`. +**Important**: When a claim is attempted after expiry, the contract returns `Error::PackageExpired` and leaves the package in `Created`. Soroban reverts all storage writes when a function returns an error, so a claim attempt **cannot** atomically mark the package `Expired` and return an error in the same call. - **Trigger**: Any claim attempt (`claim()` or `claim_with_proof()`) where `expires_at > 0 && now > expires_at` -- **State Change**: Package status remains `Created` (no automatic transition) +- **State Change**: None — package status remains `Created` - **Error Returned**: `Error::PackageExpired` -- **Persistence**: Since status doesn't change, if time is reverted, the package can still be claimed -- **Subsequent Attempts**: Further claim attempts will continue to return `Error::PackageExpired` as long as `now > expires_at` -- **Status Transition**: Package status only transitions to `Expired` through other operations (e.g., `refund()` can transition a `Created` package to `Expired`) +- **Expiry sweep**: `expire_if_past_due(id)` is a permissionless entrypoint that transitions a past-due `Created` package to `Expired`, releases its locked funds, and moves its aggregate totals from `Created` to the expired/cancelled bucket. It is idempotent and returns `Ok`. +- **Refund**: `refund(id)` converts an `Expired` (or `Cancelled`) package to `Refunded` and transfers the funds to the admin, without double-releasing locked funds. +- **Persistence**: Because the late claim leaves status `Created`, a time revert to within the window still allows a successful claim; once `expire_if_past_due` has run, the package is permanently `Expired`. ### Boundary Conditions @@ -99,11 +99,11 @@ The backend runs an automated cleanup process: | Aspect | Backend | Onchain | |--------|---------|---------| -| Trigger | Cron job (hourly) | Claim attempt | -| Status Change | `requested/verified` → `archived` | `Created` → `Expired` | -| Timing | After expiry (batch cleanup) | At claim attempt (immediate) | +| Trigger | Cron job (hourly) | `expire_if_past_due(id)` (permissionless) or `refund(id)` | +| Status Change | `requested/verified` → `archived` | `Created` → `Expired` (then `Refunded` on admin refund) | +| Timing | After expiry (batch cleanup) | On demand (any account may sweep) | | Reversibility | No (archived) | No (permanent) | -| Fund Recovery | Attempts revoke/refund | Requires manual refund by admin | +| Fund Recovery | Attempts revoke/refund | `refund(id)` transfers funds to admin | ## Frontend Display Behavior @@ -170,8 +170,8 @@ New comprehensive boundary validation tests have been added in `tests/boundary_v 2. **Expiry Boundaries**: - `succeeds_when_claimed_1_second_before_expiry` - `succeeds_when_claimed_at_exact_expiry` - - `fails_when_claimed_1_second_after_expiry_with_auto_expire` - - `fails_when_claimed_long_after_expiry_with_auto_expire` + - `fails_when_claimed_1_second_after_expiry` + - `fails_when_claimed_long_after_expiry` 3. **Combined Boundaries**: - `fails_when_claim_starts_at_equals_expires_at_and_claimed_before` @@ -180,10 +180,12 @@ New comprehensive boundary validation tests have been added in `tests/boundary_v - `narrow_claim_window_1_second` - `zero_claim_window_fails_creation` -4. **Auto-Expiry Behavior**: - - `package_status_auto_expires_on_first_late_claim_attempt` - - `auto_expired_package_cannot_be_claimed_even_if_time_reverted` - - `claim_with_proof_also_auto_expires_on_late_attempt` +4. **Late Claim / Expiry Sweep Behavior**: + - `late_claim_returns_error_without_transitioning` + - `claim_with_proof_fails_after_expiry_without_transitioning` + - `expire_if_past_due_transitions_and_moves_accounting` + - `expire_if_past_due_ignores_never_expiring_and_missing_packages` + - `refund_after_expiry_does_not_unlock_other_packages` 5. **Edge Cases**: - `package_with_zero_expiry_never_expires` @@ -206,10 +208,10 @@ Existing test coverage includes: - Confirm exact boundary behavior matches expectations - Test with real ledger timestamps (not just mocked) -2. **Monitor Auto-Expiry**: +2. **Monitor Expiry Sweep**: - Deploy a test package with short expiry (e.g., 1 hour) - - Attempt claim after expiry to verify auto-expiry - - Check that status updates correctly on-chain + - Attempt a claim after expiry and confirm it returns `Error::PackageExpired` + - Call `expire_if_past_due(id)` and check the package transitions to `Expired` and locked/aggregate totals move 3. **Frontend Integration**: - Test claim button enable/disable at exact boundaries @@ -240,8 +242,8 @@ After Testnet deployment, monitor: The claim window and expiry boundary validation is implemented with the following key behaviors: -- **Onchain**: Immediate validation at claim attempt with auto-expiry on late claims +- **Onchain**: Immediate validation at claim attempt; late claims return `Error::PackageExpired`, and the permissionless `expire_if_past_due(id)` entrypoint performs the `Created → Expired` transition and its accounting - **Backend**: Batch cleanup of expired claims via hourly cron job - **Frontend**: Visual indicators and countdown timers for claim windows -The boundary conditions are well-defined and tested, with the critical behavior being that late claim attempts automatically expire the package status on-chain. +The boundary conditions are well-defined and tested. Late claim attempts return `Error::PackageExpired` without mutating state (Soroban reverts writes on error); the idempotent, permissionless `expire_if_past_due(id)` entrypoint performs the `Created → Expired` transition and its accounting. diff --git a/app/onchain/contracts/aid_escrow/README.md b/app/onchain/contracts/aid_escrow/README.md index b7c71ae9..c894303c 100644 --- a/app/onchain/contracts/aid_escrow/README.md +++ b/app/onchain/contracts/aid_escrow/README.md @@ -63,6 +63,7 @@ expires and is refunded. | `disburse(env, id)` | Admin | Admin manually disburses a package to its recipient. | | `revoke(env, id)` | Admin | Admin revokes a package, returning funds to the surplus pool. | | `refund(env, id)` | Admin | Refunds an expired or cancelled package to the admin. | +| `expire_if_past_due(env, id)` | — | Permissionless, idempotent sweep: transitions a past-due `Created` package to `Expired`, releases its locked funds, and moves its aggregate totals to the expired/cancelled bucket. | | `cancel_package(env, package_id)` | Admin | Cancels a package (transitions to Cancelled status). | | `extend_expiration(env, package_id, additional_time)` | Admin / Distributor | Extends the expiration time of an active package. | @@ -89,7 +90,7 @@ expires and is refunded. ``` Created --> Claimed (recipient or delegate claims) -Created --> Expired (past expiry, recipient tries to claim) +Created --> Expired (past expiry, expire_if_past_due sweep) Created --> Cancelled (admin cancels) Created --> Claimed (admin) (admin disburses) Expired --> Refunded (admin refunds) diff --git a/app/onchain/contracts/aid_escrow/src/lib.rs b/app/onchain/contracts/aid_escrow/src/lib.rs index a1a307fa..75643a89 100644 --- a/app/onchain/contracts/aid_escrow/src/lib.rs +++ b/app/onchain/contracts/aid_escrow/src/lib.rs @@ -1220,11 +1220,12 @@ impl AidEscrow { .get(&key) .ok_or(Error::PackageNotFound)?; - // Can only refund if Expired or Cancelled. - // If Created, must Revoke first. If Claimed, impossible. - // If Refunded, impossible. - let should_unlock_locked = - package.status == PackageStatus::Created || package.status == PackageStatus::Expired; + // Only a `Created` package still holds its amount in KEY_TOTAL_LOCKED. + // A package auto-expired on the claim path has already had its locked + // funds released and its aggregates moved, so it must NOT be unlocked + // again here (that would double-decrement). Cancelled packages were + // already unlocked in `revoke`. + let should_unlock_locked = package.status == PackageStatus::Created; // Capture whether the package was in Created status before any mutations. // Packages already in Expired or Cancelled are already counted in @@ -1244,8 +1245,9 @@ impl AidEscrow { return Err(Error::InvalidState); } - // If Cancelled, funds were already unlocked in `revoke`. - // Expired packages are unlocked only after a successful refund transfer. + // Cancelled packages were already unlocked in `revoke`; auto-expired + // packages were already unlocked in `expire_if_past_due`. Only a + // `Created` package is unlocked here (see `should_unlock_locked`). // Transfer Contract -> Admin Self::transfer_token( @@ -1525,6 +1527,50 @@ impl AidEscrow { env.storage().instance().set(&KEY_TOTAL_LOCKED, &locked_map); } + /// Permissionless. Idempotently transitions a past-due `Created` package + /// to `Expired`, releasing its locked funds and moving its aggregate totals + /// from `Created` to the expired/cancelled bucket. + /// + /// Returns `Ok` whether the package was expired, is still claimable, or was + /// already in a terminal state (idempotent). The transition must be a + /// successful call because Soroban reverts storage writes when a function + /// returns an error, so a late `claim` cannot both transition the package + /// and return `Error::PackageExpired` in the same invocation. + pub fn expire_if_past_due(env: Env, id: u64) -> Result<(), Error> { + let key = (symbol_short!("pkg"), id); + let mut package: Package = env + .storage() + .persistent() + .get(&key) + .ok_or(Error::PackageNotFound)?; + + let now = env.ledger().timestamp(); + + // `expires_at == 0` means the package never expires. + if package.expires_at == 0 || now <= package.expires_at { + return Ok(()); + } + // Only a `Created` package can transition; an already-terminal package + // has either been paid out or already released its funds. + if package.status != PackageStatus::Created { + return Ok(()); + } + + package.status = PackageStatus::Expired; + env.storage().persistent().set(&key, &package); + + Self::decrement_locked(&env, &package.token, package.amount); + Self::add_to_status_totals( + &env, + &package.token, + PackageStatus::Created, + -package.amount, + ); + Self::add_to_status_totals(&env, &package.token, PackageStatus::Expired, package.amount); + + Ok(()) + } + /// Validates a token contract against the configured decimals policy. /// /// # Behaviour diff --git a/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/claim_with_proof_fails_after_expiry_without_transitioning.1.json b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/claim_with_proof_fails_after_expiry_without_transitioning.1.json new file mode 100644 index 00000000..af942fce --- /dev/null +++ b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/claim_with_proof_fails_after_expiry_without_transitioning.1.json @@ -0,0 +1,840 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "set_config", + "args": [ + { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "1" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "1000100" + }, + { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 100, + "timestamp": 1000110, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 10, + "min_temp_entry_ttl": 10, + "max_entry_ttl": 3110400, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "1" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "1000100" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "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": { + "symbol": "admin" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "symbol": "cmt" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "config" + }, + "val": { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "pkg_cnt" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "pkg_idx" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "version" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "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": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 121060 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 109 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_ignores_never_expiring_and_missing_packages.1.json b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_ignores_never_expiring_and_missing_packages.1.json new file mode 100644 index 00000000..6f9f3979 --- /dev/null +++ b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_ignores_never_expiring_and_missing_packages.1.json @@ -0,0 +1,823 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "set_config", + "args": [ + { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "1" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "0" + }, + { + "map": [] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 100, + "timestamp": 1000000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 10, + "min_temp_entry_ttl": 10, + "max_entry_ttl": 3110400, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "1" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "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": { + "symbol": "admin" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "symbol": "cmt" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "config" + }, + "val": { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "pkg_cnt" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "pkg_idx" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "version" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "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": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 121060 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 109 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_transitions_and_moves_accounting.1.json b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_transitions_and_moves_accounting.1.json new file mode 100644 index 00000000..0e2b1c80 --- /dev/null +++ b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/expire_if_past_due_transitions_and_moves_accounting.1.json @@ -0,0 +1,867 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "set_config", + "args": [ + { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "1" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "1000100" + }, + { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 100, + "timestamp": 1000110, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 10, + "min_temp_entry_ttl": 10, + "max_entry_ttl": 3110400, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "1" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "1000100" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "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": { + "symbol": "admin" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "symbol": "cmt" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "0" + } + } + ] + } + }, + { + "key": { + "symbol": "config" + }, + "val": { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "symbol": "expcan" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "0" + } + } + ] + } + }, + { + "key": { + "symbol": "pkg_cnt" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "pkg_idx" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "version" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "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": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 121060 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 109 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/late_claim_returns_error_without_transitioning.1.json b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/late_claim_returns_error_without_transitioning.1.json new file mode 100644 index 00000000..f18049eb --- /dev/null +++ b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/late_claim_returns_error_without_transitioning.1.json @@ -0,0 +1,841 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "set_config", + "args": [ + { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "1" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "1000100" + }, + { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 100, + "timestamp": 1000110, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 10, + "min_temp_entry_ttl": 10, + "max_entry_ttl": 3110400, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "1" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "1000100" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [ + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "string": "1000000" + } + } + ] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "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": { + "symbol": "admin" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "symbol": "cmt" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "config" + }, + "val": { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "pkg_cnt" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "pkg_idx" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "version" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "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": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 121060 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 109 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/refund_after_expiry_does_not_unlock_other_packages.1.json b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/refund_after_expiry_does_not_unlock_other_packages.1.json new file mode 100644 index 00000000..a6fc51c3 --- /dev/null +++ b/app/onchain/contracts/aid_escrow/test_snapshots/late_claim_behavior/refund_after_expiry_does_not_unlock_other_packages.1.json @@ -0,0 +1,1198 @@ +{ + "generators": { + "address": 4, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "set_config", + "args": [ + { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "20000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "1" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "1000100" + }, + { + "map": [] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_package", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "u64": "2" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + }, + { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + { + "u64": "0" + }, + { + "map": [] + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "refund", + "args": [ + { + "u64": "1" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 100, + "timestamp": 1000101, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 10, + "min_persistent_entry_ttl": 10, + "min_temp_entry_ttl": 10, + "max_entry_ttl": 3110400, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "2032731177588607455" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "2032731177588607455" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4270020994084947596" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4270020994084947596" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 3110499 + ] + ], + [ + { + "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" + }, + 3110499 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "1" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pidx" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "u64": "2" + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "1" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "1000100" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "1" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 4 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "2" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "pkg" + }, + { + "u64": "2" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "claim_starts_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "created_at" + }, + "val": { + "u64": "1000000" + } + }, + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "metadata" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + } + ] + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "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": { + "symbol": "admin" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "symbol": "cmt" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "config" + }, + "val": { + "map": [ + { + "key": { + "symbol": "allowed_tokens" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "max_expires_in" + }, + "val": { + "u64": "0" + } + }, + { + "key": { + "symbol": "min_amount" + }, + "val": { + "i128": "1" + } + }, + { + "key": { + "symbol": "min_decimals" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "symbol": "expcan" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "locked" + }, + "val": { + "map": [ + { + "key": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + }, + "val": { + "i128": "10000000" + } + } + ] + } + }, + { + "key": { + "symbol": "pkg_cnt" + }, + "val": { + "u64": "3" + } + }, + { + "key": { + "symbol": "pkg_idx" + }, + "val": { + "u64": "2" + } + }, + { + "key": { + "symbol": "version" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 109 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518500 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "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": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 121060 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 109 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/app/onchain/contracts/aid_escrow/tests/boundary_validation_tests.rs b/app/onchain/contracts/aid_escrow/tests/boundary_validation_tests.rs index 0ae10df3..7ca3212c 100644 --- a/app/onchain/contracts/aid_escrow/tests/boundary_validation_tests.rs +++ b/app/onchain/contracts/aid_escrow/tests/boundary_validation_tests.rs @@ -5,7 +5,7 @@ //! This module tests the exact boundary conditions for claim timing: //! - Claim start time boundaries //! - Expiry time boundaries -//! - Late claim auto-expiry behavior +//! - Late claim expiry-sweep behavior //! - Edge cases around timestamps use aid_escrow::{AidEscrow, AidEscrowClient, Error, PackageStatus}; @@ -130,7 +130,7 @@ mod claim_start_boundaries { let result = t.client.try_claim(&id, &recipient); assert_eq!(result, Err(Ok(Error::ClaimTooEarly))); - // Verify package status is still Created (not auto-expired) + // Verify package status is still Created (claim returns before any transition) let pkg = t.client.get_package(&id); assert_eq!(pkg.status, PackageStatus::Created); } @@ -238,7 +238,8 @@ mod expiry_boundaries { let result = t.client.try_claim(&id, &recipient); assert_eq!(result, Err(Ok(Error::PackageExpired))); - // Verify package status remains Created (not auto-updated) + // Verify package status remains Created (claim cannot commit the + // transition because Soroban reverts storage on an error return). let pkg = t.client.get_package(&id); assert_eq!(pkg.status, PackageStatus::Created); } @@ -258,7 +259,8 @@ mod expiry_boundaries { let result = t.client.try_claim(&id, &recipient); assert_eq!(result, Err(Ok(Error::PackageExpired))); - // Verify package status remains Created (not auto-updated) + // Verify package status remains Created (claim cannot commit the + // transition because Soroban reverts storage on an error return). let pkg = t.client.get_package(&id); assert_eq!(pkg.status, PackageStatus::Created); } @@ -326,7 +328,8 @@ mod combined_boundaries { let result = t.client.try_claim(&id, &recipient); assert_eq!(result, Err(Ok(Error::PackageExpired))); - // Verify package status remains Created (not auto-updated) + // Verify package status remains Created (claim cannot commit the + // transition because Soroban reverts storage on an error return). let pkg = t.client.get_package(&id); assert_eq!(pkg.status, PackageStatus::Created); } @@ -397,7 +400,7 @@ mod late_claim_behavior { use super::*; #[test] - fn late_claim_returns_error_but_status_remains_created() { + fn late_claim_returns_error_without_transitioning() { let t = TestSetup::new(); let recipient = Address::generate(&t.env); let now = t.now(); @@ -406,28 +409,20 @@ mod late_claim_behavior { let id = t.create_package_with_timing(&recipient, ONE_TOKEN, claim_starts_at, expires_at); - // Advance past expiry + // Advance past expiry. t.set_timestamp(expires_at + 10); - // First late claim attempt - should fail with PackageExpired - let result1 = t.client.try_claim(&id, &recipient); - assert_eq!(result1, Err(Ok(Error::PackageExpired))); - - // Verify status remains Created (not auto-updated) - let pkg1 = t.client.get_package(&id); - assert_eq!(pkg1.status, PackageStatus::Created); - - // Second late claim attempt - should still fail with PackageExpired - let result2 = t.client.try_claim(&id, &recipient); - assert_eq!(result2, Err(Ok(Error::PackageExpired))); - - // Verify status still remains Created - let pkg2 = t.client.get_package(&id); - assert_eq!(pkg2.status, PackageStatus::Created); + // A late claim still fails with PackageExpired. Soroban reverts storage + // on an error return, so claim cannot also commit the Expired + // transition; the package stays Created until expire_if_past_due runs. + let result = t.client.try_claim(&id, &recipient); + assert_eq!(result, Err(Ok(Error::PackageExpired))); + assert_eq!(t.client.get_package(&id).status, PackageStatus::Created); + assert_eq!(t.client.get_total_locked(&t.token), ONE_TOKEN); } #[test] - fn late_claim_can_be_retried_if_time_reverted() { + fn claim_with_proof_fails_after_expiry_without_transitioning() { let t = TestSetup::new(); let recipient = Address::generate(&t.env); let now = t.now(); @@ -436,29 +431,17 @@ mod late_claim_behavior { let id = t.create_package_with_timing(&recipient, ONE_TOKEN, claim_starts_at, expires_at); - // Advance past expiry and claim + // Advance past expiry. t.set_timestamp(expires_at + 10); - let result1 = t.client.try_claim(&id, &recipient); - assert_eq!(result1, Err(Ok(Error::PackageExpired))); - - // Verify status remains Created - let pkg1 = t.client.get_package(&id); - assert_eq!(pkg1.status, PackageStatus::Created); - // Revert time back to within claim window - t.set_timestamp(claim_starts_at + 50); - - // Should succeed because status is still Created - let result2 = t.client.try_claim(&id, &recipient); - assert!(result2.is_ok()); - - // Verify status is now Claimed - let pkg2 = t.client.get_package(&id); - assert_eq!(pkg2.status, PackageStatus::Claimed); + let proof: Vec = Vec::new(&t.env); + let result = t.client.try_claim_with_proof(&id, &recipient, &proof); + assert_eq!(result, Err(Ok(Error::PackageExpired))); + assert_eq!(t.client.get_package(&id).status, PackageStatus::Created); } #[test] - fn claim_with_proof_fails_after_expiry() { + fn expire_if_past_due_transitions_and_moves_accounting() { let t = TestSetup::new(); let recipient = Address::generate(&t.env); let now = t.now(); @@ -466,18 +449,97 @@ mod late_claim_behavior { let expires_at = now + 100; let id = t.create_package_with_timing(&recipient, ONE_TOKEN, claim_starts_at, expires_at); + assert_eq!(t.client.get_total_locked(&t.token), ONE_TOKEN); + assert_eq!(t.client.get_aggregates(&t.token).total_committed, ONE_TOKEN); - // Advance past expiry + // Before expiry the sweep is a no-op. + t.client.expire_if_past_due(&id); + assert_eq!(t.client.get_package(&id).status, PackageStatus::Created); + assert_eq!(t.client.get_total_locked(&t.token), ONE_TOKEN); + + // After expiry the sweep transitions the package and moves accounting. t.set_timestamp(expires_at + 10); + t.client.expire_if_past_due(&id); + + assert_eq!(t.client.get_package(&id).status, PackageStatus::Expired); + assert_eq!(t.client.get_total_locked(&t.token), 0); + let agg = t.client.get_aggregates(&t.token); + assert_eq!(agg.total_committed, 0); + assert_eq!(agg.total_expired_cancelled, ONE_TOKEN); + + // Idempotent: a second sweep does not double-move the amount. + t.client.expire_if_past_due(&id); + assert_eq!(t.client.get_total_locked(&t.token), 0); + assert_eq!( + t.client.get_aggregates(&t.token).total_expired_cancelled, + ONE_TOKEN + ); + } - // Try claim_with_proof after expiry - should fail - let proof: Vec = Vec::new(&t.env); - let result = t.client.try_claim_with_proof(&id, &recipient, &proof); - assert_eq!(result, Err(Ok(Error::PackageExpired))); + #[test] + fn expire_if_past_due_ignores_never_expiring_and_missing_packages() { + let t = TestSetup::new(); + let recipient = Address::generate(&t.env); - // Verify status remains Created (not auto-updated) - let pkg = t.client.get_package(&id); - assert_eq!(pkg.status, PackageStatus::Created); + // A never-expiring package is untouched by the sweep. + t.fund_contract(ONE_TOKEN); + t.client.create_package( + &t.admin, + &1u64, + &recipient, + &ONE_TOKEN, + &t.token, + &0u64, + &Map::new(&t.env), + ); + t.client.expire_if_past_due(&1u64); + assert_eq!(t.client.get_package(&1u64).status, PackageStatus::Created); + + // A missing package returns a clean error. + let res = t.client.try_expire_if_past_due(&9999u64); + assert_eq!(res, Err(Ok(Error::PackageNotFound))); + } + + #[test] + fn refund_after_expiry_does_not_unlock_other_packages() { + let t = TestSetup::new(); + let recipient = Address::generate(&t.env); + let now = t.now(); + let expires_at = now + 100; + + // Two packages on the same token: pkg 1 expires, pkg 2 never expires. + t.fund_contract(2 * ONE_TOKEN); + t.client.create_package( + &t.admin, + &1u64, + &recipient, + &ONE_TOKEN, + &t.token, + &expires_at, + &Map::new(&t.env), + ); + t.client.create_package( + &t.admin, + &2u64, + &recipient, + &ONE_TOKEN, + &t.token, + &0u64, + &Map::new(&t.env), + ); + assert_eq!(t.client.get_total_locked(&t.token), 2 * ONE_TOKEN); + + // Expire pkg 1, releasing only its locked share. + t.set_timestamp(expires_at + 1); + t.client.expire_if_past_due(&1u64); + assert_eq!(t.client.get_package(&1u64).status, PackageStatus::Expired); + assert_eq!(t.client.get_total_locked(&t.token), ONE_TOKEN); + + // Refunding the expired package must not decrement locked again + // (pkg 2 is still locked). + t.client.refund(&1u64); + assert_eq!(t.client.get_package(&1u64).status, PackageStatus::Refunded); + assert_eq!(t.client.get_total_locked(&t.token), ONE_TOKEN); } }