Maia DAO Ecosystem - yellowBirdy's results

Efficient liquidity renting and management across chains with Curvenized Uniswap V3.

General Information

Platform: Code4rena

Start Date: 30/05/2023

Pot Size: $300,500 USDC

Total HM: 79

Participants: 101

Period: about 1 month

Judge: Trust

Total Solo HM: 36

Id: 242

League: ETH

Maia DAO Ecosystem

Findings Distribution

Researcher Performance

Rank: 10/101

Findings: 2

Award: $6,139.29

🌟 Selected for report: 1

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: yellowBirdy

Labels

bug
3 (High Risk)
primary issue
satisfactory
selected for report
sponsor confirmed
H-01

Awards

5707.2337 USDC - $5,707.23

External Links

Lines of code

https://github.com/code-423n4/2023-05-maia/blob/54a45beb1428d85999da3f721f923cbf36ee3d35/src/ulysses-omnichain/BranchPort.sol#L158-L169 https://github.com/code-423n4/2023-05-maia/blob/54a45beb1428d85999da3f721f923cbf36ee3d35/src/ulysses-omnichain/BranchPort.sol#L172-L186

Vulnerability details

Impact

BranchPort.manage allows a registered Strategy to withdraw certain amounts of enabled strategy tokens. It validates access rights ie. if called by a strategy registered for the requested token. It however doesn't check if the token itself is currently enabled.

Conversely BranchPort.replenishTokens allows to force withdraw managed tokens from a strategy. It however performs a check if the token is currently an active strategy token.

Strategy token may be disabled by toggleStrategyToken() even if there are active strategies managing it active. In such case these strategies will still be able to withdraw the tokens with calls to manage() while replenishTokens will not be callable on them and thus tokens won't be force returnable.

Tools Used

Pen and Paper.

  1. Add check on enabled strategy token in manage()
  2. Validate getPortStrategyTokenDebt[_strategy][_token] > 0 instead of !isStrategyToken[_token] in replenishReserves()

Assessed type

Access Control

#0 - c4-judge

2023-07-11T15:11:02Z

trust1995 marked the issue as unsatisfactory: Insufficient proof

#1 - c4-sponsor

2023-07-12T13:33:17Z

0xBugsy marked the issue as sponsor confirmed

#2 - c4-judge

2023-07-25T09:22:51Z

trust1995 marked the issue as satisfactory

#3 - c4-judge

2023-07-25T15:02:17Z

trust1995 marked the issue as primary issue

#4 - c4-judge

2023-07-27T11:02:19Z

trust1995 marked the issue as selected for report

#5 - 0xLightt

2023-09-06T17:21:21Z

Findings Information

🌟 Selected for report: ltyu

Also found by: BPZ, Koolex, RED-LOTUS-REACH, xuwinnie, yellowBirdy

Labels

bug
3 (High Risk)
satisfactory
duplicate-91

Awards

432.0595 USDC - $432.06

External Links

Lines of code

https://github.com/code-423n4/2023-05-maia/blob/54a45beb1428d85999da3f721f923cbf36ee3d35/src/ulysses-omnichain/BranchBridgeAgent.sol#L1006-L1011 https://github.com/code-423n4/2023-05-maia/blob/54a45beb1428d85999da3f721f923cbf36ee3d35/src/ulysses-omnichain/lib/AnycallFlags.sol#L11

Vulnerability details

Impact

IAnycallProxy().anyCall() operates under one of two modes of taking fees, namely fees are taken either on source or on the destination chain. Fee mode is decided by the caller with an appropriate value of the fourth parameter, ie. uint256 _flag . Values 0,4 denote the SOURCE chain. Such invocation require ether to be send along (IAnycallProxy().anyCall() is payable) and in case of insufficient value being sent will fail.

function anyCall( address _to, bytes calldata _data, uint256 _toChainID, uint256 _flags, bytes calldata _extdata ) external payable;

BranchBridgeAgent._performCall() invokes anyCall() with AnycallFlags.FLAG_ALLOW_FALLBACK which is defined as 0x1 << 2 ie 4

source: BranchBridgeAgent.sol

function _performCall(bytes memory _calldata) internal virtual { //Sends message to AnycallProxy IAnycallProxy(localAnyCallAddress).anyCall( rootBridgeAgentAddress, _calldata, rootChainId, AnycallFlags.FLAG_ALLOW_FALLBACK, "" ); }

source: AnycallFlags.sol

uint256 public constant FLAG_ALLOW_FALLBACK = 0x1 << 2;

Consequently all cross bridge requests will fail.

Tools Used

Manual review, Multichain documentation: (Link to anyCall flags definition)[https://docs.multichain.org/developer-guide/anycall-v7/quickstart-cross-chain-text-example]

Judging from the RootBridgeAgent.anyExecute() implementation the intended mode is to pay fees on the destination chain (with fallback enabled). Under this assumption _flag = 6 should be passed ie. AnycallFlags.FLAG_ALLOW_FALLBACK_DST

Assessed type

Other

#0 - c4-judge

2023-07-09T11:58:41Z

trust1995 marked the issue as duplicate of #91

#1 - c4-judge

2023-07-09T11:58:46Z

trust1995 marked the issue as satisfactory

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