Problem
ContractConfig (stellar_send/src/lib.rs lines 62-73) has an active: bool field, documented as "Whether new payments are accepted. Set to true by initialize." It's set unconditionally to true in initialize (line 135) and then never read anywhere else in the crate — not in send_payment, send_path_payment, send_batch_payment, fulfill_payment_request, or execute_subscription. There is also no pause()/unpause() function that could ever set it to false.
Why it matters
This is dead state that implies functionality (pausability) which does not exist — directly related to issue #3's README-vs-implementation mismatch, but distinct: even purely at the Rust/storage level (ignoring the README), active is inert. Anyone reading ContractConfig's doc comment or calling get_config and seeing active: true would reasonably assume there's a way to flip it and that payments would then be blocked — neither is true. This is a footgun for integrators building admin tooling against the contract's declared shape.
Detection
grep -n "config.active\|\.active" stellar_send/src/*.rs shows the field is only ever written (in initialize), never read in a conditional, and no test in stellar_send/src/test.rs exercises pausing behavior (because it doesn't exist).
Proposed fix
Either (a) implement it properly — add pause()/unpause() admin-gated functions and an assert_active(&config) check called at the top of every value-moving entrypoint, returning a new StellarSendError::ContractPaused variant, or (b) if pause functionality is out of scope for now, remove the misleading active field entirely until it's actually wired up. Given issue #3 already tracks the README correction and eventual pause/unpause implementation, (a) is likely the better outcome to land alongside that fix rather than duplicating effort — but this issue exists separately because it can be caught and reasoned about purely from the Rust source, without needing to cross-reference the README.
Edge cases
- If implemented,
cancel_subscription/cancel_payment_request should probably remain callable while paused (users should always be able to exit, only new value-movement should block).
get_config should still work while paused (read access shouldn't be gated).
- Pausing mid-batch (
send_batch_payment) isn't a real race in Soroban (single-threaded, atomic per invocation) but the guard still needs to be checked once at the top of the call, not per-leg, to avoid wasted work if paused.
Testing strategy
Add test_active_field_currently_unused (documenting today's state, marked to be removed/updated once pause lands) or, preferably, resolve this issue by implementing pause per the sketch above with test_pause_blocks_send_payment, test_unpause_restores_send_payment, and test_paused_contract_allows_cancel_subscription.
Problem
ContractConfig(stellar_send/src/lib.rslines 62-73) has anactive: boolfield, documented as "Whether new payments are accepted. Set to true byinitialize." It's set unconditionally totrueininitialize(line 135) and then never read anywhere else in the crate — not insend_payment,send_path_payment,send_batch_payment,fulfill_payment_request, orexecute_subscription. There is also nopause()/unpause()function that could ever set it tofalse.Why it matters
This is dead state that implies functionality (pausability) which does not exist — directly related to issue #3's README-vs-implementation mismatch, but distinct: even purely at the Rust/storage level (ignoring the README),
activeis inert. Anyone readingContractConfig's doc comment or callingget_configand seeingactive: truewould reasonably assume there's a way to flip it and that payments would then be blocked — neither is true. This is a footgun for integrators building admin tooling against the contract's declared shape.Detection
grep -n "config.active\|\.active" stellar_send/src/*.rsshows the field is only ever written (ininitialize), never read in a conditional, and no test instellar_send/src/test.rsexercises pausing behavior (because it doesn't exist).Proposed fix
Either (a) implement it properly — add
pause()/unpause()admin-gated functions and anassert_active(&config)check called at the top of every value-moving entrypoint, returning a newStellarSendError::ContractPausedvariant, or (b) if pause functionality is out of scope for now, remove the misleadingactivefield entirely until it's actually wired up. Given issue #3 already tracks the README correction and eventualpause/unpauseimplementation, (a) is likely the better outcome to land alongside that fix rather than duplicating effort — but this issue exists separately because it can be caught and reasoned about purely from the Rust source, without needing to cross-reference the README.Edge cases
cancel_subscription/cancel_payment_requestshould probably remain callable while paused (users should always be able to exit, only new value-movement should block).get_configshould still work while paused (read access shouldn't be gated).send_batch_payment) isn't a real race in Soroban (single-threaded, atomic per invocation) but the guard still needs to be checked once at the top of the call, not per-leg, to avoid wasted work if paused.Testing strategy
Add
test_active_field_currently_unused(documenting today's state, marked to be removed/updated once pause lands) or, preferably, resolve this issue by implementing pause per the sketch above withtest_pause_blocks_send_payment,test_unpause_restores_send_payment, andtest_paused_contract_allows_cancel_subscription.