Skip to content

Instantly share code, notes, and snippets.

@SpiralOutDotEu
Last active November 7, 2023 23:04
Show Gist options
  • Save SpiralOutDotEu/1a57cfeabb06dd3691aa6e80f482507a to your computer and use it in GitHub Desktop.
Save SpiralOutDotEu/1a57cfeabb06dd3691aa6e80f482507a to your computer and use it in GitHub Desktop.
erc721a DAO
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
contract TheGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
constructor(IVotes _token, TimelockController _timelock)
Governor("The Governor")
GovernorSettings(7200 /* 1 day */, 50400 /* 1 week */, 1000e18)
GovernorVotes(_token)
GovernorVotesQuorumFraction(4)
GovernorTimelockControl(_timelock)
{}
// The following functions are overrides required by Solidity.
function votingDelay()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.votingDelay();
}
function votingPeriod()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.votingPeriod();
}
function quorum(uint256 blockNumber)
public
view
override(Governor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function state(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalNeedsQueuing(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.proposalNeedsQueuing(proposalId);
}
function proposalThreshold()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.proposalThreshold();
}
function _queueOperations(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
override(Governor, GovernorTimelockControl)
returns (uint48)
{
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
override(Governor, GovernorTimelockControl)
{
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
override(Governor, GovernorTimelockControl)
returns (uint256)
{
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor()
internal
view
override(Governor, GovernorTimelockControl)
returns (address)
{
return super._executor();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/governance/TimelockController.sol";
contract Timelock is TimelockController {
constructor(
uint256 minDelay,
address[] memory proposers,
address[] memory executors,
address admin
) TimelockController(minDelay, proposers, executors, admin) {}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "erc721a-governance-token/contracts/ERC721aGovernanceToken.sol";
import "@openzeppelin/contracts@5.0.0/access/Ownable.sol";
contract SampleERC721aGovernanceToken is ERC721aGovernanceToken, Ownable {
uint16 private immutable MAX_SUPPLY = 10_000; // Replace with your collection's max supply
uint16 private immutable MAX_MINT_PER_ADDRESS = 50; // Replace with your max mint per address value
uint64 private immutable MINT_PRICE = 0.1 ether; // Replace with your mint price
string private _baseTokenURI = "ipfs://QmZcH4YvBVVRJtdn4RdbaqgspFU8gH6P9vomDpBVpAL3u4/"; // Replace with your base token URI followed by slash
mapping(address => uint16) public addressMintedBalance;
constructor(string memory name, string memory symbol, string memory version)
ERC721aGovernanceToken(name, symbol, version)
Ownable(msg.sender){}
// Override for erc721a so that we can make our custom minting logic
function mint(uint256 quantity) public payable {
require(totalSupply() + quantity <= MAX_SUPPLY, "Exceeds max supply");
require(addressMintedBalance[msg.sender] + quantity <= MAX_MINT_PER_ADDRESS, "Exceeds max per address");
require(msg.value >= MINT_PRICE * quantity, "Ether sent is not correct");
addressMintedBalance[msg.sender] += uint16(quantity);
_mint(msg.sender, quantity);
}
// Override from erc721a so that it can be burned
function burn(uint256 tokenId) public {
_burn(tokenId);
}
// Override from erc721a so that it constuct our metadata
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
// Withdraw function to allow the owner to withdraw funds from contract
function withdraw() public onlyOwner {
uint256 balance = address(this).balance;
require(balance > 0, "No ether left to withdraw");
(bool success, ) = owner().call{value: balance}("");
require(success, "Transfer failed");
}
// Back up function to correct base URI
function setBaseURI(string memory newBaseURI) public onlyOwner {
_baseTokenURI = newBaseURI;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment