Assessment reports>Maia DAO Ulysses Protocol>Threat Model>retrieveDeposit

Function: retrieveDeposit(uint32 _depositNonce, GasParams _gParams)

The function sends a cross-chain request to set the status of a deposit to STATUS_FAILED if the deposit was not successfully executed on the Root chain. To initiate this, several conditions must be met: the deposit associated with _depositNonce must exist, the caller must be the owner of this deposit, and the deposit's status should not already be STATUS_FAILED.

Inputs

  • _depositNonce

    • Control: Fully controlled by the caller.

    • Constraints: The caller must be the owner of the deposit related to this _depositNonce.

    • Impact: The status of this deposit will be changed to STATUS_FAILED if the deposit action was not successfully executed on the Root chain. Subsequently, the owner of the deposit will be able to redeem these deposited funds.

  • _gParams

    • Control: Fully controlled 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

Intended branches

  • Check that status was changed to STATUS_FAILED.

Negative behavior

  • The deposit for _depositNonce does not exist.

Function call analysis

  • this._performCall(address payable(msg.sender), payload, _gParams, BridgeAgentConstants.BRANCH_BASE_CALL_OUT_GAS) -> ILayerZeroEndpoint(this.lzEndpointAddress).send{value: msg.value}

    • What is controllable? The caller controls _depositNonce and must be the owner of this deposit; additionally, the _gParams parameters are controlled by the caller.

    • 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 function can revert if the provided fee is insufficient.

  • this._performCall(address payable(msg.sender), payload, _gParams, BridgeAgentConstants.BRANCH_BASE_CALL_OUT_GAS) -> IRootBridgeAgent(this.rootBridgeAgentAddress).lzReceive{value: msg.value}

    • What is controllable? The payload contains the address of the initial caller and the _depositNonce provided and owned by the caller.

    • 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? If the address(this).excessivelySafeCall call is unsuccessful, it will return a success status of false, and all ETH balance of the contract will be transferred to the rootPortAddress contract. Therefore, the lzReceive function can only revert if the safeTransferAllETH function fails during the transfer of funds to the rootPortAddress.

Zellic © 2024Back to top ↑