Maia DAO - Ulysses - imare's results

Harnessing the power of Arbitrum, Ulysses Omnichain specializes in Virtualized Liquidity Management.

General Information

Platform: Code4rena

Start Date: 22/09/2023

Pot Size: $100,000 USDC

Total HM: 15

Participants: 175

Period: 14 days

Judge: alcueca

Total Solo HM: 4

Id: 287

League: ETH

Maia DAO

Findings Distribution

Researcher Performance

Rank: 89/175

Findings: 2

Award: $25.79

QA:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/VirtualAccount.sol#L85

Vulnerability details

A VirtualAccount represents a user wallet that allows the user to manage assets and perform remote interactions.

But because payableCall method lacks any form of authentication it can be called by anyone. The call can be also executed directly to the desired VirtualAccount instance (as shown by the POC in this report).

Impact

Anyone can call (directly) any VirtualAccount user contract and execute asset movements or any desired interaction in the name of the user (wallet).

Proof of Concept

This line is missing an access modifier:

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/VirtualAccount.sol#L85

Add the following test to the MulticallRootRouterTest.t.sol file :

// add this after helper import
import {PayableCall} from "@omni/interfaces/IVirtualAccount.sol";

// add as one of the tests
function testAnyoneCanInteractWithTheUserVirtualAccount() public {
    // userVirtualAccount variable is defined as :
    //userVirtualAccount = address(rootPort.fetchVirtualAccount(address(this)));

    PayableCall[] memory payableCallData = new PayableCall[](1);

    payableCallData[0] =
    PayableCall({target: mockApp, callData: abi.encodeWithSelector(bytes4(keccak256(bytes("distro()")))), value : 0});

    // RLP Encode Calldata
    bytes memory data = encodeCalls(abi.encode(payableCallData));

    hevm.startPrank(address(0x1337));
    // value can be anything ..also 0
    userVirtualAccount.call{value : 0}(abi.encodeWithSignature("payableCall(PayableCall[] data)", data));
    hevm.stopPrank();
}

The test will succeed to run and will show that anyone can directly call an VirtualAccount that makes interactions on behalf of the user.

Running 1 test for test/ulysses-omnichain/MulticallRootRouterTest.t.sol:MulticallRootRouterTest
[PASS] testAnyoneCanInteractWithTheUserVirtualAccount() (gas: 13697)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 11.68ms

Running 1 test for test/ulysses-omnichain/MulticallRootRouterZippedTest.t.sol:MulticallRootRouterZipTest
[PASS] testAnyoneCanInteractWithTheUserVirtualAccount() (gas: 47730)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 11.84ms

Tools Used

Manual review

Add an access modifier like is done for VirtualAccount#call method

-function payableCall(PayableCall[] calldata calls) public payable returns (bytes[] memory returnData) { 
+function payableCall(PayableCall[] calldata calls) public payable returns (bytes[] memory returnData) requiresApprovedCaller { 

Assessed type

Access Control

#0 - c4-pre-sort

2023-10-08T14:03:24Z

0xA5DF marked the issue as duplicate of #888

#1 - c4-pre-sort

2023-10-08T14:37:02Z

0xA5DF marked the issue as sufficient quality report

#2 - c4-judge

2023-10-26T11:29:03Z

alcueca marked the issue as satisfactory

#3 - c4-judge

2023-10-26T11:32:08Z

alcueca changed the severity to 3 (High Risk)

Lines of code

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L142 https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L943 https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgent.sol#L1210

Vulnerability details

Impact

Layer0 supports also chains that have different address byte size then 20.

https://layerzero.gitbook.io/docs/technical-reference/mainnet/supported-chain-ids

A chain that support size different address then 20 is for example Aptos chain.

Such chain can be added to the protocol but will not work as expected.

Proof of Concept

Such chain can be added as its shown by this lines:

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L142

This line will not revert:

 rootBridgeAgentPath = abi.encodePacked(_rootBridgeAgentAddress, address(this));

But inside the executor contract (the BranchBridgeAgentExecutor) the modifier that protects the receive functionality expects a different size of address

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/BranchBridgeAgent.sol#L943

 if (_srcAddress.length != 40) revert LayerZeroUnauthorizedCaller(); 
 if (rootBridgeAgentAddress != address(uint160(bytes20(_srcAddress[20:])))) revert LayerZeroUnauthorizedCaller(); 

There is also a line in the RootBridgeAgent contract:

https://github.com/code-423n4/2023-09-maia/blob/f5ba4de628836b2a29f9b5fff59499690008c463/src/RootBridgeAgent.sol#L1210

Tools Used

Manual review

To achieve compatibility for such type of chain there is a lot of code to change. For example we should not use address type but bytes instead.

The simplest solution would be to not support such chain.

Assessed type

Error

#0 - c4-pre-sort

2023-10-07T14:03:42Z

0xA5DF marked the issue as primary issue

#1 - 0xA5DF

2023-10-07T14:04:00Z

Leaving open for sponsor to comment whether they intend to use chains like Aptos

#2 - c4-pre-sort

2023-10-07T14:04:03Z

0xA5DF marked the issue as sufficient quality report

#3 - c4-sponsor

2023-10-17T19:55:54Z

0xBugsy (sponsor) disputed

#4 - alcueca

2023-10-26T08:53:22Z

On what grounds is this being disputed?

#5 - 0xBugsy

2023-10-26T14:41:55Z

This is intended, we are only implementing EVM compatible chains trying to add different chains will not be allowed by our governance process and this interactions would revert in the setup process of the new chain. Furthermore, we don't have any Branch contracts developed that could be deployed in said chains so any impact through this isn't really feasible.

#6 - alcueca

2023-10-27T08:56:55Z

Valid QA to add in the documentation as project scope.

#7 - c4-judge

2023-10-27T08:57:04Z

alcueca changed the severity to QA (Quality Assurance)

#8 - c4-judge

2023-10-27T08:57:10Z

alcueca marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter