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

Contracts added #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,15 @@ typechain
#Hardhat files
cache
artifacts

# VScode
.vscode

# Typechain-types
typechain-types/*

# OpenZeppelin
.openzeppelin

# deployments
deployments/*
22 changes: 0 additions & 22 deletions contracts/Greeter.sol

This file was deleted.

75 changes: 75 additions & 0 deletions contracts/SlcDaoErc721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

/// @custom:security-contact [email protected]
contract SlcDaoErc721 is
ERC721,
ERC721URIStorage,
Pausable,
Ownable,
EIP712,
ERC721Votes
{
using Counters for Counters.Counter;

Counters.Counter private _tokenIdCounter;

constructor() ERC721("SlcDaoErc721", "SLD") EIP712("SlcDaoErc721", "1") {}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}

function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override whenNotPaused {
super._beforeTokenTransfer(from, to, tokenId);
}

// The following functions are overrides required by Solidity.

function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721, ERC721Votes) {
super._afterTokenTransfer(from, to, tokenId);
}

function _burn(uint256 tokenId)
internal
override(ERC721, ERC721URIStorage)
{
super._burn(tokenId);
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
}
161 changes: 161 additions & 0 deletions contracts/SlcDaoGovernor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

/// @custom:security-contact [email protected]
contract SlcDaoGovernor is
Initializable,
GovernorUpgradeable,
GovernorSettingsUpgradeable,
GovernorCountingSimpleUpgradeable,
GovernorVotesUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorTimelockControlUpgradeable,
OwnableUpgradeable,
UUPSUpgradeable
{
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

function initialize(
IVotesUpgradeable _token,
TimelockControllerUpgradeable _timelock,
uint256 _votingPeriod,
uint256 _votingDelay,
uint256 _minQuorumFraction
) public initializer {
__Governor_init("SlcDaoGovernor");
__GovernorSettings_init(
_votingPeriod, /* 1 block */
_votingDelay, /* 1 week */
0
);
__GovernorCountingSimple_init();
__GovernorVotes_init(_token);
__GovernorVotesQuorumFraction_init(_minQuorumFraction);
__GovernorTimelockControl_init(_timelock);
__Ownable_init();
__UUPSUpgradeable_init();
}

function _authorizeUpgrade(address newImplementation)
internal
override
onlyOwner
{}

// The following functions are overrides required by Solidity.

function votingDelay()
public
view
override(IGovernorUpgradeable, GovernorSettingsUpgradeable)
returns (uint256)
{
return super.votingDelay();
}

function votingPeriod()
public
view
override(IGovernorUpgradeable, GovernorSettingsUpgradeable)
returns (uint256)
{
return super.votingPeriod();
}

function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}

function state(uint256 proposalId)
public
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (ProposalState)
{
return super.state(proposalId);
}

function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
)
public
override(GovernorUpgradeable, IGovernorUpgradeable)
returns (uint256)
{
return super.propose(targets, values, calldatas, description);
}

function proposalThreshold()
public
view
override(GovernorUpgradeable, GovernorSettingsUpgradeable)
returns (uint256)
{
return super.proposalThreshold();
}

function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
)
internal
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
{
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}

function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
)
internal
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (uint256)
{
return super._cancel(targets, values, calldatas, descriptionHash);
}

function _executor()
internal
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (address)
{
return super._executor();
}

function supportsInterface(bytes4 interfaceId)
public
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
17 changes: 17 additions & 0 deletions contracts/SlcDaoTimelock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/TimelockController.sol)

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/governance/TimelockController.sol";

contract SlcDaoTimelock is TimelockController {
// minDelay: how long to wait before executing
// proposers: is the list of addresses that can propose
// executors: who can execute when a proposal passes
constructor(
uint256 minDelay,
address[] memory proposers, // should be only the TimeLock contract
address[] memory executors // anyone can be an executor
) TimelockController(minDelay, proposers, executors) {}
}
57 changes: 57 additions & 0 deletions contracts/SlcDaoTopics.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

// import "hardhat/console.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract SlcDaoTopics is Ownable, AccessControl {
// all observed proposal descriptions (each hashed description is firstly false (unobserved))
mapping(bytes32 => bool) public observables;

event LogObservedProposal(address manager, bytes32 hashedDescription);

// role confirmator means managers of the contract to say certain proposal was executed
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");

// assign roles to all init managers
constructor(address[] memory _managers) {
// owner of the contract is default admin
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);

for (uint256 i = 0; i < _managers.length; ++i) {
_setupRole(MANAGER_ROLE, _managers[i]);
}
}

// only owner can add a manager
function addManager(address _manager) public onlyOwner {
_grantRole(MANAGER_ROLE, _manager);
}

// removes a manager from the list of managers
function removeManager(address _manager) public onlyOwner {
revokeRole(MANAGER_ROLE, _manager);
}

// adds a proposal id to the list of observed proposals
function addPassedProposal(bytes32 _hashedDescription) public onlyOwner {
observables[_hashedDescription] = false;
}

function getPassedProposal(bytes32 _hashedDescription)
public
view
returns (bool)
{
return observables[_hashedDescription];
}

// marks the observed proposal as observed (it can only be marked as observed once)
function markProposalAsObserved(bytes32 _hashedDescription) public {
// check that this is one of the managers
require(hasRole(MANAGER_ROLE, msg.sender), "not allowed");
observables[_hashedDescription] = true;
emit LogObservedProposal(msg.sender, _hashedDescription);
}
}
28 changes: 28 additions & 0 deletions deploy/01_deploy_erc721.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

const deployGovernanceToken: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { getNamedAccounts, deployments } = hre;
const { deploy, log } = deployments;
const { deployer } = await getNamedAccounts();
// TODO: add waitConfirmations (for deploy to testnet or mainnet)
const governanceToken = await deploy("SlcDaoErc721", { from: deployer, args: [], log: true });
log("Governance Token deployed at ", governanceToken.address);

await delegate(governanceToken.address, deployer);
log("Delegated to deployer");
}

// deletegate ownership of the governance token to the account
// basically answering: who do we want to be able to vote with their token
const delegate = async (governanceTokenAddress: string, delegatedAccount: string) => {
const governanceToken = await ethers.getContractAt("SlcDaoErc721", governanceTokenAddress);
const tx = await governanceToken.delegate(delegatedAccount);
await tx.wait(1);
//
console.log('delegated governance token to', delegatedAccount);
// console.log(`Voting units available ${await governanceToken._getVotingUnits(delegatedAccount)}`);
};

export default deployGovernanceToken;
Loading