diff --git a/blackhole/contracts/BlackHoleTimestamp.sol b/blackhole/contracts/BlackHoleTimestamp.sol new file mode 100644 index 0000000..9a06d6f --- /dev/null +++ b/blackhole/contracts/BlackHoleTimestamp.sol @@ -0,0 +1,67 @@ +pragma solidity ^0.4.22; + +import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; + +/** @title BlackHole + * + * @dev Implementation of the BlackHole contract. + * It deadlocks ERC20 tockens and emit events on success. + */ +contract BlackHole { + event Opened(); + event Teleport(uint amount, string note); + event Closed(); + + bool public closed = false; + ERC20 public erc20Contract; + uint public minimumAmount; + uint public startTime; + uint public eligibleCloseTime; + + /** @dev Construction of the ETH BlackHole contract. + * @param _erc20Contract The address of the ERC20 contract to attract tockens from. + * @param _minDurationDays BlackHole can be closed after set days. + * @param _minimumAmount the smallest amount BlackHole can attract. + */ + constructor(address _erc20Contract, uint _minDurationDays, uint _minimumAmount) public { + erc20Contract = ERC20(_erc20Contract); + minimumAmount = _minimumAmount; + startTime = block.timestamp; //start when contract is issued. + // Approximate. Does not account for leap seconds. + eligibleCloseTime = startTime + (_minDurationDays * 86400); + emit Opened(); + } + + /** @dev It closes the BlackHole if critical block has been reached. + */ + function close() public { + require(!closed, "This BlackHole contract's active period has expired."); + require(block.timestamp >= eligibleCloseTime, "BlackHole hasn't reached the critical mass"); + closed = true; + emit Closed(); + } + + /** @dev teleport attracts tokens and emit Teleport event + * @param note Teleport event note. + */ + function teleport(string note) public { + uint amount = attract(); + emit Teleport(amount, note); + } + + function attract() private returns (uint amount){ + require(!closed, "blackHole closed"); + uint balance = erc20Contract.balanceOf(msg.sender); + uint allowed = erc20Contract.allowance(msg.sender, address(this)); + require(allowed >= minimumAmount, "less than minimum amount"); + require(balance == allowed, "blackHole must attract all your tokens"); + require(erc20Contract.transferFrom(msg.sender, address(this), balance), "blackHole can't attract your tokens"); + return balance; + } + + // Approximate based on timestamp and 86400 epoch day + function daysLeft() constant returns (uint) { + return (eligibleCloseTime - block.timestamp) / 86400; + } + +} diff --git a/blackhole/migrations/2_contract_ts_migration.js b/blackhole/migrations/2_contract_ts_migration.js new file mode 100644 index 0000000..f747ae7 --- /dev/null +++ b/blackhole/migrations/2_contract_ts_migration.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const check = require('../../utils/Check'); + +var ERC20Token = artifacts.require("./ERC20Token.sol"); +var BlackHole = artifacts.require("./BlackHoleEosAccount.sol") + +module.exports = function (deployer) { + const configFile = "../config.json"; + //check(fs.existsSync(configFile), "configuration file: " + configFile); + const config = JSON.parse(fs.readFileSync(configFile)); + //console.log(config) + const name = "ERC20 Test"; + const symbol = config.blackhole.symbol; + const decimals = config.blackhole.decimals; + const tokens = config.blackhole.tokens; + //const genesisBlock = config.blackhole.critic_block; + const duration = config.blackhole.minDuration; + const minimumAmount = config.blackhole.minimum_amount; + + check(name, "ERC20 name: " + name); + check(symbol, "ERC20 symbol: " + symbol); + check(tokens, "ERC20 tokens: " + tokens); + check(decimals, "ERC20 decimals: " + decimals); + //check(genesisBlock, "BlackHole critical block: " + genesisBlock); + check(duration, "BlackHole duration: " + duration); + check(minimumAmount, "BlackHole minimum amount: " + minimumAmount); + + deployer.deploy(ERC20Token, name, symbol, tokens, decimals).then(() => { + return deployer.deploy(BlackHole, ERC20Token.address, duration, minimumAmount); + }) + .then(() => { + fs.writeFileSync('../erc20_address', ERC20Token.address); + fs.writeFileSync('../blackhole_address', BlackHole.address); + }) +}; + diff --git a/config_ts.json b/config_ts.json new file mode 100644 index 0000000..2174c70 --- /dev/null +++ b/config_ts.json @@ -0,0 +1,16 @@ +{ + "blackhole": { + "websocket_provider": "ws://127.0.0.1:7545", + "minDuration": "30", + "minimum_amount": "100", + "symbol": "", + "decimals": "4", + "tokens": "4" + }, + "eosiotoken": { + "chain_id": "038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca", + "http_endpoint": "http://dev.cryptolions.io:38888", + "account": "