Stargate is a fully composable liquidity transport protocol meaning it supports additional compose logic on destination chain. You can use this feature to perform calls to external smart contracts.
Note: Only Stargate's taxi() method is composable, you cannot perform destination logic with rideBus().
Composable methods
The following methods are composable:
IStargate.sendToken()
IStargate.send()
IStargatePool.redeemSend()
Architecture
Send
To take advantage of compose feature you need to modify SendParam struct passed to IStargate.sendToken().
First, you need to change:
bytescalldata composeMsg
Make sure it is non-zero bytes. You would usually use this field with ABI encode and decode to pass your application-specific input that contracts along the way understand.
You also need to pass additional gas for the compose call. You need to set this value to the amount of gas your lzCompose function in the compose receiver consumes.
For "taxi" you can use typical LayerZero's OptionsBuilder. Make sure to pass it as SendParam.extraOptions:
bytesmemory extraOptions = _composeMsg.length >0? OptionsBuilder.newOptions().addExecutorLzComposeOption(0,200_000,0) // compose gas limit:bytes("");
Receive
Stargate will attempt to call LayerZero's Endpoint.sendCompose() on the destination chain when it distributes tokens to receiver.
and receiver is an address that was supposed to receive tokens on the destination chain.
Stargate is using standard OFTComposeMsgCodec for encoding a composed message. This means that when you receive this message in the composer it will be encoded using the aforementioned codec.
To access your custom application specific message (the one you passed as SendParams.composeMsg) you have to call:
To receive a composed message from Stargate and perform additional logic the receiver address has to be a smart contract implementing ILayerZeroComposer. LayerZero's Endpoint defaults to calling the lzCompose() function on the receiver contract address.
This very simple example above will emit ComposeAcknowledged each time a composed call is received and increment the acknowledgedCount by 1. A more advanced contract example is detailed below.
External contract interaction example
Below you can find a Solidity example of doing a swap through external smart contract with a composed message, using the taxi method.
This example illustrates the process of swapping Token A on the source chain for Token B on the destination chain. Following this, it demonstrates how to swap Token B for Token C on the destination chain by leveraging an external smart contract through a composed call.
As shown above, lzCompose() will attempt to swap token B received from Stargate into token C and transfer it to the receiver address. If the swap fails in the try/catch clause it will send the original token B to the receiver address instead.