Skip to content

docs(security): add time manipulation analysis and non-monotonic timestamp tests#4

Open
devUnixx wants to merge 33 commits into
mainfrom
fix/66-time-manipulation-analysis
Open

docs(security): add time manipulation analysis and non-monotonic timestamp tests#4
devUnixx wants to merge 33 commits into
mainfrom
fix/66-time-manipulation-analysis

Conversation

@devUnixx
Copy link
Copy Markdown
Owner

Closes Vera3289#66

Changes

docs/security/time-manipulation.md (new file)

Covers:

  • How Soroban ledger time works (consensus-controlled, monotonic at network level)
  • Four attack scenarios: timestamp skew, non-monotonic rollback, far-future leap, cliff/stop bypass
  • Mitigations already present in the contract (saturating_sub, min(earned, remaining) cap, stop_time)
  • Recommendations for employers and off-chain monitoring

Tests (contracts/stream/src/test.rs)

Three new tests under the Issue #66 section:

Test What it verifies
test_non_monotonic_timestamp_yields_zero_claimable Rolled-back timestamp → claimable = 0, no panic
test_far_future_timestamp_capped_by_deposit Timestamp leap → withdrawal capped at deposit
test_stop_time_caps_accrual_on_timestamp_leap stop_time bounds accrual even with extreme timestamp

devUnixx and others added 30 commits April 29, 2026 03:00
- Replace inline mod test with external tests.rs module
- Add transfer_from and approve tests (overwrite, revoke)
- Add mint auth failure (not admin) and zero-amount panics
- Add burn/burn_from zero-amount panics
- Add balance invariant tests across transfer, mint, burn
- Add unknown address balance returns zero test

Closes Vera3289#53
- Poll Horizon contract events for PayStream stream contract
- Send configurable webhook POST on create, withdraw, cancel events
- Optional SMTP email delivery to employer/employee addresses
- Configurable event filter via WATCH_EVENTS env var
- Documented in docs/notifications.md

Closes Vera3289#113
- Test withdraw at exactly stop_time drains deposit exactly
- Test withdraw 1s after stop_time still caps at stop_time earnings
- Test no extra claimable after stop_time and full withdrawal
- Test top_up doubles deposit, stream lasts twice as long
- Test claimable calculation is correct after mid-stream top_up
- Test top_up during paused state extends duration correctly on resume
- Add proptest 1.6.0 to dev-dependencies
- Property 1: claimable never exceeds remaining deposit
- Property 2: withdrawn never exceeds deposit after withdrawal
- Property 3: total funds conserved (withdrawn + claimable <= deposit)
- Add .github/workflows/staging.yml: deploys to Stellar testnet on
  every merge to main and on manual trigger
- Builds WASM, deploys token + stream contracts, initialises both,
  runs stream_count smoke test, prints contract IDs to job summary
- Add docs/staging.md: documents contract IDs, required secrets
  (STAGING_DEPLOYER_SECRET, STAGING_ADMIN_ADDRESS), auto-redeploy
  behaviour, and manual redeploy instructions
Soroban's auth framework natively handles multi-sig Stellar accounts —
employer.require_auth() collects threshold signatures transparently.
No contract logic changes required.

- Add multisig_tests.rs: 8 tests covering all employer operations
  with a multi-sig employer address (create, top_up, pause, resume,
  cancel, update_rate, transfer, batch create)
- Add explicit 2-of-3 mock_auths test demonstrating the auth structure
  with two signers authorising on behalf of the multi-sig account
- Add docs/multisig-employer.md: setup guide for 2-of-3 multi-sig
  employer on testnet (CLI + JavaScript), security considerations

Closes Vera3289#116
…auth checks, events, stream ID uniqueness

Issue Vera3289#6 - Only employer can call pause/resume/cancel:
- Verified require_employer_by_id enforces stored employer address on
  pause_stream, resume_stream, cancel_stream
- Added 6 unauthorized tests: non-employer and employee-cannot variants
  for each of the three functions

Issue Vera3289#7 - Only employee can call withdraw:
- Verified require_employee_by_id enforces stored employee address
- Added 3 tests: non-employee rejected, employer-cannot-withdraw,
  and funds-sent-to-stored-employee (not caller)

Issue Vera3289#8 - Emit events for all state-changing operations:
- Added dedicated stream_cancelled event in events.rs with employer,
  employee, refund, and employee_payout fields
- Updated cancel_stream to emit stream_cancelled instead of generic
  stream_status_changed
- Added 6 event assertion tests: create, withdraw, top_up, pause,
  resume, cancel each verified to emit events

Issue Vera3289#9 - stream_id uniqueness and monotonic counter:
- Verified next_id() increments atomically within each transaction
- Added 3 tests: sequential creates produce unique monotonic IDs,
  batch creates produce unique sequential IDs, mixed individual+batch
  creates produce globally unique IDs

Also fixed pre-existing compilation errors:
- pause_contract/unpause_contract/propose_admin/upgrade calls missing
  admin argument
- env.events().all() requires Events as _ import
- access_control unit tests needed env.as_contract() wrapping
- Cross-stream auth tests needed employer_b token balance
- USDC test needed larger token supply (10B instead of 1B)

All 114 tests pass.
Add employee and employer dashboards with top-up feature
…onment

feat: add staging environment on Stellar testnet
…oyer-116

feat(multisig): support multi-sig employer accounts (Vera3289#116)
feat(devops): add audit and help Makefile targets, use make in CI
…service-113

feat(notifications): add Horizon event notification service
…erty-based-tests

test: add property-based tests with proptest
test(token): add comprehensive token contract tests
…on-tests

test: add top_up duration tests
…ithdraw-test

test(stream): add withdraw with zero claimable test
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.

Add time manipulation resistance analysis

7 participants