Skip to content

feat: secure upgrade mechanism, flash loan attack prevention, DTO refactor, event schema standardization#415

Merged
Smartdevs17 merged 4 commits into
Smartdevs17:mainfrom
akintewe:feat/secure-upgrade-flash-loan-dto-events
May 28, 2026
Merged

feat: secure upgrade mechanism, flash loan attack prevention, DTO refactor, event schema standardization#415
Smartdevs17 merged 4 commits into
Smartdevs17:mainfrom
akintewe:feat/secure-upgrade-flash-loan-dto-events

Conversation

@akintewe
Copy link
Copy Markdown
Contributor

Summary

This PR implements four open issues across the StellarLend codebase:

Issue #382 — Secure upgrade mechanism with timelock and multisig

  • Added STANDARD_TIMELOCK_SECS (48 h) and EMERGENCY_TIMELOCK_SECS (4 h) constants to stellarlend-common
  • New TimelockQueued stage in UpgradeStage enum; proposals must pass upgrade_queue_timelock() before execution
  • New upgrade_propose_emergency() entrypoint uses the shorter 4 h delay
  • upgrade_execute() now checks execute_after and panics with TimelockNotElapsed if the window has not elapsed
  • New UpgradeTimelockQueuedEvent and UpgradeEmergencyProposedEvent emitted on queue/emergency-propose
  • All existing upgrade tests updated; new tests cover emergency path and early-execution blocking

Issue #379 — Flash loan attack prevention with price manipulation detection

  • ManipulationConfig with configurable pool-liquidity cap (50%), price impact limit (1%), TWAP deviation threshold (2%), and concurrent-loan guard
  • TwapAccumulator/TwapState maintain a time-windowed rolling average of oracle prices
  • check_twap_deviation() blocks loans when spot price deviates excessively from TWAP
  • check_liquidity_cap() limits each flash loan to a fraction of pool liquidity
  • check_price_impact() uses constant-product approximation to bound impact
  • Per-asset AssetLoanGuard prevents concurrent loans on the same asset (sandwich mitigation)
  • Applied to both lending/src/flash_loan.rs and hello-world/src/flash_loan.rs
  • New flash_record_price() and set_flash_manipulation_config() entrypoints
  • New tests: liquidity cap, price impact, TWAP manipulation detection

Issue #362 — TypeScript DTO refactor

  • New api/src/dto/ directory with typed DTO classes
  • base.dto.ts: ValidationResult, FieldError, isValidStellarAddress(), isValidAmount(), MAX_I128
  • lending.dto.ts: LendingOperationDto, PrepareRequestDto, SubmitRequestDto, RelayDelegatedDto, response DTOs
  • subscription.dto.ts: CreateSubscriptionDto
  • pagination.dto.ts: PaginationQueryDto
  • Each DTO exposes static validate() + fromBody()/fromQuery() factories
  • New DTO-based middleware variants in middleware/validation.ts attach typed DTOs to req
  • Full OpenAPI JSDoc annotations on all DTO classes

Issue #356 — Standardized event schemas

  • All AMM events: added topics attributes (amm_swap, amm_liq_add, amm_liq_rm, amm_op, amm_cb_valid) and timestamp: u64 field
  • All Bridge events: added topics attributes and timestamp: u64 field to all 11 structs
  • New docs/event-schema.md: mandatory field spec, topic naming conventions, per-contract catalogue, PR checklist
  • New scripts/check_event_schema.sh: CI script that detects event structs missing timestamp

Test plan

  • cargo test -p stellarlend-common — upgrade timelock tests pass
  • cargo test -p lending — flash loan, upgrade, migration tests pass
  • cargo test -p hello-world — flash loan tests pass
  • cargo test -p bridge and -p amm — compile with new event fields
  • scripts/check_event_schema.sh — reports 0 violations
  • cd api && npx tsc --noEmit — DTO types compile cleanly

Closes #356 closes #362 closes #379 closes #382

akintewe added 4 commits May 28, 2026 17:41
- Add STANDARD_TIMELOCK_SECS (48h) and EMERGENCY_TIMELOCK_SECS (4h) constants
- Add TimelockNotElapsed and StorageLayoutMismatch error variants
- Add TimelockQueued stage to UpgradeStage enum
- Add execute_after and is_emergency fields to UpgradeProposal and UpgradeStatus
- Add upgrade_queue_timelock() to start the standard 48h countdown post-approval
- Add upgrade_propose_emergency() for 4h emergency path (admin only)
- Enforce timelock in upgrade_execute() — rejects before execute_after elapses
- Add UpgradeTimelockQueuedEvent and UpgradeEmergencyProposedEvent to events
- Update all tests to go through queue_and_execute() helper for correct flow
…evention

- Add ManipulationConfig with pool liquidity cap (50%), price impact limit,
  TWAP deviation threshold, and concurrent loan detection
- Add TwapAccumulator/TwapState structs with time-windowed price sampling
- Add check_twap_deviation(), check_liquidity_cap(), check_price_impact()
- Add per-asset AssetLoanGuard to block concurrent flash loans (sandwich prevention)
- Update flash_loan() signature to accept spot_price for TWAP checks
- Add flash_record_price() and set_flash_manipulation_config() entrypoints
- Apply same attack guards to hello-world flash_loan module
- Update all tests to use new flash_loan() signature with spot_price
- Add tests for liquidity cap, price impact, and TWAP deviation blocking

Closes Smartdevs17#379, Smartdevs17#401
- Add api/src/dto/ directory with TypeScript DTO classes
- base.dto.ts: FieldError, ValidationResult, helper validators (isValidStellarAddress,
  isValidAmount, isOptionalString), MAX_I128 constant
- lending.dto.ts: LendingOperationDto, PrepareRequestDto, SubmitRequestDto,
  RelayDelegatedDto, PrepareResponseDto, TransactionResponseDto — all with
  static validate() and fromBody()/fromQuery() factories + JSDoc/OpenAPI schemas
- subscription.dto.ts: CreateSubscriptionDto covering all subscription fields
- pagination.dto.ts: PaginationQueryDto with configurable max-limit
- dto/index.ts: barrel re-export
- middleware/validation.ts: add DTO-based middleware variants (validateLendingOperationDto,
  validatePrepareDto, validateSubmitDto, validateRelayDelegatedDto,
  validateCreateSubscriptionDto, validatePaginationDto) that attach typed DTOs
  to req for use in controllers — existing express-validator chain preserved

Closes Smartdevs17#362
AMM (amm.rs):
- Add explicit topics attributes: amm_swap, amm_liq_add, amm_liq_rm, amm_op, amm_cb_valid
- Add timestamp: u64 field to SwapExecutedEvent, LiquidityAddedEvent, LiquidityRemovedEvent,
  CallbackValidatedEvent (AmmOperationEvent already had it)
- Update all emit helper functions to pass env.ledger().timestamp()

Bridge (bridge.rs):
- Add explicit topics attributes: br_reg, br_fee, br_active, br_dep, br_wdraw, br_pause,
  br_val_upd, br_sec_cfg, br_slash, br_ch_emrg, br_anomaly
- Add timestamp: u64 to all 11 bridge event structs (previously none had it)
- Update all emit call sites to include timestamp

Docs:
- Add docs/event-schema.md: mandatory fields spec, topic naming conventions,
  per-contract event catalogue, backward-compat note, PR checklist

CI:
- Add scripts/check_event_schema.sh: detects contractevent structs missing
  the required timestamp field; warns on missing explicit topics

Closes Smartdevs17#356, Smartdevs17#408
@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

@akintewe is attempting to deploy a commit to the smartdevs17's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented May 28, 2026

@akintewe 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! 🚀

Learn more about application limits

@Smartdevs17 Smartdevs17 merged commit cc43b6d into Smartdevs17:main May 28, 2026
5 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants