Consistent spellings of reentrant

Consistent spellings of reentrant

Changed `rentrancy_lock` variable to `reentrancy_lock`

pragma solidity ^0.4.18;

/**
 * @title Helps contracts guard agains rentrancy attacks.
 * @author Remco Bloemen <remco@2π.com>
 * @notice If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {

  /**
   * @dev We use a single lock for the whole contract.
   */
  bool private reentrancy_lock = false;

  /**
   * @dev Prevents a contract from calling itself, directly or indirectly.
   * @notice If you mark a function `nonReentrant`, you should also
   * mark it `external`. Calling one nonReentrant function from
   * another is not supported. Instead, you can implement a
   * `private` function doing the actual work, and a `external`
   * wrapper marked as `nonReentrant`.
   */
  modifier nonReentrant() {
    require(!reentrancy_lock);
    reentrancy_lock = true;
    _;
    reentrancy_lock = false;
  }

}

pragma solidity ^0.4.18;

/**
 * @title Helps contracts guard agains rentrancy attacks.
 * @author Remco Bloemen <remco@2π.com>
 * @notice If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {

  /**
   * @dev We use a single lock for the whole contract.
   */
  bool private rentrancy_lock = false;

  /**
   * @dev Prevents a contract from calling itself, directly or indirectly.
   * @notice If you mark a function `nonReentrant`, you should also
   * mark it `external`. Calling one nonReentrant function from
   * another is not supported. Instead, you can implement a
   * `private` function doing the actual work, and a `external`
   * wrapper marked as `nonReentrant`.
   */
  modifier nonReentrant() {
    require(!rentrancy_lock);
    rentrancy_lock = true;
    _;
    rentrancy_lock = false;
  }

}


fixed data pass through

fixed data pass through

pragma solidity ^0.4.11;

import "./SafeMath.sol";
import "./ERC20.sol";
import "./Power.sol";
import "./ERC223ReceivingContract.sol";

/**
 * Nutz implements a price floor and a price ceiling on the token being
 * sold. It is based of the zeppelin token contract. Nutz implements the
 * https://github.com/ethereum/EIPs/issues/20 interface.
 */
contract Nutz is ERC20 {
  using SafeMath for uint;

  event Purchase(address indexed purchaser, uint256 value);
  event Sell(address indexed seller, uint256 value);

  string public name = "Acebusters Nutz";
  // acebusters units:
  // 10^12 - Nutz   (NTZ)
  // 10^9 - Jonyz
  // 10^6 - Helcz
  // 10^3 - Pascalz
  // 10^0 - Babz
  string public symbol = "NTZ";
  uint256 public decimals = 12;
  uint256 INFINITY = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
  uint256 BABBAGE = 1000000;   // 1 BABBAGE equals 1,000,000 WEI, used as price factor

  uint256 actSupply;
  // contract's ether balance, except all ether parked to be withdrawn
  uint256 public reserve;
  // balanceOf[powerAddr] returns power pool
  // balanceOf[address(this)] returns burn pool
  mapping(address => uint) balances;
  // "allowed[address(this)][x]" ether parked to be withdraw
  mapping (address => mapping (address => uint)) allowed;

  // the Token sale mechanism parameters:
  // ceiling is the number of NTZ returned for 1 ETH
  uint256 public ceiling;
  // floor is the number of NTZ needed, no receive 1 ETH back
  // we say that floor is lower than ceiling, if the number of NTZ needed to sell
  // to receive the same amount of ETH as used in purchase, is higher.
  uint256 public floor;
  address[] public admins;
  address public powerAddr;

  // returns balance
  function balanceOf(address _owner) constant returns (uint) {
    return balances[_owner];
  }

  function totalSupply() constant returns (uint256) {
    // active supply + power pool + burn pool
    return actSupply.add(balances[powerAddr]).add(balances[address(this)]);
  }

  function activeSupply() constant returns (uint256) {
    return actSupply;
  }

  // return remaining allowance
  // if calling return allowed[address(this)][_spender];
  // returns balance of ether parked to be withdrawn
  function allowance(address _owner, address _spender) constant returns (uint) {
    return allowed[_owner][_spender];
  }

  function Nutz(uint256 _downTime) {
    admins.length = 1;
    admins[0] = msg.sender;
    // initial purchase price
    ceiling = 0;
    // initial sale price
    floor = INFINITY;
    powerAddr = new Power(address(this), _downTime);
  }

  // ############################################
  // ########### INTERNAL FUNCTIONS #############
  // ############################################

  function _sellTokens(address _from, uint256 _amountBabz) internal returns (bool) {
    if (floor == INFINITY) {
      throw;
    }

    uint256 amountWei = _amountBabz.mul(BABBAGE).div(floor);
    // make sure power pool shrinks proportional to economy
    uint256 powerPool = balances[powerAddr];
    if (powerPool > 0) {
      uint256 powerShare = powerPool.mul(_amountBabz).div(actSupply);
      balances[powerAddr] = powerPool.sub(powerShare);
    }
    actSupply = actSupply.sub(_amountBabz);
    balances[_from] = balances[_from].sub(_amountBabz);
    reserve = reserve.sub(amountWei);
    allowed[address(this)][_from] = allowed[address(this)][_from].add(amountWei);
    Sell(_from,  _amountBabz);
    return true;
  }

  // withdraw accumulated balance, called by seller or beneficiary
  function _claimEther(address _sender, address _to) internal returns (bool) {
    uint256 amountEth = allowed[address(this)][_sender];
    if (amountEth == 0 || this.balance < amountEth) {
      throw;
    }
    allowed[address(this)][_sender] = 0;
    if (!_to.send(amountEth)) {
      throw;
    }
    return true;
  }

  function _transfer(address _from, address _to, uint256 _amountNtz, bytes _data) internal returns (bool) {
    bytes memory data;
    // power up
    if (_to == powerAddr) {
      data = new bytes(32);
      uint ts = totalSupply();
      assembly { mstore(add(data, 32), ts) }
      actSupply = actSupply.sub(_amountNtz);
    } else {
      data = _data;
    }
    // power down
    if (_from == powerAddr) {
      actSupply = actSupply.add(_amountNtz);
    }

    balances[_from] = balances[_from].sub(_amountNtz);
    balances[_to] = balances[_to].add(_amountNtz);

    // erc223: Retrieve the size of the code on target address, this needs assembly .
    uint256 codeLength;
    assembly {
      codeLength := extcodesize(_to)
    }
    if(codeLength>0) {
      ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
      receiver.tokenFallback(_from, _amountNtz, data);
    }

    Transfer(_from, _to, _amountNtz);
    return true;
  }

  // ############################################
  // ########### ADMIN FUNCTIONS ################
  // ############################################

  modifier onlyAdmins() {
    for (uint256 i = 0; i < admins.length; i++) {
      if (msg.sender == admins[i]) {
        _;
      }
    }
  }

  function addAdmin(address _admin) onlyAdmins {
    for (uint256 i = 0; i < admins.length; i++) {
      if (_admin == admins[i]) {
        throw;
      }
    }
    if (admins.length > 10) {
      throw;
    }
    uint256 pos = admins.length++;
    admins[pos] = _admin;
  }

  function removeAdmin(address _admin) onlyAdmins {
    uint256 pos = 1337;
    for (uint256 i = 0; i < admins.length; i++) {
      if (_admin == admins[i]) {
        pos = i;
      }
    }
    // if not last element, switch with last
    if (pos < admins.length - 1) {
      admins[pos] = admins[admins.length - 1];
    }
    // then cut off the tail
    admins.length--;
  }

  function moveCeiling(uint256 _newCeiling) onlyAdmins {
    if (_newCeiling > floor) {
        throw;
    }
    ceiling = _newCeiling;
  }

  function moveFloor(uint256 _newFloor) onlyAdmins {
    if (_newFloor < ceiling) {
        throw;
    }
    // moveFloor fails if the administrator tries to push the floor so low
    // that the sale mechanism is no longer able to buy back all tokens at
    // the floor price if those funds were to be withdrawn.
    if (_newFloor > 0) {
      uint256 newReserveNeeded = actSupply.mul(BABBAGE).div(_newFloor);
      if (reserve < newReserveNeeded) {
          throw;
      }
    }
    floor = _newFloor;
  }

  function allocateEther(uint256 _amountWei, address _beneficiary) onlyAdmins {
    if (_amountWei == 0) {
        return;
    }
    // allocateEther fails if allocating those funds would mean that the
    // sale mechanism is no longer able to buy back all tokens at the floor
    // price if those funds were to be withdrawn.
    uint256 leftReserve = reserve.sub(_amountWei);
    if (leftReserve < actSupply.mul(BABBAGE).div(floor)) {
        throw;
    }
    reserve = reserve.sub(_amountWei);
    allowed[address(this)][_beneficiary] = allowed[address(this)][_beneficiary].add(_amountWei);
  }

  function dilutePower(uint256 _amountNtz) onlyAdmins {
    uint256 burn = balances[address(this)];
    uint256 totalSupply = actSupply.add(balances[powerAddr]).add(burn);
    if (!Power(powerAddr).dilutePower(totalSupply, _amountNtz)) {
      throw;
    }
    balances[address(this)] = burn.add(_amountNtz);
  }

  function setMaxPower(uint256 _maxPower) onlyAdmins {
    Power(powerAddr).setMaxPower(_maxPower);
  }

  // ############################################
  // ########### PAYABLE FUNCTIONS ##############
  // ############################################

  function () payable {
    purchaseTokens();
  }

  function purchaseTokens() payable {
    if (msg.value == 0) {
      return;
    }
    // disable purchases if ceiling set to 0
    if (ceiling == 0) {
      throw;
    }
    uint256 amountToken = msg.value.mul(ceiling).div(BABBAGE);
    // avoid deposits that issue nothing
    // might happen with very large ceiling
    if (amountToken == 0) {
      throw;
    }
    reserve = reserve.add(msg.value);
    // make sure power pool grows proportional to economy
    if (powerAddr != 0x0 && balances[powerAddr] > 0) {
      uint256 powerShare = balances[powerAddr].mul(amountToken).div(actSupply);
      balances[powerAddr] = balances[powerAddr].add(powerShare);
    }
    actSupply = actSupply.add(amountToken);
    balances[msg.sender] = balances[msg.sender].add(amountToken);
    Purchase(msg.sender, amountToken);
  }

  // ############################################
  // ########### PUBLIC FUNCTIONS ###############
  // ############################################

  function approve(address _spender, uint256 _amountNtz) {
    if (_spender == address(this) || msg.sender == _spender || _amountNtz == 0) {
      throw;
    }
    allowed[msg.sender][_spender] = _amountNtz;
    Approval(msg.sender, _spender, _amountNtz);
  }

  function transfer(address _to, uint256 _amountNtz) returns (bool) {
    bytes memory empty;
    return transfer(_to, _amountNtz, empty);
  }

  function transData(address _to, uint256 _amountNtz, bytes _data) returns (bool) {
    return transfer(_to, _amountNtz, _data);
  }

  function transfer(address _to, uint256 _amountNtz, bytes _data) returns (bool) {
    if (_amountNtz == 0) {
      throw;
    }
    // sell tokens
    if (_to == address(this)) {
      return _sellTokens(msg.sender, _amountNtz);
    }
    return _transfer(msg.sender, _to, _amountNtz, _data);
  }

  function transferFrom(address _from, address _to, uint256 _amountNtz) returns (bool) {
    if (_from == _to) {
      throw;
    }
    // claim ether
    if (_from == address(this) && _amountNtz == 0) {
      return _claimEther(msg.sender, _to);
    }
    if (_amountNtz == 0) {
      throw;
    }
    // sell tokens
    if (_to == address(this)) {
      return _sellTokens(_from, _amountNtz);
    }
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amountNtz);
    bytes memory empty;
    return _transfer(_from, _to, _amountNtz, empty);
  }

}

pragma solidity ^0.4.11;

import "./SafeMath.sol";
import "./ERC20.sol";
import "./Power.sol";
import "./ERC223ReceivingContract.sol";

/**
 * Nutz implements a price floor and a price ceiling on the token being
 * sold. It is based of the zeppelin token contract. Nutz implements the
 * https://github.com/ethereum/EIPs/issues/20 interface.
 */
contract Nutz is ERC20 {
  using SafeMath for uint;

  event Purchase(address indexed purchaser, uint256 value);
  event Sell(address indexed seller, uint256 value);

  string public name = "Acebusters Nutz";
  // acebusters units:
  // 10^12 - Nutz   (NTZ)
  // 10^9 - Jonyz
  // 10^6 - Helcz
  // 10^3 - Pascalz
  // 10^0 - Babz
  string public symbol = "NTZ";
  uint256 public decimals = 12;
  uint256 INFINITY = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
  uint256 BABBAGE = 1000000;   // 1 BABBAGE equals 1,000,000 WEI, used as price factor

  uint256 actSupply;
  // contract's ether balance, except all ether parked to be withdrawn
  uint256 public reserve;
  // balanceOf[powerAddr] returns power pool
  // balanceOf[address(this)] returns burn pool
  mapping(address => uint) balances;
  // "allowed[address(this)][x]" ether parked to be withdraw
  mapping (address => mapping (address => uint)) allowed;

  // the Token sale mechanism parameters:
  // ceiling is the number of NTZ returned for 1 ETH
  uint256 public ceiling;
  // floor is the number of NTZ needed, no receive 1 ETH back
  // we say that floor is lower than ceiling, if the number of NTZ needed to sell
  // to receive the same amount of ETH as used in purchase, is higher.
  uint256 public floor;
  address[] public admins;
  address public powerAddr;

  // returns balance
  function balanceOf(address _owner) constant returns (uint) {
    return balances[_owner];
  }

  function totalSupply() constant returns (uint256) {
    // active supply + power pool + burn pool
    return actSupply.add(balances[powerAddr]).add(balances[address(this)]);
  }

  function activeSupply() constant returns (uint256) {
    return actSupply;
  }

  // return remaining allowance
  // if calling return allowed[address(this)][_spender];
  // returns balance of ether parked to be withdrawn
  function allowance(address _owner, address _spender) constant returns (uint) {
    return allowed[_owner][_spender];
  }

  function Nutz(uint256 _downTime) {
    admins.length = 1;
    admins[0] = msg.sender;
    // initial purchase price
    ceiling = 0;
    // initial sale price
    floor = INFINITY;
    powerAddr = new Power(address(this), _downTime);
  }

  // ############################################
  // ########### INTERNAL FUNCTIONS #############
  // ############################################

  function _sellTokens(address _from, uint256 _amountBabz) internal returns (bool) {
    if (floor == INFINITY) {
      throw;
    }

    uint256 amountWei = _amountBabz.mul(BABBAGE).div(floor);
    // make sure power pool shrinks proportional to economy
    uint256 powerPool = balances[powerAddr];
    if (powerPool > 0) {
      uint256 powerShare = powerPool.mul(_amountBabz).div(actSupply);
      balances[powerAddr] = powerPool.sub(powerShare);
    }
    actSupply = actSupply.sub(_amountBabz);
    balances[_from] = balances[_from].sub(_amountBabz);
    reserve = reserve.sub(amountWei);
    allowed[address(this)][_from] = allowed[address(this)][_from].add(amountWei);
    Sell(_from,  _amountBabz);
    return true;
  }

  // withdraw accumulated balance, called by seller or beneficiary
  function _claimEther(address _sender, address _to) internal returns (bool) {
    uint256 amountEth = allowed[address(this)][_sender];
    if (amountEth == 0 || this.balance < amountEth) {
      throw;
    }
    allowed[address(this)][_sender] = 0;
    if (!_to.send(amountEth)) {
      throw;
    }
    return true;
  }

  function _transfer(address _from, address _to, uint256 _amountNtz, bytes _data) internal returns (bool) {
    bytes memory data;
    // todo: copy data
    // power up
    if (_to == powerAddr) {
      data = new bytes(32);
      uint ts = totalSupply();
      assembly { mstore(add(data, 32), ts) }
      actSupply = actSupply.sub(_amountNtz);
    }
    // power down
    if (_from == powerAddr) {
      actSupply = actSupply.add(_amountNtz);
    }

    balances[_from] = balances[_from].sub(_amountNtz);
    balances[_to] = balances[_to].add(_amountNtz);

    // erc223: Retrieve the size of the code on target address, this needs assembly .
    uint256 codeLength;
    assembly {
      codeLength := extcodesize(_to)
    }
    if(codeLength>0) {
      ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
      receiver.tokenFallback(_from, _amountNtz, data);
    }

    Transfer(_from, _to, _amountNtz);
    return true;
  }

  // ############################################
  // ########### ADMIN FUNCTIONS ################
  // ############################################

  modifier onlyAdmins() {
    for (uint256 i = 0; i < admins.length; i++) {
      if (msg.sender == admins[i]) {
        _;
      }
    }
  }

  function addAdmin(address _admin) onlyAdmins {
    for (uint256 i = 0; i < admins.length; i++) {
      if (_admin == admins[i]) {
        throw;
      }
    }
    if (admins.length > 10) {
      throw;
    }
    uint256 pos = admins.length++;
    admins[pos] = _admin;
  }

  function removeAdmin(address _admin) onlyAdmins {
    uint256 pos = 1337;
    for (uint256 i = 0; i < admins.length; i++) {
      if (_admin == admins[i]) {
        pos = i;
      }
    }
    // if not last element, switch with last
    if (pos < admins.length - 1) {
      admins[pos] = admins[admins.length - 1];
    }
    // then cut off the tail
    admins.length--;
  }

  function moveCeiling(uint256 _newCeiling) onlyAdmins {
    if (_newCeiling > floor) {
        throw;
    }
    ceiling = _newCeiling;
  }

  function moveFloor(uint256 _newFloor) onlyAdmins {
    if (_newFloor < ceiling) {
        throw;
    }
    // moveFloor fails if the administrator tries to push the floor so low
    // that the sale mechanism is no longer able to buy back all tokens at
    // the floor price if those funds were to be withdrawn.
    if (_newFloor > 0) {
      uint256 newReserveNeeded = actSupply.mul(BABBAGE).div(_newFloor);
      if (reserve < newReserveNeeded) {
          throw;
      }
    }
    floor = _newFloor;
  }

  function allocateEther(uint256 _amountWei, address _beneficiary) onlyAdmins {
    if (_amountWei == 0) {
        return;
    }
    // allocateEther fails if allocating those funds would mean that the
    // sale mechanism is no longer able to buy back all tokens at the floor
    // price if those funds were to be withdrawn.
    uint256 leftReserve = reserve.sub(_amountWei);
    if (leftReserve < actSupply.mul(BABBAGE).div(floor)) {
        throw;
    }
    reserve = reserve.sub(_amountWei);
    allowed[address(this)][_beneficiary] = allowed[address(this)][_beneficiary].add(_amountWei);
  }

  function dilutePower(uint256 _amountNtz) onlyAdmins {
    uint256 burn = balances[address(this)];
    uint256 totalSupply = actSupply.add(balances[powerAddr]).add(burn);
    if (!Power(powerAddr).dilutePower(totalSupply, _amountNtz)) {
      throw;
    }
    balances[address(this)] = burn.add(_amountNtz);
  }

  function setMaxPower(uint256 _maxPower) onlyAdmins {
    Power(powerAddr).setMaxPower(_maxPower);
  }

  // ############################################
  // ########### PAYABLE FUNCTIONS ##############
  // ############################################

  function () payable {
    purchaseTokens();
  }

  function purchaseTokens() payable {
    if (msg.value == 0) {
      return;
    }
    // disable purchases if ceiling set to 0
    if (ceiling == 0) {
      throw;
    }
    uint256 amountToken = msg.value.mul(ceiling).div(BABBAGE);
    // avoid deposits that issue nothing
    // might happen with very large ceiling
    if (amountToken == 0) {
      throw;
    }
    reserve = reserve.add(msg.value);
    // make sure power pool grows proportional to economy
    if (powerAddr != 0x0 && balances[powerAddr] > 0) {
      uint256 powerShare = balances[powerAddr].mul(amountToken).div(actSupply);
      balances[powerAddr] = balances[powerAddr].add(powerShare);
    }
    actSupply = actSupply.add(amountToken);
    balances[msg.sender] = balances[msg.sender].add(amountToken);
    Purchase(msg.sender, amountToken);
  }

  // ############################################
  // ########### PUBLIC FUNCTIONS ###############
  // ############################################

  function approve(address _spender, uint256 _amountNtz) {
    if (_spender == address(this) || msg.sender == _spender || _amountNtz == 0) {
      throw;
    }
    allowed[msg.sender][_spender] = _amountNtz;
    Approval(msg.sender, _spender, _amountNtz);
  }

  function transfer(address _to, uint256 _amountNtz) returns (bool) {
    bytes memory empty;
    return transfer(_to, _amountNtz, empty);
  }

  function transData(address _to, uint256 _amountNtz, bytes _data) returns (bool) {
    return transfer(_to, _amountNtz, _data);
  }

  function transfer(address _to, uint256 _amountNtz, bytes _data) returns (bool) {
    if (_amountNtz == 0) {
      throw;
    }
    // sell tokens
    if (_to == address(this)) {
      return _sellTokens(msg.sender, _amountNtz);
    }
    return _transfer(msg.sender, _to, _amountNtz, _data);
  }

  function transferFrom(address _from, address _to, uint256 _amountNtz) returns (bool) {
    if (_from == _to) {
      throw;
    }
    // claim ether
    if (_from == address(this) && _amountNtz == 0) {
      return _claimEther(msg.sender, _to);
    }
    if (_amountNtz == 0) {
      throw;
    }
    // sell tokens
    if (_to == address(this)) {
      return _sellTokens(_from, _amountNtz);
    }
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amountNtz);
    bytes memory empty;
    return _transfer(_from, _to, _amountNtz, empty);
  }

}


Shizzled some smizzle

Shizzled some smizzle

contract IPOI {

  struct Party {
    address addr;
  }

  struct Idea {
    /* Array of parties involved in the idea */
    mapping(uint => Party) parties;
    /* Date stamp */
    uint256 date;
    /* Idea description */
    bytes32 description;
    /* Digital document hash */
    bytes proofDoc;
  }

  //Declares a state variable 'numCampaigns'
  uint numIdeaId;
  //Creates a mapping of Campaign datatypes
  mapping(uint => Idea) ideas;

  // Owner
  address public owner;

  //Set Owner
  function IPOI() {
    owner = msg.sender;
  }

  modifier onlyowner() {
    if (msg.sender == owner)
      _
  }

  // Create initial idea contract
  function createIdea(address[] partiesEntry, bytes32 descriptionEntry) onlyowner returns (uint ideaId) {
    ideaId = numIdeaId++;
    Idea idea = ideas[ideaId];

    for (uint i = 0; i < partiesEntry.length; i++) {
      idea.parties[i].addr = partiesEntry[i];
    }

    idea.date = now;
    idea.description = descriptionEntry;
    bytes32 name = "IPOI Contract Creation";

    majorEventFunc(idea.date, name, descriptionEntry);
  }

  function getOwner() returns(address owner) {
    return owner;
  }

  // Upload documentation for proof of idea (signed signatures?)
  function ideaProofDocument(bytes IPOIProofHash, uint ideaId) onlyowner {
    ideas[ideaId].proofDoc = IPOIProofHash;
    majorEventFunc(block.timestamp, "Entered Idea Proof Document", "Idea proof in IPFS");
  }

  // Log major life events
  function majorEventFunc(uint256 eventTimeStamp, bytes32 name, bytes32 description) {
    MajorEvent(block.timestamp, eventTimeStamp, name, description);
  }

  // Declare event structure
  event MajorEvent(uint256 logTimeStamp, uint256 eventTimeStamp, bytes32 indexed name, bytes32 indexed description);

  function destroy() {
    if (msg.sender == owner) {
      suicide(owner); // send any funds to owner
    }
  }

  // This function gets executed if a transaction with invalid data is sent to
  // the contract or just ether without data. We revert the send so that no-one
  // accidentally loses money when using the contract.
  function() {
    throw;
  }
}

contract Idea {
  // Owner
  address public owner;
  /* Array of parties involved in the idea */
  mapping(uint => address) parties;
  /* Date stamp */
  uint256 public ideaDate;
  /* Idea status */
  bytes32 public ideaStatus;
  /* Digital document hash */
  bytes public ideaProofDoc;

  //Set Owner
  function Idea() {
    owner = msg.sender;
  }
  modifier onlyowner() {
    if (msg.sender == owner)
      _
  }

  // Create initial idea contract
  function createIdea(address[] partiesEntry, bytes32 descriptionEntry) onlyowner {
    for (uint i = 0; i < partiesEntry.length; i++) {
      parties[i] = partiesEntry[i];
    }

    ideaDate = now;
    setStatus("Created");
    bytes32 name = "IPOI Contract Creation";

    majorEventFunc(ideaDate, name, descriptionEntry);
  }

  function getOwner() returns(address owner) {
    return owner;
  }

  // Set the idea status if it changes
  function setStatus(bytes32 status) onlyowner {
    ideaStatus = status;
    majorEventFunc(block.timestamp, "Changed Status", status);
  }

  // Upload documentation for proof of idea (signed signatures?)
  function ideaProofDocument(bytes IPOIProofHash) onlyowner {
    ideaProofDoc = IPOIProofHash;
    majorEventFunc(block.timestamp, "Entered Idea Proof Document", "Idea proof in IPFS");
  }

  // Log major life events
  function majorEventFunc(uint256 eventTimeStamp, bytes32 name, bytes32 description) {
    MajorEvent(block.timestamp, eventTimeStamp, name, description);
  }

  // Declare event structure
  event MajorEvent(uint256 logTimeStamp, uint256 eventTimeStamp, bytes32 indexed name, bytes32 indexed description);

  function destroy() {
    if (msg.sender == owner) {
      suicide(owner); // send any funds to owner
    }
  }

  // This function gets executed if a transaction with invalid data is sent to
  // the contract or just ether without data. We revert the send so that no-one
  // accidentally loses money when using the contract.
  function() {
    throw;
  }
}


team 0 and 1

team 0 and 1

pragma solidity ^0.4.11;

import './ethereum-api/oraclizeAPI.sol';
import './helpers.sol';

contract Bet is usingOraclize {
  enum BET_STATES {
    OPEN,
    TEAM_ZERO_WON,
    TEAM_ONE_WON,
    DRAW,
    ORACLE_UNDECIDED
    }

  BET_STATES bet_state = BET_STATES.OPEN;
  address public resolver;
  bool public is_featured;
  string public title;
  string public description;
  string public category;
  string public team_0; // Team 0 identifier
  string public team_1; // Team 1 identifier
  uint public team_0_bet_sum;
  uint public team_1_bet_sum;
  mapping (address => uint) public bets_to_team_0;
  mapping (address => uint) public bets_to_team_1;

  uint public timestamp_match_begin;
  uint public timestamp_match_end;
  uint public timestamp_hard_deadline; // Hard deadline to end bet
  uint public timestamp_terminate_deadline; // Self-destruct deadline > hard_deadline (this must be big, so people can withdraw their funds)

  uint8 constant TAX = 10;

  string url_oraclize;

  event new_bet(bool for_team, address from, uint amount);
  event new_winner_declared(BET_STATES winner);

  function Bet(address _resolver, string _title, string _category,
               string _team_0, string _team_1, uint _timestamp_match_begin,
               uint _timestamp_match_end, uint _timestamp_hard_deadline,
               uint _timestamp_terminate_deadline, string _url_oraclize) {
    resolver = _resolver;
    title = _title;
    category = _category;
    team_0 = _team_0;
    team_1 = _team_1;
    timestamp_match_begin = _timestamp_match_begin;
    timestamp_match_end = _timestamp_match_end;
    timestamp_terminate_deadline = _timestamp_terminate_deadline;
    url_oraclize = _url_oraclize;
  }

  function arbitrate(BET_STATES result) {
    require(block.timestamp >= timestamp_hard_deadline);
    require(bet_state == BET_STATES.ORACLE_UNDECIDED);
    require(result != BET_STATES.ORACLE_UNDECIDED);
    require(result != BET_STATES.OPEN);

    bet_state = result;
    new_winner_declared(result);
  }

  function __callback(bytes32 myid, string result) {
    // Cannot call after hard deadline
    require(block.timestamp < timestamp_hard_deadline);
    // Oraclize should call this
    require(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    require(block.timestamp >= timestamp_match_end);

    if (Helpers.string_equal(result, team_0))
      bet_state = BET_STATES.TEAM_ZERO_WON;
    else if (Helpers.string_equal(result, team_1))
      bet_state = BET_STATES.TEAM_ONE_WON;
    else
      bet_state = BET_STATES.ORACLE_UNDECIDED;

    new_winner_declared(bet_state);
  }

  function update_result() payable {
    // Can call only when bet is open or undecided
    require(bet_state == BET_STATES.OPEN || bet_state == BET_STATES.ORACLE_UNDECIDED);
    require(block.timestamp >= timestamp_match_end);

    oraclize_query('URL', url_oraclize);
  }

  function toggle_featured() {
    require(msg.sender == resolver);

    is_featured = !is_featured;
  }

  //
  function bet(bool for_team) payable {
    require(block.timestamp < timestamp_match_begin);
    uint prev_sum;

    if (for_team) {
      // Cannot bet in two teams
      require(bets_to_team_1[msg.sender] == 0);
      prev_sum = team_0_bet_sum;
      require((prev_sum + msg.value) >= prev_sum); // Overflow
      team_0_bet_sum += msg.value;
      assert(team_0_bet_sum >= prev_sum);
      bets_to_team_0[msg.sender] += msg.value;
    }
    else {
      // Cannot bet in two teams
      require(bets_to_team_0[msg.sender] == 0);
      prev_sum = team_1_bet_sum;
      require((prev_sum + msg.value) >= prev_sum); // Overflow
      team_1_bet_sum += msg.value;
      assert(team_1_bet_sum >= prev_sum);
      bets_to_team_1[msg.sender] += msg.value;
    }

    new_bet(for_team, msg.sender, msg.value);
  }

  function withdraw() {
    require(block.timestamp < timestamp_match_begin || bet_state == BET_STATES.TEAM_ZERO_WON || bet_state == BET_STATES.TEAM_ONE_WON || bet_state == BET_STATES.DRAW);
    if (block.timestamp < timestamp_match_begin || bet_state == BET_STATES.DRAW) {
        collect_bet();
    }
    else {
        collect_profit();
    }
  }

  // Transfers the user's initial bet back
  function collect_bet() internal {
    require(bets_to_team_0[msg.sender] > 0 || bets_to_team_1[msg.sender] > 0);

    if (bets_to_team_0[msg.sender] > 0) {
      msg.sender.transfer(bets_to_team_0[msg.sender]);
      bets_to_team_0[msg.sender] = 0;
    }
    else { // if (bets_to_team_1[msg.sender] > 0)
      msg.sender.transfer(bets_to_team_1[msg.sender]);
      bets_to_team_1[msg.sender] = 0;
    }
  }

  // Transfers the user's profit
  function collect_profit() internal {
    require( ( bet_state == BET_STATES.TEAM_ZERO_WON && bets_to_team_0[msg.sender] > 0 ) || ( bet_state == BET_STATES.TEAM_ONE_WON && bets_to_team_1[msg.sender] > 0 ) );

    uint bet = 0;
    uint sum = 0;
    uint profit = 0;

    if (bet_state == BET_STATES.TEAM_ZERO_WON && bets_to_team_0[msg.sender] > 0) {
      bet = bets_to_team_0[msg.sender];
      sum = team_0_bet_sum;
      profit = team_1_bet_sum;
    }
    else { // if (BET_STATES.bet_state == TEAM_ONE_WON && bets_to_team_1[msg.sender] > 0)
      bet = bets_to_team_1[msg.sender];
      sum = team_1_bet_sum;
      profit = team_1_bet_sum;
    }

    assert(bet <= sum);

    // Approach one:
    // We might lose precision, but no overflow
    var sender_pc = bet / sum;
    assert(sender_pc >= 0 && sender_pc <= 1);

    var sender_profit = sender_pc * profit;
    assert(sender_profit <= profit);

    // Approach two:
    // Better precision, since multiplication is done first, but may overflow
    //uint sender_profit = (bet * profit) / sum;

    var mul_tax = (sender_profit * TAX);
    require(mul_tax >= sender_profit); // Overflow
    var tax = mul_tax / 100;
    assert(tax <= sender_profit);

    var notax_profit = sender_profit;
    sender_profit -= tax;
    assert(sender_profit <= notax_profit);

    resolver.transfer(tax);
    msg.sender.transfer(sender_profit);

    collect_bet();
  }

  // If the oracle fails or is not able to get the right answer
  function resolve_conflict(uint8 for_team_idx) {
    require(msg.sender == resolver);

  }
}

pragma solidity ^0.4.11;

import './ethereum-api/oraclizeAPI.sol';
import './helpers.sol';

contract Bet is usingOraclize {
  enum BET_STATES {
    OPEN,
    TEAM_ONE_WON,
    TEAM_TWO_WON,
    DRAW,
    ORACLE_UNDECIDED
    }

  BET_STATES bet_state = BET_STATES.OPEN;
  address public resolver;
  bool public is_featured;
  string public title;
  string public description;
  string public category;
  string public team_0; // Team 0 identifier
  string public team_1; // Team 1 identifier
  uint public team_0_bet_sum;
  uint public team_1_bet_sum;
  mapping (address => uint) public bets_to_team_0;
  mapping (address => uint) public bets_to_team_1;

  uint public timestamp_match_begin;
  uint public timestamp_match_end;
  uint public timestamp_hard_deadline; // Hard deadline to end bet
  uint public timestamp_terminate_deadline; // Self-destruct deadline > hard_deadline (this must be big, so people can withdraw their funds)

  uint8 constant TAX = 10;

  string url_oraclize;

  event new_betting(bool for_team, address from, uint amount);
  event new_winner_declared(BET_STATES winner);

  function Bet(address _resolver, string _title, string _category,
               string _team_0, string _team_1, uint _timestamp_match_begin,
               uint _timestamp_match_end, uint _timestamp_hard_deadline,
               uint _timestamp_terminate_deadline, string _url_oraclize) {
    resolver = _resolver;
    title = _title;
    category = _category;
    team_0 = _team_0;
    team_1 = _team_1;
    timestamp_match_begin = _timestamp_match_begin;
    timestamp_match_end = _timestamp_match_end;
    timestamp_terminate_deadline = _timestamp_terminate_deadline;
    url_oraclize = _url_oraclize;
  }

  function arbitrate(BET_STATES result) {
    require(block.timestamp >= timestamp_hard_deadline);
    require(bet_state == BET_STATES.ORACLE_UNDECIDED);
    require(result != BET_STATES.ORACLE_UNDECIDED);
    require(result != BET_STATES.OPEN);

    bet_state = result;
    new_winner_declared(result);
  }

  function __callback(bytes32 myid, string result) {
    // Cannot call after hard deadline
    require(block.timestamp < timestamp_hard_deadline);
    // Oraclize should call this
    require(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    require(block.timestamp >= timestamp_match_end);

    if (Helpers.string_equal(result, team_0))
      bet_state = BET_STATES.TEAM_ONE_WON;
    else if (Helpers.string_equal(result, team_1))
      bet_state = BET_STATES.TEAM_TWO_WON;
    else
      bet_state = BET_STATES.ORACLE_UNDECIDED;

    new_winner_declared(bet_state);
  }

  function update_result() payable {
    // Can call only when bet is open or undecided
    require(bet_state == BET_STATES.OPEN || bet_state == BET_STATES.ORACLE_UNDECIDED);
    require(block.timestamp >= timestamp_match_end);

    oraclize_query('URL', url_oraclize);
  }

  function toggle_featured() {
    require(msg.sender == resolver);

    is_featured = !is_featured;
  }

  //
  function bet(bool for_team) payable {
    require(block.timestamp < timestamp_match_begin);
    uint prev_sum;

    if (for_team) {
      // Cannot bet in two teams
      require(bets_to_team_1[msg.sender] == 0);
      prev_sum = team_0_bet_sum;
      require((prev_sum + msg.value) >= prev_sum); // Overflow
      team_0_bet_sum += msg.value;
      assert(team_0_bet_sum >= prev_sum);
      bets_to_team_0[msg.sender] += msg.value;
    }
    else {
      // Cannot bet in two teams
      require(bets_to_team_0[msg.sender] == 0);
      prev_sum = team_1_bet_sum;
      require((prev_sum + msg.value) >= prev_sum); // Overflow
      team_1_bet_sum += msg.value;
      assert(team_1_bet_sum >= prev_sum);
      bets_to_team_1[msg.sender] += msg.value;
    }

    new_betting(for_team, msg.sender, msg.value);
  }

  function withdraw() {
    require(block.timestamp < timestamp_match_begin || bet_state == BET_STATES.TEAM_ONE_WON || bet_state == BET_STATES.TEAM_TWO_WON || bet_state == BET_STATES.DRAW);
    if (block.timestamp < timestamp_match_begin || bet_state == BET_STATES.DRAW) {
        collect_bet();
    }
    else {
        collect_profit();
    }
  }

  // Transfers the user's initial bet back
  function collect_bet() internal {
    require(bets_to_team_0[msg.sender] > 0 || bets_to_team_1[msg.sender] > 0);

    if (bets_to_team_0[msg.sender] > 0) {
      msg.sender.transfer(bets_to_team_0[msg.sender]);
      bets_to_team_0[msg.sender] = 0;
    }
    else { // if (bets_to_team_1[msg.sender] > 0)
      msg.sender.transfer(bets_to_team_1[msg.sender]);
      bets_to_team_1[msg.sender] = 0;
    }
  }

  // Transfers the user's profit
  function collect_profit() internal {
    require( ( bet_state == BET_STATES.TEAM_ONE_WON && bets_to_team_0[msg.sender] > 0 ) || ( bet_state == BET_STATES.TEAM_TWO_WON && bets_to_team_1[msg.sender] > 0 ) );

    uint bet = 0;
    uint sum = 0;
    uint profit = 0;

    if (bet_state == BET_STATES.TEAM_ONE_WON && bets_to_team_0[msg.sender] > 0) {
      bet = bets_to_team_0[msg.sender];
      sum = team_0_bet_sum;
      profit = team_1_bet_sum;
    }
    else { // if (BET_STATES.bet_state == TEAM_TWO_WON && bets_to_team_1[msg.sender] > 0)
      bet = bets_to_team_1[msg.sender];
      sum = team_1_bet_sum;
      profit = team_1_bet_sum;
    }

    assert(bet <= sum);

    // Approach one:
    // We might lose precision, but no overflow
    var sender_pc = bet / sum;
    assert(sender_pc >= 0 && sender_pc <= 1);

    var sender_profit = sender_pc * profit;
    assert(sender_profit <= profit);

    // Approach two:
    // Better precision, since multiplication is done first, but may overflow
    //uint sender_profit = (bet * profit) / sum;

    var mul_tax = (sender_profit * TAX);
    require(mul_tax >= sender_profit); // Overflow
    var tax = mul_tax / 100;
    assert(tax <= sender_profit);

    var notax_profit = sender_profit;
    sender_profit -= tax;
    assert(sender_profit <= notax_profit);

    resolver.transfer(tax);
    msg.sender.transfer(sender_profit);

    collect_bet();
  }

  // If the oracle fails or is not able to get the right answer
  function resolve_conflict(uint8 for_team_idx) {
    require(msg.sender == resolver);

  }
}


Updated to camelCase

Updated to camelCase

pragma solidity ^0.4.8;

import "./LivepeerToken.sol";
import '../installed_contracts/zeppelin/contracts/SafeMath.sol';

contract LivepeerProtocol is SafeMath {

    // Token address
    LivepeerToken public token;

    // Truebit address
    address public truebitAddress;

    /* Token constants */

    // 1 LPT == 10^18th units
    uint8 decimals = 18;

    // Start with 10M tokens
    uint256 public initialTokenSupply = 10000000 * (10 ** decimals);

    // Fixed inflation rate of 26%
    uint8 public initialYearlyInflation = 26;

    /* Protocol Parameters */

    // Segment length
    uint64 public t;

    // Number of active transcoders
    uint64 public n;

    // Round length in seconds
    uint64 public roundLength;

    // Current round
    uint64 public currentRound;

    // Mapping of round number with start timestamp of round
    uint256[] public roundStartTimestamps;

    // Number of times each transcoder is expected to call Reward() in a round
    uint64 public cyclesPerRound;

    // Time before the start of a round that the transcoders rates lock
    uint64 public rateLockDeadline;

    // Time between unbonding and possible withdrawl
    uint64 public unbondingPeriod;

    // Time that data must be guaranteed in storage for verification
    uint64 public persistenceLength;

    // % of segments to be verified. 1 / verificationRate == % to be verified
    uint64 public verificationRate;

    // Slash % in the case of failed verification
    uint64 public failedVerificationSlashAmount;

    // Slash % in the case of failing to call Reward()
    uint64 public missedRewardSlashAmount;

    // Slash % in the case of missing a call to verification
    uint64 public missedVerificationSlashAmount;

    // % of tolerance for failing to do proper share of work
    uint64 public competitivenessTolerance;

    // % of verifications you can fail before being slashed
    uint64 public verificationFailureThreshold;

    // Represents a transcoder's current state
    struct Transcoder {
        address transcoderAddress;    // The address of this transcoder.
        bool active;                   // Is this transcoder active. Also will be false if uninitialized

        // TODO: add all the state information about pricing, fee split, etc.
    }

    // The various states a delegator can be in
    enum DelegatorStatus { Inactive, Pending, Bonded, Unbonding }

    // Represents a delegator's current state
    struct Delegator {
        address delegatorAddress;       // The ethereum address of this delegator
        uint256 bondedAmount;           // The amount they have bonded
        address transcoderAddress;      // The ethereum address of the transcoder they are delgating towards
        DelegatorStatus status;          // Their current state
        uint64 roundStart;             // The round the delegator transitions to bonded phase
        uint256 withdrawTimestamp;      // The timestamp at which a delegator can withdraw
        bool active;                     // Is this delegator active. Also will be false if uninitialized
    }

    // Keep track of the known transcoders and delegators
    // Note: Casper style implementation would have us using arrays and bitmaps to index these
    mapping (address => Delegator) public delegators;
    mapping (address => Transcoder) public transcoders;

    // Initialize protocol
    function LivepeerProtocol() {
        // Deploy new token contract
        token = new LivepeerToken();

        // Set truebit address
        truebitAddress = 0x647167a598171d06aecf0f5fa1daf3c5cc848df0;

        // Initialize parameters
        // Segment length of 2 seconds
        t = 2;

        // Start with 1 transcoder for testing
        n = 1;

        // Round length of 1 day, with transcoder expected to call reward every 10 minutes
        currentRound = 0;
        roundLength = 1 days;
        roundStartTimestamps.push(block.timestamp);
        cyclesPerRound = roundLength / 10 minutes;

        // Lock rate changes 2 hours before round
        rateLockDeadline = 2 hours;

        // Unbond for 10 days
        unbondingPeriod = 10 days;

        // Keep data in storage for 6 hours
        persistenceLength = 6 hours;

        // Verify 1/500 segments
        verificationRate = 500;

        // Slash percentages
        failedVerificationSlashAmount = 5;
        missedRewardSlashAmount = 3;
        missedVerificationSlashAmount = 10;

        // Expect transcoders to be 90% competitive
        competitivenessTolerance = 90;

        // Fail no more than 1% of the time
        verificationFailureThreshold = 1;

        // Setup initial transcoder
        address tAddr = 0xb7e5575ddb750db2722929905e790de65ef2c078;
        transcoders[tAddr] =
            Transcoder({transcoderAddress: tAddr, active: true});

        // Do initial token distribution - currently clearly fake, minting 3 LPT to the contract creator
        token.mint(msg.sender, 3000000000000000000);

    }

    /**
     * Delegate stake towards a specific address.
     * @param _amount The amount of LPT to stake.
     * @param _to The address of the transcoder to stake towards.
     */
    function bond(uint _amount, address _to) returns (bool) {
        // Check if this is a valid transcoder who is active
        if (transcoders[_to].active == false) throw;

        if (_amount > 0) {
            // Only transfer tokens if _amount is greater than 0
            // Transfer the token. This call throws if it fails.
            token.transferFrom(msg.sender, this, _amount);
        }

        // Update or create this delegator
        Delegator del = delegators[msg.sender];

        if (del.active == false) {
            // Only transition to pending if creating delegator for first time
            del.status = DelegatorStatus.Pending;
            // Only set round start if creating delegator for first time
            del.roundStart = currentRound + 2;
        }

        del.delegatorAddress = msg.sender;
        del.transcoderAddress = _to;
        del.bondedAmount = safeAdd(del.bondedAmount, _amount);
        del.withdrawTimestamp = 0;
        del.active = true;
        delegators[msg.sender] = del;

        return true;
    }

    /**
     * Finalize bond and transition a delegator to the bonded phase
     * Can only be called if it has been 2 rounds since a delegator originally bonded
     */
    function finalizeBond() returns (bool) {
        // Check if delegator is in pending phase
        if (delegators[msg.sender].status != DelegatorStatus.Pending) throw;
        // Check if the current round is the delegator's start round
        if (delegators[msg.sender].roundStart < currentRound) throw;

        delegators[msg.sender].status = DelegatorStatus.Bonded;

        return true;
    }

    /**
     * Unbond your current stake. This will enter the unbonding phase for
     * the unbondingPeriod.
     */
    function unbond() returns (bool) {
        // Check if this is an active delegator
        if (delegators[msg.sender].active == false) throw;
        // Check if delegator is in bonded status
        if (delegators[msg.sender].status != DelegatorStatus.Bonded) throw;

        // Transition to unbonding phase
        delegators[msg.sender].status = DelegatorStatus.Unbonding;
        delegators[msg.sender].withdrawTimestamp = block.timestamp + unbondingPeriod;

        return true;
    }

    /**
     * Withdraws withdrawable funds back to the caller after unbonding period.
     */
    function withdraw() returns (bool) {
        // Check if this is an active delegator
        if (delegators[msg.sender].active == false) throw;
        // Check if active delegator is in unbonding phase
        if (delegators[msg.sender].status != DelegatorStatus.Unbonding) throw;
        // Check if active delegator's unbonding period is over
        if (block.timestamp < delegators[msg.sender].withdrawTimestamp) throw;

        // Transfer token. This call throws if it fails.
        token.transfer(msg.sender, delegators[msg.sender].bondedAmount);

        // Delete delegator
        delete delegators[msg.sender];

        return true;
    }

    /**
     * Active transcoders call this once per cycle when it is their turn.
     * Distribute the token rewards to transcoder and delegates.
     */
    function reward() returns (bool) {

        return true;
    }

    /**
     * The sender is declaring themselves as a candidate for active transcoding.
     */
    function transcoder() returns (bool) {
        transcoders[msg.sender] = Transcoder({transcoderAddress: msg.sender, active: true});
        return true;
    }

    /**
     * Move to the next round
     * Can only be called if the current round is over
     */
    function nextRound() {
        // Check if current round is over
        if (block.timestamp < roundStartTimestamps[currentRound] + roundLength) throw;

        currentRound += 1;
        roundStartTimestamps.push(block.timestamp);
    }
}

pragma solidity ^0.4.8;

import "./LivepeerToken.sol";
import '../installed_contracts/zeppelin/contracts/SafeMath.sol';

contract LivepeerProtocol is SafeMath {

    // Token address
    LivepeerToken public token;

    // Truebit address
    address public truebitAddress;

    /* Token constants */

    // 1 LPT == 10^18th units
    uint8 decimals = 18;

    // Start with 10M tokens
    uint256 public initialTokenSupply = 10000000 * (10 ** decimals);

    // Fixed inflation rate of 26%
    uint8 public initialYearlyInflation = 26;

    /* Protocol Parameters */

    // Segment length
    uint64 public t;

    // Number of active transcoders
    uint64 public n;

    // Round length in seconds
    uint64 public roundLength;

    // Current round
    uint64 public currentRound;

    // Mapping of round number with start timestamp of round
    uint256[] public roundStartTimestamps;

    // Number of times each transcoder is expected to call Reward() in a round
    uint64 public cyclesPerRound;

    // Time before the start of a round that the transcoders rates lock
    uint64 public rateLockDeadline;

    // Time between unbonding and possible withdrawl
    uint64 public unbondingPeriod;

    // Time that data must be guaranteed in storage for verification
    uint64 public persistenceLength;

    // % of segments to be verified. 1 / verificationRate == % to be verified
    uint64 public verificationRate;

    // Slash % in the case of failed verification
    uint64 public failedVerificationSlashAmount;

    // Slash % in the case of failing to call Reward()
    uint64 public missedRewardSlashAmount;

    // Slash % in the case of missing a call to verification
    uint64 public missedVerificationSlashAmount;

    // % of tolerance for failing to do proper share of work
    uint64 public competitivenessTolerance;

    // % of verifications you can fail before being slashed
    uint64 public verificationFailureThreshold;

    // Represents a transcoder's current state
    struct Transcoder {
        address transcoder_address;    // The address of this transcoder.
        bool active;                   // Is this transcoder active. Also will be false if uninitialized

        // TODO: add all the state information about pricing, fee split, etc.
    }

    // The various states a delegator can be in
    enum DelegatorStatus { Inactive, Pending, Bonded, Unbonding }

    // Represents a delegator's current state
    struct Delegator {
        address delegator_address;       // The ethereum address of this delegator
        uint256 bonded_amount;           // The amount they have bonded
        address transcoder_address;      // The ethereum address of the transcoder they are delgating towards
        DelegatorStatus status;          // Their current state
        uint64 round_start;             // The round the delegator transitions to bonded phase
        uint256 withdraw_timestamp;      // The timestamp at which a delegator can withdraw
        bool active;                     // Is this delegator active. Also will be false if uninitialized
    }

    // Keep track of the known transcoders and delegators
    // Note: Casper style implementation would have us using arrays and bitmaps to index these
    mapping (address => Delegator) public delegators;
    mapping (address => Transcoder) public transcoders;

    // Initialize protocol
    function LivepeerProtocol() {
        // Deploy new token contract
        token = new LivepeerToken();

        // Set truebit address
        truebitAddress = 0x647167a598171d06aecf0f5fa1daf3c5cc848df0;

        // Initialize parameters
        // Segment length of 2 seconds
        t = 2;

        // Start with 1 transcoder for testing
        n = 1;

        // Round length of 1 day, with transcoder expected to call reward every 10 minutes
        currentRound = 0;
        roundLength = 1 days;
        roundStartTimestamps.push(block.timestamp);
        cyclesPerRound = roundLength / 10 minutes;

        // Lock rate changes 2 hours before round
        rateLockDeadline = 2 hours;

        // Unbond for 10 days
        unbondingPeriod = 10 days;

        // Keep data in storage for 6 hours
        persistenceLength = 6 hours;

        // Verify 1/500 segments
        verificationRate = 500;

        // Slash percentages
        failedVerificationSlashAmount = 5;
        missedRewardSlashAmount = 3;
        missedVerificationSlashAmount = 10;

        // Expect transcoders to be 90% competitive
        competitivenessTolerance = 90;

        // Fail no more than 1% of the time
        verificationFailureThreshold = 1;

        // Setup initial transcoder
        address t_addr = 0xb7e5575ddb750db2722929905e790de65ef2c078;
        transcoders[t_addr] =
            Transcoder({transcoder_address: t_addr, active: true});

        // Do initial token distribution - currently clearly fake, minting 3 LPT to the contract creator
        token.mint(msg.sender, 3000000000000000000);

    }

    /**
     * Delegate stake towards a specific address.
     * @param _amount The amount of LPT to stake.
     * @param _to The address of the transcoder to stake towards.
     */
    function bond(uint _amount, address _to) returns (bool) {
        // Check if this is a valid transcoder who is active
        if (transcoders[_to].active == false) throw;

        if (_amount > 0) {
            // Only transfer tokens if _amount is greater than 0
            // Transfer the token. This call throws if it fails.
            token.transferFrom(msg.sender, this, _amount);
        }

        // Update or create this delegator
        Delegator del = delegators[msg.sender];

        if (del.active == false) {
            // Only transition to pending if creating delegator for first time
            del.status = DelegatorStatus.Pending;
            // Only set round start if creating delegator for first time
            del.round_start = currentRound + 2;
        }

        del.delegator_address = msg.sender;
        del.transcoder_address = _to;
        del.bonded_amount = safeAdd(del.bonded_amount, _amount);
        del.withdraw_timestamp = 0;
        del.active = true;
        delegators[msg.sender] = del;

        return true;
    }

    /**
     * Finalize bond and transition a delegator to the bonded phase
     * Can only be called if it has been 2 rounds since a delegator originally bonded
     */
    function finalizeBond() returns (bool) {
        // Check if delegator is in pending phase
        if (delegators[msg.sender].status != DelegatorStatus.Pending) throw;
        // Check if the current round is the delegator's start round
        if (delegators[msg.sender].round_start < currentRound) throw;

        delegators[msg.sender].status = DelegatorStatus.Bonded;

        return true;
    }

    /**
     * Unbond your current stake. This will enter the unbonding phase for
     * the unbondingPeriod.
     */
    function unbond() returns (bool) {
        // Check if this is an active delegator
        if (delegators[msg.sender].active == false) throw;
        // Check if delegator is in bonded status
        if (delegators[msg.sender].status != DelegatorStatus.Bonded) throw;

        // Transition to unbonding phase
        delegators[msg.sender].status = DelegatorStatus.Unbonding;
        delegators[msg.sender].withdraw_timestamp = block.timestamp + unbondingPeriod;

        return true;
    }

    /**
     * Withdraws withdrawable funds back to the caller after unbonding period.
     */
    function withdraw() returns (bool) {
        // Check if this is an active delegator
        if (delegators[msg.sender].active == false) throw;
        // Check if active delegator is in unbonding phase
        if (delegators[msg.sender].status != DelegatorStatus.Unbonding) throw;
        // Check if active delegator's unbonding period is over
        if (block.timestamp < delegators[msg.sender].withdraw_timestamp) throw;

        // Transfer token. This call throws if it fails.
        token.transfer(msg.sender, delegators[msg.sender].bonded_amount);

        // Delete delegator
        delete delegators[msg.sender];

        return true;
    }

    /**
     * Active transcoders call this once per cycle when it is their turn.
     * Distribute the token rewards to transcoder and delegates.
     */
    function reward() returns (bool) {

        return true;
    }

    /**
     * The sender is declaring themselves as a candidate for active transcoding.
     */
    function transcoder() returns (bool) {
        transcoders[msg.sender] = Transcoder({transcoder_address: msg.sender, active: true});
        return true;
    }

    /**
     * Move to the next round
     * Can only be called if the current round is over
     */
    function nextRound() {
        // Check if current round is over
        if (block.timestamp < roundStartTimestamps[currentRound] + roundLength) throw;

        currentRound += 1;
        roundStartTimestamps.push(block.timestamp);
    }
}


Remove deprecated CashFlow contract

Remove deprecated CashFlow contract

pragma solidity ^0.4.4;
import './Proposal.sol';
import 'lib/AddressList.sol';
import 'common/Mortal.sol';
import 'token/Token.sol';

contract CashFlow is Owned {
    Token public credits;
    Token public shares;

    // Proposal list
    Proposal[] public proposals;

    // Events
    event Created(address indexed proposal);
    event Updated(address indexed proposal);
    event Closed(address indexed proposal);

    // Constructor
    function CashFlow(address _credits, address _shares) {
        credits = Token(_credits);
        shares  = Token(_shares);
    }

    /**
     * @dev Nominal price of one share in credits
     * @return amount of credits in one share
     */
    function nominalSharePrice() constant returns (uint)
    { return credits.getBalance() / shares.totalSupply(); }

    /**
     * @dev Initial new proposal
     * @param _target is a destination address
     * @param _total is a credits goal
     * @param _description is a short description of new proposal
     * @return proposal address
     */
    function proposal(address _target, uint _total, string _description) returns (Proposal) {
        var proposal = new Proposal(_target, _total, _description);
        proposals.push(proposal);
        Created(proposal);
        return proposal;
    }

    /**
     * @dev Vote for the proposal
     * @param _proposal is an proposal instance
     * @param _value is a count of given shares
     */
    function fund(Proposal _proposal, uint _value) {
        if (_proposal.closed() > 0 ||
            shares.getBalance(msg.sender) < _value) throw;

        var share_price = nominalSharePrice();
        var summary     = _proposal.summaryShares() + _value;

        bool overload = summary * share_price > _proposal.targetValue();
        if (overload) {
            var correction = summary * share_price - _proposal.targetValue();
            _value -= correction / share_price;
        }

        // Transfer shares
        shares.transferFrom(msg.sender, this, _value);

        // Append new funder
        _proposal.appendFunder(msg.sender);
        _proposal.setSharesOf(msg.sender, _proposal.sharesOf(msg.sender) + _value);
        _proposal.setSummaryShares(_proposal.summaryShares() + _value);

        // Is proposal done?
        if (_proposal.summaryShares() * share_price >= _proposal.targetValue()) {
            // Transfer credits
            if (!credits.transfer(_proposal.destination(),
                                  _proposal.targetValue())) throw;

            // Close proposal
            _proposal.close();
            _proposal.setSharePrice(share_price);
            Closed(_proposal);
        } else {
            Updated(_proposal);
        }
    }

    /**
     * @dev Refund shares from proposal
     * @param _proposal is a proposal instance
     * @param _value is how amount shares will be refunded
     * @notice target proposal should be open
     */
    function refund(Proposal _proposal, uint _value) {
        uint sender_balance = _proposal.sharesOf(msg.sender);
        uint refund_shares  = 0;

        if (_proposal.closed() > 0) {
            // CLOSED proposal
            var free_shares  = sender_balance
                             * _proposal.backValue()
                             / _proposal.targetValue();

            refund_shares = free_shares > sender_balance
                          ? sender_balance : free_shares;
            refund_shares = refund_shares > _value
                          ? _value : refund_shares;

            _proposal.setRefunSharesOf(msg.sender, refund_shares);
        } else {
            // OPEN proposal
            refund_shares  = sender_balance > _value ? _value : sender_balance;

            _proposal.setSharesOf(msg.sender, sender_balance - refund_shares);
            _proposal.setSummaryShares(_proposal.summaryShares() - refund_shares);
        }

        if (!shares.transfer(msg.sender, refund_shares)) throw;
        Updated(_proposal);
    }

    /**
     * @dev Request for release shares by sending
     * @param _proposal is a proposal instance
     * @param _value is a value of returned credits
     */
    function fundback(Proposal _proposal, uint _value) {
        // Try to take a credits
        if (!credits.transferFrom(msg.sender, this, _value)) throw;

        // Update back value
        _proposal.setBackValue(_proposal.backValue() + _value);
        Updated(_proposal);
    }
}


Fix typos in ERC20 docs (#2364)

Fix typos in ERC20 docs (#2364)

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}