Skip to content

Create campaign milestone celebration maintainability for Frontend UI - #1

Open
Keengfk wants to merge 387 commits into
Keengfk:mainfrom
Crowdfunding-DApp:main
Open

Create campaign milestone celebration maintainability for Frontend UI#1
Keengfk wants to merge 387 commits into
Keengfk:mainfrom
Crowdfunding-DApp:main

Conversation

@Keengfk

@Keengfk Keengfk commented Mar 29, 2026

Copy link
Copy Markdown
Owner

Create campaign milestone celebration maintainability for Frontend UI. done

obajecollinsmicheal-cmd and others added 30 commits March 28, 2026 13:50
- bump svgo 3.3.2 -> 3.3.3 (CVE: GHSA-xpqw-6gx7-v673, high severity DoS)
- add allowJs: true to jest ts-jest config to fix ESM import errors in .js test files
- fix FIXED_TIMESTAMP in dateFormatter.test.js (1740182400 was 2025, corrected to 1771718400 for 2026)
- fix isExpired(0) returning false by using null check instead of falsy check

All 100 tests passing, 0 npm vulnerabilities
…ests and docs

- Add contract_state_size module with MAX_CONTRIBUTORS (1000),
  MAX_ROADMAP_ITEMS (20), MAX_STRETCH_GOALS (10), MAX_STRING_LEN (256)
- Add StateSizeError with stable discriminants (100-103)
- Wire check_contributor_limit into contribute()
- Wire check_pledger_limit into pledge()
- Wire check_string_len + check_roadmap_limit into add_roadmap_item()
- Wire check_stretch_goal_limit into add_stretch_goal()
- 19 unit tests covering all helpers, boundary conditions, and error codes
- Add docs/contract_state_size.md with rationale and integration table
- Fix pre-existing duplicate refund_single definition and duplicate
  token transfer in refund_single (double-spend bug)
- Fix pre-existing duplicate args field in refund_single_token_tests.rs

Closes #373
…ty with tests and docs

- Extract validate_refund_preconditions: pure guard returning Ok(amount)
  or the appropriate ContractError (CampaignStillActive, GoalReached,
  NothingToRefund, or panic on Successful/Cancelled)
- Extract execute_refund_single: atomic CEI execution — zeroes storage
  before token transfer to prevent re-entrancy / double-claim
- refund_single in lib.rs reduced to 3 lines delegating to the helpers
- Add refund_single_token.test.rs with 15 unit tests covering both helpers
- Update refund_single_token.md with full API reference and security model

Closes #328
…r-smart-contract with tests and docs

- Bump soroban-sdk 22.0.1 → 22.0.11 (latest 22.x patch) in workspace
- Bump proptest 1.4 → 1.11.0 (dev-only) in crowdfund Cargo.toml
- Add cargo_toml_rust.rs: pinned version constants, DepRecord type,
  audited_dependencies() and all_deprecated_versions_replaced() helpers
- Add cargo_toml_rust.test.rs: 15 tests covering version pins, dep
  metadata, deprecation flags, and record equality
- Add docs/cargo_toml_rust.md with upgrade rationale and security notes

Closes #327
…-scripts with tests and docs

- Add bounded [LOG] key=value lines to deploy.sh (max 7) and interact.sh (2 per action)
- Unknown action in interact.sh emits 1 error log line and exits 1
- Update readme_md_installation.md with Logging Bounds section documenting
  format, per-script line counts, grep parsing examples, and security notes
- Add readme_md_installation.test.js: 33 tests covering prerequisites,
  script permissions, log line counts, format validation, injection guard,
  and README content assertions
- Fix pre-existing jest.config.json syntax error (] → } in transform block)

Closes #297
…pts with tests and docs

Test Output:
  CssVariableValidator: isValidVariableName passes for valid vars and handles invalid/malicious ones properly.
  CssVariablesUsage: Set and Get handle defined CSS variables safely without injection vectors.
  useDocsCssVariable hook executes correctly under test.
Coverage:
  Statements: 98.57%
  Branches: 86.95%
  Functions: 100%
  Lines: 98.57%

Security Notes:
- Validation restricts input strictly to the ALLOWED_CSS_VARIABLES list derived directly from a unified THEME object.
- DANGEROUS_CSS_PATTERN filters out XSS payloads using url(), javascript:, text/css, expression() and @import syntax blockages.
- Safe implementation of cssVar, cssCalc, and hooks to strictly enforce secure variable passing without unsafe arbitrary strings.
Removes duplicate module declarations and fixes the token minter test filename wiring in lib.rs, plus updates docs to reference the correct test file path.

Made-with: Cursor
…for-smart-contract with tests and docs

Extracts initialize validation/storage into a dedicated module, adds initialize-focused security tests, and documents assumptions and test execution for easier review and maintenance.

Made-with: Cursor
…ditions-for-gas-efficiency with tests and docs

Adds bounded proptest case and batch helpers for scalability, comprehensive boundary property tests, and documentation covering gas-efficiency assumptions and test execution.

Made-with: Cursor
…for-frontend-ui with tests and docs

Adds bounded frontend/scalability helpers for Soroban minor-bump workflows, a focused test module, and documentation covering security assumptions and test execution.

Made-with: Cursor
- Extract initialize() into execute_initialize() with named InitParams struct
- Replace panics with typed ContractError variants (codes 8-12)
- Enforce validate-before-write ordering
- Emit structured initialized event for off-chain indexers
- Add 50-test suite and crowdfund_initialize_function.md

Closes #325
…ansfer logic for security (closes #320)

- Add amount > 0 check in refund_single_transfer to skip no-op transfers (gas opt)
- Add debug event (debug, refund_transfer_attempt) before transfers
- Remove duplicate inline transfer in lib.rs refund_single
- Add comprehensive security tests in refund_single_token_security_tests.rs
- Update docs with zero-opt/logging details and test references

All tests pass, changes secure/efficient.
- Call token::Client::decimals() during initialize to verify the token
  address implements the SEP-41 interface; traps on invalid addresses.
- Store the result under DataKey::TokenDecimals so callers can convert
  raw atomic amounts to human-readable values (amount / 10^decimals).
- Add ContractError::InvalidToken (variant 11) for future explicit use.
- Expose token_decimals() view function.
- Add test asserting Stellar asset contracts report 7 decimals.
… with tests and docs

- Add NatSpec-style documentation to all public constants and validation functions
- Add MAX_PLEDGERS and additional metadata length limits
- Add pure validation helpers (validate_title, validate_description, etc.)
- Implement overflow-safe validation using saturating arithmetic
- Add comprehensive test coverage for boundary conditions and edge cases
- Fix duplicate module declarations in lib.rs
- Update documentation with security assumptions and changelog

All 197 tests pass.
afurious and others added 30 commits July 21, 2026 18:41
Audit #12: Rollback Path for Contract Upgrades
…rgo-modules

chore: remove dead npm_package_lock and cargo_toml_rust modules
…ion-policy

fix(contracts): audited TTL/rent-extension policy across all storage keys
fix: resolve stretch/bonus goal informational design gap (issue #65)
[#33] Add fail-fast token address validation in execute_initialize
Three finish-up fixes to the Rollback Path for Contract Upgrades deliverable:

* Add DataKey::PreviousWasmHash variant. The helpers
  admin_upgrade_mechanism::store_current_wasm_hash and
  admin_upgrade_mechanism::rollback_upgrade read/write against this
  variant, but it was never declared in the DataKey enum in lib.rs,
  so the contract would not have compiled.
* Rewrite admin_upgrade_mechanism.md to a single self-consistent
  section that documents the production API accurately and drops the
  stale references to a validate_wasm_hash helper that was never
  declared.
* Delete admin_upgrade_mechanism.test.rs. The file was intentionally
  gated off in lib.rs (mod admin_upgrade_mechanism_test commented
  out), referenced non-existent API, used the old single-arg
  upgrade(hash) signature rather than the new two-arg
  upgrade(new, current) needed for the rollback path, and contained
  merge-collision artefacts. The rollback path is not currently
  exercised by any test on disk.
…#37, closes #1353)

Resolves audit backlog #37 / issue #1353 ("Dead code, architecture debt & duplication"). The six-file cluster apps/contracts/crowdfund/src/security_compliance_{enforcement,automation}.{rs,test.rs,md} is not referenced by any mod declaration in lib.rs and depends on DataKey variants (DefaultAdmin, Pauser) that were never declared in the production DataKey enum. Re-enabling any of these would not compile and would introduce a multi-admin threat model that the active single-Admin design deliberately rejects.

What was deleted (6 files):
* security_compliance_enforcement.rs          (538 lines, audit #37 subject)
* security_compliance_enforcement.test.rs    (its gated-off tests)
* security_compliance_enforcement.md         (its doc)
* security_compliance_automation.rs          (sibling it depends on)
* security_compliance_automation.test.rs
* security_compliance_automation.md

What was preserved:
* The active kyc_gate module, which already implements KYC/AML at the call
  site of contribute()/pledge().
* The single DataKey::Admin role. The orphan code introduced new roles
  (DefaultAdmin, Pauser) that are intentionally absent from the design.
* Audit #12 history (DataKey::PreviousWasmHash, admin_upgrade_mechanism fix)
  preserved in TODO.md as a non-overlapping record.

TODO.md is updated to record both the Audit #12 finish-up and this Audit
#37 deletion in adjacent sections.
collect_pledges, refund, and cancel each looped over every pledger/
contributor and called token_client.transfer per entry inside one atomic
transaction. A SEP-41 token with a compliance blocklist (common for
regulated stablecoins) can make transfer panic for a single frozen
address, permanently reverting the batch for every other participant.

Switch these three loops to try_transfer (SDK-generated, backed by
env.try_invoke_contract) and skip-and-restore on failure: the entry's
storage is zeroed before the call and restored if the transfer fails, so
a frozen participant no longer blocks anyone else and remains retryable
later. refund/cancel only settle to their terminal Status once nobody
was skipped. Adds emit_transfer_skipped for visibility and a regression
suite (blocklist_transfer_test.rs) with a mock blocklisting token.

Also restores several DataKey/ContractError enum variants and fixes a
crowdfund_initialize_function.rs call to a nonexistent env.try() API
that left the crate unable to compile on main independent of this fix
(merge-conflict fallout from recent PRs), plus 3 stale test call sites
missing the expected_token_decimals argument.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
get_stats() and bonus_goal_progress_bps() both reimplemented
basis-point progress with raw i128 multiplication instead of
calling the existing compute_progress_bps helper in
campaign_goal_minimum.rs.

Raw multiplication is unsafe:
- Overflows for total_raised > i128::MAX / 10_000 (~1.7e34)
- No guard on negative total_raised (wraps to garbage u32)

Changes:
- Import compute_progress_bps in lib.rs
- Replace both inline raw-* blocks with compute_progress_bps calls
- Add audit_29_equivalence_tests.rs with 24 tests that verify
  behavioral identity for the normal-value domain and explicitly
  document the divergence for inputs the inline code mishandled

All 92 crowdfund tests pass.

Closes #1345
…ctError

Three .expect() calls in the fee calculation path of withdraw() would
cause unrecoverable panics on arithmetic failure. Replace each with a
typed ContractError variant so callers receive inspectable errors.

New error variants:
  FeeOverflow = 19         — total * fee_bps overflows i128
  FeeDivisionByZero = 20  — checked_div(10_000) returns None
  CreatorPayoutUnderflow = 21 — total - fee underflows

Changes:
- ContractError: add FeeOverflow, FeeDivisionByZero, CreatorPayoutUnderflow
- withdraw(): replace .expect() with .ok_or(ContractError::…)?
- Tests: add withdraw_fee_overflow_returns_typed_error and
  withdraw_with_valid_fee_does_not_error; all 71 crowdfund tests pass

Closes #1344
…inishup

fix(crowdfund): complete audit #12 rollback path
…rphan-security-compliance

chore(crowdfund): remove orphaned security_compliance_* cluster (audit #37, closes #1353)
…ist-fundlock

Fix batch-transfer fund-lock on blocklisted SEP-41 addresses
…ogress-bps-math

fix(crowdfund): consolidate progress-bps math to safe helper [Audit #29]
…-errors

fix(crowdfund): replace withdraw() .expect() panics with typed ContractError
Documents the previously-missing test-infra finding (mock SEP-41 token
with configurable failure) as resolved, covered by
blocklist_transfer_test.rs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
proptest_generator_boundary_tests was commented out of lib.rs and its
contents were corrupted (imports for functions that don't exist in
proptest_generator_boundary, a duplicate fn inside the proptest! macro,
dangling braces from a bad merge). Rewrote it against the real module
API and re-enabled it. Also removed proptest_generator_boundary.test.rs,
1955 lines of dead code testing a Soroban contract that was never built.

While verifying, found the crate didn't compile at all on main: DataKey
was missing 5 variants (KycGate, Milestones, MilestoneBasis,
MilestoneVote, MilestoneRefundClaimed) and ContractError was missing 3
(FeeOverflow, FeeDivisionByZero, CreatorPayoutUnderflow), both silently
dropped by an earlier merge even though other code already depended on
them. compute_progress_bps was called without its import. Two tests and
factory's create_campaign were also calling initialize() with a stale
9-arg signature missing expected_token_decimals; factory now reads the
token's own decimals instead of assuming one.

Also fixed cargo fmt and cargo clippy --all-targets --all-features -D
warnings violations (both broken on main already) so CI's build, test,
fmt, and clippy steps all pass clean under PROPTEST_CASES=1000.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
campaigns() grew monotonically forever with no way to flag cancelled,
expired, or fraudulent campaigns and no pagination, forcing front-ends
to filter an unbounded, ever-growing list client-side.

Adds a moderator-gated CampaignStatus (Active/Cancelled/Expired/Flagged)
tracked separately from the append-only Campaigns log, plus
campaigns_page/active_campaigns_page for paginated (and filtered) reads.
Campaign creation itself stays fully permissionless.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both failures are unrelated to the factory changes and reproduce on
main/other open PRs too:

- wasm-opt's two invocations rejected crowdfund.wasm's memory.copy ops
  ("Bulk memory operation (bulk memory is disabled)") because Ubuntu's
  current binaryen package no longer implies bulk-memory support the
  way rustc's wasm32-unknown-unknown output now assumes. Added
  --enable-bulk-memory-opt to both.
- cspell flagged "rescoping" in TODO.md, a pre-existing word missing
  from the project dictionary. Added it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-transfer-resolved

Add findings.md tracking resolved mid-batch transfer test-coverage gap
…undary-coverage-and-build

fix(crowdfund): restore proptest boundary coverage and fix broken build
…deration-pagination

Fix/factory campaign moderation pagination
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.