Submitted by hickuphh3, also found by 0xRajeev
A host of problems arise from the L110-113 of the claimForMember() function, where _claimable is deducted from the bondedLP balance before the condition check, when it should be performed after (or the condition is changed to checking if the remaining bondedLP balance to zero).
1. Permanently Locked Funds
If a user claims his bonded LP asset by calling dao.claimForMember(), or a malicious attacker helps a user to claim by calling dao.claimAllForMember(), either which is done such that _claimable is exactly half of his remaining bondedLP funds of an asset, then the other half would be permanently locked.
2. Claim Rate Never Zeroes For Final Claim
On the flip side, should a user perform a claim that enables him to perform a full withdrawal (ie. _claimable = mapBondAsset_memberDetails[asset].bondedLP[member], we see the following effects:
Thankfully, subsequent behavior remains as expected since calcBondedLP returns zero as claimAmount is set to the members bondedLP balance (which is zero after a full withdrawal).
The _claimable deduction should occur after the condition check. Alternatively, change the condition check to if (mapBondAsset_memberDetails[asset].bondedLP[member] == 0).
verifyfirst (Spartan) confirmed:
