-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add support for contract calls through intent #25
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
Merged
Merged
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
cfba24e
change contract logic
lumtis e010258
add test
lumtis 40d1113
format
lumtis f0707e5
skip gas payment when target is zetachain
lumtis f419d91
add intent proxy deployment script
lumtis 448f071
fmt
lumtis 5d716f4
use transfer instead of approve
lumtis 1546cb9
remove try initiate
lumtis 69e55ae
add call support
lumtis 837181c
fix tests
lumtis 2c6d2bb
add example contract
lumtis ab0cbea
fmt
lumtis 5c3074a
conflicts
lumtis 114c7c5
fix file
lumtis f8c8761
add initiateTransfer
lumtis 5009d03
add fulfillTransfer
lumtis 502cfdc
add intent call tests
lumtis 3d4d593
support ciustom gas limit
lumtis f5a6804
a few fix
lumtis 7616eff
fix imports
lumtis 501e63a
remove nonReentrant
lumtis 6596f99
increase default gas limit
lumtis 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
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,168 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
| import "@openzeppelin/contracts/access/Ownable.sol"; | ||
| import "../src/interfaces/IntentTarget.sol"; | ||
|
|
||
| // Uniswap V2 Router interface (partial) | ||
| interface IUniswapV2Router { | ||
| function swapExactTokensForTokens( | ||
| uint256 amountIn, | ||
| uint256 amountOutMin, | ||
| address[] calldata path, | ||
| address to, | ||
| uint256 deadline | ||
| ) external returns (uint256[] memory amounts); | ||
| } | ||
|
|
||
| /** | ||
| * @title CrossChainSwapper | ||
| * @dev Example implementation of IntentTarget that performs token swaps | ||
| */ | ||
| contract CrossChainSwapper is IntentTarget, Ownable { | ||
| // Uniswap V2 Router address | ||
| address public uniswapRouter; | ||
|
|
||
| // Reward configuration | ||
| uint256 public rewardPercentage = 5; // 5% reward to fulfillers | ||
|
|
||
| /** | ||
| * @dev Constructor | ||
| * @param _uniswapRouter The Uniswap V2 Router address | ||
| */ | ||
| constructor(address _uniswapRouter) Ownable(msg.sender) { | ||
| uniswapRouter = _uniswapRouter; | ||
| } | ||
|
|
||
| /** | ||
| * @dev Update the Uniswap router address | ||
| * @param _uniswapRouter The new router address | ||
| */ | ||
| function setUniswapRouter(address _uniswapRouter) external onlyOwner { | ||
| uniswapRouter = _uniswapRouter; | ||
| } | ||
|
|
||
| /** | ||
| * @dev Set reward percentage for fulfillers | ||
| * @param _percentage New percentage (0-100) | ||
| */ | ||
| function setRewardPercentage(uint256 _percentage) external onlyOwner { | ||
| require(_percentage <= 100, "Percentage must be between 0-100"); | ||
| rewardPercentage = _percentage; | ||
| } | ||
|
|
||
| /** | ||
| * @dev Called by the protocol during intent fulfillment | ||
| * @param intentId The ID of the intent | ||
| * @param asset The ERC20 token address | ||
| * @param amount Amount transferred | ||
| * @param data Custom data for execution | ||
| */ | ||
| function onFulfill( | ||
| bytes32 intentId, | ||
| address asset, | ||
| uint256 amount, | ||
| bytes calldata data | ||
| ) external override { | ||
| // Decode the swap parameters from the data field | ||
| ( | ||
| address[] memory path, | ||
| uint256 minAmountOut, | ||
| uint256 deadline, | ||
| address receiver | ||
| ) = decodeSwapParams(data); | ||
|
|
||
| // Ensure the first token in the path matches the received asset | ||
| require(path[0] == asset, "Asset mismatch"); | ||
|
|
||
| // Approve router to spend the tokens | ||
| IERC20(asset).approve(uniswapRouter, amount); | ||
|
|
||
| // Execute the swap on Uniswap | ||
| IUniswapV2Router(uniswapRouter).swapExactTokensForTokens( | ||
lumtis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| amount, | ||
| minAmountOut, | ||
| path, | ||
| receiver, | ||
| deadline | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * @dev Called by the protocol during intent settlement | ||
| * @param intentId The ID of the intent | ||
| * @param asset The ERC20 token address | ||
| * @param amount Amount transferred | ||
| * @param data Custom data for execution | ||
| * @param fulfillmentIndex The fulfillment index for this intent | ||
| */ | ||
| function onSettle( | ||
| bytes32 intentId, | ||
| address asset, | ||
| uint256 amount, | ||
| bytes calldata data, | ||
| bytes32 fulfillmentIndex | ||
| ) external override { | ||
| // This function is called when an intent is settled | ||
| // We can implement custom logic here, such as rewarding the fulfiller | ||
|
|
||
| // We could send a small reward to the fulfiller from this contract's balance | ||
| // This might be tokens previously sent to this contract for this purpose | ||
|
|
||
| // Example: get receiver address from the data | ||
| (, , , address receiver) = decodeSwapParams(data); | ||
|
|
||
| // Example: transfer a small reward from this contract to the fulfiller | ||
| // This assumes this contract holds some tokens for rewards | ||
| // In a real implementation, you might have a more sophisticated reward system | ||
|
|
||
| // Get fulfiller address from the Intent contract (passed as msg.sender) | ||
| address intentContract = msg.sender; | ||
|
|
||
| // Note: In a real implementation, you would have a way to get the fulfiller address | ||
| // For this example, we're just showing the concept | ||
| // Normally, you could call a view function on the Intent contract to get the fulfiller | ||
| } | ||
|
|
||
| /** | ||
| * @dev Helper function to decode swap parameters from the bytes data | ||
| * @param data The encoded swap parameters | ||
| * @return path Array of token addresses for the swap path | ||
| * @return minAmountOut Minimum output amount | ||
| * @return deadline Transaction deadline | ||
| * @return receiver Address that will receive the swapped tokens | ||
| */ | ||
| function decodeSwapParams( | ||
| bytes memory data | ||
| ) | ||
| internal | ||
| pure | ||
| returns ( | ||
| address[] memory path, | ||
| uint256 minAmountOut, | ||
| uint256 deadline, | ||
| address receiver | ||
| ) | ||
| { | ||
| // Decode the packed data | ||
| return abi.decode(data, (address[], uint256, uint256, address)); | ||
| } | ||
|
|
||
| /** | ||
| * @dev Helper function to encode swap parameters | ||
| * @param path Array of token addresses for the swap path | ||
| * @param minAmountOut Minimum output amount | ||
| * @param deadline Transaction deadline | ||
| * @param receiver Address that will receive the swapped tokens | ||
| * @return The encoded parameters as bytes | ||
| */ | ||
| function encodeSwapParams( | ||
| address[] memory path, | ||
| uint256 minAmountOut, | ||
| uint256 deadline, | ||
| address receiver | ||
| ) public pure returns (bytes memory) { | ||
| return abi.encode(path, minAmountOut, deadline, receiver); | ||
| } | ||
| } | ||
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.