-
-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
209 additions
and
0 deletions.
There are no files selected for viewing
209 changes: 209 additions & 0 deletions
209
blockchain_integration/pi_network/pi-stablecoin/governance/Governance.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol"; | ||
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; | ||
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/access/AccessControl.sol"; | ||
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol"; | ||
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/utils/Pausable.sol"; | ||
|
||
contract Governance is AccessControl, ReentrancyGuard, Pausable { | ||
// Mapping of proposal IDs to proposal details | ||
mapping(uint256 => Proposal) public proposals; | ||
|
||
// Mapping of user addresses to their voting power | ||
mapping(address => uint256) public votingPower; | ||
|
||
// Mapping of user addresses to their delegate addresses | ||
mapping(address => address) public delegates; | ||
|
||
// Mapping of proposal IDs to vote counts | ||
mapping(uint256 => mapping(bool => uint256)) public voteCounts; | ||
|
||
// Mapping of proposal IDs to vote records | ||
mapping(uint256 => mapping(address => bool)) public voteRecords; | ||
|
||
// Total voting power | ||
uint256 public totalVotingPower; | ||
|
||
// Proposal counter | ||
uint256 public proposalCounter; | ||
|
||
// Quorum threshold | ||
uint256 public quorumThreshold; | ||
|
||
// Proposal threshold | ||
uint256 public proposalThreshold; | ||
|
||
// Voting period | ||
uint256 public votingPeriod; | ||
|
||
// Event emitted when a new proposal is created | ||
event NewProposal(uint256 proposalId, string description); | ||
|
||
// Event emitted when a vote is cast | ||
event VoteCast(uint256 proposalId, address voter, bool support); | ||
|
||
// Event emitted when a proposal is executed | ||
event ProposalExecuted(uint256 proposalId); | ||
|
||
// Event emitted when a proposal is canceled | ||
event ProposalCanceled(uint256 proposalId); | ||
|
||
// Event emitted when a delegate is set | ||
event DelegateSet(address indexed delegator, address indexed delegate); | ||
|
||
// Event emitted when a delegate is removed | ||
event DelegateRemoved(address indexed delegator, address indexed delegate); | ||
|
||
// Struct to represent a proposal | ||
struct Proposal { | ||
uint256 id; | ||
string description; | ||
uint256 startTime; | ||
uint256 endTime; | ||
uint256 yesVotes; | ||
uint256 noVotes; | ||
bool executed; | ||
bool canceled; | ||
} | ||
|
||
// Modifier to check if a user has voting power | ||
modifier hasVotingPower { | ||
require(votingPower[msg.sender] > 0, "User has no voting power"); | ||
_; | ||
} | ||
|
||
// Modifier to check if a proposal exists | ||
modifier proposalExists(uint256 _proposalId) { | ||
require(proposals[_proposalId].id != 0, "Proposal does not exist"); | ||
_; | ||
} | ||
|
||
// Modifier to check if a proposal is active | ||
modifier proposalActive(uint256 _proposalId) { | ||
require(proposals[_proposalId].startTime <= block.timestamp && block.timestamp <= proposals[_proposalId].endTime, "Proposal is not active"); | ||
_; | ||
} | ||
|
||
// Modifier to check if a user has already voted | ||
modifier hasNotVoted(uint256 _proposalId) { | ||
require(!voteRecords[_proposalId][msg.sender], "User has already voted"); | ||
_; | ||
} | ||
|
||
// Function to create a new proposal | ||
function createProposal(string memory _description) public hasVotingPower { | ||
// Increment proposal counter | ||
proposalCounter++; | ||
|
||
// Create a new proposal | ||
Proposal memory proposal = Proposal( | ||
proposalCounter, | ||
_description, | ||
block.timestamp, | ||
block.timestamp + votingPeriod, | ||
0, | ||
0, | ||
false, | ||
false | ||
); | ||
|
||
// Store the proposal | ||
proposals[proposalCounter] = proposal; | ||
|
||
// Emit a new proposal event | ||
emit NewProposal(proposalCounter, _description); | ||
} | ||
|
||
// Function to cast a vote | ||
function castVote(uint256 _proposalId, bool _support) public proposalExists(_proposalId) proposalActive(_proposalId) hasNotVoted(_proposalId) { | ||
// Update the vote count | ||
voteCounts[_proposalId][_support]++; | ||
|
||
// Update the vote record | ||
voteRecords[_proposalId][msg.sender] = true; | ||
|
||
// Emit a vote cast event | ||
emit VoteCast(_proposalId, msg.sender, _support); | ||
} | ||
|
||
// Function to execute a proposal | ||
function executeProposal(uint256 _proposalId) public proposalExists(_proposalId) { | ||
// Check if the proposal has been executed | ||
require(!proposals[_proposalId].executed, "Proposal has already been executed"); | ||
|
||
// Check if the proposal has passed | ||
require(voteCounts[_proposalId][true] > voteCounts[_proposalId][false], "Proposal has not passed"); | ||
|
||
// Execute the proposal | ||
// ... | ||
|
||
// Update the proposal's executed status | ||
proposals[_proposalId].executed = true; | ||
|
||
// Emit a proposal executed event | ||
emit ProposalExecuted(_proposalId); | ||
} | ||
|
||
// Function to cancel a proposal | ||
function cancelProposal(uint256 _proposalId) public proposalExists(_proposalId) { | ||
// Check if the proposal has been executed | ||
require(!proposals[_proposalId].executed, "Proposal has already been executed"); | ||
|
||
// Check if the proposal has been canceled | ||
require(!proposals[_proposalId].canceled, "Proposal has already been canceled"); | ||
|
||
// Update the proposal's canceled status | ||
proposals[_proposalId].canceled = true; | ||
|
||
// Emit a proposal canceled event | ||
emit ProposalCanceled(_proposalId); | ||
} | ||
|
||
// Function to set a delegate | ||
function setDelegate(address _delegate) public { | ||
// Check if the delegate is not the same as the delegator | ||
require(_delegate != msg.sender, "Delegate cannot be the same as the delegator"); | ||
|
||
// Update the delegate | ||
delegates[msg.sender] = _delegate; | ||
|
||
// Emit a delegate set event | ||
emit DelegateSet(msg.sender, _delegate); | ||
} | ||
|
||
// Function to remove a delegate | ||
function removeDelegate() public { | ||
// Update the delegate | ||
delete delegates[msg.sender]; | ||
|
||
// Emit a delegate removed event | ||
emit DelegateRemoved(msg.sender, delegates[msg.sender]); | ||
} | ||
|
||
// Function to get the voting power of a user | ||
function getVotingPower(address _user) public view returns (uint256) { | ||
return votingPower[_user]; | ||
} | ||
|
||
// Function to get the delegate of a user | ||
function getDelegate(address _user) public view returns (address) { | ||
return delegates[_user]; | ||
} | ||
|
||
// Function to get the proposal details | ||
function getProposal(uint256 _proposalId) public view returns (Proposal memory) { | ||
return proposals[_proposalId]; | ||
} | ||
|
||
// Function to get the vote count of a proposal | ||
function getVoteCount(uint256 _proposalId, bool _support) public view returns (uint256) { | ||
return voteCounts[_proposalId][_support]; | ||
} | ||
|
||
// Function to get the vote record of a user | ||
function getVoteRecord(uint256 _proposalId, address _user) public view returns (bool) { | ||
return voteRecords[_proposalId][_user]; | ||
} | ||
} |