Skip to content

Instantly share code, notes, and snippets.

@publu
Created September 15, 2021 18:38
Show Gist options
  • Save publu/f29a9d9afa5736a46e704e6b27053dc6 to your computer and use it in GitHub Desktop.
Save publu/f29a9d9afa5736a46e704e6b27053dc6 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.7.0 <0.8.0;
contract CongressRegistry {
// The first key is the delegator and the second key a id.
// The value is the address of the delegate
mapping (address => address) public delegation;
mapping (address => uint256) public expiration;
mapping (address => bytes) public affiliation;
mapping (bytes => uint256) public funds;
mapping (bytes => address) public tokenInfo;
mapping (bytes => uint256) public exp;
mapping (bytes => uint8) public status; // 0 doesn't exist, 1 created
mapping (bytes => address) public owner;
// Using these events it is possible to process the events to build up reverse lookups.
// The indeces allow it to be very partial about how to build this lookup (e.g. only for a specific delegate).
event SetDelegate(address indexed delegator, address indexed delegate, bytes bill);
event ClearDelegate(address indexed delegator, address indexed delegate, bytes bill);
event CreateBribe(bytes ipfsHash, address indexed token, uint256 amount, uint256 expire, bytes hash);
/// @dev Creates and Funds a Political Action Committee
/// The combination of msg.sender and bill must be unique.
/// PAC is owned by msg.sender and votes are delegated to them.
/// @param ipfsHash is the snapshot ipfs hash of the vote
// @param token is the address of the token in question
/// @param amount is the total number of tokens to be distributed
/// @param expire is the time until the votes are needed (max 1 week from creation)
function createPAC(bytes ipfsHash, address token, uint256 amount, uint256 expire){
bytes bill = keccak256(abi.encodePacked(ipfsHash, msg.sender));
require(status[bill] == 0, "PAC already created for this bill.");
IERC20 ERC = IERC20(token);
ERC.transferFrom(msg.sender, address(this), amount);
tokenInfo[bill] = token;
funds[bill] = amount;
exp[bill] = expire;
exists[bill] = 1;
owner[bill] = msg.sender;
emit CreateBribe(ipfsHash, token, amount, expire, hash);
}
/// @dev Delegates votes to a PAC creator
/// User can delegate to one bill at a time.
/// @param bill is keccak256(ipfsHash, PAC_Owner_Address)
function delegatePAC(bytes bill) {
require(status[bill] == 1, "There's no PAC under this bill");
require(expiration[msg.sender]<=block.timestamp, "The party demands your participation.");
// Update delegation/expiration mapping
delegation[msg.sender] = owner[bill];
expiration[msg.sender] = exp[bill];
affiliation[msg.sender]=bill;
emit SetDelegate(msg.sender, delegate, bill);
}
/// @dev Claims reward
/// Can only be called once the PAC expires.
/// @param bill is keccak256(ipfsHash, PAC_Owner_Address)
function claimContribution(bytes bill) {
require(status[bill] == 1, "There's no PAC under this bill");
require(affiliation[msg.sender]==bill, "Not affiliated with PAC");
require(expiration[msg.sender]<=block.timestamp, "The party demands your participation.");
// How to calculate the % the user earned?
// Ideally it would be a % of the pooled tokens based on the amount of voting power / total power delegated
}
/// @dev Sets a delegate for the msg.sender and a specific id.
///
/// @param delegate Address of the delegate
function setDelegate(address delegate) public {
require (delegate != msg.sender, "Can't delegate to self");
require (delegate != address(0), "Can't delegate to 0x0");
address currentDelegate = delegation[msg.sender];
require (delegate != currentDelegate, "Already delegated to this address");
require (expiration[msg.sender]<=block.timestamp, "The party demands your participation.");
// Update delegation mapping
delegation[msg.sender] = delegate;
if (currentDelegate != address(0)) {
emit ClearDelegate(msg.sender, currentDelegate);
}
emit SetDelegate(msg.sender, delegate, bytes(0));
}
/// @dev Clears a delegate for the msg.sender and a specific id.
///
function clearDelegate() public {
address currentDelegate = delegation[msg.sender][id];
require (currentDelegate != address(0), "No delegate set");
require (expiration[msg.sender]<=block.timestamp, "The party demands your participation.");
// update delegation mapping
delegation[msg.sender] = address(0);
emit ClearDelegate(msg.sender, currentDelegate, bytes(0));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment