-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
414 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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,16 @@ | ||
{ | ||
"mainnet": { | ||
"example": "0x0000000000000000000000000000000000000000", | ||
"exampleAllowedTokens": [ | ||
"0x0000000000000000000000000000000000000000", | ||
"0x0000000000000000000000000000000000000000" | ||
] | ||
}, | ||
"arbitrum": { | ||
"example": "0x0000000000000000000000000000000000000000", | ||
"exampleAllowedTokens": [ | ||
"0x0000000000000000000000000000000000000000", | ||
"0x0000000000000000000000000000000000000000" | ||
] | ||
} | ||
} |
This file contains 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,92 @@ | ||
# Relay Facet | ||
|
||
## How it works | ||
|
||
The Relay Facet works by ... | ||
|
||
```mermaid | ||
graph LR; | ||
D{LiFiDiamond}-- DELEGATECALL -->RelayFacet; | ||
RelayFacet -- CALL --> C(Relay) | ||
``` | ||
|
||
## Public Methods | ||
|
||
- `function startBridgeTokensViaRelay(BridgeData calldata _bridgeData, RelayData calldata _relayData)` | ||
- Simply bridges tokens using relay | ||
- `swapAndStartBridgeTokensViarelay(BridgeData memory _bridgeData, LibSwap.SwapData[] calldata _swapData, relayData memory _relayData)` | ||
- Performs swap(s) before bridging tokens using relay | ||
|
||
## relay Specific Parameters | ||
|
||
The methods listed above take a variable labeled `_relayData`. This data is specific to relay and is represented as the following struct type: | ||
|
||
```solidity | ||
/// @param example Example parameter. | ||
struct relayData { | ||
string example; | ||
} | ||
``` | ||
|
||
## 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: 'relay', // 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=relay&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=relay&fromAddress={YOUR_WALLET_ADDRESS}' | ||
``` |
This file contains 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,33 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.17; | ||
|
||
import { DeployScriptBase } from "./utils/DeployScriptBase.sol"; | ||
import { stdJson } from "forge-std/Script.sol"; | ||
import { RelayFacet } from "lifi/Facets/RelayFacet.sol"; | ||
|
||
contract DeployScript is DeployScriptBase { | ||
using stdJson for string; | ||
|
||
constructor() DeployScriptBase("RelayFacet") {} | ||
|
||
function run() | ||
public | ||
returns (RelayFacet deployed, bytes memory constructorArgs) | ||
{ | ||
constructorArgs = getConstructorArgs(); | ||
|
||
deployed = RelayFacet(deploy(type(RelayFacet).creationCode)); | ||
} | ||
|
||
function getConstructorArgs() internal override returns (bytes memory) { | ||
// If you don't have a constructor or it doesn't take any arguments, you can remove this function | ||
string memory path = string.concat(root, "/config/relay.json"); | ||
string memory json = vm.readFile(path); | ||
|
||
address example = json.readAddress( | ||
string.concat(".", network, ".example") | ||
); | ||
|
||
return abi.encode(example); | ||
} | ||
} |
This file contains 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,24 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.17; | ||
|
||
import { UpdateScriptBase } from "./utils/UpdateScriptBase.sol"; | ||
import { stdJson } from "forge-std/StdJson.sol"; | ||
import { DiamondCutFacet, IDiamondCut } from "lifi/Facets/DiamondCutFacet.sol"; | ||
import { RelayFacet } from "lifi/Facets/RelayFacet.sol"; | ||
|
||
contract DeployScript is UpdateScriptBase { | ||
using stdJson for string; | ||
|
||
struct Config { | ||
uint256 a; | ||
bool b; | ||
address c; | ||
} | ||
|
||
function run() | ||
public | ||
returns (address[] memory facets, bytes memory cutData) | ||
{ | ||
return update("RelayFacet"); | ||
} | ||
} |
This file contains 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,123 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.17; | ||
|
||
import { ILiFi } from "../Interfaces/ILiFi.sol"; | ||
import { LibDiamond } from "../Libraries/LibDiamond.sol"; | ||
import { LibAsset } from "../Libraries/LibAsset.sol"; | ||
import { LibSwap } from "../Libraries/LibSwap.sol"; | ||
import { ReentrancyGuard } from "../Helpers/ReentrancyGuard.sol"; | ||
import { SwapperV2 } from "../Helpers/SwapperV2.sol"; | ||
import { Validatable } from "../Helpers/Validatable.sol"; | ||
|
||
/// @title Relay Facet | ||
/// @author LI.FI (https://li.fi) | ||
/// @notice Provides functionality for bridging through Relay Protocol | ||
/// @custom:version 1.0.0 | ||
contract RelayFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable { | ||
/// Storage /// | ||
|
||
// Receiver for native transfers | ||
address public immutable relayReceiver; | ||
address public immutable relaySolver; | ||
|
||
/// Types /// | ||
|
||
/// @dev Optional bridge specific struct | ||
/// @param exampleParam Example parameter | ||
struct RelayData { | ||
bytes32 requestId; | ||
address receivingAssetId; | ||
bytes signature; | ||
} | ||
|
||
/// Modifiers /// | ||
modifier isValidQuote( | ||
ILiFi.BridgeData calldata _bridgeData, | ||
RelayData calldata _relayData | ||
) { | ||
// TODO: Verify the following | ||
// requestId bytes32 | ||
// originChainId uint256 | ||
// sender bytes32(address) | ||
// sendingAssetId bytes32(address) | ||
// dstChainId uint256 | ||
// receiver bytes32(address) | ||
// receivingAssetId bytes32(address) | ||
_; | ||
} | ||
|
||
/// Constructor /// | ||
|
||
constructor(address _relayReceiver, address _relaySolver) { | ||
relayReceiver = _relayReceiver; | ||
relaySolver = _relaySolver; | ||
} | ||
|
||
/// External Methods /// | ||
|
||
/// @notice Bridges tokens via Relay | ||
/// @param _bridgeData The core information needed for bridging | ||
/// @param _relayData Data specific to Relay | ||
function startBridgeTokensViaRelay( | ||
ILiFi.BridgeData memory _bridgeData, | ||
RelayData calldata _relayData | ||
) | ||
external | ||
payable | ||
nonReentrant | ||
refundExcessNative(payable(msg.sender)) | ||
validateBridgeData(_bridgeData) | ||
doesNotContainSourceSwaps(_bridgeData) | ||
doesNotContainDestinationCalls(_bridgeData) | ||
{ | ||
LibAsset.depositAsset( | ||
_bridgeData.sendingAssetId, | ||
_bridgeData.minAmount | ||
); | ||
_startBridge(_bridgeData, _relayData); | ||
} | ||
|
||
/// @notice Performs a swap before bridging via Relay | ||
/// @param _bridgeData The core information needed for bridging | ||
/// @param _swapData An array of swap related data for performing swaps before bridging | ||
/// @param _relayData Data specific to Relay | ||
function swapAndStartBridgeTokensViaRelay( | ||
ILiFi.BridgeData memory _bridgeData, | ||
LibSwap.SwapData[] calldata _swapData, | ||
RelayData calldata _relayData | ||
) | ||
external | ||
payable | ||
nonReentrant | ||
refundExcessNative(payable(msg.sender)) | ||
containsSourceSwaps(_bridgeData) | ||
doesNotContainDestinationCalls(_bridgeData) | ||
validateBridgeData(_bridgeData) | ||
{ | ||
_bridgeData.minAmount = _depositAndSwap( | ||
_bridgeData.transactionId, | ||
_bridgeData.minAmount, | ||
_swapData, | ||
payable(msg.sender) | ||
); | ||
_startBridge(_bridgeData, _relayData); | ||
} | ||
|
||
/// Internal Methods /// | ||
|
||
/// @dev Contains the business logic for the bridge via Relay | ||
/// @param _bridgeData The core information needed for bridging | ||
/// @param _relayData Data specific to Relay | ||
function _startBridge( | ||
ILiFi.BridgeData memory _bridgeData, | ||
RelayData calldata _relayData | ||
) internal { | ||
// check if sendingAsset is native or ERC20 | ||
if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) { | ||
// Native | ||
} else { | ||
// ERC20 | ||
} | ||
emit LiFiTransferStarted(_bridgeData); | ||
} | ||
} |
This file contains 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
Oops, something went wrong.