diff --git a/Anon Suggestion Box/anonSuggestionBox.sol b/Anon Suggestion Box/anonSuggestionBox.sol new file mode 100644 index 0000000..6472846 --- /dev/null +++ b/Anon Suggestion Box/anonSuggestionBox.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +/// @title Anon Suggestion Box Contract +/// @notice This contract allows users to anonymously submit encrypted suggestions. +/// @dev The suggestions are stored privately and can only be accessed or managed by the contract owner. +contract AnonSuggestionBox { + /// @dev Array to store encrypted suggestions privately, managed by the L2 protocol + bytes[] private suggestions; + + /// @dev The owner of the contract, initially set to the deployer + address private owner; + + /// @notice Event emitted when a new suggestion is submitted + /// @param suggestionId The index of the new suggestion in the suggestions array + event NewSuggestion(uint256 indexed suggestionId); + + /// @notice Constructor that sets the contract deployer as the owner + constructor() { + owner = msg.sender; + } + + /// @notice Submits a new suggestion in encrypted form + /// @param encryptedSuggestion The encrypted suggestion data submitted by the user + function submitSuggestion(bytes calldata encryptedSuggestion) external { + suggestions.push(encryptedSuggestion); + emit NewSuggestion(suggestions.length - 1); + } + + /// @notice Returns the total number of suggestions submitted + /// @return The count of suggestions in the contract + function getSuggestionCount() external view returns (uint256) { + return suggestions.length; + } + + /// @notice Allows the owner to read all submitted suggestions + /// @dev Only callable by the contract owner + /// @return An array of all encrypted suggestions + function readAllSuggestions() external view onlyOwner returns (bytes[] memory) { + return suggestions; + } + + /// @notice Clears all suggestions from the contract + /// @dev Only callable by the contract owner; deletes the entire suggestions array + function clearSuggestions() external onlyOwner { + delete suggestions; + } + + /// @dev Modifier that restricts function access to the contract owner only + modifier onlyOwner() { + require(msg.sender == owner, "Only the owner can perform this action"); + _; + } +} diff --git a/Encrypted DAO Voting/encryptedVoting.sol b/Encrypted DAO Voting/encryptedVoting.sol new file mode 100644 index 0000000..e5e1f85 --- /dev/null +++ b/Encrypted DAO Voting/encryptedVoting.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +/// @title Encrypted DAO Voting Contract +/// @notice This contract facilitates a private voting system for a DAO using TEN's L2 protocol for encryption. +/// @dev Voting results are private, with upvotes and downvotes stored securely. Only the admin can end the voting. +contract encryptedVoting { + /// @notice The address of the admin who deployed the contract + address public admin; + + /// @notice The timestamp when the voting ends + uint public votingEndTime; + + /// @dev Private variable to store the count of upvotes, encrypted by TEN's L2 protocol + uint private upvotes; + + /// @dev Private variable to store the count of downvotes, encrypted by TEN's L2 protocol + uint private downvotes; + + /// @dev Mapping to track whether an address has voted + mapping(address => bool) private hasVoted; + + /// @notice Event emitted when a vote is cast + /// @param voter The address of the voter + event VoteCast(address indexed voter); + + /// @notice Event emitted when the voting ends + /// @param upvotes The final count of upvotes + /// @param downvotes The final count of downvotes + event VotingEnded(uint upvotes, uint downvotes); + + /// @notice Constructor that sets the admin and voting duration + /// @param _durationInMinutes The duration of the voting period in minutes + constructor(uint _durationInMinutes) { + admin = msg.sender; + votingEndTime = block.timestamp + (_durationInMinutes * 1 minutes); + } + + /// @dev Modifier to restrict access to the admin only + modifier onlyAdmin() { + require(msg.sender == admin, "Only admin can perform this action"); + _; + } + + /// @dev Modifier to ensure that voting is still open + modifier votingOpen() { + require(block.timestamp < votingEndTime, "Voting has ended"); + _; + } + + /// @notice Allows users to cast their vote as either an upvote or a downvote + /// @dev Users can only vote once and voting must be open + /// @param isUpvote Boolean indicating whether the vote is an upvote (`true`) or a downvote (`false`) + function vote(bool isUpvote) external votingOpen { + require(!hasVoted[msg.sender], "Already voted"); + + if (isUpvote) { + upvotes++; + } else { + downvotes++; + } + hasVoted[msg.sender] = true; + + emit VoteCast(msg.sender); + } + + /// @notice Ends the voting process and emits the final vote counts + /// @dev Only the admin can call this function and only after the voting period has ended + function endVoting() external onlyAdmin { + require(block.timestamp >= votingEndTime, "Voting period not yet over"); + emit VotingEnded(upvotes, downvotes); + } + + /// @notice Checks if a specific user has voted + /// @param user The address of the user to check + /// @return A boolean indicating whether the user has voted + function hasUserVoted(address user) external view returns (bool) { + return hasVoted[user]; + } + + /// @notice Retrieves the current voting status + /// @return isOpen Boolean indicating if voting is still open + /// @return timeRemaining The amount of time remaining for voting in seconds + function getVotingStatus() external view returns (bool isOpen, uint timeRemaining) { + isOpen = block.timestamp < votingEndTime; + timeRemaining = votingEndTime > block.timestamp ? votingEndTime - block.timestamp : 0; + } +} diff --git a/Sealed Bid Auctions/sealedBidAuctions.sol b/Sealed Bid Auctions/sealedBidAuctions.sol new file mode 100644 index 0000000..7b3123b --- /dev/null +++ b/Sealed Bid Auctions/sealedBidAuctions.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +/// @title Sealed Bid Auction Contract +/// @notice This contract allows for a sealed bid auction where the highest bidder wins. +/// @dev Implements a sealed bid auction with the auctioneer as the only authority to end the auction. +contract SealedBidAuction { + /// @notice The address of the auctioneer who deploys the contract + address public auctioneer; + + /// @notice The timestamp when the auction ends + uint public auctionEndTime; + + /// @notice The address of the current highest bidder + address private highestBidder; + + /// @notice The highest bid amount + uint private highestBid; + + /// @notice Boolean indicating whether the auction has ended + bool public auctionEnded; + + /// @dev Private mapping of bidders to their bid amounts + mapping(address => uint) private bids; + + /// @dev Private mapping of pending returns for each address + mapping(address => uint) private pendingReturns; + + /// @notice Event emitted when the auction ends + event AuctionEnded(); + + /// @dev Event emitted when a bid is placed + /// @param bidder The address of the bidder + event BidPlaced(address indexed bidder); + + /// @dev Event emitted when the winner is determined + /// @param winner The address of the highest bidder + /// @param winningBid The winning bid amount + event WinnerDetermined(address indexed winner, uint winningBid); + + /// @dev Event emitted when a bidder withdraws their pending returns + /// @param bidder The address of the bidder + /// @param amount The amount withdrawn + event WithdrawalMade(address indexed bidder, uint amount); + + /// @dev Modifier that restricts function access to the auctioneer only + modifier onlyAuctioneer() { + require(msg.sender == auctioneer, "Only auctioneer can call this function"); + _; + } + + /// @dev Modifier that allows function execution only before the auction ends + modifier onlyBeforeEnd() { + require(block.timestamp < auctionEndTime, "Auction already ended"); + _; + } + + /// @dev Modifier that allows function execution only after the auction ends + modifier onlyAfterEnd() { + require(block.timestamp >= auctionEndTime, "Auction not yet ended"); + _; + } + + /// @notice Constructor to initialize the auction duration + /// @param _auctionDuration Duration in seconds for which the auction will be active + constructor(uint _auctionDuration) { + auctioneer = msg.sender; + auctionEndTime = block.timestamp + _auctionDuration; + } + + /// @notice Allows a user to place a bid in the auction + /// @dev Bids are cumulative; a new bid adds to the previous bid amount by the same bidder + function placeBid() public payable onlyBeforeEnd { + require(msg.value > 0, "Bid amount must be greater than 0"); + + uint currentBid = bids[msg.sender] + msg.value; + bids[msg.sender] = currentBid; + + if (currentBid > highestBid) { + if (highestBidder != address(0)) { + pendingReturns[highestBidder] += highestBid; + } + highestBidder = msg.sender; + highestBid = currentBid; + } + + emit BidPlaced(msg.sender); + } + + /// @notice Allows a bidder to withdraw their pending returns + function withdraw() public { + uint amount = pendingReturns[msg.sender]; + if (amount > 0) { + pendingReturns[msg.sender] = 0; + payable(msg.sender).transfer(amount); + emit WithdrawalMade(msg.sender, amount); + } + } + + /// @notice Ends the auction and transfers the highest bid to the auctioneer + /// @dev Only the auctioneer can end the auction and only after the auction end time has passed + function endAuction() public onlyAuctioneer onlyAfterEnd { + require(!auctionEnded, "Auction already ended"); + auctionEnded = true; + emit AuctionEnded(); + emit WinnerDetermined(highestBidder, highestBid); + payable(auctioneer).transfer(highestBid); + } + + /// @notice Returns the caller's bid amount + /// @return The bid amount placed by the caller + function getMyBid() public view returns (uint) { + return bids[msg.sender]; + } + + /// @notice Allows the auctioneer to check the auction status + /// @dev Can only be called by the auctioneer after the auction has ended + /// @return highestBidder The address of the highest bidder + /// @return highestBid The highest bid amount + function checkAuctionStatus() public view onlyAuctioneer returns (address, uint) { + require(auctionEnded, "Auction not yet ended"); + return (highestBidder, highestBid); + } +}