# Genius Router

The GeniusRouter is a contract that simplifies the process of creating cross-chain orders in the Genius bridge protocol. It provides convenient functions for users to swap tokens and create bridge orders in a single transaction, with optional Permit2 integration for gasless approvals and enhanced user experience.

The router acts as a bridge between users and the core vault functionality, handling token transfers, swaps, and order creation in a streamlined manner. It supports both traditional token approvals and gasless Permit2 transactions, making it accessible to a wide range of users and wallet types.

### The GeniusRouter contract - overview

The GeniusRouter contract is an immutable contract that serves as the primary user interface for the Genius bridge protocol. It integrates with the vault, proxy call, fee collector, and Permit2 contracts to provide a seamless experience for creating cross-chain orders.

The contract handles the complexity of token management, fee calculation, and order creation, allowing users to focus on their desired cross-chain operations rather than the underlying technical details.

### The GeniusRouter contract - key features

#### **Integrated swap and order creation**

The router allows users to swap tokens and create cross-chain orders in a single transaction, eliminating the need for multiple separate transactions and reducing gas costs.

#### **Permit2 integration**

Supports gasless token approvals through Uniswap's Permit2 system, enabling users to create orders without requiring pre-approved token allowances.

#### **Flexible token input**

Supports multiple input tokens in a single transaction, allowing users to swap various tokens for stablecoins before creating bridge orders.

#### **Automatic fee calculation**

Integrates with the fee collector to automatically calculate and include the appropriate fees for cross-chain orders based on destination chain and order size.

#### **Proxy call integration**

Leverages the GeniusProxyCall contract for executing complex swap operations and ensuring secure token transfers.

#### **Immutable architecture**

Uses immutable state variables for critical contract addresses, ensuring security and preventing unauthorized modifications.

#### **User-friendly interface**

Provides simple, intuitive functions that abstract away the complexity of the underlying protocol while maintaining full functionality.

#### **Comprehensive error handling**

Implements detailed error messages and validation to help users understand and resolve any issues with their transactions.

### Understanding the workflow of GeniusRouter

1. **Token Input**: Users provide input tokens either through direct transfers or Permit2 permits.
2. **Token Swapping**: The router executes swaps using the proxy call contract to convert input tokens to stablecoins.
3. **Fee Calculation**: The fee collector calculates the appropriate fees for the destination chain and order size.
4. **Order Creation**: The router creates a cross-chain order with the vault using the swapped stablecoins.
5. **Order Execution**: The order is then executed by orchestrators on the destination chain.

### Core functions and their purposes

#### **Swap and Create Order**

{% code title="GeniusRouter.sol" %}

```solidity
function swapAndCreateOrder(
    bytes32 seed,
    address[] calldata tokensIn,
    uint256[] calldata amountsIn,
    address target,
    address toApprove,
    bytes calldata data,
    address owner,
    uint256 destChainId,
    uint256 feeSurplus,
    bytes32 receiver,
    uint256 minAmountOut,
    bytes32 tokenOut
) public payable override {
    if (tokensIn.length != amountsIn.length)
        revert GeniusErrors.ArrayLengthsMismatch();

    // Transfer input tokens to proxy call
    for (uint256 i = 0; i < tokensIn.length; i++) {
        if (msg.sender != address(PROXYCALL)) {
            IERC20(tokensIn[i]).safeTransferFrom(
                msg.sender,
                address(PROXYCALL),
                amountsIn[i]
            );
        }
    }

    // Execute swap operation
    if (target == address(PROXYCALL))
        PROXYCALL.execute{value: msg.value}(target, data);
    else
        PROXYCALL.approveAddressAndExecute{value: msg.value}(
            tokensIn,
            target,
            data,
            toApprove
        );

    uint256 delta = STABLECOIN.balanceOf(address(this));

    // Calculate fees
    IFeeCollector.FeeBreakdown memory feeBreakdown = FEE_COLLECTOR
        .getOrderFees(delta, destChainId);

    // Create order
    IGeniusVault.Order memory order = IGeniusVault.Order({
        seed: seed,
        trader: VAULT.addressToBytes32(owner),
        receiver: receiver,
        tokenIn: VAULT.addressToBytes32(address(STABLECOIN)),
        tokenOut: tokenOut,
        amountIn: delta,
        minAmountOut: minAmountOut,
        destChainId: destChainId,
        srcChainId: block.chainid,
        fee: feeBreakdown.totalFee + feeSurplus
    });

    VAULT.createOrder(order);
}
```

{% endcode %}

#### **Permit2 Swap and Create Order**

{% code title="GeniusRouter.sol" %}

```solidity
function swapAndCreateOrderPermit2(
    bytes32 seed,
    IAllowanceTransfer.PermitBatch calldata permitBatch,
    bytes calldata permitSignature,
    address target,
    address toApprove,
    bytes calldata data,
    uint256 destChainId,
    uint256 feeSurplus,
    bytes32 receiver,
    uint256 minAmountOut,
    bytes32 tokenOut
) public payable override {
    address owner = msg.sender;

    // Handle Permit2 token transfers
    address[] memory tokensIn = _permitAndBatchTransfer(
        permitBatch,
        permitSignature,
        owner
    );

    // Execute swap operation
    if (target == address(PROXYCALL))
        PROXYCALL.execute{value: msg.value}(target, data);
    else
        PROXYCALL.approveAddressAndExecute{value: msg.value}(
            tokensIn,
            target,
            data,
            toApprove
        );

    uint256 delta = STABLECOIN.balanceOf(address(this));

    // Calculate fees and create order
    IFeeCollector.FeeBreakdown memory feeBreakdown = FEE_COLLECTOR
        .getOrderFees(delta, destChainId);

    IGeniusVault.Order memory order = IGeniusVault.Order({
        seed: seed,
        trader: VAULT.addressToBytes32(owner),
        receiver: receiver,
        tokenIn: VAULT.addressToBytes32(address(STABLECOIN)),
        tokenOut: tokenOut,
        amountIn: delta,
        minAmountOut: minAmountOut,
        destChainId: destChainId,
        srcChainId: block.chainid,
        fee: feeBreakdown.totalFee + feeSurplus
    });

    VAULT.createOrder(order);
}
```

{% endcode %}

#### **Permit2 Order Creation**

{% code title="GeniusRouter.sol" %}

```solidity
function createOrderPermit2(
    bytes32 seed,
    IAllowanceTransfer.PermitBatch calldata permitBatch,
    bytes calldata permitSignature,
    uint256 destChainId,
    uint256 fee,
    bytes32 receiver,
    uint256 minAmountOut,
    bytes32 tokenOut
) external payable override {
    address owner = msg.sender;
    if (permitBatch.details.length != 0)
        revert GeniusErrors.ArrayLengthsMismatch();
    if (permitBatch.details[0].token != address(STABLECOIN))
        revert GeniusErrors.InvalidTokenIn();

    // Transfer stablecoins using Permit2
    _permitAndBatchTransfer(permitBatch, permitSignature, owner);

    uint256 delta = STABLECOIN.balanceOf(address(this));

    // Create order directly with stablecoins
    IGeniusVault.Order memory order = IGeniusVault.Order({
        seed: seed,
        trader: VAULT.addressToBytes32(owner),
        receiver: receiver,
        tokenIn: VAULT.addressToBytes32(address(STABLECOIN)),
        tokenOut: tokenOut,
        amountIn: delta,
        minAmountOut: minAmountOut,
        destChainId: destChainId,
        srcChainId: block.chainid,
        fee: fee
    });

    VAULT.createOrder(order);
}
```

{% endcode %}

#### **Permit2 Token Transfer Helper**

{% code title="GeniusRouter.sol" %}

```solidity
function _permitAndBatchTransfer(
    IAllowanceTransfer.PermitBatch calldata permitBatch,
    bytes calldata permitSignature,
    address owner
) private returns (address[] memory tokensIn) {
    tokensIn = new address[](permitBatch.details.length);
    if (permitBatch.spender != address(this))
        revert GeniusErrors.InvalidSpender();

    // Execute permit
    PERMIT2.permit(owner, permitBatch, permitSignature);

    // Prepare transfer details
    IAllowanceTransfer.AllowanceTransferDetails[]
        memory transferDetails = new IAllowanceTransfer.AllowanceTransferDetails[](
            permitBatch.details.length
        );
    for (uint i; i < permitBatch.details.length; i++) {
        tokensIn[i] = permitBatch.details[i].token;
        transferDetails[i] = IAllowanceTransfer.AllowanceTransferDetails({
            from: owner,
            to: address(PROXYCALL),
            amount: permitBatch.details[i].amount,
            token: permitBatch.details[i].token
        });
    }

    // Execute transfers
    PERMIT2.transferFrom(transferDetails);
}
```

{% endcode %}

### Function types and use cases

#### **Traditional Token Approvals**

* **Function**: `swapAndCreateOrder()`
* **Use case**: Users who prefer traditional token approvals
* **Process**: Direct token transfers followed by swap and order creation

#### **Gasless Permit2 Operations**

* **Function**: `swapAndCreateOrderPermit2()`
* **Use case**: Users wanting gasless token approvals
* **Process**: Permit2 signature validation followed by swap and order creation

#### **Direct Stablecoin Orders**

* **Function**: `createOrderPermit2()`
* **Use case**: Users with stablecoins wanting direct bridge orders
* **Process**: Permit2 stablecoin transfer followed by order creation

### Integration with other contracts

The GeniusRouter integrates with several core contracts in the Genius ecosystem:

* **GeniusVault**: Creates cross-chain orders
* **GeniusProxyCall**: Executes swap operations
* **FeeCollector**: Calculates order fees
* **Permit2**: Handles gasless token approvals
* **Stablecoin**: The underlying stablecoin for bridge operations

### Key state variables

* `STABLECOIN`: The stablecoin token used for bridge operations
* `VAULT`: The GeniusVault contract for order creation
* `PERMIT2`: The Permit2 contract for gasless approvals
* `PROXYCALL`: The GeniusProxyCall contract for swap execution
* `FEE_COLLECTOR`: The FeeCollector contract for fee calculation

### Security features

#### **Immutable Architecture**

All critical contract addresses are immutable, preventing unauthorized modifications and ensuring contract integrity.

#### **Input Validation**

Comprehensive validation of input parameters including:

* Array length matching
* Valid token addresses
* Proper spender addresses
* Sufficient token amounts

#### **Safe Token Transfers**

All token transfers use SafeERC20 to prevent common token-related vulnerabilities.

#### **Permit2 Security**

Proper validation of Permit2 signatures and spender addresses to prevent unauthorized token transfers.

#### **Native Token Protection**

The contract rejects direct native token transfers to prevent accidental fund loss.

### User experience features

#### **Single Transaction Operations**

Users can swap tokens and create bridge orders in a single transaction, reducing gas costs and improving convenience.

#### **Gasless Approvals**

Permit2 integration allows users to create orders without requiring pre-approved token allowances, saving gas and improving user experience.

#### **Flexible Token Support**

Supports multiple input tokens, allowing users to bridge various assets by first converting them to stablecoins.

#### **Automatic Fee Handling**

Fees are automatically calculated and included, eliminating the need for users to manually determine appropriate fee amounts.

#### **Clear Error Messages**

Comprehensive error handling provides clear feedback when transactions fail, helping users understand and resolve issues.

### Order creation process

#### **Step 1: Token Input**

* Users provide input tokens through direct transfers or Permit2 permits
* Multiple tokens can be provided in a single transaction

#### **Step 2: Token Swapping**

* Input tokens are transferred to the proxy call contract
* Swaps are executed to convert tokens to stablecoins
* Swap operations can target any DEX or DeFi protocol

#### **Step 3: Fee Calculation**

* The fee collector calculates appropriate fees based on:
  * Destination chain
  * Order amount
  * Current fee tiers

#### **Step 4: Order Creation**

* A cross-chain order is created with the vault
* Order includes all necessary parameters for execution
* Order is queued for processing by orchestrators

### Error handling and validation

#### **Input Validation**

* Array lengths must match
* Token addresses must be valid
* Spender addresses must be correct
* Permit signatures must be valid

#### **Operation Validation**

* Token transfers must succeed
* Swap operations must complete
* Fee calculations must be valid
* Order creation must succeed

#### **Security Checks**

* Native tokens are rejected
* Unauthorized spenders are blocked
* Invalid permits are rejected

The GeniusRouter is a critical user-facing component of the Genius bridge protocol, providing a simple and efficient interface for creating cross-chain orders. Its integration with Permit2, support for complex swaps, and automatic fee handling make it accessible to users of all technical levels while maintaining the security and functionality of the underlying protocol.
