@@ -5145,6 +5145,27 @@ fn test_is_contract_paused_independent_per_instance() {
51455145 assert ! ( !client_2. is_contract_paused( ) ) ;
51465146}
51475147
5148+ // ═══════════════════════════════════════════════════════════════════════════
5149+ // is_pool_active Helper Tests
5150+ // ═══════════════════════════════════════════════════════════════════════════
5151+
5152+ /// is_pool_active returns true for a freshly created pool.
5153+ #[ test]
5154+ fn test_is_pool_active_returns_true_for_active_pool ( ) {
5155+ let env = Env :: default ( ) ;
5156+ env. mock_all_auths ( ) ;
5157+
5158+ let ( _, client, token_address, _, _, _, _, creator) = setup ( & env) ;
5159+
5160+ let pool_id = client. create_pool (
5161+ & creator,
5162+ & 100_000u64 ,
5163+ & token_address,
5164+ & 2u32 ,
5165+ & symbol_short ! ( "Tech" ) ,
5166+ & PoolConfig {
5167+ description : String :: from_str ( & env, "Active pool test" ) ,
5168+ metadata_url : String :: from_str ( & env, "ipfs://active" ) ,
51485169// ── bump_ttl helper tests ────────────────────────────────────────────────────
51495170
51505171/// Helper: create an env with predictable ledger settings for TTL assertions.
@@ -5192,6 +5213,248 @@ fn create_test_pool(
51925213 String :: from_str( env, "Outcome 1" ) ,
51935214 ] ,
51945215 } ,
5216+ ) ;
5217+
5218+ let pool = client. get_pool ( & pool_id) ;
5219+ // All three conditions must hold for an active pool.
5220+ assert ! ( !pool. resolved) ;
5221+ assert ! ( !pool. canceled) ;
5222+ assert_eq ! ( pool. state, MarketState :: Active ) ;
5223+ }
5224+
5225+ /// is_pool_active returns false (via behavior) after pool is resolved —
5226+ /// resolve_pool on an already-resolved pool must panic.
5227+ #[ test]
5228+ #[ should_panic( expected = "Pool already resolved" ) ]
5229+ fn test_is_pool_active_false_after_resolve ( ) {
5230+ let env = Env :: default ( ) ;
5231+ env. mock_all_auths ( ) ;
5232+
5233+ let ( _, client, token_address, _, _, _, operator, creator) = setup ( & env) ;
5234+
5235+ let pool_id = client. create_pool (
5236+ & creator,
5237+ & 100_000u64 ,
5238+ & token_address,
5239+ & 2u32 ,
5240+ & symbol_short ! ( "Tech" ) ,
5241+ & PoolConfig {
5242+ description : String :: from_str ( & env, "Resolve inactive test" ) ,
5243+ metadata_url : String :: from_str ( & env, "ipfs://resolved" ) ,
5244+ min_stake : 1i128 ,
5245+ max_stake : 0i128 ,
5246+ initial_liquidity : 0i128 ,
5247+ required_resolutions : 1u32 ,
5248+ private : false ,
5249+ whitelist_key : None ,
5250+ } ,
5251+ ) ;
5252+
5253+ env. ledger ( ) . with_mut ( |li| li. timestamp = 100_001 ) ;
5254+ client. resolve_pool ( & operator, & pool_id, & 0u32 ) ;
5255+
5256+ // Pool is now resolved — resolved == true, state == Resolved.
5257+ // is_pool_active would return false, so a second resolve attempt must panic.
5258+ client. resolve_pool ( & operator, & pool_id, & 0u32 ) ;
5259+ }
5260+
5261+ /// is_pool_active returns false (via behavior) after pool is canceled —
5262+ /// place_prediction on a canceled pool must panic with the correct message.
5263+ #[ test]
5264+ #[ should_panic( expected = "Cannot place prediction on canceled pool" ) ]
5265+ fn test_is_pool_active_false_after_cancel ( ) {
5266+ let env = Env :: default ( ) ;
5267+ env. mock_all_auths ( ) ;
5268+
5269+ let ( _, client, token_address, _, token_admin_client, _, operator, creator) = setup ( & env) ;
5270+
5271+ let pool_id = client. create_pool (
5272+ & creator,
5273+ & 100_000u64 ,
5274+ & token_address,
5275+ & 2u32 ,
5276+ & symbol_short ! ( "Tech" ) ,
5277+ & PoolConfig {
5278+ description : String :: from_str ( & env, "Cancel inactive test" ) ,
5279+ metadata_url : String :: from_str ( & env, "ipfs://canceled" ) ,
5280+ min_stake : 1i128 ,
5281+ max_stake : 0i128 ,
5282+ initial_liquidity : 0i128 ,
5283+ required_resolutions : 1u32 ,
5284+ private : false ,
5285+ whitelist_key : None ,
5286+ } ,
5287+ ) ;
5288+
5289+ client. cancel_pool ( & operator, & pool_id) ;
5290+
5291+ let user = Address :: generate ( & env) ;
5292+ token_admin_client. mint ( & user, & 500 ) ;
5293+
5294+ // Pool is canceled — is_pool_active returns false.
5295+ // place_prediction must be blocked.
5296+ client. place_prediction ( & user, & pool_id, & 100 , & 0 , & None , & None ) ;
5297+ }
5298+
5299+ /// Resolving a canceled pool must be blocked — verifies is_pool_active
5300+ /// integration in resolve_pool.
5301+ #[ test]
5302+ #[ should_panic( expected = "Cannot resolve a canceled pool" ) ]
5303+ fn test_is_pool_active_blocks_resolve_on_canceled_pool ( ) {
5304+ let env = Env :: default ( ) ;
5305+ env. mock_all_auths ( ) ;
5306+
5307+ let ( _, client, token_address, _, _, _, operator, creator) = setup ( & env) ;
5308+
5309+ let pool_id = client. create_pool (
5310+ & creator,
5311+ & 100_000u64 ,
5312+ & token_address,
5313+ & 2u32 ,
5314+ & symbol_short ! ( "Tech" ) ,
5315+ & PoolConfig {
5316+ description : String :: from_str ( & env, "Cancel then resolve test" ) ,
5317+ metadata_url : String :: from_str ( & env, "ipfs://cancelresolve" ) ,
5318+ min_stake : 1i128 ,
5319+ max_stake : 0i128 ,
5320+ initial_liquidity : 0i128 ,
5321+ required_resolutions : 1u32 ,
5322+ private : false ,
5323+ whitelist_key : None ,
5324+ } ,
5325+ ) ;
5326+
5327+ client. cancel_pool ( & operator, & pool_id) ;
5328+
5329+ env. ledger ( ) . with_mut ( |li| li. timestamp = 100_001 ) ;
5330+ // is_pool_active == false → should panic
5331+ client. resolve_pool ( & operator, & pool_id, & 0u32 ) ;
5332+ }
5333+
5334+ /// Canceling a canceled pool a second time must be blocked — verifies
5335+ /// is_pool_active integration in cancel_pool.
5336+ #[ test]
5337+ #[ should_panic( expected = "Pool already canceled" ) ]
5338+ fn test_is_pool_active_blocks_double_cancel ( ) {
5339+ let env = Env :: default ( ) ;
5340+ env. mock_all_auths ( ) ;
5341+
5342+ let ( _, client, token_address, _, _, _, operator, creator) = setup ( & env) ;
5343+
5344+ let pool_id = client. create_pool (
5345+ & creator,
5346+ & 100_000u64 ,
5347+ & token_address,
5348+ & 2u32 ,
5349+ & symbol_short ! ( "Tech" ) ,
5350+ & PoolConfig {
5351+ description : String :: from_str ( & env, "Double cancel test" ) ,
5352+ metadata_url : String :: from_str ( & env, "ipfs://doublecancel" ) ,
5353+ min_stake : 1i128 ,
5354+ max_stake : 0i128 ,
5355+ initial_liquidity : 0i128 ,
5356+ required_resolutions : 1u32 ,
5357+ private : false ,
5358+ whitelist_key : None ,
5359+ } ,
5360+ ) ;
5361+
5362+ client. cancel_pool ( & operator, & pool_id) ;
5363+ // Second cancel: is_pool_active == false → should panic
5364+ client. cancel_pool ( & operator, & pool_id) ;
5365+ }
5366+
5367+ /// increase_max_total_stake on a resolved pool must return InvalidPoolState —
5368+ /// verifies is_pool_active integration in that function too.
5369+ #[ test]
5370+ #[ should_panic( expected = "Error(Contract, #24)" ) ]
5371+ fn test_is_pool_active_blocks_increase_max_stake_on_resolved_pool ( ) {
5372+ let env = Env :: default ( ) ;
5373+ env. mock_all_auths ( ) ;
5374+
5375+ let ( _, client, token_address, _, _, _, operator, creator) = setup ( & env) ;
5376+
5377+ let pool_id = client. create_pool (
5378+ & creator,
5379+ & 100_000u64 ,
5380+ & token_address,
5381+ & 2u32 ,
5382+ & symbol_short ! ( "Tech" ) ,
5383+ & PoolConfig {
5384+ description : String :: from_str ( & env, "Max stake resolved test" ) ,
5385+ metadata_url : String :: from_str ( & env, "ipfs://maxresolved" ) ,
5386+ min_stake : 1i128 ,
5387+ max_stake : 0i128 ,
5388+ initial_liquidity : 0i128 ,
5389+ required_resolutions : 1u32 ,
5390+ private : false ,
5391+ whitelist_key : None ,
5392+ } ,
5393+ ) ;
5394+
5395+ env. ledger ( ) . with_mut ( |li| li. timestamp = 100_001 ) ;
5396+ client. resolve_pool ( & operator, & pool_id, & 0u32 ) ;
5397+
5398+ // Pool resolved → is_pool_active == false → must return InvalidPoolState (24)
5399+ client. increase_max_total_stake ( & creator, & pool_id, & 500_000 ) ;
5400+ }
5401+
5402+ /// Full lifecycle: active → predictions → resolve → claim.
5403+ /// Confirms is_pool_active correctly gates each phase without regression.
5404+ #[ test]
5405+ fn test_is_pool_active_full_lifecycle ( ) {
5406+ let env = Env :: default ( ) ;
5407+ env. mock_all_auths ( ) ;
5408+
5409+ let ( _, client, token_address, token, token_admin_client, _, operator, creator) = setup ( & env) ;
5410+ let contract_addr = client. address . clone ( ) ;
5411+
5412+ let pool_id = client. create_pool (
5413+ & creator,
5414+ & 100_000u64 ,
5415+ & token_address,
5416+ & 2u32 ,
5417+ & symbol_short ! ( "Tech" ) ,
5418+ & PoolConfig {
5419+ description : String :: from_str ( & env, "Lifecycle test" ) ,
5420+ metadata_url : String :: from_str ( & env, "ipfs://lifecycle" ) ,
5421+ min_stake : 1i128 ,
5422+ max_stake : 0i128 ,
5423+ initial_liquidity : 0i128 ,
5424+ required_resolutions : 1u32 ,
5425+ private : false ,
5426+ whitelist_key : None ,
5427+ } ,
5428+ ) ;
5429+
5430+ // Phase 1: pool is active — predictions accepted.
5431+ let pool = client. get_pool ( & pool_id) ;
5432+ assert ! ( !pool. resolved && !pool. canceled && pool. state == MarketState :: Active ) ;
5433+
5434+ let user_win = Address :: generate ( & env) ;
5435+ let user_lose = Address :: generate ( & env) ;
5436+ token_admin_client. mint ( & user_win, & 300 ) ;
5437+ token_admin_client. mint ( & user_lose, & 200 ) ;
5438+
5439+ client. place_prediction ( & user_win, & pool_id, & 300 , & 0 , & None , & None ) ;
5440+ client. place_prediction ( & user_lose, & pool_id, & 200 , & 1 , & None , & None ) ;
5441+ assert_eq ! ( token. balance( & contract_addr) , 500 ) ;
5442+
5443+ // Phase 2: resolve — pool transitions to inactive.
5444+ env. ledger ( ) . with_mut ( |li| li. timestamp = 100_001 ) ;
5445+ client. resolve_pool ( & operator, & pool_id, & 0u32 ) ;
5446+
5447+ let pool = client. get_pool ( & pool_id) ;
5448+ assert ! ( pool. resolved) ;
5449+ assert_eq ! ( pool. state, MarketState :: Resolved ) ;
5450+
5451+ // Phase 3: claims work correctly post-resolution.
5452+ let w = client. claim_winnings ( & user_win, & pool_id) ;
5453+ assert_eq ! ( w, 500 ) ;
5454+ let l = client. claim_winnings ( & user_lose, & pool_id) ;
5455+ assert_eq ! ( l, 0 ) ;
5456+ assert_eq ! ( token. balance( & contract_addr) , 0 ) ;
5457+ }
51955458 )
51965459}
51975460
0 commit comments