Closed c4-bot-1 closed 8 months ago
raymondfam marked the issue as sufficient quality report
raymondfam marked the issue as duplicate of #214
raymondfam marked the issue as not a duplicate
raymondfam marked the issue as primary issue
viraj124 marked the issue as disagree with severity
disagreeing with severity since curve by default doesn't implement this but this can be a qa issue and we'll think around having a check for deadline
viraj124 (sponsor) acknowledged
0xA5DF changed the severity to QA (Quality Assurance)
I agree with the sponsor. I think the protocol acts here as a proxy to interact with other protocols. Shell doesn't have to provide any more security than interacting directly with the protocol. Marking as low
Warden has 3 lows - this, #271 and #273
0xA5DF marked the issue as grade-b
+L from #294
Lines of code
https://github.com/code-423n4/2023-11-shellprotocol/blob/main/src/adapters/Curve2PoolAdapter.sol#L162-L175 https://github.com/code-423n4/2023-11-shellprotocol/blob/main/src/adapters/CurveTricryptoAdapter.sol#L198-L227
Vulnerability details
Impact
The
Curve2PoolAdapter.primitiveOutputAmount
andCurveTricryptoAdapter.primitiveOutputAmount
functions are used to execute swaps/add liquidity/remove liquidity on theCurve2 pool
andCurve Tricrypto Pool
respectively.In both of the above
primitiveOutputAmount
functions the curve pools are accessed via theexchange
,add_liquidity
and theremove_liquidity_one_coin
functions. The inherent slippage protections of these functions are not used since0
is passed for the relevant slippage variable during execution of the above mentioned curve pool functions.Slippage protection is performed separately inside the
primitiveOutputAmount
function after the decimal conversion of the output tokens as shown below:The issue is even though the slippage protection is implemented for the transactions with the
curve pools
thedeadline
check is not implemented in theprimitiveOutputAmount
functions. As a result thecurve pool
transactions such asswaps
,add liquidity
andremove liquidity
could be executed at a later point in time which could prompt the user to perform bad trades.Due to the lack of a deadline check the following two scenarios can occur:
For example if the
gasfee
provided to theexchange
transaction is low for theminers
due to high average gas fee present in the mempool due to congestion. Hence theexchange
transaction will only execute once the average gas fees drop so the miners will be interested in executing this transaction. But by then the underlying value of the output token would have dropped due to changing market dynamics (For example if the output token is weth then the underlying value of weth denominated in USD might have dropped by 200USD by the timeexchange
transaction was executed after the delay).The
MEV
bots can perform sandwich attacks on theexchange
trade. If theweth
price has dropped compared to the input token significantly thus allowing the trader to gain moreweth
tokens after the exchange. But since theexchange
transaction is performed after a delay the slippage protection gets outdated which would allow significant slippage. As a result aMEV
bot could exploit this sandwiching theexchange
transaction resulting in significant profit and large loss to the trader due to outdated slippage protection.Proof of Concept
https://github.com/code-423n4/2023-11-shellprotocol/blob/main/src/adapters/Curve2PoolAdapter.sol#L162-L175
https://github.com/code-423n4/2023-11-shellprotocol/blob/main/src/adapters/CurveTricryptoAdapter.sol#L198-L227
Tools Used
Manual Review and VSCode
Recommended Mitigation Steps
Hence while interacting with DEXes like
curve
it is recommended to implement both theslippage
anddeadline
protection. Since the slippage protection is already implemented separately without using the inherent slippage protection of curve functions, it is recommended to implement thedeadline
protection separately in theprimitiveOutputAmount
function (since curve liquidity pools do not inherently have deadline protection implemented). This can be done by passing in ainput timestamp
by the user indicating the latest time the curve transaction can be executed and if the currentblock.timestamp
has exceeded this timestamp then the transaction should revert.Assessed type
Timing