[434] [High] Oracle-Referenced Slippage and Minimum-Output Validation - #548
Merged
Conversation
Reject creates whose minimum output sits too far below or above the oracle fair destination amount, unless high slippage is explicitly signed. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@Goodnessukaigwe 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! 🚀 |
…-referenced-slippage-and-minimum-output-validation # Conflicts: # .env.staging.example # .env.testnet.example # CHANGELOG.md # docs/runbooks/on-call.md # jest.config.js # package-lock.json # package.json # src/app.module.ts # src/common/stellar-signature.ts # src/config/configuration.ts # src/config/env.validation.ts # src/governance/governance.module.ts # src/intents/dto/create-intent.dto.ts # src/intents/intents.controller.ts # src/intents/intents.gateway.spec.ts # src/intents/intents.gateway.ts # src/intents/intents.module.ts # src/intents/intents.service.shadow.spec.ts # src/intents/intents.service.spec.ts # src/intents/solver-intent-matcher.ts # src/intents/ws/connection-state.ts # src/solvers/solvers.controller.ts # src/soroban/event-ingestion.service.ts # src/soroban/signer.service.spec.ts # src/soroban/solver-registry.service.spec.ts # src/soroban/soroban.controller.spec.ts # src/soroban/soroban.module.ts # src/soroban/soroban.service.ts # src/soroban/stellar-tx.service.spec.ts # src/soroban/stellar-tx.service.ts # src/soroban/tx-confirmation.service.ts # src/tokens/in-memory-tokens.repository.ts # src/tokens/tokens.service.ts # src/treasury/treasury.service.spec.ts # src/treasury/treasury.service.ts # test/__mocks__/@stellar/stellar-sdk.ts # test/cors.e2e-spec.ts # test/dos-limits.e2e-spec.ts # test/jest-e2e.json # test/load/concurrent-accept.test.ts # test/load/concurrent-idempotent-create.test.ts # test/load/ws-broadcast-fanout.test.ts # test/params.e2e-spec.ts
Comment on lines
+70
to
+76
| helmet({ | ||
| contentSecurityPolicy: false, | ||
| hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }, | ||
| frameguard: { action: "deny" }, | ||
| noSniff: true, | ||
| referrerPolicy: { policy: "strict-origin-when-cross-origin" }, | ||
| }), |
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.
Summary
Intent creation now checks
minDstAmountagainst an oracle fair destination value before the intent is stored.AggregatorServicebuilds a price snapshot from registry USD prices.validateMinDstAmountis a pure bigint function over that snapshot (USD scaled by 1e8). Fair value is floored, so it understates the destination by at most one base unit.MAX_USER_SLIPPAGE_BPS(default 100) is rejected unlessacknowledgeHighSlippageis true and the user signedacknowledge-high-slippage:<user>:<srcAmount>:<minDstAmount>.MAX_PREMIUM_BPS(default 50) is always rejected. The exact boundary is accepted.fairValue(string or null) andslippageBps.ORACLE_MAX_STALENESS_MS(default 60s), creates at or belowORACLE_FAIL_OPEN_MAX_USD(default 100) still succeed. Larger notionals, and any create with no source price, fail closed.Also restores a typechecking, bootable tree on current
main: duplicate module registrations, a required-after-optional constructor, the ESM@nestjs/scheduleJest mock, and test updates for the current Stellar SDK. Those fixes are required for CI on this branch and do not change the validation rules above.Test plan
npm run lint(0 errors)npm run typechecknpm run check:env-driftnpm test— 68 suites, 878 tests (passes with--maxWorkers=2; the shadow p99 budget can exceed 2ms when the full suite is heavily parallel)npm run test:e2e— 28 suites, 214 teststest/oracle-min-dst.e2e-spec.tscovers the create response metadataConfiguration
New variables, documented in every
.env*.exampleandsrc/config/env.validation.ts:MAX_USER_SLIPPAGE_BPSMAX_PREMIUM_BPSORACLE_FAIL_OPEN_MAX_USDORACLE_MAX_STALENESS_MSNo database migration.
Operational notes
See
docs/adr/0003-oracle-min-dst-validation.mdand the on-call runbook. Fail-open is only for small notionals when the oracle cannot produce a usable snapshot. Operators should treat a rise inORACLE_UNAVAILABLE/STALE_ORACLErejections as an oracle or registry price outage, not as a user-input bug.Closes #434
Made with Cursor