Caviar Private Pools - Josiah's results

A fully on-chain NFT AMM that allows you to trade every NFT in a collection.

General Information

Platform: Code4rena

Start Date: 07/04/2023

Pot Size: $47,000 USDC

Total HM: 20

Participants: 120

Period: 6 days

Judge: GalloDaSballo

Total Solo HM: 4

Id: 230

League: ETH

Caviar

Findings Distribution

Researcher Performance

Rank: 53/120

Findings: 2

Award: $80.67

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

8.0283 USDC - $8.03

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-864

External Links

Lines of code

https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L623-L654 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L750-L752

Vulnerability details

Impact

changeFee that has been scaled with 4 decimals of of basis points is being adopted by flashloan(). This could make the function behave in an unexpected manner than intended.

Proof of Concept

The fee is calculated as:

PrivatePool.sol#L632

uint256 fee = flashFee(token, tokenId);

The returned changeFee is a very smaller integer. For example, if it is 1 USDC, that will mean 10000 USDC equivalent to USD 0.01 because USDC is associated with 6 decimals. It could have been worse if the baseToken has 18 decimals, which is as good as nothing.

PrivatePool.sol#L750-L752

function flashFee(address, uint256) public view returns (uint256) { return changeFee; }

Additionally, it is going to get all flash loan easily pass and execute because of an easy bypass here (baseToken is ETH in this case):

PrivatePool.sol#L635

if (baseToken == address(0) && msg.value < fee) revert InvalidEthAmount();

It is recommended scaling changeFee like it has been done so in changeFeeQuote() before having it integrated with flashLoan().

#0 - c4-pre-sort

2023-04-20T15:08:07Z

0xSorryNotSorry marked the issue as duplicate of #864

#1 - c4-judge

2023-05-01T07:07:01Z

GalloDaSballo marked the issue as satisfactory

Findings Information

🌟 Selected for report: Voyvoda

Also found by: CodingNameKiki, DishWasher, GT_Blockchain, J4de, JGcarv, Josiah, RaymondFam, neumo, saian

Labels

bug
2 (Med Risk)
satisfactory
duplicate-463

Awards

72.6437 USDC - $72.64

External Links

Lines of code

https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L737

Vulnerability details

Impact

There is an incorrect use of variable in the arithmetic calculation pertaining to assigning protocolFeeAmount in changeFeeQuote(). Although it does not currently affect the protocol, it will when the Factory owner decides to start collecting protocol fees.

Proof of Concept

feeAmount is first correctly computed after adjusting changeFee to the correct exponent. However, instead of using inputAmount, the function logic uses the diminished feeAmount to multiply with Factory(factory).protocolFeeRate(). This will make protocolFeeAmount very much smaller than expected possibly as good as nothing, defeating the purpose of introducing it to the system.

PrivatePool.sol#L731-L738

function changeFeeQuote(uint256 inputAmount) public view returns (uint256 feeAmount, uint256 protocolFeeAmount) { // multiply the changeFee to get the fee per NFT (4 decimals of accuracy) uint256 exponent = baseToken == address(0) ? 18 - 4 : ERC20(baseToken).decimals() - 4; uint256 feePerNft = changeFee * 10 ** exponent; feeAmount = inputAmount * feePerNft / 1e18; protocolFeeAmount = feeAmount * Factory(factory).protocolFeeRate() / 10_000; }

It is recommended replacing feeAmount with inputAmount like it has been done so when calculating for feeAmount.

#0 - c4-pre-sort

2023-04-20T16:36:34Z

0xSorryNotSorry marked the issue as duplicate of #463

#1 - c4-judge

2023-05-01T07:21:16Z

GalloDaSballo marked the issue as satisfactory

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