Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

Contract `Airdrop` has an Integer Overflow Risk which can lead claim LoveToken multiple times

Summary

The provided smart contract has a potential vulnerability related to integer overflow/underflow in AirDrop::claim(). The addition operation _claimedBy[msg.sender] += tokenAmountToDistribute; could result in an overflow or underflow if the values involved are too large or if the value of _claimedBy[msg.sender] is close to its maximum or minimum value.

Vulnerability Details

The _claimedBy[msg.sender] mapping is incremented by tokenAmountToDistribute, which results in integer overflow/underflow if the value exceeds the maximum/minimum limit. This vulnerability could lead to unexpected behavior.

Vulnerable Code
@> _claimedBy[msg.sender] += tokenAmountToDistribute;

Impact

The impact of this vulnerability could vary depending on the specific values involved. In the case of an overflow, the value of _claimedBy[msg.sender] could wrap around to a very small value, potentially leading to incorrect calculations or unexpected behavior in the contract. This could result in users receiving more LoveToken than intended or other unintended consequences. In the case of an underflow, the value of _claimedBy[msg.sender] could become very large, potentially causing depletion of LoveToken from the contract or disrupting its functionality, such as preventing users from claiming LoveToken altogether.

Proof of Concept

The proof of concept for this vulnerability involves simulating a scenario where the tokenAmountToDistribute exceeds the maximum limit of the uint256 data type, causing an integer overflow. This could be demonstrated through testing with large values of numberOfDaysInCouple and tokenAmountToDistribute, which could lead to unexpected behavior during LoveToken distribution.

Let’s assume that:
Day 0: Contract Deployment
The Airdrop contract is deployed with initial settings.
Initial state:
- _claimedBy[msg.sender] = 0
- airdropVault balance = 1000 LoveTokens
Day 1: First Claim
A user calls the `claim` function to claim LoveToken.
- numberOfDaysInCouple = 1
- amountAlreadyClaimed = 0
- tokenAmountToDistribute = (1 * 10^decimals) - 0 = 10^decimals
- Airdrop contract updates _claimedBy[msg.sender] to 10^decimals
- LoveTokens transferred to the user
- Event emitted: TokenClaimed(user, 10^decimals)
Day 2: Second Claim
The same user calls the `claim` function again.
- numberOfDaysInCouple = 2
- amountAlreadyClaimed = 10^decimals (from previous claim)
- tokenAmountToDistribute = (2 * 10^decimals) - 10^decimals = 10^decimals
- Airdrop contract attempts to update _claimedBy[msg.sender] to 2 * 10^decimals
- Overflow occurs as _claimedBy[msg.sender] exceeds maximum uint256 value
- Contract behavior becomes unpredictable
- LoveTokens may not be transferred as expected
- Event may not be emitted due to contract failure
Day 3: Contract Dysfunction
Due to the overflow, the Airdrop contract encounters unexpected behavior.
- Users may experience loss of LoveTokens or failed transactions
- Contract may become unusable or require intervention to recover
- Trust in the contract's reliability is compromised

Note: In the scenario provided, an integer overflow vulnerability in the Airdrop contract leads to unpredictable behavior and potential dysfunction. This vulnerability arises when a user attempts to claim LoveTokens multiple times, causing the _claimedBy mapping to overflow its maximum value. As a result, the contract may fail to transfer LoveTokens correctly, emit events, or function as intended, compromising trust in its reliability.

Attacker Scenerio

Malicious Contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import "./Airdrop.sol";
contract MaliciousContract {
Airdrop public airdropContract;
uint256 public overflowValue;
constructor(Airdrop _airdropContract) {
airdropContract = _airdropContract;
}
// Function to initiate the attack by claiming `LoveTokens` with a large value
function initiateAttack() external {
// Set a large value to cause an overflow
overflowValue = type(uint256).max;
// Call the claim function of the Airdrop contract
airdropContract.claim();
}
}

In this malicious contract:

  • The initiateAttack function is used to call the claim function of the Airdrop contract with a large value, potentially causing an integer overflow when adding the claimed LoveToken to the _claimedBy[msg.sender] mapping.

  • By setting overflowValue to the maximum value of uint256, we aim to trigger an overflow when adding it to the existing claimed LoveToken in the Airdrop contract.

The attacker would deploy this malicious contract and specify the address of the deployed Airdrop contract when deploying the MaliciousContract. Then the attacker calls the initiateAttack function to trigger the potential overflow vulnerability in the Airdrop contract.

Tools Used

Manual review.

Recommended Mitigation Steps

  1. Use SafeMath Library: Replace direct arithmetic operations with functions from the SafeMath library to prevent integer overflow/underflow.

pragma solidity ^0.8.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
}
  1. Use SafeMath for Addition: Implement SafeMath for adding values to prevent overflow.

import "./SafeMath.sol";
contract Airdrop {
using SafeMath for uint256;
// Other contract code...
function claim() public {
// Calculate tokenAmountToDistribute using SafeMath
uint256 tokenAmountToDistribute = numberOfDaysInCouple
.mul(10 ** loveToken.decimals())
.sub(amountAlreadyClaimed);
// Other contract code...
}
}
  1. Limit Maximum Claimed Value: Implement a maximum value for claimed LoveToken to prevent overflow.

contract Airdrop {
uint256 public constant MAX_CLAIMED_VALUE = 10**30; // Example maximum value
// Other contract code...
function claim() public {
// Ensure tokenAmountToDistribute does not exceed maximum value
if (tokenAmountToDistribute > MAX_CLAIMED_VALUE) {
tokenAmountToDistribute = MAX_CLAIMED_VALUE;
}
// Other contract code...
}
}
  1. Check for Potential Overflow: Implement checks to ensure that adding the claimed LoveToken does not result in overflow.

contract Airdrop {
// Other contract code...
function claim() public {
// Check for potential overflow
if (_claimedBy[msg.sender] + tokenAmountToDistribute < _claimedBy[msg.sender]) {
tokenAmountToDistribute = 0; // Prevents overflow
}
// Other contract code...
}
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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