Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
cb4ef91
feat(rfq): prevent permissioned token route aggregation
alrxy Jul 13, 2026
cc25c09
fix(rfq): scope single-route rule to permissioned fillers
alrxy Jul 13, 2026
19d076a
feeat(3f): update default discovery to 5min
oxsteins Jul 13, 2026
7ea3437
Merge pull request #85 from symbioticfi/feat-3f/default-discovery-update
oxsteins Jul 13, 2026
02a1a66
feat(3f): discover adapters from factory
1kresh Jul 13, 2026
5b8769a
Merge remote-tracking branch 'origin/stage' into feat-permissioned-to…
alrxy Jul 14, 2026
7c4b170
Merge pull request #73 from symbioticfi/feat-permissioned-tokens-rfq
oxsteins Jul 14, 2026
e9bece5
fix(3f): honor explicit adapter configuration
1kresh Jul 14, 2026
f3d3802
feat(3f): validate offer-signer via ERC-1271 instead of address match
oxsteins Jul 14, 2026
dc56850
chore(deps): bump golang.org/x/sync in the go group
dependabot[bot] Jul 14, 2026
056574c
Merge pull request #88 from symbioticfi/feat/3f-offer-signer-1271
oxsteins Jul 14, 2026
70eae1e
Merge stage into 3f factory discovery; reuse ERC-1271 offer-signer pr…
oxsteins Jul 14, 2026
fbbae92
fix(3f): align startup error wording with ERC-1271 offer-signer check
oxsteins Jul 14, 2026
0f0cc00
docs(3f): correct offer-signer eligibility wording (ERC-1271, not add…
oxsteins Jul 14, 2026
481f225
Merge pull request #86 from symbioticfi/codex/mainnet-liquid-lane-3f-…
oxsteins Jul 14, 2026
fd8b7b6
Merge pull request #91 from symbioticfi/dependabot/go_modules/stage/g…
oxsteins Jul 14, 2026
aebaf0e
refactor(liquidlane): share solver infrastructure
alrxy Jul 21, 2026
289e764
fix(txmanager): harden pending transaction handling
alrxy Jul 21, 2026
913d241
feat(lifi): add same-chain solver
alrxy Jul 21, 2026
cb80fca
docs(lifi): align plan with implementation
alrxy Jul 22, 2026
e6cf880
fix: 3f strategy
oxsteins Jul 22, 2026
1b7c2a5
fix(3f): eexpiration
oxsteins Jul 23, 2026
88fcfa5
Merge pull request #67 from symbioticfi/feat-lifi-solver
oxsteins Jul 23, 2026
bdc8cf4
Merge branch 'stage' into fix/3f-logic
oxsteins Jul 23, 2026
fd3d203
test(3f): align offerExpiration test with solve_start+buffer anchoring
oxsteins Jul 23, 2026
aa23980
feat(txmanager): log tenderly simulator url on reverted tx
oxsteins Jul 23, 2026
d551399
feat(txmanager): log tenderly url on gas estimation failure
oxsteins Jul 23, 2026
c02198d
Merge pull request #98 from symbioticfi/fix/3f-logic
oxsteins Jul 23, 2026
f7b42f1
refactor(liquidlane): share greedy quote and fill strategies
alrxy Jul 24, 2026
a33728e
build(uniswapx): generate API and executor bindings
alrxy Jul 24, 2026
c66288e
feat(uniswapx): add liquidlane quoter and filler
alrxy Jul 24, 2026
527d48f
fix(uniswapx): reprice discount legs before filling
alrxy Jul 24, 2026
3f5e794
fix(uniswapx): harden quote readiness and observability
alrxy Jul 24, 2026
86345e0
Merge pull request #94 from symbioticfi/feat/uniswapx-liquidlane-inte…
oxsteins Jul 24, 2026
f95c430
fix(liquidlane): honor delegated zero market maker fillers
alrxy Jul 24, 2026
074a8fd
Merge pull request #99 from symbioticfi/fix/liquidlane-zero-market-ma…
oxsteins Jul 24, 2026
997bb0c
feat(uniswapx): add debug decision tracing
alrxy Jul 27, 2026
c794883
Merge pull request #100 from symbioticfi/fix/uniswapx-debug-tracing
oxsteins Jul 27, 2026
a4bc418
feat(uniswapx): make gas accounting optional
alrxy Jul 27, 2026
85cf83a
Merge pull request #101 from symbioticfi/fix/uniswapx-optional-gas
oxsteins Jul 27, 2026
cdab851
feat: add liquidity lens option for max asset calc
oxsteins Jul 27, 2026
36349b9
Merge remote-tracking branch 'origin/stage' into feat/liquidity-lens
oxsteins Jul 27, 2026
184eff8
Merge pull request #102 from symbioticfi/feat/liquidity-lens
oxsteins Jul 27, 2026
45e9989
feat(rfq): decline quotes below a per-token minimum input amount
1kresh Jul 27, 2026
27a30c9
Merge branch 'NO-TASK-rwa-min-amounts' into stage
1kresh Jul 27, 2026
50a1e68
chore(deps): bump docker/login-action from 4.4.0 to 4.5.2
dependabot[bot] Jul 28, 2026
3e7478a
Merge pull request #105 from symbioticfi/dependabot/github_actions/st…
oxsteins Jul 28, 2026
4e65ffc
Return capped single-route RFQ quotes
1kresh Jul 28, 2026
4695cf3
Merge pull request #107 from symbioticfi/codex/return-capped-rfq-quotes
1kresh Jul 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:

- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # pin@v3

- uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # pin@v4
- uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # pin@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
Expand Down
72 changes: 44 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,19 @@ RFQ_OPENAPI_URL ?= https://backend-production-a0ca.up.railway.app/api/v1/openapi
# JSON endpoint — the spec is embedded inline in the page, so refresh-lifi-openapi pulls the HTML and
# extracts it via hack/scalar-openapi-extract.py (see that target).
LIFI_OPENAPI_URL ?= https://order-dev.li.fi/docs
UNISWAPX_OPENAPI_URL ?= https://raw.githubusercontent.com/Uniswap/uniswapx-service/main/swagger.json
MORPHO_GRAPHQL_URL ?= https://api.morpho.org/graphql

# Contracts whose ABIs are vendored via refresh-abi. ABIS come from the rfq Foundry build; the
# CORE_MIRROR_ABIS (the 3F ThreeFAdapter, LiquidLane adapter, universal delegator, vault/ERC4626
# interfaces) come from the core-mirror build, since they aren't in rfq/out.
ABIS := IRequest IVaultController IWhitelist Executor Reactor
CORE_MIRROR_ABIS := ThreeFAdapter LiquidLaneAdapter IVaultV2 IERC4626
# CORE_MIRROR_ABIS (the 3F ThreeFAdapter, LiquidLane adapter, adapter factory, universal delegator,
# and vault/ERC4626 interfaces) come from the core-mirror build, since they aren't in rfq/out.
ABIS := IRequest IVaultController IWhitelist Executor Reactor LiquidLaneLifiExecutor LiquidLaneUniswapXExecutor
CORE_MIRROR_ABIS := ThreeFAdapter LiquidLaneAdapter IAdapterFactory IVaultV2 IERC4626
# api/abi/UniversalDelegator.json is hand-vendored to a minimal {limitOf} ABI (the full contract has
# an overloaded deallocateAll that abigen rejects, and the solver only reads limitOf) — like Multicall3.
# api/abi/FrontendLiquidityLens.json is likewise hand-vendored to the two overloaded getMaxAssets views
# (getMaxAssets(adapter) for 3F, getMaxAssets(adapter,tokenToRedeem) for LiquidLane) — the core lens that
# replaces each adapter's own getMaxAssets with a cross-adapter deallocation-cascade estimate.

# Contract:relpath mapping for Go bindings. Each contract gets its own package (the leaf dir) so
# shared ABI structs (e.g. the `Offer` tuple in both the adapter and IRequest) don't collide.
Expand All @@ -54,16 +58,20 @@ CORE_MIRROR_ABIS := ThreeFAdapter LiquidLaneAdapter IVaultV2 IERC4626
BINDINGS_V2 := ThreeFAdapter:3f/adapter IRequest:3f/request \
IVaultController:3f/vaultcontroller IWhitelist:3f/whitelist \
LiquidLaneAdapter:liquidlane/adapter Executor:rfq/executor Reactor:rfq/reactor \
UniversalDelegator:delegator IVaultV2:vaultv2 IERC4626:erc4626 \
LiquidLaneLifiExecutor:lifi/executor LiquidLaneUniswapXExecutor:uniswapx/executor \
ILifiInputSettler:lifi/inputsettler \
IAdapterFactory:adapterfactory UniversalDelegator:delegator IVaultV2:vaultv2 IERC4626:erc4626 \
SymbioticOevSolver:oev/callback RedStoneExecutor:oev/executor Morpho:oev/morpho \
AdaptiveCurveIrm:oev/irm MorphoOracle:oev/oracle \
AggregatorV3:oev/aggregator \
AggregatorV3:chainlink/aggregator \
FrontendLiquidityLens:lens \
ERC20:erc20 Multicall3:multicall3
# The OEV contracts (Morpho + its AdaptiveCurve IRM + market oracle, RedStone
# Executor, SymbioticOevSolver) plus a minimal ERC20 (decimals() only) aren't in our Foundry build, so their
# ABIs are hand-vendored under api/abi/ (not in ABIS/CORE_MIRROR_ABIS/refresh-abi). RedStoneExecutor avoids
# the rfq Executor name clash; solver ERC-20 reads (asset/balanceOf) reuse erc4626, the generic
# chain.Decimals reader uses erc20.
# Executor, SymbioticOevSolver), the LI.FI input settler ABI, plus a minimal ERC20
# (decimals() only) aren't in our default Foundry build, so their ABIs are hand-vendored under
# api/abi/ (not in ABIS/CORE_MIRROR_ABIS/refresh-abi). RedStoneExecutor avoids the rfq Executor
# name clash; solver ERC-20 reads (asset/balanceOf) reuse erc4626, the generic chain.Decimals reader
# uses erc20.
# Multicall3 is v2 like everything else — api/abi/Multicall3.json is hand-vendored (not a Foundry contract),
# so it's in BINDINGS_V2 but not ABIS. The chain.Multicall transport packs/unpacks aggregate3 and does its
# own eth_call.
Expand Down Expand Up @@ -123,6 +131,12 @@ refresh-lifi-openapi: ## Re-pull the LI.FI order-server OpenAPI spec (LIFI_OPENA
curl -fsSL "$(LIFI_OPENAPI_URL)" | python3 hack/scalar-openapi-extract.py > openapi/lifi-order.openapi.json
@echo "vendored openapi/lifi-order.openapi.json (extracted from the Scalar /docs page)"

.PHONY: refresh-uniswapx-openapi
refresh-uniswapx-openapi: ## Re-pull the UniswapX order-pool OpenAPI spec
@mkdir -p openapi
curl -fsSL "$(UNISWAPX_OPENAPI_URL)" | jq . > openapi/uniswapx-service.openapi.json
@echo "vendored openapi/uniswapx-service.openapi.json"

.PHONY: refresh-morpho-graphql-schema
refresh-morpho-graphql-schema: ## Re-pull the live Morpho GraphQL schema SDL (MORPHO_GRAPHQL_URL=...)
@mkdir -p api/graphql/morpho
Expand All @@ -132,7 +146,7 @@ refresh-morpho-graphql-schema: ## Re-pull the live Morpho GraphQL schema SDL (MO

.PHONY: bindings
bindings: ## Generate Go bindings from vendored ABIs (grouped per integration; package = leaf dir)
@for pair in $(BINDINGS_V2); do \
@set -e; for pair in $(BINDINGS_V2); do \
c="$${pair%%:*}"; rel="$${pair##*:}"; pkg="$${rel##*/}"; \
abi="api/abi/$$c.json"; \
if [[ ! -f "$$abi" ]]; then echo "missing $$abi (run make refresh-abi)"; exit 1; fi; \
Expand All @@ -141,15 +155,12 @@ bindings: ## Generate Go bindings from vendored ABIs (grouped per integration; p
echo "generated api/bindings/$$rel/$$c.go (v2)"; \
done

# All three OpenAPI clients are generated with the Java openapi-generator (via hack/openapi-generator-cli.sh,
# All OpenAPI clients are generated with the Java openapi-generator (via hack/openapi-generator-cli.sh,
# which downloads the pinned jar on demand — needs a JRE). It is the only generator that ingests the RFQ
# backend's OpenAPI 3.1 spec; we use it for the 3F (3.0) and LI.FI order-server specs too for one toolchain.
# $(OPENAPI_GENERATOR_VERSION) is the floor — 5.4.0/7.0.1 fail on the 3.1 spec. The generated package is
# stdlib-only (no go.mod change); the recipes strip the generator's non-package cruft, keeping just the Go
# client. $(4) is optional extra generator flags — used only by the LI.FI recipe to pass
# --skip-validate-spec (its spec is labelled OpenAPI 3.0.0 but uses 3.1 JSON-Schema constructs — prefixItems /
# propertyNames — and has dangling oneOf $refs; the generator handles them fine but its strict validator
# rejects them). 3f/rfq keep validation on.
# client. $(4) is available for source-specific generator flags; current specs generate with validation on.
define gen_openapi_client
GO_POST_PROCESS_FILE='gofmt -w' OPENAPI_GENERATOR_VERSION=$(OPENAPI_GENERATOR_VERSION) bash ./hack/openapi-generator-cli.sh \
generate --enable-post-process-file $(4) -i ./$(1) -g go -o ./$(2) --package-name $(3)
Expand All @@ -169,18 +180,19 @@ refresh-rfq-client: ## Generate the RFQ backend client (openapi-generator, Go) f
.PHONY: refresh-lifi-client
refresh-lifi-client: ## Generate the LI.FI order-server client (openapi-generator, Go) from the vendored spec
@rm -f api/lifiorder/*.go
@# The raw vendored spec has two upstream defects that make the generated Go uncompilable (dangling
@# oneOf $refs in QuoteDto.order; multi-tag operations that duplicate request structs). We keep the
@# vendored file raw (contract of record) and generate from a normalized temp copy produced by
@# hack/lifi-openapi-normalize.py (see that script for the exact, documented fixes). Inlined rather than
@# using gen_openapi_client so the normalization + temp-file plumbing lives in one shell block;
@# --skip-validate-spec is still needed (the spec is labelled 3.0.0 but uses 3.1 JSON-Schema constructs).
tmp="$$(mktemp -p . --suffix=.lifi-normalized.json)"; \
trap 'rm -f "$$tmp"' EXIT; \
python3 hack/lifi-openapi-normalize.py < openapi/lifi-order.openapi.json > "$$tmp"; \
$(call gen_openapi_client,openapi/lifi-order.openapi.json,api/lifiorder,lifiorder)

.PHONY: refresh-uniswapx-client
refresh-uniswapx-client: ## Generate the UniswapX order-pool client from the vendored spec
@rm -f api/uniswapxservice/*.go
@tmpdir="$$(mktemp -d)"; \
trap 'rm -rf "$$tmpdir"' EXIT; \
tmp="$$tmpdir/uniswapx-normalized.json"; \
python3 hack/uniswapx-openapi-normalize.py < openapi/uniswapx-service.openapi.json > "$$tmp"; \
GO_POST_PROCESS_FILE='gofmt -w' OPENAPI_GENERATOR_VERSION=$(OPENAPI_GENERATOR_VERSION) bash ./hack/openapi-generator-cli.sh \
generate --enable-post-process-file --skip-validate-spec -i "$$tmp" -g go -o ./api/lifiorder --package-name lifiorder
cd api/lifiorder && rm -rf go.mod go.sum .gitignore .openapi-generator-ignore .travis.yml git_push.sh README.md api docs test .openapi-generator
generate --enable-post-process-file -i "$$tmp" -g go -o ./api/uniswapxservice --package-name uniswapxservice \
--additional-properties=useOneOfDiscriminatorLookup=true
cd api/uniswapxservice && rm -rf go.mod go.sum .gitignore .openapi-generator-ignore .travis.yml git_push.sh README.md api docs test .openapi-generator

.PHONY: refresh-morpho-graphql-client
refresh-morpho-graphql-client: ## Generate the Morpho GraphQL client (genqlient) from the vendored schema + operations
Expand All @@ -194,7 +206,7 @@ refresh-morpho-graphql-client: ## Generate the Morpho GraphQL client (genqlient)
@gofmt -w api/morphographql/generated.go

.PHONY: openapi-client
openapi-client: refresh-3f-client refresh-rfq-client refresh-lifi-client ## Generate all OpenAPI clients
openapi-client: refresh-3f-client refresh-rfq-client refresh-lifi-client refresh-uniswapx-client ## Generate all OpenAPI clients

.PHONY: graphql-client
graphql-client: refresh-morpho-graphql-client ## Generate GraphQL clients
Expand All @@ -216,6 +228,10 @@ test: ## Run tests with race detector + coverage (hermetic only; fork/live suite
test-oev-live: ## OEV live checks — Morpho API discovery plus optional Sepolia fork payload dump
go test -tags live -run TestLive -v ./internal/solvers/redstoneoev/...

.PHONY: test-txmanager-anvil
test-txmanager-anvil: ## Exercise replacement/cancellation against an Anvil mempool with automine disabled
go test -race -tags integration -run TestAnvilTxManagerPendingLifecycle -v ./internal/txmanager

.PHONY: format
format: ## Run golangci-lint with autofix
golangci-lint run --fix
Expand Down
Loading
Loading