# 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)