Skip to content

Seven Sequencer Modules #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/HarbergerTaxModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: UNLICENSED


/*

!!! DO NOT USE THIS CONTRACT IN PRODUCTION !!!

This is exists purely as a thought experiment. No tests have been written,
so actual functionality may be different than what is advertised. It might
not even compile, for all I know


HARBERGER TAX

- The Leader, at any point, may choose the SequencerAddress
- The Leader must set a LeadershipPrice at which they are willing to sell the Leadership
- At any point, another address may purchase the Leadership for that price
- The Leader must pay a tax equal to 5% of the LeadershipPrice, annualized + paid weekly,
to retain the Leadership.
- All taxes go to the Treasury

*/


pragma solidity 0.8.25;

import {IsAllowed} from "src/interfaces/IsAllowed.sol";


contract HarbergerTaxModule is IsAllowed {
address public Leader;
address public SequencerAddress;
address public Treasury;
uint256 public LeadershipPrice

uint256 public taxLastpaid;
uint256 public lastPriceUpdate;

uint256 constant public taxRateBps = 500;

constructor(address treasury) {
Treasury = treasury;
}

function setLeadershipPrice(uint256 price) external {
require(msg.sender == Leader, 'Only the Leader can set the LeadershipPrice')
LeadershipPrice = price;
lastPriceUpdate = block.timestamp;
}

function buyLeadership() external payable {
require(msg.value >= LeadershipPrice, 'Payment amount too low');

(bool sent,) = payable(Leader).call{value: msg.value}('');
require(sent, 'Failed to send');

Leader = msg.sender;
}

function payTax() external payable {
require(msg.value >= LeadershipPrice * taxRateBps / 520000, 'Tax not high enough');
require(block.timestamp - lastPriceUpdate > 1 hours, 'Must wait at least 1 hour after updating price');
taxLastpaid = block.timestamp;

(bool sent,) = payable(Treasury).call{value: msg.value}('');
require(sent, 'Failed to send');
}

function claimLeadership() external payable {
require(block.timestamp - taxLastpaid > 1 weeks, 'Leadership cannot be claimed');
Leader = msg.sender;
}


function setSequencerAddress(address newSequencer) external {
require(msg.sender == Leader, 'Caller must be the Leader');
SequencerAddress = newSequencer;
}


function isAllowed(address proposer) external view override returns (bool) {
return proposer == SequencerAddress;
}
}
54 changes: 54 additions & 0 deletions src/HighScoreModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: UNLICENSED


/*

!!! DO NOT USE THIS CONTRACT IN PRODUCTION !!!

This is exists purely as a thought experiment. No tests have been written,
so actual functionality may be different than what is advertised. It might
not even compile, for all I know


HIGH SCORE

- The Leader, at any point, may choose the SequencerAddress
- Leadership is determined as follows:
- At the start, any address may claim the Leadership for free
- Once a Leader exists, another addres can claim the Leadership by posting
any amount of ETH. This ETH goes to the old Leader, and the amount becomes
the HighScore.
- All subsequent Leadership changes require an address to post an ETH amount
that is higher than the current HighScore
*/


pragma solidity 0.8.25;

import {IsAllowed} from "src/interfaces/IsAllowed.sol";


contract HighScoreModule is IsAllowed {
address public Leader;
address public SequencerAddress;
uint256 public HighScore = 0;

function claimLeadership() external payable {
if (Leader != address(0)) {
require(msg.value > HighScore, 'Insufficient HighScore Payment');
(bool sent,) = payable(Leader).call{value: msg.value}('');
require(sent, 'Failed to send');
}
Leader = msg.sender;
}

function setSequencerAddress(address newSequencer) external {
require(msg.sender == Leader, 'Caller must be the Leader');
SequencerAddress = newSequencer;
}


function isAllowed(address proposer) external view override returns (bool) {
return proposer == SequencerAddress;
}
}
44 changes: 44 additions & 0 deletions src/KingOfTheHillModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: UNLICENSED




/*

!!! DO NOT USE THIS CONTRACT IN PRODUCTION !!!

This is exists purely as a thought experiment. No tests have been written,
so actual functionality may be different than what is advertised. It might
not even compile, for all I know


KING OF THE HILL

- The King, at any point, may choose the SequencerAddress
- At any point, any address may claim the Kingship
*/


pragma solidity 0.8.25;

import {IsAllowed} from "src/interfaces/IsAllowed.sol";


contract KingOfTheHillModule is IsAllowed {
address public King;
address public SequencerAddress;

function claimKingship() external {
King = msg.sender;
}

function setSequencerAddress(address newSequencer) external {
require(msg.sender == King, 'Caller must be the King');
SequencerAddress = newSequencer;
}


function isAllowed(address proposer) external view override returns (bool) {
return proposer == SequencerAddress;
}
}
126 changes: 126 additions & 0 deletions src/LeaderElectionModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// SPDX-License-Identifier: UNLICENSED


/*

!!! DO NOT USE THIS CONTRACT IN PRODUCTION !!!

This is exists purely as a thought experiment. No tests have been written,
so actual functionality may be different than what is advertised. It might
not even compile, for all I know


LEADER ELECTION

- The contract is instantiated with a pool of 7 Voters
- The Leader can choose the SequencerAddress at any time
- At any point, a majority vote can overthrow the Leader
- This will nullify the current SequencerAddress
- This will trigger a new leader election, in which a majority
vote must pick a new Leader
- Overthrowing the Leader will nullify the SequencerAddress, so no blocks
can be sequenced while a leader election is in progress

*/


pragma solidity 0.8.25;

import {IsAllowed} from "src/interfaces/IsAllowed.sol";


contract LeaderElectionModule is IsAllowed {
address public Leader;
address public SequencerAddress;

address[7] public VoterList;
mapping(address => bool) public Voters;
mapping(address => bool) public overthrowVotes;
mapping(address => address) public newLeaderVotes;

constructor(address[7] voters) {
VoterList = voters;

for (uint8 v; v < 7; v++) {
Voters[voters[v]] = true;
}

Leader = voters[0]
}

function overthrowVote(bool overthrow) external public {
require(Voters[msg.sender], 'Only Voters can vote');
require(Leader != address(0), 'No Leader to overthrow');

overthrowVotes[msg.sender] = overthrow;

if (totalOverthrowVotes() > 3) {
_overthrow();
}
}


function newLeaderVote(address newLeader) external public {
require(Voters[msg.sender], 'Only Voters can vote');
require(Leader == address(0), 'Must overthrow current Leader');
newLeaderVotes[msg.sender] = newLeader;

if (countVotes(newLeader) > 3) {
_setLeader(newLeader);
}
}


function totalOverthrowVotes() public view returns (uint8) {
uint8 overthrowCount;
for (uint8 v; v < 7; v++) {
if (overthrowVotes[VoterList[v]]) {
overthrowCount++;
}
}

return overthrowCount;
}


function countVotes(address addr) public view returns (uint8) {
uint8 voteCount;
for (uint8 v; v < 7; v++) {
if (newLeaderVotes[VoterList[v]] == addr) {
voteCount++;
}
}

return voteCount;
}



function _setLeader(newLeader) private {
Leader = newLeader;
for (uint8 v; v < 7; v++) {
newLeaderVotes[VoterList[v]] = address(0);
}
}

function _overthrow() private {
SequencerAddress = address(0);
Leader = address(0);
for (uint8 v; v < 7; v++) {
overthrowVotes[VoterList[v]] = false;
}
}




function setSequencerAddress(address newSequencer) external {
require(msg.sender == Leader, 'Caller must be the Leader');
SequencerAddress = newSequencer;
}


function isAllowed(address proposer) external view override returns (bool) {
return proposer == SequencerAddress;
}
}
83 changes: 83 additions & 0 deletions src/NuclearWarModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: UNLICENSED


/*

!!! DO NOT USE THIS CONTRACT IN PRODUCTION !!!

This is exists purely as a thought experiment. No tests have been written,
so actual functionality may be different than what is advertised. It might
not even compile, for all I know


NUCLEAR WAR

- Nine Leaders are chosen at instantiation
- All Leaders act as Sequencer addresses
- At any point, a Leader can nuke another Leader, removing them from the
Leader list.
- Completing a nuke operation takes 12 minutes, during which time the target
Leader can retaliate.
- If all Leaders are eliminated, there will be no valid proposer for isAllowed,
and no one will be able to sequence.
*/


pragma solidity 0.8.25;

import {IsAllowed} from "src/interfaces/IsAllowed.sol";


contract HighScoreModule is IsAllowed {
mapping(address => bool) public LeaderList;

enum MissleTargetStatus {
Dormant,
Fired,
Completed
}

struct NuclearMissle {
address target;
MissleTargetStatus status;
uint256 firedAt;
}

uint8 missleCount;

mapping(uint256 => NuclearMissle) public Missles;

address public SequencerAddress;

constructor(address[9] leaders) {
for (address l; l < 9; l++) {
LeaderList[leaders[l]] = true;
}
}


function fireMissle(address target) external public returns (uint8) {
require(LeaderList[msg.sender], 'Only a Leader can fire a nuke');

uint8 missleId = missleCount
Missles[missleId].status = MissleTargetStatus.Fired;
Missles[missleId].target = target;
Missles[missleId].firedAt = block.timestamp;

missleCount++;

return missleId;
}

function completeMissleLaunch(uint8 missleId) external public {
require(NuclearMissle[missleId].status == Fired, 'Can only complete a Fired missle');
require(block.timestamp - NuclearMissle[missleId].timestamp >= 12 minutes, 'Must wait 12 minutes to complete missle launch');
NuclearMissle[missleId].status = MissleTargetStatus.Completed;
LeaderList[NuclearMissle[missleId].target] = false;
}


function isAllowed(address proposer) external view override returns (bool) {
return proposer == LeaderList[msg.sender];
}
}
Loading