Category: Business Logic
Unable to unlock milestone
High Severity
Medium Impact
Medium Likelihood
Description
In the function confirmMilestone, the milestone award is unlocked and added to milestoneUnlockedTotal, allowing the grantee to withdraw the milestone award. However, if milestone.unlockOnCompletion is false, the milestone remains locked, and there is no alternative method to unlock it.
function confirmMilestone(uint256 _milestoneIndex) external nonReentrant {
if(terminated) revert MetaVesT_AlreadyTerminated();
Milestone storage milestone = milestones[_milestoneIndex];
if (_milestoneIndex >= milestones.length || milestone.complete)
revert MetaVesT_MilestoneIndexCompletedOrDoesNotExist();
//encode the milestone index to bytes for signature verification
bytes memory _data = abi.encodePacked(_milestoneIndex);
// perform any applicable condition checks, including whether 'authority' has a signatureCondition
for (uint256 i; i < milestone.conditionContracts.length; ++i) {
if (!IConditionM(milestone.conditionContracts[i]).checkCondition(address(this), msg.sig, _data))
revert MetaVesT_ConditionNotSatisfied();
}
milestone.complete = true;
milestoneAwardTotal += milestone.milestoneAward;
if(milestone.unlockOnCompletion)
milestoneUnlockedTotal += milestone.milestoneAward;
emit MetaVesT_MilestoneCompleted(grantee, _milestoneIndex);
}Impact
The grantee cannot get the milestone award if it is not unlocked in the function confirmMilestone.
Recommendations
Consider implementing a method to unlock a completed milestone.
Remediation
This issue has been acknowledged by MetaLeX Labs, Inc, and a fix was implemented in commit c1f26e06↗.