mirror of
https://github.com/fluencelabs/smartcontracts
synced 2025-04-24 10:42:19 +00:00
Fpt release (#1)
This commit is contained in:
parent
c779da5064
commit
cd29ed4b99
13
contracts/FakeCertifier.sol
Normal file
13
contracts/FakeCertifier.sol
Normal file
@ -0,0 +1,13 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
contract FakeCertifier {
|
||||
function FakeCertifier(){
|
||||
|
||||
}
|
||||
|
||||
function certified(address _who) constant returns (bool) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
111
contracts/FluencePreRelease.sol
Normal file
111
contracts/FluencePreRelease.sol
Normal file
@ -0,0 +1,111 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
|
||||
import 'zeppelin-solidity/contracts/token/ERC20Basic.sol';
|
||||
import 'zeppelin-solidity/contracts/token/StandardToken.sol';
|
||||
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
|
||||
|
||||
|
||||
interface Certifier {
|
||||
function certified(address _who) constant returns (bool);
|
||||
}
|
||||
|
||||
|
||||
contract FluencePreRelease is Ownable {
|
||||
event Released(address indexed caller, address indexed _to, uint256 amount);
|
||||
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping (address => uint256) public released;
|
||||
|
||||
address public certifier;
|
||||
|
||||
address public preSale;
|
||||
|
||||
address public token;
|
||||
|
||||
bool public launched;
|
||||
|
||||
address public spender;
|
||||
|
||||
modifier beforeLaunch {
|
||||
require(!launched);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier afterLaunch {
|
||||
require(launched);
|
||||
_;
|
||||
}
|
||||
|
||||
function FluencePreRelease(address _certifier, address _preSale, address _token, address _spender) {
|
||||
require(_certifier != address(0x0));
|
||||
require(_preSale != address(0x0));
|
||||
require(_token != address(0x0));
|
||||
|
||||
certifier = _certifier;
|
||||
preSale = _preSale;
|
||||
token = _token;
|
||||
|
||||
if (_spender == address(0x0)) {
|
||||
spender = msg.sender;
|
||||
}
|
||||
else {
|
||||
spender = _spender;
|
||||
}
|
||||
}
|
||||
|
||||
// Can preset only before releasing is launched
|
||||
function presetReleased(address _to, uint256 amount) onlyOwner beforeLaunch public {
|
||||
released[_to] = amount;
|
||||
}
|
||||
|
||||
// After launch, owner can't do anything with the contract
|
||||
function launch() onlyOwner beforeLaunch public {
|
||||
launched = true;
|
||||
}
|
||||
|
||||
function release(address _holder) public afterLaunch returns (uint256 amount) {
|
||||
address beneficiary = _holder;
|
||||
if (beneficiary == address(0x0)) beneficiary = msg.sender;
|
||||
// check if verified
|
||||
require(Certifier(certifier).certified(beneficiary));
|
||||
|
||||
address source = msg.sender;
|
||||
// check fpt balance
|
||||
// subtract $released
|
||||
amount = ERC20Basic(preSale).balanceOf(source).sub(released[source]);
|
||||
require(amount > 0);
|
||||
|
||||
// release tokens
|
||||
released[source] = released[source].add(amount);
|
||||
assert(released[source] == ERC20Basic(preSale).balanceOf(source));
|
||||
|
||||
assert(StandardToken(token).transferFrom(spender, beneficiary, amount));
|
||||
Released(source, beneficiary, amount);
|
||||
}
|
||||
|
||||
function bytesToAddress(bytes _address) internal returns (address) {
|
||||
uint160 m = 0;
|
||||
uint160 b = 0;
|
||||
|
||||
for (uint8 i = 0; i < 20; i++) {
|
||||
m *= 256;
|
||||
b = uint160(_address[i]);
|
||||
m += (b);
|
||||
}
|
||||
|
||||
return address(m);
|
||||
}
|
||||
|
||||
function() public {
|
||||
if (msg.data.length == 20) {
|
||||
release(bytesToAddress(msg.data));
|
||||
}
|
||||
else {
|
||||
release(msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
17
contracts/FluenceToken.sol
Normal file
17
contracts/FluenceToken.sol
Normal file
@ -0,0 +1,17 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
import './RenameableSymbol.sol';
|
||||
import 'zeppelin-solidity/contracts/token/BurnableToken.sol';
|
||||
|
||||
|
||||
contract FluenceToken is BurnableToken, RenameableSymbol("FPT(U)", "Fluence Presale Token (Unlocked)") {
|
||||
|
||||
function FluenceToken(uint256 allocation) {
|
||||
totalSupply = allocation;
|
||||
balances[owner] = allocation;
|
||||
}
|
||||
|
||||
uint public constant decimals = 18;
|
||||
|
||||
}
|
37
contracts/Haltable.sol
Normal file
37
contracts/Haltable.sol
Normal file
@ -0,0 +1,37 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
|
||||
|
||||
/*
|
||||
* Haltable
|
||||
*
|
||||
* Abstract contract that allows children to implement an
|
||||
* emergency stop mechanism. Differs from Pausable by causing a throw when in halt mode.
|
||||
*
|
||||
*
|
||||
* Originally envisioned in FirstBlood ICO contract.
|
||||
*/
|
||||
contract Haltable is Ownable {
|
||||
bool public halted;
|
||||
|
||||
modifier stopInEmergency {
|
||||
require(!halted);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyInEmergency {
|
||||
require(halted);
|
||||
_;
|
||||
}
|
||||
|
||||
// called by the owner on emergency, triggers stopped state
|
||||
function halt() external onlyOwner {
|
||||
halted = true;
|
||||
}
|
||||
|
||||
// called by the owner on end of emergency, returns to normal state
|
||||
function unhalt() external onlyOwner onlyInEmergency {
|
||||
halted = false;
|
||||
}
|
||||
|
||||
}
|
16
contracts/MintTokenProxy.sol
Normal file
16
contracts/MintTokenProxy.sol
Normal file
@ -0,0 +1,16 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import './Mintable.sol';
|
||||
|
||||
// Used only for testing
|
||||
contract MintTokenProxy {
|
||||
Mintable token;
|
||||
|
||||
function setToken(address _token) public {
|
||||
token = Mintable(_token);
|
||||
}
|
||||
|
||||
function mint(address _to, uint256 _amount) public returns(bool) {
|
||||
return token.mint(_to, _amount);
|
||||
}
|
||||
}
|
55
contracts/Mintable.sol
Normal file
55
contracts/Mintable.sol
Normal file
@ -0,0 +1,55 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import 'zeppelin-solidity/contracts/token/StandardToken.sol';
|
||||
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
|
||||
|
||||
contract Mintable is StandardToken, Ownable {
|
||||
|
||||
event Mint(address indexed to, uint256 amount);
|
||||
event MintFinished();
|
||||
|
||||
bool public mintingFinished = false;
|
||||
mapping (address => bool) private minters;
|
||||
|
||||
modifier canMint() {
|
||||
require(!mintingFinished);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyMinter() {
|
||||
require(minters[msg.sender]);
|
||||
_;
|
||||
}
|
||||
|
||||
function allowMinting(address _to) onlyOwner canMint public {
|
||||
minters[_to] = true;
|
||||
}
|
||||
|
||||
function denyMinting(address _to) onlyOwner public {
|
||||
delete minters[_to];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to mint tokens
|
||||
* @param _to The address that will receive the minted tokens.
|
||||
* @param _amount The amount of tokens to mint.
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function mint(address _to, uint256 _amount) onlyMinter canMint public returns (bool) {
|
||||
totalSupply = totalSupply.add(_amount);
|
||||
balances[_to] = balances[_to].add(_amount);
|
||||
Mint(_to, _amount);
|
||||
Transfer(0x0, _to, _amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to stop minting new tokens.
|
||||
* @return True if the operation was successful.
|
||||
*/
|
||||
function finishMinting() onlyOwner canMint public returns (bool) {
|
||||
mintingFinished = true;
|
||||
MintFinished();
|
||||
return true;
|
||||
}
|
||||
}
|
21
contracts/RenameableSymbol.sol
Normal file
21
contracts/RenameableSymbol.sol
Normal file
@ -0,0 +1,21 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
|
||||
|
||||
|
||||
contract RenameableSymbol is Ownable {
|
||||
string public name;
|
||||
|
||||
string public symbol;
|
||||
|
||||
function RenameableSymbol(string _symbol, string _name) public {
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
}
|
||||
|
||||
function rename(string _symbol, string _name) onlyOwner public {
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
}
|
||||
}
|
7
migrations/3_minting.js
Normal file
7
migrations/3_minting.js
Normal file
@ -0,0 +1,7 @@
|
||||
var Mintable = artifacts.require("./Mintable.sol");
|
||||
var MintTokenProxy = artifacts.require("./MintTokenProxy.sol");
|
||||
|
||||
module.exports = function(deployer) {
|
||||
deployer.deploy(Mintable);
|
||||
deployer.deploy(MintTokenProxy);
|
||||
};
|
12
migrations/4_releasing.js
Normal file
12
migrations/4_releasing.js
Normal file
@ -0,0 +1,12 @@
|
||||
var FluenceToken = artifacts.require("./FluenceToken.sol");
|
||||
var FluencePreSale = artifacts.require("./FluencePreSale.sol");
|
||||
var FluencePreRelease = artifacts.require("./FluencePreRelease.sol");
|
||||
var FakeCertifier = artifacts.require("./FakeCertifier.sol");
|
||||
|
||||
module.exports = function (deployer) {
|
||||
deployer.deploy(FluenceToken, 2*10**(18+7)).then(() => {
|
||||
deployer.deploy(FakeCertifier).then(() => {
|
||||
deployer.deploy(FluencePreRelease, FakeCertifier.address, FluencePreSale.address, FluenceToken.address);
|
||||
})
|
||||
});
|
||||
};
|
239
package-lock.json
generated
239
package-lock.json
generated
@ -16,9 +16,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
|
||||
"integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
@ -27,45 +27,45 @@
|
||||
}
|
||||
},
|
||||
"babel-core": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz",
|
||||
"integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
|
||||
"integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-code-frame": "6.22.0",
|
||||
"babel-generator": "6.25.0",
|
||||
"babel-code-frame": "6.26.0",
|
||||
"babel-generator": "6.26.0",
|
||||
"babel-helpers": "6.24.1",
|
||||
"babel-messages": "6.23.0",
|
||||
"babel-register": "6.24.1",
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-template": "6.25.0",
|
||||
"babel-traverse": "6.25.0",
|
||||
"babel-types": "6.25.0",
|
||||
"babylon": "6.17.4",
|
||||
"babel-register": "6.26.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"babel-template": "6.26.0",
|
||||
"babel-traverse": "6.26.0",
|
||||
"babel-types": "6.26.0",
|
||||
"babylon": "6.18.0",
|
||||
"convert-source-map": "1.5.0",
|
||||
"debug": "2.6.8",
|
||||
"debug": "2.6.9",
|
||||
"json5": "0.5.1",
|
||||
"lodash": "4.17.4",
|
||||
"minimatch": "3.0.4",
|
||||
"path-is-absolute": "1.0.1",
|
||||
"private": "0.1.7",
|
||||
"slash": "1.0.0",
|
||||
"source-map": "0.5.6"
|
||||
"source-map": "0.5.7"
|
||||
}
|
||||
},
|
||||
"babel-generator": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz",
|
||||
"integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
|
||||
"integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-messages": "6.23.0",
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-types": "6.25.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"babel-types": "6.26.0",
|
||||
"detect-indent": "4.0.0",
|
||||
"jsesc": "1.3.0",
|
||||
"lodash": "4.17.4",
|
||||
"source-map": "0.5.6",
|
||||
"source-map": "0.5.7",
|
||||
"trim-right": "1.0.1"
|
||||
}
|
||||
},
|
||||
@ -75,8 +75,8 @@
|
||||
"integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-template": "6.25.0"
|
||||
"babel-runtime": "6.26.0",
|
||||
"babel-template": "6.26.0"
|
||||
}
|
||||
},
|
||||
"babel-messages": {
|
||||
@ -85,89 +85,96 @@
|
||||
"integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0"
|
||||
"babel-runtime": "6.26.0"
|
||||
}
|
||||
},
|
||||
"babel-polyfill": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz",
|
||||
"integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
|
||||
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0",
|
||||
"core-js": "2.5.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"core-js": "2.5.1",
|
||||
"regenerator-runtime": "0.10.5"
|
||||
}
|
||||
},
|
||||
"babel-register": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz",
|
||||
"integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
|
||||
"integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-core": "6.25.0",
|
||||
"babel-runtime": "6.25.0",
|
||||
"core-js": "2.5.0",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"core-js": "2.5.1",
|
||||
"home-or-tmp": "2.0.0",
|
||||
"lodash": "4.17.4",
|
||||
"mkdirp": "0.5.1",
|
||||
"source-map-support": "0.4.15"
|
||||
"source-map-support": "0.4.18"
|
||||
}
|
||||
},
|
||||
"babel-runtime": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz",
|
||||
"integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
||||
"requires": {
|
||||
"core-js": "2.5.0",
|
||||
"regenerator-runtime": "0.10.5"
|
||||
"core-js": "2.5.1",
|
||||
"regenerator-runtime": "0.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"regenerator-runtime": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
|
||||
"integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-template": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz",
|
||||
"integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
|
||||
"integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-traverse": "6.25.0",
|
||||
"babel-types": "6.25.0",
|
||||
"babylon": "6.17.4",
|
||||
"babel-runtime": "6.26.0",
|
||||
"babel-traverse": "6.26.0",
|
||||
"babel-types": "6.26.0",
|
||||
"babylon": "6.18.0",
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-traverse": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz",
|
||||
"integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
|
||||
"integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-code-frame": "6.22.0",
|
||||
"babel-code-frame": "6.26.0",
|
||||
"babel-messages": "6.23.0",
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-types": "6.25.0",
|
||||
"babylon": "6.17.4",
|
||||
"debug": "2.6.8",
|
||||
"babel-runtime": "6.26.0",
|
||||
"babel-types": "6.26.0",
|
||||
"babylon": "6.18.0",
|
||||
"debug": "2.6.9",
|
||||
"globals": "9.18.0",
|
||||
"invariant": "2.2.2",
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-types": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz",
|
||||
"integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
|
||||
"integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"esutils": "2.0.2",
|
||||
"lodash": "4.17.4",
|
||||
"to-fast-properties": "1.0.3"
|
||||
}
|
||||
},
|
||||
"babylon": {
|
||||
"version": "6.17.4",
|
||||
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz",
|
||||
"integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==",
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
|
||||
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
@ -210,14 +217,6 @@
|
||||
"has-ansi": "2.0.0",
|
||||
"strip-ansi": "3.0.1",
|
||||
"supports-color": "2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
@ -255,14 +254,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.0.tgz",
|
||||
"integrity": "sha1-VpwFCRi+ZIazg3VSAorgRmtxcIY="
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
|
||||
"integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@ -323,7 +323,7 @@
|
||||
"jsonfile": "2.4.0",
|
||||
"klaw": "1.3.1",
|
||||
"path-is-absolute": "1.0.1",
|
||||
"rimraf": "2.6.1"
|
||||
"rimraf": "2.6.2"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
@ -384,6 +384,11 @@
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
||||
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
|
||||
},
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
||||
@ -627,9 +632,9 @@
|
||||
}
|
||||
},
|
||||
"mocha": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz",
|
||||
"integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz",
|
||||
"integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==",
|
||||
"requires": {
|
||||
"browser-stdout": "1.3.0",
|
||||
"commander": "2.9.0",
|
||||
@ -638,10 +643,29 @@
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"glob": "7.1.1",
|
||||
"growl": "1.9.2",
|
||||
"he": "1.1.1",
|
||||
"json3": "3.3.2",
|
||||
"lodash.create": "3.1.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"supports-color": "3.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
|
||||
"integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
|
||||
"requires": {
|
||||
"has-flag": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
@ -802,9 +826,9 @@
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
|
||||
"integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"requires": {
|
||||
"glob": "7.1.1"
|
||||
}
|
||||
@ -826,9 +850,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"solc": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/solc/-/solc-0.4.13.tgz",
|
||||
"integrity": "sha1-qly9zOPmrjwZDSD1/fi8iAcC7HU=",
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/solc/-/solc-0.4.18.tgz",
|
||||
"integrity": "sha512-Kq+O3PNF9Pfq7fB+lDYAuoqRdghLmZyfngsg0h1Hj38NKAeVHeGPOGeZasn5KqdPeCzbMFvaGyTySxzGv6aXCg==",
|
||||
"requires": {
|
||||
"fs-extra": "0.30.0",
|
||||
"memorystream": "0.3.1",
|
||||
@ -838,18 +862,18 @@
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz",
|
||||
"integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=",
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
|
||||
"integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map": "0.5.6"
|
||||
"source-map": "0.5.7"
|
||||
}
|
||||
},
|
||||
"spdx-correct": {
|
||||
@ -897,12 +921,10 @@
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
|
||||
"integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
|
||||
"requires": {
|
||||
"has-flag": "1.0.0"
|
||||
}
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "1.0.3",
|
||||
@ -917,13 +939,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"truffle": {
|
||||
"version": "3.4.7",
|
||||
"resolved": "https://registry.npmjs.org/truffle/-/truffle-3.4.7.tgz",
|
||||
"integrity": "sha512-sAc1dixGDpt38Qq9gqEEIFpXXIIaNKViWlojD9Xv4NBqK/03lxb43M7gcILM4gMpgMdwtTAunG4ZQe7z+HYvJQ==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/truffle/-/truffle-4.0.1.tgz",
|
||||
"integrity": "sha512-PybO+GMq3AvsfCWfEx4sbuaJlDL19iR8Ff20cO0TtP599N5JbMLlhwlffvVInPgFjP+F11vjSOYj3hT8fONs5A==",
|
||||
"requires": {
|
||||
"mocha": "3.5.0",
|
||||
"mocha": "3.5.3",
|
||||
"original-require": "1.0.1",
|
||||
"solc": "0.4.13"
|
||||
"solc": "0.4.18"
|
||||
}
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
@ -993,6 +1015,11 @@
|
||||
"camelcase": "3.0.0",
|
||||
"lodash.assign": "4.2.0"
|
||||
}
|
||||
},
|
||||
"zeppelin-solidity": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/zeppelin-solidity/-/zeppelin-solidity-1.3.0.tgz",
|
||||
"integrity": "sha512-q+WyqvQjE5gpKgXrhD8LBh0Njg7GI/zs4lKX14y0j7ISJIxe68hihSjaMU05V0M0qAbxgRC43AFTt7CxNsO8nQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
package.json
10
package.json
@ -3,13 +3,15 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"run": "truffle build"
|
||||
"build": "truffle build",
|
||||
"dev": "truffle develop"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"truffle": "^3.4.7"
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"truffle": "^4.0.1",
|
||||
"zeppelin-solidity": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-register": "^6.24.1"
|
||||
"babel-register": "^6.26.0"
|
||||
}
|
||||
}
|
||||
|
146
test/mintable.js
Normal file
146
test/mintable.js
Normal file
@ -0,0 +1,146 @@
|
||||
const MintTokenProxy = artifacts.require("./MintTokenProxy.sol");
|
||||
const Mintable = artifacts.require("./Mintable.sol");
|
||||
|
||||
contract('FluenceToken', function (accounts) {
|
||||
|
||||
|
||||
it("should allow/deny minting to owner", async function() {
|
||||
const token = await Mintable.deployed();
|
||||
|
||||
// Initially, there's no supply
|
||||
const s = await token.totalSupply()
|
||||
assert.equal(s, 0)
|
||||
|
||||
// Try to mint by owner
|
||||
try {
|
||||
await token.mint(accounts[1], 1000)
|
||||
} catch(e) {
|
||||
}
|
||||
// Try to allow minting by wrong account
|
||||
try {
|
||||
await token.allowMinting(accounts[3], {from: accounts[1]})
|
||||
} catch(e) {
|
||||
}
|
||||
// Try to mint by another account
|
||||
try {
|
||||
await token.mint(accounts[1], 1000, {from: accounts[3]})
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
// Total supply and balance should be intact
|
||||
const s1 = await token.totalSupply()
|
||||
assert.equal(s1, 0)
|
||||
|
||||
const b0 = await token.balanceOf(accounts[1])
|
||||
assert.equal(b0, 0)
|
||||
|
||||
// Allow minting for one account
|
||||
await token.allowMinting(accounts[3])
|
||||
|
||||
// Try mint from wrong account
|
||||
try {
|
||||
await token.mint(accounts[1], 1000)
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
// Balances should be intact
|
||||
const s2 = await token.totalSupply()
|
||||
assert.equal(s2, 0)
|
||||
|
||||
const b1 = await token.balanceOf(accounts[1])
|
||||
assert.equal(b1, 0)
|
||||
|
||||
// Try to mint from wrong (non-owner) account
|
||||
try {
|
||||
await token.mint(accounts[1], 1000, {from: accounts[1]})
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
// Balances should be intact
|
||||
const s3 = await token.totalSupply()
|
||||
assert.equal(s3.valueOf(), 0)
|
||||
|
||||
const b2 = await token.balanceOf(accounts[1])
|
||||
assert.equal(b2.valueOf(), 0)
|
||||
|
||||
// Try to mint from correct account
|
||||
await token.mint(accounts[1], 1000, {from: accounts[3]})
|
||||
|
||||
// Supply should be changed
|
||||
const s4 = await token.totalSupply()
|
||||
assert.equal(s4.valueOf(), 1000)
|
||||
|
||||
const b3 = await token.balanceOf(accounts[1])
|
||||
assert.equal(b3.valueOf(), 1000)
|
||||
|
||||
// Deny minting by wrong account
|
||||
try {
|
||||
await token.denyMinting(acounts[3], {from: accounts[3]})
|
||||
} catch(e){}
|
||||
|
||||
await token.mint(accounts[1], 1000, {from: accounts[3]})
|
||||
const s5 = await token.totalSupply()
|
||||
assert.equal(s5.valueOf(), 2000)
|
||||
|
||||
// Deny minting
|
||||
await token.denyMinting(accounts[3])
|
||||
try {
|
||||
await token.mint(accounts[1], 1000, {from: accounts[3]})
|
||||
} catch(e){}
|
||||
const s6 = await token.totalSupply()
|
||||
assert.equal(s6.valueOf(), 2000)
|
||||
})
|
||||
|
||||
it("should mint correctly via proxy", async function(){
|
||||
const token = await Mintable.deployed();
|
||||
const proxy = await MintTokenProxy.deployed();
|
||||
await proxy.setToken(token.address)
|
||||
|
||||
await token.allowMinting(proxy.address)
|
||||
|
||||
const s0 = await token.totalSupply()
|
||||
assert.equal(s0.valueOf(), 2000)
|
||||
|
||||
try {
|
||||
await token.mint(accounts[0], 1000)
|
||||
} catch(e){}
|
||||
|
||||
const s1 = await token.totalSupply()
|
||||
assert.equal(s1.valueOf(), 2000)
|
||||
|
||||
await proxy.mint(accounts[4], 1000)
|
||||
|
||||
const s2 = await token.totalSupply()
|
||||
assert.equal(s2.valueOf(), 3000)
|
||||
|
||||
const b0 = await token.balanceOf(accounts[4])
|
||||
assert.equal(b0.valueOf(), 1000)
|
||||
|
||||
await token.denyMinting(proxy.address)
|
||||
try {
|
||||
await proxy.mint(accounts[4], 1000)
|
||||
} catch(e){}
|
||||
|
||||
const s3 = await token.totalSupply()
|
||||
assert.equal(s3.valueOf(), 3000)
|
||||
|
||||
})
|
||||
|
||||
it("should deny minting after all", async function(){
|
||||
const token = await Mintable.deployed();
|
||||
|
||||
const s3 = await token.totalSupply()
|
||||
assert.equal(s3.valueOf(), 3000)
|
||||
|
||||
// Allow minting again
|
||||
await token.allowMinting(accounts[1])
|
||||
// Finish minting
|
||||
await token.finishMinting()
|
||||
// Can't mint anymore
|
||||
try {
|
||||
await token.mint(accounts[1], 1000, {from: accounts[3]})
|
||||
} catch(e){}
|
||||
const s7 = await token.totalSupply()
|
||||
assert.equal(s7.valueOf(), 3000)
|
||||
})
|
||||
});
|
32
test/token.js
Normal file
32
test/token.js
Normal file
@ -0,0 +1,32 @@
|
||||
const FluenceToken = artifacts.require("./FluenceToken.sol");
|
||||
|
||||
contract('FluenceToken', function (accounts) {
|
||||
it("should be renameable", async function () {
|
||||
const token = await FluenceToken.deployed();
|
||||
|
||||
const s0 = await token.symbol()
|
||||
const n0 = await token.name()
|
||||
|
||||
assert.equal(s0, "FPT(U)")
|
||||
assert.equal(n0, "Fluence Presale Token (Unlocked)")
|
||||
|
||||
await token.rename("newSymbol", "newName")
|
||||
|
||||
const s1 = await token.symbol()
|
||||
const n1 = await token.name()
|
||||
|
||||
assert.equal(s1, "newSymbol")
|
||||
assert.equal(n1, "newName")
|
||||
|
||||
try {
|
||||
await token.rename("newsNam22e", "newnSymb22ol", {from: accounts[1]})
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
const s2 = await token.symbol()
|
||||
const n2 = await token.name()
|
||||
|
||||
assert.equal(s2, "newSymbol")
|
||||
assert.equal(n2, "newName")
|
||||
})
|
||||
});
|
@ -7,6 +7,11 @@ module.exports = {
|
||||
host: "localhost",
|
||||
port: 8545,
|
||||
network_id: "*" // Match any network id
|
||||
},
|
||||
kovan: {
|
||||
host: 'localhost',
|
||||
port: 8547,
|
||||
network_id: '42'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user