From d3a78afd02146f6d7cfbf697cffb150876236fdb Mon Sep 17 00:00:00 2001 From: kevindurant735rocket-creator Date: Thu, 15 Oct 2026 17:24:47 +0800 Subject: [PATCH 1/2] feat(contract): add get_config getter (closes #173) --- PROGRESS.md | 11 + contracts/deprader_router/src/lib.rs | 20 + contracts/deprader_router/src/test.rs | 14 +- .../test_get_config_matches_constants.1.json | 464 ++++++++++++++++++ 4 files changed, 507 insertions(+), 2 deletions(-) create mode 100644 contracts/deprader_router/test_snapshots/test/test_get_config_matches_constants.1.json diff --git a/PROGRESS.md b/PROGRESS.md index bab63fb..053a171 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -319,3 +319,14 @@ is closed — see [CONTRIBUTING.md](CONTRIBUTING.md). - **By:** ALLEN-AYODEJI - **Closes:** N/A - **Status:** Merged. + +### deprader_router contract — `get_config` getter + +- **What:** Added `Config` struct (`review_window_secs`, `max_bounty_duration_secs`, + `max_claims_per_bounty`, `max_ref_len`) and `get_config() -> Config` returning + the router's configured limits, so off-chain clients do not hard-code them. + Added `test_get_config_matches_constants`. +- **By:** kevindurant735rocket-creator +- **Closes:** #173 +- **Status:** `cargo fmt`, `cargo clippy -- -D warnings`, and + `cargo test --workspace` (22 tests) pass. diff --git a/contracts/deprader_router/src/lib.rs b/contracts/deprader_router/src/lib.rs index ca0ef3a..545a16b 100644 --- a/contracts/deprader_router/src/lib.rs +++ b/contracts/deprader_router/src/lib.rs @@ -81,6 +81,15 @@ pub struct Claim { pub status: ClaimStatus, } +#[contracttype] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Config { + pub review_window_secs: u64, + pub max_bounty_duration_secs: u64, + pub max_claims_per_bounty: u32, + pub max_ref_len: u32, +} + #[contracttype] enum DataKey { Admin, @@ -173,6 +182,17 @@ impl DepRaderRouter { env.storage().instance().get(&DataKey::PendingAdmin) } + /// Returns the router's configured limits so off-chain clients do not + /// need to hard-code them. + pub fn get_config(_env: Env) -> Config { + Config { + review_window_secs: REVIEW_WINDOW_SECS, + max_bounty_duration_secs: MAX_BOUNTY_DURATION_SECS, + max_claims_per_bounty: MAX_CLAIMS_PER_BOUNTY, + max_ref_len: MAX_REF_LEN, + } + } + // ------------------------------------------------------------- bounties /// Locks `amount` of `token` from `creator` against a new bounty and diff --git a/contracts/deprader_router/src/test.rs b/contracts/deprader_router/src/test.rs index b30f566..eb03952 100644 --- a/contracts/deprader_router/src/test.rs +++ b/contracts/deprader_router/src/test.rs @@ -1,6 +1,6 @@ use super::{ - BountyStatus, ClaimStatus, DepRaderRouter, DepRaderRouterClient, Error, - MAX_BOUNTY_DURATION_SECS, MAX_CLAIMS_PER_BOUNTY, REVIEW_WINDOW_SECS, + BountyStatus, ClaimStatus, Config, DepRaderRouter, DepRaderRouterClient, Error, + MAX_BOUNTY_DURATION_SECS, MAX_CLAIMS_PER_BOUNTY, MAX_REF_LEN, REVIEW_WINDOW_SECS, }; use soroban_sdk::{ symbol_short, @@ -513,3 +513,13 @@ fn test_admin_rotation_is_two_step() { t.client.release(&bounty_id, &claim_id); assert_eq!(t.last_auth(), new_admin); } + +#[test] +fn test_get_config_matches_constants() { + let t = setup(); + let config = t.client.get_config(); + assert_eq!(config.review_window_secs, REVIEW_WINDOW_SECS); + assert_eq!(config.max_bounty_duration_secs, MAX_BOUNTY_DURATION_SECS); + assert_eq!(config.max_claims_per_bounty, MAX_CLAIMS_PER_BOUNTY); + assert_eq!(config.max_ref_len, MAX_REF_LEN); +} diff --git a/contracts/deprader_router/test_snapshots/test/test_get_config_matches_constants.1.json b/contracts/deprader_router/test_snapshots/test/test_get_config_matches_constants.1.json new file mode 100644 index 0000000..89e5c58 --- /dev/null +++ b/contracts/deprader_router/test_snapshots/test/test_get_config_matches_constants.1.json @@ -0,0 +1,464 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1000000, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + }, + [ + { + "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" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 518400 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file From 769d6c6afe7987752c0d2179185a73061ab52433 Mon Sep 17 00:00:00 2001 From: kevindurant735rocket-creator Date: Thu, 15 Oct 2026 18:04:06 +0800 Subject: [PATCH 2/2] chore(contract): remove unused Config import in test (lint fix) --- contracts/deprader_router/src/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/deprader_router/src/test.rs b/contracts/deprader_router/src/test.rs index eb03952..b7a06fd 100644 --- a/contracts/deprader_router/src/test.rs +++ b/contracts/deprader_router/src/test.rs @@ -1,5 +1,5 @@ use super::{ - BountyStatus, ClaimStatus, Config, DepRaderRouter, DepRaderRouterClient, Error, + BountyStatus, ClaimStatus, DepRaderRouter, DepRaderRouterClient, Error, MAX_BOUNTY_DURATION_SECS, MAX_CLAIMS_PER_BOUNTY, MAX_REF_LEN, REVIEW_WINDOW_SECS, }; use soroban_sdk::{