EcoCross+ Integration
Product Description
EcoCross+ is a bridge abstraction framework. A developer can use EcoCross+ in their dApp to bundle bridging and protocol actions in the same transaction, abstracting it away from the user. This can be used to promote user onboarding and defragment user liquidity ecocross chains.
Instead of users independently bridging assets to chains to use applications, EcoCross+ enables your application to meet the user where they already are.
At a high level, EcoCross+ works through the following process:
End-user (or intermediate contract) includes a message field in the deposit transaction.
To be repaid for the fill, the relayer is required to include the same message field in their fill.
When this message field is non-empty and the recipient is a contract, the
SpokePool
calls a special handler function on the recipient contract with the message (and a few other fields).This function can do anything, meaning application-specific actions can be executed atomically.At
Integrating EcoCross+ into Your Application
This guide contains instructions and examples for calling the smart contract functions and constructing the message
and creating the destination handler contract.
If you have further questions or suggestions for this guide, please send a message to the #developer-questions
channel in the EcoCross Telegram.
Creating an EcoCross+ Transaction
In this example we'll be walking through how to use EcoCross+ to perform an AAVE deposit on behalf of the user on the destination chain.
Crafting the Message
EcoCross+ requires that you send some nonempty message to your contract on the other side. This message allows you to pass arbitrary information to your recipient contract and it ensures that EcoCross understands that you intend to trigger the handler function on the recipient (instead of just transferring tokens). A message is required if you want the handler to be called.
In this example, our message will be just the user's address since that's all our contract would need to know to generate an AAVE deposit. Here's an example for generating this in typescript:
Copy
Example in solidity:
Copy
Generating the Deposit
The deposit creation process is nearly identical to the process described for initiating a deposit (Initiating a Deposit (User Intent)). However, there are two tweaks to that process to include a message.
When getting a quote (Getting a Quote), two additional query parameters need to be added.
recipient: the recipient for the deposit. For EcoCross+ transactions, this is not the end-user. It is the contract that implements the handler you would like to call (more on that later). Usually, this is a contract you have created to decode and handle the message.
message: the message you crafted above.
When calling deposit (Calling depositV3), you'll need to make a slight tweak to the parameters.
The recipient should be set to your handler contract.
The message field should be set to the message you generated above instead of
0x
.
Building a Handler Contract
You will need to implement a function matching the following interface in your handler contract to receive the message:
Copy
For this example, we're depositing the funds the user sent into AAVE on the user's behalf. Here's how that full contract implementation might look. Note: this contract has not been vetted whatsoever, so use this sample code at your own risk.
Copy
One note on this implementation: this contract only uses the funds that are sent to it. That means that the message is assumed to only have authority over those funds and no outside funds. This is important because relayers can send invalid relays. They will not be repaid the funds sent in, but if an invalid message could unlock other funds, then a relayer could use this maliciously.
You can find this interface definition in the codebase here.
Conclusion
Now that you have a process for constructing a message, creating a deposit transaction, and you have a handler contract built and deployed on the destination chain, all you need to do is send the deposit to have the handler get executed on the destination.
WrapChoice Example
Here's another contract example using a slightly different message format to allow users to choose whether they want to receive WETH or ETH. In this example, a bool
is passed along with the address of the user to allow the message to define the unwrapping behavior on the destination.
Copy
Summarized Requirements
The deposit
message
is not emptyThe
recipient
address is a contract on thedestinationChainId
that implements a publichandleV3
EcoCrossMessage(address,uint256,address,bytes)
function. See Reverting Transactions for considerations.Construct your
message
Use the EcoCross API to get an estimate of the
relayerFeePct
you should set for your message and recipient combinationCall
depositV3()
passing in your messageOnce the relayer calls
fillV3Relay()
on the destination, your recipient'shandle
EcoCrossMessage
will be executedThe additional gas cost to execute the above function is compensated for in the deposit's
relayerFeePct
.
Security & Safety Considerations
It is recommended that recipient contracts require that
handleV3
EcoCrossMessage()
is only callable by the EcoCross SpokePool contract on the same chain.Avoid making unvalidated assumptions about the
message
data supplied tohandleV3
EcoCrossMessage()
. EcoCross+ does not guarantee message integrity, only that a relayer who spoofs a message will not be repaid by EcoCross. If integrity is required, integrators should consider including a depositor signature in the message for additional verification. Message data should otherwise be treated as spoofable and untrusted for use beyond directing the funds passed along with it.Avoid embedding assumptions about the transfer token or transfer amount into their messages. Instead use the
tokenSent
andamount
variables supplied with to thehandleV3
EcoCrossMessage()
function. These fields are enforced by the SpokePool contract and so can be assumed to be correct by the recipient contract.In the event that a deposit expires, it will be refunded to the depositor address. Ensure that the depositor address on the origin SpokePool is capable of receiving refunds.
The relayer(s) able to complete a fill can be restricted by storing an approved set of addresses in a mapping and validating the
handleV3
EcoCrossMessage()
relayer
parameter. This implies a trust relationship with one or more relayers.
Reverting Transactions
If the
message
specifies a transaction that could revert when handled on the destination, the user will be refunded on the origin chain in the bundle following the expiry of the deposit.Note: Expiry occurs when the destination SpokePool timestamp exceeds the deposit fillDeadline timestamp.
If this is not desirable behavior it is recommended to include logic in the handler contract to simply transfer the funds to the user in the case of a reverting transaction.
Last updated