The buyOutEstateNFT function has critical flaws in its payment distribution logic, leading to financial loss, unfair settlements, and protocol instability. Here’s a breakdown of the risks and their implications:
Code Snippet:
** Key Issues and Impacts**
Problem: If the calling beneficiary is found in the loop, the function exits immediately with return, skipping all subsequent beneficiaries.
Example:
Beneficiaries: [Alice, Bob, Carol].
Alice calls buyOutEstateNFT.
The loop checks i=0 (Alice), triggers return, and exits.
Result: Bob and Carol receive nothing, even though Alice paid for the NFT.
Formula Flaw: The finalAmount calculation (value / divisor) * multiplier is correct, but the distribution logic is broken:
finalAmount / divisor is sent to each beneficiary except the caller.
Example: value = 100, divisor = 3 → finalAmount = 66.
Each beneficiary should get 22 (66 / 3), but the loop skips payments due to the early return.
Dust Accumulation: The truncated value / divisor leaves residual funds locked in the contract (e.g., 100 - 66 = 34 in the example above).
Risk: These funds are permanently lost, violating the protocol’s promise of fair distribution.
Problem: The NFT is burned (nft.burnEstate(_nftID)) even if payments to beneficiaries are incomplete.
Impact: The real-world asset’s on-chain representation is destroyed, but beneficiaries may not have received their fair share.
Attack Scenarios
Setup:
Beneficiaries: [Alice, Bob, Carol].
NFT value: 100 USDC.
Action: Alice calls buyOutEstateNFT.
Result:
Alice pays 66 USDC (2/3 of 100).
Loop exits immediately (Alice is first in the array).
Bob and Carol receive 0 USDC.
NFT is burned.
Profit for Alice: She effectively buys the NFT for 66 USDC instead of the intended 66 USDC split between Bob and Carol.
Scenario 2: Dust Accumulation
Setup:
Beneficiaries: [Alice, Bob].
NFT value: 101 USDC.
Action: Alice calls buyOutEstateNFT.
Result:
finalAmount = (101 / 2) * 1 = 50 USDC.
Alice pays 50 USDC.
Loop skips Bob (due to return), so Bob gets 0 USDC.
Residual 51 USDC (101 - 50) is locked forever.
Impact:
Legitimate beneficiaries receive nothing or less than owed, violating the protocol’s core promise of fair distribution.
Trust in the system erodes if users observe funds being burned or unevenly distributed.
Burning the NFT before completing payouts creates mismatches between on-chain and real-world ownership.
Fixing the Issue
returnEnsure the loop processes all beneficiaries:
Add the remainder to the last beneficiary’s share:
Ensure the NFT is burned only after all transfers succeed:
By fixing the loop logic and residual handling, the protocol ensures fair payouts and consistent state management.
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.