├── LICENSE ├── README.md └── ico-contract.sol /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 bitfwd community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ICO-tutorial -------------------------------------------------------------------------------- /ico-contract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // 'bitfwd' CROWDSALE token contract 5 | // 6 | // Deployed to : 0xD0FDf2ECd4CadE671a7EE1063393eC0eB90816FD 7 | // Symbol : FWD 8 | // Name : bitfwd Token 9 | // Total supply: Gazillion 10 | // Decimals : 18 11 | // 12 | // Enjoy. 13 | // 14 | // (c) by Moritz Neto & Daniel Bar with BokkyPooBah / Bok Consulting Pty Ltd Au 2017. The MIT Licence. 15 | // ---------------------------------------------------------------------------- 16 | 17 | 18 | // ---------------------------------------------------------------------------- 19 | // Safe maths 20 | // ---------------------------------------------------------------------------- 21 | contract SafeMath { 22 | function safeAdd(uint a, uint b) internal pure returns (uint c) { 23 | c = a + b; 24 | require(c >= a); 25 | } 26 | function safeSub(uint a, uint b) internal pure returns (uint c) { 27 | require(b <= a); 28 | c = a - b; 29 | } 30 | function safeMul(uint a, uint b) internal pure returns (uint c) { 31 | c = a * b; 32 | require(a == 0 || c / a == b); 33 | } 34 | function safeDiv(uint a, uint b) internal pure returns (uint c) { 35 | require(b > 0); 36 | c = a / b; 37 | } 38 | } 39 | 40 | 41 | // ---------------------------------------------------------------------------- 42 | // ERC Token Standard #20 Interface 43 | // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md 44 | // ---------------------------------------------------------------------------- 45 | contract ERC20Interface { 46 | function totalSupply() public constant returns (uint); 47 | function balanceOf(address tokenOwner) public constant returns (uint balance); 48 | function allowance(address tokenOwner, address spender) public constant returns (uint remaining); 49 | function transfer(address to, uint tokens) public returns (bool success); 50 | function approve(address spender, uint tokens) public returns (bool success); 51 | function transferFrom(address from, address to, uint tokens) public returns (bool success); 52 | 53 | event Transfer(address indexed from, address indexed to, uint tokens); 54 | event Approval(address indexed tokenOwner, address indexed spender, uint tokens); 55 | } 56 | 57 | 58 | // ---------------------------------------------------------------------------- 59 | // Contract function to receive approval and execute function in one call 60 | // 61 | // Borrowed from MiniMeToken 62 | // ---------------------------------------------------------------------------- 63 | contract ApproveAndCallFallBack { 64 | function receiveApproval(address from, uint256 tokens, address token, bytes data) public; 65 | } 66 | 67 | 68 | // ---------------------------------------------------------------------------- 69 | // Owned contract 70 | // ---------------------------------------------------------------------------- 71 | contract Owned { 72 | address public owner; 73 | address public newOwner; 74 | 75 | event OwnershipTransferred(address indexed _from, address indexed _to); 76 | 77 | function Owned() public { 78 | owner = msg.sender; 79 | } 80 | 81 | modifier onlyOwner { 82 | require(msg.sender == owner); 83 | _; 84 | } 85 | 86 | function transferOwnership(address _newOwner) public onlyOwner { 87 | newOwner = _newOwner; 88 | } 89 | function acceptOwnership() public { 90 | require(msg.sender == newOwner); 91 | OwnershipTransferred(owner, newOwner); 92 | owner = newOwner; 93 | newOwner = address(0); 94 | } 95 | } 96 | 97 | 98 | // ---------------------------------------------------------------------------- 99 | // ERC20 Token, with the addition of symbol, name and decimals and assisted 100 | // token transfers 101 | // ---------------------------------------------------------------------------- 102 | contract bitfwdToken is ERC20Interface, Owned, SafeMath { 103 | string public symbol; 104 | string public name; 105 | uint8 public decimals; 106 | uint public _totalSupply; 107 | uint public startDate; 108 | uint public bonusEnds; 109 | uint public endDate; 110 | 111 | mapping(address => uint) balances; 112 | mapping(address => mapping(address => uint)) allowed; 113 | 114 | 115 | // ------------------------------------------------------------------------ 116 | // Constructor 117 | // ------------------------------------------------------------------------ 118 | function bitfwdToken() public { 119 | symbol = "FWD"; 120 | name = "bitfwd Token"; 121 | decimals = 18; 122 | bonusEnds = now + 1 weeks; 123 | endDate = now + 7 weeks; 124 | 125 | } 126 | 127 | 128 | // ------------------------------------------------------------------------ 129 | // Total supply 130 | // ------------------------------------------------------------------------ 131 | function totalSupply() public constant returns (uint) { 132 | return _totalSupply - balances[address(0)]; 133 | } 134 | 135 | 136 | // ------------------------------------------------------------------------ 137 | // Get the token balance for account `tokenOwner` 138 | // ------------------------------------------------------------------------ 139 | function balanceOf(address tokenOwner) public constant returns (uint balance) { 140 | return balances[tokenOwner]; 141 | } 142 | 143 | 144 | // ------------------------------------------------------------------------ 145 | // Transfer the balance from token owner's account to `to` account 146 | // - Owner's account must have sufficient balance to transfer 147 | // - 0 value transfers are allowed 148 | // ------------------------------------------------------------------------ 149 | function transfer(address to, uint tokens) public returns (bool success) { 150 | balances[msg.sender] = safeSub(balances[msg.sender], tokens); 151 | balances[to] = safeAdd(balances[to], tokens); 152 | Transfer(msg.sender, to, tokens); 153 | return true; 154 | } 155 | 156 | 157 | // ------------------------------------------------------------------------ 158 | // Token owner can approve for `spender` to transferFrom(...) `tokens` 159 | // from the token owner's account 160 | // 161 | // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md 162 | // recommends that there are no checks for the approval double-spend attack 163 | // as this should be implemented in user interfaces 164 | // ------------------------------------------------------------------------ 165 | function approve(address spender, uint tokens) public returns (bool success) { 166 | allowed[msg.sender][spender] = tokens; 167 | Approval(msg.sender, spender, tokens); 168 | return true; 169 | } 170 | 171 | 172 | // ------------------------------------------------------------------------ 173 | // Transfer `tokens` from the `from` account to the `to` account 174 | // 175 | // The calling account must already have sufficient tokens approve(...)-d 176 | // for spending from the `from` account and 177 | // - From account must have sufficient balance to transfer 178 | // - Spender must have sufficient allowance to transfer 179 | // - 0 value transfers are allowed 180 | // ------------------------------------------------------------------------ 181 | function transferFrom(address from, address to, uint tokens) public returns (bool success) { 182 | balances[from] = safeSub(balances[from], tokens); 183 | allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens); 184 | balances[to] = safeAdd(balances[to], tokens); 185 | Transfer(from, to, tokens); 186 | return true; 187 | } 188 | 189 | 190 | // ------------------------------------------------------------------------ 191 | // Returns the amount of tokens approved by the owner that can be 192 | // transferred to the spender's account 193 | // ------------------------------------------------------------------------ 194 | function allowance(address tokenOwner, address spender) public constant returns (uint remaining) { 195 | return allowed[tokenOwner][spender]; 196 | } 197 | 198 | 199 | // ------------------------------------------------------------------------ 200 | // Token owner can approve for `spender` to transferFrom(...) `tokens` 201 | // from the token owner's account. The `spender` contract function 202 | // `receiveApproval(...)` is then executed 203 | // ------------------------------------------------------------------------ 204 | function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) { 205 | allowed[msg.sender][spender] = tokens; 206 | Approval(msg.sender, spender, tokens); 207 | ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data); 208 | return true; 209 | } 210 | 211 | // ------------------------------------------------------------------------ 212 | // 1,000 FWD Tokens per 1 ETH 213 | // ------------------------------------------------------------------------ 214 | function () public payable { 215 | require(now >= startDate && now <= endDate); 216 | uint tokens; 217 | if (now <= bonusEnds) { 218 | tokens = msg.value * 1200; 219 | } else { 220 | tokens = msg.value * 1000; 221 | } 222 | balances[msg.sender] = safeAdd(balances[msg.sender], tokens); 223 | _totalSupply = safeAdd(_totalSupply, tokens); 224 | Transfer(address(0), msg.sender, tokens); 225 | owner.transfer(msg.value); 226 | } 227 | 228 | 229 | 230 | // ------------------------------------------------------------------------ 231 | // Owner can transfer out any accidentally sent ERC20 tokens 232 | // ------------------------------------------------------------------------ 233 | function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) { 234 | return ERC20Interface(tokenAddress).transfer(owner, tokens); 235 | } 236 | } 237 | --------------------------------------------------------------------------------