Delegation

Delegation is a core feature of Summer Protocol that allows token holders to assign their voting power to other addresses while maintaining ownership of their tokens. This system includes innovative decay mechanics that encourage active participation in governance.

How Delegation Works

When you delegate your voting power, you maintain full ownership and control of your tokens while granting your voting rights to another address. The delegate can vote with the combined voting power, but cannot transfer or use your tokens in any other way.

Your voting power decays over time unless you actively participate in governance or delegate to active participants. The decay starts after a decay-free window (initially set between 30-365 days) and can follow either a linear or exponential pattern.

Important Delegation Rules

Delegation chains are limited to a maximum depth of 2 to maintain system efficiency. For example:

  • Valid: Alice → Bob → Charlie

  • Invalid: Alice → Bob → Charlie → David (voting power decays to 0)

The decay factor affects both your direct voting power and any voting power delegated to you. By being an active governance participant or delegating to one, you help maintain the voting power of your tokens.

Tips for Effective Delegation

Choose delegates who actively participate in governance to minimize decay. Monitor your voting power through the governance interface and consider updating your delegation if your current delegate becomes inactive.

Core Functions

function delegate(address delegatee) public updateDecay(_msgSender()) onlyHubChain {
    if (delegatee != address(0) && !decayState.hasDecayInfo(delegatee)) {
        decayState.initializeAccount(delegatee);
    }
    super.delegate(delegatee);
}

The delegate function runs on the hub chain only and handles delegation setup:

  • Updates caller's decay factor via updateDecay modifier

  • Sets up decay tracking for new delegatees

  • Records delegation via parent ERC20Votes contract

function getVotes(address account) public view returns (uint256) {
    uint256 rawVotingPower = super.getVotes(account);
    return decayState.getVotingPower(account, rawVotingPower, _getDelegateTo);
}

getVotes calculates total voting power by:

  • Getting base voting power (tokens + staked + vesting)

  • Applying decay factor through delegation chain

  • Using _getDelegateTo to traverse delegation links

function getDelegationChainLength(address account) external view returns (uint256) {
    return decayState.getDelegationChainLength(account, _getDelegateTo);
}

getDelegationChainLength tracks delegation depth:

  • Recursively follows delegation chain

  • Stops at MAX_DELEGATION_DEPTH (2)

  • Returns 0 for null/self-delegations

function getDecayFactor(address account) external view returns (uint256) {
    return decayState.getDecayFactor(account, _getDelegateTo);
}

getDecayFactor manages decay calculations:

  • Follows delegation chain to proper decaying account

  • Returns WAD (1e18) during decay-free window

  • Applies decay math after window expires

This creates a system where voting power can flow through delegation while maintaining decay pressure for inactive accounts.

Last updated

Was this helpful?