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

Function: retrieveSettlement(uint32 _settlementNonce, GasParams _gParams)

The retrieveSettlement function allows to retrieve a specific settlement identified by _settlementNonce. This function is callable by any user. The function ensures that the caller is authorized to retrieve the settlement by verifying the settlement owner's address. After these validations, it performs a cross-chain call to update the status of the settlement to STATUS_FAILED if this settlement is not executed in the dstChainId.

Inputs

  • _settlementNonce

    • Control: Fully controlled by the caller.

    • Constraints: The function checks that the settlement corresponding to this _settlementNonce exists and has not already been retrieved.

    • Impact: Specifies the particular settlement to be retrieved.

  • _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

  • The settlement status was updated to STATUS_FAILED after the fallback call.

Negative behavior

  • Caller is not the owner of the settlement.

  • The settlement does not exist.

Function call analysis

  • this._checkSettlementOwner(msg.sender, settlement.owner) -> IRootPort(this.rootPortAddress).getUserAccount(settlementOwner)

    • What is controllable? Nothing is controlled by the caller.

    • If the return value is controllable, how is it used and how can it go wrong? The function returns the address of the user account. If the user account has not been deployed yet, the function returns the zero address.

    • What happens if it reverts, reenters or does other unusual control flow? N/A.

  • this._performCall(settlement.dstChainId, address payable(settlementOwner), payload, _gParams, BridgeAgentConstants.ROOT_BASE_CALL_OUT_GAS) -> ILayerZeroEndpoint(this.lzEndpointAddress).send{value: msg.value}

    • What is controllable? The _settlementNonce from the payload is controlled by the caller, but the caller must be the owner of this settlement.

    • 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 caller does not provide enough fee payment or if the dstChainId is unknown.

  • this._performCall(settlement.dstChainId, address payable(settlementOwner), payload, _gParams, BridgeAgentConstants.ROOT_BASE_CALL_OUT_GAS) -> IBranchBridgeAgent(callee).lzReceive{value: msg.value}

    • What is controllable? The _settlementNonce from the payload is controlled by the initial caller, but the initial caller must be the owner of this settlement.

    • 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 executionState for the _settlementNonce is equal to STATUS_DONE, the function will revert. If the executionState is equal to STATUS_READY, the executionState will be changed to the STATUS_RETRIEVE; otherwise, it will remain the same. Subsequently, a FallbackCall will be performed back to the Root chain to change the getSettlement[nonce].status to STATUS_FAILED.

Zellic © 2024Back to top ↑