Snowman Merkle Airdrop

AI First Flight #10
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

presision and buyfee logic bug only accepts only integer numbers for buying amount of tokens **Description**

[H-1] presision and buyfee logic bug only accepts only integer numbers for buying amount of tokens

Description

The buySnow function in the Snow contract contains a logic that calculates the required payment based on the s_buyFee and the amount of tokens to be purchased. However, the current implementation only accepts integer values for the amount, which can lead to issues when users attempt to buy fractional amounts of tokens. This limitation can result in failed transactions or unexpected behavior when users try to purchase non-integer quantities of Snow tokens.
Impact

Users may be unable to purchase fractional amounts of Snow tokens, leading to a poor user experience and potential loss of sales.
Proof of Concepts

the following code snippet demonstrates the issue
function testCanBuySnow() public {
vm.startPrank(jerry);
weth.approve(address(snow), FEE);
snow.buySnow(0.2);
vm.stopPrank();
// assert(weth.balanceOf(address(snow)) == FEE);
assert(snow.balanceOf(jerry) == 0.2);
}

and this leads to logical errors that cannot accept this Operation

Compiler run failed:
Error (9553): Invalid type for argument in function call. Invalid implicit conversion from rational_const 1 / 5 to uint256 requested.
--> test/TestSnow.t.sol:57:22:
|
57 | snow.buySnow(0.2);
| ^^^
Error (2271): Built-in binary operator == cannot be applied to types uint256 and rational_const 1 / 5.
--> test/TestSnow.t.sol:61:16:
|
61 | assert(snow.balanceOf(jerry) == 0.2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Compilation failed

Recommended mitigation

I recommend updating the buySnow function to handle fractional amounts correctly
by also updating the s_buyFee calculation to accommodate decimal values by setting precision using a scaling factor (e.g., multiplying by 10^18) to ensure accurate calculations for fractional token purchases.

constructor(address _weth, uint256 _buyFee, address _collector) ERC20("Snow", "S") Ownable(msg.sender) {
// ...existing checks...
i_weth = IERC20(_weth);
s_buyFee = _buyFee;
s_collector = _collector;
i_farmingOver = block.timestamp + FARMING_DURATION;
}
function buySnow(uint256 amount) external payable canFarmSnow {
// amount is in token base units (18 decimals).
uint256 cost = (s_buyFee * amount) / PRECISION;
if (msg.value > 0) {
require(msg.value == cost, "Incorrect ETH amount");
// paid in ETH
} else {
i_weth.safeTransferFrom(msg.sender, address(this), cost);
// paid in WETH
}
_mint(msg.sender, amount);
s_earnTimer = block.timestamp;
emit SnowBought(msg.sender, amount);
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!