[SIP3.20] Wind-down SUMR lock buckets and sunset the early-unstake penalty

Connected RFC: [RFC] Operational Realignment for the Transition Period


1. Overview:

Reconfigure SUMR Staking V2 so the lockup system winds down cleanly, in two governor-only parameter changes:

  1. NoLockup bucket cap → type(uint256).max (uncapped); staking remains fully open at the no-lockup tier.
  2. All six lockup bucket caps → 0 (disabled); no new lockups of any duration can be created.
  3. updatePenaltyEnabled(false) → the early-unstake penalty no longer applies, so existing lockers can exit without a fee.

No existing stake is closed, moved, or altered by this proposal, and no voting power is confiscated. Staking stays open, so governance participation is preserved.


2. Motivation:

[RFC] Operational Realignment for the Transition Period (A2) set out the case for ending the SUMR Staking V2 reward programs: SUMR emissions run to periodFinish and are not renewed, and the USDC revenue share is discontinued. It also stated the fairness principle this SIP implements, that the early-unstake penalty should be waived first, so lockers are not trapped between an unrewarded lock and a penalized exit. Poll A2.2 carried a separate signal on exactly that.

The bucket change applies the same logic one step earlier in the lifecycle. A lockup is a bilateral bargain: the staker forgoes liquidity for up to three years, and the DAO compensates that with a quadratic reward multiplier funded by emissions and revenue share. With both sides of that compensation ending, continuing to issue new lockups would bind users into commitments the DAO has already decided not to pay for. Disabling those buckets stops new entrants taking the trade; uncapping NoLockup keeps staking, delegation and voting fully available.


3. Specification:

3.1 Parameters

Parameter Value
Contract SummerStaking0xcA2e14c7C03C9961c296C89e2d2279F5F7DB15b4
Network Base
Related StakedSummerToken (stSUMR) 0x7cC488F2681cFC2A5E8A00184bfA94ea6d520D1c
Authority onlyGovernor → executes via SummerTimelockController 0x447BF9d1485ABDc4C1778025DfdfbE8b894C3796
Execution Base governor → Timelock (direct on Base hub, no LayerZero relay)
Calls 7 × updateLockupBucketCap + 1 × updatePenaltyEnabled = 8
Risk level Low technically; the material consideration is governance/quorum (§4)

3.2 Calls

Function signatures, verified:

function updateLockupBucketCap(Bucket _bucket, uint256 _newCap) external onlyGovernor;
function updatePenaltyEnabled(bool _penaltyEnabled) external onlyGovernor;

Bucket enum values, verified in order:

# Bucket Lockup range New cap Effect
0 NoLockup 0 seconds type(uint256).max Uncapped — staking stays fully open
1 ShortTerm 1 second – 14 days 0 Disabled (already 0 by default)
2 TwoWeeksToThreeMonths >14 – 90 days 0 Disabled
3 ThreeToSixMonths >90 – 180 days 0 Disabled
4 SixToTwelveMonths >180 – 365 days 0 Disabled
5 OneToTwoYears >365 – 730 days 0 Disabled
6 TwoToThreeYears >730 – 1095 days 0 Disabled

updatePenaltyEnabled(false) — disables the early-unstake penalty.

type(uint256).max = 115792089237316195423570985008687907853269984665640564039457584007913129639935 (0xff…ff, 32 bytes).

Cap semantics are explicit in the contract: cap == 0 disables a bucket (any positive stake reverts with Staking_BucketCapExceeded); cap == type(uint256).max means unlimited.

3.3 Verified effects

  • Existing stakes are untouched. Bucket caps are enforced only on the stake path (_stakeLockup_wouldExceedBucketCap → revert). updateLockupBucketCap writes bucketData[_bucket].cap and emits LockupBucketUpdated; it does not iterate positions, alter lockupEndTime, or move tokens. Setting a cap to 0 blocks new entries and does nothing to existing ones.
  • Voting power is not affected by bucket choice. stSUMR is minted 1:1 on the raw staked amount. The quadratic multiplier (WEIGHTED_STAKE_BASE + WEIGHTED_STAKE_COEFFICIENT × t²) applies to the weighted balance that drives rewards accounting only - bucket caps are applied to the unweighted amount. Since StakedSummerToken is the ERC20Votes token, a staker’s governance weight is their raw stake regardless of lockup tier. Disabling lockup buckets therefore does not change anyone’s voting power.
  • Penalty disablement is a clean boolean. penaltyEnabled = false makes calculatePenaltyPercentage return 0. The penalty is not burned - _handleTokenTransfersOnUnstake sends the penalty to treasury(). Disabling it means early exits no longer route a fee to the treasury.
  • Penalty being removed, for the record: fixed 2% if remaining lockup < FIXED_PENALTY_PERIOD (110 days), otherwise linear timeRemaining / MAX_LOCKUP_PERIOD × 20%, i.e. up to 20% at three years. After lockup ends, and for NoLockup, the penalty is already 0.
  • Reversible. Both setters are governor-callable in either direction; a later SIP can restore caps or re-enable the penalty.

4. Risk Assessment:

Technical: low. Two governor-only setters on one contract, on one chain, no relay. No funds move, no roles granted, no positions closed, no user action required. Failure mode is a revert. Guardian pre-review of decoded calldata.

Governance/quorum: Voting power under Governance V2 is stSUMR, so it is unaffected by bucket changes. Removing the penalty gives every locked staker an unpenalized exit at once, and with rewards ending there is little reason to stay. A large voluntary exit would reduce total stSUMR and therefore quorum.

Economic. Unpenalized exits may increase circulating SUMR and create sell pressure, and the DAO treasury is heavily SUMR-weighted. The treasury also forgoes future penalty income (which, with rewards ending, is a fee charged on people leaving a program the DAO has itself discontinued). Both are foreseeable consequences of the fairness decision rather than arguments against it.

Conflict of interest. Delegates voting on this are voting on terms affecting their own staked positions and voting weight. Worth stating on the record, as RFC did for delegate compensation.


5. Voting:

If YES - set the NoLockup bucket cap to type(uint256).max, set all six lockup bucket caps to 0, and call updatePenaltyEnabled(false), per the decoded calldata published in this thread.

If NO - leave the staking bucket configuration and early-unstake penalty as they are.


Tagging @Recognized_Delegates for a checkup as always.

–jensei

1 Like

Hey @jensei, with no lock-up required, but staking remaining open in the NoLockup bucket, wouldn’t this technically create a much bigger surface for a governance attack on the protocol?

1 Like

hey @Sixty, this is a very fair comment and indeed there is a potential for this. At the same time in a way, even with the penalty and different buckets anyone was able to unstake / stake to influence their voting power.

I think the main defenses remain fairly strong:

  1. timestamp-snapshot voting (so no single-block flash attack)
  2. proposalThreshold (dependent on SUMR price, atm very low: 100,000 SUMR =~ $10)
  3. the timelock delays, and
  4. the Guardian module’s ability to cancel.
1 Like