Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
72 changes: 44 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Cross-Chain Swap Optimization Hook
# Cross-Chain Swap Optimization Hook for Uniswap V4

This is the implementation of a cross-chain swap optimization system that finds the best execution venue across multiple blockchains.
This is a Uniswap V4 hook implementation that optimizes swaps across multiple blockchains, automatically routing users to the most profitable execution venue.

## Project Structure

Expand All @@ -19,7 +19,12 @@ src/

### CrossChainSwapHook.sol

The main contract that handles cross-chain swap optimization. It inherits from OpenZeppelin's `Ownable`, `ReentrancyGuard`, and `Pausable`.
The main Uniswap V4 hook contract that handles cross-chain swap optimization. It inherits from Uniswap V4's `BaseHook` and OpenZeppelin's `Ownable`, `ReentrancyGuard`, and `Pausable`.

**Hook Implementation:**
- Implements `beforeSwap` and `afterSwap` hooks from Uniswap V4
- Automatically analyzes cross-chain opportunities before each swap
- Routes users to the most profitable execution venue

**Key State Variables:**
- `pythOracle`: IPythOracle instance for price feeds
Expand All @@ -28,26 +33,29 @@ The main contract that handles cross-chain swap optimization. It inherits from O
- `tokenPriceData[]`: Mapping of tokens to their price feed configurations
- `maxSlippageBps`: Maximum allowed slippage (default: 300 = 3%)
- `protocolFeeBps`: Protocol fee in basis points (default: 10 = 0.1%)
- `crossChainThresholdBps`: Minimum improvement threshold for cross-chain (default: 200 = 2%)

**Hook Functions:**
- `_beforeSwap()`: Analyzes cross-chain opportunities and executes if profitable
- `_afterSwap()`: Handles post-swap logic and emits events
- `getHookPermissions()`: Returns hook permissions for V4 validation

**Main Functions:**
- `executeSwap(SwapRequest memory request)`: Executes the swap optimization
- `simulateSwap(SwapRequest memory request)`: Returns quotes without executing
- `addVenue(uint256 chainId, address venueAddress, string memory name, uint256 gasEstimate)`: Adds new execution venue
- `configurePriceData(address token, bytes32 priceId, uint256 maxStaleness)`: Configures token price feeds
**Admin Functions:**
- `addVenue()`: Adds new execution venue
- `configurePriceData()`: Configures token price feeds
- `simulateSwap()`: Returns quotes without executing

**Structs:**
```solidity
struct SwapRequest {
address tokenIn;
address tokenOut;
uint256 amountIn;
struct CrossChainSwapData {
uint256 minAmountOut;
address recipient;
uint256 deadline;
bytes32 tokenInPriceId;
bytes32 tokenOutPriceId;
uint256 maxGasPrice;
bool forceLocal;
uint256 thresholdBps; // Minimum improvement threshold in basis points
}

struct SwapVenue {
Expand Down Expand Up @@ -153,8 +161,9 @@ struct ScoringWeights {
## Usage Example

```solidity
// Deploy the contract
// Deploy the hook contract
CrossChainSwapHook hook = new CrossChainSwapHook(
poolManagerAddress,
pythOracleAddress,
bridgeProtocolAddress,
feeRecipientAddress
Expand All @@ -168,21 +177,19 @@ hook.addVenue(42161, arbitrumVenueAddress, "Arbitrum Uniswap", 150000);
hook.configurePriceData(WETH, ETH_PRICE_ID, 600);
hook.configurePriceData(USDC, USDC_PRICE_ID, 300);

// Execute swap
SwapRequest memory request = SwapRequest({
tokenIn: WETH,
tokenOut: USDC,
amountIn: 1e18,
minAmountOut: 1900e6,
recipient: msg.sender,
deadline: block.timestamp + 3600,
tokenInPriceId: ETH_PRICE_ID,
tokenOutPriceId: USDC_PRICE_ID,
maxGasPrice: 50 gwei,
forceLocal: false
// Create a Uniswap V4 pool with the hook
PoolKey memory poolKey = PoolKey({
currency0: Currency.wrap(WETH),
currency1: Currency.wrap(USDC),
fee: 3000,
tickSpacing: 60,
hooks: IHooks(address(hook))
});

bytes32 swapId = hook.executeSwap(request);
poolManager.initialize(poolKey, sqrtPriceX96);

// Users can now swap through the pool, and the hook will automatically
// analyze cross-chain opportunities and route to the best venue
```

## Events
Expand Down Expand Up @@ -242,15 +249,24 @@ The project includes basic tests in `test/Counter.t.sol`. Additional tests shoul

### Deployment
```bash
# Deploy to testnet
forge script script/Counter.s.sol --rpc-url <RPC_URL> --broadcast
# Set environment variables
export PRIVATE_KEY="your_private_key"
export POOL_MANAGER="0x..."
export PYTH_ORACLE="0x..."
export BRIDGE_PROTOCOL="0x..."
export FEE_RECIPIENT="0x..."

# Deploy the hook
forge script script/DeployCrossChainHook.s.sol --rpc-url <RPC_URL> --broadcast

# Verify on block explorer
forge verify-contract <CONTRACT_ADDRESS> src/CrossChainSwapHook.sol:CrossChainSwapHook --chain-id <CHAIN_ID>
```

## Dependencies

- Uniswap V4 Core (`v4-core`)
- Uniswap V4 Periphery (`v4-periphery`)
- OpenZeppelin Contracts v5.4.0
- Foundry (forge, cast, anvil)
- Solidity ^0.8.24
Expand Down
3 changes: 3 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
src = "src"
out = "out"
libs = ["lib"]
via_ir = true
optimizer = true
optimizer_runs = 200
remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"v4-core/=lib/v4-core/src/",
Expand Down
42 changes: 42 additions & 0 deletions script/DeployCrossChainHook.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {CrossChainSwapHook} from "../src/CrossChainSwapHook.sol";
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";

contract DeployCrossChainHook is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address poolManager = vm.envAddress("POOL_MANAGER");
address pythOracle = vm.envAddress("PYTH_ORACLE");
address bridgeProtocol = vm.envAddress("BRIDGE_PROTOCOL");
address feeRecipient = vm.envAddress("FEE_RECIPIENT");

vm.startBroadcast(deployerPrivateKey);

CrossChainSwapHook hook = new CrossChainSwapHook(
IPoolManager(poolManager),
pythOracle,
bridgeProtocol,
feeRecipient
);

console.log("CrossChainSwapHook deployed at:", address(hook));
console.log("Hook permissions:", _getHookPermissionsString(hook.getHookPermissions()));

vm.stopBroadcast();
}

function _getHookPermissionsString(Hooks.Permissions memory permissions)
internal
pure
returns (string memory)
{
return string(abi.encodePacked(
"beforeSwap: ", permissions.beforeSwap ? "true" : "false", ", ",
"afterSwap: ", permissions.afterSwap ? "true" : "false"
));
}
}
Loading
Loading