// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract Submission is ERC721 {
struct Haiku {
address author;
string line1;
string line2;
string line3;
}
uint public counter;
mapping(uint256 => Haiku) private haikus;
mapping(bytes32 => bool) private line1Hashes;
mapping(address => uint256[]) private sharedHaikus;
error HaikuNotUnique();
error NotYourHaiku(uint256 tokenId);
error NoHaikusShared();
constructor() ERC721("HaikuNFT", "HNK") {}
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external {
bytes32 line1Hash = keccak256(abi.encodePacked(_line1));
if (line1Hashes[line1Hash]) {
revert HaikuNotUnique();
}
line1Hashes[line1Hash] = true;
uint256 id = counter;
haikus[id] = Haiku(msg.sender, _line1, _line2, _line3);
_mint(msg.sender, id);
counter++;
}
function shareHaiku(uint256 _id, address _to) external {
if (ownerOf(_id) != msg.sender) {
revert NotYourHaiku(_id);
}
sharedHaikus[_to].push(_id);
}
function getMySharedHaikus() external view returns (Haiku[] memory) {
uint256[] memory ids = sharedHaikus[msg.sender];
if (ids.length == 0) {
revert NoHaikusShared();
}
Haiku[] memory result = new Haiku[](ids.length);
for (uint256 i = 0; i < ids.length; i++) {
result[i] = haikus[ids[i]];
}
return result;
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
contract Submission {
mapping(address => uint256) public balances;
mapping(address => bool) private hasClaimed;
uint256 public totalClaimed;
error TokensClaimed();
error UnsafeTransfer(address to);
error InsufficientBalance(uint256 available, uint256 required);
function claim() external {
if (hasClaimed[msg.sender]) {
revert TokensClaimed();
}
hasClaimed[msg.sender] = true;
balances[msg.sender] += 1000;
totalClaimed += 1000;
}
function safeTransfer(address _to, uint256 _amount) external {
if (_to == address(0)) {
revert UnsafeTransfer(_to);
}
if (_to.code.length > 0) {
if (_to.balance == 0) {
revert UnsafeTransfer(_to);
}
}
if (balances[msg.sender] < _amount) {
revert InsufficientBalance(balances[msg.sender], _amount);
}
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
function totalSupply() external view returns (uint256) {
return totalClaimed;
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract Submission is ERC20 {
using EnumerableSet for EnumerableSet.AddressSet;
struct Issue {
EnumerableSet.AddressSet voters;
string issueDesc;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
uint256 totalVotes;
uint256 quorum;
bool passed;
bool closed;
}
struct ReturnableIssue {
address[] voters;
string issueDesc;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
uint256 totalVotes;
uint256 quorum;
bool passed;
bool closed;
}
enum Vote {
AGAINST,
FOR,
ABSTAIN
}
mapping(address => bool) private hasClaimed;
Issue[] private issues;
error TokensClaimed();
error NoTokensHeld();
error AlreadyVoted();
constructor() ERC20("VoteToken", "VTK") {}
function claim() external {
if (hasClaimed[msg.sender]) {
revert TokensClaimed();
}
hasClaimed[msg.sender] = true;
_mint(msg.sender, 100);
}
function createIssue(
string memory _issueDesc,
uint256 _quorum
) external returns (uint256) {
if (balanceOf(msg.sender) == 0) {
revert NoTokensHeld();
}
Issue storage newIssue = issues.push();
newIssue.issueDesc = _issueDesc;
newIssue.quorum = _quorum;
return issues.length - 1;
}
function getIssue(
uint256 _id
) external view returns (ReturnableIssue memory) {
Issue storage issue = issues[_id];
return
ReturnableIssue(
issue.voters.values(),
issue.issueDesc,
issue.votesFor,
issue.votesAgainst,
issue.votesAbstain,
issue.totalVotes,
issue.quorum,
issue.passed,
issue.closed
);
}
function vote(uint256 _issueId, Vote _vote) external {
Issue storage issueToVote = issues[_issueId];
if (issueToVote.voters.contains(msg.sender)) {
revert AlreadyVoted();
}
uint256 voteWeight = balanceOf(msg.sender);
issueToVote.voters.add(msg.sender);
if (_vote == Vote.FOR) {
issueToVote.votesFor += voteWeight;
} else if (_vote == Vote.AGAINST) {
issueToVote.votesAgainst += voteWeight;
} else {
issueToVote.votesAbstain += voteWeight;
}
issueToVote.totalVotes += voteWeight;
if (issueToVote.totalVotes >= issueToVote.quorum) {
issueToVote.closed = true;
if (issueToVote.votesFor > issueToVote.votesAgainst) {
issueToVote.passed = true;
}
}
}
}
Share Dialog
Timurlenk
Support dialog
All comments (2)
Thanks friend!!!!
thanks broo