Time-Locks

Time-locks prevent immediate execution of proposals, giving the community time to review and respond.

What is a Time-Lock?

A time-lock is a mandatory delay between when a proposal succeeds and when it can be executed. This provides:

  • Security window - Time to detect malicious proposals
  • Community response - Opportunity to exit or respond
  • Cooling period - Prevent rash execution of changes

Time-Lock Duration by Tier

TierTime-LockDuration
Platinum24 hours1 day
Gold48 hours2 days
Silver72 hours3 days
Bronze168 hours7 days
Unscored336 hours14 days

Implementation

impl ReputationTier {
    pub fn time_lock_seconds(&self) -> i64 {
        match self {
            ReputationTier::Platinum => TIME_LOCK_PLATINUM,   // 24 hours
            ReputationTier::Gold => TIME_LOCK_GOLD,           // 48 hours
            ReputationTier::Silver => TIME_LOCK_SILVER,       // 72 hours
            ReputationTier::Bronze => TIME_LOCK_BRONZE,       // 7 days
            ReputationTier::Unscored => TIME_LOCK_DEFAULT,    // 14 days
        }
    }
}

Time-Lock Calculation

The time-lock is determined by the proposer’s tier:

// In create_proposal
let time_lock = proposer.tier.time_lock_seconds();
let voting_end = clock.unix_timestamp + config.voting_period;
 
proposal.time_lock_expiry = voting_end + time_lock;

Timeline Example

For a Gold member creating a standard proposal with a 7-day voting period:

Day 0   → Proposal created, voting starts
Day 7   → Voting ends
        → If succeeded, time-lock starts
Day 9   → Time-lock expires (48 hours)
        → Proposal can be executed

Execution Requirements

pub fn execute_proposal(ctx: Context<ExecuteProposal>) -> Result<()> {
    let proposal = &mut ctx.accounts.proposal;
    let clock = Clock::get()?;
 
    // Proposal must have succeeded
    require!(
        proposal.state == ProposalState::Succeeded,
        CredDAOError::ProposalVotingActive
    );
 
    // Time-lock must have expired
    require!(
        clock.unix_timestamp >= proposal.time_lock_expiry,
        CredDAOError::TimeLockNotExpired
    );
 
    proposal.state = ProposalState::Executed;
    proposal.executed_at = Some(clock.unix_timestamp);
 
    Ok(())
}

Why Tier-Based Time-Locks?

Trusted Members (Platinum)

  • Proven track record
  • Higher community trust
  • Shorter delays acceptable
  • 24-hour time-lock

New Members (Unscored)

  • Limited history
  • Higher risk profile
  • Maximum scrutiny needed
  • 14-day time-lock

Checking Time-Lock Status

const proposal = await client.getProposal(proposalAddress);
const now = Math.floor(Date.now() / 1000);
const timeLockExpiry = proposal.timeLockExpiry.toNumber();
 
if (proposal.state === 'succeeded') {
  if (now >= timeLockExpiry) {
    console.log('Ready to execute!');
  } else {
    const remaining = timeLockExpiry - now;
    const hours = Math.floor(remaining / 3600);
    console.log(`Time-lock expires in ${hours} hours`);
  }
}

Emergency Proposals

Warning:

Even emergency proposals from Platinum members have a 24-hour time-lock. This is the minimum security window in CredDAO.

Time-Lock Constants

pub const TIME_LOCK_PLATINUM: i64 = 24 * 60 * 60;    // 86,400 seconds
pub const TIME_LOCK_GOLD: i64 = 48 * 60 * 60;        // 172,800 seconds
pub const TIME_LOCK_SILVER: i64 = 72 * 60 * 60;      // 259,200 seconds
pub const TIME_LOCK_BRONZE: i64 = 168 * 60 * 60;     // 604,800 seconds
pub const TIME_LOCK_DEFAULT: i64 = 336 * 60 * 60;    // 1,209,600 seconds