The buyOutEstateNFT function contains a flawed calculation for distributing payments among beneficiaries, leading to unequal and incorrect payouts. The formula (value / divisor) * multiplier (where divisor is the number of beneficiaries and multiplier is beneficiaries.length - 1) does not correctly split the NFT’s value, causing some beneficiaries to receive less than their fair share and leaving funds stuck in the contract due to rounding and logic errors.
The vulnerable code is in the buyOutEstateNFT function:
solidity
Issues:
Incorrect Payment Calculation:
finalAmount = (value / divisor) * multiplier computes the total amount the caller pays, where value is the NFT’s worth (e.g., 60e6 USDC), divisor is the number of beneficiaries (e.g., 3), and multiplier is beneficiaries.length - 1 (e.g., 2).
Example: For value = 60e6, divisor = 3, multiplier = 2:
finalAmount = (60e6 / 3) * 2 = 20e6 * 2 = 40e6.
This suggests the caller pays 40e6 USDC, but the intent seems to be that each of the other beneficiaries (2 in this case) receives a fair share of the NFT’s value.
Uneven Distribution:
The payout to each non-caller beneficiary is finalAmount / divisor:
40e6 / 3 = 13,333,333 USDC (with integer division).
With 3 beneficiaries, only 2 receive payouts (due to the return for the caller), so total distributed = 13,333,333 * 2 = 26,666,666.
The caller pays 40e6, but only 26,666,666 is distributed, leaving 40e6 - 26,666,666 = 13,333,334 USDC stuck in the contract.
Logic Flaw:
The NFT’s value (60e6) should ideally be split equally among the non-caller beneficiaries (e.g., 30e6 each for 2 others with 3 total), but the calculation underestimates this.
The early return prevents proper iteration, and the burn happens even if distribution is incomplete.
POC
Test Evidence/Result:
From the test test_buyOutEstateNFTWrongCalculaion:
Initial State: 3 beneficiaries (user1, user2, user3), NFT value = 60e6 USDC.
Post-Execution (user3 calls):
user3 balance: 20e6 (60e6 - 40e6 paid).
user2 balance: 13,333,333.
user1 balance: 13,333,333.
contract balance: 13,333,334.
Expected: Each non-caller (user1, user2) should receive 30e6 (half of 60e6), totaling 60e6 paid by user3, with 0 remaining in the contract.
Actual: Incorrect payouts and 13,333,334 USDC stuck.
Funds Stuck: Approximately 1/3 of the payment (13,333,334 USDC in the test) remains in the contract, inaccessible without additional withdrawal mechanisms.
Unequal Distribution: Beneficiaries receive less than their fair share (13,333,333 vs. 30e6 expected), violating the intent of equitable buyout.
Financial Loss: The caller overpays relative to what’s distributed, and stuck funds reduce the contract’s usability.
Trust Issue: Incorrect payouts undermine confidence in the inheritance system.
Manual Review and Foundry
Correct the calculation to ensure the caller pays the full NFT value, equally distributed to other beneficiaries:
solidity
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.