Created
November 14, 2018 20:45
-
-
Save darrendbutler/2e33a3b1d2ec763b9c40b6487955778f to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.25+commit.59dbf8f1.js&optimize=true&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.24; | |
| //CrowdSale contract knows the function signatures of IERC20 | |
| // because it is imported here | |
| //Call functions from IERC20 like token.transfer(...). | |
| import "./IERC20.sol"; | |
| import "./SafeMath.sol"; | |
| //The crowd sale contract allows a user to send ether directly to the | |
| //contract's address and receive tokens in return. | |
| contract Crowdsale { | |
| using SafeMath for uint256; | |
| uint256 private cap; // maximum amount of ether to be raised | |
| //once the contract receives the preset amount of ether, | |
| //the sale ends and no one can buy more tokens | |
| uint256 private weiRaised; // current amount of wei raised in the contract | |
| uint256 private rate; // price in wei per smallest unit of token (e.g. 1 wei = 10 smallet unit of a token) | |
| address private wallet; // wallet to hold the ethers raised. ether can be transfered her | |
| IERC20 private token; // address of erc20 tokens | |
| //Rate and wallet are passed into the constructor | |
| //Address of the token is passed into contructor | |
| /** | |
| * Event for token purchase logging | |
| * @param purchaser who paid for the tokens | |
| * @param beneficiary who got the tokens | |
| * @param value weis paid for purchase | |
| * @param amount amount of tokens purchased | |
| */ | |
| event TokensPurchased( | |
| address indexed purchaser, | |
| address indexed beneficiary, | |
| uint256 value, | |
| uint256 amount | |
| ); | |
| // ----------------------------------------- | |
| // Public functions (DO NOT change the interface!) | |
| // ----------------------------------------- | |
| /** | |
| * @param _rate Number of token units a buyer gets per wei | |
| * @dev The rate is the conversion between wei and the smallest and indivisible token unit. | |
| * @param _wallet Address where collected funds will be forwarded to | |
| * @param _token Address of the token being sold | |
| */ | |
| constructor(uint256 _rate, address _wallet, IERC20 _token, uint256 _cap, uint256 _weiRaised) public { | |
| // TODO: Your Code Here | |
| rate = _rate; | |
| wallet = _wallet; | |
| token = _token; | |
| cap = _cap; | |
| weiRaised = _weiRaised; | |
| } | |
| /** | |
| * @dev Fallback function for users to send ether directly to contract address | |
| * It should call the buyTokens function | |
| */ | |
| //Fallback function function is invoked when a user tries to send ether | |
| //directly to a smart contract address | |
| //Call the | |
| function() external payable { | |
| //Call the buyTokens function. | |
| //Pass in the address of the buyer | |
| buyTokens(msg.sender); | |
| } | |
| //determine how many tokens the user will get based on the amount | |
| //of ethers they've sent | |
| // Let's say 1 wei = 10 smallet unit of a token | |
| //Retreive the amount of ethers sent with msg.value | |
| //Transfer the amount of token to the user by | |
| //invoking the transfer() function in the ERC20 contract | |
| //The transfer function in the ERC20 contract transfers tokens | |
| //The transfer function on addrersses transfers wei | |
| //beneficiary will get tokens once they've bought them | |
| function buyTokens(address beneficiary) public payable { | |
| // - Calculate number of tokens | |
| //For every unit of wei the user gets some amount of tokens | |
| //The amount of tokens the user will get is | |
| // equal to the number the amount of wei being sent times the rate | |
| //(number of wei for every token) | |
| uint256 buyerTokens = msg.value.mul(rate); | |
| // - Validate any conditions | |
| //Make sure that the buyer is sending some wei | |
| require(msg.value > 0, "Invalid amount sent"); | |
| //Make sure that it hasn't reached the cap | |
| require(capReached() == false, "The cap has already been reached. No more ether can be received"); | |
| //Make sure that the wei being sent doesn't exceed the cap | |
| require(msg.value <= cap, "The amount being sent exceeds the cap"); | |
| //Ensure we have enough tokens in stock to complete this request | |
| //Check that the buyerTokens (tokens being requested) is less than | |
| // or equal to the tokens at the address stored in "tokens" | |
| require(buyerTokens <= token.balanceOf(address(this)), "number of tokens requested exceeds the amount of available tokens"); | |
| //Make sure the address wei is going to is valid | |
| require(beneficiary != 0, "Invalid beneficiary address"); | |
| // - Update any states | |
| //Receive pmt and give bidder their tokens | |
| //Add the wei payed to the weiRaised in the contract | |
| weiRaised = weiRaised.add(msg.value); | |
| // - Forward the wei payed to the beneificiary's wallet | |
| wallet.transfer(msg.value); | |
| // - Transfer tokens and emit event | |
| token.transfer(beneficiary, buyerTokens); | |
| emit TokensPurchased(msg.sender, beneficiary, msg.value, buyerTokens); | |
| } | |
| /** | |
| * @dev Checks whether the cap has been reached. | |
| * @return Whether the cap was reached | |
| */ | |
| function capReached() public view returns (bool) { | |
| // TODO: Your Code Here | |
| bool maxedOut; | |
| if(weiRaised >= cap ){ | |
| //If the weiRaised is equal to or greater than than cap, then | |
| // then the cap has been reached | |
| maxedOut = true; | |
| } else { | |
| maxedOut = false; | |
| } | |
| return maxedOut; | |
| } | |
| // ----------------------------------------- | |
| // Internal functions (you can write any other internal helper functions here) | |
| // ----------------------------------------- | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.24; | |
| import "./IERC20.sol"; | |
| import "./SafeMath.sol"; | |
| /** | |
| * @title Standard ERC20 token | |
| * @dev Implementation of the basic standard token. | |
| */ | |
| contract ERC20 is IERC20 { | |
| using SafeMath for uint256; | |
| //_balances: an address points to an integer that represnts | |
| //the number of tokens a user address owns | |
| //Update the mapping when a token is transferred | |
| mapping (address => uint256) internal _balances; | |
| //An address that represents the owner of some token points to another | |
| // adrress that has been authorized to spend tokens by the owner, which points | |
| //to an integer represnetation of tokens | |
| //(The owner's address points to the spender's address that points to | |
| //the amount of tokens to be spent) | |
| //Access it like myMapping[outerKey][innerKey]. | |
| mapping (address => mapping (address => uint256)) internal _allowed; | |
| //Keeps track of the total amount of tokens in the system | |
| uint256 internal _totalSupply; | |
| // ----------------------------------------- | |
| // Public Functions (DO NOT CHANGE!!) | |
| // ----------------------------------------- | |
| /** | |
| * @dev returns the Total number of tokens in existence | |
| */ | |
| function totalSupply() public view returns (uint256) { | |
| // TODO: Your Code Here | |
| return _totalSupply; | |
| } | |
| /** | |
| * @dev Gets the balance of the specified address. | |
| * @param owner (The address you want the balance of.) | |
| * @return An uint256 representing the amount owned by the passed address. | |
| */ | |
| function balanceOf(address owner) public view returns (uint256) { | |
| // TODO: Your Code Here | |
| return _balances[owner]; | |
| } | |
| /** | |
| * @dev Function to check the amount of tokens that an owner allows | |
| * a spender to spend | |
| * @param owner address is the address which owns the funds. | |
| * @param spender address is the address which will spend the funds. | |
| * @return A uint256 (integer) the amount of tokens the spender can still | |
| * spend. | |
| */ | |
| function allowance(address owner, address spender) public view returns(uint256) { | |
| // TODO: Your Code Here | |
| return _allowed[owner][spender]; | |
| } | |
| /** | |
| * @dev Allow the owner to tansfer tokens to another user | |
| * @param to The address to transfer to. | |
| * @param value The amount to be transferred. | |
| * @return Should always return true if all conditions are met (if the owner | |
| * has tokens. Otherwise throw exception using require statements. | |
| */ | |
| function transfer(address to, uint256 value) public returns (bool) { | |
| // TODO: Your Code Here | |
| //Require the balances is greater than or equal to the value of tokens | |
| //being sent | |
| require (_balances[msg.sender] >= value, "Insufficient tokens to transfer specified amount"); | |
| //Require that the adress is not a 0x0 address (it must be elligible) | |
| require(to != address(0), "Invalid address used"); | |
| //Substract the value being transfered from the address of the owner | |
| _balances[msg.sender] = _balances[msg.sender].sub(value); | |
| //Add the tokens being transferred to the balance of the receiving address | |
| _balances[to] = _balances[to].add(value); | |
| //Log information of transfer to the blockchain using the Transfer event | |
| //from IERC20 | |
| emit Transfer(msg.sender, to, value); | |
| return true; | |
| } | |
| /** | |
| * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. | |
| * Note that the owner (msg.sender) can approve someone to spend tokens that they do not yet have. | |
| * @param spender The address which will spend the funds. | |
| * @param value The amount of tokens to be spent. | |
| * @return Should always return true if success. Otherwise throw exception. | |
| */ | |
| function approve(address spender, uint256 value) public returns (bool) { | |
| // TODO: Your Code Here | |
| //Only allow the owner to approve an address to spend | |
| require(msg.sender != spender); | |
| //Make sure the spender address is valid | |
| require(spender != address(0), "Invalid spender address"); | |
| //Catch negative numbers or zero | |
| require(value > 0, "Value to be spent must be greater than 0"); | |
| //Set the amount of tokens that can be spent. | |
| value = _allowed[msg.sender][spender]; | |
| //Log the approval information to the blockchain | |
| emit Approval(msg.sender, spender, value); | |
| return true; | |
| } | |
| /** | |
| * @dev Transfer tokens from one address to another | |
| * A spender will call to spend an owner's token | |
| * @param from address The address which you want to send tokens from | |
| * @param to address The address which you want to transfer to | |
| * @param value uint256 the amount of tokens to be transferred | |
| */ | |
| function transferFrom(address from, address to, uint256 value) public returns (bool) { | |
| // TODO: Your Code Here | |
| //First check that the receiving address is valid | |
| require(to != address(0)); | |
| //Check that the value being sent is greater than 0 | |
| require(value > 0); | |
| //check that the spender is approved by the owner | |
| //Check that the value being spent is greater than or equal the | |
| //value allowed by the owner | |
| require(_allowed[from][msg.sender] >= value, "You are not allowed to spend that many tokens."); | |
| //check that the owner has enough tokens to spend | |
| //The balance associated with address "from" must be greater than or equal to value being spent | |
| require(_balances[from] >= value, "Owner has insufficient tokens"); | |
| //Substract the value of tokens being transfered from the owners's balance | |
| _balances[from] = _balances[from].sub(value); | |
| //Add the value of token being transfered to the receiving address balance | |
| _balances[to] = _balances[to].add(value); | |
| //Substract the value of tokens being transferred from the | |
| //amount the spender is allowed to spender | |
| _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); | |
| //transfer the tokens to the receiving address | |
| to.transfer(value); | |
| //check | |
| //update state | |
| //Log the transfer information to the blockchain | |
| emit Transfer(from, to, value); | |
| } | |
| // ----------------------------------------- | |
| // Internal functions (you can write any other internal helper functions here) | |
| // ----------------------------------------- | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.24; | |
| import "./ERC20.sol"; | |
| contract ERC20Test is ERC20 { | |
| address public owner; | |
| constructor() public { | |
| owner = msg.sender; | |
| } | |
| /** | |
| * @dev Function that mints an amount of the token and assigns it to | |
| * an account. This encapsulates the modification of balances such that the | |
| * proper events are emitted. | |
| * @param account The account that will receive the created tokens. | |
| * @param amount The amount that will be created. | |
| */ | |
| function mint(address account, uint256 amount) public { | |
| require(msg.sender == owner); | |
| require(account != 0); | |
| _totalSupply = _totalSupply.add(amount); | |
| _balances[account] = _balances[account].add(amount); | |
| emit Transfer(address(0), account, amount); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.24; | |
| /** | |
| * @title ERC20 interface | |
| * @dev see https://github.com/ethereum/EIPs/issues/20 | |
| */ | |
| interface IERC20 { | |
| function totalSupply() external view returns (uint256); | |
| function balanceOf(address who) external view returns (uint256); | |
| function allowance(address owner, address spender) external view returns (uint256); | |
| function transfer(address to, uint256 value) external returns (bool); | |
| function approve(address spender, uint256 value) external returns (bool); | |
| function transferFrom(address from, address to, uint256 value) external returns (bool); | |
| event Transfer(address indexed from, address indexed to, uint256 value); | |
| event Approval(address indexed owner, address indexed spender, uint256 value); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.24; | |
| /** | |
| * @title SafeMath | |
| * @dev Math operations with safety checks that revert on error | |
| */ | |
| library SafeMath { | |
| /** | |
| * @dev Multiplies two numbers, reverts on overflow. | |
| */ | |
| function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
| // Gas optimization: this is cheaper than requiring 'a' not being zero, but the | |
| // benefit is lost if 'b' is also tested. | |
| // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
| if (a == 0) { | |
| return 0; | |
| } | |
| uint256 c = a * b; | |
| require(c / a == b); | |
| return c; | |
| } | |
| /** | |
| * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. | |
| */ | |
| function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
| require(b > 0); // Solidity only automatically asserts when dividing by 0 | |
| uint256 c = a / b; | |
| // assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
| return c; | |
| } | |
| /** | |
| * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). | |
| */ | |
| function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
| require(b <= a); | |
| uint256 c = a - b; | |
| return c; | |
| } | |
| /** | |
| * @dev Adds two numbers, reverts on overflow. | |
| */ | |
| function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
| uint256 c = a + b; | |
| require(c >= a); | |
| return c; | |
| } | |
| /** | |
| * @dev Divides two numbers and returns the remainder (unsigned integer modulo), | |
| * reverts when dividing by zero. | |
| */ | |
| function mod(uint256 a, uint256 b) internal pure returns (uint256) { | |
| require(b != 0); | |
| return a % b; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment