Description: In InheritanceManager:buyOutEstateNFT, it will loop through the beneficiaries array and transfer the asset to all beneficiaries except the buyer.
however, when reaching the buyer index, it will break, and the asset will not be transferred to the remaining beneficiaries following the buyer's index.
function buyOutEstateNFT(uint256 _tokenId) external payable {
...
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
@> return;
} else {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
}
...
}
Impact: This issue results in the remaining beneficiaries following the buyer's index not receiving the intended asset.
Proof of Concept: Add the following test and run it
function test_buyOutEstateNoValueDistributionToLatterBeneficieries() public {
vm.startPrank(owner);
im.addBeneficiery(beneficiary1);
im.addBeneficiery(beneficiary2);
im.addBeneficiery(beneficiary3);
im.createEstateNFT("my estate", 3e18, address(usdc));
vm.stopPrank();
vm.warp(im.getDeadline());
im.inherit();
usdc.mint(beneficiary1, 2e18);
vm.startPrank(beneficiary1);
usdc.approve(address(im), 2e18);
im.buyOutEstateNFT(1);
vm.stopPrank();
assertEq(usdc.balanceOf(beneficiary1), 0);
assertEq(usdc.balanceOf(beneficiary2), 0);
}
Recommended Mitigation: replace return with continue to continue the loop after the buyer's index.
function buyOutEstateNFT(uint256 _tokenId) external payable {
...
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
- return;
+ continue;
} else {
IERC20(assetToPay).safeTransfer(beneficiaries[i], finalAmount / divisor);
}
}
...
}