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
call
function of the VirtualAccount contract.Invoke the
call
function, withdraw assets from the Virtual Account contract, and bridge out the withdrawn assets.Invoke the
call
function, withdraw a batch of token assets, and bridge them out.
Inputs
_params
Control: 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,_executeSigned
will revert). The rest of the data depends on the type of function.
_gParams
Control: Full control by the caller.
Constraints: There are no constraints.
Impact: These values are used to encode
AdapterParameters
data 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
_gParams
data.
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
_payload
is partially controlled,_params
is fully controlled by the caller, andmsg.value
is 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
callOutSigned
function has alock
to 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
_payload
is 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
excessivelySafeCall
function, 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 theforceResumeReceive
function.