Open hats-bug-reporter[bot] opened 1 year ago
What is the recommended way to solve this issue?
I would recommend adding the specific function selector to each curve pool metadata, this will enforce that each pool is checked against a stricter set of functions.
If the reEntrancy check is not set, I'd revert by default as a way to enforce configurations that are safe
A switch for each type of check would on one hand save gas and on the other hand avoid the ghost function triggering a false positive
I feel tricrypto sounds a little disingenous as it uses WETH
This is a Curve Pool with a fallback that uses ETH (would require reEntrancy check and has false positive): https://etherscan.io/address/0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511#code
Thanks. Please take a look at the analysis by @abhishekvispute and let me know your thoughts.
yeah, I thought of same issue as well @GalloDaSballo :)
since their try catch fix isn't common
but I couldn't find a pool having both properties
like fallback but without remove_liquidty_one_coin
I checked the pools they mentioned in their doc, and couldn't prove it I dont know but there could be one in wild
Regardless, I think @GalloDaSballo had a good recommendation that we will implement. Regarding the severity, we currently don't support pools that have this issue, and if it's not clear that any other pool would have this issue, I will mark it as a low for now. If new evidence comes up we can talk about the severity later.
Have amended the POC and it does pass via the remove_liquidity_one_coin
Interestingly the fact that try_remove_liquidity_one_coin
uses the no-return-value version first is the saving grace at this time
Will check against more curve pool implementations and follow up if I find an example
Github username: @GalloDaSballo Submission hash (on-chain): 0x452fbd793a0e0e2cc2cfc7197efd6862bac5723a1e389d5fe49c2446782082c3 Severity: medium severity
Description: Description\ The Reentrancy Guard for Curve is based on the idea that one of the functions called should pass, and passing is a guarantee that the guard was engaged.
That is not the case for Vyper Contract that implement a fallback via
__default__
The most notable example being Tricrypto on Mainnet: 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46
Attack Scenario\ Such a pool is added, reentrancy guard becomes ineffective
Attachments / POC
The following POC is written in brownie, just add the contracts and interfaces, then follow the instructions
The goal of the POC is to demonstrate: 1) Tricrypto will not revert if you transfer with some data 2) Fake Curve Pool just implements the fallback 3) If we call a pool with just a fallback, the first try catch in which a function expects no return value will pass, marking the pool as reentrancy safe
Open Up the Console via
brownie console --network mainnet-fork
Setup: paste in the console
POC
Calling it will result in:
Code
Fake Curve Pool simply has a receive (in line with TriCrypto on Mainnet)
Extracted from your CurveOracle