30 lines
3.6 KiB
Markdown
30 lines
3.6 KiB
Markdown
# Design
|
|
|
|
## Context
|
|
|
|
See proposal.md for motivation and the two delta specifications for required behavior. The burner already selects one rounded, reserve/minimum/maximum-qualified input, invokes Jupiter at most once, and then independently reloads EVE for burn evaluation. Its fresh canonical EVE/USDT reader is also used for burn valuation. The Hub constructs processes in the manually configured order and rejects unavailable process dependencies.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:** Insert the purchase condition at the last point before a new Jupiter attempt, use the corresponding live reference API, and retain independent burn and pending-transaction behavior.
|
|
|
|
**Non-Goals:** A general price-policy framework, another clock/configuration/freshness option, duplicated curve calculations, stored-history decisions, or changes to transaction execution, Ticker sources, lifecycle and deployment selection.
|
|
|
|
## Decisions
|
|
|
|
1. Add a required `EvelynStatusService` constructor dependency beside Ticker. Production composition uses the existing `requireProcessDependency` guard for `evelyn.status.prod`. The Hub does not infer or start dependencies; operators must place Ticker and Production status before the burner. Constructing a private reference calculator in the burner would duplicate ownership and risk policy drift.
|
|
2. After the first eligible rounded input is selected, reuse `findFreshPrice(eveUsdtTradingPair)`, obtain the reference through `getReferencePrice(Instant.now())`, validate its canonical pair and positive amount, and compare with `BigDecimal.compareTo`. This avoids division/index rounding and keeps the check close to submission. Checking before input selection would age the decision during balance/mint work; history/chart reads would use stale sample time.
|
|
3. A rejected condition returns only from `attemptAtMostOneSwap`, preserving the unconditional later `processCompleteEveBalance`. No other input can bypass a globally rejected EVE price. Missing/invalid reference or runtime lookup failure produces a safe warning; an at/above comparison logs the values and decision instant. No suspension state is set. Burn valuation independently reads its existing fresh price and never depends on reference availability.
|
|
4. Pending burn and swap paths stay ahead of input selection. Reconciliation is read-only regardless of price, and only a newly eligible purchase after reconciliation invokes the gate. Amount limits, precision, unknown-outcome handling and notifications remain as existing contracts define.
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- [Market movement after observation] → Use the existing maximum price age and the last purchase-selection point; Jupiter execution and slippage rules remain unchanged.
|
|
- [Reference service failure] → Skip the purchase for this iteration, keep burn processing and re-evaluate next time; log exception type without arbitrary provider text.
|
|
- [Missing deployment predecessor] → Fail clearly through existing Hub dependency validation; document order without editing private deployment configuration.
|
|
- [Unknown transaction after restart] → Retain current pending-state/restart contracts; the price gate cannot replace reconciliation.
|
|
|
|
## Migration Plan
|
|
|
|
Compile and verify offline, then review the change. A later separately authorized deployment must have `assetaz.ticker.default` and `evelyn.status.prod` before a selected `evelyn.iou-burner.prod`. This implementation request changes no live configuration, performs no transactions and deploys nothing. Rollback restores the preceding application version and its constructor composition; uncertain transactions must first be reconciled under the existing restart rules.
|