You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Beneficiary: 0x12aD392BE0510b35E27348f2AB20723373d69F2b Submission hash (on-chain): 0x3c13b8d619f5a7dd5b4fd21bf27878afcc72c9239055d0cc067d60e54742e0a5 Severity: high
Description:
Finding description and impact
In LockingBase.sol, the getLock() function performs individual validations but misses the combined duration check:
// @bug - Missing validation of total lock duration (cliff + slope)// This allows creating locks with combined duration > MAX_TOTAL_DURATION (207 weeks)function getLock(uint96amount, uint32slopePeriod, uint32cliff) publicviewreturns (uint96lockAmount, uint96lockSlope) {
require(cliff >= minCliffPeriod, "cliff period < minimal lock period");
require(slopePeriod >= minSlopePeriod, "slope period < minimal lock period");
// Missing: require(cliff + slopePeriod <= MAX_CLIFF_PERIOD + MAX_SLOPE_PERIOD)
The contract validates cliff period (≤ 103 weeks) and slope period (≤ 104 weeks) separately, there's no validation of their combined duration against MAX_TOTAL_DURATION (207 weeks). A user could set cliff=103 and slope=104, which individually pass checks but sum to 207 weeks, and i think this violates the intended maximum lock duration constraint
Impact
gap in the locking mechanism that affects voting power calculations.
// @bug - Missing total duration validation allows exceeding max lock time// This enables creating locks with combined duration > MAX_TOTAL_DURATIONfunction getLock(uint96amount, uint32slopePeriod, uint32cliff) publicviewreturns (uint96lockAmount, uint96lockSlope) {
require(cliff >= minCliffPeriod, "cliff period < minimal lock period");
require(slopePeriod >= minSlopePeriod, "slope period < minimal lock period");
// Missing: require(cliff + slopePeriod <= MAX_TOTAL_DURATION)
propagates through multiple contracts:
In Locking.sol
// @bug - Propagates invalid durations to lock creationfunction lock(addressaccount, address_delegate, uint96amount, uint32slopePeriod, uint32cliff) externalreturns (uint256) {
// Calls getLock() without total duration validation
In LockingRelock.sol
// @bug - Allows relocking with invalid total durationfunction relock(uint256id, addressnewDelegate, uint96newAmount, uint32newSlopePeriod, uint32newCliff) externalreturns (uint256) {
// Missing total duration validation
In LockingVotes.sol
// @bug - Calculates voting power based on potentially invalid lock durationsfunction getVotes(addressaccount) externalviewreturns (uint256) {
// Uses potentially inflated lock durations
Github username: @0xbrett8571
Twitter username: 0xbrett8571
HATS Profile: HATS Profile
Beneficiary: 0x12aD392BE0510b35E27348f2AB20723373d69F2b
Submission hash (on-chain): 0x3c13b8d619f5a7dd5b4fd21bf27878afcc72c9239055d0cc067d60e54742e0a5
Severity: high
Description:
Finding description and impact
In LockingBase.sol, the getLock() function performs individual validations but misses the combined duration check:
The contract validates cliff period (≤ 103 weeks) and slope period (≤ 104 weeks) separately, there's no validation of their combined duration against MAX_TOTAL_DURATION (207 weeks). A user could set cliff=103 and slope=104, which individually pass checks but sum to 207 weeks, and i think this violates the intended maximum lock duration constraint
Impact
gap in the locking mechanism that affects voting power calculations.
propagates through multiple contracts:
In Locking.sol
In LockingRelock.sol
In LockingVotes.sol
System Architecture Impact
The fundamental issue stems from incomplete validation in the base locking mechanism. While individual period checks exist
Proof of Concept
Recommended mitigation steps
In LockingBase.sol
In LockingRelock.sol:
The text was updated successfully, but these errors were encountered: