Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

govstaking/src/extensions/GovernanceStakerDelegateSurrogateVotes.sol #29

Open
wants to merge 1 commit into
base: base
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions GovernanceStakerDelegateSurrogateVotes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.23;

import {DelegationSurrogate} from "src/DelegationSurrogate.sol";
import {DelegationSurrogateVotes} from "src/DelegationSurrogateVotes.sol";
import {GovernanceStaker} from "src/GovernanceStaker.sol";
import {IERC20Delegates} from "src/interfaces/IERC20Delegates.sol";

/// @title GovernanceStakerDelegateSurrogateVotes
/// @author [ScopeLift](https://scopelift.co)
/// @notice This contract extension adds delegation surrogates to the GovernanceStaker base
/// contract, allowing staked tokens to be delegated to a specific delegate.
abstract contract GovernanceStakerDelegateSurrogateVotes is GovernanceStaker {
/// @notice Emitted when a surrogate contract is deployed.
event SurrogateDeployed(address indexed delegatee, address indexed surrogate);

/// @notice Maps the account of each governance delegate with the surrogate contract which holds
/// the staked tokens from deposits which assign voting weight to said delegate.
mapping(address delegatee => DelegationSurrogate surrogate) private storedSurrogates;

/// @notice Thrown if an inheritor uses a seperate staking token.
error GovernanceStakerDelegateSurrogateVotes__UnauthorizedToken();

constructor(IERC20Delegates _votingToken) {
if (address(STAKE_TOKEN) != address(_votingToken)) {
revert GovernanceStakerDelegateSurrogateVotes__UnauthorizedToken();
}
}

/// @inheritdoc GovernanceStaker
function surrogates(address _delegatee) public view override returns (DelegationSurrogate) {
return storedSurrogates[_delegatee];
}

/// @inheritdoc GovernanceStaker
function _fetchOrDeploySurrogate(address _delegatee)
internal
virtual
override
returns (DelegationSurrogate _surrogate)
{
_surrogate = storedSurrogates[_delegatee];

if (address(_surrogate) == address(0)) {
_surrogate = new DelegationSurrogateVotes(IERC20Delegates(address(STAKE_TOKEN)), _delegatee);
storedSurrogates[_delegatee] = _surrogate;
emit SurrogateDeployed(_delegatee, address(_surrogate));
}
}
}