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

Business Logic Flaw in `inheritanceManager::buyOutEstateNFT`: leads to absence of Financial Settlement

Summary

The inheritanceManager::buyOutEstateNFT function contains a business logic flaw that allows a beneficiary to obtain the NFT without making payments to other beneficiaries. This occurs because the function exits early if the caller is a beneficiary, preventing fund distribution while still burning the NFT.

Vulnerability Details

https://github.com/CodeHawks-Contests/2025-03-inheritable-smart-contract-wallet/blob/9de6350f3b78be35a987e972a1362e26d8d5817d/src/InheritanceManager.sol#L269

The issue occurs in the following loop:

for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
return; // Exits early before payments are distributed
} else {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
}

If msg.sender is a beneficiary, the function returns early, skipping the payment distribution. Despite this, nft.burnEstate(_nftID) is outside the loop and still executes. As a result, the NFT is burned, but other beneficiaries do not receive their rightful share of the buyout.

Example Scenario

  1. The estate NFT is valued at 1,000 USDC with 4 beneficiaries.

  2. One of the beneficiaries calls inheritanceManager::buyOutEstateNFT.

  3. The function returns early, skipping fund distribution.

  4. The NFT is burned, and the beneficiaries receive no compensation.

Impact

  • Beneficiaries do not receive their fair share of the NFT’s value.

  • The contract does not fulfill its intended purpose.

Tools Used

  • Manual code review

Recommendations

  • To fix this issue, the check if (msg.sender == beneficiaries[i]) is unnecessary and should be removed like indicated below, ensuring payments are distributed before burning the NFT:

for (uint256 i = 0; i < beneficiaries.length; i++) {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
nft.burnEstate(_nftID);
Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

buyOutNFT has return instead of continue

Support

FAQs

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