Harnessing the power of Arbitrum, Ulysses Omnichain specializes in Virtualized Liquidity Management.
Platform: Code4rena
Start Date: 22/09/2023
End Date: 06/10/2023
Period: 14 days
Status: Completed
Pot Size: $100,000 USDC
Participants: 175
Reporter: thebrittfactor
Judge: alcueca
Id: 287
League: ETH
alexxander | 1/175 | $8,485.23 | 4 | 2 | 0 | 0 | 0 | Grade A | 0 | Grade B |
0xStalin | 2/175 | $7,750.98 | 4 | 1 | 0 | 3 | 0 | 0 | 0 | 0 |
nobody2018 | 3/175 | $7,014.85 | 5 | 1 | 0 | 4 | 1 | 0 | 0 | 0 |
3docSec | 4/175 | $6,739.11 | 6 | 2 | 0 | 3 | 0 | Grade A | 0 | 0 |
rvierdiiev | 5/175 | $6,614.45 | 8 | 1 | 0 | 5 | 2 | Grade A | Grade A | 0 |
MrPotatoMagic | 6/175 | $5,981.43 | 5 | 1 | 0 | 1 | 1 | Grade A | Grade B | Grade A |
Arz | 7/175 | $5,707.71 | 2 | 0 | 0 | 2 | 1 | 0 | 0 | 0 |
ladboy233 | 8/175 | $3,912.33 | 3 | 2 | 0 | 0 | 0 | Grade A | 0 | 0 |
hals | 9/175 | $3,886.65 | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 0 |
Bauchibred | 10/175 | $2,232.29 | 4 | 0 | 0 | 2 | 0 | Grade A | 0 | Grade A |
Auditor per page
Automated findings output for the audit can be found here within 24 hours of audit opening.
Note for C4 wardens: Anything included in the automated findings output is considered a publicly known issue and is ineligible for awards.
Maia DAO V2 Ecosytem docs section that explains the business logic and technical references for Ulysses Protocol, can be found here.
Ulysses scope for this audit focuses on Ulysses Omnichain our Liquidity and Execution Platform built on top of Layer Zero.
This can be divided in two main features:
Virtualized liquidity is achieved by connecting Ports within a Pool and Spoke architecture, comprising both the Root Chain and multiple Branch Chains. These contracts are responsible for managing token balances and address mappings across environments. In addition, means that an asset deposited from a specific chain, is recognized as a different asset from the "same" asset but from a different chain (ex: arb ETH is different from mainnet ETH).
Arbitrary Cross-Chain Execution is facilitated by an expandable set of routers such as the Multicall Root Router that can be permissionlessly deployed through the Bridge Agent Factories. For more insight on Bridge Agents, please refer to our documentation here. Our Virtual Account contract simplifies remote asset management and interaction within the Root chain.
While this audit has all the Ulysses Omnichain components and features in scope, there are specific concerns that we would like to highlight for the wardens to pay special attention to. These are:
srChain
settlement and deposits should either have status
set to STATUS_SUCCESS
and STATUS_FAILED
depending on their redeemability by the user on the source.dstChain
settlement and deposit execution should have executionState
set to STATUS_READY
, STATUS_DONE
or STATUS_RETRIEVE
according to user input fallback and destination execution outcome.Previous Audits by Zellic and Code4rena can be found in the audits folder. There are three audits, two of them featuring Ulysses:
See scope.txt
Contract | SLOC | Purpose | Libraries Used |
---|---|---|---|
src/ArbitrumBranchBridgeAgent.sol | 56 | This contract is used for interfacing with Users/Routers acting as a middleman. | |
src/ArbitrumBranchPort.sol | 60 | Ulysses Port implementation for Arbitrum Branch Chain deployment | solady |
src/ArbitrumCoreBranchRouter.sol | 76 | Core Branch Router implementation for Arbitrum deployment. | solmate |
src/MulticallRootRouter.sol | 323 | Root Router implementation for interfacing with third-party dApps present in the Root Omnichain Environment. | solady |
src/CoreRootRouter.sol | 257 | Core Root Router implementation for Root Environment deployment. | solady, solmate |
src/RootBridgeAgentExecutor.sol | 198 | This contract is used for requesting token settlement clearance and executing transaction requests from the branch chains. | solady |
src/CoreBranchRouter.sol | 147 | Core Branch Router implementation for deployment in Branch Chains. | solmate |
src/RootBridgeAgent.sol | 710 | Responsible for interfacing with Users and Routers acting as a middleman. | solady |
src/VirtualAccount.sol | 94 | A Virtual Account allows users to manage assets and perform interactions remotely. | solady, solmate, @openzeppelin/contracts |
src/BranchPort.sol | 288 | This contract is used to manage the deposit and withdrawal of underlying assets from the Branch Chain in response to Branch Bridge Agents' requests. | solady, solmate |
src/MulticallRootRouterLibZip.sol | 12 | Root Router implementation for interfacing with third-party dApps present in the Root Omnichain Environment. | solady |
src/BranchBridgeAgent.sol | 553 | Contract for deployment in Branch Chains of Omnichain System, responsible for interfacing with Users and Routers. | |
src/BaseBranchRouter.sol | 117 | Base Branch Contract for interfacing with Branch Bridge Agents. | solady, solmate |
src/RootPort.sol | 327 | This contract is used to manage the deposit and withdrawal of assets between the Root Omnichain Environment and every Branch Chain in response to Root Bridge Agents requests. | solady |
src/BranchBridgeAgentExecutor.sol | 61 | This contract is used for requesting token deposit clearance and executing transactions in response to requests from the root environment. | solady |
src/token/ERC20hTokenRoot.sol | 32 | Root Chain 1:1 ERC20 representation of a token deposited in a Branch Chain's Port. | solmate, solady |
src/token/ERC20hTokenBranch.sol | 23 | Branch Chains 1:1 ERC20 representation of a token deposited in a Branch Chain's Port. | solmate, solady |
src/factories/BranchBridgeAgentFactory.sol | 77 | Factory contract for allowing permissionless deployment of new Branch Bridge Agents. | solady |
src/factories/RootBridgeAgentFactory.sol | 26 | Factory contract used to deploy new Root Bridge Agents. | |
src/factories/ERC20hTokenBranchFactory.sol | 51 | Factory contract allowing for permissionless deployment of new Branch hTokens in Branch Chains of Ulysses Omnichain Liquidity Protocol. | solady |
src/factories/ERC20hTokenRootFactory.sol | 47 | Factory contract allowing for permissionless deployment of new Root hTokens in the Root Chain of Ulysses Omnichain Liquidity Protocol. | solmate, solady |
src/factories/ArbitrumBranchBridgeAgentFactory.sol | 52 | Factory contract for allowing permissionless deployment of new Arbitrum Branch Bridge Agents. | |
src/interfaces/BridgeAgentStructs.sol | 77 | File with Bridge Agent Structs | |
src/interfaces/IRootBridgeAgent.sol | 99 | Interface for Root Bridge Agent Contract. | |
src/interfaces/BridgeAgentConstants.sol | 23 | Interface for Bridge Agent Constants. | |
src/interfaces/IERC20hTokenBranchFactory.sol | 9 | Interface for ERC20 hToken Branch Factory. | |
src/interfaces/IPortStrategy.sol | 5 | Interface to be implemented by Brach Port Strategy contracts. | |
src/interfaces/ICoreBranchRouter.sol | 10 | Interface for Core Branch Router. | |
src/interfaces/IERC20hTokenBranch.sol | 5 | Interface for ERC20 hToken Branch. | |
src/interfaces/IBranchBridgeAgent.sol | 90 | Interface for Branch Bridge Agent. | |
src/interfaces/IBranchBridgeAgentFactory.sol | 8 | Interface for Branch Bridge Agent Factory. | |
src/interfaces/IRootPort.sol | 124 | Interfaces for Root Port. | |
src/interfaces/ILayerZeroEndpoint.sol | 42 | Interface for LayerZero Endpoint. | |
src/interfaces/IERC20hTokenRoot.sol | 9 | Interface for ERC20 hToken Root. | |
src/interfaces/IBranchPort.sol | 70 | Interface for Branch Port. | |
src/interfaces/IVirtualAccount.sol | 22 | Interface for Virtual Account. | @openzeppelin/contracts |
src/interfaces/IArbitrumBranchPort.sol | 10 | Interface for Arbitrum Branch Port. | |
src/interfaces/ILayerZeroUserApplicationConfig.sol | 7 | Interface for LayerZero User Application Config. | |
src/interfaces/IMulticall2.sol | 12 | Interface for Multicall2. | |
src/interfaces/IBranchRouter.sol | 31 | Interface for Branch Router. | |
src/interfaces/IRootBridgeAgentFactory.sol | 4 | Interface for Root Bridge Agent Factory. | |
src/interfaces/IERC20hTokenRootFactory.sol | 8 | Interface for ERC20 hToken Root Factory | |
src/interfaces/IRootRouter.sol | 27 | Interface for Root Router. | |
src/interfaces/ILayerZeroReceiver.sol | 4 | Interface for LayerZero Receiver. |
Everything out of "src" is out of scope, namely "lib" and "test".
Branch / Root Bridge Agent and Bridge Agent Executor packed payload decoding and encoding.
Arbitrum's deployment of UniswapV3 and Balancer.
Virtual Account should be able to keep and use UniswapV3 NFT's.
Root contracts are to be deployed on Arbitrum and Branch contracts in several L1 and L2 networks such as Ethereum mainnet, Polygon, Base and Optimism
Only our governance has access to key admin state changing functions present in the RootPort
and CoreRootRouter
and the Root Bridge Agent deployer (referred to in the codebase as manager) is responsible for allowing new branch chains to connect to their Root Bridge Agent in order to prevent griefing.
Unless there is the need to upgrade and migrate any component of Ulysses via governance ( e.g. Bridge Agents or Core Routers) downtime should be negligible to ensure assets are available at any time to their different users.
ERC20hTokenBranch
: Should comply with ERC20/EIP20
ERC20hTokenRoot
: Should comply with ERC20/EIP20
- If you have a public code repo, please share it here: - How many contracts are in scope?: 50 - Total SLoC for these contracts?: 4281 - How many external imports are there?: 33 - How many separate interfaces and struct definitions are there for the contracts within scope?: 42 - Does most of your code generally use composition or inheritance?: Inheritance - How many external calls?: 17 - What is the overall line coverage percentage provided by your tests?: 69% - Is this an upgrade of an existing system?: False - Check all that apply (e.g. timelock, NFT, AMM, ERC20, rollups, etc.): Uses L2, Multi-Chain, Side-Chain, ERC-20 Token, Timelock function - Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol?: Yes - Please describe required context: Layerzero Messaging layer, namely Endpoint contract: https://github.com/LayerZero-Labs/LayerZero/blob/main/contracts/Endpoint.sol - Does it use an oracle?: No - Describe any novel or unique curve logic or mathematical models your code uses: None - Is this either a fork of or an alternate implementation of another project?: No - Does it use a side-chain?: True - Describe any specific areas you would like addressed: Please try to break token deposits and settlements patterns - retry, retrieve, and redeem - to avoid double spending, reentrancy and race conditions. Ensure proper asset management of different ports. Encoding and decoding of cross-chain payloads/data on bridge agents and routers.
Here is an example of a full script to run the first time you build the contracts in both Windows and Linux:
.example
from the provided .env
file and edit the uncommented RPC
and RPC_API_KEY
values to your preferences. These values will be used by our fork testing suite.forge install forge build forge test --gas-report forge snapshot --diff
Default gas price is 10,000, but you can change it by adding --gas-price <gas price>
to the command or by setting the gas_price
property in the foundry.toml file.
Install libraries using forge and compile contracts.
forge install forge build
only uses native foundry tools (VM.fork)
Whenever you need to change chain during there are 6 functions at your disposal:
If you encounter any issues, please update slither to 0.9.3, the latest version at the moment.
To run slither from root, please specify the src directory.
slither "./src/*"
We have a slither config file that turns on optimization and adds forge remappings.
The output is provided in ./slither.txt