Inbox Contract
An overview of the Inbox contract, responsible for managing intent fulfillment, preventing double fills, and filler whitelisting (for the Alpha).
Each destination chain supported by the Eco Protocol has one Inbox
contract.
Inbox Contract Design
The Inbox
contract contains four primary functions:
-
fulfillStorage
— this function is used to fulfill requests that specified the Native Path (which uses storage proofs) during intent origination. -
fulfillHyperInstant
— this function is used to fulfill requests that specified the Hyperprover Path during intent origination. It immediately dispatches a Hyperlane message to prove the intent fufillment on the Origin chain. -
fulfillHyperBatched
— this function is used to fulfill requests that specified the Hyperprover Path during intent origination. Instead of immediately dispatching, it allows intents to be queued in a batch message sent through Hyperlane later. -
sendBatch
— this function is used to send a batch of intents through Hyperlane that opted for thefulfillHyperBatched
option when filling an intent.
All code snippets in this section reference this specific commit.
Intent Fulfillment
Intent fulfillment is managed through the internal function _fulfill
function on the Inbox
contract. All 3 of the fulfilling methods enter this internal function, so it’s best to explain it first. The function accepts as input the:
-
Source Chain
-
Array of Contracts to Call
-
Array of Calldata for those Functions
-
Expiration Time
-
Nonce
-
Claimant for Reward
-
Expected Hash
After running a few sanity checks (like making sure the intent has already been fulfilled), the contract takes the inputs, and calls the downstream functions requested by the intent. If any of the calls are unsuccessful, the _fulfill
call reverts and the intent remains unfulfilled. If all the calls are successful, the intent is marked as fulfilled and the claimant is designated as the eligible recipient for the rewards.
Intent Fulfillment (fulfillStorage)
This function is used to fulfill requests that specified the Native Path (which uses storage proofs) during intent origination. It wraps _fulfill
and then emits an event.
Intent Fulfillment (fulfillHyperInstant)
This function is used to fulfill requests that specified the Hyperprover Path during intent origination. It immediately dispatches a Hyperlane message to prove the intent fulfillment on the Origin chain.
Intent Fulfillment (fulfillHyperBatched)
This function is used to fulfill requests that specified the Hyperprover Path during intent origination. Instead of immediately dispatching, it allows intents to be queued in a batch message sent through Hyperlane later.
The sendBatch
function takes a list of intent IDs, and relays them to a specific source chain via a batched Hyperlane message.
Design Discussion
Fulfill Parameters
The _fulfill
function requires the filler to specify many parameters as part of intent fulfillment.
-
Source Chain — This specifies the ID of the origin chain where the the requested intent was submitted to the
IntentSource
contract. -
Array of Contracts to Call — This specifies the list of contracts that the filler is calling on the destination chain.
-
Array of Calldata for those Functions — This specifies the list of corresponding function signatures and calldata that pair with the contracts to call.
-
Expiration Time — This specifies the expiration blocktime after which the intent will be considered expired. If the intent fulfillment is not proven by this time, the intent originator can claw back their funds. This expiration time must be appropriately set to the proving method chosen by the intent creator.
-
Nonce — This represents the unique nonce generated in the
IntentSource
contract as part of intent origination. -
Claimant for Reward — This specifies the eligible claimant for the rewards on the source chain.
-
Expected Hash — This specifies the expected hash the filler anticipated, to protect the filler in case there is some issue during construction of the
_fulfill
transaction.
Hash Reference and Filler Race Conditions
As mentioned in the Intent Contract Design, the hash is used on all contracts in the system as a reference and to enforce uniqueness. In the Inbox
contract, the hash is also used to prevent a given hash from being fulfilled more than once.
If a filler tries to solve an intent after another filler has successfully solved it, then the intent will revert with an IntentAlreadyFulfilled
error. This prevents filler from accidentally solving intents twice.
This does create a race condition if two fillers submit transactions at the same time trying to solve the same intent. Future versions of the protocol will intend to deal with this for chains where conditional execution cannot be achieved through the use of bundlers (see Future Directions on the IntentSource
contract page).
Contract Call Execution
Intent creators will need to be careful when creating intents for contracts that may not produce deterministic outcomes. Some contracts may successfully complete calls without obtaining the desired outcome that intent creators wanted.
Likewise, fillers will need to be careful not to fill intents that contain function calls. If not careful, they could be quickly drained of funds.
Future Directions
Future versions of the Eco Protocol will introduce significant flexibility around the filler fufillment process. Below are some possible future improvements relevant to the Inbox
contract, which are also discussed in more detail in Future Directions.
- Delegate Calls / Helper Contracts — In the Beta release, the system is dependent on fillers prefilling the Inbox contract for stablecoin transfers via multicalls. This is a more secure way to deal with arbitrary call execution, but DelegateCall and helper contracts will be added in the Mainnet launch to support more gas efficient execution.