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

Lack of Ownership Transfer in `buyOutEstateNFT` Function

Summary

In src/InheritanceManager.sol, the buyOutEstateNFT function allows a beneficiary to buy out an estate NFT by transferring tokens to other beneficiaries. However, after the payment is completed, the function burns the NFT instead of transferring ownership to the buyer. This results in the buyer losing their claim to the estate despite successfully paying for it.

Vulnerability Details

In InheritanceManager.sol#L263, the buyOutEstateNFT function facilitates the payment process but does not correctly update the NFT ownership.

Here is the affected code:

function buyOutEstateNFT(uint256 _nftID) external onlyBeneficiaryWithIsInherited {
uint256 value = nftValue[_nftID];
uint256 divisor = beneficiaries.length;
uint256 multiplier = beneficiaries.length - 1;
uint256 finalAmount = (value / divisor) * multiplier;
IERC20(assetToPay).safeTransferFrom(msg.sender, address(this), finalAmount);
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
return; // ❌ Incorrectly exits the loop, NFT is not transferred
} else {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
}
nft.burnEstate(_nftID); // ❌ NFT is burned, buyer loses their claim
}

Impact

  • Loss of Ownership: After completing the payment, the buyer does not receive the estate NFT.

  • Irrecoverable Asset Destruction: The NFT is permanently burned, meaning the buyer cannot claim the estate.

  • Financial Loss: A paying beneficiary loses both the tokens spent on the buyout and the estate NFT.

Tools Used

  • Manual code review

Recommendations

Instead of burning the estate NFT, transfer it to the buyer after the payment is processed.

Here is the fixed code:

function buyOutEstateNFT(uint256 _nftID) external onlyBeneficiaryWithIsInherited {
uint256 value = nftValue[_nftID];
uint256 divisor = beneficiaries.length;
uint256 multiplier = beneficiaries.length - 1;
uint256 finalAmount = (value / divisor) * multiplier;
IERC20(assetToPay).safeTransferFrom(msg.sender, address(this), finalAmount);
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
// ✅ Transfer the NFT to the buyer
nft.safeTransferFrom(address(this), msg.sender, _nftID);
} else {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
}
}
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.