diff --git a/SampleCampaign-TokenController.sol b/SampleCampaign-TokenController.sol
new file mode 100644
index 0000000..c583ef6
--- /dev/null
+++ b/SampleCampaign-TokenController.sol
@@ -0,0 +1,194 @@
+pragma solidity ^0.4.6;
+
+/*
+ Copyright 2017, Jordi Baylina
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+/// @title MilestoneTracker Contract
+/// @author Jordi Baylina
+/// @dev This contract controls the issuance of tokens for the MiniMe Token
+/// Contract. This version specifically acts as a Campaign manager for raising
+/// funds for non-profit causes, but it can be customized for any variety of
+/// purposes.
+
+import "MiniMeToken.sol";
+
+
+/// @dev `Owned` is a base level contract that assigns an `owner` that can be
+/// later changed
+contract Owned {
+ /// @dev `owner` is the only address that can call a function with this
+ /// modifier
+ modifier onlyOwner { if (msg.sender != owner) throw; _; }
+
+ address public owner;
+
+ /// @notice The Constructor assigns the message sender to be `owner`
+ function Owned() { owner = msg.sender;}
+
+ /// @notice `owner` can step down and assign some other address to this role
+ /// @param _newOwner The address of the new owner. 0x0 can be used to create
+ /// an unowned neutral vault, however that cannot be undone
+ function changeOwner(address _newOwner) onlyOwner {
+ owner = _newOwner;
+ }
+}
+
+
+/// @dev This is designed to control the issuance of a MiniMe Token for a
+/// non-profit Campaign. This contract effectively dictates the terms of the
+/// funding round.
+
+contract Campaign is TokenController, Owned {
+
+ uint public startFundingTime; // In UNIX Time Format
+ uint public endFundingTime; // In UNIX Time Format
+ uint public maximumFunding; // In wei
+ uint public totalCollected; // In wei
+ MiniMeToken public tokenContract; // The new token for this Campaign
+ address public vaultAddress; // The address to hold the funds donated
+
+/// @notice 'Campaign()' initiates the Campaign by setting its funding
+/// parameters
+/// @dev There are several checks to make sure the parameters are acceptable
+/// @param _startFundingTime The UNIX time that the Campaign will be able to
+/// start receiving funds
+/// @param _endFundingTime The UNIX time that the Campaign will stop being able
+/// to receive funds
+/// @param _maximumFunding In wei, the Maximum amount that the Campaign can
+/// receive (currently the max is set at 10,000 ETH for the beta)
+/// @param _vaultAddress The address that will store the donated funds
+/// @param _tokenAddress Address of the token contract this contract controls
+
+ function Campaign(
+ uint _startFundingTime,
+ uint _endFundingTime,
+ uint _maximumFunding,
+ address _vaultAddress,
+ address _tokenAddress
+ ) {
+ if ((_endFundingTime < now) || // Cannot end in the past
+ (_endFundingTime <= _startFundingTime) ||
+ (_maximumFunding > 10000 ether) || // The Beta is limited
+ (_vaultAddress == 0)) // To prevent burning ETH
+ {
+ throw;
+ }
+ startFundingTime = _startFundingTime;
+ endFundingTime = _endFundingTime;
+ maximumFunding = _maximumFunding;
+ tokenContract = MiniMeToken(_tokenAddress);// The Deployed Token Contract
+ vaultAddress = _vaultAddress;
+ }
+
+/// @dev The fallback function is called when ether is sent to the contract, it
+/// simply calls `doPayment()` with the address that sent the ether as the
+/// `_owner`. Payable is a required solidity modifier for functions to receive
+/// ether, without this modifier functions will throw if ether is sent to them
+
+ function () payable {
+ doPayment(msg.sender);
+ }
+
+/////////////////
+// TokenController interface
+/////////////////
+
+/// @notice `proxyPayment()` allows the caller to send ether to the Campaign and
+/// have the tokens created in an address of their choosing
+/// @param _owner The address that will hold the newly created tokens
+
+ function proxyPayment(address _owner) payable returns(bool) {
+ doPayment(_owner);
+ return true;
+ }
+
+/// @notice Notifies the controller about a transfer, for this Campaign all
+/// transfers are allowed by default and no extra notifications are needed
+/// @param _from The origin of the transfer
+/// @param _to The destination of the transfer
+/// @param _amount The amount of the transfer
+/// @return False if the controller does not authorize the transfer
+ function onTransfer(address _from, address _to, uint _amount) returns(bool) {
+ return true;
+ }
+
+/// @notice Notifies the controller about an approval, for this Campaign all
+/// approvals are allowed by default and no extra notifications are needed
+/// @param _owner The address that calls `approve()`
+/// @param _spender The spender in the `approve()` call
+/// @param _amount The amount in the `approve()` call
+/// @return False if the controller does not authorize the approval
+ function onApprove(address _owner, address _spender, uint _amount)
+ returns(bool)
+ {
+ return true;
+ }
+
+
+/// @dev `doPayment()` is an internal function that sends the ether that this
+/// contract receives to the `vault` and creates tokens in the address of the
+/// `_owner` assuming the Campaign is still accepting funds
+/// @param _owner The address that will hold the newly created tokens
+
+ function doPayment(address _owner) internal {
+
+// First check that the Campaign is allowed to receive this donation
+ if ((nowendFundingTime) ||
+ (tokenContract.controller() == 0) || // Extra check
+ (msg.value == 0) ||
+ (totalCollected + msg.value > maximumFunding))
+ {
+ throw;
+ }
+
+//Track how much the Campaign has collected
+ totalCollected += msg.value;
+
+//Send the ether to the vault
+ if (!vaultAddress.send(msg.value)) {
+ throw;
+ }
+
+// Creates an equal amount of tokens as ether sent. The new tokens are created
+// in the `_owner` address
+ if (!tokenContract.generateTokens(_owner, msg.value)) {
+ throw;
+ }
+
+ return;
+ }
+
+/// @notice `finalizeFunding()` ends the Campaign by calling setting the
+/// controller to 0, thereby ending the issuance of new tokens and stopping the
+/// Campaign from receiving more ether
+/// @dev `finalizeFunding()` can only be called after the end of the funding period.
+
+ function finalizeFunding() {
+ if (now < endFundingTime) throw;
+ tokenContract.changeController(0);
+ }
+
+
+/// @notice `onlyOwner` changes the location that ether is sent
+/// @param _newVaultAddress The address that will receive the ether sent to this
+/// Campaign
+ function setVault(address _newVaultAddress) onlyOwner {
+ vaultAddress = _newVaultAddress;
+ }
+
+}