Summary
User can claim token with Airdrop even if they are divorced
Vulnerability Details
The isDivorced function mistakenly checks the Airdrop's status instead of the user's (msg.sender) when claiming an Airdrop. This error allows users to claim tokens even if they are divorced, as the check incorrectly returns false.
Impact
Users can claim the Airdrop multiple times even if they are divorced, Airdrop Vaut is giving token to user that shouldn't be benifeciary
The test case below, to be included in AirdropTest.sol, demonstrates that when a user claims an Airdrop without being divorced, it does not revert as expected.
Airdrop.t.test
function test_ClaimWhenDivorced() public {
_mintOneTokenForBothSoulmates();
vm.prank(soulmate1);
soulmateContract.getDivorced();
vm.prank(soulmate1);
bool status = soulmateContract.isDivorced();
console2.log("are your divorced : ",status);
vm.warp(block.timestamp + 200 days + 1 seconds);
vm.prank(soulmate1);
@> vm.expectRevert(abi.encodeWithSelector(Airdrop__CoupleIsDivorced.selector));
airdropContract.claim();
}
Tools Used
Recommendations
To adjust the function Soulmate.isDivorced so that it accepts an address as a parameter for checking divorce status.
Report the changes made to the Soulmate.isDivorced function in the Airdrop.sol file
Soulmate.sol
- function isDivorced() public view returns (bool) {
+ function isDivorced(address soulmate) public view returns (bool) {
return divorced[soulmate];
}
Airdrop.sol
function claim() public {
// No LoveToken for people who don't love their soulmates anymore.
- if (soulmateContract.isDivorced()) revert Airdrop__CoupleIsDivorced();
+ if (soulmateContract.isDivorced(msg.sender)) revert Airdrop__CoupleIsDivorced();
// Calculating since how long soulmates are reunited
uint256 numberOfDaysInCouple = (block.timestamp -
soulmateContract.idToCreationTimestamp(
soulmateContract.ownerToId(msg.sender)
)) / daysInSecond; //check the user could not claim token before 24h twice
uint256 amountAlreadyClaimed = _claimedBy[msg.sender];
if (
amountAlreadyClaimed >=
numberOfDaysInCouple * 10 ** loveToken.decimals()
) revert Airdrop__PreviousTokenAlreadyClaimed();
uint256 tokenAmountToDistribute = (numberOfDaysInCouple *
10 ** loveToken.decimals()) - amountAlreadyClaimed;
// Dust collector
if (
tokenAmountToDistribute >=
loveToken.balanceOf(address(airdropVault))
) {
tokenAmountToDistribute = loveToken.balanceOf(
address(airdropVault)
);
}
_claimedBy[msg.sender] += tokenAmountToDistribute;
emit TokenClaimed(msg.sender, tokenAmountToDistribute);
loveToken.transferFrom(
address(airdropVault),
msg.sender,
tokenAmountToDistribute
);
}