Skip to content

Commit

Permalink
feat: add change delegate
Browse files Browse the repository at this point in the history
  • Loading branch information
agusduha committed Jan 5, 2024
1 parent bb0fa27 commit 0f19e39
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
75 changes: 75 additions & 0 deletions solidity/contracts/governance/utils/WonderVotes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,45 @@ abstract contract WonderVotes is Context, EIP712, Nonces, IERC6372, IWonderVotes
emit DelegateSuspended(msg.sender, suspend);
}

/**
* @dev Renounce all of the sender's delegations for a given `account` and `proposalType`.
*
* Renouncing means leaving the delegation to the voting units owner.
*
* Only the delegate can call this function.
*/
function renounceDelegation(
address account,
uint8 proposalType
) public virtual validProposalType(proposalType) onlyDelegate(account, proposalType) {
_changeDelegate(account, proposalType, _msgSender(), account);
}

/**
* @dev Migrate all of the sender's delegations for a given `account` and `proposalType` to a `newDelegatee`.
*
* Only the delegate can call this function.
*/
function migrateDelegation(
address account,
uint8 proposalType,
address newDelegatee
) public virtual validProposalType(proposalType) onlyDelegate(account, proposalType) activeDelegate(newDelegatee) {
_changeDelegate(account, proposalType, _msgSender(), newDelegatee);
}

/**
* @dev Migrate the sender delegation for a given `proposalType` to a `newDelegatee`.
*/
function changeDelegation(
uint8 proposalType,
address oldeDelegatee,
address newDelegatee
) public virtual validProposalType(proposalType) activeDelegate(newDelegatee) {
address account = _msgSender();
_changeDelegate(account, proposalType, oldeDelegatee, newDelegatee);
}

/**
* @dev Delegate all of `account`'s voting units to `delegatee`.
*
Expand Down Expand Up @@ -291,6 +330,35 @@ abstract contract WonderVotes is Context, EIP712, Nonces, IERC6372, IWonderVotes
_moveDelegateVotes(proposalType, _oldDelegates, delegatees, _getVotingUnits(account));
}

/**
* @dev Changes the delegation of `account`'s voting units from `oldDelegate` to `newDelegate`.
*/
function _changeDelegate(
address account,
uint8 proposalType,
address oldDelegate,
address newDelegate
) internal virtual {
DelegateSet.Set storage _delegateesSet = _delegatees[account][proposalType];

Delegate[] memory _oldDelegates = _delegateesSet.values();

uint256 _weight = _delegateesSet.get(oldDelegate).weight;

_delegateesSet.remove(oldDelegate);

if (_delegateesSet.contains(newDelegate)) {
_delegateesSet.get(newDelegate).weight += _weight;
} else {
_delegateesSet.add(Delegate({account: newDelegate, weight: _weight}));
}

Delegate[] memory _newDelegates = _delegateesSet.values();

emit DelegateChanged(account, proposalType, _oldDelegates, _newDelegates);
_moveDelegateVotes(proposalType, _oldDelegates, _newDelegates, _getVotingUnits(account));
}

/**
* @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`
* should be zero. Total supply of voting units will be adjusted with mints and burns.
Expand Down Expand Up @@ -424,4 +492,11 @@ abstract contract WonderVotes is Context, EIP712, Nonces, IERC6372, IWonderVotes
}
_;
}

modifier onlyDelegate(address account, uint8 proposalType) {
address _delegateAccount = _msgSender();
bool isDelegate = _delegatees[account][proposalType].contains(_delegateAccount);
if (!isDelegate) revert VotesNotDelegate(_delegateAccount);
_;
}
}
5 changes: 5 additions & 0 deletions solidity/interfaces/governance/utils/IWonderVotes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ interface IWonderVotes {
*/
error VotesDuplicatedDelegate(address account);

/**
* @dev The account is not a delegate.
*/
error VotesNotDelegate(address account);

/**
* @dev The weight set for a delegate is zero.
*/
Expand Down

0 comments on commit 0f19e39

Please sign in to comment.