The issue is that saveProfit() reads and updates global state (totalProfit and lastProfit) without proper synchronization. When multiple users claim simultaneously:
User1 reads totalProfit = X
User2 reads totalProfit = X
User1 updates lastProfit[user1] = X
User2 updates lastProfit[user2] = X
This can lead to double-counting of profits.
The profit distribution system uses shared state variables (totalProfit and lastProfit) without proper synchronization mechanisms. When multiple users claim simultaneously, they can read the same totalProfit value before their respective lastProfit values are updated, leading to profit calculation inconsistencies.
The vulnerability originates from the fundamental design of the profit distribution system in MembershipERC1155.sol. The core issue stems from three key architectural decisions:
Shared State Management: https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/tokens/MembershipERC1155.sol#L26-L28
These global state variables are accessed and modified without atomic operations.
Profit Calculation Logic: https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/tokens/MembershipERC1155.sol#L182-L187
The calculation relies on reading global state (totalProfit) and updating user-specific state (lastProfit) in separate operations.
Non-Atomic Claim Process: https://github.com/Cyfrin/2024-11-one-world/blob/1e872c7ab393c380010a507398d4b4caca1ae32b/contracts/dao/tokens/MembershipERC1155.sol#L144-L150
The claim process spans multiple state changes without transaction-level atomicity.
This design creates a race condition where multiple users claiming simultaneously can read the same totalProfit value before individual lastProfit values are updated, leading to profit calculation inconsistencies. The vulnerability is inherent in the contract's architecture rather than a simple coding error.
Consider this attack Scenario Initial State
Total profits: 1000 tokens
Alice and Bob each hold 50% of shares
Expected claim: 500 tokens each
Attack Flow
Result:
Alice receives 500 tokens
Bob receives 500 tokens
Total distributed: 1000 tokens (200% of intended amount)
// Add snapshot mechanism to ensure consistent profit calculations across simultaneous claims
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.