Re-rate pending swap orders¶
swap-rerate replaces one or more pending SundaeSwap V3 orders for a
single treasury scope at a new ADA/USDM rate. It is the address-based
operator path shipped across the CLI, POST /v1/build/swap-rerate, and
the Operate UI.
Use it when a treasury swap order is still pending and the operator wants to cancel the old order and submit a replacement order at a new rate. Use the standalone swap-cancel flow when the goal is only to return one pending order to the treasury without creating a replacement order.
What re-rate does¶
The normal run is:
- Select one treasury scope.
- Pick the pending orders from that scope.
- Provide a wallet address. The live runner auto-selects fee fuel, collateral, and change UTxOs from that address.
- Build one atomic cancel-and-reoffer transaction when the selection fits current execution-memory, execution-step, and transaction-size budgets.
- If the selection is too large, receive a split fallback plan instead of an overflowing transaction.
- Review the report, witness the unsigned CBOR, attach witnesses, and submit.
The command does not sign or submit. It writes unsigned Conway CBOR and a JSON report, the same handoff shape used by the rest of the operator pipeline.
Safety model¶
The preferred shape is a single atomic transaction: every selected
pending order is cancelled and its replacement order is created in the
same transaction body. That is the only shape that writes unsigned CBOR
for the normal single_tx result.
Before writing bytes, the planner checks the current protocol budget. If
the selection exceeds execution memory, execution steps, or transaction
body size, swap-rerate writes a split report instead of CBOR. The
report names the planner reason, the budget estimate, and ordered split
groups. Treat that as a new operator plan: build, review, witness, and
submit each group deliberately rather than forcing the original
selection into one transaction.
The order spend uses the SundaeSwap V3 order validator as a PlutusV2
script and the Cancel redeemer. The Amaru permissions withdraw-zero
path still supplies the treasury scope approval rule, so the final
transaction requires the expected treasury owner witnesses.
Value and funding rule¶
Re-rate is not a wallet-funded swap. For each selected order, the old order's offered ADA amount is conserved and becomes the offered amount of the replacement order. The new rate only changes the replacement datum's requested USDM amount.
Each replacement order output must also clear the ledger min-UTxO and re-fund the Sundae scooper rider. The planner accounts for that per-order extra lovelace when deriving the replacement output value.
The operator wallet funds fees, collateral, and change only. It must have pure ADA UTxOs, but it must not be treated as contributing the traded ADA. If the wallet address has no pure ADA fuel or cannot cover the fee slack, the live runner rejects the build with a stable wallet selection diagnostic.
CLI worked example¶
Start with the same metadata and node socket setup used by the swap recipe:
export CARDANO_NODE_SOCKET_PATH=/path/to/cardano-node.socket
curl -fsSL https://raw.githubusercontent.com/pragma-org/amaru-treasury/main/journal/2026/metadata.json \
-o metadata-mainnet.json
Inspect pending orders for the scope, then choose the order UTxOs to re-rate:
amaru-treasury-tx \
--node-socket "$CARDANO_NODE_SOCKET_PATH" --network mainnet \
treasury-inspect \
--metadata metadata-mainnet.json \
--scope network_compliance
Build the preferred atomic transaction by passing the wallet address and the selected pending orders:
amaru-treasury-tx \
--node-socket "$CARDANO_NODE_SOCKET_PATH" --network mainnet \
swap-rerate \
--metadata metadata-mainnet.json \
--scope network_compliance \
--wallet-address "$WALLET_ADDR" \
--order-txin "$ORDER_TXIN_A" \
--order-txin "$ORDER_TXIN_B" \
--new-rate 0.47 \
--validity-hours 28 \
--out rerate.cbor.hex \
--report rerate.report.json
Use --all-orders only when every pending order in the selected scope
should be re-rated together:
amaru-treasury-tx \
--node-socket "$CARDANO_NODE_SOCKET_PATH" --network mainnet \
swap-rerate \
--metadata metadata-mainnet.json \
--scope network_compliance \
--wallet-address "$WALLET_ADDR" \
--all-orders \
--new-rate 0.47 \
--out rerate.cbor.hex \
--report rerate.report.json
On a successful atomic build, the report has status: "single_tx" and
the CBOR file is present. On an over-budget selection, the report has
status: "split" and no CBOR is written for the combined selection.
HTTP JSON example¶
The API exposes the same unsigned build through
POST /v1/build/swap-rerate. The request uses the srr* field names
from the Haskell JSON type and accepts the wallet address, not manual
wallet or collateral tx-ins:
curl -fsS \
-H 'content-type: application/json' \
-X POST \
http://127.0.0.1:8080/v1/build/swap-rerate \
--data-binary @- <<'JSON'
{
"srrScope": "network_compliance",
"srrSelectedOrders": [
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#1"
],
"srrNewRate": 0.47,
"srrWalletAddress": "addr1q..."
}
JSON
A single-transaction response carries srrDecision: "single_tx" plus
srrCborHex, srrCborEnvelope, and srrReport. A split fallback
carries srrDecision: "split", srrReason, and srrReport, with no
CBOR. Typed failures use srrFailureTag and srrFailureReason.
Operate UI workflow¶
In the hosted operator app, open Operate, choose Re-rate, and select a scope. The UI fetches pending orders for that scope and shows a checkbox for each order. Select the orders to re-rate, enter the new ADA/USDM rate, and provide the wallet address in the Funding section.
The build button posts the same request shape as the HTTP example:
srrScope, srrSelectedOrders, srrNewRate, and srrWalletAddress.
The result panel shows whether the build produced a single unsigned
transaction or a split fallback.
The committed review screenshot for the address-based workflow is available in the repository source: 419-rerate-operate-desktop-1280.png.
Review, witness, submit¶
Review rerate.report.json before signing. Confirm at least:
scopeis the intended treasury scope.statusissingle_txbefore using the CBOR file.selectedOrderscontains only the intended pending order UTxOs.newRateis the intended ADA/USDM rate.- each order shows the expected returned and re-offered values.
- the fee and required signing steps are acceptable.
Then produce detached witnesses, attach them, and submit:
exec 9<<<"$VAULT_PASSPHRASE"
amaru-treasury-tx --network mainnet witness \
--tx rerate.cbor.hex \
--vault treasury.vault.age \
--vault-passphrase-fd 9 \
--identity core_development \
--out core_development.witness.hex
exec 9<&-
owner_witness_hex="$(tr -d '\n' < core_development.witness.hex)"
amaru-treasury-tx attach-witness \
--tx rerate.cbor.hex \
--witness "$owner_witness_hex" \
--out rerate.signed.cbor.hex
amaru-treasury-tx \
--node-socket "$CARDANO_NODE_SOCKET_PATH" --network mainnet \
submit --tx rerate.signed.cbor.hex
Attach every owner witness required by the order datum and the Amaru scope approval rule before submission.
Related operations¶
- Swap recipe covers normal new swap order construction, quote-derived swap runs, report review, and the shared witness / submit pipeline.
- swap-cancel cancels one pending SundaeSwap order back to the treasury without creating a replacement.
POST /v1/build/swap-rerateis the HTTP build endpoint used by Operate.- Epic #395 tracks the broader swap re-rate recovery work.