Open code423n4 opened 1 year ago
trust1995 marked the issue as primary issue
trust1995 marked the issue as satisfactory
0xLightt marked the issue as sponsor confirmed
trust1995 marked the issue as selected for report
We recognize the audit's findings on Decimal Conversion for Ulysses AMM. These will not be rectified due to the upcoming migration of this section to Balancer Stable Pools.
Lines of code
https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchPort.sol#L388-L390 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L1340-L1342 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/ArbitrumBranchPort.sol#L52-L54 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/ArbitrumBranchBridgeAgent.sol#L104 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L269 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L313 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L696 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L745
Vulnerability details
_normalizeDecimals()
and_denormalizeDecimals()
are used to handle non-18 decimals tokens when bridging deposit, by scaling them to a normalized 18 decimals form for hToken accounting, and then denormalizing to the token's decimals when interacting with the underlying token.However, there are 3 issues as follows,
_normalizeDecimals()
and_denormalizeDecimals()
are reversed._denormalizeDecimals()
is missing inArbitrumBranchPort.depositToPort()
._normalizeDecimals()
is missing in functions withinBranchBridgeAgent
.These issues will cause an incorrect accounting of hTokens and underlying tokens in the system.
Impact
Incorrect decimal scaling will lead to loss of fund as the amount deposited and withdrawn for bridging will be inaccurate, which can be abused by an attacker or result in users inccuring losses.
For example, an attacker can abuse the
ArbitrumBranchPort.depositToPort()
issue and steal from the system by first depositing a token that has more than 18 decimals, as the attacker will receive more hTokens than the deposited underlying token amount. The attacker can then make a profit by withdrawing from the port with the excess hTokens.On the other hand, if the underlying token is less than 18 decimals, the depositor can inccur losses as the amount of underlying tokens deposited will be more than the amount of hTokens received.
Detailed Explanation
Issue 1
BranchBridgeAgent._normalizeDecimals()
andBranchPort._denormalizeDecimals()
(shown vbelow) are incorrect as they are implemented in a reversed manner, such that_denormalizeDecimals()
is normalizing to 18 decimals while_normalizeDecimals()
is denormalizing to the underlying token decimals.The result is that for tokens with > 18 decimals,
_normalizeDecimals()
will overscale the decimals, while for tokens with < 18 decimals,_normalizeDecimals()
will underscale the decimals.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L1340-L1342
https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchPort.sol#L388-L390
Issue 2
ArbitrumBranchPort.depositToPort()
is mssing_denormalizeDecimals()
to scale back the decimals of the underlying token amount before transfering. This will cause a wrong amount of the underlying token to be transfered.As shown below,
ArbitrumBranchBridgeAgent.depositToPort()
has normalized theamount
to 18 decimals before passing intoArbitrumBranchPort.depositToPort()
.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/ArbitrumBranchBridgeAgent.sol#L104
That means the
_deposit
amount forArbitrumBranchPort.depositToPort()
(see below) will be incorrect as it is not denormalized back to the underlying token's decimal, causing the wrong value to be transfered from the depositor.If the underlying token is more than 18 decimals, the depositor will transfer less underlying tokens than the hToken received resulting in excess hTokens. The depositor can then call
withdrawFromPort()
to receive more underlying tokens than deposited.If the underlying token is less than 18 decimals, that will inflate the amount to be transferred from the depositor, causing the depositor to deposit more underlying token than the amount of hToken received. The depositor will incurr a loss when withdrawing from the port.
Instead, the
_deposit
should be denormalized inArbitrumBranchPort.depositToPort()
when passing to_underlyingAddress.safeTransferFrom()
, so that it is scaled back to the underlying token's decimals when transfering.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/ArbitrumBranchPort.sol#L52-L54
Issue 3
In
BranchBridgeAgent
, the deposit amount passed into_depositAndCall()
and_depositAndCallMultiple()
are missing_normalizeDecimals()
. Example below showscallOutSignedAndBridge()
, but the issue is also present incallOutAndBridge()
,callOutSignedAndBridgeMultiple()
,callOutAndBridgeMultiple()
.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L269
And that will affect
_createDepositSingle()
and_createDepositMultiple()
, leading to incorrect decimals forIPort(localPortAddress).bridgeOut()
. That will affect hToken burning and deposit of underlying tokens.At the same time, the deposits to be stored in
getDeposit[]
is also not normalized, causing a mis-match of decimals whenclearToken()
is called viaredeemDeposit()
.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L857-L891
Recommended Mitigation Steps
Switch the implementation of
_normalizeDecimals()
to_denormalizeDecimals()
and vice versa.Add
_denormalizeDecimals()
toArbitrumBranchPort.depositToPort()
when callingIRootPort(rootPortAddress).mintToLocalBranch()
.Utilize
_normalizeDecimals()
for when passing deposit amount to_depositAndCall()
and_depositAndCallMultiple()
withinBranchBridgeAgent
.Assessed type
Decimal