Platform: Code4rena
Start Date: 07/09/2022
Pot Size: $20,000 CANTO
Total HM: 7
Participants: 65
Period: 1 day
Judge: 0xean
Total Solo HM: 3
Id: 159
League: ETH
Rank: 2/65
Findings: 2
Award: $2,811.32
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: csanuragjain
17164.6802 CANTO - $2,772.10
https://github.com/code-423n4/2022-09-canto/blob/main/src/Swap/BaseV1-core.sol#L598
The period size is not update to current while creating a new pair. This means even if period size has been reduced from default value, this new pair will still point to the higher default value
Assume Pair P1,P2 exists in BaseV1Factory with default period size as 1800
Admin decides to decrease the period size to 900 using setPeriodSize function
function setPeriodSize(uint newPeriod) external { require(msg.sender == admin); require(newPeriod <= MaxPeriod); for (uint i; i < allPairs.length; ) { BaseV1Pair(allPairs[i]).setPeriodSize(newPeriod); unchecked {++i;} } }
This changes period size of P1, P2 to 900
Admin creates a new Pair P3 using createPair function
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair) { require(tokenA != tokenB, "IA"); // BaseV1: IDENTICAL_ADDRESSES (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), "ZA"); // BaseV1: ZERO_ADDRESS require(getPair[token0][token1][stable] == address(0), "PE"); // BaseV1: PAIR_EXISTS - single check is sufficient bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters (_temp0, _temp1, _temp) = (token0, token1, stable); pair = address(new BaseV1Pair{salt:salt}()); getPair[token0][token1][stable] = pair; getPair[token1][token0][stable] = pair; // populate mapping in the reverse direction allPairs.push(pair); isPair[pair] = true; emit PairCreated(token0, token1, stable, pair, allPairs.length); }
Add a new variable which stores the updated period size. Once a pair is created, update its period size using this new variable
uint periodSizeUpdated=1800; function setPeriodSize(uint newPeriod) external { ... periodSizeUpdated=newPeriod; } function createPair(address tokenA, address tokenB, bool stable) external returns (address pair) { ... BaseV1Pair(pair).setPeriodSize(newPeriod); }
🌟 Selected for report: lukris02
Also found by: 0x040, 0x1f8b, 0x52, 0xA5DF, 0xNazgul, 0xSky, Bnke0x0, Bronicle, CertoraInc, Chom, CodingNameKiki, Deivitto, Diraco, Dravee, EthLedger, IgnacioB, JC, JansenC, Jeiwan, R2, RaymondFam, ReyAdmirado, Rolezn, SinceJuly, TomJ, Tomo, Yiko, a12jmx, ajtra, ak1, codexploder, cryptphi, csanuragjain, erictee, fatherOfBlocks, gogo, hake, hansfriese, hickuphh3, ignacio, ontofractal, oyc_109, p_crypt0, pashov, peritoflores, rajatbeladiya, rbserver, rokinot, rvierdiiev, tnevler
242.8216 CANTO - $39.22
Contract: https://github.com/code-423n4/2022-09-canto/blob/main/src/Swap/BaseV1-core.sol#L305
Issue: The very first mint (_totalSupply=0) will deduct MINIMUM_LIQUIDITY from user deposited amount. Hence the user will be in loss, however the amount is very less thus marking this as QA
Recommendation: While initializing the contract, mint a small amount so that owner deploying the contract will pay for Minimum liquidity instead of user
Contract: https://github.com/code-423n4/2022-09-canto/blob/main/src/Swap/BaseV1-core.sol
Issue: If a security issue is identified in the pair contract, then there seems no way to instantly migrate liquidity funds from existing pair to new one