fix(contract): issues 816-819 — pause expiry getter, day-index cap, t… - #960
Open
talktosam2003 wants to merge 7 commits into
Open
fix(contract): issues 816-819 — pause expiry getter, day-index cap, t…#960talktosam2003 wants to merge 7 commits into
talktosam2003 wants to merge 7 commits into
Conversation
…oken validation, typed errors SiLioLabs#816 — get_pause_expiry read API + auto-resume event consistency - Add pub fn get_pause_expiry(env, user) -> Option<u64> in lib.rs (delegates to storage::get_pause_expiry, no auth required) - Verified try_auto_resume in charge_exec.rs already clears PauseExpiry and emits subscription_auto_resumed on both charge() and batch_charge() paths - Tests: get_pause_expiry returns None/expiry/u64::MAX, cleared on resume, cleared after charge/batch_charge auto-resume, event assertions SiLioLabs#817 — enforce MAX_MERCHANT_REVENUE_DAY_INDEX_SIZE with typed overflow error - Add MAX_MERCHANT_REVENUE_DAY_INDEX_SIZE = 365 constant in merchant_stats.rs (documented: ~1 year cap, operators use prune_merchant_revenue_days to free) - Enforce cap at day-index append time in increment_revenue_with_daily; fails closed with ContractError::MerchantDayIndexFull = 41 - Existing-day updates (is_new_day == false) always succeed - Add MerchantDayIndexFull = 41 to errors.rs - Tests: cap-1 succeeds, cap+1 fails with SiLioLabs#41, same-day update at cap succeeds SiLioLabs#818 — validate token contract address + SAC interface on subscribe - Extract require_valid_token_address() helper in validation.rs (XDR byte-7 discriminant check + token::Client::new.decimals() probe) - Replace inline XDR check in subscribe_inner with the new helper - Validation fires before any subscription state is written; no row on failure - Tests: valid SAC succeeds, second token succeeds, non-SAC rejected, no subscription row written on failure SiLioLabs#819 — convert string panic/expect in admin, fee, grace, upgrade to ContractError - admin.rs accept_admin: .expect('no pending admin') → NoPendingAdmin = 42 - storage.rs get_admin: .expect('admin not set') → NotInitialized = 7 - grace.rs propose_grace_period: assert!(...) → AmountExceedsMaximum = 15 - lib.rs set_min_interval: assert!(...) → IntervalMustBePositive = 3 - lib.rs set_initial_admin: panic!('admin already set') → AlreadyInitialized = 1 - Add NoPendingAdmin = 42 to errors.rs - Update affected #[should_panic(expected = ...)] tests to use typed error codes - Delete 8 stale snapshots (auto-regenerated by cargo test with new errors) - Converted sites: admin.rs/accept_admin, storage.rs/get_admin, grace.rs/propose_grace_period, lib.rs/set_min_interval + set_initial_admin
|
@talktosam2003 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
…ontractError
- Remove UTF-8 BOM from contract/src/test.rs (introduced as a merge
artefact, caused the file to fail compilation on Linux CI)
- Restore 8 test snapshots deleted by the PR branch, then update their
diagnostic events to match the new env.panic_with_error() call sites:
* 'admin not set' raw panic -> ContractError::NotInitialized (SiLioLabs#7)
* 'no pending admin' raw panic -> ContractError::NoPendingAdmin (SiLioLabs#42)
* 'min interval must be positive' raw panic -> ContractError::IntervalMustBePositive (SiLioLabs#3)
Each snapshot had its 'log' event block (caught panic string) removed
and every 'wasm_vm: invalid_action' error replaced with 'contract: N'
to match what the host records when panic_with_error is used.
…osam2003/PayFlow into fix/issues-816-817-818-819
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Close #816
Close #817
close #818
close #819
feat(contract): API expansion, day-index safety caps, SAC token validation, and typed errors (#816, #817, #818, #819)
Title
feat(contract): implement pause expiry API, merchant day cap, SAC token validation, and typed errors📌 Summary & Context
This pull request resolves four contract-level stability, state integrity, and developer-experience issues (#816, #817, #818, and #819).
Together, these changes:
ContractErrorvariants for robust client-side handling.🛠 Detailed Breakdown of Changes
1. Issue #816 — Pause Expiry Read API & Event Consistency
pub fn get_pause_expiry(env: Env, user: Address) -> Option<u64>inlib.rs, which delegates directly tostorage::get_pause_expiry. As a read-only view, it requires no authentication.pause()writesu64::MAXto represent an indefinite pause.pause_until(expiry)writes the specific Unix timestamp.Some(u64)for both states andNonewhen active.charge()andbatch_charge()paths cleanly erasePauseExpiryfrom storage and emitsubscription_auto_resumedevents when charging past an expired pause window.2. Issue #817 — Max Merchant Revenue Day-Index Size Cap
MAX_MERCHANT_REVENUE_DAY_INDEX_SIZE = 365inmerchant_stats.rs. Included inline documentation explaining that a 1-year daily index bounds storage pressure and requires operators to utilize existingprune_merchant_revenue_daysAPIs.increment_revenue_with_daily. Attempting to append a new day beyond 365 returnsContractError::MerchantDayIndexFull(Error Code41).is_new_day == false) bypasses the check, ensuring operational continuity even when the index array is full.MerchantDayIndexFull = 41inerrors.rs.3. Issue #818 — Token Address & SAC Interface Validation
require_valid_token_address()invalidation.rsfeaturing a two-layer validation strategy:ContractError::InvalidTokenAddress(Error Code12).token::Client::new(env, addr).decimals()host call to verify Stellar Asset Contract (SAC) compliance without blowing CPU limits.subscribe_innerprior to state updates, guaranteeing no orphaned or corruptSubscriptionstorage rows are written if validation fails.4. Issue #819 — Typed ContractError Conversion for Core Modules
panic!and.expect()calls acrossadmin.rs,fee.rs,grace.rs,upgrade.rs, and their wrapper sites inlib.rsandstorage.rs.NoPendingAdmin = 42toerrors.rs.ContractErroradmin.rsaccept_admin.expect("no pending admin")ContractError::NoPendingAdmin(42)storage.rsget_admin.expect("admin not set")ContractError::NotInitialized(7)grace.rspropose_grace_periodassert!(…, "grace period too large")ContractError::AmountExceedsMaximum(15)lib.rsset_min_intervalassert!(…, "min interval must be positive")ContractError::IntervalMustBePositive(3)lib.rsset_initial_adminpanic!("admin already set")ContractError::AlreadyInitialized(1)🧪 Testing & Validation
All acceptance criteria have been verified against local cargo test suites.
Summary of Added/Updated Unit Tests
Noneoutput, timestamp verification, clearing on manual resume, clearing on single/batch auto-resume charges, event assertion checks, and premature charge prevention before expiry.cap-1success,cap+1failure returning error#41, and successful same-day revenue updates at max capacity.0), oversized grace periods, and two-step happy path executions. Deleted 8 obsolete string-panic snapshot files.Execution Commands