EIP150 not taken into account in RootBridgeAgent which allows an attacker to break the deposit functionality completely from any branch chain to the root
Audit: 2023-09-maia-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-09-maia/blob/c0dc3550e0754571b82d7bfd8f0282ac8fa5e42f/src/RootBridgeAgent.sol#L423-L432


# Vulnerability details

## Impact

#### Context

*Note:skip this if you have a good understanding of how LayerZero works*

LayerZero delivers the messages in the same order they were sent. In case a message delivery fails, it will block the messaging channel.

> LayerZero provides ordered delivery of messages from a given sender to a destination chain, i.e. srcUA-> dstChain. In other words, the message order nonce is shared by all dstUA on the same dstChain. That's why a STORED message blocks the message pathway from srcUA to all dstUA on the same destination chain.

[Reference from LZ docs](https://layerzero.gitbook.io/docs/faq/messaging-properties#message-ordering)

```solidity
        // block if any message blocking
        StoredPayload storage sp = storedPayload[_srcChainId][_srcAddress];
        require(sp.payloadHash == bytes32(0), "LayerZero: in message blocking");

        try ILayerZeroReceiver(_dstAddress).lzReceive{gas: _gasLimit}(_srcChainId, _srcAddress, _nonce, _payload) {
            // success, do nothing, end of the message delivery
        } catch (bytes memory reason) {
            // revert nonce if any uncaught errors/exceptions if the ua chooses the blocking mode
            storedPayload[_srcChainId][_srcAddress] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload));
            emit PayloadStored(_srcChainId, _srcAddress, _dstAddress, _nonce, _payload, reason);
        }
```

[LayerZero Endpoint: L114-L124](https://github.com/LayerZero-Labs/LayerZero/blob/main/contracts/Endpoint.sol#L114-L124)

To prevent this from happening, UAs should implement a non-blocking pattern in the contract code. So that whenever `lzReceive`  method is called by LayerZero endpoint, it should always succeed. This way we guarantee messaging channel will never be blocked.

[More details on this](https://layerzero.gitbook.io/docs/evm-guides/advanced/nonblockinglzapp)

#### Implementation and Vulnerability

Maia implements the non-blocking pattern in **RootBridgeAgent** as suggested by LayerZero. 

```solidity
    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64, bytes calldata _payload) public {
        (bool success,) = address(this).excessivelySafeCall(
            gasleft(),
            150,
            abi.encodeWithSelector(this.lzReceiveNonBlocking.selector, msg.sender, _srcChainId, _srcAddress, _payload)
        ); 
		
        if (!success) if (msg.sender == getBranchBridgeAgent[localChainId]) revert ExecutionFailure();
    }
```

[RootBridgeAgent: L423-L432](https://github.com/code-423n4/2023-09-maia/blob/c0dc3550e0754571b82d7bfd8f0282ac8fa5e42f/src/RootBridgeAgent.sol#L423-L432)

As seen `lzReceive` doesn't care if the `lzReceiveNonBlocking`  call fails (unless it is a local call which is irrelevant here). This way,  `lzReceive` should always succeed so