# SKALE Network Bridging & Token Flows
## Background
[SKALE](https://skale.space) is a multi-chain EVM network offering
zero gas fees at the chain level. Due to the multi-chain setup, the
token mappings and setup was designed very specifically to help
avoid liquidity fragmentation and make it easier for users to move throughout
the ecosystem.
The below goes through the flow of tokens and explores how to actually bridge a token back and forth and the steps in between.
## Table of Contents
| Section | Link |
| - | - |
| Token Setup | [Link](#Token-Setup) |
| Docs & Resources | [Link](#Documentation-amp-Resources) |
| Contracts | [Link](#Contracts) |
| Flows | [Link](#SKALE-Chain--gt-SKALE-Chain-with-a-Swap) |
### Token Setup
L1 <--> Europa <--> Wrapped Europa <--> Nebula
The majority of tokens on SKALE are designed with the above flow in mind.
Their is a core token that exists on Ethereum Mainnet, from there, that
token is mapped through the SKALE Native IMA Bridge to the Europa DeFi & Liquidity Hub. From there, due to a key protection in IMA that disables the
clone token (e.g the one on Europa mapped over from Mainnet) to be mapped to
another SKALE Chain; from there tokens are then "Wrapped" to resolve this IMA
block and from their mapped again to another SKALE Chain (e.g. Nebula).
### Documentation & Resources
1. [SKALE S2S Transfer](https://docs.skale.network/ima/1.4.x/s2s-transferring-erc20)
2. [Metaport](https://github.com/skalenetwork/metaport)
- [ERC-20 Actions](https://github.com/skalenetwork/metaport/blob/develop/src/core/actions/erc20.ts)
4. [Portal](https://github.com/skalenetwork/portal)
### Contracts
| Contract Name | Address |
| - | - |
| TokenManagerERC20 | 0xD2aAA00500000000000000000000000000000000 |
#### Mainnet (Ethereum)
**Explorers**
| Chain | Link |
| - | - |
|Ethereum Mainnet | https://etherscan.io |
| Calypso | https://honorable-steel-rasalhague.explorer.mainnet.skalenodes.com |
| Europa | https://elated-tan-skat.explorer.mainnet.skalenodes.com |
| Nebula | https://green-giddy-denebola.explorer.mainnet.skalenodes.com |
**Contracts**
| Contract Name | Chain | Address |
| - | - | - |
| RubyRouter | Europa Mainnet | 0x2fa290dcb232b04d2f97f4d4ad45396b62193d51 |
| DepositBoxERC20 | Ethereum Mainnet | 0x8fB1A35bB6fB9c47Fb5065BE5062cB8dC1687669
| DepostiBoxEth | Ethereum Mainnet | 0x49F583d263e4Ef938b9E09772D3394c71605Df94
**Tokens**
| Token Name | Ethereum | Europa | Europa Wrapped | Nebula | Calypso |
| - | - | - | - | - | - |
| USDC |0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 | 0x5F795bb52dAC3085f578f4877D450e2929D2F13d | 0x1c566a47e1baC535Ca616373146e3BE024F88Aa4 | 0xCC205196288B7A26f6D43bBD68AaA98dde97276d | 0x7Cf76E740Cb23b99337b21F392F22c47Ad910c67 | <!-- End USDC -->
| SKL | 0x00c83aecc790e8a4453e5dd3b0b4b3680501a7a7 | 0xE0595a049d02b7674572b0d59cd4880Db60EDC50 | 0xD162bB5c75FE99144295b03510bAb2DF99617440 | 0x7F73B66d4e6e67bCdeaF277b9962addcDabBFC4d | 0x4048C4dd6eccF1Dc23b068211fDf20AD19602e50 |<!-- End SKL -->
| USDT | 0xdac17f958d2ee523a2206206994597c13d831ec7 | 0x1c0491E3396AD6a35f061c62387a95d7218FC515 | 0x42dDeBDa2195FaEDAEC1cf24c19B42da1c881feB | 0x932427E1f1Ea096e2bb05C7dE937d083ddb8Ff83 | 0xf9B5736E74b37Ec2EDd37B1B3c8e1aF9fa426F2A | <!-- End USDT -->
#### Testnet (Ethereum Holesky)
WIP
### Flows
#### Mainnet -> SKALE Chain (ERC-20)
This flow would be used when a user is onramping to SKALE and bridging from
Ethereum Mainnet to Europa with a supported ERC-20 token (USDC, USDT, SKL, WBTC, DAI).
**Variables**
| Name | Description |
| - | - |
| mUSDC | The token being transfered |
| eUSDC | The token being transfered |
| X | Amount of USDC on ETH Mainnet being transferred |
| Y | Amount of USDC on Europa being transferred |
**On ETH Mainnet**
1. Call approve on mUSDC for DepositBoxERC20
2. call depositERC20 on DepositBoxERC20
- Chain Name: elated-tan-skat (Mainnet) | juicy-low-small-testnet (testnet)
- Result -> mUSDC locked on Mainnet
** On Europa**
3. TokenManagerERC20 on Europa *mints* eUSDC on Europa
#### Mainnet -> SKALE Chain (ETH)
This flow would be used when a user is onramping to SKALE and bridging from
Ethereum Mainnet to Europa with their native ETH.
**Variables**
| Name | Description |
| - | - |
| ETH | The token being transfered |
| ETHC | The token being transfered |
| X | Amount of ETH being transferred |
| Y | Amount of ETHC being transferred |
**On ETH Mainnet**
1. call deposit on DepositBoxETH
- Chain Name: elated-tan-skat (Mainnet) | juicy-low-small-testnet (testnet)
- Result -> eth locked on Mainnet
** On Europa**
2. TokenManagerETH on Europa *mints* ETHC on Europa
#### Mainnet -> SKALE Chain (Europa) -> SKALE Chain
This flow would be used when a user is onramping to SKALE and bridging from
Ethereum Mainnet to Nebula or Calypso through the Europa Hub. The movement through
the Europa Hub is a requirement based on the liquidity hub being used as the primary
entrpoint.
**Variables**
| Name | Description |
| - | - |
| mUSDC | USDC on Eth Mainnet |
| eUSDC | USDC on Europa |
| weUSDC | wUSDC on Europa |
| nUSDC | Europa USDC on Nebula |
| W | Amount of mUSDC on ETH Mainnet being transferred |
| X | Amount of eUSDC on Europa being transferred |
| Y | Amount of weUSDC on Europa being transferred |
| Z | Amount of nUSDC on Nebula being transferred |
**On ETH Mainnet**
1. Call approve on mUSDC for DepositBoxERC20
2. call depositERC20 on DepositBoxERC20
- Chain Name: elated-tan-skat (Mainnet) | juicy-low-small-testnet (testnet)
- Result -> mUSDC locked on Mainnet
** On Europa**
3. TokenManagerERC20 on Europa *mints* X eUSDC on Europa
4. Approve **X eUSDC** on eUSDC Contract
7. Wrap **X eUSDC** to **Y weUSDC**
8. Approve TokenManagerERC20 for **Y weUSDC**
9. Transfer **Y weUSDC** to Nebula (lock on Europa)
**On Nebula**
10. TokenManagerERC20 mints Z nUSDC to User
#### SKALE Chain -> SKALE Chain with a Swap
**Variables**
| Name | Description |
| - | - |
| USDC | The token being transfered |
| W | Amount of USDC being transferred |
| X | Amount of wUSDC being transferred |
| Y | Amount of ETH being transferred |
| Z | Amount of wETHC being transferred |
| E | Amount of Europa ETH on Nebula |
> Note, ETHC is the ERC-20 form of ETH on Europa. This token is mapped
> from native ETH on Ethereum. This is not WETH.
>
**On Nebula**
1. Approve TokenManagerERC20 on Nebula for **W USDC**
2. Transfer **W USDC** using transferERC20 on TokenManagerERC20 to Europa
**On Europa**
3. Unwrap **X wUSDC** on Europa
4. [Approve **X USDC** to allow RubyRouter to Swap **X USDC**](https://elated-tan-skat.explorer.mainnet.skalenodes.com/tx/0x3ab17e4207bef1cf5ae9ac2b082be7caa01022e10c469752d37515174eedb6ab)
5. [Swap on RubyRouter](https://elated-tan-skat.explorer.mainnet.skalenodes.com/tx/0x4ccb39e9e1be49c29c9b2d6dff5d67dc3d2ebc535f57c7526172cafea7ccec46)
6. Approve **Z wETHC** on ETHC Contract
7. Wrap **Y ETHC** to **Z wETHC**
8. Approve TokenManagerERC20 for **Z wETHC**
9. Transfer **Z wETHC** to Nebula (lock on Europa)
**On Nebula**
10. TokenManagerERC20 mints **E Europa ETH** on Nebula
### Functions
1. [Transfer ERC-20 S2S](https://github.com/skalenetwork/IMA/blob/3c667f85abf575c419f825742cce02c852866dee/proxy/contracts/schain/TokenManagers/TokenManagerERC20.sol#L112)
2. [Ruby Swap](https://github.com/RubyExchange/contracts/blob/562e5564a572883cb36352dea3ac51e4e4b8f5a0/contracts/ruby_router/RubyRouter.sol#L68)
3. [Ruby Swap - getAmountsOut](https://github.com/RubyExchange/contracts/blob/562e5564a572883cb36352dea3ac51e4e4b8f5a0/contracts/amm/libraries/UniswapV2Library.sol#L102)
See [Ruby Swap Example](https://hackmd.io/@TheGreatAxios/rk4E8Ozm0)