Description: An incorrect array element deletion is used to remove a beneficiary in InheritanceManager::removeBeneficiary. When delete is called on an indexed array element in InheritanceManager::beneficiaries, the array element at that index is set to its default. In this case, an address array has its element set to address(0). Also the array length remains the same and is not decremented. The result is instead of deleting a beneficiary, a beneficiary's address is changed to address(0).
Impact: If the owner calls InheritanceManager::removeBeneficiary to remove a beneficiary, a future call to withdraw ether withInheritanceManager::withdrawInheritedFunds leads to ether being sent to that "removed" beneficiary at address(0). That ether is burned and lost.
Proof of Concept:
Add the following unit test to InheritanceManagerTest.t.sol:
Run the unit test with verbosity: forge test --mt test_removeBeneficiaryLossOfFunds -vvvv
Further verification is in the stack trace with the 3rd beneficiary having ether sent to address 0x0000000000000000000000000000000000000000 :
Recommended Mitigation:
The proper way to delete an array element is with the "swap and pop":
Take the last element in the array and copy to the position of the element to be removed.
Remove the last element with with a pop(). This also decreases the array length by 1.
Add the "swap and pop" to InheritanceManager::removeBeneficiary for proper deletion:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.