Symbiosis - Grant Final report


In November 2023, Symbiosis received a 50,000 ARB grant from GMX to expand sustainable growth of GMX GM pools on Arbitrum via Symbiosis cross-chain zaps feauture. In our idea we were planning to return gas refunds in ARB for successful deposits from any chains to GMX GM pools on Arbitrum.

Howewer, due to integration complexity and internal priorities in Symbiosis we were able to start integration in February. Our technical team has encountered several challenges in particular in interacting with GM pools and gas refunds. Here’s our explanation:

GMX executeDeposit call can’t be executed due to slippage or insufficient executionFee then user’s funds are returned to caller’s address.

In our case the caller is a MulticallRouter contract MulticallRouterV2 | Address 0x5ad095de83693ba063941f2f2c5a0df02383b651 | Arbiscan

We expect that funds are returned to user’s address (receiver) as shown in official docs but not to caller.

Example txs:
deposit tx - Arbitrum Transaction Hash (Txhash) Details | Arbiscan
receiver is 0x04fde790d26da69aa9178249ead6863977684e9d

refund tx - Arbitrum Transaction Hash (Txhash) Details | Arbiscan
funs have been returned to another address (caller address, not receiver) 0x5ad095de83693ba063941f2f2c5a0df02383b651.

Funds mustn’t be returned to contract back. Its will be taken (or stolen) by someone else’s whether it is next user zapping to GMX or any other user.

We implemented callbackContract and imitated deposit cancelation.

Here is a tx: Arbitrum Transaction Hash (Txhash) Details | Arbiscan

It works, but we found out that a rest of executionFee transters after afterDepositCancelled callback, therefore we can transfer to user’s address a deposit body only but can’t transfer rest of execution fee.

Of course, amounts not so huge and this doesn’t block using cross-chain ZAPs to GMX but we would like the story to be clear and transparent to user.

That’s why we still waiting for the implementation of possibility to specify refund address (for receiving as deposit body as a rest of execution fee)


We managed to fully finish integration of GM pools on Arbitrum is Symbiosis main app. Users are able to deposit funds from any 25 supported chains and any token in just one click.

Symbiosis completed milestone 1, but it’s not possible to distribute gas refunds in ARB tokens due to technical limitations.

How it works under the hood?

We make a swap to USDC on Arbitrum.

  1. Bridge contract accept tx
  2. Call portal contract (contract that holds protocol funds), portal unlock USDC
  3. Portal sends USDC to MetaRouter. MetaRouter is a contract to execute any third-party calldata in isolated context (not in context of Portal)
  4. Third-party call is a MulticallRouter call that consists of
    — swap some amount of USDC to WETH on some DEX in order to pay for executionFee (we need to make a swap because destination chain doesn’t have any other tokens except USDC)
    — transfer executionFee in WETH to GMX deposit vault
    — transfer rest of USDC to deposit vault
    — call createDeposit function

Feedback on grants committe and GMX Devs

During the entire grant period, we have received support from all related to GMX and grants committe on technical and marketing side. With their help, we were able to finalize the integration and realize that the problem with gas refunds can only be solved on the GMX side.

1 Like