An attacker can steal assets from RootPort if assets are deposited by callOutAndBridge()
or callOutAndBridgeMultiple()
#765
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-685
edited-by-warden
grade-c
high quality report
This report is of especially high quality
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgent.sol#L490-L536
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgent.sol#L351-L384
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootPort.sol#L277-L291
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L219-L221
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L241-L250
Vulnerability details
Impact
callOutAndBridge()
is a deposit function where users can deposit underlying tokens and local tokens on the branch chain, and global tokens are minted on the root chain. However, there's an issue with this function. The message passed to the root chain only contains information about the underlying token and local token, lacking details about the depositor. Consequently, the root chain is unaware of who deposited these tokens.https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L209-L228
After receiving the callOutAndBridge message from BranchBridgeAgent, RootBridgeAgent generates global tokens based on the quantity of underlying tokens and local tokens in the message. These global tokens are stored in
localRouterAddress
. However, there is no indication or marking to identify which user owns these global tokens.https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgent.sol#L479-L487
https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgentExecutor.sol#L66C1-L73C6
When a user initiates a withdrawal request by calling
callOut
, RootBridgeAgent retrieves global tokens fromlocalRouterAddress
according to the requested quantity, regardless of whether the user has made a deposit or the specified quantities of underlying tokens and local tokens. Subsequently, a response message is sent to the user.https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/MulticallRootRouter.sol#L508-L533
The same issue exists with callOutAndBridgeMultiple.
Proof of Concept
In the following test code, a legitimate user calls
callOutAndBridge()
to deposit 100 avaxMockAssetToken tokens. Subsequently, the hacker callscallOut()
to steal these 100 avaxMockAssetToken tokens.Tools Used
Foundry
Recommended Mitigation Steps
Add depositor information in both callOutAndBridge and callOutAndBridgeMultiple, with the root chain recording the depositors. When users request withdrawals, check whether they have sufficient deposits.
Assessed type
Context
The text was updated successfully, but these errors were encountered: