Minor wording fixes `ERC4626` contract (#3510)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../utils/SafeERC20.sol";
import "../../../interfaces/IERC4626.sol";
import "../../../utils/math/Math.sol";

/**
 * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in
 * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].
 *
 * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for
 * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends
 * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this
 * contract and not the "assets" token which is an independent contract.
 *
 * CAUTION: Deposits and withdrawals may incur unexpected slippage. Users should verify that the amount received of
 * shares or assets is as expected. EOAs should operate through a wrapper that performs these checks such as
 * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].
 *
 * _Available since v4.7._
 */
abstract contract ERC4626 is ERC20, IERC4626 {
    using Math for uint256;

    IERC20Metadata private immutable _asset;

    /**
     * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).
     */
    constructor(IERC20Metadata asset_) {
        _asset = asset_;
    }

    /** @dev See {IERC4262-asset}. */
    function asset() public view virtual override returns (address) {
        return address(_asset);
    }

    /** @dev See {IERC4262-totalAssets}. */
    function totalAssets() public view virtual override returns (uint256) {
        return _asset.balanceOf(address(this));
    }

    /** @dev See {IERC4262-convertToShares}. */
    function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) {
        return _convertToShares(assets, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-convertToAssets}. */
    function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) {
        return _convertToAssets(shares, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-maxDeposit}. */
    function maxDeposit(address) public view virtual override returns (uint256) {
        return _isVaultCollateralized() ? type(uint256).max : 0;
    }

    /** @dev See {IERC4262-maxMint}. */
    function maxMint(address) public view virtual override returns (uint256) {
        return type(uint256).max;
    }

    /** @dev See {IERC4262-maxWithdraw}. */
    function maxWithdraw(address owner) public view virtual override returns (uint256) {
        return _convertToAssets(balanceOf(owner), Math.Rounding.Down);
    }

    /** @dev See {IERC4262-maxRedeem}. */
    function maxRedeem(address owner) public view virtual override returns (uint256) {
        return balanceOf(owner);
    }

    /** @dev See {IERC4262-previewDeposit}. */
    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-previewMint}. */
    function previewMint(uint256 shares) public view virtual override returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Up);
    }

    /** @dev See {IERC4262-previewWithdraw}. */
    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Up);
    }

    /** @dev See {IERC4262-previewRedeem}. */
    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-deposit}. */
    function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {
        require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max");

        uint256 shares = previewDeposit(assets);
        _deposit(_msgSender(), receiver, assets, shares);

        return shares;
    }

    /** @dev See {IERC4262-mint}. */
    function mint(uint256 shares, address receiver) public virtual override returns (uint256) {
        require(shares <= maxMint(receiver), "ERC4626: mint more than max");

        uint256 assets = previewMint(shares);
        _deposit(_msgSender(), receiver, assets, shares);

        return assets;
    }

    /** @dev See {IERC4262-withdraw}. */
    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual override returns (uint256) {
        require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max");

        uint256 shares = previewWithdraw(assets);
        _withdraw(_msgSender(), receiver, owner, assets, shares);

        return shares;
    }

    /** @dev See {IERC4262-redeem}. */
    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual override returns (uint256) {
        require(shares <= maxRedeem(owner), "ERC4626: redeem more than max");

        uint256 assets = previewRedeem(shares);
        _withdraw(_msgSender(), receiver, owner, assets, shares);

        return assets;
    }

    /**
     * @dev Internal conversion function (from assets to shares) with support for rounding direction.
     *
     * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset
     * would represent an infinite amout of shares.
     */
    function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256 shares) {
        uint256 supply = totalSupply();
        return
            (assets == 0 || supply == 0)
                ? assets.mulDiv(10**decimals(), 10**_asset.decimals(), rounding)
                : assets.mulDiv(supply, totalAssets(), rounding);
    }

    /**
     * @dev Internal conversion function (from shares to assets) with support for rounding direction.
     */
    function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256 assets) {
        uint256 supply = totalSupply();
        return
            (supply == 0)
                ? shares.mulDiv(10**_asset.decimals(), 10**decimals(), rounding)
                : shares.mulDiv(totalAssets(), supply, rounding);
    }

    /**
     * @dev Deposit/mint common workflow.
     */
    function _deposit(
        address caller,
        address receiver,
        uint256 assets,
        uint256 shares
    ) internal virtual {
        // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the
        // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,
        // calls the vault, which is assumed not malicious.
        //
        // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the
        // assets are transfered and before the shares are minted, which is a valid state.
        // slither-disable-next-line reentrancy-no-eth
        SafeERC20.safeTransferFrom(_asset, caller, address(this), assets);
        _mint(receiver, shares);

        emit Deposit(caller, receiver, assets, shares);
    }

    /**
     * @dev Withdraw/redeem common workflow.
     */
    function _withdraw(
        address caller,
        address receiver,
        address owner,
        uint256 assets,
        uint256 shares
    ) internal virtual {
        if (caller != owner) {
            _spendAllowance(owner, caller, shares);
        }

        // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the
        // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,
        // calls the vault, which is assumed not malicious.
        //
        // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the
        // shares are burned and after the assets are transfered, which is a valid state.
        _burn(owner, shares);
        SafeERC20.safeTransfer(_asset, receiver, assets);

        emit Withdraw(caller, receiver, owner, assets, shares);
    }

    function _isVaultCollateralized() private view returns (bool) {
        return totalAssets() > 0 || totalSupply() == 0;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../utils/SafeERC20.sol";
import "../../../interfaces/IERC4626.sol";
import "../../../utils/math/Math.sol";

/**
 * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in
 * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].
 *
 * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for
 * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends
 * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this
 * contract and not the "assets" token which is an independent contract.
 *
 * CAUTION: Deposits and withdrawals may incur unexpected slippage. Users should verify that the amount received of
 * shares or assets is as expected. EOAs should operate through a wrapper that performs these checks such as
 * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].
 *
 * _Available since v4.7._
 */
abstract contract ERC4626 is ERC20, IERC4626 {
    using Math for uint256;

    IERC20Metadata private immutable _asset;

    /**
     * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).
     */
    constructor(IERC20Metadata asset_) {
        _asset = asset_;
    }

    /** @dev See {IERC4262-asset} */
    function asset() public view virtual override returns (address) {
        return address(_asset);
    }

    /** @dev See {IERC4262-totalAssets} */
    function totalAssets() public view virtual override returns (uint256) {
        return _asset.balanceOf(address(this));
    }

    /** @dev See {IERC4262-convertToShares} */
    function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) {
        return _convertToShares(assets, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-convertToAssets} */
    function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) {
        return _convertToAssets(shares, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-maxDeposit} */
    function maxDeposit(address) public view virtual override returns (uint256) {
        return _isVaultCollateralized() ? type(uint256).max : 0;
    }

    /** @dev See {IERC4262-maxMint} */
    function maxMint(address) public view virtual override returns (uint256) {
        return type(uint256).max;
    }

    /** @dev See {IERC4262-maxWithdraw} */
    function maxWithdraw(address owner) public view virtual override returns (uint256) {
        return _convertToAssets(balanceOf(owner), Math.Rounding.Down);
    }

    /** @dev See {IERC4262-maxRedeem} */
    function maxRedeem(address owner) public view virtual override returns (uint256) {
        return balanceOf(owner);
    }

    /** @dev See {IERC4262-previewDeposit} */
    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-previewMint} */
    function previewMint(uint256 shares) public view virtual override returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Up);
    }

    /** @dev See {IERC4262-previewWithdraw} */
    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Up);
    }

    /** @dev See {IERC4262-previewRedeem} */
    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Down);
    }

    /** @dev See {IERC4262-deposit} */
    function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {
        require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max");

        uint256 shares = previewDeposit(assets);
        _deposit(_msgSender(), receiver, assets, shares);

        return shares;
    }

    /** @dev See {IERC4262-mint} */
    function mint(uint256 shares, address receiver) public virtual override returns (uint256) {
        require(shares <= maxMint(receiver), "ERC4626: mint more than max");

        uint256 assets = previewMint(shares);
        _deposit(_msgSender(), receiver, assets, shares);

        return assets;
    }

    /** @dev See {IERC4262-withdraw} */
    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual override returns (uint256) {
        require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max");

        uint256 shares = previewWithdraw(assets);
        _withdraw(_msgSender(), receiver, owner, assets, shares);

        return shares;
    }

    /** @dev See {IERC4262-redeem} */
    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual override returns (uint256) {
        require(shares <= maxRedeem(owner), "ERC4626: redeem more than max");

        uint256 assets = previewRedeem(shares);
        _withdraw(_msgSender(), receiver, owner, assets, shares);

        return assets;
    }

    /**
     * @dev Internal convertion function (from assets to shares) with support for rounding direction
     *
     * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset
     * would represent an infinite amout of shares.
     */
    function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256 shares) {
        uint256 supply = totalSupply();
        return
            (assets == 0 || supply == 0)
                ? assets.mulDiv(10**decimals(), 10**_asset.decimals(), rounding)
                : assets.mulDiv(supply, totalAssets(), rounding);
    }

    /**
     * @dev Internal convertion function (from shares to assets) with support for rounding direction
     */
    function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256 assets) {
        uint256 supply = totalSupply();
        return
            (supply == 0)
                ? shares.mulDiv(10**_asset.decimals(), 10**decimals(), rounding)
                : shares.mulDiv(totalAssets(), supply, rounding);
    }

    /**
     * @dev Deposit/mint common workflow
     */
    function _deposit(
        address caller,
        address receiver,
        uint256 assets,
        uint256 shares
    ) internal virtual {
        // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the
        // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,
        // calls the vault, which is assumed not malicious.
        //
        // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the
        // assets are transfered and before the shares are minted, which is a valid state.
        // slither-disable-next-line reentrancy-no-eth
        SafeERC20.safeTransferFrom(_asset, caller, address(this), assets);
        _mint(receiver, shares);

        emit Deposit(caller, receiver, assets, shares);
    }

    /**
     * @dev Withdraw/redeem common workflow
     */
    function _withdraw(
        address caller,
        address receiver,
        address owner,
        uint256 assets,
        uint256 shares
    ) internal virtual {
        if (caller != owner) {
            _spendAllowance(owner, caller, shares);
        }

        // If _asset is ERC777, `transfer` can trigger trigger a reentrancy AFTER the transfer happens through the
        // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,
        // calls the vault, which is assumed not malicious.
        //
        // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the
        // shares are burned and after the assets are transfered, which is a valid state.
        _burn(owner, shares);
        SafeERC20.safeTransfer(_asset, receiver, assets);

        emit Withdraw(caller, receiver, owner, assets, shares);
    }

    function _isVaultCollateralized() private view returns (bool) {
        return totalAssets() > 0 || totalSupply() == 0;
    }
}


Add assembly if regression test source

Add assembly if regression test source

pragma solidity ^0.5.0;

contract Test {

  /// @notice Checks if a given address is whitelisted
  /// @return true if address is whitelisted, false if not
  function isWhitelisted
  (
    address _address
  )
    public
    view
    returns (bool _isWhitelisted)
  {
    bytes4 _signature = bytes4(keccak256("whitelisted(address)"));
    address _whitelistContract = getContractAddress("Whitelist");

    assembly {
      let _pointer := mload(0x40)  // Set _pointer to free memory pointer
      mstore(_pointer, _signature) // Store _signature at _pointer
      mstore(add(_pointer, 0x04), _address) // Store _address at _pointer. Offset by 4 bytes for previously stored _signature

      // staticcall(g, a, in, insize, out, outsize) => returns 0 on error, 1 on success
      let result := staticcall(
        gas,                // g = gas: whatever was passed already
        _whitelistContract, // a = address: _whitelist address assigned from getContractAddress()
        _pointer,           // in = mem in  mem[in..(in+insize): set to _pointer pointer
        0x24,               // insize = mem insize  mem[in..(in+insize): size of signature (bytes4) + bytes32 = 0x24
        _pointer,           // out = mem out  mem[out..(out+outsize): output assigned to this storage address
        0x20                // outsize = mem outsize  mem[out..(out+outsize): output should be 32byte slot (bool size = 0x01 < slot size 0x20)
      )

      // Revert if not successful
      if iszero(result) {
        revert(0, 0)
      }

      _isWhitelisted := mload(_pointer) // Assign result to returned value
      mstore(0x40, add(_pointer, 0x24)) // Advance free memory pointer by largest _pointer size
    }
  }
}

error: pathspec 'test/sources/assembly/if.sol' did not match any file(s) known to git


getCandidateList in ballot

getCandidateList in ballot

pragma solidity ^0.4.6;
// We have to specify what version of compiler this code will compile with

contract Ballot {

    struct Voter {
        uint weight;
        bool voted;
    }

    address public admin;
    bytes32[] public candidateList;
    mapping(address => Voter) public votersList;
    mapping(address => uint8) public candidateSubmissionNumbers;
    mapping (bytes32 => uint8) public votesForCandidates;
    bytes32[] private winners;
    //phase 0: registration. phase 1: voting. phase 2: calculate winner
    //phase 3: end of election
    uint8 private phase;

  function Ballot() {
      phase = 0;
      admin = msg.sender;
  }

  function addCandidate(bytes32 candidate) {
      if (phase == 0) {
          if (candidate == "") return;
          if (validCandidate(candidate)) return;
          if (candidateSubmissionNumbers[msg.sender] > 5) return;
          candidateList.push(candidate);
          candidateSubmissionNumbers[msg.sender] += 1;
      }
  }

   function getCandidateList() returns (bytes32[]) {
      return candidateList;
  }

  function startVoting() {
      if (msg.sender == admin) {
        phase = 1;
      }
  }

  function finishVoting() {
      if (msg.sender == admin) {
        phase = 2;
      }
  }

  function getPhase() returns (uint8) {
      return phase;
  }

  function addVoter(address voter) {
      if (phase == 0) {
        votersList[voter] = Voter({weight: 1, voted: false});
      }
  }

  function totalVotesFor(bytes32 candidate) returns (uint8) {
    if (validCandidate(candidate) == false) throw;
    return votesForCandidates[candidate];
  }

  function vote(bytes32 candidate) {
    if (phase == 1) {
        if (votersList[msg.sender].weight != 1 || votersList[msg.sender].voted) return;
        if (validCandidate(candidate) == false) throw;
        votesForCandidates[candidate] += 1;
        votersList[msg.sender].voted = true;
    }
  }

  function validCandidate(bytes32 candidate) returns (bool) {
    for(uint i = 0; i < candidateList.length; i++) {
      if (candidateList[i] == candidate) {
        return true;
      }
    }
    return false;
  }

  function calculateWinner() returns (bytes32[]) {
      if (phase == 2 && msg.sender == admin) {
        uint maxVotes = 0;
        for (uint i = 0; i < candidateList.length; i++) {
            if (votesForCandidates[candidateList[i]] == maxVotes) {
                winners.push(candidateList[i]);
            } else if (votesForCandidates[candidateList[i]] > maxVotes) {
                winners = new bytes32[](0);
                maxVotes = votesForCandidates[candidateList[i]];
                winners.push(candidateList[i]);
            }
        }
        phase = 3;
        return winners;
      }
  }

  function getWinner() returns (bytes32[]) {
      if (phase == 3) {
          return winners;
      }
  }
}

pragma solidity ^0.4.6;
// We have to specify what version of compiler this code will compile with

contract Ballot {

    struct Voter {
        uint weight;
        bool voted;
    }

    address public admin;
    bytes32[] public candidateList;
    mapping(address => Voter) public votersList;
    mapping(address => uint8) public candidateSubmissionNumbers;
    mapping (bytes32 => uint8) public votesForCandidates;
    bytes32[] private winners;
    //phase 0: registration. phase 1: voting. phase 2: calculate winner
    //phase 3: end of election
    uint8 private phase;

  function Ballot() {
      phase = 0;
      admin = msg.sender;
  }

  function addCandidate(bytes32 candidate) {
      if (phase == 0) {
          if (candidate == "") return;
          if (validCandidate(candidate)) return;
          if (candidateSubmissionNumbers[msg.sender] > 5) return;
          candidateList.push(candidate);
          candidateSubmissionNumbers[msg.sender] += 1;
      }
  }

  function startVoting() {
      if (msg.sender == admin) {
        phase = 1;
      }
  }

  function finishVoting() {
      if (msg.sender == admin) {
        phase = 2;
      }
  }

  function getPhase() returns (uint8) {
      return phase;
  }

  function addVoter(address voter) {
      if (phase == 0) {
        votersList[voter] = Voter({weight: 1, voted: false});
      }
  }

  function totalVotesFor(bytes32 candidate) returns (uint8) {
    if (validCandidate(candidate) == false) throw;
    return votesForCandidates[candidate];
  }

  function vote(bytes32 candidate) {
    if (phase == 1) {
        if (votersList[msg.sender].weight != 1 || votersList[msg.sender].voted) return;
        if (validCandidate(candidate) == false) throw;
        votesForCandidates[candidate] += 1;
        votersList[msg.sender].voted = true;
    }
  }

  function validCandidate(bytes32 candidate) returns (bool) {
    for(uint i = 0; i < candidateList.length; i++) {
      if (candidateList[i] == candidate) {
        return true;
      }
    }
    return false;
  }

  function calculateWinner() returns (bytes32[]) {
      if (phase == 2 && msg.sender == admin) {
        uint maxVotes = 0;
        for (uint i = 0; i < candidateList.length; i++) {
            if (votesForCandidates[candidateList[i]] == maxVotes) {
                winners.push(candidateList[i]);
            } else if (votesForCandidates[candidateList[i]] > maxVotes) {
                winners = new bytes32[](0);
                maxVotes = votesForCandidates[candidateList[i]];
                winners.push(candidateList[i]);
            }
        }
        phase = 3;
        return winners;
      }
  }

  function getWinner() returns (bytes32[]) {
      if (phase == 3) {
          return winners;
      }
  }
}


comment and fix

comment and fix

pragma solidity ^0.4.8;
import "./SafeMath.sol";
import "./RLC.sol";

/*
  Crowdsale Smart Contract for the iEx.ec project

  This smart contract collects ETH and BTC, and in return emits RLC tokens to the backers

  Thanks to BeyondTheVoid and TokenMarket who helped us shaping this code.

 */

// TODO
// Comment vont faire les gars qui ont investit en BTC avant le min cap pour recuperer leur rlc?
// add lockable to RLC transfer only for owner
// add emergency stop

// TEST:
// test differente timeframe
// test multiple invest
// test claim ETH

contract Crowdsale is SafeMath {

  	struct Backer {
  	  uint weiReceived;	// Amount of ETH given
	  string btc_address;  //store the btc address for full tracability
	  uint satoshiReceived;	// Amount of BTC given
	  uint rlcToSend;   	// rlc to distribute when the min cap is reached
	  uint rlcSent;
	}

	RLC 	public rlc;         // RLC contract reference
	address public owner;       // Contract owner (iEx.ec team)
	address public multisigETH; // Multisig contract that will receive the ETH
	address public BTCproxy;	// addess of the BTC Proxy

	uint public RLCPerETH;      // Number of RLC per ETH
	uint public RLCPerSATOSHI;  // Number of RLC per SATOSHI
	uint public ETHReceived;    // Number of ETH received
	uint public BTCReceived;    // Number of BTC received
	uint public RLCSentToETH;   // Number of RLC sent to ETH contributors
	uint public RLCSentToBTC;   // Number of RLC sent to BTC contributors
	uint public RLCEmitted;		// Number of RLC emitted
	uint public startBlock;     // Crowdsale start block
	uint public endBlock;       // Crowdsale end block
	uint public minCap;         // Minimum number of RLC to sell
	uint public maxCap;         // Maximum number of RLC to sell
	bool public maxCapReached;  // Max cap has been reached
	uint public minInvestETH;   // Minimum amount to invest
	uint public minInvestBTC;   // Minimum amount to invest
	bool public crowdsaleClosed;// Is crowdsale still on going

	address public bounty;		// address at which the bounty RLC will be sent
	address public reserve; 	// address at which the contingency reserve will be sent
	address public team;		// address at which the team RLC will be sent

	uint public rlc_bounty;		// amount of bounties RLC
	uint public rlc_reserve;	// amount of the contingency reserve
	uint public rlc_team;		// amount of the team RLC

	mapping(address => Backer) public backers; //backersETH indexed by their ETH address
	//mapping(address => BackerBTC) public backersBTC; //backersBTC indexed by their (BTC,ETH) address

    // Auth modifier, if the msg.sender isn't the expected address, throw.
	modifier onlyBy(address a){
	    if (msg.sender != a) throw;
	    _;
	}

	modifier minCapNotReached() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		_;
	}

	event ReceivedETH(address addr, uint value);
	event ReceivedBTC(address addr, string from, uint value);
	event RefundBTC(string to, uint value);
	event Logs(address indexed from, uint amount, string value);
	// Constructor of the contract.
	function Crowdsale(address _token, address _btcproxy) {

	  //set the different variables
	  owner = msg.sender;
	  BTCproxy = _btcproxy; // to change
	  //RLC = Token(0x0a8f269d52fad5f0f6297a264f48cbb290c68130); 	// RLC contract address
	  rlc = RLC(_token); 	// RLC contract address
	  multisigETH = 0x8cd6B3D8713df6aA35894c8beA200c27Ebe92550;
	  RLCSentToETH = 0;
	  minInvestETH = 100 finney; // 0.1 ether
	  minInvestBTC = 100000;     // approx 1 USD or 0.00100000 BTC
	  startBlock = now ;            // now (testnet)
	  endBlock =  now + 30 days;    // ever (testnet) startdate + 30 days
	  //RLCPerBTC = 50000000000000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  RLCPerETH = 5000000000000;          // FIXME
	  RLCPerSATOSHI = 50000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  minCap=12000000000000000;
	  maxCap=60000000000000000;
	  rlc_bounty=1700000000000000;
	  rlc_reserve=17000000000000000;
	  rlc_team=12000000000000000;
	  RLCEmitted = rlc_bounty + rlc_reserve + rlc_team;
	}

	/*
	* The fallback function corresponds to a donation in ETH
	*/
	function() payable	{
	  receiveETH(msg.sender);
	}

	/*
	*	Receives a payment in ETH
	*/
	function receiveETH(address beneficiary) payable {
// TODO check for msg.value coherent ?

	  //don't accept funding under a predefined treshold
	  if (msg.value < minInvestETH) throw;

	  // check if we are in the correct time slot
	  if ((now < startBlock) || (now > endBlock )) throw;

	  //compute the number of RLC to send
	  uint rlcToSend = bonus((msg.value*RLCPerETH)/(1 ether));
	  //uint rlcToSend = bonus((msg.value*RLCPerFINNEY)/(1 finney));

	  // check if we are not reaching the maxCap by accepting this payment
	  if ((rlcToSend + RLCSentToETH + RLCSentToBTC) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!transferRLC(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent, rlcToSend);
	  backer.weiReceived = safeAdd(backer.weiReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  ETHReceived = safeAdd(ETHReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  RLCSentToETH = safeAdd(RLCSentToETH, rlcToSend);

	  emitRLC(rlcToSend);
	  // send the corresponding contribution event
	  ReceivedETH(beneficiary,ETHReceived);
	}

	/*
	* receives a payment in BTC
	*/

	// Refund BTC in JS if function throw

	function receiveBTC(address beneficiary, string btc_address, uint value) onlyBy(BTCproxy){
	  //don't accept funding under a predefined treshold
	  if (value < minInvestBTC) throw;

	  // if we are in the correct time slot
	  if ((now < startBlock) || (now > endBlock )) throw;

	  //compute the number of RLC to send
	  uint rlcToSend = bonus((value*RLCPerSATOSHI));

	  // check if we are not reaching the maxCap
	  if ((rlcToSend + RLCSentToETH + RLCSentToBTC) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  // if the min cap is reached, token transfer happens immediately possibly along
	  // with the previous payment
	  if (!transferRLC(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent , rlcToSend);
	  backer.btc_address = btc_address;
	  backer.satoshiReceived = safeAdd(backer.satoshiReceived, value);
	  BTCReceived =  safeAdd(BTCReceived, value);// Update the total satoshi collcted during the crowdfunding
	  RLCSentToBTC = safeAdd(RLCSentToBTC, rlcToSend);
	  emitRLC(rlcToSend);

	  ReceivedBTC(beneficiary, btc_address, BTCReceived);
	}

	function isMinCapReached() returns (bool) {
		return (RLCSentToETH + RLCSentToBTC ) > minCap;
	}

	function isMaxCapReached() returns (bool) {
		return (RLCSentToETH + RLCSentToBTC ) == maxCap;
	}

	// Compute the variable part
	function emitRLC(uint amount) internal {
		Logs(msg.sender ,amount, "emitRLC");
		rlc_bounty+=amount/10;      // bounty is 10% of the crowdsale
		rlc_team+=amount/20;        // team is 5% of the crowdsale
		rlc_reserve+=amount/10; 	// contingency is 10% of the crowdsale
		RLCEmitted+=amount + amount/4;	// adjust the total number of RLC emitted
	}

	/*
	  Compute the RLC bonus according to the investment period
	*/
	function bonus(uint amount) returns (uint) {
	  if (now < (startBlock + 10 days)) return (amount + amount/5);  // bonus 20%
	  if (now < startBlock + 20 days) return (amount + amount/10);  // bonus 10%
	  return amount;
	}

	/*
	 * Transfer RLC to backers
	 * Assumes that the owner of the token contract and the crowdsale contract is the same
	 */
	function transferRLC(address to, uint amount) internal returns (bool) {
	  return rlc.transfer(to, amount);
	}

	/*
	 * When mincap is not reach backer can call the approveAndCall function of the RLC token contract
	 * whith this crowdsale contract on parameter with all the RLC they get in order to be refund
	 */

    function receiveApproval(address _from, uint256 _value, address _token, string _extraData, string _extraData2) minCapNotReached {
        if (msg.sender != rlc) throw;
        if (bytes(_extraData).length != 0) throw;  // no extradata needed
        if (bytes(_extraData2).length!= 0) throw;  // no extradata needed
        if (_value != backer[_from].rlcSent) throw; // compare value from backer balance
        if (!rlc.transferFrom(_from, this, _value)) throw ; // get the token back to the crowdsale contract
		uint ETHToSend = backers[_from].weiReceived;
		backers[_from].weiReceived=0;
		uint BTCToSend = backers[_from].satoshiReceived;
		backers[_from].satoshiReceived = 0;
		if (!_from.send(ETHToSend)) throw;
		if (BTCToSend > 0)
			RefundBTC(backersBTC[msg.sender].btc_address ,valueToSend); // event message to manually refund BTC
    }

	/*
	* After the end of the crowdsale let user reclaimed their RLC if minCap has not been reached.
	* It must be sent from the backer address

	function claimRLC() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint amount=backersETH[msg.sender].rlcToSend;
		if (amount !=0 ) {
			backersETH[msg.sender].rlcToSend=0;
			if (!rlc.transfer(msg.sender,amount)) throw;
			//transfer the corresponding amount to the multisig address
			uint weitosend = backersETH[msg.sender].weiReceived;
			backersETH[msg.sender].weiReceived=0;
			if (!multisigETH.send(backersETH[msg.sender].weiReceived)) throw;
		} else {
			amount = backersBTC[msg.sender].rlcToSend;
			backersBTC[msg.sender].rlcToSend=0;
			backersBTC[msg.sender].satoshiReceived=0;
			if (!rlc.transfer(msg.sender,amount)) throw;
		}
	}
	*/

	/*
	* After the end of the crowdsale let user reclaimed their ETH if minCap has not been reached.
	* It must be sent from the backer address

	function claimETH() {
		//check if we are in the correct time frame
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint valToSend = backersETH[msg.sender].weiReceived;
		backersETH[msg.sender].weiReceived=0;
		backersETH[msg.sender].rlcToSend=0;
		if (!msg.sender.send(valToSend)) throw;
	}
	*/
	/*
	* After the end of the crowdsale let user reclaimetheir BTC if minCap has not been reached.
	* It must be sent from the backer address

	function claimBTC() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint valueToSend = backersBTC[msg.sender].satoshiReceived;
		backersBTC[msg.sender].satoshiReceived=0;
		//reverse sold RLC to the team
		backersETH[msg.sender].rlcToSend=0;
		RefundBTC(backersBTC[msg.sender].btc_address ,valueToSend);
	}
	*/
	/*
	* Update the rate RLC per ETH, computed externally by using the BTCETH index
	*/
	function setRLCPerETH(uint rate) onlyBy(BTCproxy) {
		RLCPerETH=rate;
	}

	/*
	* Finalize the crowdsale, should be called after the refund period
	*/
	function finalize() onlyBy(owner) {
		if ((now > endBlock + 10 days ) && (now < endBlock + 60 days)) throw;
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
	    if (!transferRLC(team,rlc_team)) throw;
	    if (!transferRLC(reserve,rlc_reserve)) throw;
	    if (!transferRLC(bounty,rlc_bounty)) throw;
	    rlc.burn(rlc.totalSupply() - RLCEmitted);
		crowdsaleClosed = true;
	}
}

pragma solidity ^0.4.8;
import "./SafeMath.sol";
import "./RLC.sol";

/*
  Crowdsale Smart Contract for the iEx.ec project

  This smart contract collects ETH and BTC, and in return emits RLC tokens to the backers

  Thanks to BeyondTheVoid and TokenMarket who helped us shaping this code.

 */

// TODO
// Comment vont faire les gars qui ont investit en BTC avant le min cap pour recuperer leur rlc?
// add lockable to RLC transfer only for owner
// add emergency stop

// TEST:
// test differente timeframe
// test multiple invest
// test claim ETH

contract Crowdsale is SafeMath {

  	struct Backer {
  	  uint weiReceived;	// Amount of ETH given
	  string btc_address;  //store the btc address for full tracability
	  uint satoshiReceived;	// Amount of BTC given
	  uint rlcToSend;   	// rlc to distribute when the min cap is reached
	  uint rlcSent;
	}

	RLC 	public rlc;         // RLC contract reference
	address public owner;       // Contract owner (iEx.ec team)
	address public multisigETH; // Multisig contract that will receive the ETH
	address public BTCproxy;	// addess of the BTC Proxy

	uint public RLCPerETH;      // Number of RLC per ETH
	uint public RLCPerSATOSHI;  // Number of RLC per SATOSHI
	uint public ETHReceived;    // Number of ETH received
	uint public BTCReceived;    // Number of BTC received
	uint public RLCSentToETH;   // Number of RLC sent to ETH contributors
	uint public RLCSentToBTC;   // Number of RLC sent to BTC contributors
	uint public RLCEmitted;		// Number of RLC emitted
	uint public startBlock;     // Crowdsale start block
	uint public endBlock;       // Crowdsale end block
	uint public minCap;         // Minimum number of RLC to sell
	uint public maxCap;         // Maximum number of RLC to sell
	bool public maxCapReached;  // Max cap has been reached
	uint public minInvestETH;   // Minimum amount to invest
	uint public minInvestBTC;   // Minimum amount to invest
	bool public crowdsaleClosed;// Is crowdsale still on going

	address public bounty;		// address at which the bounty RLC will be sent
	address public reserve; 	// address at which the contingency reserve will be sent
	address public team;		// address at which the team RLC will be sent

	uint public rlc_bounty;		// amount of bounties RLC
	uint public rlc_reserve;	// amount of the contingency reserve
	uint public rlc_team;		// amount of the team RLC

	mapping(address => Backer) public backers; //backersETH indexed by their ETH address
	//mapping(address => BackerBTC) public backersBTC; //backersBTC indexed by their (BTC,ETH) address

    // Auth modifier, if the msg.sender isn't the expected address, throw.
	modifier onlyBy(address a){
	    if (msg.sender != a) throw;
	    _;
	}

	modifier minCapNotReached() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		_;
	}

	event ReceivedETH(address addr, uint value);
	event ReceivedBTC(address addr, string from, uint value);
	event RefundBTC(string to, uint value);
	event Logs(address indexed from, uint amount, string value);
	// Constructor of the contract.
	function Crowdsale(address _token, address _btcproxy) {

	  //set the different variables
	  owner = msg.sender;
	  BTCproxy = _btcproxy; // to change
	  //RLC = Token(0x0a8f269d52fad5f0f6297a264f48cbb290c68130); 	// RLC contract address
	  rlc = RLC(_token); 	// RLC contract address
	  multisigETH = 0x8cd6B3D8713df6aA35894c8beA200c27Ebe92550;
	  RLCSentToETH = 0;
	  minInvestETH = 100 finney; // 0.1 ether
	  minInvestBTC = 100000;     // approx 1 USD or 0.00100000 BTC
	  startBlock = now ;            // now (testnet)
	  endBlock =  now + 30 days;    // ever (testnet) startdate + 30 days
	  //RLCPerBTC = 50000000000000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  RLCPerETH = 5000000000000;          // FIXME
	  RLCPerSATOSHI = 50000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  minCap=12000000000000000;
	  maxCap=60000000000000000;
	  rlc_bounty=1700000000000000;
	  rlc_reserve=17000000000000000;
	  rlc_team=12000000000000000;
	  RLCEmitted = rlc_bounty + rlc_reserve + rlc_team;
	}

	/*
	* The fallback function corresponds to a donation in ETH
	*/
	function() payable	{
	  receiveETH(msg.sender);
	}

	/*
	*	Receives a payment in ETH
	*/
	function receiveETH(address beneficiary) payable {
// TODO check for msg.value coherent ?

	  //don't accept funding under a predefined treshold
	  if (msg.value < minInvestETH) throw;

	  // check if we are in the correct time slot
	  if ((now < startBlock) || (now > endBlock )) throw;

	  //compute the number of RLC to send
	  uint rlcToSend = bonus((msg.value*RLCPerETH)/(1 ether));
	  //uint rlcToSend = bonus((msg.value*RLCPerFINNEY)/(1 finney));

	  // check if we are not reaching the maxCap by accepting this payment
	  if ((rlcToSend + RLCSentToETH + RLCSentToBTC) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!transferRLC(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent, rlcToSend);
	  backer.weiReceived = safeAdd(backer.weiReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  ETHReceived = safeAdd(ETHReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  RLCSentToETH = safeAdd(RLCSentToETH, rlcToSend);

	  emitRLC(rlcToSend);
	  // send the corresponding contribution event
	  ReceivedETH(beneficiary,ETHReceived);
	}

	/*
	* receives a payment in BTC
	*/

	// Refund BTC in JS if function throw

	function receiveBTC(address beneficiary, string btc_address, uint value) onlyBy(BTCproxy){
	  //don't accept funding under a predefined treshold
	  if (value < minInvestBTC) throw;

	  // if we are in the correct time slot
	  if ((now < startBlock) || (now > endBlock )) throw;

	  //compute the number of RLC to send
	  uint rlcToSend = bonus((value*RLCPerSATOSHI));

	  // check if we are not reaching the maxCap
	  if ((rlcToSend + RLCSentToETH + RLCSentToBTC) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  // if the min cap is reached, token transfer happens immediately possibly along
	  // with the previous payment
	  if (!transferRLC(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent , rlcToSend);
	  backer.btc_address = btc_address;
	  backer.satoshiReceived = safeAdd(backer.satoshiReceived, value);
	  BTCReceived =  safeAdd(BTCReceived, value);// Update the total satoshi collcted during the crowdfunding
	  RLCSentToBTC = safeAdd(RLCSentToBTC, rlcToSend);
	  emitRLC(rlcToSend);

	  ReceivedBTC(beneficiary, btc_address, BTCReceived);
	}

	function isMinCapReached() returns (bool) {
		return (RLCSentToETH + RLCSentToBTC ) > minCap;
	}

	function isMaxCapReached() returns (bool) {
		return (RLCSentToETH + RLCSentToBTC ) == maxCap;
	}

	// Compute the variable part
	function emitRLC(uint amount) internal {
		Logs(msg.sender ,amount, "emitRLC");
		rlc_bounty+=amount/10;      // bounty is 10% of the crowdsale
		rlc_team+=amount/20;        // team is 5% of the crowdsale
		rlc_reserve+=amount/10; 	// contingency is 10% of the crowdsale
		RLCEmitted+=amount + amount/4;	// adjust the total number of RLC emitted
	}

	/*
	  Compute the RLC bonus according to the investment period
	*/
	function bonus(uint amount) returns (uint) {
	  if (now < (startBlock + 10 days)) return (amount + amount/5);  // bonus 20%
	  if (now < startBlock + 20 days) return (amount + amount/10);  // bonus 10%
	  return amount;
	}

	/*
	 * Transfer RLC to backers
	 * Assumes that the owner of the token contract and the crowdsale contract is the same
	 */
	function transferRLC(address to, uint amount) internal returns (bool) {
	  return rlc.transfer(to, amount);
	}

	/*
	 * When mincap is not reach backer can call the approveAndCall function of the RLC token contract
	 * whith this crowdsale contract on parameter with all the RLC they get in order to be refund
	 */

    function receiveApproval(address _from, uint256 _value, address _token, string _extraData, string _extraData2) minCapNotReached {
        if (msg.sender != rlc) throw;
        if (bytes(_extraData).length != 0) throw;
        if (bytes(_extraData2).length!= 0) throw;
        if (_value != backer[_from].rlcSent) throw; // compare value from backer balance
        if (!rlc.transferFrom(_from, this, _value)) throw ; // get the token back to the crowdsale contract
		uint ETHToSend = backers[_from].weiReceived;
		backers[_from].weiReceived=0;
		uint BTCToSend = backers[_from].satoshiReceived;
		backers[_from].satoshiReceived = 0;
		if (!msg.sender.send(ETHToSend)) throw;
		if (BTCToSend > 0)
			RefundBTC(backersBTC[msg.sender].btc_address ,valueToSend); // event message to manually refund BTC
    }

	/*
	* After the end of the crowdsale let user reclaimed their RLC if minCap has not been reached.
	* It must be sent from the backer address

	function claimRLC() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint amount=backersETH[msg.sender].rlcToSend;
		if (amount !=0 ) {
			backersETH[msg.sender].rlcToSend=0;
			if (!rlc.transfer(msg.sender,amount)) throw;
			//transfer the corresponding amount to the multisig address
			uint weitosend = backersETH[msg.sender].weiReceived;
			backersETH[msg.sender].weiReceived=0;
			if (!multisigETH.send(backersETH[msg.sender].weiReceived)) throw;
		} else {
			amount = backersBTC[msg.sender].rlcToSend;
			backersBTC[msg.sender].rlcToSend=0;
			backersBTC[msg.sender].satoshiReceived=0;
			if (!rlc.transfer(msg.sender,amount)) throw;
		}
	}
	*/

	/*
	* After the end of the crowdsale let user reclaimed their ETH if minCap has not been reached.
	* It must be sent from the backer address

	function claimETH() {
		//check if we are in the correct time frame
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint valToSend = backersETH[msg.sender].weiReceived;
		backersETH[msg.sender].weiReceived=0;
		backersETH[msg.sender].rlcToSend=0;
		if (!msg.sender.send(valToSend)) throw;
	}
	*/
	/*
	* After the end of the crowdsale let user reclaimetheir BTC if minCap has not been reached.
	* It must be sent from the backer address

	function claimBTC() {
		if ((now<endBlock) || isMinCapReached() || (now > endBlock + 15 days)) throw;
		uint valueToSend = backersBTC[msg.sender].satoshiReceived;
		backersBTC[msg.sender].satoshiReceived=0;
		//reverse sold RLC to the team
		backersETH[msg.sender].rlcToSend=0;
		RefundBTC(backersBTC[msg.sender].btc_address ,valueToSend);
	}
	*/
	/*
	* Update the rate RLC per ETH, computed externally by using the BTCETH index
	*/
	function setRLCPerETH(uint rate) onlyBy(BTCproxy) {
		RLCPerETH=rate;
	}

	/*
	* Finalize the crowdsale, should be called after the refund period
	*/
	function finalize() onlyBy(owner) {
		if ((now > endBlock + 10 days ) && (now < endBlock + 60 days)) throw;
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
	    if (!transferRLC(team,rlc_team)) throw;
	    if (!transferRLC(reserve,rlc_reserve)) throw;
	    if (!transferRLC(bounty,rlc_bounty)) throw;
	    rlc.burn(rlc.totalSupply() - RLCEmitted);
		crowdsaleClosed = true;
	}
}


potFull event

potFull event

pragma solidity ^0.4.11;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastPlayerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address public owner;

    Pot[] allPots;
    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creator);
    event potJoin(string name, address newPlayer);
    event potFull(string name);
    event potExpired(string name);
    event potClosed(string name, address loser);

    function PotOfGold() {
        owner = msg.sender;
    }

    function ownerWithdraw(){
        require(msg.sender == owner);

        int toWithdraw = int(this.balance - 100 finney); // leave 0.1 ether for gas (?)
        require(toWithdraw > 0);

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = msg.value;
        pot.players.push(msg.sender);

        allPots.push(pot);

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        require(pot.buyIn > 0); // pot exists
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount
        require(pot.players[0] != msg.sender && pot.players[1] != msg.sender);

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
            pot.lastPlayerBlockNumber = block.number;
            potFull(name);
        }

        potJoin(name, msg.sender);
    }

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber);

        bytes32 blockHash = block.blockhash(pot.lastPlayerBlockNumber + 1);
        if(blockHash == 0) { // pot expired due to hash storage limits - players didn't solve pot
            require(pot.loser == 0); // need this?
            pot.loser = msg.sender; // doesn't matter, everybody loses a fee

            for(uint i = 0; i < pot.players.length; i++){
                pot.players[i].transfer((pot.buyIn * 99) / 100); // return money minus 1% fee
            }

            potExpired(name);
            return;
        }

        bytes32 potShaResult = sha3(msg.sender, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

        require(pot.loser == 0); // need this?
        pot.loser = pot.players[loserIndex];

        address winner1 = pot.players[(loserIndex + 1) % 3];
        address winner2 = pot.players[(loserIndex + 2) % 3];

        uint winAmount = ((pot.buyIn / 2) * 99) / 100;
        uint returnAmount = pot.buyIn + winAmount;

        winner1.transfer(returnAmount);
        winner2.transfer(returnAmount);

        potClosed(name, pot.loser);
    }
}

pragma solidity ^0.4.11;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastPlayerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address public owner;

    Pot[] allPots;
    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creator);
    event potJoin(string name, address newPlayer);
    event potExpired(string name);
    event potClosed(string name, address loser);

    function PotOfGold() {
        owner = msg.sender;
    }

    function ownerWithdraw(){
        require(msg.sender == owner);

        int toWithdraw = int(this.balance - 100 finney); // leave 0.1 ether for gas (?)
        require(toWithdraw > 0);

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = msg.value;
        pot.players.push(msg.sender);

        allPots.push(pot);

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        require(pot.buyIn > 0); // pot exists
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount
        require(pot.players[0] != msg.sender && pot.players[1] != msg.sender);

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
            pot.lastPlayerBlockNumber = block.number;
        }

        potJoin(name, msg.sender);
    }

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber);

        bytes32 blockHash = block.blockhash(pot.lastPlayerBlockNumber + 1);
        if(blockHash == 0) { // pot expired due to hash storage limits - players didn't solve pot
            require(pot.loser == 0); // need this?
            pot.loser = msg.sender; // doesn't matter, everybody loses a fee

            for(uint i = 0; i < pot.players.length; i++){
                pot.players[i].transfer((pot.buyIn * 99) / 100); // return money minus 1% fee
            }

            potExpired(name);
            return;
        }

        bytes32 potShaResult = sha3(msg.sender, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

        require(pot.loser == 0); // need this?
        pot.loser = pot.players[loserIndex];

        address winner1 = pot.players[(loserIndex + 1) % 3];
        address winner2 = pot.players[(loserIndex + 2) % 3];

        uint winAmount = ((pot.buyIn / 2) * 99) / 100;
        uint returnAmount = pot.buyIn + winAmount;

        winner1.transfer(returnAmount);
        winner2.transfer(returnAmount);

        potClosed(name, pot.loser);
    }
}


Removing superflous comments

Removing superflous comments

pragma solidity ^0.4.2;

// Blockchain Ballot Contract
contract Ballot {

  // Public variables of the ballot
  string public title;
  string public description;
  string public candidates;
  uint public candidatesCount;
  address[] public voters;
  mapping (address => bool) public hasVoted;
  uint[] public publicKeyN;
  uint[] public publicKeyG;
  uint[] public votes;

  // Contract constructor
  function Ballot(string _title, string _description, string _candidates, uint _candidatesCount, address[] _voters, uint[] _publicKeyN, uint[] _publicKeyG) {

    // Set the basic variables
    title = _title;
    description = _description;
    candidates = _candidates;
    candidatesCount = _candidatesCount;

    // Loop through each voter address
    uint index = 0;
    for (index = 0; index < _voters.length; index++) {

      // Add the address to the voters array
      voters.push(_voters[index]);

      // Initalise the voter has voted flag
      hasVoted[_voters[index]] = false;
    }

    // Loop through each chunk of the public key 'n'
    for (index = 0; index < _publicKeyN.length; index++) {

      // Add the chunk to the complete array
      publicKeyN.push(_publicKeyN[index]);
    }

    // Loop through each chunk of the public key 'g'
    for (index = 0; index < _publicKeyG.length; index++) {

      // Add the chunk to the complete array
      publicKeyG.push(_publicKeyG[index]);
    }
  }

  // Get the voters of the ballot
  function getVoters() constant returns (address[]) { return voters; }

  // Get the public key 'n' of the ballot
  function getPublicKeyN() constant returns (uint[]) { return publicKeyN; }

  // Get the public key 'g' of the ballot
  function getPublicKeyG() constant returns (uint[]) { return publicKeyG; }

  // Get the votes in the ballot
  function getVotes() constant returns (uint[]) { return votes; }

  // Vote in the ballot
  function executeVote(uint[] vote) returns (bool sucess) {

    // Get the address attempting to voters
    address sender = msg.sender;

    // Loop through each voter
    for (uint index = 0; index < voters.length; index++) {

      // Check if this voter is the sender
      if (sender == voters[index]) {

        // Check if this voter has already voted
        if(!hasVoted[sender]) {

          // Check the vote is of the correct length
          // Each vote is 2048 bits long represented in 8 256 bit integers
          if(vote.length == candidatesCount * 8) {

              // Loop through the votes
              for (index = 0; index < vote.length; index++) {

                // Add this vote
                votes.push(vote[index]);

                // Mark this voter as having now voted
                hasVoted[sender] = true;
              }

              // The vote action was successful
              return true;
          }
        }
      }
    }

    // Sender is not a valid voter
    return false;
  }
}


use timestamp

use timestamp

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)

  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 _block_match_begin,
               uint _block_match_end, uint _block_hard_deadline,
               uint _block_terminate_deadline, string _url_oraclize) {
    resolver = _resolver;
    title = _title;
    category = _category;
    team_0 = _team_0;
    team_1 = _team_1;
    block_match_begin = _block_match_begin;
    block_match_end = _block_match_end;
    block_terminate_deadline = _block_terminate_deadline;
    url_oraclize = _url_oraclize;
  }

  function arbitrate(BET_STATES result) {
    require(block.number >= block_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.number < block_hard_deadline);
    // Oraclize should call this
    require(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    require(block.number >= block_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.number >= block_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.number < block_match_begin);
    if (for_team)

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

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

  // Called by the user to collect his reward
  function collect_profit() {

  }

  // 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 block_match_begin;
  uint public block_match_end;
  uint public block_hard_deadline; // Hard deadline to end bet
  uint public block_terminate_deadline; // Self-destruct deadline > hard_deadline (this must be big, so people can withdraw their funds)

  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 _block_match_begin,
               uint _block_match_end, uint _block_hard_deadline,
               uint _block_terminate_deadline, string _url_oraclize) {
    resolver = _resolver;
    title = _title;
    category = _category;
    team_0 = _team_0;
    team_1 = _team_1;
    block_match_begin = _block_match_begin;
    block_match_end = _block_match_end;
    block_terminate_deadline = _block_terminate_deadline;
    url_oraclize = _url_oraclize;
  }

  function arbitrate(BET_STATES result) {
    require(block.number >= block_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.number < block_hard_deadline);
    // Oraclize should call this
    require(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    require(block.number >= block_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.number >= block_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.number < block_match_begin);
    if (for_team)

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

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

  // Called by the user to collect his reward
  function collect_profit() {

  }

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

  }
}


A little bit of formatting; Renamed event's return value;

pragma solidity ^0.4.13;

import "./TokenERC20.sol";
import "./Timed.sol";
import "./SafeMathLib.sol";

contract Battle is Timed {
    using SafeMathLib for uint256;

    uint256  constant public maxPersians         = 300000 * 10**18;  // 300.000
    uint256 public constant maxSpartans         = 300 * 10**18;     // 300
    uint256 public constant maxImmortals        = 100;              // 100
    uint256 public constant maxAthenians        = 100 * 10*18;      // 100

    uint8   public constant battlePointDecimals = 18;

    string  public constant version             = '1.0.0';

    address public constant persians            = 0xF63D4Ec615898163CdE5EBC2Aa8d5768ccC92965;   //0xaec98a708810414878c3bcdf46aad31ded4a4557 MainNet
    address public constant immortals           = 0xED19698C0abdE8635413aE7AD7224DF6ee30bF22;   //0xED19698C0abdE8635413aE7AD7224DF6ee30bF22 MainNet
    address public constant spartans            = 0x94F72fa9d9e035a40F22f6e7ceDb78E697fF54C2;   //0x163733bcc28dbf26B41a8CfA83e369b5B3af741b MainNet
    address public constant athenians           = 0x17052d51E954592C1046320c2371AbaB6C73Ef10;   //0x17052d51e954592c1046320c2371abab6c73ef10 MainNet

    mapping (address => mapping (address => uint256))   public  warriors;                       // Troops currently allocated by each player
    mapping (address => uint256)                        public  warriorsOnTheBattlefield;       // Total troops fighting in the battle
    mapping (address => uint256)                        public  warriorsIntoAde;                // Total casualties, increased after each warriors redeem

    event WarriorsAssignedToBattlefield (address indexed from, address faction, uint256 battlePointsIncrementForecast);
    event WarriorsBackToHome            (address indexed to, address faction, uint256 survivedWarriors);

    /*******************************************************************************************
    When the battle ends in a draw:
        (*) 10% of troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) No slaves are assigned

    When the battle ends with a winning factions:
        (*) 10% of troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) Surviving warriors of the loosing faction are assigned as slaves to winners

    Immortals and Athenians are support troops: there will be no casualties in their row, and they can
    be retrieved without losses.

    Only Persians and Spartans can be slaves. Immortals and Athenians WILL NOT be sent back as slaves to winners.
    *******************************************************************************************/
    function Battle(uint256 _startTime, uint256 _life, uint8 _avarageBlockTime) Timed(_startTime, _life, _avarageBlockTime) { }

    /**** PHASE #1 ******/

    function assignPersiansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, persians, _warriors, maxPersians);
        // Persians are divisible with 18 decimals and their value is 1 BP
        WarriorsAssignedToBattlefield(msg.sender, persians, _warriors / 10**18);
    }

    function assignSpartansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, spartans, _warriors, maxSpartans);
        // Spartans are divisible with 18 decimals and their value is 1.000 BP
        WarriorsAssignedToBattlefield(msg.sender, spartans, (_warriors / 10**18) * 1000);
    }

    function assignImmortalsToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, immortals, _warriors, maxImmortals);
        // Immortals are not divisible and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, immortals, _warriors * 100);
    }

    function assignAtheniansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, athenians, _warriors, maxAthenians);
        // Athenians are divisible with 18 decimals and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, athenians, (_warriors / 10**18) * 100);
    }

    /**** PHASE #2 ******/

    function victoryIsOurs() onlyIfTimePassed {
        // Persians win
        if (getPersiansBattlePoints() > getGreeksBattlePoints()) retrieveWarriorsAndSlaves(persians, spartans);
        // Spartans win
        else if (getPersiansBattlePoints() < getGreeksBattlePoints()) retrieveWarriorsAndSlaves(spartans, persians);
        // It's a draw
        else retireveWarriors(msg.sender, persians, 10);
    }

    // When the battle is over, Immortals can be sent back to the former owner
    function retrieveImmortals() onlyIfTimePassed {
        retireveWarriors(msg.sender, immortals, 0);
    }

    // When the battle is over, Athenians can be sent back to the former owner
    function retrieveAthenians() onlyIfTimePassed {
        retireveWarriors(msg.sender, athenians, 0);
    }

    /*** PRIVATE FUNCTIONS ***/

    function assignWarriorsToBattle(address _player, address _faction, uint256 _warriors, uint256 _maxWarriors) private {
        require(warriorsOnTheBattlefield[_faction].add(_warriors) <= _maxWarriors);
        assert(TokenERC20(_faction).transferFrom(_player, address(this), _warriors));
        warriors[_player][_faction] = warriors[_player][_faction].add(_warriors);
        warriorsOnTheBattlefield[_faction] = warriorsOnTheBattlefield[_faction].add(_warriors);
    }

    function retrieveWarriorsAndSlaves(address _winners, address _loosers) private {
        uint256 slaveWarriors = getSlaves(msg.sender, _winners, _loosers);
        retireveWarriors(msg.sender, _winners, 10);
        sendWarriors(msg.sender, _loosers, slaveWarriors);
    }

    function retireveWarriors(address _player, address _faction, uint8 _deadAmount) private {
        if (_deadAmount > 0) {
            uint256 _deadWarriors = warriors[_player][_faction].div(_deadAmount);
            warriorsIntoAde[_faction] = warriorsIntoAde[_faction].add(_deadWarriors);
            warriors[_player][_faction] = warriors[_player][_faction].sub(_deadWarriors);
        }
        uint256 _warriors = warriors[_player][_faction];
        require(_warriors > 0);
        warriors[_player][_faction] = 0;
        sendWarriors(_player, _faction, _warriors);
        WarriorsBackToHome(_player, _faction, _warriors);
    }

    function sendWarriors(address _player, address _faction, uint256 _warriors) private {
        assert(TokenERC20(_faction).transfer(_player, _warriors));
    }

    /*** DAPP HELPERS AND CONSTANT FUNCTIONS ***/

    function getPersiansBattlePoints() constant returns (uint _battlePoints) {
        return ((warriorsOnTheBattlefield[persians]) + (warriorsOnTheBattlefield[immortals] * 10**18 * 100));
    }

    function getGreeksBattlePoints() constant returns (uint _battlePoints) {
        return ((warriorsOnTheBattlefield[spartans] * 1000) + (warriorsOnTheBattlefield[athenians] * 100));
    }

    // This method returns sensible values for two combinations of parameters: (persians, spartans) and (spartans, persians)
    function getSlaves(address _player, address _winningFaction, address _looserFaction) constant returns (uint256 _slaves) {
        return ((_winningFaction == persians && _looserFaction == spartans) || (_winningFaction == spartans && _looserFaction == persians)) ?
            (warriorsOnTheBattlefield[_looserFaction] - (warriorsOnTheBattlefield[_looserFaction] / 10)) / (warriorsOnTheBattlefield[_winningFaction] / warriors[_player][_winningFaction]) : 0;
    }

    function isDraw() constant returns (bool _draw) {
        return (getPersiansBattlePoints() == getGreeksBattlePoints());
    }

    function getWinningFaction() constant returns (string _winningFaction) {
        if (!isTimePassed()) return "The battle is still in progress";
        if (isDraw()) return "The battle ended in a draw!";
        return getPersiansBattlePoints() > getGreeksBattlePoints() ? "Persians" : "Greeks";
    }

    /**** DEV FUNCTIONS ******/

    function setPersiansWin() {
        warriorsOnTheBattlefield[persians] = 3000 * 10**18;  //3000
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 2 * 10**18; //2000
        warriorsOnTheBattlefield[athenians] = 3 * 10**18; //300
    }

    function setGreeksWin() {
        warriorsOnTheBattlefield[persians] = 300 * 10**18;  //300
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 27003 * 10**14; //2700.3
        warriorsOnTheBattlefield[athenians] = 3 * 10**18; //300
    }

    function setDraw() {
        warriorsOnTheBattlefield[persians] = 2200 * 10**18;  //2200
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 2 * 10**18; //2000
        warriorsOnTheBattlefield[athenians] = 4 * 10**18; //400
    }

}

pragma solidity ^0.4.13;

import "./TokenERC20.sol";
import "./Timed.sol";
import "./SafeMathLib.sol";

contract Battle is Timed {
    using SafeMathLib for uint256;

    // Battle attributes
    mapping (address => uint256) public warriorsOnTheBattlefield;       // Total troops fighting in the battle
    mapping (address => uint256) public warriorsIntoAde;                // Total casualties, increased after each warriors redeem
    mapping (address => mapping (address => uint256)) public warriors;  // Troops currently allocated by each player

    uint256 public constant maxPersians = 300000 * 10**18;  // 300.000
    uint256 public constant maxSpartans = 300 * 10**18;     // 300
    uint256 public constant maxImmortals = 100;             // 100
    uint256 public constant maxAthenians = 100 * 10*18;     // 100

    uint8 public constant battlePointDecimals = 18;
    string public constant version = '1.0.0';

    // Token addresses
    address public constant persians = 0xF63D4Ec615898163CdE5EBC2Aa8d5768ccC92965;  //0xaec98a708810414878c3bcdf46aad31ded4a4557 MainNet
    address public constant immortals = 0xED19698C0abdE8635413aE7AD7224DF6ee30bF22;  //0xED19698C0abdE8635413aE7AD7224DF6ee30bF22 MainNet
    address public constant spartans = 0x94F72fa9d9e035a40F22f6e7ceDb78E697fF54C2;  //0x163733bcc28dbf26B41a8CfA83e369b5B3af741b MainNet
    address public constant athenians = 0x17052d51E954592C1046320c2371AbaB6C73Ef10; //0x17052d51e954592c1046320c2371abab6c73ef10 MainNet

    // Battle events
    event WarriorsAssignedToBattlefield(address indexed from, address faction, uint256 battlePointsIncrementForecast);
    event WarriorsBackToHome(address indexed to, address faction, uint256 warriors);

    /*******************************************************************************************
    When the battle ends in a draw:
        (*) 10% of troops of both sides lie on the ground
        (*) 90% of them will be sent back to the former owner
        (*) No slaves are assigned
    When the battle ends with a winner:
        (*) 10% of troops of both sides lie on the ground
        (*) 90% of them will be sent back to the former owner
        (*) Surviving slaves are assigned to winner
    *******************************************************************************************/
    function Battle(uint256 _startTime, uint256 _life, uint8 _avarageBlockTime) Timed(_startTime, _life, _avarageBlockTime) { }

    /**** PHASE #1 ******/

    function assignPersiansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, persians, _warriors, maxPersians);
        // Persians are divisible with 18 decimals and their value is 1 BP
        WarriorsAssignedToBattlefield(msg.sender, persians, _warriors / 10**18);
    }

    function assignSpartansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, spartans, _warriors, maxSpartans);
        // Spartans are divisible with 18 decimals and their value is 1.000 BP
        WarriorsAssignedToBattlefield(msg.sender, spartans, (_warriors / 10**18) * 1000);
    }

    function assignImmortalsToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, immortals, _warriors, maxImmortals);
        // Immortals are not divisible and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, immortals, _warriors * 100);
    }

    function assignAtheniansToBattle(uint256 _warriors) onlyIfInTime external {
        assignWarriorsToBattle(msg.sender, athenians, _warriors, maxAthenians);
        // Athenians are divisible with 18 decimals and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, athenians, (_warriors / 10**18) * 100);
    }

    /**** PHASE #2 ******/

    function victoryIsOurs() onlyIfTimePassed {
        // Persians win
        if (getPersiansBattlePoints() > getGreeksBattlePoints()) retrieveWarriorsAndSlaves(persians, spartans);
        // Spartans win
        else if (getPersiansBattlePoints() < getGreeksBattlePoints()) retrieveWarriorsAndSlaves(spartans, persians);
        // It's a draw
        else retireveWarriors(msg.sender, persians, 10);
    }

    // When the battle is over, Immortals can be sent back to the former owner
    function retrieveImmortals() onlyIfTimePassed {
        retireveWarriors(msg.sender, immortals, 0);
    }

    // When the battle is over, Athenians can be sent back to the former owner
    function retrieveAthenians() onlyIfTimePassed {
        retireveWarriors(msg.sender, athenians, 0);
    }

    /*** PRIVATE FUNCTIONS ***/

    function assignWarriorsToBattle(address _player, address _faction, uint256 _warriors, uint256 _maxWarriors) private {
        require(warriorsOnTheBattlefield[_faction].add(_warriors) <= _maxWarriors);
        assert(TokenERC20(_faction).transferFrom(_player, address(this), _warriors));
        warriors[_player][_faction] = warriors[_player][_faction].add(_warriors);
        warriorsOnTheBattlefield[_faction] = warriorsOnTheBattlefield[_faction].add(_warriors);
    }

    function retrieveWarriorsAndSlaves(address _winners, address _loosers) private {
        uint256 slaveWarriors = getSlaves(msg.sender, _winners, _loosers);
        retireveWarriors(msg.sender, _winners, 10);
        sendWarriors(msg.sender, _loosers, slaveWarriors);
    }

    function retireveWarriors(address _player, address _faction, uint8 _deadAmount) private {
        if (_deadAmount > 0) {
            uint256 _deadWarriors = warriors[_player][_faction].div(_deadAmount);
            warriorsIntoAde[_faction] = warriorsIntoAde[_faction].add(_deadWarriors);
            warriors[_player][_faction] = warriors[_player][_faction].sub(_deadWarriors);
        }
        uint256 _warriors = warriors[_player][_faction];
        require(_warriors > 0);
        warriors[_player][_faction] = 0;
        sendWarriors(_player, _faction, _warriors);
        WarriorsBackToHome(_player, _faction, _warriors);
    }

    function sendWarriors(address _player, address _faction, uint256 _warriors) private {
        assert(TokenERC20(_faction).transfer(_player, _warriors));
    }

    /*** DAPP HELPERS AND CONSTANT FUNCTIONS ***/

    function getPersiansBattlePoints() constant returns (uint _battlePoints) {
        return ((warriorsOnTheBattlefield[persians]) + (warriorsOnTheBattlefield[immortals] * 10**18 * 100));
    }

    function getGreeksBattlePoints() constant returns (uint _battlePoints) {
        return ((warriorsOnTheBattlefield[spartans] * 1000) + (warriorsOnTheBattlefield[athenians] * 100));
    }

    // This method returns sensible values for two combinations of parameters: (persians, spartans) and (spartans, persians)
    function getSlaves(address _player, address _winningFaction, address _looserFaction) constant returns (uint256 _slaves) {
        return ((_winningFaction == persians && _looserFaction == spartans) || (_winningFaction == spartans && _looserFaction == persians)) ?
            (warriorsOnTheBattlefield[_looserFaction] - (warriorsOnTheBattlefield[_looserFaction] / 10)) / (warriorsOnTheBattlefield[_winningFaction] / warriors[_player][_winningFaction]) : 0;
    }

    function isDraw() constant returns (bool _draw) {
        return (getPersiansBattlePoints() == getGreeksBattlePoints());
    }

    function getWinningFaction() constant returns (string _winningFaction) {
        if (!isTimePassed()) return "The battle is still in progress";
        if (isDraw()) return "The battle ended in a draw!";
        return getPersiansBattlePoints() > getGreeksBattlePoints() ? "Persians" : "Greeks";
    }

    /**** DEV FUNCTIONS ******/

    function setPersiansWin() {
        warriorsOnTheBattlefield[persians] = 3000 * 10**18;  //3000
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 2 * 10**18; //2000
        warriorsOnTheBattlefield[athenians] = 3 * 10**18; //300
    }

    function setGreeksWin() {
        warriorsOnTheBattlefield[persians] = 300 * 10**18;  //300
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 27003 * 10**14; //2700.3
        warriorsOnTheBattlefield[athenians] = 3 * 10**18; //300
    }

    function setDraw() {
        warriorsOnTheBattlefield[persians] = 2200 * 10**18;  //2200
        warriorsOnTheBattlefield[immortals] = 2; //200
        warriorsOnTheBattlefield[spartans] = 2 * 10**18; //2000
        warriorsOnTheBattlefield[athenians] = 4 * 10**18; //400
    }

}


Replace explicit constructor with initializer

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.8.0;

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.8.0;

contract Migrations {
  address public owner;
  uint public last_completed_migration;

  constructor() public {
    owner = msg.sender;
  }

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}