72: Add the Evelyn IOU buyback-and-burn service
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package com.fanitas.evelyn.service.burner;
|
||||
|
||||
import com.r35157.libs.valuetypes.basic.MoneyAmount;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Continuously buys back and burns Evelyn IOU from a dedicated wallet.
|
||||
*
|
||||
* <p>Accepted buyback inputs and their reserves are configured as an ordered
|
||||
* {@link List} of {@link MoneyAmount} values. Each
|
||||
* {@link MoneyAmount#currencyType() currency type}'s stable AssetAZ UUID is
|
||||
* the authoritative identity, and each {@link MoneyAmount#amount() amount} is
|
||||
* the minimum balance that must remain. List order is currency priority.
|
||||
* Solana mint addresses and token programs are integration details resolved
|
||||
* internally through the Currency Identity Service and Solana and are not
|
||||
* part of Evelyn's input configuration.</p>
|
||||
*
|
||||
* <p>Every non-overlapping iteration has this order:</p>
|
||||
* <ol>
|
||||
* <li>If a prior burn has a pending signature, await only that exact
|
||||
* signature at Solana {@code FINALIZED}. An unknown result ends the
|
||||
* iteration; definitive failure is logged without notification; success
|
||||
* receives the burn's single notification attempt. No new swap or burn is
|
||||
* submitted in an iteration that begins with a pending burn.</li>
|
||||
* <li>Unless swaps are suspended, inspect accepted currencies in priority
|
||||
* order. Canonicalize each AssetAZ UUID, resolve its native-SOL or SPL
|
||||
* representation internally, apply its own minimum reserve, and require a
|
||||
* fresh input/USDC price. Missing or unusable candidate data does not
|
||||
* prevent later currencies from being considered.</li>
|
||||
* <li>Select at most the configured USDC-equivalent maximum, rounded down
|
||||
* to the input currency's supported precision. Native SOL uses its native
|
||||
* balance and nine-decimal precision; no future transaction fee is
|
||||
* estimated when applying its reserve.</li>
|
||||
* <li>Attempt no more than one exact-input Jupiter swap. Normal return is
|
||||
* already {@code CONFIRMED}; it is not awaited a second time. A definitive
|
||||
* failure permits a later iteration to try again, while a timeout or other
|
||||
* potentially unknown post-submission result suspends swaps for this
|
||||
* lifecycle.</li>
|
||||
* <li>Reload the complete visible Evelyn IOU balance, including tokens
|
||||
* deposited or acquired before this iteration. Absence or failure of a
|
||||
* swap does not suppress this step, and the USDC buyback limit never caps
|
||||
* the amount eligible for burning.</li>
|
||||
* <li>Require a positive, sufficiently fresh canonical EVE/USDT price and
|
||||
* calculate the complete balance's dollar value before submitting a burn.
|
||||
* Missing, invalid, or stale price data postpones the burn.</li>
|
||||
* <li>Submit the complete EVE balance once and retain its signature,
|
||||
* amount, and notification value as pending before waiting. The service
|
||||
* never automatically retries, rebuilds, re-signs, or resubmits a swap or
|
||||
* burn because timeout, interruption, or communication failure can leave
|
||||
* the original transaction's outcome unknown.</li>
|
||||
* <li>Await the burn at {@code FINALIZED}. Timeout or I/O retains the
|
||||
* signature for a later await; definitive on-chain failure clears it
|
||||
* without notification; successful finalization permits notification.</li>
|
||||
* <li>Attempt the fixed proof notification exactly once for a successfully
|
||||
* finalized burn. Notification failure neither retries delivery nor
|
||||
* repeats the completed burn.</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>One dedicated worker begins immediately on {@link #start()}, uses fixed
|
||||
* delay measured after each completed iteration, and never overlaps
|
||||
* iterations. {@link #stop()} prevents new iterations and stops that worker.
|
||||
* Pending signatures and swap/burn suspension flags are process-local only
|
||||
* and are deliberately reset by a completed explicit stop/start cycle or a
|
||||
* process restart. Such a reset forgets unknown transaction state and can
|
||||
* weaken duplicate prevention; operators should reconcile uncertain on-chain
|
||||
* activity before deliberately restarting a suspended or pending service.</p>
|
||||
*/
|
||||
public interface EvelynIOUBurnerService {
|
||||
/**
|
||||
* Starts the dedicated worker and begins the first iteration immediately.
|
||||
*
|
||||
* @throws IllegalStateException if this instance is already running or a
|
||||
* prior worker has not terminated cleanly
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Prevents new iterations, interrupts current processing, and stops the
|
||||
* dedicated worker cleanly.
|
||||
*
|
||||
* <p>A completed stop clears process-local pending and suspension state.
|
||||
* If the calling thread is interrupted while waiting for termination, its
|
||||
* interrupt status is preserved.</p>
|
||||
*
|
||||
* @throws IllegalStateException if clean worker termination cannot be
|
||||
* established
|
||||
*/
|
||||
void stop();
|
||||
}
|
||||
+1045
File diff suppressed because it is too large
Load Diff
@@ -8,16 +8,31 @@ import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Exchanges an exact human-readable SPL-token amount through Jupiter.
|
||||
* Exchanges an exact human-readable token amount through Jupiter.
|
||||
*
|
||||
* <p>The service resolves token precision from Solana, obtains and validates a
|
||||
* <p>An input can be a supported SPL token or native SOL represented by
|
||||
* Jupiter's canonical SOL/WSOL mint
|
||||
* {@code So11111111111111111111111111111111111111112}. The canonical address
|
||||
* remains the {@code inputTokenMint} passed to the unchanged swap operation;
|
||||
* callers that select native SOL remain responsible for reading the native
|
||||
* wallet balance and applying their own reserve policy. Output remains a
|
||||
* supported SPL-token mint.</p>
|
||||
*
|
||||
* <p>The service resolves mint precision from Solana, obtains and validates a
|
||||
* Jupiter Swap V2 order, asks its configured wallet to sign the transaction,
|
||||
* submits the signed transaction through Jupiter's managed execution
|
||||
* endpoint, and independently awaits Solana confirmation.</p>
|
||||
* endpoint, and independently awaits Solana confirmation. Legacy SPL-token
|
||||
* and Token-2022 behavior is unchanged.</p>
|
||||
*/
|
||||
public interface JupiterSwapService {
|
||||
/**
|
||||
* Swaps an exact amount of one SPL token for another SPL token.
|
||||
* Swaps an exact amount of a supported token or native SOL into an SPL
|
||||
* token.
|
||||
*
|
||||
* <p>Native SOL input is expressed with the canonical SOL/WSOL mint
|
||||
* {@code So11111111111111111111111111111111111111112}; the service passes
|
||||
* that value unchanged to Jupiter as {@code inputMint}. No separate
|
||||
* native-SOL method is required.</p>
|
||||
*
|
||||
* <p>The returned amounts are the actual wallet-level amounts reported by
|
||||
* Jupiter after successful provider execution, not the quoted amounts.
|
||||
@@ -26,7 +41,8 @@ public interface JupiterSwapService {
|
||||
* error after submission can leave the transaction outcome unknown and
|
||||
* must never cause automatic resubmission.</p>
|
||||
*
|
||||
* @param inputTokenMint input SPL-token mint address
|
||||
* @param inputTokenMint input SPL-token mint address, or the canonical
|
||||
* SOL/WSOL mint representing native SOL
|
||||
* @param inputTokenAmount exact input amount in human-readable token units
|
||||
* @param outputTokenMint output SPL-token mint address
|
||||
* @param maxSlippageBps maximum accepted slippage from 0 through 10000
|
||||
|
||||
Reference in New Issue
Block a user