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

Duplicate Beneficiary Entries Possible in addBeneficiery Function

Finding description and impact

The InheritanceManager contract contains a vulnerability in the addBeneficiery function that allows duplicate beneficiary entries. The core issue stems from the lack of validation before adding a new beneficiary to the array, enabling the same address to be added multiple times.

The impact is that:

  • A beneficiary added multiple times will receive multiple shares during fund distribution

  • The inheritance distribution mechanism becomes unfair and unpredictable

  • In the withdrawInheritedFunds function, assets are divided by beneficiaries.length, so duplicate entries receive proportionally more funds

  • Gas costs for operations that iterate through the beneficiaries array will increase unnecessarily

Proof of Concept

The following code segment demonstrates the vulnerability:

function addBeneficiery(address _beneficiary) external onlyOwner {
beneficiaries.push(_beneficiary);
_setDeadline();
}

Consider this scenario:

  1. Owner adds Alice as a beneficiary: addBeneficiery(aliceAddress)

  2. Owner adds Bob as a beneficiary: addBeneficiery(bobAddress)

  3. Owner accidentally (or deliberately) adds Alice again: addBeneficiery(aliceAddress)

  4. When funds are distributed in withdrawInheritedFunds, the division would be:

    uint256 divisor = beneficiaries.length; // This equals 3 instead of 2
    uint256 amountPerBeneficiary = assetAmountAvailable / divisor;
  5. Alice would receive 2 * amountPerBeneficiary while Bob would only receive amountPerBeneficiary, despite them supposedly having equal shares

This issue affects other functions as well:

  • buyOutEstateNFT would send duplicate payments to beneficiaries listed multiple times

  • inherit function's behavior could be unpredictable if there are duplicates in the array

Recommended mitigation steps

To fix this issue, implement a duplicate check in the addBeneficiery function:

function addBeneficiery(address _beneficiary) external onlyOwner {
// Check for duplicate beneficiary
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (beneficiaries[i] == _beneficiary) {
revert("Beneficiary already exists");
}
}
beneficiaries.push(_beneficiary);
_setDeadline();
}

Alternatively, a more gas-efficient approach using a mapping:

// Add this state variable
mapping(address => bool) private isBeneficiary;
function addBeneficiery(address _beneficiary) external onlyOwner {
require(!isBeneficiary[_beneficiary], "Beneficiary already exists");
beneficiaries.push(_beneficiary);
isBeneficiary[_beneficiary] = true;
_setDeadline();
}
// Remember to update removeBeneficiary as well
function removeBeneficiary(address _beneficiary) external onlyOwner {
uint256 indexToRemove = _getBeneficiaryIndex(_beneficiary);
// Proper array removal logic here
isBeneficiary[_beneficiary] = false;
_setDeadline();
}

Tools Used

  • Manual Code Review

  • Logical Analysis

Updates

Lead Judging Commences

0xtimefliez Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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