arrow_backRetour aux issues
Wayfare-labs/wayfare
#54
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
Effective transfer cost decomposition: FX loss, fees, slippage, expected-failure-cost
ecoDébutant
help wanted
area:pricing
difficulty:medium
descriptionDescription
> Written to the standard set by #33 — read that issue first for the expected level of detail.
## What
Decompose the effective transfer cost into four separately-reported components: FX loss, fees, slippage, and expected failure cost. Each is computed and reported independently. Expected failure cost stays **explicitly unknown** until failure history exists.
Currently, the verdict reports a single loss percentage against fair value. That number is useful but opaque — a 27% loss could be mostly FX spread, mostly fees, mostly slippage, or some combination. A reader deciding whether to use a corridor needs to know *where* the cost is coming from, not just that it exists.
## Why it matters
A route with a worse headline rate can be cheaper all-in if it has lower fees or less slippage. Showing that decomposition is the point — it turns a single verdict into actionable information. Without it, the reader cannot distinguish "this corridor has a bad rate" from "this corridor has good rates but high fees" from "this corridor is thin and slippage dominates at size."
## Which layer
**Layer 2 — computed from observable data.** The components are derived from pathfinding results, SEP-38 quotes, and the reference rate. Nothing is inferred beyond what the data supports.
## Exactly where the code goes
- **Modified files:** `route/route.go` (or a new `route/cost.go` if the decomposition is complex enough)
- **Tests:** `route/route_test.go`
- The decomposition should be a function that takes a priced route and returns the four components
- Each component is a `decimal.Decimal` with a unit (percent or absolute)
- The wire format in `server/api.go` is extended to include the decomposition (or a new endpoint)
## Where the data comes from
- **FX loss:** difference between the route's received amount and the reference mid (already computed by the verdict)
- **Fees:** sum of explicit fees from SEP-38 quotes and implicit fees from the route's spread (available from `sep38/` and `dex/`)
- **Slippage:** difference between the quoted price and the executable price at the actual trade size (available from `dex/` order book data)
- **Expected failure cost:** explicitly `UNABLE-TO-DETERMINE` — the data does not exist yet
## What "unmeasurable" means here
The expected failure cost is the key case. Until the project has observed actual payment failures (which requires history that `runstore` is collecting but does not yet have enough of), this component must be reported as unknown. It must not be estimated, defaulted to zero, or filled in with a plausible-looking number.
The other three components are computable from existing data. If any of them cannot be computed for a specific route (e.g., no SEP-38 quote available), that component is reported as `UNABLE-TO-DETERMINE` with a reason.
## Acceptance criteria
- [ ] Implements the decomposition as described in `docs/checks.md` (MetricResult shape, not CheckResult)
- [ ] Each component is reported separately — never blended into a single number
- [ ] Expected failure cost is `UNABLE-TO-DETERMINE` with a reason explaining why
- [ ] `decimal.Decimal` for all values; no `float64`
- [ ] Network I/O goes through the existing `http.RoundTripper` seam
- [ ] Table tests driven from recorded bytes — no live network in tests
- [ ] Includes a negative test: a case where a component must be undeterminable
- [ ] `gofmt`, `go vet`, `go test -race`, `golangci-lint` all clean
- [ ] Does not change the headline integrity state or verdict thresholds
- [ ] The wire format is backward-compatible (new fields are optional/omittable)
## Out of scope
Do not change:
- The verdict thresholds or bands
- The integrity taxonomy
- `refrate/` code
- `runstore/runstore.go` — the record shape is hash-chained; changing it is a version bump
- The check engine in `checks/`
## How to verify locally
```bash
make offline-test
go test ./route/ -run TestCostDecomposition -v
make fmt vet test race lint
```
Then confirm it falsifies —
Issues similaires
medik8s/fence-agents-remediation
star18
Poids du dépôt moyen
v0.8.0 starts a cluster-scoped Secret informer despite namespace-scoped Secret RBAC
## Description While testing Fence Agents Remediation (FAR) v0.8.0, I observed the manager repeatedly attempting to li…
Go
good first issue
Wayfare-labs/wayfare
star1
Poids du dépôt léger
Check that an issuer's home_domain round-trips to the same stellar.toml
Written to the standard set by #33 — read that issue first for the expected level of detail and the acceptance criteria…
Go
help wanted
area:corridor
Wayfare-labs/wayfare
star1
Poids du dépôt léger
Report auth_immutable: whether an issuer's flags can still change
> **This issue is the reference standard.** Every other check issue links back here for the expected level of detail. I…
Go
help wanted
good first issue