Canto Dex Oracle contest - csanuragjain's results

Execution layer for original work.

General Information

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

Canto

Findings Distribution

Researcher Performance

Rank: 2/65

Findings: 2

Award: $2,811.32

🌟 Selected for report: 1

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: csanuragjain

Labels

bug
2 (Med Risk)
sponsor confirmed

Awards

17164.6802 CANTO - $2,772.10

External Links

Lines of code

https://github.com/code-423n4/2022-09-canto/blob/main/src/Swap/BaseV1-core.sol#L598

Vulnerability details

Impact

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

Proof of Concept

  1. Assume Pair P1,P2 exists in BaseV1Factory with default period size as 1800

  2. 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;} } }
  1. This changes period size of P1, P2 to 900

  2. 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); }
  1. A new Pair is created but the period size is not updated which means P3's period size will be 1800 instead of 900 which is incorrect

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); }

User with first Mint lose funds

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

No provision for emergency migration

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

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