Skip to content

Add Arc swaps via LI.FI - #495

Open
j0ntz wants to merge 1 commit into
masterfrom
jon/arc-chain
Open

j0ntz wants to merge 1 commit into
masterfrom
jon/arc-chain

Conversation

@j0ntz

@j0ntz j0ntz commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

EdgeApp/edge-currency-accountbased#1106 (the arc currency plugin)

Description

Adds Arc swaps through LI.FI (chain key arc). Per the task, LI.FI is the only provider mapped; every other provider maps arc to null.

Asana: https://app.asana.com/0/1215088146871429/1218563157181138

LI.FI trades Arc's native USDC as its ERC-20 interface at 0x3600000000000000000000000000000000000000 with 6 decimals, while the wallet counts the same balance in 18. Looking the native asset up at the zero address fails intermittently ("Could not find token '5042-0x000…'"). So a chain in NATIVE_ERC20_INTERFACES:

  • quotes with the interface address and sends LI.FI the amount at 6 decimals, dropping the digits it cannot express (an amount below one interface unit is SwapBelowLimitError);
  • scales LI.FI's fromAmount, toAmount and toAmountMin back to native units, including when Arc is the destination;
  • swaps out as an approval on 0x3600 plus a call that sends no value, the shape of LI.FI's transaction request (value: 0x0). The engine's balance check then covers only the fee, so the plugin checks the swapped amount against the balance and throws InsufficientFundsError itself.

Tested on the iOS sim with the plugin forced to LI.FI (screenshots below):

  • 6.001 USDC on Polygon to 5.952388 USDC on Arc executed; the balance matched the quote.
  • 2.5 USDC on Arc to Polygon USDC executed: approval 0x4e4ada5f… and swap 0xf4a07658… mined, and LI.FI's contract pulled exactly 2500000 through 0x3600.

Frames 02 to 07 were captured before a fix in EdgeApp/edge-currency-accountbased#1106 changed the Arc denomination symbol from $ to USDC, so those amounts carry a $ prefix. The $0 fiat values come from Arc having no rates yet; the edge-rates-server PR adds them.


Note

Medium Risk
Changes swap quoting, approvals, and balance validation for Arc’s non-standard native representation; incorrect scaling or checks could mis-quote or fail swaps involving user balances.

Overview
Adds Arc as a supported chain for swaps, wired only through LI.FI (arc chain key). The arc plugin id is registered across provider mappings; every non-LI.FI partner maps it to null so Arc routes do not appear elsewhere.

The LI.FI plugin gains handling for chains where the native asset is exposed as an ERC-20 interface (Arc native USDC at 0x3600…0000, 6 decimals vs the wallet’s 18-decimal native units). Quotes use the interface contract instead of the zero address, scale fromAmount/toAmount/toAmountMin between LI.FI and wallet units, and build swaps as token approval + zero-value contract call. Extra safeguards include rejecting sub-minimum scaled amounts, capping quoted spend above the request, correcting approval metadata for display, a manual balance check (swap amount + fees) when the engine only validates gas, and max-swap integration via getMaxSwappable / fromMaxSwap.

Reviewed by Cursor Bugbot for commit a4672bb. Bugbot is set up for automated code reviews on this repo. Configure here.

Test evidence

a4672bb
Add Arc swaps via LI.FI

lifi quote polygon usdc to arc

lifi swap into arc success

lifi quote arc to polygon usdc

lifi swap out of arc success

arc history send swap approval receive

lifi quote arc out after fix

lifi swap arc out after fix success

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4fec97f1ee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/swap/defi/lifi.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4fec97f. Configure here.

Comment thread src/swap/defi/lifi.ts Outdated
Map the arc plugin id to LI.FI's chain key, arc.

LI.FI trades Arc's native USDC as its ERC-20 interface at 0x3600...0000
with 6 decimals, while the wallet counts the same balance in 18, and
looking the native asset up at the zero address fails intermittently. A
chain listed in NATIVE_ERC20_INTERFACES therefore quotes with the
interface address, sends LI.FI the amount at the interface's precision,
and scales LI.FI's amounts back to native units.

A swap from that native asset is an approval on the interface plus a
call that sends no value, the path LI.FI's transaction request takes.
The approval takes LI.FI's amount, so a quote above the requested amount
is rejected. The engine's balance check then sees only the call's fee,
so the plugin checks the amount plus the approval and swap fees against
the balance itself; a max swap skips that check because it sizes itself
from those fees. An amount below one interface unit is below LI.FI's
limit.

Every other provider maps arc to null.
@j0ntz

j0ntz commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Description update for a4672bb, superseding the third bullet above:

  • A quote whose estimate.fromAmount is above the requested amount (in LI.FI's units) is rejected before the approval is built, since the approval takes LI.FI's amount.
  • The Arc balance check requires the amount plus the approval fees and the swap fee (buffered gas limit times gas price). Max swaps skip it: getMaxSwappable already subtracts those fees.

Re-driven against the live LI.FI API: a 2 USDC quote on a 10 USDC balance builds normally, the same quote on a 2 USDC balance returns InsufficientFundsError, and a max swap on 3 USDC sizes to 2.98958 USDC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant