Function: callOutSigned(bytes _params, GasParams _gParams)
This transfers a cross-chain message using the LayerZero protocol. This allows a user to invoke their VirtualAccount contract on the Root chain. Importantly, this message does not allow to make a deposit. The message will be processed by the lzReceiveNonBlocking function of the RootBridgeAgent contract upon delivery to the Root chain. Subsequently, the user's _params will be forwarded to the executeSigned function of the rootRouter contract. The processing of _params varies based on the implementation of the rootRouter contract. The MulticallRootRouter contract enables the user to execute one of three actions:
Invoke the
callfunction of the VirtualAccount contract.Invoke the
callfunction, withdraw assets from the Virtual Account contract, and bridge out the withdrawn assets.Invoke the
callfunction, withdraw a batch of token assets, and bridge them out.
Inputs
_paramsControl: Full control by the caller.
Constraints: There are no constraints.
Impact: Contains the data that will be processed in the RootRouter contract on the Root chain. In the case of
MulticallRootRouter, the first byte should be the ID of the function (0x01, 0x02, 0x03; in other cases,_executeSignedwill revert). The rest of the data depends on the type of function.
_gParamsControl: Full control by the caller.
Constraints: There are no constraints.
Impact: These values are used to encode
AdapterParametersdata for the LayerZero relayer contract.
Branches and code coverage
No tests have been implemented for this function.
Intended branches
Check if the branch has test coverage.
Negative behavior
The incorrect
_gParamsdata.
Function call analysis
this._performCall(address payable(msg.sender), payload, _gParams, BridgeAgentConstants.BRANCH_BASE_CALL_OUT_SIGNED_GAS) -> ILayerZeroEndpoint(lzEndpointAddress).send{value: msg.value}What is controllable? The
_payloadis partially controlled,_paramsis fully controlled by the caller, andmsg.valueis used as a fee for cross-chain transferring.If the return value is controllable, how is it used and how can it go wrong? There is no return value.
What happens if it reverts, reenters or does other unusual control flow? The
callOutSignedfunction has alockto prevent reentrancy attacks. The function can revert if the caller does not provide sufficient fee payment.
this._performCall(address payable(msg.sender), payload, _gParams, BridgeAgentConstants.BRANCH_BASE_CALL_OUT_SIGNED_GAS) -> IRootBridgeAgent(this.rootBridgeAgentAddress).lzReceive{value: msg.value}What is controllable? The
_payloadis partly controlled by the initial caller in srcChain.If the return value is controllable, how is it used and how can it go wrong? There is no return value.
What happens if it reverts, reenters or does other unusual control flow? This function call is a part of the cross-chain--message transferring process, but it will be executed in a different transaction and on a different chain than the original call. Since all the logic for message processing is executed within the
excessivelySafeCallfunction, in case of a revert, the message will not be saved for resending and all native tokens from this contract will be transferred to the rootPortAddress contract. But if either transfers revert, the message will be saved for resending. However, it will also be possible to skip this message using theforceResumeReceivefunction.