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
Rank: 60/101
Findings: 2
Award: $185.31
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: shealtielanz
Also found by: 0xStalin, 0xnev, Breeje, RED-LOTUS-REACH, kutugu, xuwinnie
166.6515 USDC - $166.65
https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/libraries/PoolVariables.sol#L53 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/libraries/PoolVariables.sol#L74 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/libraries/PoolVariables.sol#L119 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/libraries/PoolVariables.sol#L232
The following functions uses the UniV3Pool.slot0
to get price of tokens instead of a TWAP price. Given the price stored in slot0
is determined by the ratio of assets in the pool, it can easily be manipulated by buying/selling in the pool, such as utilizing a flashloan to manipulate prices of tokens and arbritrage, causing loss to Maia's Talos protocol.
PoolVariables.amountsForLiquidity()
LinkPoolVariables.liquidityForAmounts()
LinkPoolVariables.getPositionTicks()
LinkPoolVariables.getSwapToEqualAmountsParams()
LinkManual Analysis
Use a TWAP price instead of directly using slot0
to retrieve token prices for calculation of token amount and liquidity.
Uniswap
#0 - c4-judge
2023-07-11T08:08:43Z
trust1995 marked the issue as duplicate of #823
#1 - c4-judge
2023-07-11T08:08:49Z
trust1995 marked the issue as satisfactory
#2 - c4-judge
2023-07-11T08:09:06Z
trust1995 marked the issue as partial-50
🌟 Selected for report: 0xnev
Also found by: 0xSmartContract, Breeje, BugBusters, ByteBandits, IllIllI, Kaiziron, Madalad, MohammedRizwan, SpicyMeatball, T1MOH, kutugu, nadin, peanuts, said, shealtielanz, tsvetanovv
18.6629 USDC - $18.66
https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/base/TalosBaseStrategy.sol#L269 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/TalosStrategyVanilla.sol#L148 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/base/TalosBaseStrategy.sol#L147 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/base/TalosBaseStrategy.sol#L208 https://github.com/code-423n4/2023-05-maia/blob/main/src/talos/base/TalosBaseStrategy.sol#L359
In the following functions except TalosBaseStrategy.redeem()
, the minimum slippage is still hardcoded to 0, not allowing user to specify their own slippage parameters. This can expose users to sandwich attacks due to unlimited slippage.
Additionally, it also does not allow users to supply their own deadline as the deadline
parameter is simply passed in as current block.timestamp
in which transaction occurs. This effectively means that transaction has no deadline, which means that swap transaction may be included anytime by validators and remain pending in mempool, potentially exposing users to sandwich attacks by attackers or MEV bots.
TalosBaseStrategy.redeem()
LinkTalosStrategyVanilla._compoundFees()
LinkTalosBaseStrategy.init()
LinkTaloseBaseStrategy.deposit()
LinkTaloseBaseStrategy._withdrawAll()
LinkConsider the following scenario:
TalosBaseStrategy.redeem()
with inputAmount = 30 vBNB and amountOutmin
= 0.99 BNB (1$ slippage).amountOutmin
, but the DAI value of that output might be significantly lower. She has unknowingly performed a bad trade due to the pending transaction she forgot about.An even worse way this issue can be maliciously exploited is through MEV:
minOutput
value is outdated and would allow for significant slippage.minOut
now allows for high slippage, the bot sandwiches Alice, resulting in significant profit for the bot and significant loss for Alice.The above scenario could be made worst for other functions where slippage is not allowed to be user-specified, where combined with a lack of deadline check, MEV bots can simply immediately sandwich users.
Manual Analysis
Allow users to supply their own slippage and deadline parameter within the stated functions. The deadline modifier can than can be checked via a modifier or check, which has already been implemented via the checkDeadline()
modifier.
Timing
#0 - c4-judge
2023-07-09T11:18:16Z
trust1995 marked the issue as duplicate of #171
#1 - c4-judge
2023-07-09T11:18:22Z
trust1995 marked the issue as satisfactory
#2 - c4-judge
2023-07-25T13:48:24Z
trust1995 marked the issue as selected for report
#3 - c4-sponsor
2023-07-28T13:15:42Z
0xLightt marked the issue as sponsor confirmed
#4 - 0xLightt
2023-09-06T21:39:43Z