Platform: Code4rena
Start Date: 20/01/2022
Pot Size: $50,000 USDC
Total HM: 3
Participants: 35
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 2
Id: 77
League: ETH
Rank: 5/35
Findings: 2
Award: $1,250.60
🌟 Selected for report: 0
🚀 Solo Findings: 0
845.0019 USDC - $845.00
danb
first liquidity provider can drain others
consider the following scenario: a malicious user creates the usdc-usdt pool, they provided 1 basic unit of usdt and 1 basic unit of usdc (1/10**6 each)
the amount of liquidity token that will be minted is sqrt(1*1) = 1.
next, they will transfer 1M usdc and 1M usdt, this won't change the amount of liquidity tokens
now the value of 1 liquidity tokens (the total supply) is equal to the entire pool reserves.
this means that providing liquidity which is less than the pool reserves will cause minting 0 liquidity token, because of rounding down to zero
the next liquidity provider provides 500K USDT and 500K USDC.
the amount of liquidity token that will be minted for them will round down to zero, and they will end up paying 500k usdc and 500k usdt and get nothing.
this money will go to the pool reserves so the attacker can just withdraw their liquidity and get all of the money from the new liquidity provider because they own the entire liquidity tokens supply.
the attacker can also wait for more liquidity providers to provide liquidity so they can take their money.
manual review
I suggest using the same mechanism in uniswap v2 to prevent such attack, locking the first 1000 liquidity tokens of the first liquidity provider, this makes the attack not practical.
https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L120 https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L121
#0 - 0xean
2022-01-31T15:05:31Z
Yup, we are going to implement that. Thank you for the report.
#1 - 0xean
2022-01-31T15:50:31Z
dupe of #145
🌟 Selected for report: pauliax
Also found by: 0x1f8b, Jujic, danb, harleythedog
danb
https://github.com/code-423n4/2022-01-elasticswap/blob/main/elasticswap/src/libraries/MathLib.sol#L640 https://github.com/code-423n4/2022-01-elasticswap/blob/main/elasticswap/src/libraries/MathLib.sol#L676
>
instead if >=
the function might fail unexpectedly.
a user wants to swap with zero slippage.
they check the amount they would get from the swap before they call the function, and set the minimum amount to this.
there is no slippage, but the transaction still fails, because it requires the amount to be greater than the minimum but it's equal.
manual review
change >
to >=
#0 - 0xean
2022-01-31T15:01:09Z
dupe of #175
🌟 Selected for report: harleythedog
danb
tokens with fee on transfer can still be added. if the balance is not zero their is no check for fee on transfer.
alice create a pair with a token with fee on transfer, she transfer a tiny amount to the pool and then provides liquidity. the check
if (isExchangeEmpty) { require( IERC20(baseToken).balanceOf(address(this)) == tokenQtys.baseTokenQty, "Exchange: FEE_ON_TRANSFER_NOT_SUPPORTED" ); }
is not reached because the pool is not empty.
check if the pool is empty by totalSupply instead of the balance, and compare the balance before the transfer to the balance after the transfer.
#0 - 0xean
2022-01-31T14:41:12Z
dupe of #119