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

Whitelisted proposers #108

Merged
merged 31 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ae0019d
Remove unnecessary code in a test
adamgall Oct 2, 2024
73db7fa
Update MockHats to actually track wearers of Hats
adamgall Oct 2, 2024
84e4312
Update IHats interface and Mock to implement isWearerOfHat convenienc…
adamgall Oct 2, 2024
d6ceda2
Create new contract LinearERC20VotingExtensible
adamgall Oct 2, 2024
88e89d7
Create a new Strategy which is based off of LinearERC20Voting, but mo…
adamgall Oct 2, 2024
1e96d39
Require at least one whitelisted hat upon creation
adamgall Oct 7, 2024
b79b43f
Add comments
adamgall Oct 7, 2024
8d9b4d8
Add new strategy for ERC721 voting but Hats proposal creation
adamgall Oct 7, 2024
73f5ad8
Extract HatsProposalCreationWhitelist code into own contract, and inh…
adamgall Oct 7, 2024
ee48e3d
Move HatsProposalCreationWhitelist tests to own file using new specif…
adamgall Oct 8, 2024
7a1605a
Create test for new LinearERC721VotingWithHatsProposals
adamgall Oct 8, 2024
51c539e
Undo changes to IHats interface, so as to not create changes in Decen…
adamgall Oct 9, 2024
e1fd7d7
Copy in the FULL Hats interface(s) and use those in HatsProposalCreat…
adamgall Oct 9, 2024
ccf08fa
Create deployment scripts for two new strategies
adamgall Oct 9, 2024
095bafc
Move new Hats interfaces into new "full" directory
adamgall Oct 9, 2024
821b4ba
Merge branch 'develop' into whitelisted-proposers
adamgall Oct 9, 2024
c10803f
Deployment to Sepolia
mudrila Oct 23, 2024
fc25431
Merge branch 'develop' into whitelisted-proposers
adamgall Nov 1, 2024
2837bb2
Fix deployment script names
adamgall Nov 1, 2024
22b9dba
Lint and pretty
adamgall Nov 1, 2024
4232195
Move new strategy contracts into a new strategy directory
adamgall Nov 5, 2024
298db7e
Remove "full" hats interface subdir which was accidentally added back
adamgall Nov 5, 2024
72a3400
Remove deployment artifacts from this branch
adamgall Nov 5, 2024
21d2c4b
Fix typo
adamgall Nov 5, 2024
57a5e6e
Merge branch 'develop' into whitelisted-proposers
adamgall Nov 5, 2024
8b4b568
Merge branch 'develop' into whitelisted-proposers
adamgall Nov 6, 2024
93c0a97
Update new deployment script file numbers
adamgall Nov 6, 2024
436d899
Implement some simplification in HatsProposalCreationWhitelist
adamgall Nov 6, 2024
e6e0bd1
Add tests to confirm only owner can whitelist hats
adamgall Nov 6, 2024
f0d0acd
Add more tests to confirm non-owner cannot remove hat from whitelist
adamgall Nov 6, 2024
3992445
Already had these tests!
adamgall Nov 6, 2024
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
119 changes: 119 additions & 0 deletions contracts/azorius/HatsProposalCreationWhitelist.sol
adamgall marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: MIT
pragma solidity =0.8.19;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IHats} from "../interfaces/hats/full/IHats.sol";

abstract contract HatsProposalCreationWhitelist is OwnableUpgradeable {
event HatWhitelisted(uint256 hatId);
event HatRemovedFromWhitelist(uint256 hatId);

IHats public hatsContract;

/** Array to store whitelisted Hat IDs. */
uint256[] public whitelistedHatIds;

error InvalidHatsContract();
error NoHatsWhitelisted();
error HatAlreadyWhitelisted();
error HatNotWhitelisted();

/**
* Sets up the contract with its initial parameters.
*
* @param initializeParams encoded initialization parameters:
* `address _hatsContract`, `uint256[] _initialWhitelistedHats`
*/
function setUp(bytes memory initializeParams) public virtual {
(address _hatsContract, uint256[] memory _initialWhitelistedHats) = abi
.decode(initializeParams, (address, uint256[]));

if (_hatsContract == address(0)) revert InvalidHatsContract();
hatsContract = IHats(_hatsContract);

if (_initialWhitelistedHats.length == 0) revert NoHatsWhitelisted();
for (uint256 i = 0; i < _initialWhitelistedHats.length; i++) {
_whitelistHat(_initialWhitelistedHats[i]);
}
}

/**
* Adds a Hat to the whitelist for proposal creation.
* @param _hatId The ID of the Hat to whitelist
*/
function whitelistHat(uint256 _hatId) external onlyOwner {
_whitelistHat(_hatId);
}

/**
* Internal function to add a Hat to the whitelist.
* @param _hatId The ID of the Hat to whitelist
*/
function _whitelistHat(uint256 _hatId) internal {
for (uint256 i = 0; i < whitelistedHatIds.length; i++) {
if (whitelistedHatIds[i] == _hatId) revert HatAlreadyWhitelisted();
}
whitelistedHatIds.push(_hatId);
emit HatWhitelisted(_hatId);
}

/**
* Removes a Hat from the whitelist for proposal creation.
* @param _hatId The ID of the Hat to remove from the whitelist
*/
function removeHatFromWhitelist(uint256 _hatId) external onlyOwner {
bool found = false;
for (uint256 i = 0; i < whitelistedHatIds.length; i++) {
if (whitelistedHatIds[i] == _hatId) {
whitelistedHatIds[i] = whitelistedHatIds[
whitelistedHatIds.length - 1
];
whitelistedHatIds.pop();
found = true;
break;
}
}
if (!found) revert HatNotWhitelisted();

emit HatRemovedFromWhitelist(_hatId);
}

/**
* @dev Checks if an address is authorized to create proposals.
* @param _address The address to check for proposal creation authorization.
* @return bool Returns true if the address is wearing any of the whitelisted Hats, false otherwise.
* @notice This function overrides the isProposer function from the parent contract.
* It iterates through all whitelisted Hat IDs and checks if the given address
* is wearing any of them using the Hats Protocol.
*/
function isProposer(address _address) public view virtual returns (bool) {
DarksightKellar marked this conversation as resolved.
Show resolved Hide resolved
for (uint256 i = 0; i < whitelistedHatIds.length; i++) {
if (hatsContract.isWearerOfHat(_address, whitelistedHatIds[i])) {
return true;
}
}
return false;
}

/**
* Returns the number of whitelisted hats.
* @return The number of whitelisted hats
*/
function getWhitelistedHatsCount() public view returns (uint256) {
return whitelistedHatIds.length;
}

/**
* Checks if a hat is whitelisted.
* @param _hatId The ID of the Hat to check
* @return True if the hat is whitelisted, false otherwise
*/
function isHatWhitelisted(uint256 _hatId) public view returns (bool) {
for (uint256 i = 0; i < whitelistedHatIds.length; i++) {
if (whitelistedHatIds[i] == _hatId) {
return true;
}
}
return false;
}
}
Loading