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
Rank: 110/120
Findings: 1
Award: $8.03
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0xNorman, 0xRobocop, Aymen0909, ElKu, GT_Blockchain, Josiah, KrisApostolov, RaymondFam, SpicyMeatball, ToonVH, Voyvoda, anodaram, aviggiano, bin2chen, climber2002, giovannidisiena, jpserrat, minhtrng, rbserver, sashik_eth, shaka, wintermute
8.0283 USDC - $8.03
https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/PrivatePool.sol#L750-L752 https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/PrivatePool.sol#L632
FlashFee is calculated incorrectly as it does not consider the decimals of basetokens, and directly output the changeFee instead. It should be consistent with changeFeeQuote() method to calculate the real fee required to flash swap a given NFT.
In the privatePool.sol we have the flashFee function to calculate the flashloan fee to swap a given NFT. However, this function does not consider that basetokens may have different decimals rather than 18(like USDT for example) and it is inconsistent with the correct method applied in ChangeFeeQuote() function.
This calculation problem will result in either naive users lose tokens, or malicous attackers gain.
function flashFee(address, uint256) public view returns (uint256) { return changeFee; }
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; }
Manual review
Consider using the correct method in ChangeFeeQuote to calculate flashFee. And remove unused parameters.
function flashFee() public view returns (uint256) { uint256 exponent = baseToken == address(0) ? 18 - 4 : ERC20(baseToken).decimals() - 4; uint256 feeAmount = changeFee * 10 ** exponent / 1e18; }
#0 - c4-pre-sort
2023-04-20T15:08:38Z
0xSorryNotSorry marked the issue as duplicate of #864
#1 - c4-judge
2023-05-01T07:06:49Z
GalloDaSballo changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-05-01T07:08:26Z
GalloDaSballo marked the issue as satisfactory