---
description: Rango Smart Contracts  Architecture
---

# Architecture

{% hint style="info" %}
The contract code and architecture is discussed briefly to give an overview of the smart contracts. However, the contracts should only be used through Rango's API and  contract details that are not discussed here.
{% endhint %}

{% hint style="info" %}
Rango Smart Contracts Code is open source and available at this Github repository:

[https://github.com/rango-exchange/rango-contracts-v2](https://github.com/rango-exchange/rango-contracts-v2)
{% endhint %}

## Overview

Rango v2 contracts are designed to handle swaps and bridge transactions and also message passing transactions.

There are two main type of contracts:

* `Diamond` : Handles swap and bridge transactions (RangoDiamond.sol)
* `Middlewares` : Receives token and message on destination chain and handles the transaction

RangoDiamond is based on [EIP-2535](https://eips.ethereum.org/EIPS/eip-2535) and [v3 implementation](https://github.com/mudgen/diamond-3). The functionality and support for each bridge is handled by a separate facet. All swapping protocols are handled by a single facet. For example:

* Axelar (Satellite): [RangoSatelliteFacet.sol](https://github.com/rango-exchange/rango-contracts-v2/tree/main/contracts%2Ffacets%2Fbridges%2FRangoSatelliteFacet.sol)
* THORChain: [RangoThorchainFacet.sol](https://github.com/rango-exchange/rango-contracts-v2/tree/main/contracts%2Ffacets%2Fbridges%2Fthorchain%2FRangoThorchainFacet.sol)
* Stargate: [RangoStargateFacet.sol](https://github.com/rango-exchange/rango-contracts-v2/tree/main/contracts%2Ffacets%2Fbridges%2FRangoStargateFacet.sol)
* Stargate Middleware: [RangoStargateMiddleware.sol](https://github.com/rango-exchange/rango-contracts-v2/tree/main/contracts%2Ffacets%2Fbridges%2FRangoStargateMiddleware.sol)
* 1inch, Paraswap, uniswap v2, v3 & forks etc: [RangoSwapperFacet.sol](https://github.com/rango-exchange/rango-contracts-v2/tree/main/contracts%2Ffacets%2Fbase%2FRangoSwapperFacet.sol)

Example scenario: Swap 100 USDT on chain A to DAI on chain B&#x20;

<figure><img src="https://4115966089-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhhhwzAA0vxnX2KRd0I5a%2Fuploads%2FMD9k0Zcsli8Wef77a1LV%2Fcontract%20example%201.png?alt=media&#x26;token=39da8a94-a315-4bc5-8b51-9a1577c4fad2" alt=""><figcaption><p>Swap + Bridge, in one transaction</p></figcaption></figure>

Example scenario: Swap 100 USDT on chain A to BUSD on chain B through a `Middleware` contract&#x20;

<figure><img src="https://4115966089-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhhhwzAA0vxnX2KRd0I5a%2Fuploads%2F11ClQ15t24tzDZo086dY%2Fcontract%20example%202.png?alt=media&#x26;token=597161c8-f9e2-46fb-b3e5-e33fa413a060" alt=""><figcaption><p>Swap + Bridge + Swap, in one transaction</p></figcaption></figure>

Example scenario: Swap 100 USDT on chain A to BUSD on chain B through a `Middleware` contract and call a third-party dApp contract.&#x20;

<figure><img src="https://4115966089-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhhhwzAA0vxnX2KRd0I5a%2Fuploads%2F2nbpBQ6tezgAMCEhjTMQ%2Fcontract%20example%203.png?alt=media&#x26;token=a7e27b8b-b814-404f-9038-8132fc9fcb73" alt=""><figcaption><p>Swap + Bridge + Third-party Contract Call, in one transaction</p></figcaption></figure>

## Bridges Facet Code Structure

Bridge Facets follow a pattern of having two `external` functions which are the main entry points:

* One function for direct bridging:
  * Stargate: `function StargateBridge(...) external`
  * Wormhole: `function wormholeBridge(...) external`
* Another function for swap and bridge:
  * Stargate: `function StargateSwapAndBridge(...) external`
  * Wormhole: `function wormholeSwapAndBridge(...) external`

To handle the interaction with the bridge, each bridge has one or more `internal` functions where the name is like `doBridge`:

* Stargate: `function doStargateSwap(...) internal`
* Symbiosis: `function doSymbiosisBridge(...) internal`

In summary, the contract code architecture looks like this:

```solidity
contract RangoSatelliteFacet {

    // entrypoint external function to swap and then bridge 
    function satelliteSwapAndBridge(
        LibSwapper.SwapRequest memory request,
        LibSwapper.Call[] calldata calls,
        IRangoSatellite.SatelliteBridgeRequest memory bridgeRequest
    ) external {
        ...
        LibSwapper.onChainSwapsPreBridge(...) // swapping 
        ...
        doSatelliteBridge(...); // interact with the bridge 
    }

    // entrypoint external function to bridge
    function satelliteBridge(
        SatelliteBridgeRequest memory request,
        RangoBridgeRequest memory bridgeRequest
    ) external {
        ...
        doSatelliteBridge(request, token, amount);// interact with the bridge 
    }

    // internal function where interaction logic with the bridge happens
    function doSatelliteBridge(
        SatelliteBridgeRequest memory request,
        address token,
        uint256 amount
    ) internal {
        ...
        // interact with bridge
        IAxelarGateway(s.gatewayAddress).callContractWithToken(
        request.toChain,
        request.receiver,
        payload,
    request.symbol,
    amount);
    }
}
```

## Swap Code Structure

The swap functionality for each bridge is very similar and the core implementation is handled by LibSwapper.sol and RangoSwapperFacet.sol

To handle swap logic, we use two structs `SwapRequest` and `Call`. A swap transaction has one `SwapRequest` and one or more swap `Call`:

The `SwapRequest` defines which tokens is to be swapped and which token should be received and some helper data:

```solidity
struct SwapRequest {
    address requestId;
    address fromToken;
    address toToken;
    uint amountIn;
    uint platformFee;
    uint destinationExecutorFee;
    uint affiliateFee;
    address payable affiliatorAddress;
    uint minimumAmountExpected;
    bool feeFromInputToken;
    uint16 dAppTag;
    string dAppName;
}
```

The `Call` defines the contract that should be given approval (`spender`) and the contract to be called (`target`) and the calldata to be sent to target contract (`callData`). Note that `Call` also defines swapFromToken and swapToToken which might be different from `SwapRequest`. This is because a swap can have multiple `Call`s and the `SwapRequest` needs to know initial and final token, but each `Call` might have its own tokens.

```solidity
struct Call {
    address spender;
    address payable target;
    address swapFromToken;
    address swapToToken;
    bool needsTransferFromUser;
    uint amount;
    bytes callData;
}
```

An example of helper function that uses `SwapRequest` and `Call`s in bridges is provided here:

```solidity
function onChainSwapsPreBridge(
    SwapRequest memory request,
    Call[] calldata calls,
    uint extraFee
) internal;
```

## Interchain Messages Code Structure

In the case of sending a message across chains, we use a standard struct called `RangoInterChainMessage`. This object is used when a swap or contract call is needed on the destination chain. The message is received in the destination chain and is handled by the `Middleware` Contract specific to that bridge.

```solidity
struct RangoInterChainMessage {
    address requestId;
    uint64 dstChainId;
    address bridgeRealOutput;
    address toToken;
    address originalSender;
    address recipient;
    ActionType actionType;
    bytes action;
    CallSubActionType postAction;
    uint16 dAppTag;

    // Extra message
    bytes dAppMessage;
    address dAppSourceContract;
    address dAppDestContract;
}
```

## Middleware Contracts Code Structure

Each bridge has its own messaging model if it supports message passing. Therefore, there is no standard or pattern for interchain message calls for different bridges. But to keep the code clean, we have defined a parent contract([`RangoBaseInterchainMiddleware.sol`](https://github.com/rango-exchange/rango-contracts-v2/blob/main/contracts/facets/base/RangoBaseInterchainMiddleware.sol)) which all middlewares can inherit from in order to have functionalities such as whitelists and refunding.
