diff --git a/.changeset/immutable-token-caps.md b/.changeset/immutable-token-caps.md new file mode 100644 index 00000000..3526a9b8 --- /dev/null +++ b/.changeset/immutable-token-caps.md @@ -0,0 +1,7 @@ +--- +"@docforum/escrow-sdk": minor +--- + +Expose immutable per-token maximum amounts in the generated escrow constructor +bindings. Cap configuration is fixed at deployment and enforced for ordinary +escrows, pooled funding targets, and payer top-ups (issue #56, ADR 0013). diff --git a/.github/workflows/sdk-go.yml b/.github/workflows/sdk-go.yml index b2b50066..d6f81348 100644 --- a/.github/workflows/sdk-go.yml +++ b/.github/workflows/sdk-go.yml @@ -162,14 +162,15 @@ jobs: --alias native-token token_id=$(stellar contract alias show native-token --network escrow-local) - # __constructor(allowed_tokens: Vec
) — empty list keeps the - # legacy open-token behavior, which is fine for an ephemeral local net. + # __constructor(allowed_tokens: Vec
, maximum_amounts: + # Map) — an empty list and an empty map keep the + # legacy open-token, uncapped behavior, fine for an ephemeral local net. stellar contract deploy \ --wasm "$wasm" \ --source-account deployer \ --network escrow-local \ --alias escrow \ - -- --allowed_tokens '[]' + -- --allowed_tokens '[]' --maximum_amounts '{}' contract_id=$(stellar contract alias show escrow --network escrow-local) echo "token_id=$token_id" diff --git a/ARCHITECTURE_ESSENTIALS.md b/ARCHITECTURE_ESSENTIALS.md index d226da84..77cfe002 100644 --- a/ARCHITECTURE_ESSENTIALS.md +++ b/ARCHITECTURE_ESSENTIALS.md @@ -10,7 +10,7 @@ ## Contract surface ``` -__constructor(allowed_tokens: Vec
) // immutable token allowlist; empty means allow all +__constructor(allowed_tokens: Vec
, maximum_amounts: Map) // immutable token allowlist and optional per-token caps version() -> String // semantic contract version; source revision and Soroban SDK version are embedded as WASM metadata create_escrow(payer, payee, token, amount, condition_ref, releaser, refund_after, notify_payee, refund_to, fee_recipient, fee_bps) -> escrow_id // Phase E5 callback + sponsored refund destination (ADR 0009) + optional protocol fee (ADR 0010); the fee is not yet on testnet create_escrow_release_time(..., fee_recipient, fee_bps) -> escrow_id // single-releaser creation with an earliest release time; accepts the same optional fee pair diff --git a/ROADMAP.md b/ROADMAP.md index 6b7b1fc6..d07b9692 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -161,6 +161,7 @@ An opt-in creation method can require the payee to authorize `accept` before rel `docs/testnet-deployments.md`. ## Phase E5 — Contract features +- [x] Immutable per-token escrow caps (issue #56, ADR 0013): constructor cap map enforced for creation, pooled targets, and top-ups before funds move. Tests: contracts/escrow/tests/token_caps.rs. Not yet on testnet. - [x] Batch release and refund (issue #29, `docs/adr/0012`): `settle_many(caller, ops: Vec<(escrow_id, Release|Refund)>)`, best-effort with one result per op, per-op auth against each escrow's own releasers, at most `MAX_SETTLE_OPS` = 20 (measured against the 16 KiB events budget). T1 response guidance updated. Tests: `contracts/escrow/tests/settle_many.rs`. **Not yet on testnet.** - [x] Per-token liability accounting and an on-chain solvency view (issue #39): `solvency(token) -> (balance, liabilities)`; the counter moves in the same invocation as every value-moving state change and its TTL is extended on each write. Property test: `contracts/escrow/tests/liabilities.rs`. Monitoring guidance in `docs/threat-model.md`. **Not yet on testnet.** - [x] Optional escrow-wide earliest release time (issue #43, ADR 0009); refund path remains independent. diff --git a/changelog.d/56-per-token-escrow-caps.md b/changelog.d/56-per-token-escrow-caps.md new file mode 100644 index 00000000..ce69dcd9 --- /dev/null +++ b/changelog.d/56-per-token-escrow-caps.md @@ -0,0 +1,9 @@ +Issue #56 (Phase E5): immutable per-token escrow caps for a guarded mainnet +beta. The constructor now takes `maximum_amounts: Map` next to +`allowed_tokens`; an empty map keeps the uncapped behaviour, otherwise tokens +without an entry are rejected (`TokenCapNotConfigured = 36`) and any escrow +total above its token's cap fails with `AmountCapExceeded = 37` — on every +creation path including each batch item, on `top_up`, and on a pooled +escrow's funding target. Staged-launch plan in ADR 0013; `scripts/deploy` +gains `--maximum-amounts`. SDK bindings regenerated; every snapshot gains the +(empty) `MaximumAmounts` instance entry. Not yet deployed to testnet. diff --git a/contracts/escrow/benches/resource_profile.rs b/contracts/escrow/benches/resource_profile.rs index a2e96b7d..c11adc73 100644 --- a/contracts/escrow/benches/resource_profile.rs +++ b/contracts/escrow/benches/resource_profile.rs @@ -1,11 +1,7 @@ #![allow(deprecated)] use docforum_escrow::{EscrowContract, EscrowContractClient}; -use soroban_sdk::{ - testutils::Address as _, - token::StellarAssetClient, - Address, Env, String, Vec, -}; +use soroban_sdk::{testutils::Address as _, token::StellarAssetClient, Address, Env, String, Vec}; struct Fixture<'a> { env: Env, @@ -26,9 +22,22 @@ fn fixture() -> Fixture<'static> { let payee = Address::generate(&env); let releaser = Address::generate(&env); asset.mint(&payer, &10_000); - let contract = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract); - Fixture { env, client, payer, payee, releaser, token } + Fixture { + env, + client, + payer, + payee, + releaser, + token, + } } impl Fixture<'_> { @@ -59,23 +68,38 @@ fn measure(name: &str, env: &Env, operation: impl FnOnce()) { fn main() { let f = fixture(); - measure("create_escrow", &f.env, || { f.create(); }); + measure("create_escrow", &f.env, || { + f.create(); + }); let f = fixture(); measure("create_escrow_release_time", &f.env, || { f.client.create_escrow_release_time( - &f.payer, &f.payee, &f.token, &100, - &String::from_str(&f.env, "resource-profile"), &f.releaser, - &None, &false, &None, &Some(1_000), + &f.payer, + &f.payee, + &f.token, + &100, + &String::from_str(&f.env, "resource-profile"), + &f.releaser, + &None, + &false, + &None, + &Some(1_000), ); }); let f = fixture(); measure("create_escrow_with_acceptance", &f.env, || { f.client.create_escrow_with_acceptance( - &f.payer, &f.payee, &f.token, &100, - &String::from_str(&f.env, "resource-profile"), &f.releaser, - &None, &true, &None, + &f.payer, + &f.payee, + &f.token, + &100, + &String::from_str(&f.env, "resource-profile"), + &f.releaser, + &None, + &true, + &None, ); }); @@ -83,27 +107,46 @@ fn main() { let releasers = soroban_sdk::vec![&f.env, f.releaser.clone()]; measure("create_escrow_with_releasers", &f.env, || { f.client.create_escrow_with_releasers( - &f.payer, &f.payee, &f.token, &100, - &String::from_str(&f.env, "resource-profile"), &releasers, - &1, &None, &false, &None, + &f.payer, + &f.payee, + &f.token, + &100, + &String::from_str(&f.env, "resource-profile"), + &releasers, + &1, + &None, + &false, + &None, ); }); let f = fixture(); let id = f.client.create_escrow_with_acceptance( - &f.payer, &f.payee, &f.token, &100, - &String::from_str(&f.env, "resource-profile"), &f.releaser, - &None, &true, &None, + &f.payer, + &f.payee, + &f.token, + &100, + &String::from_str(&f.env, "resource-profile"), + &f.releaser, + &None, + &true, + &None, ); - measure("accept", &f.env, || { f.client.accept(&id, &f.payee); }); + measure("accept", &f.env, || { + f.client.accept(&id, &f.payee); + }); let f = fixture(); let id = f.create(); - measure("get_status", &f.env, || { f.client.get_status(&id); }); + measure("get_status", &f.env, || { + f.client.get_status(&id); + }); let f = fixture(); let id = f.create(); - measure("get_escrow", &f.env, || { f.client.get_escrow(&id); }); + measure("get_escrow", &f.env, || { + f.client.get_escrow(&id); + }); let f = fixture(); let id = f.create(); @@ -114,18 +157,28 @@ fn main() { let f = fixture(); let id = f.create(); - measure("top_up", &f.env, || { f.client.top_up(&id, &f.payer, &10); }); + measure("top_up", &f.env, || { + f.client.top_up(&id, &f.payer, &10); + }); let f = fixture(); let id = f.create(); - measure("release", &f.env, || { f.client.release(&id, &f.releaser); }); + measure("release", &f.env, || { + f.client.release(&id, &f.releaser); + }); let f = fixture(); let id = f.client.create_escrow_with_releasers( - &f.payer, &f.payee, &f.token, &100, + &f.payer, + &f.payee, + &f.token, + &100, &String::from_str(&f.env, "resource-profile"), &soroban_sdk::vec![&f.env, f.releaser.clone()], - &1, &None, &false, &None, + &1, + &None, + &false, + &None, ); let approvers = soroban_sdk::vec![&f.env, f.releaser.clone()]; measure("release_with_approvals", &f.env, || { @@ -134,14 +187,22 @@ fn main() { let f = fixture(); let id = f.create(); - measure("refund", &f.env, || { f.client.refund(&id, &f.releaser); }); + measure("refund", &f.env, || { + f.client.refund(&id, &f.releaser); + }); let f = fixture(); let id = f.client.create_escrow_with_releasers( - &f.payer, &f.payee, &f.token, &100, + &f.payer, + &f.payee, + &f.token, + &100, &String::from_str(&f.env, "resource-profile"), &soroban_sdk::vec![&f.env, f.releaser.clone()], - &1, &None, &false, &None, + &1, + &None, + &false, + &None, ); let approvers = soroban_sdk::vec![&f.env, f.releaser.clone()]; measure("refund_with_approvals", &f.env, || { diff --git a/contracts/escrow/src/lib.rs b/contracts/escrow/src/lib.rs index 8568d2e9..002a81a8 100644 --- a/contracts/escrow/src/lib.rs +++ b/contracts/escrow/src/lib.rs @@ -46,12 +46,12 @@ use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, panic_with_error, symbol_short, token, - Address, Env, IntoVal, String, Vec, + Address, Env, IntoVal, Map, String, Vec, }; // Bump this value whenever a contract interface or behavior change is made. // CI checks this constant against the base branch when this file changes. -pub const CONTRACT_VERSION: &str = "2.2.0"; +pub const CONTRACT_VERSION: &str = "2.5.0"; include!(concat!(env!("OUT_DIR"), "/contract_metadata.rs")); @@ -223,6 +223,8 @@ enum DataKey { /// of `amount` over every escrow in that token whose status is /// `Funded`. Appended last, so existing entries keep their encoding. Liability(Address), + /// Immutable per-token maximum funded amount (issue #56, ADR 0013). + MaximumAmounts, } #[contracterror] @@ -316,6 +318,10 @@ pub enum Error { /// contract itself, or an amount that would overflow the fee math — /// see docs/adr/0010. InvalidFee = 35, + /// A token has no configured amount cap when cap enforcement is enabled. + TokenCapNotConfigured = 36, + /// An escrow amount, top-up total, or pooled target exceeds its token cap. + AmountCapExceeded = 37, } #[contract] @@ -325,10 +331,23 @@ pub struct EscrowContract; impl EscrowContract { /// Sets the immutable token allowlist at deployment. An empty list /// preserves the legacy behavior and allows any token address. - pub fn __constructor(env: Env, allowed_tokens: Vec
) { + pub fn __constructor( + env: Env, + allowed_tokens: Vec
, + maximum_amounts: Map, + ) -> Result<(), Error> { + for (_, maximum) in maximum_amounts.iter() { + if maximum <= 0 { + return Err(Error::InvalidAmount); + } + } env.storage() .instance() .set(&DataKey::AllowedTokens, &allowed_tokens); + env.storage() + .instance() + .set(&DataKey::MaximumAmounts, &maximum_amounts); + Ok(()) } /// Semantic version of this contract interface and behavior. @@ -579,8 +598,7 @@ impl EscrowContract { /// Read-only status query. Errors if `escrow_id` doesn't exist. pub fn get_status(env: Env, escrow_id: u64) -> Result { - env - .storage() + env.storage() .persistent() .get(&DataKey::Status(escrow_id)) .ok_or(Error::NotFound) @@ -638,6 +656,7 @@ impl EscrowContract { if funding_target <= 0 { return Err(Error::InvalidAmount); } + Self::check_token_cap(&env, &token, funding_target)?; if funding_deadline <= env.ledger().timestamp() { return Err(Error::InvalidFundingDeadline); } @@ -679,7 +698,9 @@ impl EscrowContract { fee_bps: None, }; env.storage().persistent().set(&DataKey::Escrow(id), &data); - env.storage().persistent().set(&DataKey::Status(id), &data.status); + env.storage() + .persistent() + .set(&DataKey::Status(id), &data.status); env.storage().persistent().set( &DataKey::Pooled(id), &PooledData { @@ -942,6 +963,7 @@ impl EscrowContract { return Err(Error::NotFunded); } let updated_amount = data.amount.checked_add(amount).ok_or(Error::Overflow)?; + Self::check_token_cap(&env, &data.token, updated_amount)?; // The fee is a bps of the escrowed amount, so a top-up grows it; fail // now (before the transfer) if the larger amount would overflow the // fee math, rather than at release (docs/adr/0010). @@ -1129,6 +1151,25 @@ impl EscrowContract { Self::settle(&env, escrow_id, &mut data, EscrowStatus::Refunded) } + /// Enforces the immutable deployment-time cap for this token. + fn check_token_cap(env: &Env, token: &Address, amount: i128) -> Result<(), Error> { + let maximum_amounts: Map = env + .storage() + .instance() + .get(&DataKey::MaximumAmounts) + .unwrap_or(Map::new(env)); + if maximum_amounts.is_empty() { + return Ok(()); + } + let maximum = maximum_amounts + .get(token.clone()) + .ok_or(Error::TokenCapNotConfigured)?; + if amount > maximum { + return Err(Error::AmountCapExceeded); + } + Ok(()) + } + fn create_escrow_inner( env: &Env, payer: Address, @@ -1157,6 +1198,7 @@ impl EscrowContract { if amount <= 0 { return Err(Error::InvalidAmount); } + Self::check_token_cap(env, &token, amount)?; if let Some(deadline) = refund_after { if deadline <= env.ledger().timestamp() { return Err(Error::InvalidRefundAfter); @@ -1227,7 +1269,9 @@ impl EscrowContract { fee_bps, }; env.storage().persistent().set(&DataKey::Escrow(id), &data); - env.storage().persistent().set(&DataKey::Status(id), &data.status); + env.storage() + .persistent() + .set(&DataKey::Status(id), &data.status); Self::publish_state(env, symbol_short!("created"), id, &data); Ok(id) } diff --git a/contracts/escrow/test_snapshots/acceptance_requires_the_payee_and_only_works_while_funded.1.json b/contracts/escrow/test_snapshots/acceptance_requires_the_payee_and_only_works_while_funded.1.json index 6f9ad22a..4efedd37 100644 --- a/contracts/escrow/test_snapshots/acceptance_requires_the_payee_and_only_works_while_funded.1.json +++ b/contracts/escrow/test_snapshots/acceptance_requires_the_payee_and_only_works_while_funded.1.json @@ -483,6 +483,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/another_releasers_escrow_is_never_settled.1.json b/contracts/escrow/test_snapshots/another_releasers_escrow_is_never_settled.1.json index 93f242cb..4c7f6239 100644 --- a/contracts/escrow/test_snapshots/another_releasers_escrow_is_never_settled.1.json +++ b/contracts/escrow/test_snapshots/another_releasers_escrow_is_never_settled.1.json @@ -1047,6 +1047,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/batch_creation_checks_every_item_and_is_atomic.1.json b/contracts/escrow/test_snapshots/batch_creation_checks_every_item_and_is_atomic.1.json new file mode 100644 index 00000000..a590212e --- /dev/null +++ b/contracts/escrow/test_snapshots/batch_creation_checks_every_item_and_is_atomic.1.json @@ -0,0 +1,354 @@ +{ + "generators": { + "address": 8, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "1000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "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": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [ + { + "key": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + "val": { + "i128": "200" + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/batch_refund_returns_funds_to_refund_to.1.json b/contracts/escrow/test_snapshots/batch_refund_returns_funds_to_refund_to.1.json index abe62142..ab1d3551 100644 --- a/contracts/escrow/test_snapshots/batch_refund_returns_funds_to_refund_to.1.json +++ b/contracts/escrow/test_snapshots/batch_refund_returns_funds_to_refund_to.1.json @@ -767,6 +767,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/batch_release_pays_every_payee.1.json b/contracts/escrow/test_snapshots/batch_release_pays_every_payee.1.json index cc0cfabb..8066c8c5 100644 --- a/contracts/escrow/test_snapshots/batch_release_pays_every_payee.1.json +++ b/contracts/escrow/test_snapshots/batch_release_pays_every_payee.1.json @@ -1047,6 +1047,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/batch_without_the_callers_signature_is_rejected.1.json b/contracts/escrow/test_snapshots/batch_without_the_callers_signature_is_rejected.1.json index 23eb0ef0..fd2c6740 100644 --- a/contracts/escrow/test_snapshots/batch_without_the_callers_signature_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/batch_without_the_callers_signature_is_rejected.1.json @@ -444,6 +444,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/callback_cannot_reenter_create_escrow.1.json b/contracts/escrow/test_snapshots/callback_cannot_reenter_create_escrow.1.json index 2d224f66..bd5f4bb1 100644 --- a/contracts/escrow/test_snapshots/callback_cannot_reenter_create_escrow.1.json +++ b/contracts/escrow/test_snapshots/callback_cannot_reenter_create_escrow.1.json @@ -599,6 +599,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/callback_cannot_reenter_refund.1.json b/contracts/escrow/test_snapshots/callback_cannot_reenter_refund.1.json index 35ac573c..9ff5af79 100644 --- a/contracts/escrow/test_snapshots/callback_cannot_reenter_refund.1.json +++ b/contracts/escrow/test_snapshots/callback_cannot_reenter_refund.1.json @@ -599,6 +599,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/callback_cannot_reenter_release.1.json b/contracts/escrow/test_snapshots/callback_cannot_reenter_release.1.json index c30ef7cb..563cf28e 100644 --- a/contracts/escrow/test_snapshots/callback_cannot_reenter_release.1.json +++ b/contracts/escrow/test_snapshots/callback_cannot_reenter_release.1.json @@ -599,6 +599,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/callback_error_reverts_release_but_does_not_block_refund.1.json b/contracts/escrow/test_snapshots/callback_error_reverts_release_but_does_not_block_refund.1.json index ca462279..d4617ae1 100644 --- a/contracts/escrow/test_snapshots/callback_error_reverts_release_but_does_not_block_refund.1.json +++ b/contracts/escrow/test_snapshots/callback_error_reverts_release_but_does_not_block_refund.1.json @@ -585,6 +585,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/callback_opt_in_requires_payee_authorization.1.json b/contracts/escrow/test_snapshots/callback_opt_in_requires_payee_authorization.1.json index 33f87c4f..ee077232 100644 --- a/contracts/escrow/test_snapshots/callback_opt_in_requires_payee_authorization.1.json +++ b/contracts/escrow/test_snapshots/callback_opt_in_requires_payee_authorization.1.json @@ -173,6 +173,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/caller_authorizes_the_batch_exactly_once.1.json b/contracts/escrow/test_snapshots/caller_authorizes_the_batch_exactly_once.1.json index 9f1544c1..91858324 100644 --- a/contracts/escrow/test_snapshots/caller_authorizes_the_batch_exactly_once.1.json +++ b/contracts/escrow/test_snapshots/caller_authorizes_the_batch_exactly_once.1.json @@ -759,6 +759,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_after_release_is_rejected.1.json b/contracts/escrow/test_snapshots/cancel_after_release_is_rejected.1.json index 22089320..f5acb16f 100644 --- a/contracts/escrow/test_snapshots/cancel_after_release_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/cancel_after_release_is_rejected.1.json @@ -530,6 +530,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_after_releaser_refund_is_rejected.1.json b/contracts/escrow/test_snapshots/cancel_after_releaser_refund_is_rejected.1.json index 933214a5..c32e82ad 100644 --- a/contracts/escrow/test_snapshots/cancel_after_releaser_refund_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/cancel_after_releaser_refund_is_rejected.1.json @@ -484,6 +484,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_after_timeout_refund_is_rejected.1.json b/contracts/escrow/test_snapshots/cancel_after_timeout_refund_is_rejected.1.json index 524adbbc..ddddbfe5 100644 --- a/contracts/escrow/test_snapshots/cancel_after_timeout_refund_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/cancel_after_timeout_refund_is_rejected.1.json @@ -467,6 +467,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_is_not_available_without_requires_acceptance.1.json b/contracts/escrow/test_snapshots/cancel_is_not_available_without_requires_acceptance.1.json index 151f9e39..2d017f0b 100644 --- a/contracts/escrow/test_snapshots/cancel_is_not_available_without_requires_acceptance.1.json +++ b/contracts/escrow/test_snapshots/cancel_is_not_available_without_requires_acceptance.1.json @@ -447,6 +447,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_only_returns_that_escrows_amount.1.json b/contracts/escrow/test_snapshots/cancel_only_returns_that_escrows_amount.1.json index 369e33f0..164efe82 100644 --- a/contracts/escrow/test_snapshots/cancel_only_returns_that_escrows_amount.1.json +++ b/contracts/escrow/test_snapshots/cancel_only_returns_that_escrows_amount.1.json @@ -750,6 +750,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_pays_the_sponsored_refund_to_not_the_funder.1.json b/contracts/escrow/test_snapshots/cancel_pays_the_sponsored_refund_to_not_the_funder.1.json index f197b2ad..d4fef86a 100644 --- a/contracts/escrow/test_snapshots/cancel_pays_the_sponsored_refund_to_not_the_funder.1.json +++ b/contracts/escrow/test_snapshots/cancel_pays_the_sponsored_refund_to_not_the_funder.1.json @@ -751,6 +751,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_requires_the_payers_signature.1.json b/contracts/escrow/test_snapshots/cancel_requires_the_payers_signature.1.json index f5c0c438..5f94e687 100644 --- a/contracts/escrow/test_snapshots/cancel_requires_the_payers_signature.1.json +++ b/contracts/escrow/test_snapshots/cancel_requires_the_payers_signature.1.json @@ -444,6 +444,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_stays_rejected_after_accept_even_much_later.1.json b/contracts/escrow/test_snapshots/cancel_stays_rejected_after_accept_even_much_later.1.json index c06ad78c..d1d174ab 100644 --- a/contracts/escrow/test_snapshots/cancel_stays_rejected_after_accept_even_much_later.1.json +++ b/contracts/escrow/test_snapshots/cancel_stays_rejected_after_accept_even_much_later.1.json @@ -488,6 +488,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_still_works_after_refund_after_has_passed_if_still_funded.1.json b/contracts/escrow/test_snapshots/cancel_still_works_after_refund_after_has_passed_if_still_funded.1.json index cf2608b2..1a521525 100644 --- a/contracts/escrow/test_snapshots/cancel_still_works_after_refund_after_has_passed_if_still_funded.1.json +++ b/contracts/escrow/test_snapshots/cancel_still_works_after_refund_after_has_passed_if_still_funded.1.json @@ -487,6 +487,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/cancel_subtracts_from_liabilities.1.json b/contracts/escrow/test_snapshots/cancel_subtracts_from_liabilities.1.json index feffc298..d1699ac7 100644 --- a/contracts/escrow/test_snapshots/cancel_subtracts_from_liabilities.1.json +++ b/contracts/escrow/test_snapshots/cancel_subtracts_from_liabilities.1.json @@ -1067,6 +1067,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/claim_refund_emits_an_event.1.json b/contracts/escrow/test_snapshots/claim_refund_emits_an_event.1.json index e650e3d9..bea5b7b9 100644 --- a/contracts/escrow/test_snapshots/claim_refund_emits_an_event.1.json +++ b/contracts/escrow/test_snapshots/claim_refund_emits_an_event.1.json @@ -575,6 +575,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/claiming_requires_the_contributors_signature.1.json b/contracts/escrow/test_snapshots/claiming_requires_the_contributors_signature.1.json index 04b3c1bc..cabd607a 100644 --- a/contracts/escrow/test_snapshots/claiming_requires_the_contributors_signature.1.json +++ b/contracts/escrow/test_snapshots/claiming_requires_the_contributors_signature.1.json @@ -556,6 +556,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/configured_allowlist_accepts_listed_token_and_rejects_unlisted_token.1.json b/contracts/escrow/test_snapshots/configured_allowlist_accepts_listed_token_and_rejects_unlisted_token.1.json index c49af439..00aeaa9f 100644 --- a/contracts/escrow/test_snapshots/configured_allowlist_accepts_listed_token_and_rejects_unlisted_token.1.json +++ b/contracts/escrow/test_snapshots/configured_allowlist_accepts_listed_token_and_rejects_unlisted_token.1.json @@ -549,6 +549,18 @@ ] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/contribute_emits_an_event.1.json b/contracts/escrow/test_snapshots/contribute_emits_an_event.1.json index 38fd52cc..44157da0 100644 --- a/contracts/escrow/test_snapshots/contribute_emits_an_event.1.json +++ b/contracts/escrow/test_snapshots/contribute_emits_an_event.1.json @@ -553,6 +553,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/contribute_rejects_lying_transfer.1.json b/contracts/escrow/test_snapshots/contribute_rejects_lying_transfer.1.json index 1624fbab..9a637ff2 100644 --- a/contracts/escrow/test_snapshots/contribute_rejects_lying_transfer.1.json +++ b/contracts/escrow/test_snapshots/contribute_rejects_lying_transfer.1.json @@ -387,6 +387,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/contribute_rejects_short_delivery.1.json b/contracts/escrow/test_snapshots/contribute_rejects_short_delivery.1.json index 1624fbab..9a637ff2 100644 --- a/contracts/escrow/test_snapshots/contribute_rejects_short_delivery.1.json +++ b/contracts/escrow/test_snapshots/contribute_rejects_short_delivery.1.json @@ -387,6 +387,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/contributor_cannot_claim_another_contributors_funds.1.json b/contracts/escrow/test_snapshots/contributor_cannot_claim_another_contributors_funds.1.json index 9052c256..e244ecec 100644 --- a/contracts/escrow/test_snapshots/contributor_cannot_claim_another_contributors_funds.1.json +++ b/contracts/escrow/test_snapshots/contributor_cannot_claim_another_contributors_funds.1.json @@ -558,6 +558,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_accepts_amount_at_cap_and_rejects_amount_over_cap.1.json b/contracts/escrow/test_snapshots/create_accepts_amount_at_cap_and_rejects_amount_over_cap.1.json new file mode 100644 index 00000000..58dbb7b0 --- /dev/null +++ b/contracts/escrow/test_snapshots/create_accepts_amount_at_cap_and_rejects_amount_over_cap.1.json @@ -0,0 +1,712 @@ +{ + "generators": { + "address": 8, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "1000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "create_escrow", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + { + "i128": "300" + }, + { + "string": "cap-test" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + "void", + { + "bool": false + }, + "void", + "void", + "void" + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "300" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Escrow" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "accepted_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "300" + } + }, + { + "key": { + "symbol": "condition_ref" + }, + "val": { + "string": "cap-test" + } + }, + { + "key": { + "symbol": "fee_bps" + }, + "val": "void" + }, + { + "key": { + "symbol": "fee_recipient" + }, + "val": "void" + }, + { + "key": { + "symbol": "notify_payee" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "payee" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "symbol": "payer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "refund_after" + }, + "val": "void" + }, + { + "key": { + "symbol": "refund_to" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "release_not_before" + }, + "val": "void" + }, + { + "key": { + "symbol": "releasers" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + { + "key": { + "symbol": "requires_acceptance" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + }, + { + "key": { + "symbol": "threshold" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Liability" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + ] + }, + "durability": "persistent", + "val": { + "i128": "300" + } + } + }, + "ext": "v0" + }, + "live_until": 2073600 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Status" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "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": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [ + { + "key": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + "val": { + "i128": "300" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "1" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "700" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "300" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/create_bounds_the_releaser_set_size.1.json b/contracts/escrow/test_snapshots/create_bounds_the_releaser_set_size.1.json index ca59da20..46da9a45 100644 --- a/contracts/escrow/test_snapshots/create_bounds_the_releaser_set_size.1.json +++ b/contracts/escrow/test_snapshots/create_bounds_the_releaser_set_size.1.json @@ -501,6 +501,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_accepts_deadline_strictly_in_the_future.1.json b/contracts/escrow/test_snapshots/create_escrow_accepts_deadline_strictly_in_the_future.1.json index 3ee780ce..e415cc89 100644 --- a/contracts/escrow/test_snapshots/create_escrow_accepts_deadline_strictly_in_the_future.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_accepts_deadline_strictly_in_the_future.1.json @@ -447,6 +447,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_accepts_fee_bps_at_the_cap.1.json b/contracts/escrow/test_snapshots/create_escrow_accepts_fee_bps_at_the_cap.1.json index 2b5c1769..f89a4074 100644 --- a/contracts/escrow/test_snapshots/create_escrow_accepts_fee_bps_at_the_cap.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_accepts_fee_bps_at_the_cap.1.json @@ -451,6 +451,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_assigns_sequential_ids.1.json b/contracts/escrow/test_snapshots/create_escrow_assigns_sequential_ids.1.json index 057d22ea..9354284c 100644 --- a/contracts/escrow/test_snapshots/create_escrow_assigns_sequential_ids.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_assigns_sequential_ids.1.json @@ -708,6 +708,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_locks_funds_and_reports_funded.1.json b/contracts/escrow/test_snapshots/create_escrow_locks_funds_and_reports_funded.1.json index 215db285..e0e2eefe 100644 --- a/contracts/escrow/test_snapshots/create_escrow_locks_funds_and_reports_funded.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_locks_funds_and_reports_funded.1.json @@ -444,6 +444,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_a_fee_recipient_without_a_rate_and_vice_versa.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_a_fee_recipient_without_a_rate_and_vice_versa.1.json index ab17cc7c..c585d4c7 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_a_fee_recipient_without_a_rate_and_vice_versa.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_a_fee_recipient_without_a_rate_and_vice_versa.1.json @@ -150,6 +150,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_condition_ref_that_is_too_long.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_condition_ref_that_is_too_long.1.json index 00838a13..ad1aebf5 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_condition_ref_that_is_too_long.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_condition_ref_that_is_too_long.1.json @@ -442,6 +442,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_deadline_already_passed_or_now.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_deadline_already_passed_or_now.1.json index 392f9890..d21f57b3 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_deadline_already_passed_or_now.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_deadline_already_passed_or_now.1.json @@ -151,6 +151,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_bps_above_the_cap.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_bps_above_the_cap.1.json index 4668d5ae..95122e7d 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_bps_above_the_cap.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_bps_above_the_cap.1.json @@ -151,6 +151,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_math_overflow_before_locking_anything.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_math_overflow_before_locking_anything.1.json index a4a53e54..c0c44790 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_math_overflow_before_locking_anything.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_math_overflow_before_locking_anything.1.json @@ -149,6 +149,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_recipient_equal_to_the_contract_itself.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_recipient_equal_to_the_contract_itself.1.json index 044be31c..cda1d026 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_fee_recipient_equal_to_the_contract_itself.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_fee_recipient_equal_to_the_contract_itself.1.json @@ -149,6 +149,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_lying_transfer.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_lying_transfer.1.json index 8682c4bc..10b4af90 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_lying_transfer.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_lying_transfer.1.json @@ -98,6 +98,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_non_positive_amount.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_non_positive_amount.1.json index 85e90d13..ae06b9c3 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_non_positive_amount.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_non_positive_amount.1.json @@ -105,6 +105,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_short_delivery.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_short_delivery.1.json index 8682c4bc..10b4af90 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_short_delivery.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_short_delivery.1.json @@ -98,6 +98,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_rejects_the_contract_as_refund_to.1.json b/contracts/escrow/test_snapshots/create_escrow_rejects_the_contract_as_refund_to.1.json index 9cfe1bb9..9c55f86a 100644 --- a/contracts/escrow/test_snapshots/create_escrow_rejects_the_contract_as_refund_to.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_rejects_the_contract_as_refund_to.1.json @@ -150,6 +150,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_escrow_with_refund_to_requires_the_funders_auth.1.json b/contracts/escrow/test_snapshots/create_escrow_with_refund_to_requires_the_funders_auth.1.json index 27139ec4..651b524a 100644 --- a/contracts/escrow/test_snapshots/create_escrow_with_refund_to_requires_the_funders_auth.1.json +++ b/contracts/escrow/test_snapshots/create_escrow_with_refund_to_requires_the_funders_auth.1.json @@ -148,6 +148,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_rejects_an_empty_releaser_set.1.json b/contracts/escrow/test_snapshots/create_rejects_an_empty_releaser_set.1.json index 74f6e2d3..e9015f60 100644 --- a/contracts/escrow/test_snapshots/create_rejects_an_empty_releaser_set.1.json +++ b/contracts/escrow/test_snapshots/create_rejects_an_empty_releaser_set.1.json @@ -147,6 +147,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_rejects_duplicate_releasers.1.json b/contracts/escrow/test_snapshots/create_rejects_duplicate_releasers.1.json index 0c0b2b4d..07d00e44 100644 --- a/contracts/escrow/test_snapshots/create_rejects_duplicate_releasers.1.json +++ b/contracts/escrow/test_snapshots/create_rejects_duplicate_releasers.1.json @@ -147,6 +147,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/create_rejects_zero_threshold_and_threshold_above_set_size.1.json b/contracts/escrow/test_snapshots/create_rejects_zero_threshold_and_threshold_above_set_size.1.json index 01c6d114..6b2b62d1 100644 --- a/contracts/escrow/test_snapshots/create_rejects_zero_threshold_and_threshold_above_set_size.1.json +++ b/contracts/escrow/test_snapshots/create_rejects_zero_threshold_and_threshold_above_set_size.1.json @@ -148,6 +148,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/creation_paths_add_to_liabilities.1.json b/contracts/escrow/test_snapshots/creation_paths_add_to_liabilities.1.json index f275e321..a4c75d52 100644 --- a/contracts/escrow/test_snapshots/creation_paths_add_to_liabilities.1.json +++ b/contracts/escrow/test_snapshots/creation_paths_add_to_liabilities.1.json @@ -2492,6 +2492,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/creation_rejects_release_time_in_the_past_or_after_refund_deadline.1.json b/contracts/escrow/test_snapshots/creation_rejects_release_time_in_the_past_or_after_refund_deadline.1.json index bbfeaedc..c42f8727 100644 --- a/contracts/escrow/test_snapshots/creation_rejects_release_time_in_the_past_or_after_refund_deadline.1.json +++ b/contracts/escrow/test_snapshots/creation_rejects_release_time_in_the_past_or_after_refund_deadline.1.json @@ -150,6 +150,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/double_cancel_is_rejected_and_pays_out_once.1.json b/contracts/escrow/test_snapshots/double_cancel_is_rejected_and_pays_out_once.1.json index c96f2a89..976cf283 100644 --- a/contracts/escrow/test_snapshots/double_cancel_is_rejected_and_pays_out_once.1.json +++ b/contracts/escrow/test_snapshots/double_cancel_is_rejected_and_pays_out_once.1.json @@ -483,6 +483,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/double_claim_is_rejected.1.json b/contracts/escrow/test_snapshots/double_claim_is_rejected.1.json index 82705533..fe6ead71 100644 --- a/contracts/escrow/test_snapshots/double_claim_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/double_claim_is_rejected.1.json @@ -580,6 +580,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/double_refund_pays_refund_to_once.1.json b/contracts/escrow/test_snapshots/double_refund_pays_refund_to_once.1.json index ba550177..0db3fc69 100644 --- a/contracts/escrow/test_snapshots/double_refund_pays_refund_to_once.1.json +++ b/contracts/escrow/test_snapshots/double_refund_pays_refund_to_once.1.json @@ -487,6 +487,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/duplicate_approvals_from_one_releaser_cannot_satisfy_the_threshold.1.json b/contracts/escrow/test_snapshots/duplicate_approvals_from_one_releaser_cannot_satisfy_the_threshold.1.json index 15d15275..c4179e3a 100644 --- a/contracts/escrow/test_snapshots/duplicate_approvals_from_one_releaser_cannot_satisfy_the_threshold.1.json +++ b/contracts/escrow/test_snapshots/duplicate_approvals_from_one_releaser_cannot_satisfy_the_threshold.1.json @@ -461,6 +461,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/each_listed_approver_must_actually_authorize_the_invocation.1.json b/contracts/escrow/test_snapshots/each_listed_approver_must_actually_authorize_the_invocation.1.json index d756993b..ea3418af 100644 --- a/contracts/escrow/test_snapshots/each_listed_approver_must_actually_authorize_the_invocation.1.json +++ b/contracts/escrow/test_snapshots/each_listed_approver_must_actually_authorize_the_invocation.1.json @@ -521,6 +521,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/empty_allowlist_preserves_open_token_behavior.1.json b/contracts/escrow/test_snapshots/empty_allowlist_preserves_open_token_behavior.1.json index a2e5f45f..f3ea1d0f 100644 --- a/contracts/escrow/test_snapshots/empty_allowlist_preserves_open_token_behavior.1.json +++ b/contracts/escrow/test_snapshots/empty_allowlist_preserves_open_token_behavior.1.json @@ -441,6 +441,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/empty_batch_returns_no_results.1.json b/contracts/escrow/test_snapshots/empty_batch_returns_no_results.1.json index 1e837a2a..3a090bf9 100644 --- a/contracts/escrow/test_snapshots/empty_batch_returns_no_results.1.json +++ b/contracts/escrow/test_snapshots/empty_batch_returns_no_results.1.json @@ -168,6 +168,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/empty_cap_map_preserves_uncapped_behavior.1.json b/contracts/escrow/test_snapshots/empty_cap_map_preserves_uncapped_behavior.1.json new file mode 100644 index 00000000..5a21f891 --- /dev/null +++ b/contracts/escrow/test_snapshots/empty_cap_map_preserves_uncapped_behavior.1.json @@ -0,0 +1,800 @@ +{ + "generators": { + "address": 6, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "1000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "create_escrow", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + { + "i128": "1000000" + }, + { + "string": "cap-test" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + "void", + { + "bool": false + }, + "void", + "void", + "void" + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "1000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Escrow" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "accepted_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "condition_ref" + }, + "val": { + "string": "cap-test" + } + }, + { + "key": { + "symbol": "fee_bps" + }, + "val": "void" + }, + { + "key": { + "symbol": "fee_recipient" + }, + "val": "void" + }, + { + "key": { + "symbol": "notify_payee" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "payee" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "symbol": "payer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "refund_after" + }, + "val": "void" + }, + { + "key": { + "symbol": "refund_to" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "release_not_before" + }, + "val": "void" + }, + { + "key": { + "symbol": "releasers" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + { + "key": { + "symbol": "requires_acceptance" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + }, + { + "key": { + "symbol": "threshold" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Liability" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + ] + }, + "durability": "persistent", + "val": { + "i128": "1000000" + } + } + }, + "ext": "v0" + }, + "live_until": 2073600 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Status" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "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": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "1" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "0" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + ], + "data": { + "i128": "1000000" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "ESCROW" + }, + { + "symbol": "created" + }, + { + "u64": "0" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + { + "i128": "1000000" + }, + { + "string": "cap-test" + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + { + "u32": 1 + }, + "void", + { + "bool": false + }, + { + "bool": false + }, + "void", + { + "symbol": "Funded" + }, + { + "vec": [ + "void", + "void" + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/escrow_without_fee_pays_the_full_amount_to_the_payee_as_before.1.json b/contracts/escrow/test_snapshots/escrow_without_fee_pays_the_full_amount_to_the_payee_as_before.1.json index 44416e4c..9fabc88b 100644 --- a/contracts/escrow/test_snapshots/escrow_without_fee_pays_the_full_amount_to_the_payee_as_before.1.json +++ b/contracts/escrow/test_snapshots/escrow_without_fee_pays_the_full_amount_to_the_payee_as_before.1.json @@ -486,6 +486,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/escrow_without_requires_acceptance_still_releases_and_refunds_as_before.1.json b/contracts/escrow/test_snapshots/escrow_without_requires_acceptance_still_releases_and_refunds_as_before.1.json index 62189392..383919bd 100644 --- a/contracts/escrow/test_snapshots/escrow_without_requires_acceptance_still_releases_and_refunds_as_before.1.json +++ b/contracts/escrow/test_snapshots/escrow_without_requires_acceptance_still_releases_and_refunds_as_before.1.json @@ -655,6 +655,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ @@ -975,6 +987,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/explicit_refund_to_equal_to_payer_behaves_like_the_default.1.json b/contracts/escrow/test_snapshots/explicit_refund_to_equal_to_payer_behaves_like_the_default.1.json index e8b6163e..1939d493 100644 --- a/contracts/escrow/test_snapshots/explicit_refund_to_equal_to_payer_behaves_like_the_default.1.json +++ b/contracts/escrow/test_snapshots/explicit_refund_to_equal_to_payer_behaves_like_the_default.1.json @@ -486,6 +486,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/failed_claim_leaves_the_contribution_intact.1.json b/contracts/escrow/test_snapshots/failed_claim_leaves_the_contribution_intact.1.json index 42d49cd1..abc7825b 100644 --- a/contracts/escrow/test_snapshots/failed_claim_leaves_the_contribution_intact.1.json +++ b/contracts/escrow/test_snapshots/failed_claim_leaves_the_contribution_intact.1.json @@ -559,6 +559,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/failed_operations_leave_liabilities_unchanged.1.json b/contracts/escrow/test_snapshots/failed_operations_leave_liabilities_unchanged.1.json index f58788e5..8bc06b6a 100644 --- a/contracts/escrow/test_snapshots/failed_operations_leave_liabilities_unchanged.1.json +++ b/contracts/escrow/test_snapshots/failed_operations_leave_liabilities_unchanged.1.json @@ -1051,6 +1051,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/failed_payout_leaves_the_escrow_funded.1.json b/contracts/escrow/test_snapshots/failed_payout_leaves_the_escrow_funded.1.json index b61f7154..ed16372c 100644 --- a/contracts/escrow/test_snapshots/failed_payout_leaves_the_escrow_funded.1.json +++ b/contracts/escrow/test_snapshots/failed_payout_leaves_the_escrow_funded.1.json @@ -425,6 +425,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/failed_round_refunds_every_contributor_exactly.1.json b/contracts/escrow/test_snapshots/failed_round_refunds_every_contributor_exactly.1.json index 01ca8ce1..12bc75ec 100644 --- a/contracts/escrow/test_snapshots/failed_round_refunds_every_contributor_exactly.1.json +++ b/contracts/escrow/test_snapshots/failed_round_refunds_every_contributor_exactly.1.json @@ -899,6 +899,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/failing_payee_callback_reverts_the_whole_batch.1.json b/contracts/escrow/test_snapshots/failing_payee_callback_reverts_the_whole_batch.1.json index 95c9e7b2..ea4fd113 100644 --- a/contracts/escrow/test_snapshots/failing_payee_callback_reverts_the_whole_batch.1.json +++ b/contracts/escrow/test_snapshots/failing_payee_callback_reverts_the_whole_batch.1.json @@ -754,6 +754,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/fee_bps_zero_is_accepted_and_transfers_nothing.1.json b/contracts/escrow/test_snapshots/fee_bps_zero_is_accepted_and_transfers_nothing.1.json index d84f64e8..d7a09648 100644 --- a/contracts/escrow/test_snapshots/fee_bps_zero_is_accepted_and_transfers_nothing.1.json +++ b/contracts/escrow/test_snapshots/fee_bps_zero_is_accepted_and_transfers_nothing.1.json @@ -493,6 +493,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/fee_floored_to_zero_gives_the_payee_everything.1.json b/contracts/escrow/test_snapshots/fee_floored_to_zero_gives_the_payee_everything.1.json index 28208416..e76d25db 100644 --- a/contracts/escrow/test_snapshots/fee_floored_to_zero_gives_the_payee_everything.1.json +++ b/contracts/escrow/test_snapshots/fee_floored_to_zero_gives_the_payee_everything.1.json @@ -494,6 +494,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/fee_recipient_may_be_the_payee_and_receives_both_payouts.1.json b/contracts/escrow/test_snapshots/fee_recipient_may_be_the_payee_and_receives_both_payouts.1.json index 947eddba..e4dc82fc 100644 --- a/contracts/escrow/test_snapshots/fee_recipient_may_be_the_payee_and_receives_both_payouts.1.json +++ b/contracts/escrow/test_snapshots/fee_recipient_may_be_the_payee_and_receives_both_payouts.1.json @@ -493,6 +493,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/fee_rounds_down_and_the_remainder_stays_with_the_payee.1.json b/contracts/escrow/test_snapshots/fee_rounds_down_and_the_remainder_stays_with_the_payee.1.json index 5809e92b..e3d15823 100644 --- a/contracts/escrow/test_snapshots/fee_rounds_down_and_the_remainder_stays_with_the_payee.1.json +++ b/contracts/escrow/test_snapshots/fee_rounds_down_and_the_remainder_stays_with_the_payee.1.json @@ -495,6 +495,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/funder_calling_refund_after_the_deadline_cannot_steer_the_money_to_itself.1.json b/contracts/escrow/test_snapshots/funder_calling_refund_after_the_deadline_cannot_steer_the_money_to_itself.1.json index d1fbbbca..9b9b4372 100644 --- a/contracts/escrow/test_snapshots/funder_calling_refund_after_the_deadline_cannot_steer_the_money_to_itself.1.json +++ b/contracts/escrow/test_snapshots/funder_calling_refund_after_the_deadline_cannot_steer_the_money_to_itself.1.json @@ -491,6 +491,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/get_escrow_errors_for_unknown_escrow.1.json b/contracts/escrow/test_snapshots/get_escrow_errors_for_unknown_escrow.1.json index cac7ef6d..d748f8a2 100644 --- a/contracts/escrow/test_snapshots/get_escrow_errors_for_unknown_escrow.1.json +++ b/contracts/escrow/test_snapshots/get_escrow_errors_for_unknown_escrow.1.json @@ -44,6 +44,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/get_escrow_exposes_the_fee_exactly_as_declared_at_creation.1.json b/contracts/escrow/test_snapshots/get_escrow_exposes_the_fee_exactly_as_declared_at_creation.1.json index b3436a0d..c1d013bb 100644 --- a/contracts/escrow/test_snapshots/get_escrow_exposes_the_fee_exactly_as_declared_at_creation.1.json +++ b/contracts/escrow/test_snapshots/get_escrow_exposes_the_fee_exactly_as_declared_at_creation.1.json @@ -450,6 +450,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/get_escrow_exposes_the_stored_parties_and_deadline.1.json b/contracts/escrow/test_snapshots/get_escrow_exposes_the_stored_parties_and_deadline.1.json index f88f8b9f..b1751ee3 100644 --- a/contracts/escrow/test_snapshots/get_escrow_exposes_the_stored_parties_and_deadline.1.json +++ b/contracts/escrow/test_snapshots/get_escrow_exposes_the_stored_parties_and_deadline.1.json @@ -446,6 +446,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/get_escrow_reports_no_deadline_when_none_was_set.1.json b/contracts/escrow/test_snapshots/get_escrow_reports_no_deadline_when_none_was_set.1.json index 6b3dce42..f9069916 100644 --- a/contracts/escrow/test_snapshots/get_escrow_reports_no_deadline_when_none_was_set.1.json +++ b/contracts/escrow/test_snapshots/get_escrow_reports_no_deadline_when_none_was_set.1.json @@ -442,6 +442,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/get_escrow_reports_no_fee_when_none_was_set.1.json b/contracts/escrow/test_snapshots/get_escrow_reports_no_fee_when_none_was_set.1.json index 3523e13e..e343f2d7 100644 --- a/contracts/escrow/test_snapshots/get_escrow_reports_no_fee_when_none_was_set.1.json +++ b/contracts/escrow/test_snapshots/get_escrow_reports_no_fee_when_none_was_set.1.json @@ -442,6 +442,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/get_status_errors_for_unknown_escrow.1.json b/contracts/escrow/test_snapshots/get_status_errors_for_unknown_escrow.1.json index cac7ef6d..d748f8a2 100644 --- a/contracts/escrow/test_snapshots/get_status_errors_for_unknown_escrow.1.json +++ b/contracts/escrow/test_snapshots/get_status_errors_for_unknown_escrow.1.json @@ -44,6 +44,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/invalid_contributions_are_rejected.1.json b/contracts/escrow/test_snapshots/invalid_contributions_are_rejected.1.json index 02a6ccd2..eea34bbb 100644 --- a/contracts/escrow/test_snapshots/invalid_contributions_are_rejected.1.json +++ b/contracts/escrow/test_snapshots/invalid_contributions_are_rejected.1.json @@ -652,6 +652,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/issued_assets_are_isolated_between_escrows.1.json b/contracts/escrow/test_snapshots/issued_assets_are_isolated_between_escrows.1.json index 118173a4..131bb1f9 100644 --- a/contracts/escrow/test_snapshots/issued_assets_are_isolated_between_escrows.1.json +++ b/contracts/escrow/test_snapshots/issued_assets_are_isolated_between_escrows.1.json @@ -840,6 +840,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/legacy_creation_keeps_acceptance_opt_out.1.json b/contracts/escrow/test_snapshots/legacy_creation_keeps_acceptance_opt_out.1.json index 4026e6fe..84caf097 100644 --- a/contracts/escrow/test_snapshots/legacy_creation_keeps_acceptance_opt_out.1.json +++ b/contracts/escrow/test_snapshots/legacy_creation_keeps_acceptance_opt_out.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/liabilities_are_kept_per_token.1.json b/contracts/escrow/test_snapshots/liabilities_are_kept_per_token.1.json index 60dcf30e..a6546c1a 100644 --- a/contracts/escrow/test_snapshots/liabilities_are_kept_per_token.1.json +++ b/contracts/escrow/test_snapshots/liabilities_are_kept_per_token.1.json @@ -1352,6 +1352,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/liability_entry_ttl_is_extended_on_write.1.json b/contracts/escrow/test_snapshots/liability_entry_ttl_is_extended_on_write.1.json index ea1be4cc..b0b6bb2f 100644 --- a/contracts/escrow/test_snapshots/liability_entry_ttl_is_extended_on_write.1.json +++ b/contracts/escrow/test_snapshots/liability_entry_ttl_is_extended_on_write.1.json @@ -1027,6 +1027,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/max_batch_fits_mainnet_limits.1.json b/contracts/escrow/test_snapshots/max_batch_fits_mainnet_limits.1.json index 7f76b719..456a033b 100644 --- a/contracts/escrow/test_snapshots/max_batch_fits_mainnet_limits.1.json +++ b/contracts/escrow/test_snapshots/max_batch_fits_mainnet_limits.1.json @@ -3569,6 +3569,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/mixed_release_and_refund_in_one_batch.1.json b/contracts/escrow/test_snapshots/mixed_release_and_refund_in_one_batch.1.json index b813f61e..3f161de2 100644 --- a/contracts/escrow/test_snapshots/mixed_release_and_refund_in_one_batch.1.json +++ b/contracts/escrow/test_snapshots/mixed_release_and_refund_in_one_batch.1.json @@ -764,6 +764,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/multiple_contributors_recorded_independently.1.json b/contracts/escrow/test_snapshots/multiple_contributors_recorded_independently.1.json index a5347965..6cd2d2cb 100644 --- a/contracts/escrow/test_snapshots/multiple_contributors_recorded_independently.1.json +++ b/contracts/escrow/test_snapshots/multiple_contributors_recorded_independently.1.json @@ -827,6 +827,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/neither_funder_nor_refund_to_may_trigger_a_refund_before_the_deadline.1.json b/contracts/escrow/test_snapshots/neither_funder_nor_refund_to_may_trigger_a_refund_before_the_deadline.1.json index 3b561a66..b675b9b2 100644 --- a/contracts/escrow/test_snapshots/neither_funder_nor_refund_to_may_trigger_a_refund_before_the_deadline.1.json +++ b/contracts/escrow/test_snapshots/neither_funder_nor_refund_to_may_trigger_a_refund_before_the_deadline.1.json @@ -451,6 +451,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/no_contributor_cap_each_claim_is_independent.1.json b/contracts/escrow/test_snapshots/no_contributor_cap_each_claim_is_independent.1.json index 90e63789..2f2f2098 100644 --- a/contracts/escrow/test_snapshots/no_contributor_cap_each_claim_is_independent.1.json +++ b/contracts/escrow/test_snapshots/no_contributor_cap_each_claim_is_independent.1.json @@ -2329,6 +2329,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/non_member_approver_is_rejected.1.json b/contracts/escrow/test_snapshots/non_member_approver_is_rejected.1.json index 4cb18933..fb6f0c7c 100644 --- a/contracts/escrow/test_snapshots/non_member_approver_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/non_member_approver_is_rejected.1.json @@ -460,6 +460,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/non_positive_cap_is_rejected_at_deployment.1.json b/contracts/escrow/test_snapshots/non_positive_cap_is_rejected_at_deployment.1.json new file mode 100644 index 00000000..e85c4d75 --- /dev/null +++ b/contracts/escrow/test_snapshots/non_positive_cap_is_rejected_at_deployment.1.json @@ -0,0 +1,224 @@ +{ + "generators": { + "address": 3, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/omitted_refund_to_defaults_to_payer.1.json b/contracts/escrow/test_snapshots/omitted_refund_to_defaults_to_payer.1.json index 6bbc29d1..ca02706b 100644 --- a/contracts/escrow/test_snapshots/omitted_refund_to_defaults_to_payer.1.json +++ b/contracts/escrow/test_snapshots/omitted_refund_to_defaults_to_payer.1.json @@ -486,6 +486,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/omitted_refund_to_timeout_refund_still_goes_to_payer.1.json b/contracts/escrow/test_snapshots/omitted_refund_to_timeout_refund_still_goes_to_payer.1.json index 1d13a536..2f1d80fd 100644 --- a/contracts/escrow/test_snapshots/omitted_refund_to_timeout_refund_still_goes_to_payer.1.json +++ b/contracts/escrow/test_snapshots/omitted_refund_to_timeout_refund_still_goes_to_payer.1.json @@ -468,6 +468,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/only_the_stored_payer_may_cancel.1.json b/contracts/escrow/test_snapshots/only_the_stored_payer_may_cancel.1.json index d7667014..d61a24a5 100644 --- a/contracts/escrow/test_snapshots/only_the_stored_payer_may_cancel.1.json +++ b/contracts/escrow/test_snapshots/only_the_stored_payer_may_cancel.1.json @@ -446,6 +446,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/opted_in_contract_payee_receives_release_callback.1.json b/contracts/escrow/test_snapshots/opted_in_contract_payee_receives_release_callback.1.json index e6a5ecec..b347e7ac 100644 --- a/contracts/escrow/test_snapshots/opted_in_contract_payee_receives_release_callback.1.json +++ b/contracts/escrow/test_snapshots/opted_in_contract_payee_receives_release_callback.1.json @@ -593,6 +593,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/ordinary_escrows_are_unaffected.1.json b/contracts/escrow/test_snapshots/ordinary_escrows_are_unaffected.1.json index 2ddb0a48..9a145780 100644 --- a/contracts/escrow/test_snapshots/ordinary_escrows_are_unaffected.1.json +++ b/contracts/escrow/test_snapshots/ordinary_escrows_are_unaffected.1.json @@ -866,6 +866,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/oversized_batch_is_rejected_before_anything_settles.1.json b/contracts/escrow/test_snapshots/oversized_batch_is_rejected_before_anything_settles.1.json index 60f9f1e7..4efe5996 100644 --- a/contracts/escrow/test_snapshots/oversized_batch_is_rejected_before_anything_settles.1.json +++ b/contracts/escrow/test_snapshots/oversized_batch_is_rejected_before_anything_settles.1.json @@ -443,6 +443,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/partial_funding_records_and_blocks_release.1.json b/contracts/escrow/test_snapshots/partial_funding_records_and_blocks_release.1.json index 20ac040f..0e1318f4 100644 --- a/contracts/escrow/test_snapshots/partial_funding_records_and_blocks_release.1.json +++ b/contracts/escrow/test_snapshots/partial_funding_records_and_blocks_release.1.json @@ -560,6 +560,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/payer_cancel_before_accept_refunds_payer_in_full.1.json b/contracts/escrow/test_snapshots/payer_cancel_before_accept_refunds_payer_in_full.1.json index 2ea69aa8..df7da0b9 100644 --- a/contracts/escrow/test_snapshots/payer_cancel_before_accept_refunds_payer_in_full.1.json +++ b/contracts/escrow/test_snapshots/payer_cancel_before_accept_refunds_payer_in_full.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/per_op_rejections_leave_each_escrow_untouched.1.json b/contracts/escrow/test_snapshots/per_op_rejections_leave_each_escrow_untouched.1.json index 5bae3028..87bccd09 100644 --- a/contracts/escrow/test_snapshots/per_op_rejections_leave_each_escrow_untouched.1.json +++ b/contracts/escrow/test_snapshots/per_op_rejections_leave_each_escrow_untouched.1.json @@ -2099,6 +2099,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/pooled_claim_refund_subtracts_each_claim.1.json b/contracts/escrow/test_snapshots/pooled_claim_refund_subtracts_each_claim.1.json index c365d335..bad07343 100644 --- a/contracts/escrow/test_snapshots/pooled_claim_refund_subtracts_each_claim.1.json +++ b/contracts/escrow/test_snapshots/pooled_claim_refund_subtracts_each_claim.1.json @@ -1363,6 +1363,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/pooled_contributions_and_release_track_liabilities.1.json b/contracts/escrow/test_snapshots/pooled_contributions_and_release_track_liabilities.1.json index 09f2cb72..37ad070d 100644 --- a/contracts/escrow/test_snapshots/pooled_contributions_and_release_track_liabilities.1.json +++ b/contracts/escrow/test_snapshots/pooled_contributions_and_release_track_liabilities.1.json @@ -1295,6 +1295,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/pooled_creation_respects_the_token_allowlist.1.json b/contracts/escrow/test_snapshots/pooled_creation_respects_the_token_allowlist.1.json index 3a46c70b..7d6f32a9 100644 --- a/contracts/escrow/test_snapshots/pooled_creation_respects_the_token_allowlist.1.json +++ b/contracts/escrow/test_snapshots/pooled_creation_respects_the_token_allowlist.1.json @@ -457,6 +457,18 @@ ] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/pooled_creation_validation.1.json b/contracts/escrow/test_snapshots/pooled_creation_validation.1.json index 959ca1a8..e373a8f8 100644 --- a/contracts/escrow/test_snapshots/pooled_creation_validation.1.json +++ b/contracts/escrow/test_snapshots/pooled_creation_validation.1.json @@ -397,6 +397,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/pooled_funding_target_is_capped.1.json b/contracts/escrow/test_snapshots/pooled_funding_target_is_capped.1.json new file mode 100644 index 00000000..6af32b93 --- /dev/null +++ b/contracts/escrow/test_snapshots/pooled_funding_target_is_capped.1.json @@ -0,0 +1,557 @@ +{ + "generators": { + "address": 9, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "create_pooled_escrow", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + { + "i128": "500" + }, + { + "string": "pooled-cap" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "u64": "2000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 1000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Escrow" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "accepted_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "0" + } + }, + { + "key": { + "symbol": "condition_ref" + }, + "val": { + "string": "pooled-cap" + } + }, + { + "key": { + "symbol": "fee_bps" + }, + "val": "void" + }, + { + "key": { + "symbol": "fee_recipient" + }, + "val": "void" + }, + { + "key": { + "symbol": "notify_payee" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "payee" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "symbol": "payer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "refund_after" + }, + "val": "void" + }, + { + "key": { + "symbol": "refund_to" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "release_not_before" + }, + "val": "void" + }, + { + "key": { + "symbol": "releasers" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + { + "key": { + "symbol": "requires_acceptance" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + }, + { + "key": { + "symbol": "threshold" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Pooled" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "funding_deadline" + }, + "val": { + "u64": "2000" + } + }, + { + "key": { + "symbol": "funding_target" + }, + "val": { + "i128": "500" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Status" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [ + { + "key": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + "val": { + "i128": "500" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "1" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/push_paths_and_top_up_reject_pooled_escrows.1.json b/contracts/escrow/test_snapshots/push_paths_and_top_up_reject_pooled_escrows.1.json index 2c36c2c1..cc6b4c0c 100644 --- a/contracts/escrow/test_snapshots/push_paths_and_top_up_reject_pooled_escrows.1.json +++ b/contracts/escrow/test_snapshots/push_paths_and_top_up_reject_pooled_escrows.1.json @@ -779,6 +779,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/quorum_escrow_stores_the_releaser_set_and_threshold.1.json b/contracts/escrow/test_snapshots/quorum_escrow_stores_the_releaser_set_and_threshold.1.json index 57cf02fe..b2012420 100644 --- a/contracts/escrow/test_snapshots/quorum_escrow_stores_the_releaser_set_and_threshold.1.json +++ b/contracts/escrow/test_snapshots/quorum_escrow_stores_the_releaser_set_and_threshold.1.json @@ -459,6 +459,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/quorum_release_invokes_opted_in_contract_payee.1.json b/contracts/escrow/test_snapshots/quorum_release_invokes_opted_in_contract_payee.1.json index d2ade6e2..daeebd85 100644 --- a/contracts/escrow/test_snapshots/quorum_release_invokes_opted_in_contract_payee.1.json +++ b/contracts/escrow/test_snapshots/quorum_release_invokes_opted_in_contract_payee.1.json @@ -667,6 +667,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/quorum_settlements_subtract_from_liabilities.1.json b/contracts/escrow/test_snapshots/quorum_settlements_subtract_from_liabilities.1.json index a9f2f3fc..010e3a1f 100644 --- a/contracts/escrow/test_snapshots/quorum_settlements_subtract_from_liabilities.1.json +++ b/contracts/escrow/test_snapshots/quorum_settlements_subtract_from_liabilities.1.json @@ -1449,6 +1449,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/race_accept_lands_first_then_cancel_fails_and_payee_keeps_the_escrow.1.json b/contracts/escrow/test_snapshots/race_accept_lands_first_then_cancel_fails_and_payee_keeps_the_escrow.1.json index 29938462..5b19e755 100644 --- a/contracts/escrow/test_snapshots/race_accept_lands_first_then_cancel_fails_and_payee_keeps_the_escrow.1.json +++ b/contracts/escrow/test_snapshots/race_accept_lands_first_then_cancel_fails_and_payee_keeps_the_escrow.1.json @@ -533,6 +533,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/race_cancel_lands_first_then_accept_fails_and_payer_keeps_the_funds.1.json b/contracts/escrow/test_snapshots/race_cancel_lands_first_then_accept_fails_and_payer_keeps_the_funds.1.json index 9f321fc9..6d4adba1 100644 --- a/contracts/escrow/test_snapshots/race_cancel_lands_first_then_accept_fails_and_payer_keeps_the_funds.1.json +++ b/contracts/escrow/test_snapshots/race_cancel_lands_first_then_accept_fails_and_payer_keeps_the_funds.1.json @@ -489,6 +489,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/reaching_the_target_releases_the_pooled_total.1.json b/contracts/escrow/test_snapshots/reaching_the_target_releases_the_pooled_total.1.json index d348eda5..4878d590 100644 --- a/contracts/escrow/test_snapshots/reaching_the_target_releases_the_pooled_total.1.json +++ b/contracts/escrow/test_snapshots/reaching_the_target_releases_the_pooled_total.1.json @@ -916,6 +916,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/reentrant_transfer_cannot_double_release.1.json b/contracts/escrow/test_snapshots/reentrant_transfer_cannot_double_release.1.json index 57ef7723..520c0219 100644 --- a/contracts/escrow/test_snapshots/reentrant_transfer_cannot_double_release.1.json +++ b/contracts/escrow/test_snapshots/reentrant_transfer_cannot_double_release.1.json @@ -471,6 +471,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.1.json b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.1.json index ab6d888b..66251e67 100644 --- a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.1.json +++ b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.1.json @@ -893,6 +893,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.2.json b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.2.json index d4302d22..21d8822f 100644 --- a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.2.json +++ b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.2.json @@ -893,6 +893,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.3.json b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.3.json index 78246d70..f525313b 100644 --- a/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.3.json +++ b/contracts/escrow/test_snapshots/refund_entitlements_are_order_independent.3.json @@ -893,6 +893,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_rejects_after_release.1.json b/contracts/escrow/test_snapshots/refund_rejects_after_release.1.json index 76a57f89..a01b8af5 100644 --- a/contracts/escrow/test_snapshots/refund_rejects_after_release.1.json +++ b/contracts/escrow/test_snapshots/refund_rejects_after_release.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_rejects_unauthorized_caller.1.json b/contracts/escrow/test_snapshots/refund_rejects_unauthorized_caller.1.json index 3507124c..84031e0a 100644 --- a/contracts/escrow/test_snapshots/refund_rejects_unauthorized_caller.1.json +++ b/contracts/escrow/test_snapshots/refund_rejects_unauthorized_caller.1.json @@ -443,6 +443,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_to_is_fixed_at_creation_and_visible_via_get_escrow.1.json b/contracts/escrow/test_snapshots/refund_to_is_fixed_at_creation_and_visible_via_get_escrow.1.json index c91ecfda..bfa170b7 100644 --- a/contracts/escrow/test_snapshots/refund_to_is_fixed_at_creation_and_visible_via_get_escrow.1.json +++ b/contracts/escrow/test_snapshots/refund_to_is_fixed_at_creation_and_visible_via_get_escrow.1.json @@ -446,6 +446,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_transfers_funds_back_to_payer_and_marks_refunded.1.json b/contracts/escrow/test_snapshots/refund_transfers_funds_back_to_payer_and_marks_refunded.1.json index f5286d27..65df127a 100644 --- a/contracts/escrow/test_snapshots/refund_transfers_funds_back_to_payer_and_marks_refunded.1.json +++ b/contracts/escrow/test_snapshots/refund_transfers_funds_back_to_payer_and_marks_refunded.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_with_approvals_rejects_duplicates_and_short_thresholds.1.json b/contracts/escrow/test_snapshots/refund_with_approvals_rejects_duplicates_and_short_thresholds.1.json index 15d15275..c4179e3a 100644 --- a/contracts/escrow/test_snapshots/refund_with_approvals_rejects_duplicates_and_short_thresholds.1.json +++ b/contracts/escrow/test_snapshots/refund_with_approvals_rejects_duplicates_and_short_thresholds.1.json @@ -461,6 +461,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/refund_with_approvals_returns_funds_to_the_payer.1.json b/contracts/escrow/test_snapshots/refund_with_approvals_returns_funds_to_the_payer.1.json index af3db6e7..5b919d4a 100644 --- a/contracts/escrow/test_snapshots/refund_with_approvals_returns_funds_to_the_payer.1.json +++ b/contracts/escrow/test_snapshots/refund_with_approvals_returns_funds_to_the_payer.1.json @@ -517,6 +517,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/rejected_quorum_creation_locks_nothing.1.json b/contracts/escrow/test_snapshots/rejected_quorum_creation_locks_nothing.1.json index 27139ec4..651b524a 100644 --- a/contracts/escrow/test_snapshots/rejected_quorum_creation_locks_nothing.1.json +++ b/contracts/escrow/test_snapshots/rejected_quorum_creation_locks_nothing.1.json @@ -148,6 +148,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/release_and_refund_can_never_share_funds.1.json b/contracts/escrow/test_snapshots/release_and_refund_can_never_share_funds.1.json index 5233c549..1e8726ae 100644 --- a/contracts/escrow/test_snapshots/release_and_refund_can_never_share_funds.1.json +++ b/contracts/escrow/test_snapshots/release_and_refund_can_never_share_funds.1.json @@ -792,6 +792,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ @@ -1203,6 +1215,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_and_refund_subtract_from_liabilities.1.json b/contracts/escrow/test_snapshots/release_and_refund_subtract_from_liabilities.1.json index 91fb9ee0..71a03522 100644 --- a/contracts/escrow/test_snapshots/release_and_refund_subtract_from_liabilities.1.json +++ b/contracts/escrow/test_snapshots/release_and_refund_subtract_from_liabilities.1.json @@ -1338,6 +1338,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_is_rejected_before_time_and_allowed_at_the_exact_boundary.1.json b/contracts/escrow/test_snapshots/release_is_rejected_before_time_and_allowed_at_the_exact_boundary.1.json index 2bc5d99e..457d48ab 100644 --- a/contracts/escrow/test_snapshots/release_is_rejected_before_time_and_allowed_at_the_exact_boundary.1.json +++ b/contracts/escrow/test_snapshots/release_is_rejected_before_time_and_allowed_at_the_exact_boundary.1.json @@ -499,6 +499,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_lock_does_not_restrict_releaser_refunds.1.json b/contracts/escrow/test_snapshots/release_lock_does_not_restrict_releaser_refunds.1.json index 0f8c4d9e..84a05fe0 100644 --- a/contracts/escrow/test_snapshots/release_lock_does_not_restrict_releaser_refunds.1.json +++ b/contracts/escrow/test_snapshots/release_lock_does_not_restrict_releaser_refunds.1.json @@ -495,6 +495,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_rejects_after_refund.1.json b/contracts/escrow/test_snapshots/release_rejects_after_refund.1.json index f5286d27..65df127a 100644 --- a/contracts/escrow/test_snapshots/release_rejects_after_refund.1.json +++ b/contracts/escrow/test_snapshots/release_rejects_after_refund.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_rejects_double_release.1.json b/contracts/escrow/test_snapshots/release_rejects_double_release.1.json index 76a57f89..a01b8af5 100644 --- a/contracts/escrow/test_snapshots/release_rejects_double_release.1.json +++ b/contracts/escrow/test_snapshots/release_rejects_double_release.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_rejects_unauthorized_caller.1.json b/contracts/escrow/test_snapshots/release_rejects_unauthorized_caller.1.json index 43dc557a..f3640a1b 100644 --- a/contracts/escrow/test_snapshots/release_rejects_unauthorized_caller.1.json +++ b/contracts/escrow/test_snapshots/release_rejects_unauthorized_caller.1.json @@ -444,6 +444,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_still_pays_the_payee_not_refund_to.1.json b/contracts/escrow/test_snapshots/release_still_pays_the_payee_not_refund_to.1.json index 44d0dd40..b26b52e2 100644 --- a/contracts/escrow/test_snapshots/release_still_pays_the_payee_not_refund_to.1.json +++ b/contracts/escrow/test_snapshots/release_still_pays_the_payee_not_refund_to.1.json @@ -488,6 +488,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_time_equal_to_creation_time_is_valid_and_releasable_immediately.1.json b/contracts/escrow/test_snapshots/release_time_equal_to_creation_time_is_valid_and_releasable_immediately.1.json index ab5f6835..633b64af 100644 --- a/contracts/escrow/test_snapshots/release_time_equal_to_creation_time_is_valid_and_releasable_immediately.1.json +++ b/contracts/escrow/test_snapshots/release_time_equal_to_creation_time_is_valid_and_releasable_immediately.1.json @@ -495,6 +495,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_time_equal_to_refund_deadline_is_valid.1.json b/contracts/escrow/test_snapshots/release_time_equal_to_refund_deadline_is_valid.1.json index cea8d3f7..4fced80c 100644 --- a/contracts/escrow/test_snapshots/release_time_equal_to_refund_deadline_is_valid.1.json +++ b/contracts/escrow/test_snapshots/release_time_equal_to_refund_deadline_is_valid.1.json @@ -451,6 +451,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_transfers_funds_to_payee_and_marks_released.1.json b/contracts/escrow/test_snapshots/release_transfers_funds_to_payee_and_marks_released.1.json index 76a57f89..a01b8af5 100644 --- a/contracts/escrow/test_snapshots/release_transfers_funds_to_payee_and_marks_released.1.json +++ b/contracts/escrow/test_snapshots/release_transfers_funds_to_payee_and_marks_released.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_wins_at_the_deadline_and_timeout_refund_then_fails.1.json b/contracts/escrow/test_snapshots/release_wins_at_the_deadline_and_timeout_refund_then_fails.1.json index b58fc07b..308fcd2a 100644 --- a/contracts/escrow/test_snapshots/release_wins_at_the_deadline_and_timeout_refund_then_fails.1.json +++ b/contracts/escrow/test_snapshots/release_wins_at_the_deadline_and_timeout_refund_then_fails.1.json @@ -491,6 +491,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_with_approvals_is_gated_by_full_funding_too.1.json b/contracts/escrow/test_snapshots/release_with_approvals_is_gated_by_full_funding_too.1.json index 563896ad..36423b34 100644 --- a/contracts/escrow/test_snapshots/release_with_approvals_is_gated_by_full_funding_too.1.json +++ b/contracts/escrow/test_snapshots/release_with_approvals_is_gated_by_full_funding_too.1.json @@ -648,6 +648,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_with_exactly_threshold_distinct_approvals_pays_the_payee.1.json b/contracts/escrow/test_snapshots/release_with_exactly_threshold_distinct_approvals_pays_the_payee.1.json index 8e67e316..7a12ff44 100644 --- a/contracts/escrow/test_snapshots/release_with_exactly_threshold_distinct_approvals_pays_the_payee.1.json +++ b/contracts/escrow/test_snapshots/release_with_exactly_threshold_distinct_approvals_pays_the_payee.1.json @@ -516,6 +516,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_with_fee_pays_recipient_and_remainder_summing_to_amount.1.json b/contracts/escrow/test_snapshots/release_with_fee_pays_recipient_and_remainder_summing_to_amount.1.json index cf780d39..5482d512 100644 --- a/contracts/escrow/test_snapshots/release_with_fee_pays_recipient_and_remainder_summing_to_amount.1.json +++ b/contracts/escrow/test_snapshots/release_with_fee_pays_recipient_and_remainder_summing_to_amount.1.json @@ -497,6 +497,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_with_fewer_than_threshold_approvals_is_rejected.1.json b/contracts/escrow/test_snapshots/release_with_fewer_than_threshold_approvals_is_rejected.1.json index 15d15275..c4179e3a 100644 --- a/contracts/escrow/test_snapshots/release_with_fewer_than_threshold_approvals_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/release_with_fewer_than_threshold_approvals_is_rejected.1.json @@ -461,6 +461,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/release_with_more_than_threshold_approvals_succeeds.1.json b/contracts/escrow/test_snapshots/release_with_more_than_threshold_approvals_succeeds.1.json index 7d819e78..ffe0da77 100644 --- a/contracts/escrow/test_snapshots/release_with_more_than_threshold_approvals_succeeds.1.json +++ b/contracts/escrow/test_snapshots/release_with_more_than_threshold_approvals_succeeds.1.json @@ -551,6 +551,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releaser_can_still_release_after_the_deadline.1.json b/contracts/escrow/test_snapshots/releaser_can_still_release_after_the_deadline.1.json index c7afe6fb..9af18f19 100644 --- a/contracts/escrow/test_snapshots/releaser_can_still_release_after_the_deadline.1.json +++ b/contracts/escrow/test_snapshots/releaser_can_still_release_after_the_deadline.1.json @@ -489,6 +489,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releaser_cannot_pay_out_after_cancel.1.json b/contracts/escrow/test_snapshots/releaser_cannot_pay_out_after_cancel.1.json index c96f2a89..976cf283 100644 --- a/contracts/escrow/test_snapshots/releaser_cannot_pay_out_after_cancel.1.json +++ b/contracts/escrow/test_snapshots/releaser_cannot_pay_out_after_cancel.1.json @@ -483,6 +483,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releaser_refund_goes_to_refund_to_not_the_funder.1.json b/contracts/escrow/test_snapshots/releaser_refund_goes_to_refund_to_not_the_funder.1.json index e1420e57..3332b0c7 100644 --- a/contracts/escrow/test_snapshots/releaser_refund_goes_to_refund_to_not_the_funder.1.json +++ b/contracts/escrow/test_snapshots/releaser_refund_goes_to_refund_to_not_the_funder.1.json @@ -490,6 +490,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releaser_refund_returns_the_full_amount_with_no_fee.1.json b/contracts/escrow/test_snapshots/releaser_refund_returns_the_full_amount_with_no_fee.1.json index 4530d5c1..069ad008 100644 --- a/contracts/escrow/test_snapshots/releaser_refund_returns_the_full_amount_with_no_fee.1.json +++ b/contracts/escrow/test_snapshots/releaser_refund_returns_the_full_amount_with_no_fee.1.json @@ -495,6 +495,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releaser_refund_still_works_before_deadline.1.json b/contracts/escrow/test_snapshots/releaser_refund_still_works_before_deadline.1.json index 15553486..55681987 100644 --- a/contracts/escrow/test_snapshots/releaser_refund_still_works_before_deadline.1.json +++ b/contracts/escrow/test_snapshots/releaser_refund_still_works_before_deadline.1.json @@ -489,6 +489,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/releasers_can_still_release_after_the_deadline.1.json b/contracts/escrow/test_snapshots/releasers_can_still_release_after_the_deadline.1.json index 16c24200..1407ef5b 100644 --- a/contracts/escrow/test_snapshots/releasers_can_still_release_after_the_deadline.1.json +++ b/contracts/escrow/test_snapshots/releasers_can_still_release_after_the_deadline.1.json @@ -519,6 +519,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/repeated_contributions_accumulate_per_payer.1.json b/contracts/escrow/test_snapshots/repeated_contributions_accumulate_per_payer.1.json index 87ac6732..7ed5d956 100644 --- a/contracts/escrow/test_snapshots/repeated_contributions_accumulate_per_payer.1.json +++ b/contracts/escrow/test_snapshots/repeated_contributions_accumulate_per_payer.1.json @@ -738,6 +738,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/required_acceptance_blocks_release_until_payee_accepts.1.json b/contracts/escrow/test_snapshots/required_acceptance_blocks_release_until_payee_accepts.1.json index e5933960..51b8ddc0 100644 --- a/contracts/escrow/test_snapshots/required_acceptance_blocks_release_until_payee_accepts.1.json +++ b/contracts/escrow/test_snapshots/required_acceptance_blocks_release_until_payee_accepts.1.json @@ -531,6 +531,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/rotation_rejects_contract_and_payee_as_new_releaser.1.json b/contracts/escrow/test_snapshots/rotation_rejects_contract_and_payee_as_new_releaser.1.json index 40e25a4c..c89c1db8 100644 --- a/contracts/escrow/test_snapshots/rotation_rejects_contract_and_payee_as_new_releaser.1.json +++ b/contracts/escrow/test_snapshots/rotation_rejects_contract_and_payee_as_new_releaser.1.json @@ -443,6 +443,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/rotation_rejects_wrong_releaser_and_non_funded_escrows.1.json b/contracts/escrow/test_snapshots/rotation_rejects_wrong_releaser_and_non_funded_escrows.1.json index b7bd8da7..888c4135 100644 --- a/contracts/escrow/test_snapshots/rotation_rejects_wrong_releaser_and_non_funded_escrows.1.json +++ b/contracts/escrow/test_snapshots/rotation_rejects_wrong_releaser_and_non_funded_escrows.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/rotation_requires_both_stored_parties_and_updates_the_releaser.1.json b/contracts/escrow/test_snapshots/rotation_requires_both_stored_parties_and_updates_the_releaser.1.json index b87c010a..f35f68e2 100644 --- a/contracts/escrow/test_snapshots/rotation_requires_both_stored_parties_and_updates_the_releaser.1.json +++ b/contracts/escrow/test_snapshots/rotation_requires_both_stored_parties_and_updates_the_releaser.1.json @@ -583,6 +583,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/same_escrow_twice_second_op_fails_not_funded.1.json b/contracts/escrow/test_snapshots/same_escrow_twice_second_op_fails_not_funded.1.json index ef02b5e4..ce77471f 100644 --- a/contracts/escrow/test_snapshots/same_escrow_twice_second_op_fails_not_funded.1.json +++ b/contracts/escrow/test_snapshots/same_escrow_twice_second_op_fails_not_funded.1.json @@ -495,6 +495,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/settle_many_subtracts_each_release.1.json b/contracts/escrow/test_snapshots/settle_many_subtracts_each_release.1.json index 6205d118..5e496ec4 100644 --- a/contracts/escrow/test_snapshots/settle_many_subtracts_each_release.1.json +++ b/contracts/escrow/test_snapshots/settle_many_subtracts_each_release.1.json @@ -1674,6 +1674,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/settled_approvals_cannot_be_replayed.1.json b/contracts/escrow/test_snapshots/settled_approvals_cannot_be_replayed.1.json index 38d2dc17..d2b98e3a 100644 --- a/contracts/escrow/test_snapshots/settled_approvals_cannot_be_replayed.1.json +++ b/contracts/escrow/test_snapshots/settled_approvals_cannot_be_replayed.1.json @@ -516,6 +516,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/settled_escrow_cannot_be_refunded_to_refund_to_afterwards.1.json b/contracts/escrow/test_snapshots/settled_escrow_cannot_be_refunded_to_refund_to_afterwards.1.json index 04e9364f..99c7c738 100644 --- a/contracts/escrow/test_snapshots/settled_escrow_cannot_be_refunded_to_refund_to_afterwards.1.json +++ b/contracts/escrow/test_snapshots/settled_escrow_cannot_be_refunded_to_refund_to_afterwards.1.json @@ -492,6 +492,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/single_caller_release_on_a_quorum_escrow_needs_the_approval_path.1.json b/contracts/escrow/test_snapshots/single_caller_release_on_a_quorum_escrow_needs_the_approval_path.1.json index 4bc0f663..74a3b306 100644 --- a/contracts/escrow/test_snapshots/single_caller_release_on_a_quorum_escrow_needs_the_approval_path.1.json +++ b/contracts/escrow/test_snapshots/single_caller_release_on_a_quorum_escrow_needs_the_approval_path.1.json @@ -460,6 +460,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/single_releaser_escrow_behaves_as_a_one_of_one_quorum.1.json b/contracts/escrow/test_snapshots/single_releaser_escrow_behaves_as_a_one_of_one_quorum.1.json index 4d9c3527..aeea5584 100644 --- a/contracts/escrow/test_snapshots/single_releaser_escrow_behaves_as_a_one_of_one_quorum.1.json +++ b/contracts/escrow/test_snapshots/single_releaser_escrow_behaves_as_a_one_of_one_quorum.1.json @@ -799,6 +799,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/the_beneficiary_refund_to_never_has_to_sign.1.json b/contracts/escrow/test_snapshots/the_beneficiary_refund_to_never_has_to_sign.1.json index e2de63b4..2089643d 100644 --- a/contracts/escrow/test_snapshots/the_beneficiary_refund_to_never_has_to_sign.1.json +++ b/contracts/escrow/test_snapshots/the_beneficiary_refund_to_never_has_to_sign.1.json @@ -443,6 +443,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_at_the_exact_deadline_goes_to_refund_to.1.json b/contracts/escrow/test_snapshots/timeout_refund_at_the_exact_deadline_goes_to_refund_to.1.json index 1c4b5ed2..8bb0ee3e 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_at_the_exact_deadline_goes_to_refund_to.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_at_the_exact_deadline_goes_to_refund_to.1.json @@ -471,6 +471,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_also_returns_the_full_amount_with_no_fee.1.json b/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_also_returns_the_full_amount_with_no_fee.1.json index f9e7e345..14cb25d9 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_also_returns_the_full_amount_with_no_fee.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_also_returns_the_full_amount_with_no_fee.1.json @@ -479,6 +479,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_goes_to_refund_to.1.json b/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_goes_to_refund_to.1.json index cd2bd071..cfcada9a 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_goes_to_refund_to.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_by_a_stranger_goes_to_refund_to.1.json @@ -474,6 +474,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_after_deadline.1.json b/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_after_deadline.1.json index 978a8de0..4d63db3c 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_after_deadline.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_after_deadline.1.json @@ -470,6 +470,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_at_the_exact_deadline.1.json b/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_at_the_exact_deadline.1.json index 703ca6a5..3987b9f5 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_at_the_exact_deadline.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_by_stranger_succeeds_at_the_exact_deadline.1.json @@ -471,6 +471,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_cannot_pay_anyone_but_the_payer.1.json b/contracts/escrow/test_snapshots/timeout_refund_cannot_pay_anyone_but_the_payer.1.json index 035770e2..f3d17c74 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_cannot_pay_anyone_but_the_payer.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_cannot_pay_anyone_but_the_payer.1.json @@ -470,6 +470,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_fails_after_release.1.json b/contracts/escrow/test_snapshots/timeout_refund_fails_after_release.1.json index 1a3446a9..8371050b 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_fails_after_release.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_fails_after_release.1.json @@ -491,6 +491,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_fails_after_releaser_refund.1.json b/contracts/escrow/test_snapshots/timeout_refund_fails_after_releaser_refund.1.json index 95dc24e4..c7d70015 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_fails_after_releaser_refund.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_fails_after_releaser_refund.1.json @@ -491,6 +491,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_op_opens_to_anyone_only_after_the_deadline.1.json b/contracts/escrow/test_snapshots/timeout_refund_op_opens_to_anyone_only_after_the_deadline.1.json index 854295fd..5f48bac5 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_op_opens_to_anyone_only_after_the_deadline.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_op_opens_to_anyone_only_after_the_deadline.1.json @@ -538,6 +538,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_rejected_before_deadline.1.json b/contracts/escrow/test_snapshots/timeout_refund_rejected_before_deadline.1.json index fc7dadc3..e9e68014 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_rejected_before_deadline.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_rejected_before_deadline.1.json @@ -449,6 +449,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_still_needs_no_approvals_on_a_quorum_escrow.1.json b/contracts/escrow/test_snapshots/timeout_refund_still_needs_no_approvals_on_a_quorum_escrow.1.json index ee6da607..458b0844 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_still_needs_no_approvals_on_a_quorum_escrow.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_still_needs_no_approvals_on_a_quorum_escrow.1.json @@ -487,6 +487,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_subtracts_from_liabilities.1.json b/contracts/escrow/test_snapshots/timeout_refund_subtracts_from_liabilities.1.json index c1fd5830..1cb023c1 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_subtracts_from_liabilities.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_subtracts_from_liabilities.1.json @@ -1052,6 +1052,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/timeout_refund_wins_at_the_deadline_and_release_then_fails.1.json b/contracts/escrow/test_snapshots/timeout_refund_wins_at_the_deadline_and_release_then_fails.1.json index 703ca6a5..3987b9f5 100644 --- a/contracts/escrow/test_snapshots/timeout_refund_wins_at_the_deadline_and_release_then_fails.1.json +++ b/contracts/escrow/test_snapshots/timeout_refund_wins_at_the_deadline_and_release_then_fails.1.json @@ -471,6 +471,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/token_without_a_cap_entry_is_rejected_when_caps_are_configured.1.json b/contracts/escrow/test_snapshots/token_without_a_cap_entry_is_rejected_when_caps_are_configured.1.json new file mode 100644 index 00000000..a5c63162 --- /dev/null +++ b/contracts/escrow/test_snapshots/token_without_a_cap_entry_is_rejected_when_caps_are_configured.1.json @@ -0,0 +1,517 @@ +{ + "generators": { + "address": 8, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": "100" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "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": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [ + { + "key": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + "val": { + "i128": "1000" + } + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "100" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000004" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/top_up_adds_funds_to_the_same_funded_escrow.1.json b/contracts/escrow/test_snapshots/top_up_adds_funds_to_the_same_funded_escrow.1.json index 05356740..ca41fd63 100644 --- a/contracts/escrow/test_snapshots/top_up_adds_funds_to_the_same_funded_escrow.1.json +++ b/contracts/escrow/test_snapshots/top_up_adds_funds_to_the_same_funded_escrow.1.json @@ -553,6 +553,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_adds_to_liabilities.1.json b/contracts/escrow/test_snapshots/top_up_adds_to_liabilities.1.json index 328e3784..5b603f85 100644 --- a/contracts/escrow/test_snapshots/top_up_adds_to_liabilities.1.json +++ b/contracts/escrow/test_snapshots/top_up_adds_to_liabilities.1.json @@ -1092,6 +1092,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_after_cancel_is_rejected.1.json b/contracts/escrow/test_snapshots/top_up_after_cancel_is_rejected.1.json index 8bdffa97..c2ee7177 100644 --- a/contracts/escrow/test_snapshots/top_up_after_cancel_is_rejected.1.json +++ b/contracts/escrow/test_snapshots/top_up_after_cancel_is_rejected.1.json @@ -482,6 +482,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_before_accept_is_fully_returned_by_cancel.1.json b/contracts/escrow/test_snapshots/top_up_before_accept_is_fully_returned_by_cancel.1.json index cddbb326..0d07c06a 100644 --- a/contracts/escrow/test_snapshots/top_up_before_accept_is_fully_returned_by_cancel.1.json +++ b/contracts/escrow/test_snapshots/top_up_before_accept_is_fully_returned_by_cancel.1.json @@ -552,6 +552,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_cannot_raise_an_escrow_above_its_cap.1.json b/contracts/escrow/test_snapshots/top_up_cannot_raise_an_escrow_above_its_cap.1.json new file mode 100644 index 00000000..8439cc9f --- /dev/null +++ b/contracts/escrow/test_snapshots/top_up_cannot_raise_an_escrow_above_its_cap.1.json @@ -0,0 +1,779 @@ +{ + "generators": { + "address": 6, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "1000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "create_escrow", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + { + "i128": "300" + }, + { + "string": "cap-test" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + "void", + { + "bool": false + }, + "void", + "void", + "void" + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "300" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "top_up", + "args": [ + { + "u64": "0" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "200" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "200" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [], + [] + ], + "ledger": { + "protocol_version": 27, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Escrow" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "accepted_at" + }, + "val": "void" + }, + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "500" + } + }, + { + "key": { + "symbol": "condition_ref" + }, + "val": { + "string": "cap-test" + } + }, + { + "key": { + "symbol": "fee_bps" + }, + "val": "void" + }, + { + "key": { + "symbol": "fee_recipient" + }, + "val": "void" + }, + { + "key": { + "symbol": "notify_payee" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "payee" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "symbol": "payer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "refund_after" + }, + "val": "void" + }, + { + "key": { + "symbol": "refund_to" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "release_not_before" + }, + "val": "void" + }, + { + "key": { + "symbol": "releasers" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + { + "key": { + "symbol": "requires_acceptance" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + }, + { + "key": { + "symbol": "threshold" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "token" + }, + "val": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Liability" + }, + { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + } + ] + }, + "durability": "persistent", + "val": { + "i128": "500" + } + } + }, + "ext": "v0" + }, + "live_until": 2073600 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Status" + }, + { + "u64": "0" + } + ] + }, + "durability": "persistent", + "val": { + "vec": [ + { + "symbol": "Funded" + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "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": "AllowedTokens" + } + ] + }, + "val": { + "vec": [] + } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [ + { + "key": { + "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL" + }, + "val": { + "i128": "500" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextId" + } + ] + }, + "val": { + "u64": "1" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "500" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "500" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000002" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 4095 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/escrow/test_snapshots/top_up_emits_an_event.1.json b/contracts/escrow/test_snapshots/top_up_emits_an_event.1.json index 29a39263..20845745 100644 --- a/contracts/escrow/test_snapshots/top_up_emits_an_event.1.json +++ b/contracts/escrow/test_snapshots/top_up_emits_an_event.1.json @@ -507,6 +507,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_increases_the_fee_taken_at_release.1.json b/contracts/escrow/test_snapshots/top_up_increases_the_fee_taken_at_release.1.json index f37273fb..4931e308 100644 --- a/contracts/escrow/test_snapshots/top_up_increases_the_fee_taken_at_release.1.json +++ b/contracts/escrow/test_snapshots/top_up_increases_the_fee_taken_at_release.1.json @@ -561,6 +561,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_rejects_fee_math_overflow_before_transferring.1.json b/contracts/escrow/test_snapshots/top_up_rejects_fee_math_overflow_before_transferring.1.json index 76490df1..c2a0f8e9 100644 --- a/contracts/escrow/test_snapshots/top_up_rejects_fee_math_overflow_before_transferring.1.json +++ b/contracts/escrow/test_snapshots/top_up_rejects_fee_math_overflow_before_transferring.1.json @@ -452,6 +452,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/top_up_rejects_invalid_payer_amount_overflow_and_settled_state.1.json b/contracts/escrow/test_snapshots/top_up_rejects_invalid_payer_amount_overflow_and_settled_state.1.json index e76cba16..bcb8c6de 100644 --- a/contracts/escrow/test_snapshots/top_up_rejects_invalid_payer_amount_overflow_and_settled_state.1.json +++ b/contracts/escrow/test_snapshots/top_up_rejects_invalid_payer_amount_overflow_and_settled_state.1.json @@ -487,6 +487,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/two_escrows_keep_their_own_refund_to.1.json b/contracts/escrow/test_snapshots/two_escrows_keep_their_own_refund_to.1.json index bc78762b..d9bb0cd4 100644 --- a/contracts/escrow/test_snapshots/two_escrows_keep_their_own_refund_to.1.json +++ b/contracts/escrow/test_snapshots/two_escrows_keep_their_own_refund_to.1.json @@ -800,6 +800,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/unused_token_reports_zero.1.json b/contracts/escrow/test_snapshots/unused_token_reports_zero.1.json index 7d7b1cb7..4588d157 100644 --- a/contracts/escrow/test_snapshots/unused_token_reports_zero.1.json +++ b/contracts/escrow/test_snapshots/unused_token_reports_zero.1.json @@ -732,6 +732,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/version_reports_the_contract_semver.1.json b/contracts/escrow/test_snapshots/version_reports_the_contract_semver.1.json index cac7ef6d..d748f8a2 100644 --- a/contracts/escrow/test_snapshots/version_reports_the_contract_semver.1.json +++ b/contracts/escrow/test_snapshots/version_reports_the_contract_semver.1.json @@ -44,6 +44,18 @@ "val": { "vec": [] } + }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } } ] } diff --git a/contracts/escrow/test_snapshots/without_deadline_releaser_refund_still_works.1.json b/contracts/escrow/test_snapshots/without_deadline_releaser_refund_still_works.1.json index 9dd93fa4..94cf2b4b 100644 --- a/contracts/escrow/test_snapshots/without_deadline_releaser_refund_still_works.1.json +++ b/contracts/escrow/test_snapshots/without_deadline_releaser_refund_still_works.1.json @@ -485,6 +485,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/test_snapshots/without_deadline_stranger_refund_stays_unauthorized_even_forever_after.1.json b/contracts/escrow/test_snapshots/without_deadline_stranger_refund_stays_unauthorized_even_forever_after.1.json index bf66c975..c311fc2d 100644 --- a/contracts/escrow/test_snapshots/without_deadline_stranger_refund_stays_unauthorized_even_forever_after.1.json +++ b/contracts/escrow/test_snapshots/without_deadline_stranger_refund_stays_unauthorized_even_forever_after.1.json @@ -445,6 +445,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/escrow/tests/cancel.rs b/contracts/escrow/tests/cancel.rs index 7461e12a..1eee95ea 100644 --- a/contracts/escrow/tests/cancel.rs +++ b/contracts/escrow/tests/cancel.rs @@ -42,7 +42,13 @@ fn fund<'a>(env: &'a Env, requires_acceptance: bool, refund_after: Option) let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let condition = String::from_str(env, "opaque-condition-ref"); let escrow_id = if requires_acceptance { @@ -73,7 +79,15 @@ fn fund<'a>(env: &'a Env, requires_acceptance: bool, refund_after: Option) ) }; - Fixture { client, token, contract_id, payer, payee, releaser, escrow_id } + Fixture { + client, + token, + contract_id, + payer, + payee, + releaser, + escrow_id, + } } fn assert_unchanged_funded(f: &Fixture) { @@ -189,11 +203,7 @@ fn only_the_stored_payer_may_cancel() { env.mock_all_auths(); let f = fund(&env, true, None); - for impostor in [ - Address::generate(&env), - f.payee.clone(), - f.releaser.clone(), - ] { + for impostor in [Address::generate(&env), f.payee.clone(), f.releaser.clone()] { assert_eq!( f.client.try_cancel(&f.escrow_id, &impostor), Err(Ok(Error::Unauthorized)) @@ -241,7 +251,9 @@ fn escrow_without_requires_acceptance_still_releases_and_refunds_as_before() { env.mock_all_auths(); let released = fund(&env, false, None); - released.client.release(&released.escrow_id, &released.releaser); + released + .client + .release(&released.escrow_id, &released.releaser); assert_eq!(released.token.balance(&released.payee), 300); assert_eq!( released.client.get_status(&released.escrow_id), @@ -249,7 +261,9 @@ fn escrow_without_requires_acceptance_still_releases_and_refunds_as_before() { ); let refunded = fund(&env, false, None); - refunded.client.refund(&refunded.escrow_id, &refunded.releaser); + refunded + .client + .refund(&refunded.escrow_id, &refunded.releaser); assert_eq!(refunded.token.balance(&refunded.payer), 1_000); assert_eq!( refunded.client.get_status(&refunded.escrow_id), @@ -390,7 +404,10 @@ fn top_up_before_accept_is_fully_returned_by_cancel() { assert_eq!(f.token.balance(&f.payer), 1_000); assert_eq!(f.token.balance(&f.payee), 0); assert_eq!(f.token.balance(&f.contract_id), 0); - assert_eq!(f.client.get_escrow(&f.escrow_id).status, EscrowStatus::Cancelled); + assert_eq!( + f.client.get_escrow(&f.escrow_id).status, + EscrowStatus::Cancelled + ); } #[test] diff --git a/contracts/escrow/tests/create_escrow.rs b/contracts/escrow/tests/create_escrow.rs index 3c381de1..c4694474 100644 --- a/contracts/escrow/tests/create_escrow.rs +++ b/contracts/escrow/tests/create_escrow.rs @@ -7,7 +7,7 @@ use docforum_escrow::{EscrowContract, EscrowContractClient, EscrowStatus}; use soroban_sdk::{ testutils::{Address as _, Events as _, MockAuth, MockAuthInvoke}, token::{StellarAssetClient, TokenClient}, - Address, Env, IntoVal, String, Vec, + Address, Env, IntoVal, Map, String, Vec, }; fn setup<'a>(env: &Env) -> (Address, TokenClient<'a>, StellarAssetClient<'a>) { @@ -21,10 +21,13 @@ fn setup<'a>(env: &Env) -> (Address, TokenClient<'a>, StellarAssetClient<'a>) { #[test] fn version_reports_the_contract_semver() { let env = Env::default(); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + (Vec::
::new(&env), Map::::new(&env)), + ); let client = EscrowContractClient::new(&env, &contract_id); - assert_eq!(client.version(), String::from_str(&env, "2.2.0")); + assert_eq!(client.version(), String::from_str(&env, "2.5.0")); } #[test] @@ -38,7 +41,13 @@ fn create_escrow_locks_funds_and_reports_funded() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let escrow_id = client.create_escrow( @@ -80,7 +89,13 @@ fn create_escrow_assigns_sequential_ids() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let first = client.create_escrow( @@ -124,7 +139,13 @@ fn create_escrow_rejects_non_positive_amount() { let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_create_escrow( @@ -148,7 +169,13 @@ fn get_status_errors_for_unknown_escrow() { let env = Env::default(); env.mock_all_auths(); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_get_status(&999); @@ -166,7 +193,13 @@ fn create_escrow_rejects_condition_ref_that_is_too_long() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); // 64 bytes is accepted (the bound is inclusive). @@ -218,7 +251,13 @@ fn callback_opt_in_requires_payee_authorization() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let condition_ref = String::from_str(&env, "payee-opt-in-auth"); let invoke = MockAuthInvoke { diff --git a/contracts/escrow/tests/liabilities.proptest-regressions b/contracts/escrow/tests/liabilities.proptest-regressions new file mode 100644 index 00000000..1de4d992 --- /dev/null +++ b/contracts/escrow/tests/liabilities.proptest-regressions @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 29be6d02ccd22a68dedfcdb9a54d632d2479359347403040cf2129bfdad7bf80 # shrinks to ops = [Create { token: 0, amount: -1, timeout: false }] diff --git a/contracts/escrow/tests/liabilities.rs b/contracts/escrow/tests/liabilities.rs index fd14e6aa..3ae6fc1a 100644 --- a/contracts/escrow/tests/liabilities.rs +++ b/contracts/escrow/tests/liabilities.rs @@ -33,7 +33,7 @@ use proptest::prelude::*; use soroban_sdk::{ testutils::{storage::Persistent as _, Address as _, Ledger as _}, token::StellarAssetClient, - Address, Env, String, Symbol, Vec, + Address, Env, Map, String, Symbol, Vec, }; const CREATED_AT: u64 = 1_000; @@ -80,7 +80,10 @@ fn fixture(env: &Env) -> Fixture<'_> { let tokens = [new_token(env), new_token(env)]; let unused = new_token(env); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + (Vec::
::new(env), Map::::new(env)), + ); Fixture { env, client: EscrowContractClient::new(env, &contract_id), @@ -168,7 +171,11 @@ impl<'a> Fixture<'a> { fn assert_invariant(&self) { for t in 0..TOKENS { let (balance, liabilities) = self.client.solvency(&self.tokens[t]); - assert_eq!(liabilities, self.funded_sum(t), "liabilities drifted for token {t}"); + assert_eq!( + liabilities, + self.funded_sum(t), + "liabilities drifted for token {t}" + ); assert!(liabilities >= 0); assert_eq!(balance, liabilities, "balance != liabilities for token {t}"); } @@ -211,7 +218,15 @@ fn creation_paths_add_to_liabilities() { &None, ); f.client.create_escrow_with_acceptance( - &f.payer, &f.payee, &f.tokens[0], &30, &f.cond(), &f.releaser, &None, &true, &None, + &f.payer, + &f.payee, + &f.tokens[0], + &30, + &f.cond(), + &f.releaser, + &None, + &true, + &None, ); f.client.create_escrow_with_releasers( &f.payer, @@ -329,9 +344,15 @@ fn settle_many_subtracts_each_release() { let b = f.create(0, 20); f.create(1, 30); // One id per call; see `creation_paths_add_to_liabilities` for why. - f.client.settle_many(&f.releaser, &soroban_sdk::vec![&env, (a, SettleAction::Release)]); + f.client.settle_many( + &f.releaser, + &soroban_sdk::vec![&env, (a, SettleAction::Release)], + ); assert_eq!(f.liabilities(0), 20); - f.client.settle_many(&f.releaser, &soroban_sdk::vec![&env, (b, SettleAction::Release)]); + f.client.settle_many( + &f.releaser, + &soroban_sdk::vec![&env, (b, SettleAction::Release)], + ); assert_eq!(f.liabilities(0), 0); assert_eq!(f.liabilities(1), 30); f.assert_invariant(); @@ -342,7 +363,15 @@ fn cancel_subtracts_from_liabilities() { let env = Env::default(); let f = fixture(&env); let id = f.client.create_escrow_with_acceptance( - &f.payer, &f.payee, &f.tokens[0], &45, &f.cond(), &f.releaser, &None, &true, &None, + &f.payer, + &f.payee, + &f.tokens[0], + &45, + &f.cond(), + &f.releaser, + &None, + &true, + &None, ); assert_eq!(f.liabilities(0), 45); f.client.cancel(&id, &f.payer); @@ -415,7 +444,10 @@ fn liability_entry_ttl_is_extended_on_write() { f.create(0, 100); let key = (Symbol::new(&env, "Liability"), f.tokens[0].clone()); let (ttl, max_ttl) = env.as_contract(&f.client.address, || { - (env.storage().persistent().get_ttl(&key), env.storage().max_ttl()) + ( + env.storage().persistent().get_ttl(&key), + env.storage().max_ttl(), + ) }); let expected = docforum_escrow::LIABILITY_TTL_EXTEND_TO.min(max_ttl); assert_eq!(ttl, expected); @@ -431,24 +463,72 @@ fn liability_entry_ttl_is_extended_on_write() { #[derive(Debug, Clone, Copy)] enum Op { - Create { token: usize, amount: i128, timeout: bool }, - CreateTimed { token: usize, amount: i128 }, - CreateAcceptance { token: usize, amount: i128 }, - CreateQuorum { token: usize, amount: i128 }, - CreateBatch { token: usize, amount: i128 }, - CreatePooled { token: usize, target: i128 }, - TopUp { pick: usize, amount: i128 }, - Contribute { pick: usize, who: usize, amount: i128 }, - Accept { pick: usize }, - Rotate { pick: usize }, - Release { pick: usize }, - ReleaseQuorum { pick: usize }, - SettleMany { pick: usize }, - Refund { pick: usize, stranger: bool }, - RefundQuorum { pick: usize }, - Cancel { pick: usize }, - ClaimRefund { pick: usize, who: usize }, - Advance { seconds: u64 }, + Create { + token: usize, + amount: i128, + timeout: bool, + }, + CreateTimed { + token: usize, + amount: i128, + }, + CreateAcceptance { + token: usize, + amount: i128, + }, + CreateQuorum { + token: usize, + amount: i128, + }, + CreateBatch { + token: usize, + amount: i128, + }, + CreatePooled { + token: usize, + target: i128, + }, + TopUp { + pick: usize, + amount: i128, + }, + Contribute { + pick: usize, + who: usize, + amount: i128, + }, + Accept { + pick: usize, + }, + Rotate { + pick: usize, + }, + Release { + pick: usize, + }, + ReleaseQuorum { + pick: usize, + }, + SettleMany { + pick: usize, + }, + Refund { + pick: usize, + stranger: bool, + }, + RefundQuorum { + pick: usize, + }, + Cancel { + pick: usize, + }, + ClaimRefund { + pick: usize, + who: usize, + }, + Advance { + seconds: u64, + }, } /// A test env that writes no snapshot per randomized case (issue #120). @@ -472,8 +552,13 @@ fn arb_amount() -> impl Strategy { fn arb_op() -> impl Strategy { let pick = 0usize..64; prop_oneof![ - (arb_token(), arb_amount(), any::()) - .prop_map(|(token, amount, timeout)| Op::Create { token, amount, timeout }), + (arb_token(), arb_amount(), any::()).prop_map(|(token, amount, timeout)| { + Op::Create { + token, + amount, + timeout, + } + }), (arb_token(), arb_amount()).prop_map(|(token, amount)| Op::CreateTimed { token, amount }), (arb_token(), arb_amount()) .prop_map(|(token, amount)| Op::CreateAcceptance { token, amount }), @@ -512,7 +597,11 @@ fn apply(f: &Fixture, op: Op) { let env = f.env; let now = env.ledger().timestamp(); match op { - Op::Create { token, amount, timeout } => { + Op::Create { + token, + amount, + timeout, + } => { let refund_after = timeout.then_some(now + 100); let _ = f.client.try_create_escrow( &f.payer, @@ -580,7 +669,9 @@ fn apply(f: &Fixture, op: Op) { releaser: f.releaser.clone(), refund_after: None, }; - let _ = f.client.try_create_escrows(&f.payer, &soroban_sdk::vec![env, item]); + let _ = f + .client + .try_create_escrows(&f.payer, &soroban_sdk::vec![env, item]); } Op::CreatePooled { token, target } => { let _ = f.client.try_create_pooled_escrow( @@ -611,7 +702,9 @@ fn apply(f: &Fixture, op: Op) { Op::Rotate { pick } => { if let Some(id) = existing_id(f, pick) { let new_releaser = Address::generate(env); - let _ = f.client.try_rotate_releaser(&id, &f.releaser, &new_releaser); + let _ = f + .client + .try_rotate_releaser(&id, &f.releaser, &new_releaser); } } Op::Release { pick } => { @@ -626,12 +719,19 @@ fn apply(f: &Fixture, op: Op) { } Op::SettleMany { pick } => { if let Some(id) = existing_id(f, pick) { - let _ = f.client.try_settle_many(&f.releaser, &soroban_sdk::vec![env, (id, SettleAction::Release)]); + let _ = f.client.try_settle_many( + &f.releaser, + &soroban_sdk::vec![env, (id, SettleAction::Release)], + ); } } Op::Refund { pick, stranger } => { if let Some(id) = existing_id(f, pick) { - let caller = if stranger { Address::generate(env) } else { f.releaser.clone() }; + let caller = if stranger { + Address::generate(env) + } else { + f.releaser.clone() + }; let _ = f.client.try_refund(&id, &caller); } } diff --git a/contracts/escrow/tests/malicious_token.rs b/contracts/escrow/tests/malicious_token.rs index dab8ea8a..9ef340f6 100644 --- a/contracts/escrow/tests/malicious_token.rs +++ b/contracts/escrow/tests/malicious_token.rs @@ -198,7 +198,13 @@ fn create_escrow_rejects_lying_transfer() { let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_create_escrow( @@ -236,7 +242,13 @@ fn create_escrow_rejects_short_delivery() { let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_create_escrow( @@ -278,7 +290,13 @@ fn failed_payout_leaves_the_escrow_funded() { let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let escrow_id = client.create_escrow( @@ -316,7 +334,13 @@ fn reentrant_transfer_cannot_double_release() { let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); // Creating with this token is fine: the transfer in is honest, and @@ -387,18 +411,16 @@ fn contribute_rejects_lying_transfer() { let creator = Address::generate(&env); let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); - let escrow_id = pooled_id( - &client, - &env, - &token_id, - &creator, - &payee, - &releaser, - 300, - ); + let escrow_id = pooled_id(&client, &env, &token_id, &creator, &payee, &releaser, 300); let result = client.try_contribute(&escrow_id, &payer, &100); @@ -425,18 +447,16 @@ fn contribute_rejects_short_delivery() { let creator = Address::generate(&env); let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); - let escrow_id = pooled_id( - &client, - &env, - &token_id, - &creator, - &payee, - &releaser, - 300, - ); + let escrow_id = pooled_id(&client, &env, &token_id, &creator, &payee, &releaser, 300); let result = client.try_contribute(&escrow_id, &payer, &100); @@ -464,18 +484,16 @@ fn failed_claim_leaves_the_contribution_intact() { let creator = Address::generate(&env); let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); - let escrow_id = pooled_id( - &client, - &env, - &token_id, - &creator, - &payee, - &releaser, - 300, - ); + let escrow_id = pooled_id(&client, &env, &token_id, &creator, &payee, &releaser, 300); // Honest funding in; only the outbound payout leg is armed later. client.contribute(&escrow_id, &payer, &300); token.arm(); diff --git a/contracts/escrow/tests/model.rs b/contracts/escrow/tests/model.rs index 02509ac6..c882d6ce 100644 --- a/contracts/escrow/tests/model.rs +++ b/contracts/escrow/tests/model.rs @@ -160,7 +160,11 @@ impl Model { } fn expected_payer_balance(&self) -> i128 { - let refunded = if self.phase == Phase::Refunded { self.amount } else { 0 }; + let refunded = if self.phase == Phase::Refunded { + self.amount + } else { + 0 + }; INITIAL_BALANCE - self.paid_in + refunded } } @@ -208,7 +212,13 @@ fn fixture<'a>(env: &'a Env, amount: i128, refund_after: Option) -> Fixture let stranger = Address::generate(env); asset.mint(&payer, &INITIAL_BALANCE); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let escrow_id = client.create_escrow( &payer, @@ -264,7 +274,11 @@ fn call(env: &Env, f: &Fixture, op: Op) -> Predicted { other => panic!("top_up: unexpected result {other:?}"), }, Op::Release { as_releaser } => { - let caller = if as_releaser { &f.releaser } else { &f.stranger }; + let caller = if as_releaser { + &f.releaser + } else { + &f.stranger + }; match f.client.try_release(&f.escrow_id, caller) { Ok(Ok(())) => Ok(()), Err(Ok(Error::NotFunded)) => Err(Failure::NotFunded), @@ -273,7 +287,11 @@ fn call(env: &Env, f: &Fixture, op: Op) -> Predicted { } } Op::Refund { as_releaser } => { - let caller = if as_releaser { &f.releaser } else { &f.stranger }; + let caller = if as_releaser { + &f.releaser + } else { + &f.stranger + }; match f.client.try_refund(&f.escrow_id, caller) { Ok(Ok(())) => Ok(()), Err(Ok(Error::NotFunded)) => Err(Failure::NotFunded), diff --git a/contracts/escrow/tests/payee_acceptance.rs b/contracts/escrow/tests/payee_acceptance.rs index d872055b..d2c45da0 100644 --- a/contracts/escrow/tests/payee_acceptance.rs +++ b/contracts/escrow/tests/payee_acceptance.rs @@ -26,7 +26,13 @@ fn setup(env: &Env) -> Fixture<'_> { let payee = Address::generate(env); let releaser = Address::generate(env); asset.mint(&payer, &500); - let contract_id = env.register(EscrowContract, (soroban_sdk::Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + soroban_sdk::Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let id = client.create_escrow_with_acceptance( &payer, @@ -89,7 +95,13 @@ fn legacy_creation_keeps_acceptance_opt_out() { let payee = Address::generate(&env); let releaser = Address::generate(&env); StellarAssetClient::new(&env, &token_id).mint(&payer, &100); - let contract_id = env.register(EscrowContract, (soroban_sdk::Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + soroban_sdk::Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let id = client.create_escrow( &payer, diff --git a/contracts/escrow/tests/pooled.rs b/contracts/escrow/tests/pooled.rs index afb15bc4..ab51de48 100644 --- a/contracts/escrow/tests/pooled.rs +++ b/contracts/escrow/tests/pooled.rs @@ -58,7 +58,13 @@ fn setup(env: &Env, target: i128) -> Fixture<'_> { let payee = Address::generate(env); let releaser = Address::generate(env); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let id = client.create_pooled_escrow( &creator, @@ -312,7 +318,11 @@ fn run_refund_order(order: [u8; 3]) -> [i128; 3] { } assert_eq!(f.token.balance(&f.contract_id), 0); - [f.token.balance(&a), f.token.balance(&b), f.token.balance(&c)] + [ + f.token.balance(&a), + f.token.balance(&b), + f.token.balance(&c), + ] } #[test] @@ -461,33 +471,63 @@ fn pooled_creation_validation() { let creator = Address::generate(&env); let payee = Address::generate(&env); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let ref_str = String::from_str(&env, "pooled"); // Non-positive targets. assert_eq!( client.try_create_pooled_escrow( - &creator, &payee, &token_id, &0, &ref_str, &releaser, &(DEADLINE) + &creator, + &payee, + &token_id, + &0, + &ref_str, + &releaser, + &(DEADLINE) ), Err(Ok(Error::InvalidAmount)) ); assert_eq!( client.try_create_pooled_escrow( - &creator, &payee, &token_id, &-1, &ref_str, &releaser, &(DEADLINE) + &creator, + &payee, + &token_id, + &-1, + &ref_str, + &releaser, + &(DEADLINE) ), Err(Ok(Error::InvalidAmount)) ); // A deadline that is not strictly in the future. assert_eq!( client.try_create_pooled_escrow( - &creator, &payee, &token_id, &100, &ref_str, &releaser, &CREATED_AT + &creator, + &payee, + &token_id, + &100, + &ref_str, + &releaser, + &CREATED_AT ), Err(Ok(Error::InvalidFundingDeadline)) ); assert_eq!( client.try_create_pooled_escrow( - &creator, &payee, &token_id, &100, &ref_str, &releaser, &(CREATED_AT - 1) + &creator, + &payee, + &token_id, + &100, + &ref_str, + &releaser, + &(CREATED_AT - 1) ), Err(Ok(Error::InvalidFundingDeadline)) ); @@ -529,7 +569,13 @@ fn pooled_creation_respects_the_token_allowlist() { let mut allowlist = Vec::new(&env); allowlist.push_back(allowed.clone()); - let contract_id = env.register(EscrowContract, (allowlist,)); + let contract_id = env.register( + EscrowContract, + ( + allowlist, + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); assert_eq!( @@ -719,7 +765,13 @@ fn ordinary_escrows_are_unaffected() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let id = client.create_escrow( &payer, @@ -828,5 +880,3 @@ fn claim_refund_emits_an_event() { ] ); } - - diff --git a/contracts/escrow/tests/protocol_fee.rs b/contracts/escrow/tests/protocol_fee.rs index 381969d4..7f3f02a6 100644 --- a/contracts/escrow/tests/protocol_fee.rs +++ b/contracts/escrow/tests/protocol_fee.rs @@ -23,7 +23,7 @@ use docforum_escrow::{Error, EscrowContract, EscrowContractClient, EscrowStatus, use soroban_sdk::{ testutils::{Address as _, Ledger as _}, token::{StellarAssetClient, TokenClient}, - Address, Env, String, Vec, + Address, Env, Map, String, Vec, }; const CREATED_AT: u64 = 1_000; @@ -40,7 +40,10 @@ fn setup<'a>(env: &Env) -> (Address, TokenClient<'a>, StellarAssetClient<'a>) { } fn deploy(env: &Env) -> (Address, EscrowContractClient<'_>) { - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + (Vec::
::new(env), Map::::new(env)), + ); ( contract_id.clone(), EscrowContractClient::new(env, &contract_id), diff --git a/contracts/escrow/tests/quorum.rs b/contracts/escrow/tests/quorum.rs index f8a388a5..3c631b2f 100644 --- a/contracts/escrow/tests/quorum.rs +++ b/contracts/escrow/tests/quorum.rs @@ -54,7 +54,13 @@ fn quorum_escrow( let payee = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let releasers = releaser_set(env, count); @@ -474,7 +480,13 @@ fn single_releaser_escrow_behaves_as_a_one_of_one_quorum() { let releaser = Address::generate(&env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let first = client.create_escrow( @@ -526,7 +538,13 @@ fn empty_fixture<'a>(env: &'a Env) -> (EscrowContractClient<'a>, Address, Addres let asset = StellarAssetClient::new(env, &token_id); let payer = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); (client, token_id, payer) } diff --git a/contracts/escrow/tests/release_callback.rs b/contracts/escrow/tests/release_callback.rs index 73087e1b..56bdc0e5 100644 --- a/contracts/escrow/tests/release_callback.rs +++ b/contracts/escrow/tests/release_callback.rs @@ -164,7 +164,13 @@ fn fixture(env: &Env) -> Fixture<'_> { let hook_id = env.register(PayeeHook, ()); let hook = PayeeHookClient::new(&env, &hook_id); - let escrow_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let escrow_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let escrow = EscrowContractClient::new(&env, &escrow_id); let id = escrow.create_escrow( &payer, @@ -216,7 +222,13 @@ fn quorum_release_invokes_opted_in_contract_payee() { asset.mint(&payer, &1_000); let hook_id = env.register(PayeeHook, ()); let hook = PayeeHookClient::new(&env, &hook_id); - let escrow_id = env.register(EscrowContract, (soroban_sdk::Vec::
::new(&env),)); + let escrow_id = env.register( + EscrowContract, + ( + soroban_sdk::Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let escrow = EscrowContractClient::new(&env, &escrow_id); let id = escrow.create_escrow_with_releasers( &payer, diff --git a/contracts/escrow/tests/release_refund.rs b/contracts/escrow/tests/release_refund.rs index 29d95e7c..125513e4 100644 --- a/contracts/escrow/tests/release_refund.rs +++ b/contracts/escrow/tests/release_refund.rs @@ -37,7 +37,13 @@ fn fund_escrow(env: &Env, amount: i128) -> Fixture<'_> { let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let escrow_id = client.create_escrow( diff --git a/contracts/escrow/tests/releaser_rotation.rs b/contracts/escrow/tests/releaser_rotation.rs index 19f1746f..99bad4c3 100644 --- a/contracts/escrow/tests/releaser_rotation.rs +++ b/contracts/escrow/tests/releaser_rotation.rs @@ -24,7 +24,13 @@ fn funded_escrow( let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let id = client.create_escrow( &payer, diff --git a/contracts/escrow/tests/settle_many.rs b/contracts/escrow/tests/settle_many.rs index c30a8757..cf7cd80e 100644 --- a/contracts/escrow/tests/settle_many.rs +++ b/contracts/escrow/tests/settle_many.rs @@ -14,7 +14,7 @@ use soroban_sdk::{ contract, contracterror, contractimpl, testutils::{Address as _, Events as _, Ledger as _}, token::{StellarAssetClient, TokenClient}, - Address, Env, String, Vec, + Address, Env, Map, String, Vec, }; const CREATED_AT: u64 = 1_000; @@ -56,7 +56,10 @@ fn fixture(env: &Env) -> Fixture<'_> { .address(); let payer = Address::generate(env); StellarAssetClient::new(env, &token_id).mint(&payer, &1_000_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + (Vec::
::new(env), Map::::new(env)), + ); Fixture { env, client: EscrowContractClient::new(env, &contract_id), diff --git a/contracts/escrow/tests/sponsored_refund.rs b/contracts/escrow/tests/sponsored_refund.rs index 3097e7d5..0b270437 100644 --- a/contracts/escrow/tests/sponsored_refund.rs +++ b/contracts/escrow/tests/sponsored_refund.rs @@ -47,7 +47,13 @@ fn fund<'a>(env: &'a Env, distinct_refund_to: bool, refund_after: Option) - let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let (refund_to, arg) = if distinct_refund_to { @@ -292,7 +298,13 @@ fn explicit_refund_to_equal_to_payer_behaves_like_the_default() { let payer = Address::generate(&env); StellarAssetClient::new(&env, &sac.address()).mint(&payer, &1_000); let releaser = Address::generate(&env); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let id = client.create_escrow( @@ -324,7 +336,13 @@ fn create_escrow_rejects_the_contract_as_refund_to() { let token = TokenClient::new(&env, &sac.address()); let payer = Address::generate(&env); StellarAssetClient::new(&env, &sac.address()).mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_create_escrow( @@ -359,7 +377,13 @@ fn create_escrow_with_refund_to_requires_the_funders_auth() { let payer = Address::generate(&env); env.mock_all_auths(); StellarAssetClient::new(&env, &sac.address()).mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); // Drop every mocked auth: nobody signed, so creation must fail even diff --git a/contracts/escrow/tests/time_locked_release.rs b/contracts/escrow/tests/time_locked_release.rs index 6f0d4adf..4b1dc7fc 100644 --- a/contracts/escrow/tests/time_locked_release.rs +++ b/contracts/escrow/tests/time_locked_release.rs @@ -36,7 +36,13 @@ fn setup<'a>(env: &Env, release_at: Option, refund_at: Option) -> Fixt let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (soroban_sdk::Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + soroban_sdk::Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let escrow_id = client.create_escrow_release_time( &payer, @@ -109,7 +115,13 @@ fn creation_rejects_release_time_in_the_past_or_after_refund_deadline() { let releaser = Address::generate(&env); let asset = StellarAssetClient::new(&env, &token_id); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (soroban_sdk::Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + soroban_sdk::Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let past = client.try_create_escrow_release_time( diff --git a/contracts/escrow/tests/timeout_refund.rs b/contracts/escrow/tests/timeout_refund.rs index 050b231c..788fb7f4 100644 --- a/contracts/escrow/tests/timeout_refund.rs +++ b/contracts/escrow/tests/timeout_refund.rs @@ -49,7 +49,13 @@ fn fund_escrow(env: &Env, refund_after: Option) -> Fixture<'_> { let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let escrow_id = client.create_escrow( @@ -122,7 +128,13 @@ fn create_escrow_rejects_deadline_already_passed_or_now() { asset.mint(&payer, &1_000); env.ledger().set_timestamp(CREATED_AT); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let now = client.try_create_escrow( @@ -387,7 +399,13 @@ fn get_escrow_errors_for_unknown_escrow() { let env = Env::default(); env.mock_all_auths(); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); let result = client.try_get_escrow(&999); diff --git a/contracts/escrow/tests/token_allowlist.rs b/contracts/escrow/tests/token_allowlist.rs index 2f79b911..009dcdf6 100644 --- a/contracts/escrow/tests/token_allowlist.rs +++ b/contracts/escrow/tests/token_allowlist.rs @@ -50,7 +50,13 @@ fn configured_allowlist_accepts_listed_token_and_rejects_unlisted_token() { let mut allowlist = Vec::new(&env); allowlist.push_back(allowed_token.clone()); - let contract_id = env.register(EscrowContract, (allowlist,)); + let contract_id = env.register( + EscrowContract, + ( + allowlist, + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); assert_eq!(create_escrow(&env, &client, &allowed_token, &payer), 0); @@ -79,7 +85,13 @@ fn empty_allowlist_preserves_open_token_behavior() { let payer = Address::generate(&env); asset.mint(&payer, &100); - let contract_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(&env), + soroban_sdk::Map::::new(&env), + ), + ); let client = EscrowContractClient::new(&env, &contract_id); assert_eq!(create_escrow(&env, &client, &token, &payer), 0); diff --git a/contracts/escrow/tests/token_caps.rs b/contracts/escrow/tests/token_caps.rs new file mode 100644 index 00000000..847f51f9 --- /dev/null +++ b/contracts/escrow/tests/token_caps.rs @@ -0,0 +1,187 @@ +// Deploy-time immutable per-token escrow caps (issue #56, docs/adr/0013). + +use docforum_escrow::{CreateItem, Error, EscrowContract, EscrowContractClient}; +use soroban_sdk::{ + testutils::{Address as _, Ledger}, + token::{StellarAssetClient, TokenClient}, + Address, Env, Map, String, Vec, +}; + +fn create_token<'a>(env: &'a Env) -> (Address, TokenClient<'a>, StellarAssetClient<'a>) { + let admin = Address::generate(env); + let contract_id = env.register_stellar_asset_contract_v2(admin); + ( + contract_id.address(), + TokenClient::new(env, &contract_id.address()), + StellarAssetClient::new(env, &contract_id.address()), + ) +} + +fn register_with_cap(env: &Env, token: &Address, maximum: i128) -> Address { + let mut caps = Map::new(env); + caps.set(token.clone(), maximum); + env.register(EscrowContract, (Vec::
::new(env), caps)) +} + +fn try_create( + env: &Env, + client: &EscrowContractClient<'_>, + token: &Address, + payer: &Address, + amount: i128, +) -> Result { + match client.try_create_escrow( + payer, + &Address::generate(env), + token, + &amount, + &String::from_str(env, "cap-test"), + &Address::generate(env), + &None, + &false, + &None, + &None, + &None, + ) { + Ok(Ok(id)) => Ok(id), + Err(Ok(e)) => Err(e), + other => panic!("unexpected result: {other:?}"), + } +} + +#[test] +fn create_accepts_amount_at_cap_and_rejects_amount_over_cap() { + let env = Env::default(); + env.mock_all_auths(); + let (token, token_client, asset) = create_token(&env); + let payer = Address::generate(&env); + asset.mint(&payer, &1_000); + let contract_id = register_with_cap(&env, &token, 300); + let client = EscrowContractClient::new(&env, &contract_id); + + assert_eq!(try_create(&env, &client, &token, &payer, 300), Ok(0)); + assert_eq!( + try_create(&env, &client, &token, &payer, 301), + Err(Error::AmountCapExceeded) + ); + // The rejected call moved nothing. + assert_eq!(token_client.balance(&payer), 700); +} + +#[test] +fn token_without_a_cap_entry_is_rejected_when_caps_are_configured() { + let env = Env::default(); + env.mock_all_auths(); + let (capped, _, _) = create_token(&env); + let (uncapped, _, uncapped_asset) = create_token(&env); + let payer = Address::generate(&env); + uncapped_asset.mint(&payer, &100); + let contract_id = register_with_cap(&env, &capped, 1_000); + let client = EscrowContractClient::new(&env, &contract_id); + + assert_eq!( + try_create(&env, &client, &uncapped, &payer, 1), + Err(Error::TokenCapNotConfigured) + ); +} + +#[test] +fn empty_cap_map_preserves_uncapped_behavior() { + let env = Env::default(); + env.mock_all_auths(); + let (token, _, asset) = create_token(&env); + let payer = Address::generate(&env); + asset.mint(&payer, &1_000_000); + let contract_id = env.register( + EscrowContract, + (Vec::
::new(&env), Map::::new(&env)), + ); + let client = EscrowContractClient::new(&env, &contract_id); + + assert_eq!(try_create(&env, &client, &token, &payer, 1_000_000), Ok(0)); +} + +#[test] +fn top_up_cannot_raise_an_escrow_above_its_cap() { + let env = Env::default(); + env.mock_all_auths(); + let (token, token_client, asset) = create_token(&env); + let payer = Address::generate(&env); + asset.mint(&payer, &1_000); + let contract_id = register_with_cap(&env, &token, 500); + let client = EscrowContractClient::new(&env, &contract_id); + let id = try_create(&env, &client, &token, &payer, 300).unwrap(); + + client.top_up(&id, &payer, &200); + assert_eq!( + client.try_top_up(&id, &payer, &1), + Err(Ok(Error::AmountCapExceeded)) + ); + assert_eq!(client.get_escrow(&id).amount, 500); + assert_eq!(token_client.balance(&payer), 500); +} + +#[test] +fn batch_creation_checks_every_item_and_is_atomic() { + let env = Env::default(); + env.mock_all_auths(); + let (token, token_client, asset) = create_token(&env); + let payer = Address::generate(&env); + asset.mint(&payer, &1_000); + let contract_id = register_with_cap(&env, &token, 200); + let client = EscrowContractClient::new(&env, &contract_id); + + let item = |amount: i128| CreateItem { + payee: Address::generate(&env), + token: token.clone(), + amount, + condition_ref: String::from_str(&env, "batch-cap"), + releaser: Address::generate(&env), + refund_after: None, + }; + let mut items = Vec::new(&env); + items.push_back(item(200)); + items.push_back(item(201)); + + assert_eq!( + client.try_create_escrows(&payer, &items), + Err(Ok(Error::AmountCapExceeded)) + ); + assert_eq!(token_client.balance(&payer), 1_000); +} + +#[test] +fn pooled_funding_target_is_capped() { + let env = Env::default(); + env.mock_all_auths(); + env.ledger().set_timestamp(1_000); + let (token, _, _) = create_token(&env); + let contract_id = register_with_cap(&env, &token, 500); + let client = EscrowContractClient::new(&env, &contract_id); + let create = |target: i128| { + client.try_create_pooled_escrow( + &Address::generate(&env), + &Address::generate(&env), + &token, + &target, + &String::from_str(&env, "pooled-cap"), + &Address::generate(&env), + &2_000, + ) + }; + + assert!(create(500).is_ok()); + assert_eq!(create(501), Err(Ok(Error::AmountCapExceeded))); +} + +#[test] +fn non_positive_cap_is_rejected_at_deployment() { + let env = Env::default(); + let (token, _, _) = create_token(&env); + let mut caps = Map::new(&env); + caps.set(token, 0i128); + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + env.register(EscrowContract, (Vec::
::new(&env), caps)) + })); + assert!(result.is_err(), "a zero cap must fail the constructor"); +} diff --git a/contracts/escrow/tests/token_edge_cases.rs b/contracts/escrow/tests/token_edge_cases.rs index c2bd372e..20399145 100644 --- a/contracts/escrow/tests/token_edge_cases.rs +++ b/contracts/escrow/tests/token_edge_cases.rs @@ -1,15 +1,54 @@ //! SAC edge-case coverage: each issued asset has an independent balance and authorization state. use docforum_escrow::{EscrowContract, EscrowContractClient}; -use soroban_sdk::{testutils::Address as _, token::{StellarAssetClient, TokenClient}, Address, Env, String, Vec}; +use soroban_sdk::{ + testutils::Address as _, + token::{StellarAssetClient, TokenClient}, + Address, Env, Map, String, Vec, +}; #[test] fn issued_assets_are_isolated_between_escrows() { - let env=Env::default(); env.mock_all_auths(); - let issuer=Address::generate(&env); let a=env.register_stellar_asset_contract_v2(issuer.clone()); - let b=env.register_stellar_asset_contract_v2(issuer); let payer=Address::generate(&env); let payee=Address::generate(&env); let rel=Address::generate(&env); - StellarAssetClient::new(&env,&a.address()).mint(&payer,&100); StellarAssetClient::new(&env,&b.address()).mint(&payer,&200); - let id=env.register(EscrowContract,(Vec::
::new(&env),)); let c=EscrowContractClient::new(&env,&id); - c.create_escrow(&payer,&payee,&a.address(),&50,&String::from_str(&env,"a"),&rel,&None,&false,&None,&None,&None); - c.create_escrow(&payer,&payee,&b.address(),&75,&String::from_str(&env,"b"),&rel,&None,&false,&None,&None,&None); - assert_eq!(TokenClient::new(&env,&a.address()).balance(&id),50); assert_eq!(TokenClient::new(&env,&b.address()).balance(&id),75); + let env = Env::default(); + env.mock_all_auths(); + let issuer = Address::generate(&env); + let a = env.register_stellar_asset_contract_v2(issuer.clone()); + let b = env.register_stellar_asset_contract_v2(issuer); + let payer = Address::generate(&env); + let payee = Address::generate(&env); + let rel = Address::generate(&env); + StellarAssetClient::new(&env, &a.address()).mint(&payer, &100); + StellarAssetClient::new(&env, &b.address()).mint(&payer, &200); + let id = env.register( + EscrowContract, + (Vec::
::new(&env), Map::::new(&env)), + ); + let c = EscrowContractClient::new(&env, &id); + c.create_escrow( + &payer, + &payee, + &a.address(), + &50, + &String::from_str(&env, "a"), + &rel, + &None, + &false, + &None, + &None, + &None, + ); + c.create_escrow( + &payer, + &payee, + &b.address(), + &75, + &String::from_str(&env, "b"), + &rel, + &None, + &false, + &None, + &None, + &None, + ); + assert_eq!(TokenClient::new(&env, &a.address()).balance(&id), 50); + assert_eq!(TokenClient::new(&env, &b.address()).balance(&id), 75); } diff --git a/contracts/escrow/tests/top_up.rs b/contracts/escrow/tests/top_up.rs index e61aabd3..2b2355be 100644 --- a/contracts/escrow/tests/top_up.rs +++ b/contracts/escrow/tests/top_up.rs @@ -27,7 +27,13 @@ fn setup(env: &Env) -> Fixture<'_> { let payee = Address::generate(env); let releaser = Address::generate(env); asset.mint(&payer, &1_000); - let contract_id = env.register(EscrowContract, (Vec::
::new(env),)); + let contract_id = env.register( + EscrowContract, + ( + Vec::
::new(env), + soroban_sdk::Map::::new(env), + ), + ); let client = EscrowContractClient::new(env, &contract_id); let id = client.create_escrow( &payer, diff --git a/contracts/releaser-account/test_snapshots/custom_account_can_be_configured_as_escrow_releaser.1.json b/contracts/releaser-account/test_snapshots/custom_account_can_be_configured_as_escrow_releaser.1.json index 3699617d..b2ab4729 100644 --- a/contracts/releaser-account/test_snapshots/custom_account_can_be_configured_as_escrow_releaser.1.json +++ b/contracts/releaser-account/test_snapshots/custom_account_can_be_configured_as_escrow_releaser.1.json @@ -439,6 +439,18 @@ "vec": [] } }, + { + "key": { + "vec": [ + { + "symbol": "MaximumAmounts" + } + ] + }, + "val": { + "map": [] + } + }, { "key": { "vec": [ diff --git a/contracts/releaser-account/tests/escrow_integration.rs b/contracts/releaser-account/tests/escrow_integration.rs index 8bfb2c6c..105dd4f2 100644 --- a/contracts/releaser-account/tests/escrow_integration.rs +++ b/contracts/releaser-account/tests/escrow_integration.rs @@ -15,7 +15,7 @@ fn custom_account_can_be_configured_as_escrow_releaser() { let token_client = token::Client::new(&env, &token_id.address()); token.mint(&payer, &500); - let escrow_id = env.register(EscrowContract, (Vec::
::new(&env),)); + let escrow_id = env.register(EscrowContract, (Vec::
::new(&env), soroban_sdk::Map::::new(&env))); let escrow = EscrowContractClient::new(&env, &escrow_id); let signer_key = soroban_sdk::BytesN::from_array(&env, &[7; 32]); let signers: Vec> = Vec::from_array(&env, [signer_key]); diff --git a/docs/adr/0013-per-token-escrow-caps.md b/docs/adr/0013-per-token-escrow-caps.md new file mode 100644 index 00000000..760ab8f4 --- /dev/null +++ b/docs/adr/0013-per-token-escrow-caps.md @@ -0,0 +1,61 @@ +# ADR 0013: Immutable per-token escrow caps + +**Status:** accepted for the guarded beta (issue #56) + +## Context + +The contract holds all escrows for a token in one shared balance. A +deployment-time cap limits the amount one escrow can commit, including +later top-ups, and gives a staged launch a fixed bound that cannot be +raised by an administrator key. The deployment already takes an immutable +token allowlist (`allowed_tokens`, issue #36); caps sit alongside it. + +## Decision + +The constructor is `__constructor(allowed_tokens, maximum_amounts)`, where +`maximum_amounts` maps a token contract address to a positive maximum in +that token's smallest units. A non-positive cap fails deployment. + +- **Empty map: no caps.** This mirrors the allowlist, where an empty list + allows any token. It keeps existing deployments, tests and integrations + working with one extra empty argument. +- **Non-empty map: a token without an entry is rejected** + (`TokenCapNotConfigured = 36`), so a capped deployment cannot accidentally + accept an uncapped asset. +- **Enforcement points**, all rejecting with `AmountCapExceeded = 37` before + any transfer: + - every creation path, via the shared `create_escrow_inner` — single, + release-time, acceptance-gated, M-of-N releaser, and each item of + `create_escrows` (the batch is atomic, so one over-cap item rejects + the whole call); + - `top_up`, against the escrow's total after the top-up; + - `create_pooled_escrow`, against the funding target. Contributions can + never exceed the target, so this bounds a pooled escrow's total. + +Code 35 is deliberately left unused here because the pre-payout solvency +check proposed in issue #38 claims it. + +## Staged launch plan + +For each allowlisted token, choose a cap in its smallest units based on +the token's decimals and the intended initial beta exposure. Start at +25% of the reviewed beta target, increase to 50%, then 100% only after +the preceding stage has been monitored and reviewed. Each increase +requires deploying a new contract (`scripts/deploy --maximum-amounts +C...=AMOUNT,...`) and moving new escrows to its contract ID; the existing +deployment remains capped and must settle its outstanding escrows before +it is retired. This is a conservative operational plan, not a mainnet +authorization: the Phase E4 security review remains a hard prerequisite +for any mainnet use. + +## Consequences + +- Caps are immutable for a deployment; there is no setter and no admin. +- Redeployment changes the contract ID and requires an explicit + migration and settlement plan. +- Caps limit individual escrow exposure, not aggregate liabilities in a + shared token pool; the token allowlist and balance-delta checks remain + necessary. +- Every deployment now passes a second constructor argument. The SDK + bindings were regenerated; `scripts/deploy` and the local-network SDK + workflow pass an empty map unless caps are requested. diff --git a/docs/testnet-deployments.md b/docs/testnet-deployments.md index fb845185..a0abdc85 100644 --- a/docs/testnet-deployments.md +++ b/docs/testnet-deployments.md @@ -24,6 +24,9 @@ machine-readable `/deployments.json`. Older records were written by hand. | Source commit | `eafe267` (`eafe26743c255cd1e6b4c44a556aad080ad850a9`) | | Constructor `allowed_tokens` | `CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC` | +This deployment predates the per-token cap constructor argument (issue #56, +ADR 0013) and has no caps; it is not a capped beta deployment. + ### Scripted live verification The on-chain WASM was fetched after deployment and matched the hash above. @@ -212,6 +215,11 @@ layout changed, so the old contract ID is no longer signature- or layout-compatible with the current contract source. The prior entries are kept as accurate history, not deleted. +This 2026-10-08 deployment predates issue #56's constructor cap map and +`top_up`; it has no per-token maximum. It must not be treated as a capped +beta deployment. A new deployment with an explicit cap map and regenerated +bindings is required before using the capped contract surface. + ### Verified live, on this deployment Every claim below is a real transaction or a real contract error diff --git a/scripts/deploy b/scripts/deploy index a9a57b82..6f8faca3 100755 --- a/scripts/deploy +++ b/scripts/deploy @@ -8,7 +8,8 @@ # # Usage: # scripts/deploy [--network testnet] [--wasm PATH] [--expected-wasm-hash HEX] -# [--allowed-tokens C...,C...] [--no-record] +# [--allowed-tokens C...,C...] +# [--maximum-amounts C...=AMOUNT,...] [--no-record] # scripts/deploy --dry-run # same flow against a local quickstart # # Options: @@ -24,6 +25,10 @@ # --allowed-tokens LIST Comma-separated constructor allowlist. Default: # the network's native XLM asset contract. Pass an # empty string to allow any token. +# --maximum-amounts LIST Comma-separated TOKEN=AMOUNT per-token escrow caps +# in the token's smallest unit (issue #56, +# docs/adr/0013). Default: none (no caps). When +# set, tokens without an entry cannot be escrowed. # --no-record Deploy and verify, but write no record. # -h, --help Show this help. # @@ -53,6 +58,7 @@ wasm_path="" expected_hash="" allowed_tokens_set=false allowed_tokens="" +maximum_amounts="" record=true while [[ $# -gt 0 ]]; do @@ -62,6 +68,7 @@ while [[ $# -gt 0 ]]; do --wasm) wasm_path="${2:?--wasm needs a path}"; shift 2 ;; --expected-wasm-hash) expected_hash="${2:?--expected-wasm-hash needs a value}"; shift 2 ;; --allowed-tokens) allowed_tokens="${2-}"; allowed_tokens_set=true; shift 2 ;; + --maximum-amounts) maximum_amounts="${2-}"; shift 2 ;; --no-record) record=false; shift ;; -h|--help) usage; exit 0 ;; *) usage >&2; die "unknown argument: $1" ;; @@ -201,6 +208,19 @@ if [[ "$allowed_tokens_set" == false ]]; then allowed_tokens="$native_token" fi allowed_json="$(node -e 'const l=process.argv[1].split(",").map(s=>s.trim()).filter(Boolean);console.log(JSON.stringify(l))' "$allowed_tokens")" +# Map as JSON: {"C...": "amount"}; i128 values stay strings. +maximum_json="$(node -e ' +const out = {}; +for (const pair of process.argv[1].split(",").map((s) => s.trim()).filter(Boolean)) { + const [token, amount] = pair.split("=").map((s) => s.trim()); + if (!/^C[A-Z2-7]{55}$/.test(token || "") || !/^[1-9][0-9]*$/.test(amount || "")) { + console.error(`deploy: bad --maximum-amounts entry "${pair}" (want C...=POSITIVE_INTEGER)`); + process.exit(1); + } + out[token] = amount; +} +console.log(JSON.stringify(out)); +' "$maximum_amounts")" || die "invalid --maximum-amounts" # --- Upload + deploy ------------------------------------------------------------- log "Uploading WASM to $network" @@ -209,9 +229,9 @@ upload_tx="$(tx_of_last)" [[ "$uploaded_hash" == "$wasm_hash" ]] || die "uploaded WASM hash $uploaded_hash does not match local $wasm_hash." -log "Deploying with allowed_tokens=$allowed_json" +log "Deploying with allowed_tokens=$allowed_json maximum_amounts=$maximum_json" contract_id="$(submit contract deploy --wasm-hash "$wasm_hash" --source deployer "${net_args[@]}" \ - -- --allowed_tokens "$allowed_json" | tail -n 1)" + -- --allowed_tokens "$allowed_json" --maximum_amounts "$maximum_json" | tail -n 1)" deploy_tx="$(tx_of_last)" [[ "$contract_id" =~ ^C[A-Z2-7]{55}$ ]] || die "unexpected contract id: $contract_id" log "Contract $contract_id" @@ -274,18 +294,18 @@ pass reject_non_positive_amount Passed "" "" "Error(Contract, #2) InvalidAmount" record_json="$work_dir/record.json" node -e ' const fs = require("fs"); -const [net, pass, rpc, cid, hash, sha, upTx, depTx, allowed, results, txBase, contractBase] = process.argv.slice(1); +const [net, pass, rpc, cid, hash, sha, upTx, depTx, allowed, maximums, results, txBase, contractBase] = process.argv.slice(1); const verification = fs.readFileSync(results, "utf8").trim().split("\n").map((l) => JSON.parse(l)); const record = { network: net, networkPassphrase: pass, rpcUrl: rpc, contractId: cid, wasmHash: hash, gitSha: sha, deployedAt: new Date().toISOString(), uploadTxHash: upTx || null, deployTxHash: depTx, - allowedTokens: JSON.parse(allowed), verification, + allowedTokens: JSON.parse(allowed), maximumAmounts: JSON.parse(maximums), verification, }; if (txBase) record.explorer = { contract: contractBase + cid, tx: txBase }; -fs.writeFileSync(process.argv[13], JSON.stringify(record, null, 2) + "\n"); +fs.writeFileSync(process.argv[14], JSON.stringify(record, null, 2) + "\n"); ' "$network" "$network_passphrase" "$rpc_url" "$contract_id" "$wasm_hash" "$git_sha" \ - "$upload_tx" "$deploy_tx" "$allowed_json" "$results" "$explorer_tx" "$explorer_contract" "$record_json" + "$upload_tx" "$deploy_tx" "$allowed_json" "$maximum_json" "$results" "$explorer_tx" "$explorer_contract" "$record_json" if [[ "$dry_run" == true ]]; then log "Dry run: tracked files not changed. Record:" diff --git a/scripts/deploy-record.mjs b/scripts/deploy-record.mjs index c01785e5..5aac2331 100644 --- a/scripts/deploy-record.mjs +++ b/scripts/deploy-record.mjs @@ -50,6 +50,9 @@ export function renderDocsSection(r) { `| Deploy tx | ${tx(r.deployTxHash)} |`, `| Source commit | \`${short}\` (\`${r.gitSha}\`) |`, `| Constructor \`allowed_tokens\` | ${r.allowedTokens.length ? r.allowedTokens.map((t) => `\`${t}\``).join(", ") : "empty (any token)"} |`, + ...(r.maximumAmounts + ? [`| Constructor \`maximum_amounts\` | ${Object.keys(r.maximumAmounts).length ? Object.entries(r.maximumAmounts).map(([t, a]) => `\`${t}\` ≤ ${a}`).join(", ") : "empty (no caps)"} |`] + : []), ]; const cases = r.verification.map((v) => { const where = v.txHash ? `[transaction](${tx(v.txHash)})` : "rejected in simulation, not submitted"; diff --git a/sdk/src/generated/contract-client.ts b/sdk/src/generated/contract-client.ts index f995b60b..3650e0ed 100644 --- a/sdk/src/generated/contract-client.ts +++ b/sdk/src/generated/contract-client.ts @@ -170,7 +170,15 @@ export const Errors = { * contract itself, or an amount that would overflow the fee math — * see docs/adr/0010. */ - 35: {message:"InvalidFee"} + 35: {message:"InvalidFee"}, + /** + * A token has no configured amount cap when cap enforcement is enabled. + */ + 36: {message:"TokenCapNotConfigured"}, + /** + * An escrow amount, top-up total, or pooled target exceeds its token cap. + */ + 37: {message:"AmountCapExceeded"} } @@ -625,7 +633,7 @@ export interface Client { export class Client extends ContractClient { static async deploy( /** Constructor/Initialization Args for the contract's `__constructor` method */ - {allowed_tokens}: {allowed_tokens: Array}, + {allowed_tokens, maximum_amounts}: {allowed_tokens: Array, maximum_amounts: Map}, /** Options for initializing a Client as well as for calling a method, with extras specific to deploying. */ options: MethodOptions & Omit & { @@ -637,11 +645,11 @@ export class Client extends ContractClient { format?: "hex" | "base64"; } ): Promise> { - return ContractClient.deploy({allowed_tokens}, options) + return ContractClient.deploy({allowed_tokens, maximum_amounts}, options) } constructor(public readonly options: ContractClientOptions) { super( - new ContractSpec([ "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAIQAAAAAAAAAITm90Rm91bmQAAAABAAAAAAAAAA1JbnZhbGlkQW1vdW50AAAAAAAAAgAAAAAAAAAMVW5hdXRob3JpemVkAAAAAwAAAAAAAAAJTm90RnVuZGVkAAAAAAAABAAAALpgcmVmdW5kX2FmdGVyYCB3YXMgbm90IHN0cmljdGx5IGluIHRoZSBmdXR1cmUgYXQgY3JlYXRpb24g4oCUIHNlZQpkb2NzL2Fkci8wMDA0OiBhIGRlYWRsaW5lIHRoYXQgaGFzIGFscmVhZHkgcGFzc2VkIHdvdWxkIGxldAphbnlvbmUgcmVmdW5kIHRoZSBlc2Nyb3cgYmVmb3JlIHRoZSByZWxlYXNlciBjb3VsZCBldmVyIGFjdC4AAAAAABJJbnZhbGlkUmVmdW5kQWZ0ZXIAAAAAAAUAAACjVGhlIGNvbnRyYWN0J3MgdG9rZW4gYmFsYW5jZSBkaWRuJ3QgcmlzZSBieSBleGFjdGx5IGBhbW91bnRgCmFjcm9zcyBgY3JlYXRlX2VzY3Jvd2AncyB0cmFuc2ZlciAoYSBseWluZyBvciBzaG9ydC1kZWxpdmVyaW5nCnRva2VuKSDigJQgc2VlIGRvY3MvdGhyZWF0LW1vZGVsLm1kIFQ1LgAAAAAPQmFsYW5jZU1pc21hdGNoAAAAAAYAAAEAYGNvbmRpdGlvbl9yZWZgIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGFsbG93ZWQgbGVuZ3RoIChjdXJyZW50bHkKNjQgYnl0ZXMpIOKAlCBzZWUgZG9jcy90aHJlYXQtbW9kZWwubWQgVDEwIGFuZCBST0FETUFQLm1kIFBoYXNlIEU1LgpCb3VuZGVkIHRvIGtlZXAgc3RvcmFnZSBhbmQgZXZlbnQgY29zdHMgcHJlZGljdGFibGU7IHJlamVjdCBhdApjcmVhdGlvbiBzbyBubyBvbi1jaGFpbiBzdG9yYWdlIGlzIHdhc3RlZCBvbiBhbiBvdmVyc2l6ZWQgcmVmLgAAABNDb25kaXRpb25SZWZUb29Mb25nAAAAAAcAAAA2YHRva2VuYCBpcyBub3QgaW4gdGhlIGltbXV0YWJsZSBkZXBsb3ktdGltZSBhbGxvd2xpc3QuAAAAAAAPRGlzYWxsb3dlZFRva2VuAAAAAAgAAACDVGhlIG9wdGVkLWluIHBheWVlIGNhbGxiYWNrIHJldHVybmVkIGFuIGVycm9yIG9yIGNvdWxkIG5vdCBiZQppbnZva2VkLiBUaGUgcmVsZWFzZSB0cmFuc2FjdGlvbiAoaW5jbHVkaW5nIGl0cyB0cmFuc2Zlcikgcm9sbHMgYmFjay4AAAAADkNhbGxiYWNrRmFpbGVkAAAAAAAJAAAAAAAAAAhPdmVyZmxvdwAAAAwAAABsVGhlIHJlbGVhc2VyIHNldCBpcyBlbXB0eSwgb3IgYHRocmVzaG9sZGAgaXMgMCBvciBsYXJnZXIgdGhhbiB0aGUKbnVtYmVyIG9mIHJlbGVhc2VycyDigJQgc2VlIGRvY3MvYWRyLzAwMDcuAAAAEEludmFsaWRUaHJlc2hvbGQAAAANAAAAQ01vcmUgdGhhbiBgTUFYX1JFTEVBU0VSU2AgKDEwKSBhZGRyZXNzZXMgd2VyZSBzdXBwbGllZCBhdCBjcmVhdGlvbi4AAAAAEFRvb01hbnlSZWxlYXNlcnMAAAAOAAAAn0Zld2VyIGRpc3RpbmN0IGFwcHJvdmFscyB3ZXJlIHN1cHBsaWVkIHRoYW4gdGhlIGVzY3JvdydzIHRocmVzaG9sZCwKb3IgYSBzaW5nbGUgcmVsZWFzZXIgdHJpZWQgdG8gc2V0dGxlIGEgcXVvcnVtIGVzY3JvdyB0aHJvdWdoIHRoZQpzaW5nbGUtY2FsbGVyIGVudHJ5IHBvaW50LgAAAAAPVGhyZXNob2xkTm90TWV0AAAAAA8AAABoVGhlIHNhbWUgYWRkcmVzcyBhcHBlYXJlZCB0d2ljZSBpbiBvbmUgYXBwcm92YWwgbGlzdC4gRHVwbGljYXRlcwpuZXZlciBjb3VudCB0d2ljZSB0b3dhcmQgdGhlIHRocmVzaG9sZC4AAAARRHVwbGljYXRlQXBwcm92ZXIAAAAAAAAQAAAAQFRoZSBzYW1lIGFkZHJlc3MgYXBwZWFyZWQgdHdpY2UgaW4gdGhlIHJlbGVhc2VyIHNldCBhdCBjcmVhdGlvbi4AAAARRHVwbGljYXRlUmVsZWFzZXIAAAAAAAARAAAAAAAAABJBY2NlcHRhbmNlUmVxdWlyZWQAAAAAABIAAAAAAAAAF0FjY2VwdGFuY2VOb3RDb25maWd1cmVkAAAAABMAAAAAAAAAD0FscmVhZHlBY2NlcHRlZAAAAAAUAAAAOFRoZSBuZXcgcmVsZWFzZXIgY2Fubm90IGJlIHRoZSBlc2Nyb3cgY29udHJhY3Qgb3IgcGF5ZWUuAAAAD0ludmFsaWRSZWxlYXNlcgAAAAAYAAAAfGByZWZ1bmRfdG9gIHdhcyB0aGUgZXNjcm93IGNvbnRyYWN0J3Mgb3duIGFkZHJlc3Mg4oCUIGZ1bmRzIHNlbnQKdGhlcmUgb24gcmVmdW5kIGNvdWxkIG5ldmVyIGJlIG1vdmVkIGFnYWluIChkb2NzL2Fkci8wMDA5KS4AAAAPSW52YWxpZFJlZnVuZFRvAAAAABUAAABEVGhlIGNvbmZpZ3VyZWQgcmVsZWFzZSB0aW1lIGlzIGluIHRoZSBwYXN0IG9yIGFmdGVyIHRoZSByZWZ1bmQgdGltZS4AAAAXSW52YWxpZFJlbGVhc2VOb3RCZWZvcmUAAAAAFgAAADFSZWxlYXNlIHdhcyBhdHRlbXB0ZWQgYmVmb3JlIHRoZSBjb25maWd1cmVkIHRpbWUuAAAAAAAAD1JlbGVhc2VUb29FYXJseQAAAAAXAAAArUEgYmF0Y2ggY2FsbCB3YXMgcGFzc2VkIG1vcmUgdGhhbiBgTUFYX0JBVENIX1NJWkVgIGl0ZW1zIOKAlCBzZWUKZG9jcy9hZHIvMDAwNS4gQ2FsbGVycyBtdXN0IGNodW5rLiBBcHBlbmRlZCBhdCB0aGUgZW5kIHNvIGV4aXN0aW5nCmRpc2NyaW1pbmFudHMga2VlcCB0aGVpciBvbi1jaGFpbiB2YWx1ZXMuAAAAAAAADUJhdGNoVG9vTGFyZ2UAAAAAAAAZAAAAiGBjb250cmlidXRlYC9gY2xhaW1fcmVmdW5kYC9gZ2V0X2NvbnRyaWJ1dGlvbmAgb24gYSBub24tcG9vbGVkCmVzY3Jvdywgb3IgYGdldF9wb29sZWRgIG9uIGEgbm9uLXBvb2xlZC91bmtub3duIGlkIOKAlCBzZWUKZG9jcy9hZHIvMDAxMS4AAAAJTm90UG9vbGVkAAAAAAAAGgAAAL9BIGNvbnRyaWJ1dGlvbiBhcnJpdmVkIGFmdGVyIHRoZSBwb29sZWQgZXNjcm93J3MgZnVuZGluZyBkZWFkbGluZS4KTGF0ZSBjb250cmlidXRpb25zIGNhbiBuZXZlciBiZSBhY2NlcHRlZDogdGhlIHJvdW5kJ3Mgb3V0Y29tZQoocmVsZWFzZSB2cyBwZXItY29udHJpYnV0b3IgcmVmdW5kcykgaXMgZml4ZWQgYXQgdGhlIGRlYWRsaW5lLgAAAAAVRnVuZGluZ0RlYWRsaW5lUGFzc2VkAAAAAAAAGwAAAL9BIGNvbnRyaWJ1dGlvbiB3b3VsZCBwdXNoIHRoZSBwb29sZWQgdG90YWwgcGFzdCB0aGUgZnVuZGluZyB0YXJnZXQKKG92ZXJmdW5kaW5nIGlzIHJlamVjdGVkLCBub3QgYWNjZXB0ZWQpLCB0aGUgdGFyZ2V0IGlzIGFscmVhZHkgbWV0LApvciBhIHJlZnVuZCB3YXMgY2xhaW1lZCBvbiBhIGZ1bGx5IGZ1bmRlZCBwb29sZWQgZXNjcm93LgAAAAAURnVuZGluZ1RhcmdldFJlYWNoZWQAAAAcAAAAdGByZWxlYXNlYCBvbiBhIHBvb2xlZCBlc2Nyb3cgd2hvc2UgZnVuZGVkIHRvdGFsIGlzIGJlbG93IHRoZQpmdW5kaW5nIHRhcmdldCDigJQgcGFydGlhbCBmdW5kaW5nIGlzIG5ldmVyIHJlbGVhc2FibGUuAAAAEUZ1bmRpbmdJbmNvbXBsZXRlAAAAAAAAHQAAAIZgY2xhaW1fcmVmdW5kYCBiZWZvcmUgdGhlIGZ1bmRpbmcgZGVhZGxpbmUgcGFzc2VkIG9uIGEgcm91bmQgdGhhdAppcyBzdGlsbCAob3Igbm93IGZ1bGx5KSBmdW5kZWQuIENsYWltcyBvcGVuIG9ubHkgZm9yIGEgZmFpbGVkIHJvdW5kLgAAAAAADVJlZnVuZE5vdE9wZW4AAAAAAAAeAAAAM1RoZSBzYW1lIGNvbnRyaWJ1dG9yIHRyaWVkIHRvIGNsYWltIGEgcmVmdW5kIHR3aWNlLgAAAAAPQWxyZWFkeVJlZnVuZGVkAAAAAB8AAAA7YGNsYWltX3JlZnVuZGAgYnkgYW4gYWRkcmVzcyB3aXRoIG5vIHJlY29yZGVkIGNvbnRyaWJ1dGlvbi4AAAAADk5vQ29udHJpYnV0aW9uAAAAAAAgAAAA82ByZWZ1bmRgL2ByZWZ1bmRfd2l0aF9hcHByb3ZhbHNgL2BjYW5jZWxgL2B0b3BfdXBgIG9uIGEgcG9vbGVkCmVzY3JvdzogcHVzaGluZyB0aGUgd2hvbGUgcG9vbGVkIHRvdGFsIHRvIG9uZSBhZGRyZXNzIHdvdWxkIHZpb2xhdGUKcGVyLWNvbnRyaWJ1dG9yIGFjY291bnRpbmcuIFBvb2xlZCByZWZ1bmRzIGFyZSBwdWxsLWJhc2VkCihgY2xhaW1fcmVmdW5kYCk7IHBvb2xlZCBmdW5kaW5nIGlzIGBjb250cmlidXRlYC1vbmx5LgAAAAAVTm90U3VwcG9ydGVkRm9yUG9vbGVkAAAAAAAAIQAAAEBUaGUgZnVuZGluZyBkZWFkbGluZSB3YXMgbm90IHN0cmljdGx5IGluIHRoZSBmdXR1cmUgYXQgY3JlYXRpb24uAAAAFkludmFsaWRGdW5kaW5nRGVhZGxpbmUAAAAAACIAAADSVGhlIG9wdGlvbmFsIHByb3RvY29sIGZlZSB3YXMgbWlzY29uZmlndXJlZCBhdCBjcmVhdGlvbjogYGJwc2AKYWJvdmUgW2BNQVhfRkVFX0JQU2BdICgxMCAlKSwgYSByZWNpcGllbnQgZXF1YWwgdG8gdGhlIGVzY3Jvdwpjb250cmFjdCBpdHNlbGYsIG9yIGFuIGFtb3VudCB0aGF0IHdvdWxkIG92ZXJmbG93IHRoZSBmZWUgbWF0aCDigJQKc2VlIGRvY3MvYWRyLzAwMTAuAAAAAAAKSW52YWxpZEZlZQAAAAAAIw==", + new ContractSpec([ "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAIwAAAAAAAAAITm90Rm91bmQAAAABAAAAAAAAAA1JbnZhbGlkQW1vdW50AAAAAAAAAgAAAAAAAAAMVW5hdXRob3JpemVkAAAAAwAAAAAAAAAJTm90RnVuZGVkAAAAAAAABAAAALpgcmVmdW5kX2FmdGVyYCB3YXMgbm90IHN0cmljdGx5IGluIHRoZSBmdXR1cmUgYXQgY3JlYXRpb24g4oCUIHNlZQpkb2NzL2Fkci8wMDA0OiBhIGRlYWRsaW5lIHRoYXQgaGFzIGFscmVhZHkgcGFzc2VkIHdvdWxkIGxldAphbnlvbmUgcmVmdW5kIHRoZSBlc2Nyb3cgYmVmb3JlIHRoZSByZWxlYXNlciBjb3VsZCBldmVyIGFjdC4AAAAAABJJbnZhbGlkUmVmdW5kQWZ0ZXIAAAAAAAUAAACjVGhlIGNvbnRyYWN0J3MgdG9rZW4gYmFsYW5jZSBkaWRuJ3QgcmlzZSBieSBleGFjdGx5IGBhbW91bnRgCmFjcm9zcyBgY3JlYXRlX2VzY3Jvd2AncyB0cmFuc2ZlciAoYSBseWluZyBvciBzaG9ydC1kZWxpdmVyaW5nCnRva2VuKSDigJQgc2VlIGRvY3MvdGhyZWF0LW1vZGVsLm1kIFQ1LgAAAAAPQmFsYW5jZU1pc21hdGNoAAAAAAYAAAEAYGNvbmRpdGlvbl9yZWZgIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGFsbG93ZWQgbGVuZ3RoIChjdXJyZW50bHkKNjQgYnl0ZXMpIOKAlCBzZWUgZG9jcy90aHJlYXQtbW9kZWwubWQgVDEwIGFuZCBST0FETUFQLm1kIFBoYXNlIEU1LgpCb3VuZGVkIHRvIGtlZXAgc3RvcmFnZSBhbmQgZXZlbnQgY29zdHMgcHJlZGljdGFibGU7IHJlamVjdCBhdApjcmVhdGlvbiBzbyBubyBvbi1jaGFpbiBzdG9yYWdlIGlzIHdhc3RlZCBvbiBhbiBvdmVyc2l6ZWQgcmVmLgAAABNDb25kaXRpb25SZWZUb29Mb25nAAAAAAcAAAA2YHRva2VuYCBpcyBub3QgaW4gdGhlIGltbXV0YWJsZSBkZXBsb3ktdGltZSBhbGxvd2xpc3QuAAAAAAAPRGlzYWxsb3dlZFRva2VuAAAAAAgAAACDVGhlIG9wdGVkLWluIHBheWVlIGNhbGxiYWNrIHJldHVybmVkIGFuIGVycm9yIG9yIGNvdWxkIG5vdCBiZQppbnZva2VkLiBUaGUgcmVsZWFzZSB0cmFuc2FjdGlvbiAoaW5jbHVkaW5nIGl0cyB0cmFuc2Zlcikgcm9sbHMgYmFjay4AAAAADkNhbGxiYWNrRmFpbGVkAAAAAAAJAAAAAAAAAAhPdmVyZmxvdwAAAAwAAABsVGhlIHJlbGVhc2VyIHNldCBpcyBlbXB0eSwgb3IgYHRocmVzaG9sZGAgaXMgMCBvciBsYXJnZXIgdGhhbiB0aGUKbnVtYmVyIG9mIHJlbGVhc2VycyDigJQgc2VlIGRvY3MvYWRyLzAwMDcuAAAAEEludmFsaWRUaHJlc2hvbGQAAAANAAAAQ01vcmUgdGhhbiBgTUFYX1JFTEVBU0VSU2AgKDEwKSBhZGRyZXNzZXMgd2VyZSBzdXBwbGllZCBhdCBjcmVhdGlvbi4AAAAAEFRvb01hbnlSZWxlYXNlcnMAAAAOAAAAn0Zld2VyIGRpc3RpbmN0IGFwcHJvdmFscyB3ZXJlIHN1cHBsaWVkIHRoYW4gdGhlIGVzY3JvdydzIHRocmVzaG9sZCwKb3IgYSBzaW5nbGUgcmVsZWFzZXIgdHJpZWQgdG8gc2V0dGxlIGEgcXVvcnVtIGVzY3JvdyB0aHJvdWdoIHRoZQpzaW5nbGUtY2FsbGVyIGVudHJ5IHBvaW50LgAAAAAPVGhyZXNob2xkTm90TWV0AAAAAA8AAABoVGhlIHNhbWUgYWRkcmVzcyBhcHBlYXJlZCB0d2ljZSBpbiBvbmUgYXBwcm92YWwgbGlzdC4gRHVwbGljYXRlcwpuZXZlciBjb3VudCB0d2ljZSB0b3dhcmQgdGhlIHRocmVzaG9sZC4AAAARRHVwbGljYXRlQXBwcm92ZXIAAAAAAAAQAAAAQFRoZSBzYW1lIGFkZHJlc3MgYXBwZWFyZWQgdHdpY2UgaW4gdGhlIHJlbGVhc2VyIHNldCBhdCBjcmVhdGlvbi4AAAARRHVwbGljYXRlUmVsZWFzZXIAAAAAAAARAAAAAAAAABJBY2NlcHRhbmNlUmVxdWlyZWQAAAAAABIAAAAAAAAAF0FjY2VwdGFuY2VOb3RDb25maWd1cmVkAAAAABMAAAAAAAAAD0FscmVhZHlBY2NlcHRlZAAAAAAUAAAAOFRoZSBuZXcgcmVsZWFzZXIgY2Fubm90IGJlIHRoZSBlc2Nyb3cgY29udHJhY3Qgb3IgcGF5ZWUuAAAAD0ludmFsaWRSZWxlYXNlcgAAAAAYAAAAfGByZWZ1bmRfdG9gIHdhcyB0aGUgZXNjcm93IGNvbnRyYWN0J3Mgb3duIGFkZHJlc3Mg4oCUIGZ1bmRzIHNlbnQKdGhlcmUgb24gcmVmdW5kIGNvdWxkIG5ldmVyIGJlIG1vdmVkIGFnYWluIChkb2NzL2Fkci8wMDA5KS4AAAAPSW52YWxpZFJlZnVuZFRvAAAAABUAAABEVGhlIGNvbmZpZ3VyZWQgcmVsZWFzZSB0aW1lIGlzIGluIHRoZSBwYXN0IG9yIGFmdGVyIHRoZSByZWZ1bmQgdGltZS4AAAAXSW52YWxpZFJlbGVhc2VOb3RCZWZvcmUAAAAAFgAAADFSZWxlYXNlIHdhcyBhdHRlbXB0ZWQgYmVmb3JlIHRoZSBjb25maWd1cmVkIHRpbWUuAAAAAAAAD1JlbGVhc2VUb29FYXJseQAAAAAXAAAArUEgYmF0Y2ggY2FsbCB3YXMgcGFzc2VkIG1vcmUgdGhhbiBgTUFYX0JBVENIX1NJWkVgIGl0ZW1zIOKAlCBzZWUKZG9jcy9hZHIvMDAwNS4gQ2FsbGVycyBtdXN0IGNodW5rLiBBcHBlbmRlZCBhdCB0aGUgZW5kIHNvIGV4aXN0aW5nCmRpc2NyaW1pbmFudHMga2VlcCB0aGVpciBvbi1jaGFpbiB2YWx1ZXMuAAAAAAAADUJhdGNoVG9vTGFyZ2UAAAAAAAAZAAAAiGBjb250cmlidXRlYC9gY2xhaW1fcmVmdW5kYC9gZ2V0X2NvbnRyaWJ1dGlvbmAgb24gYSBub24tcG9vbGVkCmVzY3Jvdywgb3IgYGdldF9wb29sZWRgIG9uIGEgbm9uLXBvb2xlZC91bmtub3duIGlkIOKAlCBzZWUKZG9jcy9hZHIvMDAxMS4AAAAJTm90UG9vbGVkAAAAAAAAGgAAAL9BIGNvbnRyaWJ1dGlvbiBhcnJpdmVkIGFmdGVyIHRoZSBwb29sZWQgZXNjcm93J3MgZnVuZGluZyBkZWFkbGluZS4KTGF0ZSBjb250cmlidXRpb25zIGNhbiBuZXZlciBiZSBhY2NlcHRlZDogdGhlIHJvdW5kJ3Mgb3V0Y29tZQoocmVsZWFzZSB2cyBwZXItY29udHJpYnV0b3IgcmVmdW5kcykgaXMgZml4ZWQgYXQgdGhlIGRlYWRsaW5lLgAAAAAVRnVuZGluZ0RlYWRsaW5lUGFzc2VkAAAAAAAAGwAAAL9BIGNvbnRyaWJ1dGlvbiB3b3VsZCBwdXNoIHRoZSBwb29sZWQgdG90YWwgcGFzdCB0aGUgZnVuZGluZyB0YXJnZXQKKG92ZXJmdW5kaW5nIGlzIHJlamVjdGVkLCBub3QgYWNjZXB0ZWQpLCB0aGUgdGFyZ2V0IGlzIGFscmVhZHkgbWV0LApvciBhIHJlZnVuZCB3YXMgY2xhaW1lZCBvbiBhIGZ1bGx5IGZ1bmRlZCBwb29sZWQgZXNjcm93LgAAAAAURnVuZGluZ1RhcmdldFJlYWNoZWQAAAAcAAAAdGByZWxlYXNlYCBvbiBhIHBvb2xlZCBlc2Nyb3cgd2hvc2UgZnVuZGVkIHRvdGFsIGlzIGJlbG93IHRoZQpmdW5kaW5nIHRhcmdldCDigJQgcGFydGlhbCBmdW5kaW5nIGlzIG5ldmVyIHJlbGVhc2FibGUuAAAAEUZ1bmRpbmdJbmNvbXBsZXRlAAAAAAAAHQAAAIZgY2xhaW1fcmVmdW5kYCBiZWZvcmUgdGhlIGZ1bmRpbmcgZGVhZGxpbmUgcGFzc2VkIG9uIGEgcm91bmQgdGhhdAppcyBzdGlsbCAob3Igbm93IGZ1bGx5KSBmdW5kZWQuIENsYWltcyBvcGVuIG9ubHkgZm9yIGEgZmFpbGVkIHJvdW5kLgAAAAAADVJlZnVuZE5vdE9wZW4AAAAAAAAeAAAAM1RoZSBzYW1lIGNvbnRyaWJ1dG9yIHRyaWVkIHRvIGNsYWltIGEgcmVmdW5kIHR3aWNlLgAAAAAPQWxyZWFkeVJlZnVuZGVkAAAAAB8AAAA7YGNsYWltX3JlZnVuZGAgYnkgYW4gYWRkcmVzcyB3aXRoIG5vIHJlY29yZGVkIGNvbnRyaWJ1dGlvbi4AAAAADk5vQ29udHJpYnV0aW9uAAAAAAAgAAAA82ByZWZ1bmRgL2ByZWZ1bmRfd2l0aF9hcHByb3ZhbHNgL2BjYW5jZWxgL2B0b3BfdXBgIG9uIGEgcG9vbGVkCmVzY3JvdzogcHVzaGluZyB0aGUgd2hvbGUgcG9vbGVkIHRvdGFsIHRvIG9uZSBhZGRyZXNzIHdvdWxkIHZpb2xhdGUKcGVyLWNvbnRyaWJ1dG9yIGFjY291bnRpbmcuIFBvb2xlZCByZWZ1bmRzIGFyZSBwdWxsLWJhc2VkCihgY2xhaW1fcmVmdW5kYCk7IHBvb2xlZCBmdW5kaW5nIGlzIGBjb250cmlidXRlYC1vbmx5LgAAAAAVTm90U3VwcG9ydGVkRm9yUG9vbGVkAAAAAAAAIQAAAEBUaGUgZnVuZGluZyBkZWFkbGluZSB3YXMgbm90IHN0cmljdGx5IGluIHRoZSBmdXR1cmUgYXQgY3JlYXRpb24uAAAAFkludmFsaWRGdW5kaW5nRGVhZGxpbmUAAAAAACIAAADSVGhlIG9wdGlvbmFsIHByb3RvY29sIGZlZSB3YXMgbWlzY29uZmlndXJlZCBhdCBjcmVhdGlvbjogYGJwc2AKYWJvdmUgW2BNQVhfRkVFX0JQU2BdICgxMCAlKSwgYSByZWNpcGllbnQgZXF1YWwgdG8gdGhlIGVzY3Jvdwpjb250cmFjdCBpdHNlbGYsIG9yIGFuIGFtb3VudCB0aGF0IHdvdWxkIG92ZXJmbG93IHRoZSBmZWUgbWF0aCDigJQKc2VlIGRvY3MvYWRyLzAwMTAuAAAAAAAKSW52YWxpZEZlZQAAAAAAIwAAAEVBIHRva2VuIGhhcyBubyBjb25maWd1cmVkIGFtb3VudCBjYXAgd2hlbiBjYXAgZW5mb3JjZW1lbnQgaXMgZW5hYmxlZC4AAAAAAAAVVG9rZW5DYXBOb3RDb25maWd1cmVkAAAAAAAAJAAAAEdBbiBlc2Nyb3cgYW1vdW50LCB0b3AtdXAgdG90YWwsIG9yIHBvb2xlZCB0YXJnZXQgZXhjZWVkcyBpdHMgdG9rZW4gY2FwLgAAAAARQW1vdW50Q2FwRXhjZWVkZWQAAAAAAAAl", "AAAAAQAAAHJPbmUgZW50cnkgb2YgYSBgY3JlYXRlX2VzY3Jvd3NgIGJhdGNoLiBNaXJyb3JzIHRoZSBzaW5nbGUtZXNjcm93CmNyZWF0aW9uIHBhcmFtZXRlcnMgbWludXMgdGhlIGJhdGNoLXdpZGUgYHBheWVyYC4AAAAAAAAAAAAKQ3JlYXRlSXRlbQAAAAAABgAAAAAAAAAGYW1vdW50AAAAAAALAAAAAAAAAA1jb25kaXRpb25fcmVmAAAAAAAAEAAAAAAAAAAFcGF5ZWUAAAAAAAATAAAAAAAAAAxyZWZ1bmRfYWZ0ZXIAAAPoAAAABgAAAAAAAAAIcmVsZWFzZXIAAAATAAAAAAAAAAV0b2tlbgAAAAAAABM=", "AAAAAQAAAAAAAAAAAAAACkVzY3Jvd0RhdGEAAAAAABAAAAA1TGVkZ2VyIHRpbWVzdGFtcCBhdCB3aGljaCB0aGUgcGF5ZWUgYWNjZXB0ZWQsIGlmIGFueS4AAAAAAAALYWNjZXB0ZWRfYXQAAAAD6AAAAAYAAAAAAAAABmFtb3VudAAAAAAACwAAAAAAAAANY29uZGl0aW9uX3JlZgAAAAAAABAAAACnRmVlIHJhdGUgaW4gYmFzaXMgcG9pbnRzIG9mIGBhbW91bnRgIChjYXBwZWQgYXQgW2BNQVhfRkVFX0JQU2BdCj0gMTAgJSksIHRha2VuIG9uY2UgYXQgcmVsZWFzZSwgcm91bmRlZCAqKmRvd24qKiB3aXRoIHRoZQpyZW1haW5kZXIgdG8gdGhlIHBheWVlIOKAlCBzZWUgZG9jcy9hZHIvMDAxMC4AAAAAB2ZlZV9icHMAAAAD6AAAAAQAAAF7T3B0aW9uYWwgcHJvdG9jb2wgZmVlIHJlY2lwaWVudCwgc2V0IG9uY2UgYXQgYGNyZWF0ZV9lc2Nyb3dgIHRpbWUKYW5kIHBhaWQgYXQgcmVsZWFzZSAobmV2ZXIgb24gcmVmdW5kKSDigJQgc2VlIGRvY3MvYWRyLzAwMTAuIFN0b3JlZAphcyBvbmUgKHJlY2lwaWVudCwgYnBzKSBwYWlyIGluIHR3byBmaWVsZHMgc28gYm90aCBhcmUgYWx3YXlzIHNldAp0b2dldGhlciBvciBub3QgYXQgYWxsIChjcmVhdGlvbi10aW1lIHJ1bGUsIGBJbnZhbGlkRmVlYApvdGhlcndpc2UpLiBgTm9uZWAgKHdpdGggbm8gYnBzKSBtZWFucyBubyBmZWU6IHRoZSBwYXllZSByZWNlaXZlcwp0aGUgZnVsbCBgYW1vdW50YCwgZXhhY3RseSBhcyBiZWZvcmUgdGhpcyBmaWVsZCBleGlzdGVkLgAAAAANZmVlX3JlY2lwaWVudAAAAAAAA+gAAAATAAAAhklmIHRydWUsIGludm9rZSB0aGUgY29udHJhY3QgcGF5ZWUncyBgb25fZXNjcm93X3JlbGVhc2VkYCBob29rIGFmdGVyCnRoZSBwYXlvdXQgdHJhbnNmZXIuIEEgZmFpbGVkIGNhbGxiYWNrIHJldmVydHMgdGhlIHdob2xlIHJlbGVhc2UuAAAAAAAMbm90aWZ5X3BheWVlAAAAAQAAAAAAAAAFcGF5ZWUAAAAAAAATAAAAelRoZSBmdW5kZXI6IGF1dGhvcmlzZXMgYW5kIHBheXMgZm9yIHRoZSBlc2Nyb3cgYXQgY3JlYXRpb24uIEFsc28KdGhlIHJlZnVuZCBkZXN0aW5hdGlvbiB1bmxlc3MgYHJlZnVuZF90b2Agc2F5cyBvdGhlcndpc2UuAAAAAAAFcGF5ZXIAAAAAAAATAAAAxU9wdGlvbmFsIGRlYWRsaW5lICh1bml4IHNlY29uZHMpIGFmdGVyIHdoaWNoIGByZWZ1bmRgIG9wZW5zIHRvCmFueW9uZSDigJQgc3RpbGwgb25seSB0byBgcmVmdW5kX3RvYC4gYE5vbmVgIG1lYW5zIG5vIHRpbWVvdXQsCmJlaGF2aW91ciBpZGVudGljYWwgdG8gYmVmb3JlIHRoaXMgZmllbGQgZXhpc3RlZCDigJQgc2VlIGRvY3MvYWRyLzAwMDQuAAAAAAAADHJlZnVuZF9hZnRlcgAAA+gAAAAGAAAA4VdoZXJlICoqZXZlcnkqKiByZWZ1bmQgcGF0aCAocmVsZWFzZXIsIHRpbWVvdXQpIHNlbmRzIHRoZSBmdW5kcy4KRml4ZWQgYXQgY3JlYXRpb24gdW5kZXIgdGhlIGZ1bmRlcidzIGF1dGggYW5kIG5ldmVyIGNob3NlbiBhdApwYXlvdXQsIHNvIGludmFyaWFudCBJMSBob2xkczsgZGVmYXVsdHMgdG8gYHBheWVyYCB3aGVuIG9taXR0ZWQgYXQKY3JlYXRpb24g4oCUIHNlZSBkb2NzL2Fkci8wMDA5LgAAAAAAAAlyZWZ1bmRfdG8AAAAAAAATAAAANkVhcmxpZXN0IGxlZGdlciB0aW1lc3RhbXAgYXQgd2hpY2ggcmVsZWFzZSBpcyBhbGxvd2VkLgAAAAAAEnJlbGVhc2Vfbm90X2JlZm9yZQAAAAAD6AAAAAYAAAC9QWRkcmVzc2VzIHBlcm1pdHRlZCB0byBzZXR0bGUgdGhpcyBlc2Nyb3cg4oCUIHNlZSBkb2NzL2Fkci8wMDAyIGZvciB0aGUKcGVyLWVzY3JvdyByZWxlYXNlciwgYW5kIGRvY3MvYWRyLzAwMDcgZm9yIE0tb2YtTiBzZXRzLiBBIHBsYWluCnNpbmdsZS1yZWxlYXNlciBlc2Nyb3cgc3RvcmVzIGV4YWN0bHkgb25lIGVudHJ5IGhlcmUuAAAAAAAACXJlbGVhc2VycwAAAAAAA+oAAAATAAAAOVdoZXRoZXIgcmVsZWFzZSByZXF1aXJlcyB0aGUgcGF5ZWUncyBleHBsaWNpdCBhY2NlcHRhbmNlLgAAAAAAABNyZXF1aXJlc19hY2NlcHRhbmNlAAAAAAEAAAAAAAAABnN0YXR1cwAAAAAH0AAAAAxFc2Nyb3dTdGF0dXMAAAC6SG93IG1hbnkgKmRpc3RpbmN0KiBhZGRyZXNzZXMgZnJvbSBgcmVsZWFzZXJzYCBtdXN0IGF1dGhvcml6ZSBvbmUKc2V0dGxlbWVudC4gQWx3YXlzIGA+PSAxYCBhbmQgYDw9IHJlbGVhc2Vycy5sZW4oKWA7IGAxYCBtZWFucyBhbnkKc2luZ2xlIHJlbGVhc2VyIGNhbiBzZXR0bGUgKHRoZSBwcmUtcXVvcnVtIGJlaGF2aW91cikuAAAAAAAJdGhyZXNob2xkAAAAAAAABAAAAAAAAAAFdG9rZW4AAAAAAAAT", "AAAAAQAAAYBPbmUgZW50cnkgb2YgYSBgY3JlYXRlX2VzY3Jvd3NgIGJhdGNoLiBNaXJyb3JzIHRoZSBzaW5nbGUtZXNjcm93CmNyZWF0aW9uIHBhcmFtZXRlcnMgbWludXMgdGhlIGJhdGNoLXdpZGUgYHBheWVyYC4KSW1tdXRhYmxlIGZ1bmRpbmcgY29uZmlndXJhdGlvbiBvZiBhIHBvb2xlZCBlc2Nyb3cgKGlzc3VlICMxMTMsCmRvY3MvYWRyLzAwMTEpLiBFeGlzdGVuY2Ugb2YgdGhpcyByZWNvcmQgdW5kZXIgYERhdGFLZXk6OlBvb2xlZChpZClgIGlzCndoYXQgbWFrZXMgYW4gZXNjcm93ICJwb29sZWQiOyB0aGUgYWdncmVnYXRlIGZ1bmRlZCBhbW91bnQgbGl2ZXMgaW4KYEVzY3Jvd0RhdGEuYW1vdW50YCAob25lIHNvdXJjZSBvZiB0cnV0aCBzaGFyZWQgd2l0aCBgc2V0dGxlKClgKS4AAAAAAAAAClBvb2xlZERhdGEAAAAAAAIAAAEJVW5peCBzZWNvbmRzIHVudGlsIHdoaWNoIGBjb250cmlidXRlYCBpcyBhY2NlcHRlZC4gV2hlbiBpdCBwYXNzZXMKd2l0aCB0aGUgdGFyZ2V0IHVubWV0LCB0aGUgcm91bmQgaGFzIGZhaWxlZDogY29udHJpYnV0aW9ucyBhcmUKZnJvemVuIGZvcmV2ZXIgYW5kIGV2ZXJ5IGNvbnRyaWJ1dG9yIG1heSBwdWxsIHRoZWlyIGV4YWN0IHJlY29yZGVkCmFtb3VudCBiYWNrIHdpdGggYGNsYWltX3JlZnVuZGAg4oCUIHRoZSBlc2Nyb3cgY2FuIG5ldmVyIGJlIHJlbGVhc2VkLgAAAAAAABBmdW5kaW5nX2RlYWRsaW5lAAAABgAAAIFUb3RhbCB0aGUgY29udHJpYnV0b3JzIG11c3QgcmVhY2ggZm9yIHJlbGVhc2UgdG8gYmVjb21lIHBvc3NpYmxlLgpTdHJpY3RseSBwb3NpdGl2ZSwgZml4ZWQgYXQgY3JlYXRpb24sIG5ldmVyIGNoYW5nZWQgYWZ0ZXJ3YXJkcy4AAAAAAAAOZnVuZGluZ190YXJnZXQAAAAAAAs=", @@ -661,7 +669,7 @@ export class Client extends ContractClient { "AAAAAAAAADxSZWFkLW9ubHkgc3RhdHVzIHF1ZXJ5LiBFcnJvcnMgaWYgYGVzY3Jvd19pZGAgZG9lc24ndCBleGlzdC4AAAAKZ2V0X3N0YXR1cwAAAAAAAQAAAAAAAAAJZXNjcm93X2lkAAAAAAAABgAAAAEAAAPpAAAH0AAAAAxFc2Nyb3dTdGF0dXMAAAAD", "AAAAAAAABABTZXR0bGVzIG1hbnkgZXNjcm93cyBpbiBvbmUgdHJhbnNhY3Rpb24gKGlzc3VlICMyOSwgZG9jcy9hZHIvMDAxMikg4oCUCnRoZSBmYXN0IHBhdGggZm9yIHRocmVhdCBtb2RlbCBUMSdzICJyYWNlIHRoZSBhdHRhY2tlciIgcmVzcG9uc2UgYW5kCmZvciBoaWdoLXZvbHVtZSBpbnRlZ3JhdG9ycy4gRWFjaCBgKGVzY3Jvd19pZCwgYWN0aW9uKWAgaXMgY2hlY2tlZApleGFjdGx5IGxpa2UgdGhlIHNpbmdsZS1lc2Nyb3cgZW50cnkgcG9pbnQgaXQgbWlycm9yczoKCi0gYFJlbGVhc2VgOiBgY2FsbGVyYCBtdXN0IGJlIGEgcmVsZWFzZXIgb2YgdGhhdCBlc2Nyb3cgd2l0aAp0aHJlc2hvbGQgMSwgdGhlIGVzY3JvdyBtdXN0IGJlIGBGdW5kZWRgLCBhIHBvb2xlZCBlc2Nyb3cgbXVzdCBiZQpmdWxseSBmdW5kZWQsIGFuZCBgcmVsZWFzZV9ub3RfYmVmb3JlYC9wYXllZSBhY2NlcHRhbmNlIGFwcGx5LgotIGBSZWZ1bmRgOiBwb29sZWQgZXNjcm93cyBhcmUgcmVqZWN0ZWQ7IGBjYWxsZXJgIG11c3QgYmUgYSByZWxlYXNlcgoodGhyZXNob2xkIDEpIHVubGVzcyBgcmVmdW5kX2FmdGVyYCBoYXMgcGFzc2VkLCBpbiB3aGljaCBjYXNlCmFueW9uZSBtYXkgcmVmdW5kIOKAlCBhbHdheXMgdG8gdGhlIHN0b3JlZCBgcmVmdW5kX3RvYC4KCmBjYWxsZXJgIGF1dGhvcml6ZXMgdGhlIHdob2xlIGJhdGNoIG9uY2UuIFBlci1vcCBhdXRob3JpdHkgY29tZXMKb25seSBmcm9tIGVhY2ggZXNjcm93J3Mgb3duIHN0b3JlZCByZWxlYXNlciBzZXQsIHNvIGEgYmF0Y2ggY2FuIG5ldmVyCnNldHRsZSBhbiBlc2Nyb3cgd2hvc2UgcmVsZWFzZXIgaXMgc29tZW9uZSBlbHNlOiB0aGF0IG9wIHJldHVybnMKYFVuYXV0aG9yaXplZGAgYW5kIHRvdWNoZXMgbm90aGluZy4KCioqQmVzdC1lZmZvcnQgd2l0aCBwZXItb3AgcmVzdWx0czoqKiB0aGUgcmV0dXJuZWQgdmVjdG9yIGhhcyBvbmUKZW50cnkgcGVyIGlucHV0IG9wLCBpbiBpbnB1dCBvcmRlci4gYE9rKCgpKWAgbWVhbnMgdGhhdCBlc2Nyb3cgd2FzCnNldHRsZWQgYnkgdGhpAAAAC3NldHRsZV9tYW55AAAAAAIAAAAAAAAABmNhbGxlcgAAAAAAEwAAAAAAAAADb3BzAAAAA+oAAAPtAAAAAgAAAAYAAAfQAAAADFNldHRsZUFjdGlvbgAAAAEAAAPpAAAD6gAAA+kAAAACAAAAAwAAAAM=", "AAAAAAAAA0JQdWxsLWJhc2VkIHJlZnVuZCAoaXNzdWUgIzExMywgZG9jcy9hZHIvMDAxMSk6IHBheXMgYGNvbnRyaWJ1dG9yYApleGFjdGx5IHRoZSBhbW91bnQgcmVjb3JkZWQgYWdhaW5zdCB0aGF0IGFkZHJlc3MsIG9uY2UuIEF2YWlsYWJsZQpvbmx5IGZvciBhICpmYWlsZWQqIGZ1bmRpbmcgcm91bmQg4oCUIHRoZSBmdW5kaW5nIGRlYWRsaW5lIGhhcyBwYXNzZWQKd2l0aCB0aGUgcG9vbGVkIHRvdGFsIHN0aWxsIGJlbG93IHRoZSB0YXJnZXQgKGBSZWZ1bmROb3RPcGVuYApvdGhlcndpc2UpIOKAlCBhbmQgb25seSB3aGlsZSB0aGUgZXNjcm93IGhhcyBub3QgYmVlbiByZWxlYXNlZAooYE5vdEZ1bmRlZGAgYWZ0ZXJ3YXJkczogcmVsZWFzZWQgZnVuZHMgY2FuIG5ldmVyIGJlIGNsYWltZWQpLgpFYWNoIGNsYWltIGlzIE8oMSkgd29yayDigJQgbm8gcGF0aCBpdGVyYXRlcyBjb250cmlidXRvcnMg4oCUIGFuZCBpdHMKb3duIGF1dGhvcml6YXRpb246IG5vIG9uZSBjYW4gY2xhaW0gb24gYW5vdGhlciBjb250cmlidXRvcidzCmJlaGFsZiAoYE5vQ29udHJpYnV0aW9uYCBmb3IgYW4gYWRkcmVzcyB3aXRoIG5vIHJlY29yZCksIGEgc2Vjb25kCmNsYWltIGZhaWxzIGBBbHJlYWR5UmVmdW5kZWRgLCBhbmQgdGhlIG9yZGVyIG9mIGNsYWltcyBjYW4gbmV2ZXIKY2hhbmdlIGFueW9uZSdzIGVudGl0bGVtZW50LiBDaGVja3MtZWZmZWN0cy1pbnRlcmFjdGlvbnM6IHRoZQpgcmVmdW5kZWRgIGZsYWcgYW5kIHRoZSBwb29sZWQgdG90YWwgYXJlIHdyaXR0ZW4gYmVmb3JlIHRoZQp0cmFuc2ZlciwgYW5kIGEgZmFpbGluZyB0cmFuc2ZlciByb2xscyB0aGUgd2hvbGUgY2xhaW0gYmFjay4AAAAAAAxjbGFpbV9yZWZ1bmQAAAACAAAAAAAAAAllc2Nyb3dfaWQAAAAAAAAGAAAAAAAAAAtjb250cmlidXRvcgAAAAATAAAAAQAAA+kAAAACAAAAAw==", - "AAAAAAAAAHtTZXRzIHRoZSBpbW11dGFibGUgdG9rZW4gYWxsb3dsaXN0IGF0IGRlcGxveW1lbnQuIEFuIGVtcHR5IGxpc3QKcHJlc2VydmVzIHRoZSBsZWdhY3kgYmVoYXZpb3IgYW5kIGFsbG93cyBhbnkgdG9rZW4gYWRkcmVzcy4AAAAADV9fY29uc3RydWN0b3IAAAAAAAABAAAAAAAAAA5hbGxvd2VkX3Rva2VucwAAAAAD6gAAABMAAAAA", + "AAAAAAAAAHtTZXRzIHRoZSBpbW11dGFibGUgdG9rZW4gYWxsb3dsaXN0IGF0IGRlcGxveW1lbnQuIEFuIGVtcHR5IGxpc3QKcHJlc2VydmVzIHRoZSBsZWdhY3kgYmVoYXZpb3IgYW5kIGFsbG93cyBhbnkgdG9rZW4gYWRkcmVzcy4AAAAADV9fY29uc3RydWN0b3IAAAAAAAACAAAAAAAAAA5hbGxvd2VkX3Rva2VucwAAAAAD6gAAABMAAAAAAAAAD21heGltdW1fYW1vdW50cwAAAAPsAAAAEwAAAAsAAAABAAAD6QAAAAIAAAAD", "AAAAAAAABABMb2NrcyBgYW1vdW50YCBvZiBgdG9rZW5gIHB1bGxlZCBmcm9tIGBwYXllcmAsIGhlbGQgZm9yIGBwYXllZWAsCmRvY3MvdGhyZWF0LW1vZGVsLm1kIFQxMCBhbmQgUk9BRE1BUC5tZCBQaGFzZSBFNSkuIGByZWxlYXNlcmAgaXMgdGhlCmFkZHJlc3MgcGVybWl0dGVkIHRvIGNhbGwgYHJlbGVhc2VgL2ByZWZ1bmRgIG9uIHRoaXMgZXNjcm93Cihkb2NzL2Fkci8wMDAyKS4gYHJlZnVuZF9hZnRlcmAgaXMgb3B0aW9uYWwgKGRvY3MvYWRyLzAwMDQpLgpgbm90aWZ5X3BheWVlYCBvcHRzIGFuIGltcGxlbWVudGluZyBjb250cmFjdCBwYXllZSBpbnRvCmBvbl9lc2Nyb3dfcmVsZWFzZWQoZXNjcm93X2lkLCBhbW91bnQpYCAoZG9jcy9hZHIvMDAwNSkuIFRoZSBwYXllcgptdXN0IGF1dGhvcml6ZSBjcmVhdGlvbiwgYW5kIHRoZSBwYXllZSBtdXN0IGFsc28gYXV0aG9yaXplIGlmCmBub3RpZnlfcGF5ZWVgIGlzIHRydWUuIGByZWZ1bmRfdG9gIGlzIHRoZSBvcHRpb25hbCByZWZ1bmQKZGVzdGluYXRpb24gZm9yIGEgc3BvbnNvcmVkIGVzY3JvdyB3aGVyZSB0aGUgZnVuZGVyIChgcGF5ZXJgKSBpcwpub3Qgd2hvIHNob3VsZCBnZXQgdGhlIG1vbmV5IGJhY2sgKGRvY3MvYWRyLzAwMDkpOiBgTm9uZWAgbWVhbnMKYHBheWVyYDsgaXQgbWF5IG5vdCBiZSB0aGlzIGNvbnRyYWN0J3Mgb3duIGFkZHJlc3MsIGFuZCB0aGUKYHBheWVyYCdzIGF1dGggb24gdGhpcyBjYWxsIGNvdmVycyBpdC4gRm9yIE0tb2YtTiByZWxlYXNlcnMgdXNlCmBjcmVhdGVfZXNjcm93X3dpdGhfcmVsZWFzZXJzYC4KYGZlZV9yZWNpcGllbnRgL2BmZWVfYnBzYCBhcmUgdGhlIG9wdGlvbmFsIHByb3RvY29sIGZlZSwgZml4ZWQgYXQKY3JlYXRpb24gYW5kIHRha2VuIGF0IHJlbGVhc2Ug4oCUIG5ldmVyIG9uIHJlZnVuZCDigJQgd2l0aCBgZmVlX2JwcyDiiaRgCltgTUFYX0ZFRV9CUFNgXSAoMTAgJSksIGZsb29yIHJvdW5kaW5nLCBhbmQgYm90aCBnaXZlbiB0b2dldGhlciBvcgpub3QgYXQgYWxsIChkb2NzL2Fkci8wMDEwKS4gYE5vbmVgAAAADWNyZWF0ZV9lc2Nyb3cAAAAAAAALAAAAAAAAAAVwYXllcgAAAAAAABMAAAAAAAAABXBheWVlAAAAAAAAEwAAAAAAAAAFdG9rZW4AAAAAAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAADWNvbmRpdGlvbl9yZWYAAAAAAAAQAAAAAAAAAAhyZWxlYXNlcgAAABMAAAAAAAAADHJlZnVuZF9hZnRlcgAAA+gAAAAGAAAAAAAAAAxub3RpZnlfcGF5ZWUAAAABAAAAAAAAAAlyZWZ1bmRfdG8AAAAAAAPoAAAAEwAAAAAAAAANZmVlX3JlY2lwaWVudAAAAAAAA+gAAAATAAAAAAAAAAdmZWVfYnBzAAAAA+gAAAAEAAAAAQAAA+kAAAAGAAAAAw==", "AAAAAAAAAaNCYXRjaCB2ZXJzaW9uIG9mIGBjcmVhdGVfZXNjcm93YC4gQ3JlYXRlcyBvbmUgZXNjcm93IHBlciBpdGVtLCBpbgppbnB1dCBvcmRlciwgYW5kIHJldHVybnMgdGhlIG5ldyBpZHMgaW4gdGhlIHNhbWUgb3JkZXIgYXMgYGl0ZW1zYC4KYHBheWVyYCBhdXRob3JpemVzIG9uY2UgZm9yIHRoZSB3aG9sZSBjYWxsLiBGYWlscyBhdG9taWNhbGx5OiBpZgphbnkgaXRlbSBpcyBpbnZhbGlkIChiYWQgYW1vdW50LCBwYXN0IGByZWZ1bmRfYWZ0ZXJgLCBvdmVyc2l6ZWQKYGNvbmRpdGlvbl9yZWZgLCBzaG9ydC1kZWxpdmVyaW5nIHRva2VuKSB0aGUgd2hvbGUgY2FsbCByZXZlcnRzIGFuZApubyBlc2Nyb3dzIGFyZSBjcmVhdGVkLgoKYGl0ZW1zLmxlbigpYCBtdXN0IGJlIGA8PSBNQVhfQkFUQ0hfU0laRWAg4oCUIHNlZSBkb2NzL2Fkci8wMDA1LgAAAAAOY3JlYXRlX2VzY3Jvd3MAAAAAAAIAAAAAAAAABXBheWVyAAAAAAAAEwAAAAAAAAAFaXRlbXMAAAAAAAPqAAAH0AAAAApDcmVhdGVJdGVtAAAAAAABAAAD6QAAA+oAAAAGAAAAAw==", "AAAAAAAAAPhSb3RhdGVzIGEgZnVuZGVkIGVzY3JvdydzIHJlbGVhc2VyLiBCb3RoIHRoZSBjdXJyZW50IHJlbGVhc2VyIGFuZApwYXllciBtdXN0IGF1dGhvcml6ZSB0aGUgY2hhbmdlOyB0aGUgcGF5ZXIncyBjb25zZW50IHByZXZlbnRzIGEKY29tcHJvbWlzZWQgcmVsZWFzZXIgZnJvbSBzaWxlbnRseSBhcHBvaW50aW5nIGFuIGF0dGFja2VyLiBUaGUKcmVwbGFjZW1lbnQgY2Fubm90IGJlIHRoZSBjb250cmFjdCBpdHNlbGYgb3IgdGhlIHBheWVlLgAAAA9yb3RhdGVfcmVsZWFzZXIAAAAAAwAAAAAAAAAJZXNjcm93X2lkAAAAAAAABgAAAAAAAAAGY2FsbGVyAAAAAAATAAAAAAAAAAxuZXdfcmVsZWFzZXIAAAATAAAAAQAAA+kAAAACAAAAAw==",