The InheritanceManager contract contains a critical vulnerability in the onlyBeneficiaryWithIsInherited modifier. The modifier implements a while loop that can access an index beyond the boundaries of the beneficiaries array, leading to consistent out-of-bounds access that will revert all transactions using this modifier.
The problematic code is in the onlyBeneficiaryWithIsInherited modifier:
The vulnerability exists because:
The loop condition allows i to reach the value of beneficiaries.length
When i == beneficiaries.length, the code attempts to access beneficiaries[i]
This access is out-of-bounds as arrays in Solidity are 0-indexed (valid indices are 0 to length-1)
This will cause a runtime error and revert the transaction
What makes this issue particularly severe is that it will always occur for non-beneficiary addresses or when isInherited is false, rendering the modifier and all functions using it completely unusable.
The impact of this vulnerability is severe:
Complete Function Failure: All functions using this modifier will always revert for non-beneficiary callers or when isInherited is false
Denial of Service: Beneficiaries cannot access their inheritance even after the inheritance condition is met
Locked Funds: Assets controlled by functions protected by this modifier become permanently inaccessible
Broken Access Control: The actual access control logic never executes correctly
Failed Inheritance Process: The core purpose of the contract - managing inheritance - is compromised
The issue can be demonstrated with the following execution path:
Initialize i = 0
Check loop condition: 0 < beneficiaries.length + 1 is true
If the caller is not a beneficiary or isInherited is false, the if condition fails
Increment i to 1 and loop continues
This repeats until i == beneficiaries.length
At this point, the code attempts to access beneficiaries[beneficiaries.length]
This access is out-of-bounds and causes a revert
The function never executes its body
This means the modifier will revert for all non-beneficiary addresses and will not correctly enforce the access control it was designed for.
The fix is straightforward - correct the loop condition to prevent out-of-bounds access:
This implementation:
Uses a correctly bounded for loop to iterate through beneficiaries
Sets a flag when an authorized caller is found
Explicitly reverts with an informative message if no match is found
Prevents out-of-bounds access entirely
Solidity documentation on arrays: Arrays in Solidity are 0-indexed
Common Smart Contract Vulnerabilities: Out-of-bounds array access
The Solidity compiler does not prevent out-of-bounds access at compile time, it's a runtime error
OpenZeppelin's AccessControl pattern demonstrates safer approaches to access control
Immediate Fix: Implement the remediation above to prevent out-of-bounds access
Refactor for Gas Efficiency: Consider refactoring to use a mapping for beneficiary lookups instead of array iteration
Input Validation: Add explicit checks that prevent operations with invalid array indices
Testing: Add comprehensive tests for edge cases in access control logic
Access Control Patterns: Consider using established access control libraries like OpenZeppelin's AccessControl
Error Messages: Add informative error messages to aid in debugging and improve user experience
Formal Verification: Consider using formal verification tools to mathematically prove the absence of such issues
The vulnerability represents a complete modifier failure that renders protected functions unusable and potentially locks funds in the contract. It should be addressed immediately before deployment.
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.