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
Rank: 17/74
Findings: 2
Award: $180.46
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: tonisives
Also found by: Inspecktor, MohammedRizwan, Qeew, peanuts, sces60107
162.9427 USDC - $162.94
https://github.com/code-423n4/2023-07-basin/blob/main/src/Aquifer.sol#L34-L52
The Aquifer.boreWell function is responsible for creating new Well. This is done using the LibClone.cloneDeterministic function.
The address of the new Well depends solely on the _salt and/or immutableData parameter provided by the user. Once a user create transaction is broadcast, the _salt and/or immutableData parameter can be viewed by anyone viewing the public mempool.
This may result in a DoS for Aquifer.boreWell.
If the user intends to create a Well, his create txn can be forcibly revoked by an attacker by deploying the pool to himself using the user's salt. Here's how it might happen:
The user broadcasts the pool creation txn with salt XXX and/or immutableData. The attacker preempts the user's txn and creates a pool for themselves using the same XXX salt and/or immutableData. The initial user creation txn is returned because the attacker pool already exists at the predefined address. This attack can be repeated over and over, resulting in a DoS for the Aquifer.boreWell function.
A similar issue is described in https://github.com/code-423n4/2023-04-caviar-findings/issues/419.
Manual review
Consider making the upcoming pool address a specific user by concatenating the salt value with the user's address. bytes32 salt = keccak256(abi.encode(msg.sender, _salt))
Context
#0 - c4-pre-sort
2023-07-11T14:40:02Z
141345 marked the issue as duplicate of #217
#1 - c4-pre-sort
2023-07-12T16:02:33Z
141345 marked the issue as not a duplicate
#2 - c4-pre-sort
2023-07-12T16:02:37Z
141345 marked the issue as primary issue
#3 - c4-pre-sort
2023-07-12T16:12:33Z
141345 marked the issue as duplicate of #181
#4 - c4-judge
2023-08-04T06:01:43Z
alcueca marked the issue as satisfactory
#5 - c4-judge
2023-08-05T21:38:58Z
alcueca changed the severity to 2 (Med Risk)
🌟 Selected for report: 0xprinc
Also found by: 0x11singh99, 0xAnah, 0xWaitress, 0xkazim, 2997ms, 33audits, 404Notfound, 8olidity, CRIMSON-RAT-REACH, CyberPunks, DanielWang888, Deekshith99, Eeyore, Eurovickk, Inspecktor, JGcarv, John, Jorgect, Kaysoft, LosPollosHermanos, MohammedRizwan, Qeew, QiuhaoLi, Rolezn, TheSavageTeddy, Topmark, Trust, Udsen, a3yip6, alexzoid, bigtone, codegpt, erebus, fatherOfBlocks, ginlee, glcanvas, hunter_w3b, josephdara, kaveyjoe, kutugu, mahdirostami, max10afternoon, oakcobalt, peanuts, pfapostol, ptsanev, qpzm, radev_sw, ravikiranweb3, sces60107, seth_lawson, te_aut, twcctop, zhaojie, ziyou-
17.5208 USDC - $17.52
[L1]: An attacker can initialize Well before an administrator
When Well.sol init() is initialized, the parameters string memory name, string memory symbol are entered, which cannot be changed later in the contract. This function can also be called in Aquifer.boreWell() when certain parameters are set. If this function is not initialized in Aquifer.sol, an attacker can get ahead and set their own values (because init() is public)
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L31-L43
[L2]: Transfer fee tokens can also be transferred via swapFrom() under certain conditions
There is a swapFromFeeOnTransfer() function to exchange tokens with a transfer fee. However, this can also be done in the swapFrom() function if the condition is met if reserves[i] > _tokens[i].balanceOf(address(this)) (https://github.com/code-423n4/2023-07-basin /blob/main/src/Well.sol#L634) after the token swap. Thus, you can get more tokens at the expense of the contract.
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L186-L196 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L215-L240 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L634
[L3]: No check for address(0)
There is no check for address(0) for the recipient parameter. You need to add the require(recipient != address(0)) check
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L191 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L208 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L269 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L355 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L395 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L404
[L4]: No check for the number of sent tokens
The amountIn and amountOut parameters require the require(... != 0) check.
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L211 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L237 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L303-L304 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L370 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L477
[L5]: Check before _mint that number of tokens != 0
require(lpAmountOut != 0); _mint(recipient, lpAmountOut);
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L441
[L6]: Check before _burn that number of tokens != 0
require(lpAmountIn != 0); _mint(recipient, lpAmountOut);
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L471 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L511 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L566
#0 - c4-pre-sort
2023-07-13T14:33:39Z
141345 marked the issue as high quality report
#1 - c4-pre-sort
2023-07-14T05:43:01Z
141345 marked the issue as low quality report
#2 - c4-judge
2023-08-05T10:20:07Z
alcueca marked the issue as grade-b