Open c4-submissions opened 1 year ago
0xA5DF marked the issue as sufficient quality report
0xA5DF marked the issue as primary issue
Severity shouldn't be more than med imo, since it's probably not that common and the core assets are not lost
0xLightt (sponsor) disputed
The behavior described, where a transaction failure results in native tokens being retained in the Bridge Agents and potentially utilized by the next user, is by design. This system reduces complexity in our gas management process. The recommendation to calculate the messageFee in advance and to include potential fallback costs is based on a misunderstanding. Implementing such a mechanism would, in most cases, be misleading. Since this estimate is from the source to the destination and not from the destination to the source as the fallback would be. Refunding users would be dangerous and could brick the BridgeAgent by setting it's layerzero endpoint status to blocking.
The sponsor acknowledges the issue. Accepting that users will sometimes lose value might be an acceptable trade-off for the sponsor, but that doesn't negate the issue as per the rules of the contest.
Given that the losses are limited to a part of the gas the user accepted to use for the transaction, the severity is Medium.
alcueca changed the severity to 2 (Med Risk)
I believe there might be a number of duplicates to this issue.
alcueca marked the issue as satisfactory
The issue is that getFeeEstimate
doesn't include the gas costs of a fallback call, if it were to happen. The only costs to the user are gas costs from a transaction reverting in very rare cases. The agent should not have native tokens, and if they do, it is accepted that anyone can take them. I can't really classify this as more than QA.
alcueca changed the severity to QA (Quality Assurance)
alcueca marked the issue as grade-a
Lines of code
https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L785-L795 https://github.com/code-423n4/2023-09-maia/blob/main/src/RootBridgeAgent.sol#L938-L948 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L464 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L343 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L281 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L311 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L468 https://github.com/code-423n4/2023-09-maia/blob/main/src/BranchBridgeAgent.sol#L348 https://github.com/code-423n4/2023-09-maia/blob/main/src/RootBridgeAgent.sol#L182 https://github.com/code-423n4/2023-09-maia/blob/main/src/RootBridgeAgent.sol#L209 https://github.com/code-423n4/2023-09-maia/blob/main/src/RootBridgeAgent.sol#L238
Vulnerability details
Impact
The fees calculated is underpaid because the fee of the Fallback transaction is not taken into the calculation. Users can estimate the fees using getFeeEstimate.
In case the _hasFallbackToggled is true and the protocol need to send back the fallback message via the LayerZero then the users underpaid the amount of the message fee for the fallback message. Because users 's transactions will pass if the msg.value is enough to cover the message fees for delivering the message on the destination chain. The LayerZero Endpoint message fees is calculated based only on the message that need to be sent via the EndPoint. Any amount (msg.value - message fee) is refunded to the user (the refundee).
Currently the contracts RootBridgeAgent have getFeeEstimate as following:
Title
Title
So the Fee calculation is based on the _payload of the transaction sent from the other chains to the root chain and vice versa. But in the case, the _hasFallbackToggled is true, the cost of sending the Fallback transaction is not charged to the user and this will charge from the contract balance.
Note: Currently the Maia protocol supports the Fallback feature that will send the fallback payload. In the Branch Bridge Agent contract, the fallback payload will be sent via the Layerzero to the Root Bridge Agent as seen in the code below.
When the _hasFallbackToggled is true, then in some scenarios, the bridge agent will send the fallback payload to other chains as seen below.
Title
In the Root Bridge Agent contract, the fallback payload will be sent via the Layerzero to the Branch Bridge Agent as seen in the code below. Title
Proof of Concept
Step 1: Users call on the Branch Bridge Agent or the Root Bridge Agent with _hasFallbackToggled is true for example
_hasFallbackToggled is true
Step 2: In case there is some error in the root chain, the fallback message is sent to the Branch Bridge Agent, then users call the redeemDeposit to take back his money.
The POC on Branch Bridge Agent is similar to test case testFallbackClearDepositRedeemSuccess Title
The flow of the message on the root chain: the message is sent from the Layerzero Endpoint to the Root bridge agent Title
Then Title
Then Title
The cost of the fallback message is charged from the contract balance.
Note: The contract balance ETH in Root Bridge Agent and Branch Bridge Agent can come from the Layerzero endpoint when users uses adapter parameters: _gasParams.remoteBranchExecutionGas as airdrop native token via Layerzero as explained in (https://layerzero.gitbook.io/docs/evm-guides/advanced/relayer-adapter-parameters). We can see this is similuted in the test cases of Maia: https://github.com/code-423n4/2023-09-maia/blob/c0dc3550e0754571b82d7bfd8f0282ac8fa5e42f/test/ulysses-omnichain/MulticallRootRouterTest.t.sol#L1384-L1386
But notice that in the lzReceive of Root Bridge Agent and Branch Bridge Agent, it is used excessivelySafeCall to lzReceiveNonBlocking, so if the call to lzReceiveNonBlocking is failed (reverted), the message delivery from the Layerzero endpoint is still succesfull. So for some transactions that the call to lzReceiveNonBlocking is reverted, it does not spend ETH, but the contract still received ETH from Layerzero, so ETH is accumulated in Root Bridge Agent and Branch Bridge Agent. This ETH can come from different users with different transactions.
End of Note.
Tools Used
Manual Review
Recommended Mitigation Steps
Should calculate the messageFee and in case the fallback is needed then the message fee should include the fee of sending the fallback. If not using the fallback, should refund the users on the other chain.
Assessed type
ETH-Transfer