Skip to content

Instantly share code, notes, and snippets.

@DanteAlabastro
Last active October 17, 2018 22:10
Show Gist options
  • Save DanteAlabastro/6cbbc20d8e304487ebb78438a3d8895e to your computer and use it in GitHub Desktop.
Save DanteAlabastro/6cbbc20d8e304487ebb78438a3d8895e to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.25+commit.59dbf8f1.js&optimize=true&gist=
pragma solidity ^0.4.25;
/* Welcome to my submission for EthSF!
This is a Payroll System built for ether miners.
I hope you enjoy. */
// # Now collected in one contract! # //
// # And hopefully less overflows! # //
//github: https://github.com/DanteAlabastro
//remix: https://remix.ethereum.org/#version=soljson-v0.4.25+commit.59dbf8f1.js&optimize=true&gist=6cbbc20d8e304487ebb78438a3d8895e
// I transitioned to SafeMath! Let's hope nothing is broken...
// 'openzeppelin-solidity/contracts/math/SafeMath.sol';
// Local import
library SafeMath {
/**
* @dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asserts when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
contract payroll{
using SafeMath for uint256;
/* a + b becomes a.add(b)
| a - b becomes a.sub(b)
| a * b becomes a.mul(b)
| a / b becomes a.div(b)
*/
// Test SafeMath import
function Add(uint256 a, uint256 b) public pure returns (uint256){
a = a.add(b);
return a;
}
/* Deposit */
function deposit() payable public PayPeriod{
redistribute();
}
/* Variables */
address private owner = msg.sender;
uint blockweeks = 1209600; // 14 days in 14 second blocktime
uint creation = block.number;
uint public lastPayday = block.number;
uint public nextPayday = lastPayday.add(blockweeks);
bool payPeriodToggle = true;
uint Balance;
uint AvailableBalance;
uint ReservedBalance;
uint GasReserve;
uint256 EmployeeCount;
uint256 ID = 1;
/* Event */
event broadcast(string);
/* Modifiers */
modifier Owned(){
require (msg.sender == owner, "Administrative access required.");
_;
}
// Check for passing of 2 weeks.
modifier PayPeriod(){
if (lastPayday.add(blockweeks) <= block.number){
lastPayday = lastPayday.add(blockweeks);
Distribute();
_;
}
_;
}
// Biweekly payments with 3 day window is toggleable in preference of...
// manual distribution.
modifier PayDay() {
if (payPeriodToggle == true){
require(lastPayday <= block.number);
require(block.number <= lastPayday.add(259200));
_;
}
_;
}
/* Mapping */
// Employee info.
mapping (uint256 => string) _Name;
mapping (uint256 => uint256) _IDnumber;
mapping (uint256 => address) _Address;
mapping (uint256 => uint256) _Balance;
mapping (uint256 => bool) _Lock;
//Reverse lookup
mapping (address => uint256) IDbyAddress;
/* Core Functions */
// Update Balance + AvailableBalance. Check for PayPeriod.
function redistribute() internal {
Balance = address(this).balance;
if(Balance > ReservedBalance.add(GasReserve)){
AvailableBalance = Balance.sub((ReservedBalance.add(GasReserve)));
}
}
// Distribute Funds
function Distribute() internal PayDay{
require(EmployeeCount > 0, "There are no employees in the system.");
redistribute();
require(AvailableBalance > 0, "There are no funds available.");
uint Payout = AvailableBalance.div(EmployeeCount);
ReservedBalance = ReservedBalance.add(AvailableBalance);
AvailableBalance = 0;
for(uint i=1; i <= ID -1; i++) {
if(_IDnumber[i] >= 1 ){
_Balance[i] = _Balance[i].add(Payout) ;
}
}
}
/* Employee Funcitons */
function IsitPayday() public view returns (bool){
require(payPeriodToggle == true, "This feature has been turned off.");
if ( lastPayday <= block.number && block.number <= lastPayday + 259200){
return true;
}
return false;
}
function GetEmployeeInfo() public view returns(string, uint256, address, uint256, bool){
require(_Address[IDbyAddress[msg.sender]] == msg.sender, "Your account is not listed in the database.");
uint256 EmployeeID = IDbyAddress[msg.sender];
return(_Name[EmployeeID], EmployeeID, _Address[EmployeeID], _Balance[EmployeeID], _Lock[EmployeeID]);
}
function Withdrawl(uint256 EmployeeID) public PayDay {
require(_Address[EmployeeID] == msg.sender, "The ID you provided does not match you address.");
require(_Lock[EmployeeID] == false, "This account has been locked.");
uint paycheck = _Balance[EmployeeID];
ReservedBalance = ReservedBalance.sub(_Balance[EmployeeID]);
_Balance[EmployeeID] = 0;
msg.sender.transfer(paycheck);
}
/* Admin Functions */
// Onboarding and Offboarding + Employee lookup and management.
//Onboard
function onboard(string Name, address Address) public Owned {
require(EmployeeCount < 2**256 - 1, "Too many employees!");
require(ID < 2**256 - 1, "Too many employees!");
_Name[ID] = Name;
_IDnumber[ID] = ID;
_Address[ID] = Address;
_Balance[ID] = 0;
_Lock[ID] = false;
IDbyAddress[Address] = ID;
EmployeeCount++;
ID++;
GasReserve = EmployeeCount.mul(1e9 wei);
emit broadcast(Name);
}
//ID lookup
function getbyID(uint256 EmployeeID) public view Owned returns(string, address, uint256, bool){
return(_Name[EmployeeID], _Address[EmployeeID], _Balance[EmployeeID], _Lock[EmployeeID]);
}
//Account Lock
function EmployeeLock(uint256 EmployeeID, bool Toggle) public Owned {
_Lock[EmployeeID] = Toggle;
}
//Address change. Requires _Lock = True.
function changeAddress(uint256 EmployeeID, address Address) public Owned{
require(_Lock[EmployeeID] == true, "This account must be locked in order to make changes.");
_Address[EmployeeID] = Address;
}
//Offboard. Requires _Lock = True.
function DeleteUser(uint256 EmployeeID) public Owned{
require(EmployeeCount > 0);
require(_Lock[EmployeeID] == true, "This account must be locked in order to make changes.");
AvailableBalance = AvailableBalance.add(_Balance[EmployeeID]);
ReservedBalance = ReservedBalance.sub(_Balance[EmployeeID]);
IDbyAddress[_Address[EmployeeID]] = 0;
_Name[EmployeeID] = '';
_IDnumber[EmployeeID] = 0;
_Address[EmployeeID] = 0;
_Balance[EmployeeID] = 0;
_Lock[EmployeeID] = true;
EmployeeCount--;
GasReserve = EmployeeCount.mul(1e9 wei);
}
// The 2 week payperiod restriction can be toggled here.
function requirePayperiod(bool Toggle) public Owned{
payPeriodToggle = Toggle;
}
// Manual distribute. Requires payPeriodToggle = False if not PayPeriod. See requirePayperiod.
function manualDistribute() public PayDay Owned{
Distribute();
}
}
pragma solidity ^0.4.25;
/* Welcome to my submission for EthSF!
This is a Payroll System built for ether miners.
I hope you enjoy. */
// # This contract should be initiated by # //
// # oInterface.sol # //
//github: https://github.com/DanteAlabastro
//remix: https://remix.ethereum.org/#version=soljson-v0.4.25+commit.59dbf8f1.js&optimize=true&gist=6cbbc20d8e304487ebb78438a3d8895e
contract payroll{
/* Deposit */
function deposit() payable public PayPeriod{
redistribute();
}
/* Variables */
address owner = msg.sender;
uint blockweeks = 1209600; // 14 days in 14 second blocktime
uint creation = block.number;
uint public lastPayday = block.number;
uint public nextPayday = lastPayday + blockweeks;
bool payPeriodToggle = true;
uint Balance;
uint AvailableBalance;
uint ReservedBalance;
uint GasReserve;
uint256 EmployeeCount;
uint256 ID = 1;
/* Event */
event broadcast(string);
/* Modifiers */
modifier Owned(){
require (msg.sender == owner);
_;
}
// Check for passing of 2 weeks.
modifier PayPeriod(){
if (lastPayday + blockweeks <= block.number){
lastPayday += blockweeks;
Distribute();
_;
}
_;
}
// Biweekly payments with 3 day window is toggleable in preference of...
// manual distribution.
modifier PayDay() {
if (payPeriodToggle == true){
require(lastPayday <= block.number);
require(block.number <= lastPayday + 259200);
_;
}
_;
}
/* Mapping */
// Employee info.
mapping (uint256 => string) _Name;
mapping (uint256 => uint256) _IDnumber;
mapping (uint256 => address) _Address;
mapping (uint256 => uint256) _Balance;
mapping (uint256 => bool) _Lock;
//Reverse lookup
mapping (address => uint256) IDbyAddress;
/* Functions */
// Update Balance + AvailableBalance. Check for PayPeriod.
function redistribute() internal {
Balance = address(this).balance;
if(Balance > ReservedBalance + GasReserve){
AvailableBalance = Balance - (ReservedBalance + GasReserve);
}
}
// Distribute Funds
function Distribute() internal PayDay{
require(EmployeeCount > 0);
redistribute();
require(AvailableBalance > 0);
uint Payout = AvailableBalance / EmployeeCount;
for(uint i=1; i <= ID -1; i++) {
if(_IDnumber[i] >= 1 ){
_Balance[i] += Payout ;
}
}
ReservedBalance += AvailableBalance;
AvailableBalance = 0;
}
}
pragma solidity ^0.4.25;
import 'gist/Distribution.sol';
contract EmployeeTools is payroll {
function IsitPayday() public view returns (bool){
require(payPeriodToggle == true);
if ( lastPayday <= block.number && block.number <= lastPayday + 259200){
return true;
}
return false;
}
function GetEmployeeInfo() public view returns(string, uint256, address, uint256, bool){
require(_Address[IDbyAddress[msg.sender]] == msg.sender);
uint256 EmployeeID = IDbyAddress[msg.sender];
return(_Name[EmployeeID], EmployeeID, _Address[EmployeeID], _Balance[EmployeeID], _Lock[EmployeeID]);
}
function Withdrawl(uint256 EmployeeID) public PayDay {
require(_Address[EmployeeID] == msg.sender);
require(_Lock[EmployeeID] == false);
msg.sender.transfer(_Balance[EmployeeID]);
ReservedBalance -= _Balance[EmployeeID];
_Balance[EmployeeID] = 0;
}
}
pragma solidity ^0.4.25;
import 'gist/EmployeeTools.sol';
contract AdminTools is EmployeeTools{
// Admin Tools //
// Onboarding and Offboarding + Employee lookup and management.
function onboard(string Name, address Address) public Owned {
_Name[ID] = Name;
_IDnumber[ID] = ID;
_Address[ID] = Address;
_Balance[ID] = 0;
_Lock[ID] = false;
IDbyAddress[Address] = ID;
EmployeeCount++;
ID++;
GasReserve = EmployeeCount * 1e9 wei;
emit broadcast(Name);
}
function getbyID(uint256 EmployeeID) public view Owned returns(string, address, uint256, bool){
return(_Name[EmployeeID], _Address[EmployeeID], _Balance[EmployeeID], _Lock[EmployeeID]);
}
function EmployeeLock(uint256 EmployeeID, bool Toggle) public Owned {
_Lock[EmployeeID] = Toggle;
}
function changeAddress(uint256 EmployeeID, address Address) public Owned{
require(_Lock[EmployeeID] == true);
_Address[EmployeeID] = Address;
}
function DeleteUser(uint256 EmployeeID) public Owned{
require(EmployeeCount > 0);
require(_Lock[EmployeeID] == true);
AvailableBalance = AvailableBalance + _Balance[EmployeeID];
ReservedBalance = ReservedBalance - _Balance[EmployeeID];
IDbyAddress[_Address[EmployeeID]] = 0;
_Name[EmployeeID] = '';
_IDnumber[EmployeeID] = 0;
_Address[EmployeeID] = 0;
_Balance[EmployeeID] = 0;
_Lock[EmployeeID] = true;
EmployeeCount--;
GasReserve = EmployeeCount * 1e9 wei;
}
// The 2 week payperiod restriction can be toggled here.
function requirePayperiod(bool Toggle) public Owned{
payPeriodToggle = Toggle;
}
// Manual distribute
function manualDistribute() public Owned{
Distribute();
}
}
pragma solidity ^0.4.25;
import 'gist/oAdminTools.sol';
contract Interface is AdminTools{
// ## Attention: ## //
// ## The Payroll System should be run from this contract. ## //
// ## This is the contract Interface. ## //
//Hello! Not much to see here but I figured I'd leave space to expand!
}
// Stored SafeMath contract for testing purposes.
// import 'openzeppelin-solidity/contracts/math/SafeMath.sol';
pragma solidity ^0.4.25;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asserts when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
@EnoRage
Copy link

EnoRage commented Oct 7, 2018

pragma solidity ^0.4.25;

contract Example {

modifier Calc() {
    
    _;
    
}

uint256[4] keys; 

uint256 iterator;

mapping(uint256=>string) exams;

function set(uint256 key, string value) {
   
    keys[iterator] = key;
    iterator++;
    exams[key] = value;
}

function get(uint256 key) view returns(string) {
    return exams[key];
}


function run() view {
     for (uint i = 0; i < keys.length; i++) {
         exams[keys[i]];
     }
}

}

@EnoRage
Copy link

EnoRage commented Oct 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment