-
Notifications
You must be signed in to change notification settings - Fork 85
LF-14786 Everclear [EverclearFacet v1.0.0, IEverclearFeeAdapter v1.0.0] #1413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mirooon
wants to merge
55
commits into
main
Choose a base branch
from
lf-14786-everclear
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
a3bd1ed
added Everclear components
mirooon 389cfa8
changes
mirooon e0fe754
changes
mirooon b895f46
changes
mirooon da228b6
updates
mirooon cf184cd
merge with main
mirooon c977407
updates
mirooon 4a1330e
updates
mirooon 7d0848a
updates
mirooon b4fb890
updates
mirooon c50b30f
Merge branch 'main' into lf-14786-everclear
mirooon b5d19f9
Refactor EverclearFacet and IEverclearFeeAdapter: Updated SPDX licens…
mirooon 2487ab8
Enhance EverclearFacet documentation and implementation: Updated the …
mirooon bad4c86
Implement native fee handling in EverclearFacet: Added nativeFee para…
mirooon 1dc7857
Remove MessageHashUtils library and replace its functionality in Ever…
mirooon 39e6abc
deployed EverclearFacet on staging
mirooon 1ea5ed8
updates
mirooon 9527bf1
Update deployment logs and demo script for EverclearFacet: Changed de…
mirooon b194cfc
Update demoEverclear script: Added transaction hash for bridging USDC…
mirooon 010f82d
update demo script
mirooon 9ea63b4
added tron script
mirooon 533144a
added EverclearV2Facet
mirooon d50ab7b
Refactor EverclearFacet and EverclearV2Facet: Updated error handling …
mirooon f5ee499
Merge branch 'main' into lf-14786-everclear
mirooon f264b7b
added nativeFee in natspec for EverclearData
mirooon 02661a7
remove old v1 in favor of v2
ezynda3 2364e1d
fix sig generation
ezynda3 7c9a130
fix
ezynda3 3e3a7c0
docs
ezynda3 cf23cc0
deploy to staging and create demo script
ezynda3 b4acd17
redeploy to staging update demo script
ezynda3 31f66ef
fix
ezynda3 11b3b3e
fixes
ezynda3 78bb769
Merge branch 'main' into lf-14786-everclear
ezynda3 5e45a9f
solana
ezynda3 b538ad2
fixes
ezynda3 76da9be
Add EverclearFacet entry to deployRequirements.json
ezynda3 e12a85e
Update EverclearFacet version to 1.0.0
ezynda3 06ff1a2
Implement positive slippage handling for Everclear swaps
ezynda3 5e6b6ff
Fix fee validation to prevent zero bridge amount
ezynda3 55a7b9d
Clarify fee handling comments in EverclearFacet
ezynda3 ea23948
Improve test code quality and add event checks
ezynda3 a8a6107
Clean up demo script and add amountOutMinMultiplier
ezynda3 a450a9d
Move Solana utility functions to demoScriptHelpers
ezynda3 e895636
Revert positive slippage handling changes
ezynda3 ca91f38
Implement positive slippage protection for Everclear swaps
ezynda3 dbdf8ef
Merge branch 'main' into lf-14786-everclear
ezynda3 8128542
Improve error comment to specify EVM OutOfFunds error
ezynda3 76c3cb3
Add all supported Everclear chains with FeeAdapter addresses
ezynda3 de1cb2b
Fix test signature format: use V2 FeeAdapter signature helpers
ezynda3 5ba1038
Update IEverclearFeeAdapter version to 1.0.0
ezynda3 bc47b72
updated demoEverclear.ts
mirooon 96b1b32
Remove redundant variable assignments in positive slippage handling
ezynda3 e2394a6
Merge branch 'main' into lf-14786-everclear
ezynda3 d8179c3
add refundReceiver
ezynda3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| { | ||
| "mainnet": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "optimism": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "bsc": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "unichain": { | ||
| "feeAdapter": "0x877Fd0A881B63eBE413124EeE6abbCD7E82cf10b" | ||
| }, | ||
| "polygon": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "zksync": { | ||
| "feeAdapter": "0xa537f0d027cBA1661dd1eB46fCd79030CD75A2cd" | ||
| }, | ||
| "ronin": { | ||
| "feeAdapter": "0x5443DF583Cc039881Fe30A730310A4f43016df88" | ||
| }, | ||
| "base": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "apechain": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "mode": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "arbitrum": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "avalanche": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "linea": { | ||
| "feeAdapter": "0xAa7ee09f745a3c5De329EB0CD67878Ba87B70Ffe" | ||
| }, | ||
| "blast": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "scroll": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "taiko": { | ||
| "feeAdapter": "0x986962C73059e06303efaD1F4c61Ed4905Fc5431" | ||
| }, | ||
| "berachain": { | ||
| "feeAdapter": "0x3c135048306b412Ad8F4375F6a8CBe94b5D56184" | ||
| }, | ||
| "gnosis": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "mantle": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "sonic": { | ||
| "feeAdapter": "0xd0185bfb8107c5b2336bC73cE3fdd9Bfb504540e" | ||
| }, | ||
| "ink": { | ||
| "feeAdapter": "0x877Fd0A881B63eBE413124EeE6abbCD7E82cf10b" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| # Everclear Facet | ||
|
|
||
| ## How it works | ||
|
|
||
| The Everclear Facet enables cross-chain token bridging through the Everclear protocol, which uses a Spoke and Hub model to transport intents and settlements between supported domains. The facet interacts with an EverclearFeeAdapter contract that handles fee collection and signature verification before forwarding intents to the Everclear protocol. | ||
|
|
||
| Everclear uses an intent-based architecture where users create intents that specify their desired cross-chain transfers. These intents are then matched and settled through a netting mechanism that optimizes liquidity across chains. The protocol supports both EVM and non-EVM destination chains. | ||
|
|
||
| ```mermaid | ||
| graph LR; | ||
| D{LiFiDiamond}-- DELEGATECALL -->EverclearFacet; | ||
| EverclearFacet -- CALL --> FeeAdapter(EverclearFeeAdapter); | ||
| FeeAdapter -- CALL --> E(Everclear Protocol) | ||
| ``` | ||
|
|
||
| ## Public Methods | ||
|
|
||
| - `function startBridgeTokensViaEverclear(BridgeData calldata _bridgeData, EverclearData calldata _everclearData)` | ||
| - Simply bridges tokens using everclear | ||
| - `swapAndStartBridgeTokensViaEverclear(BridgeData memory _bridgeData, LibSwap.SwapData[] calldata _swapData, everclearData memory _everclearData)` | ||
| - Performs swap(s) before bridging tokens using everclear | ||
mirooon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Everclear Specific Parameters | ||
|
|
||
| The methods listed above take a variable labeled `_everclearData`. This data is specific to Everclear and is represented as the following struct type: | ||
|
|
||
| ```solidity | ||
| /// @param receiverAddress The address of the receiver (bytes32 for non-EVM chains) | ||
| /// @param nativeFee The native fee amount (in native tokens, e.g., ETH) | ||
| /// @param outputAsset The address of the output asset on destination chain (bytes32 format) | ||
| /// @param amountOutMin The minimum amount out on destination chain | ||
| /// @param ttl The time to live for the intent (in seconds) | ||
| /// @param data Additional data for the intent (typically empty) | ||
| /// @param fee The protocol fee amount (in input token units) | ||
| /// @param deadline The deadline timestamp for the fee signature | ||
| /// @param sig The signature from the fee signer authorizing the fee | ||
| /// @param refundReceiver Address that will receive refunds from positive slippage | ||
| struct EverclearData { | ||
| bytes32 receiverAddress; | ||
| uint256 nativeFee; | ||
| bytes32 outputAsset; | ||
| uint256 amountOutMin; | ||
| uint48 ttl; | ||
| bytes data; | ||
| uint256 fee; | ||
| uint256 deadline; | ||
| bytes sig; | ||
| address refundReceiver; | ||
| } | ||
| ``` | ||
|
|
||
| ### Fee Structure | ||
|
|
||
| The Everclear protocol uses a signed fee mechanism where: | ||
|
|
||
| - The `fee` is deducted from the bridge amount and collected separately | ||
| - The `nativeFee` (if non-zero) must be sent as msg.value and is used for cross-chain messaging costs | ||
| - The `sig` parameter contains an EIP-191 signature over the four parameters: `abi.encode(fee, nativeFee, inputAsset, deadline)` | ||
| - The signature must be created by the authorized fee signer in the EverclearFeeAdapter | ||
| - The `deadline` must be greater than or equal to the current block timestamp | ||
|
|
||
| ### V2 Changes | ||
|
|
||
| - **Parameter Change**: `maxFee` (uint24) has been replaced with `amountOutMin` (uint256) | ||
| - **Native Fee Support**: Added `nativeFee` parameter for cross-chain messaging costs | ||
|
|
||
| ### Chain Support | ||
|
|
||
| - **EVM Chains**: For EVM destination chains, `receiverAddress` must match `bridgeData.receiver` when converted to bytes32 | ||
| - **Non-EVM Chains**: Set `bridgeData.receiver` to `NON_EVM_ADDRESS` and provide the actual receiver in `receiverAddress` | ||
|
|
||
| ### Refund Receiver | ||
|
|
||
| The `refundReceiver` parameter specifies the address that will receive any positive slippage from source swaps. When using `swapAndStartBridgeTokensViaEverclear`, if the swap results in more tokens than expected, the excess amount is sent to the `refundReceiver` instead of being included in the bridge. This is necessary because Everclear's signature validation includes the original bridge amount, preventing adjustment of the amount sent to the protocol. | ||
|
|
||
| ## Error Conditions | ||
|
|
||
| The facet will revert with specific errors in the following cases: | ||
|
|
||
| - `InvalidConfig()`: Constructor called with zero address for fee adapter | ||
| - `InvalidCallData()`: `outputAsset` is bytes32(0), `refundReceiver` is address(0), or bridge amount is less than or equal to fee | ||
| - `InvalidNonEVMReceiver()`: Non-EVM bridging with `receiverAddress` as bytes32(0) | ||
| - `InvalidReceiver()`: EVM bridging where `bridgeData.receiver` doesn't match `everclearData.receiverAddress` | ||
| - Standard LiFi validation errors for invalid bridge data | ||
|
|
||
| ## Swap Data | ||
|
|
||
| Some methods accept a `SwapData _swapData` parameter. | ||
|
|
||
| Swapping is performed by a swap specific library that expects an array of calldata to can be run on various DEXs (i.e. Uniswap) to make one or multiple swaps before performing another action. | ||
|
|
||
| The swap library can be found [here](../src/Libraries/LibSwap.sol). | ||
|
|
||
| ## LiFi Data | ||
|
|
||
| Some methods accept a `BridgeData _bridgeData` parameter. | ||
|
|
||
| This parameter is strictly for analytics purposes. It's used to emit events that we can later track and index in our subgraphs and provide data on how our contracts are being used. `BridgeData` and the events we can emit can be found [here](../src/Interfaces/ILiFi.sol). | ||
|
|
||
| ## Getting Sample Calls to interact with the Facet | ||
|
|
||
| In the following some sample calls are shown that allow you to retrieve a populated transaction that can be sent to our contract via your wallet. | ||
|
|
||
| All examples use our [/quote endpoint](https://apidocs.li.fi/reference/get_quote) to retrieve a quote which contains a `transactionRequest`. This request can directly be sent to your wallet to trigger the transaction. | ||
|
|
||
| The quote result looks like the following: | ||
|
|
||
| ```javascript | ||
| const quoteResult = { | ||
| id: '0x...', // quote id | ||
| type: 'lifi', // the type of the quote (all lifi contract calls have the type "lifi") | ||
| tool: 'everclear', // the bridge tool used for the transaction | ||
| action: {}, // information about what is going to happen | ||
| estimate: {}, // information about the estimated outcome of the call | ||
| includedSteps: [], // steps that are executed by the contract as part of this transaction, e.g. a swap step and a cross step | ||
| transactionRequest: { | ||
| // the transaction that can be sent using a wallet | ||
| data: '0x...', | ||
| to: '0x...', | ||
| value: '0x00', | ||
| from: '{YOUR_WALLET_ADDRESS}', | ||
| chainId: 100, | ||
| gasLimit: '0x...', | ||
| gasPrice: '0x...', | ||
| }, | ||
| } | ||
| ``` | ||
|
|
||
| A detailed explanation on how to use the /quote endpoint and how to trigger the transaction can be found [here](https://docs.li.fi/products/more-integration-options/li.fi-api/transferring-tokens-example). | ||
|
|
||
| **Hint**: Don't forget to replace `{YOUR_WALLET_ADDRESS}` with your real wallet address in the examples. | ||
|
|
||
| ### Cross Only | ||
|
|
||
| To get a transaction for a transfer from 30 USDC.e on Avalanche to USDC on Binance you can execute the following request: | ||
|
|
||
| ```shell | ||
| curl 'https://li.quest/v1/quote?fromChain=AVA&fromAmount=30000000&fromToken=USDC&toChain=BSC&toToken=USDC&slippage=0.03&allowBridges=everclear&fromAddress={YOUR_WALLET_ADDRESS}' | ||
| ``` | ||
|
|
||
| ### Swap & Cross | ||
|
|
||
| To get a transaction for a transfer from 30 USDT on Avalanche to USDC on Binance you can execute the following request: | ||
|
|
||
| ```shell | ||
| curl 'https://li.quest/v1/quote?fromChain=AVA&fromAmount=30000000&fromToken=USDT&toChain=BSC&toToken=USDC&slippage=0.03&allowBridges=everclear&fromAddress={YOUR_WALLET_ADDRESS}' | ||
| ``` | ||
|
|
||
| ## Additional Resources | ||
|
|
||
| - [Everclear Protocol Documentation](https://docs.everclear.org/developers/fundamentals) | ||
| - [Everclear API Reference](https://docs.everclear.org/developers/api) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.