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: 114/120
Findings: 1
Award: $5.98
🌟 Selected for report: 0
🚀 Solo Findings: 0
5.9827 USDC - $5.98
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L733
When ERC20 tokens with decimals less than 4 are set as the baseToken
the change()
functionality of PrivatePool
will not work due to an underflow.
The changeFeeQuote() function uses the magic number 4 to subtract from the return value of baseToken.decimals()
to calculate the 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; }
This poses a problem for ERC20 tokens with decimals less than 4 as the function will always underflow and revert, hence breaking the change functionality of the contract.
A popular ERC20 token with only 2 decimals currently is GUSD which is #8 stablecoin by market capitalization.
Manual review.
Here's some mitigation options:
PrivatePool
if baseToken.decimals()
is less than 4.changeFee
. This would of course have to be well documented so Pool owners would be aware that changeFee
has variable decimal precision based on the selected baseToken
. Example feePerNft
calculation:// multiply the changeFee to get the fee per NFT (4 decimals of accuracy) uint256 baseTokenDecimals = baseToken == address(0) ? 18 : ERC20(baseToken).decimals(); uint256 exponent = baseTokenDecimals > 4 ? baseTokenDecimals - 4 : 0; uint256 feePerNft = changeFee * 10 ** exponent;
#0 - c4-pre-sort
2023-04-20T15:22:53Z
0xSorryNotSorry marked the issue as duplicate of #858
#1 - c4-judge
2023-05-01T07:14:48Z
GalloDaSballo marked the issue as satisfactory