Inheritance assets in the contract becomes non-transferable when a beneficiary slot is replaced by address(0)
function test_lost_of_funds_due_to_empty_array()public{
address user2 = makeAddr("user2");
vm.startPrank(owner);
im.addBeneficiery(user1);
im.addBeneficiery(user2);
im.removeBeneficiary(user2);
usdc.mint(address(im), 10 ether);
vm.warp(block.timestamp + im.TIMELOCK() + 1 days);
im.inherit();
Trying to withdraw the inherited USDC balance to the beneficiary which should be only user1 but deleting user2 only replace user to address with zero address. Inherited USDC would not be transferable because one of the beneficiary is address 0
*/
vm.expectRevert();
im.withdrawInheritedFunds(address(usdc));
vm.stopPrank();
}
contract InheritanceManager is Trustee{
+ function _filterBeneficiaries()internal view returns(address[] memory ){
+ uint256 listOfBeneficiaries = beneficiaries.length;
+ uint numberOfNoneAddressZero;
+ for(uint i =0; i < listOfBeneficiaries; i++){
+ if(beneficiaries[i] != address(0)){
+ numberOfNoneAddressZero ++;
+ }
+ }
+ address[] memory filteredAddressList = new address[](numberOfNoneAddressZero);
+ uint256 uniqueIndex;
+ for(uint i =0; i < listOfBeneficiaries; i++){
+ if(beneficiaries[i] != address(0)){
+ filteredAddressList[uniqueIndex] = beneficiaries[i];
+ uniqueIndex ++;
+ }
+ }
+ return filteredAddressList;
+ }
function inherit() external {
+ uint256 adjustedBeneficiaryLength = _filterBeneficiaries();
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
+ if (adjustedBeneficiaryLength.length == 1) {
+ owner = adjustedBeneficiaryLength[0];
_setDeadline();
+ } else if (adjustedBeneficiaryLength.length > 1) {
isInherited = true;
+ _setDeadline();
} else {
revert InvalidBeneficiaries();
}
}
function withdrawInheritedFunds(address _asset) external {
if (!isInherited) {
revert NotYetInherited();
}
+ address[] memory adjustedBeneficiaries =_filterBeneficiaries();
+ uint256 divisor = adjustedBeneficiaries.length;
if (_asset == address(0)) {
uint256 ethAmountAvailable = address(this).balance;
uint256 amountPerBeneficiary = ethAmountAvailable / divisor;
for (uint256 i = 0; i < divisor; i++) {
+ address payable beneficiary = payable(adjustedBeneficiaries[i]);
(bool success,) = beneficiary.call{value: amountPerBeneficiary}("");
require(success, "something went wrong");
}
} else {
uint256 assetAmountAvailable = IERC20(_asset).balanceOf(address(this));
uint256 amountPerBeneficiary = assetAmountAvailable / divisor;
for (uint256 i = 0; i < divisor; i++) {
+ IERC20(_asset).safeTransfer(adjustedBeneficiaries[i], amountPerBeneficiary);
}
}
}
}