Basin - ptsanev's results

A composable EVM-native decentralized exchange protocol.

General Information

Platform: Code4rena

Start Date: 03/07/2023

Pot Size: $40,000 USDC

Total HM: 14

Participants: 74

Period: 7 days

Judge: alcueca

Total Solo HM: 9

Id: 259

League: ETH

Basin

Findings Distribution

Researcher Performance

Rank: 9/74

Findings: 2

Award: $762.57

QA:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Trust

Also found by: ptsanev

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sponsor disputed
duplicate-255

Awards

745.0513 USDC - $745.05

External Links

Lines of code

https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/Well.sol#L215-L240 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/functions/ConstantProduct2.sol#L49-L54 https://github.com/code-423n4/2023-07-basin/blob/9403cf973e95ef7219622dbbe2a08396af90b64c/src/functions/ConstantProduct2.sol#L58-L75

Vulnerability details

Details

The swapping mechanism of a Well using the ConstantProduct2.sol as it's function is susceptible to a flashloan attack to drain pool tokens, or to a combination of a flashloan + sandwich attack to DoS user swaps.

Impact

A malicious actor can drain tokens by creating his own arbitrage with a flashloan, or he can DoS user swaps to effectively freeze swaps under certain conditions, which are realistic. Check POC for more details.

Proof of Concept

Let us define a basic 2 token Well, that implements the CP2 function (for simplicity's sake). TOKEN A - reserve = 10_000 TOKEN B - reserve = 10_000 With these values, the LP token supply would be 10_000 as well (the square root of 100 million)

The flashloan + sandwich DoS scenario:

Alice wants to swap 1000 of tokenA to tokenB so she uses _swapFrom() and for a min amount she inputs a value i n the range of [100:900].

In the default scenario the tx will go as follows:

reserveA = 11_000 reserveB = _calcReserve (from the CP2) = LP supply ** 2 / reserveA = 100mill / 11_000 = 9090 This means that the amount out Alice would get is 910 which satisfies the minAmountOut, no matter what value in the specified range it is. A malicious actor can use a flashloan (or even his own balance depending on the minAmountOut) to add liquidity to tokenA and greatly decrease the amount Alice would receive by front-running her.

Malicious scenario:

reserveA after flashloan frontrun + Alice's input: 10_000 + 100_000 + 1_000(after Alice) reserveB = _calcReserve = LP supply ** 2 / reserveA = 10_000(reserveBbefore) * reserveA(before Alice) / reserveA = 1_010_000_000 / 111_000 = 9099 This means that the amount out Alice would get is only 101 which can fail is some cases due to the slippage check done. The amount get's even lower for greater pumps.

The flashloan + arbitrage drainage scenario:

A malicious actor uses a flashloan to produce a similiar pump to the one mentioned above, but he does it in reverse, aka: reserveA = 10_000 reserveB after flashloan liquidity pump = 10_000 + 100_000 LP supply ** 2 right now is: 1_100_000_000 He begins a regular transaction from A to B, by adding 1000 A tokens so reserveA = 10_000 + 1_000 reserveB now changes as follow: _calcReserve = 1_100_000_000 / 11_000 = 100_000 This means that the actor managed to take out 10K of token B for just 1K token A, effectively draining the currently defined pool when he removes his liquidity to pay back the flashloan.

Tools Used

Manual Review

There should be a default mechanism implemented, such as that even non-maliciously defined Well's that are verified by the protocol team as 'innocent' aren't susceptible to such high reserve movements. You could do a number of things like:

  1. A limit on liquidity adding, so that amounts do not get this greatly manipulated
  2. A snapshot-like mechanism to check the reserves at which the current tx is being calculated compared to the previous one (or from a previous block where the flashloan hasn't happened yet)

Assessed type

Math

#0 - c4-pre-sort

2023-07-12T02:41:17Z

141345 marked the issue as primary issue

#1 - 141345

2023-07-13T07:58:29Z

previous audit by halborn talks about similar issue: 4.2 (HAL-02) SLIPPAGE MANIPULATION

Not sure if this is known issue

#2 - c4-sponsor

2023-07-16T14:44:58Z

publiuss marked the issue as sponsor disputed

#3 - publiuss

2023-07-16T14:45:57Z

In regards to the DOS attack:

This is an issue that is already present in other AMMs. The lack of a fee just makes the DOS cheaper than in other AMMs. However, it still requires paying for 2 Ethereum transaction fees. The use of a private mempool or a higher priority fee solves this problem.

In regards to the potential drainage of funds:

This is not an issue as the actor is extracting value from themselves and this scenario is also possible in other AMMs. In the shared example, a malicious actor adds one-sided liquidity to drastically manipulate the price, and then swaps in the pool to get a drastically manipulated execution price. However, because they added the one sided liquidity themselves, they are trading against themselves -> The value of the LP tokens they received from adding liquidity decreases significantly. Thus, they are essentially extracting value from themselves and it is not an attack vector.

#4 - alcueca

2023-08-02T21:18:02Z

Vulnerability to sandwich attacks is expected of most AMMs, unless they advertise to the contrary. Likewise if used as griefing.

#5 - c4-judge

2023-08-02T21:18:08Z

alcueca marked the issue as unsatisfactory: Invalid

#6 - c4-judge

2023-08-02T21:20:16Z

alcueca marked the issue as satisfactory

#7 - c4-judge

2023-08-02T21:20:28Z

alcueca marked the issue as partial-50

#8 - alcueca

2023-08-02T21:22:17Z

After reading the much better description on #255, I agree that the lack of fees makes griefing attacks possible. Only partial credit for confusing report. Uneconomical DoS attacks are Medium at best.

#9 - c4-judge

2023-08-02T21:22:25Z

alcueca changed the severity to 2 (Med Risk)

#10 - c4-judge

2023-08-03T14:14:54Z

alcueca marked the issue as satisfactory

#11 - c4-judge

2023-08-05T21:46:15Z

alcueca marked the issue as selected for report

#12 - c4-judge

2023-08-15T19:38:22Z

alcueca marked the issue as duplicate of #255

#13 - c4-judge

2023-08-21T20:40:11Z

alcueca marked the issue as not selected for report

Lines of code

https://github.com/code-423n4/2023-07-basin/blob/c1b72d4e372a6246e0efbd57b47fb4cbb5d77062/src/Well.sol#L413-L418

Vulnerability details

Impact

In the _addLiquidty function of the Well contract a user passes an array of uint256 of the amounts of underlying tokens he wants to deposit. This creates room for user error and potential losses on gas and fee-on-transfer token involvement, since there can be multiple wells with the same tokens, ordered differently in the _tokens[] array. A user can pass the values in the wrong order for the current Well and add the wrong amount of liquidity, forcing him to remove and then redo.

Proof of Concept

https://github.com/code-423n4/2023-07-basin/blob/c1b72d4e372a6246e0efbd57b47fb4cbb5d77062/src/Well.sol#L413-L444 We can see the possibility for the amounts to be wrong since a user can accidentally pass them wrongly ordered in the array, adding liquidity not the way he intended.

Tools Used

Manual Review

Maybe change up the array from a uint256[] to a struct array holding the target token and the amount for user convenience and to avoid such errors.

Assessed type

Error

#0 - c4-pre-sort

2023-07-11T10:01:12Z

141345 marked the issue as low quality report

#1 - 141345

2023-07-13T08:40:55Z

user's error

maybe QA is more appropriate

#2 - alcueca

2023-08-03T21:36:35Z

This would be good QA advice

#3 - c4-judge

2023-08-03T21:36:40Z

alcueca changed the severity to QA (Quality Assurance)

#4 - alcueca

2023-08-04T21:03:23Z

Using structs would definitely be a good idea.

#5 - c4-judge

2023-08-04T21:03:29Z

alcueca marked the issue as grade-a

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