Transaction Hash:
Block:
11520569 at Dec-25-2020 04:23:09 AM +UTC
Transaction Fee:
0.0108839088 ETH
$26.06
Gas Used:
104,252 Gas / 104.4 Gwei
Emitted Events:
218 |
Nest_3_TokenAbonus.GetTokenLog( tokenAddress=0x04abEdA2...c74ddC74C, tokenAmount=1523850499173213164 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x19E1d193...8726e67c5 | |||||
0x2A461673...d5393Cf11 |
0.239070945095348645 Eth
Nonce: 266
|
1.752037535468561809 Eth
Nonce: 267
| 1.512966590373213164 | ||
0x43121397...e39D44852 | (NEST Protocol: Revenue Pool) | 459.058971234815197047 Eth | 457.535120735641983883 Eth | 1.523850499173213164 | |
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 819.19222140056427547 Eth | 819.20310530936427547 Eth | 0.0108839088 |
Execution Trace
Nest_3_TokenAbonus.getAbonus( token=0x04abEdA201850aC0124161F037Efd70c74ddC74C )
-
Nest_3_TokenSave.checkAmount( sender=0x2A461673861ED4fD299FbE5a8567785d5393Cf11, token=0x04abEdA201850aC0124161F037Efd70c74ddC74C ) => ( 6721075000000000000000000 )
Nest_3_Abonus.getETH( num=1523850499173213164, token=0x04abEdA201850aC0124161F037Efd70c74ddC74C, target=0x2A461673861ED4fD299FbE5a8567785d5393Cf11 )
-
Nest_3_VoteFactory.checkAddress( name=nest.v3.tokenAbonus ) => ( contractAddress=0x19E1d193A448bD13097EFC2aea867468726e67c5 )
- ETH 1.523850499173213164
0x2a461673861ed4fd299fbe5a8567785d5393cf11.CALL( )
-
getAbonus[Nest_3_TokenAbonus (ln:116)]
checkAmount[Nest_3_TokenAbonus (ln:117)]
reloadTime[Nest_3_TokenAbonus (ln:119)]
reloadToken[Nest_3_TokenAbonus (ln:120)]
sub[Nest_3_TokenAbonus (ln:155)]
levelingResult[Nest_3_TokenAbonus (ln:156)]
div[Nest_3_TokenAbonus (ln:171)]
allValue[Nest_3_TokenAbonus (ln:171)]
sub[Nest_3_TokenAbonus (ln:249)]
sub[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
checkAddress[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
totalSupply[Nest_3_TokenAbonus (ln:252)]
div[Nest_3_TokenAbonus (ln:173)]
allValue[Nest_3_TokenAbonus (ln:173)]
sub[Nest_3_TokenAbonus (ln:249)]
sub[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
checkAddress[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
totalSupply[Nest_3_TokenAbonus (ln:252)]
add[Nest_3_TokenAbonus (ln:177)]
div[Nest_3_TokenAbonus (ln:177)]
mul[Nest_3_TokenAbonus (ln:177)]
getETHNum[Nest_3_TokenAbonus (ln:179)]
sub[Nest_3_TokenAbonus (ln:183)]
div[Nest_3_TokenAbonus (ln:183)]
mul[Nest_3_TokenAbonus (ln:183)]
sub[Nest_3_TokenAbonus (ln:185)]
div[Nest_3_TokenAbonus (ln:185)]
mul[Nest_3_TokenAbonus (ln:185)]
div[Nest_3_TokenAbonus (ln:187)]
mul[Nest_3_TokenAbonus (ln:187)]
sub[Nest_3_TokenAbonus (ln:189)]
getETH[Nest_3_TokenAbonus (ln:190)]
sub[Nest_3_TokenAbonus (ln:190)]
value[Nest_3_TokenAbonus (ln:191)]
sub[Nest_3_TokenAbonus (ln:191)]
getETH[Nest_3_TokenAbonus (ln:193)]
value[Nest_3_TokenAbonus (ln:194)]
tranEth[Nest_3_TokenAbonus (ln:197)]
sub[Nest_3_TokenAbonus (ln:197)]
value[Nest_3_TokenAbonus (ln:198)]
getETHNum[Nest_3_TokenAbonus (ln:157)]
allValue[Nest_3_TokenAbonus (ln:158)]
sub[Nest_3_TokenAbonus (ln:249)]
sub[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
checkAddress[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
totalSupply[Nest_3_TokenAbonus (ln:252)]
sub[Nest_3_TokenAbonus (ln:159)]
allValue[Nest_3_TokenAbonus (ln:159)]
sub[Nest_3_TokenAbonus (ln:249)]
sub[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
checkAddress[Nest_3_TokenAbonus (ln:249)]
balanceOf[Nest_3_TokenAbonus (ln:249)]
totalSupply[Nest_3_TokenAbonus (ln:252)]
sub[Nest_3_TokenAbonus (ln:160)]
sub[Nest_3_TokenAbonus (ln:122)]
add[Nest_3_TokenAbonus (ln:122)]
sub[Nest_3_TokenAbonus (ln:122)]
sub[Nest_3_TokenAbonus (ln:123)]
sub[Nest_3_TokenAbonus (ln:124)]
div[Nest_3_TokenAbonus (ln:126)]
mul[Nest_3_TokenAbonus (ln:126)]
sub[Nest_3_TokenAbonus (ln:128)]
getETH[Nest_3_TokenAbonus (ln:129)]
GetTokenLog[Nest_3_TokenAbonus (ln:130)]
File 1 of 4: Nest_3_TokenAbonus
File 2 of 4: Nest_3_TokenSave
File 3 of 4: Nest_3_Abonus
File 4 of 4: Nest_3_VoteFactory
pragma solidity 0.6.0; /** * @title Dividend logic * @dev Some operations about dividend,logic and asset separation */ contract Nest_3_TokenAbonus { using address_make_payable for address; using SafeMath for uint256; ERC20 _nestContract; Nest_3_TokenSave _tokenSave; // Lock-up contract Nest_3_Abonus _abonusContract; // ETH bonus pool Nest_3_VoteFactory _voteFactory; // Voting contract Nest_3_Leveling _nestLeveling; // Leveling contract address _destructionAddress; // Destroy contract address uint256 _timeLimit = 168 hours; // Bonus period uint256 _nextTime = 1596168000; // Next bonus time uint256 _getAbonusTimeLimit = 60 hours; // During of triggering calculation of bonus uint256 _times = 0; // Bonus ledger uint256 _expectedIncrement = 3; // Expected bonus increment ratio uint256 _expectedSpanForNest = 100000000 ether; // NEST expected bonus increment threshold uint256 _expectedSpanForNToken = 1000000 ether; // NToken expected bonus increment threshold uint256 _expectedMinimum = 100 ether; // Expected minimum bonus uint256 _savingLevelOne = 10; // Saving threshold level 1 uint256 _savingLevelTwo = 20; // Saving threshold level 2 uint256 _savingLevelTwoSub = 100 ether; // Function parameters of savings threshold level 2 uint256 _savingLevelThree = 30; // Function parameters of savings threshold level 3 uint256 _savingLevelThreeSub = 600 ether; // Function parameters of savings threshold level 3 mapping(address => uint256) _abonusMapping; // Bonus pool snapshot - token address (NEST or NToken) => number of ETH in the bonus pool mapping(address => uint256) _tokenAllValueMapping; // Number of tokens (circulation) - token address (NEST or NToken) ) => total circulation mapping(address => mapping(uint256 => uint256)) _tokenAllValueHistory; // NEST or NToken circulation snapshot - token address (NEST or NToken) => number of periods => total circulation mapping(address => mapping(uint256 => mapping(address => uint256))) _tokenSelfHistory; // Personal lockup - NEST or NToken snapshot token address (NEST or NToken) => period => user address => total circulation mapping(address => mapping(uint256 => bool)) _snapshot; // Whether snapshot - token address (NEST or NToken) => number of periods => whether to take a snapshot mapping(uint256 => mapping(address => mapping(address => bool))) _getMapping; // Receiving records - period => token address (NEST or NToken) => user address => whether received // Log token address, amount event GetTokenLog(address tokenAddress, uint256 tokenAmount); /** * @dev Initialization method * @param voteFactory Voting contract address */ constructor (address voteFactory) public { Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); _voteFactory = voteFactoryMap; _nestContract = ERC20(address(voteFactoryMap.checkAddress("nest"))); _tokenSave = Nest_3_TokenSave(address(voteFactoryMap.checkAddress("nest.v3.tokenSave"))); address payable addr = address(voteFactoryMap.checkAddress("nest.v3.abonus")).make_payable(); _abonusContract = Nest_3_Abonus(addr); address payable levelingAddr = address(voteFactoryMap.checkAddress("nest.v3.leveling")).make_payable(); _nestLeveling = Nest_3_Leveling(levelingAddr); _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); } /** * @dev Modify voting contract * @param voteFactory Voting contract address */ function changeMapping(address voteFactory) public onlyOwner { Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); _voteFactory = voteFactoryMap; _nestContract = ERC20(address(voteFactoryMap.checkAddress("nest"))); _tokenSave = Nest_3_TokenSave(address(voteFactoryMap.checkAddress("nest.v3.tokenSave"))); address payable addr = address(voteFactoryMap.checkAddress("nest.v3.abonus")).make_payable(); _abonusContract = Nest_3_Abonus(addr); address payable levelingAddr = address(voteFactoryMap.checkAddress("nest.v3.leveling")).make_payable(); _nestLeveling = Nest_3_Leveling(levelingAddr); _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); } /** * @dev Deposit * @param amount Deposited amount * @param token Locked token address */ function depositIn(uint256 amount, address token) public { uint256 nowTime = now; uint256 nextTime = _nextTime; uint256 timeLimit = _timeLimit; if (nowTime < nextTime) { // Bonus triggered require(!(nowTime >= nextTime.sub(timeLimit) && nowTime <= nextTime.sub(timeLimit).add(_getAbonusTimeLimit))); } else { // Bonus not triggered uint256 times = (nowTime.sub(_nextTime)).div(_timeLimit); // Calculate the time when bonus should be started uint256 startTime = _nextTime.add((times).mul(_timeLimit)); // Calculate the time when bonus should be stopped uint256 endTime = startTime.add(_getAbonusTimeLimit); require(!(nowTime >= startTime && nowTime <= endTime)); } _tokenSave.depositIn(amount, token, address(msg.sender)); } /** * @dev Withdrawing * @param amount Withdrawing amount * @param token Token address */ function takeOut(uint256 amount, address token) public { require(amount > 0, "Parameter needs to be greater than 0"); require(amount <= _tokenSave.checkAmount(address(msg.sender), token), "Insufficient storage balance"); if (token == address(_nestContract)) { require(!_voteFactory.checkVoteNow(address(tx.origin)), "Voting"); } _tokenSave.takeOut(amount, token, address(msg.sender)); } /** * @dev Receiving * @param token Receiving token address */ function getAbonus(address token) public { uint256 tokenAmount = _tokenSave.checkAmount(address(msg.sender), token); require(tokenAmount > 0, "Insufficient storage balance"); reloadTime(); reloadToken(token); uint256 nowTime = now; require(nowTime >= _nextTime.sub(_timeLimit) && nowTime <= _nextTime.sub(_timeLimit).add(_getAbonusTimeLimit), "Not time to draw"); require(!_getMapping[_times.sub(1)][token][address(msg.sender)], "Have received"); _tokenSelfHistory[token][_times.sub(1)][address(msg.sender)] = tokenAmount; require(_tokenAllValueMapping[token] > 0, "Total flux error"); uint256 selfNum = tokenAmount.mul(_abonusMapping[token]).div(_tokenAllValueMapping[token]); require(selfNum > 0, "No limit available"); _getMapping[_times.sub(1)][token][address(msg.sender)] = true; _abonusContract.getETH(selfNum, token,address(msg.sender)); emit GetTokenLog(token, selfNum); } /** * @dev Update bonus time and stage ledger */ function reloadTime() private { uint256 nowTime = now; // The current time must exceed the bonus time if (nowTime >= _nextTime) { uint256 time = (nowTime.sub(_nextTime)).div(_timeLimit); uint256 startTime = _nextTime.add((time).mul(_timeLimit)); uint256 endTime = startTime.add(_getAbonusTimeLimit); if (nowTime >= startTime && nowTime <= endTime) { _nextTime = getNextTime(); _times = _times.add(1); } } } /** * @dev Snapshot of the amount of tokens * @param token Receiving token address */ function reloadToken(address token) private { if (!_snapshot[token][_times.sub(1)]) { levelingResult(token); _abonusMapping[token] = _abonusContract.getETHNum(token); _tokenAllValueMapping[token] = allValue(token); _tokenAllValueHistory[token][_times.sub(1)] = allValue(token); _snapshot[token][_times.sub(1)] = true; } } /** * @dev Leveling settlement * @param token Receiving token address */ function levelingResult(address token) private { uint256 steps; if (token == address(_nestContract)) { steps = allValue(token).div(_expectedSpanForNest); } else { steps = allValue(token).div(_expectedSpanForNToken); } uint256 minimumAbonus = _expectedMinimum; for (uint256 i = 0; i < steps; i++) { minimumAbonus = minimumAbonus.add(minimumAbonus.mul(_expectedIncrement).div(100)); } uint256 thisAbonus = _abonusContract.getETHNum(token); if (thisAbonus > minimumAbonus) { uint256 levelAmount = 0; if (thisAbonus > 5000 ether) { levelAmount = thisAbonus.mul(_savingLevelThree).div(100).sub(_savingLevelThreeSub); } else if (thisAbonus > 1000 ether) { levelAmount = thisAbonus.mul(_savingLevelTwo).div(100).sub(_savingLevelTwoSub); } else { levelAmount = thisAbonus.mul(_savingLevelOne).div(100); } if (thisAbonus.sub(levelAmount) < minimumAbonus) { _abonusContract.getETH(thisAbonus.sub(minimumAbonus), token, address(this)); _nestLeveling.switchToEth.value(thisAbonus.sub(minimumAbonus))(token); } else { _abonusContract.getETH(levelAmount, token, address(this)); _nestLeveling.switchToEth.value(levelAmount)(token); } } else { uint256 ethValue = _nestLeveling.tranEth(minimumAbonus.sub(thisAbonus), token, address(this)); _abonusContract.switchToEth.value(ethValue)(token); } } // Next bonus time, current bonus deadline, ETH number, NEST number, NEST participating in bonus, bonus to receive, approved amount, balance, whether bonus can be paid function getInfo(address token) public view returns (uint256 nextTime, uint256 getAbonusTime, uint256 ethNum, uint256 tokenValue, uint256 myJoinToken, uint256 getEth, uint256 allowNum, uint256 leftNum, bool allowAbonus) { uint256 nowTime = now; if (nowTime >= _nextTime.sub(_timeLimit) && nowTime <= _nextTime.sub(_timeLimit).add(_getAbonusTimeLimit) && _times > 0 && _snapshot[token][_times.sub(1)]) { // Bonus have been triggered, and during the time of this bonus, display snapshot data allowAbonus = _getMapping[_times.sub(1)][token][address(msg.sender)]; ethNum = _abonusMapping[token]; tokenValue = _tokenAllValueMapping[token]; } else { // Display real-time data ethNum = _abonusContract.getETHNum(token); tokenValue = allValue(token); allowAbonus = _getMapping[_times][token][address(msg.sender)]; } myJoinToken = _tokenSave.checkAmount(address(msg.sender), token); if (allowAbonus == true) { getEth = 0; } else { getEth = myJoinToken.mul(ethNum).div(tokenValue); } nextTime = getNextTime(); getAbonusTime = nextTime.sub(_timeLimit).add(_getAbonusTimeLimit); allowNum = ERC20(token).allowance(address(msg.sender), address(_tokenSave)); leftNum = ERC20(token).balanceOf(address(msg.sender)); } /** * @dev View next bonus time * @return Next bonus time */ function getNextTime() public view returns (uint256) { uint256 nowTime = now; if (_nextTime > nowTime) { return _nextTime; } else { uint256 time = (nowTime.sub(_nextTime)).div(_timeLimit); return _nextTime.add(_timeLimit.mul(time.add(1))); } } /** * @dev View total circulation * @return Total circulation */ function allValue(address token) public view returns (uint256) { if (token == address(_nestContract)) { uint256 all = 10000000000 ether; uint256 leftNum = all.sub(_nestContract.balanceOf(address(_voteFactory.checkAddress("nest.v3.miningSave")))).sub(_nestContract.balanceOf(address(_destructionAddress))); return leftNum; } else { return ERC20(token).totalSupply(); } } /** * @dev View bonus period * @return Bonus period */ function checkTimeLimit() public view returns (uint256) { return _timeLimit; } /** * @dev View duration of triggering calculation of bonus * @return Bonus period */ function checkGetAbonusTimeLimit() public view returns (uint256) { return _getAbonusTimeLimit; } /** * @dev View current lowest expected bonus * @return Current lowest expected bonus */ function checkMinimumAbonus(address token) public view returns (uint256) { uint256 miningAmount; if (token == address(_nestContract)) { miningAmount = allValue(token).div(_expectedSpanForNest); } else { miningAmount = allValue(token).div(_expectedSpanForNToken); } uint256 minimumAbonus = _expectedMinimum; for (uint256 i = 0; i < miningAmount; i++) { minimumAbonus = minimumAbonus.add(minimumAbonus.mul(_expectedIncrement).div(100)); } return minimumAbonus; } /** * @dev Check whether the bonus token is snapshoted * @param token Token address * @return Whether snapshoted */ function checkSnapshot(address token) public view returns (bool) { return _snapshot[token][_times.sub(1)]; } /** * @dev Check the expected bonus incremental ratio * @return Expected bonus increment ratio */ function checkeExpectedIncrement() public view returns (uint256) { return _expectedIncrement; } /** * @dev View expected minimum bonus * @return Expected minimum bonus */ function checkExpectedMinimum() public view returns (uint256) { return _expectedMinimum; } /** * @dev View savings threshold * @return Save threshold */ function checkSavingLevelOne() public view returns (uint256) { return _savingLevelOne; } function checkSavingLevelTwo() public view returns (uint256) { return _savingLevelTwo; } function checkSavingLevelThree() public view returns (uint256) { return _savingLevelThree; } /** * @dev View NEST liquidity snapshot * @param token Locked token address * @param times Bonus snapshot period */ function checkTokenAllValueHistory(address token, uint256 times) public view returns (uint256) { return _tokenAllValueHistory[token][times]; } /** * @dev View personal lock-up NEST snapshot * @param times Bonus snapshot period * @param user User address * @return The number of personal locked NEST snapshots */ function checkTokenSelfHistory(address token, uint256 times, address user) public view returns (uint256) { return _tokenSelfHistory[token][times][user]; } // View the period number of bonus function checkTimes() public view returns (uint256) { return _times; } // NEST expected bonus increment threshold function checkExpectedSpanForNest() public view returns (uint256) { return _expectedSpanForNest; } // NToken expected bonus increment threshold function checkExpectedSpanForNToken() public view returns (uint256) { return _expectedSpanForNToken; } // View the function parameters of savings threshold level 3 function checkSavingLevelTwoSub() public view returns (uint256) { return _savingLevelTwoSub; } // View the function parameters of savings threshold level 3 function checkSavingLevelThreeSub() public view returns (uint256) { return _savingLevelThreeSub; } /** * @dev Update bonus period * @param hour Bonus period (hours) */ function changeTimeLimit(uint256 hour) public onlyOwner { require(hour > 0, "Parameter needs to be greater than 0"); _timeLimit = hour.mul(1 hours); } /** * @dev Update collection period * @param hour Collection period (hours) */ function changeGetAbonusTimeLimit(uint256 hour) public onlyOwner { require(hour > 0, "Parameter needs to be greater than 0"); _getAbonusTimeLimit = hour; } /** * @dev Update expected bonus increment ratio * @param num Expected bonus increment ratio */ function changeExpectedIncrement(uint256 num) public onlyOwner { require(num > 0, "Parameter needs to be greater than 0"); _expectedIncrement = num; } /** * @dev Update expected minimum bonus * @param num Expected minimum bonus */ function changeExpectedMinimum(uint256 num) public onlyOwner { require(num > 0, "Parameter needs to be greater than 0"); _expectedMinimum = num; } /** * @dev Update saving threshold * @param threshold Saving threshold */ function changeSavingLevelOne(uint256 threshold) public onlyOwner { _savingLevelOne = threshold; } function changeSavingLevelTwo(uint256 threshold) public onlyOwner { _savingLevelTwo = threshold; } function changeSavingLevelThree(uint256 threshold) public onlyOwner { _savingLevelThree = threshold; } /** * @dev Update the function parameters of savings threshold level 2 */ function changeSavingLevelTwoSub(uint256 num) public onlyOwner { _savingLevelTwoSub = num; } /** * @dev Update the function parameters of savings threshold level 3 */ function changeSavingLevelThreeSub(uint256 num) public onlyOwner { _savingLevelThreeSub = num; } /** * @dev Update NEST expected bonus incremental threshold * @param num Threshold */ function changeExpectedSpanForNest(uint256 num) public onlyOwner { _expectedSpanForNest = num; } /** * @dev Update NToken expected bonus incremental threshold * @param num Threshold */ function changeExpectedSpanForNToken(uint256 num) public onlyOwner { _expectedSpanForNToken = num; } receive() external payable { } // Administrator only modifier onlyOwner(){ require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); _; } } // NEST and NToken lock-up contracts interface Nest_3_TokenSave { function depositIn(uint256 num, address token, address target) external; function checkAmount(address sender, address token) external view returns(uint256); function takeOut(uint256 num, address token, address target) external; } // ETH bonus pool interface Nest_3_Abonus { function getETH(uint256 num, address token, address target) external; function getETHNum(address token) external view returns (uint256); function switchToEth(address token) external payable; } // Leveling contract interface Nest_3_Leveling { function tranEth(uint256 amount, address token, address target) external returns (uint256); function switchToEth(address token) external payable; } // Voting factory contract interface Nest_3_VoteFactory { // Check if there is a vote currently participating function checkVoteNow(address user) external view returns(bool); // Check address function checkAddress(string calldata name) external view returns (address contractAddress); // Check whether the administrator function checkOwners(address man) external view returns (bool); } // ERC20 contract interface ERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library address_make_payable { function make_payable(address x) internal pure returns (address payable) { return address(uint160(x)); } }
File 2 of 4: Nest_3_TokenSave
pragma solidity 0.6.0; /** * @title NEST and NToken lock-up contract * @dev NEST and NToken deposit and withdrawal */ contract Nest_3_TokenSave { using SafeMath for uint256; Nest_3_VoteFactory _voteFactory; // Voting contract mapping(address => mapping(address => uint256)) _baseMapping; // Ledger token=>user=>amount /** * @dev initialization method * @param voteFactory Voting contract address */ constructor(address voteFactory) public { _voteFactory = Nest_3_VoteFactory(voteFactory); } /** * @dev Reset voting contract * @param voteFactory Voting contract address */ function changeMapping(address voteFactory) public onlyOwner { _voteFactory = Nest_3_VoteFactory(voteFactory); } /** * @dev Withdrawing * @param num Withdrawing amount * @param token Lock-up token address * @param target Transfer target */ function takeOut(uint256 num, address token, address target) public onlyContract { require(num <= _baseMapping[token][address(target)], "Insufficient storage balance"); _baseMapping[token][address(target)] = _baseMapping[token][address(target)].sub(num); ERC20(token).transfer(address(target), num); } /** * @dev Depositing * @param num Depositing amount * @param token Lock-up token address * @param target Depositing target */ function depositIn(uint256 num, address token, address target) public onlyContract { require(ERC20(token).transferFrom(address(target),address(this),num), "Authorization transfer failed"); _baseMapping[token][address(target)] = _baseMapping[token][address(target)].add(num); } /** * @dev Check the amount * @param sender Check address * @param token Lock-up token address * @return uint256 Check address corresponding lock-up limit */ function checkAmount(address sender, address token) public view returns(uint256) { return _baseMapping[token][address(sender)]; } // Administrators only modifier onlyOwner(){ require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); _; } // Only for bonus logic contract modifier onlyContract(){ require(_voteFactory.checkAddress("nest.v3.tokenAbonus") == address(msg.sender), "No authority"); _; } } // ERC20 contract interface ERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } // Voting factory interface Nest_3_VoteFactory { // Check address function checkAddress(string calldata name) external view returns (address contractAddress); // Check whether the administrator function checkOwners(address man) external view returns (bool); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
File 3 of 4: Nest_3_Abonus
pragma solidity 0.6.0; /** * @title ETH bonus pool * @dev ETH collection and inquiry */ contract Nest_3_Abonus { using address_make_payable for address; using SafeMath for uint256; Nest_3_VoteFactory _voteFactory; // Voting contract address _nestAddress; // NEST contract address mapping (address => uint256) ethMapping; // ETH bonus ledger of corresponding tokens uint256 _mostDistribution = 40; // The highest allocation ratio of NEST bonus pool uint256 _leastDistribution = 20; // The lowest allocation ratio of NEST bonus pool uint256 _distributionTime = 1200000; // The decay time interval of NEST bonus pool allocation ratio uint256 _distributionSpan = 5; // The decay degree of NEST bonus pool allocation ratio /** * @dev Initialization method * @param voteFactory Voting contract address */ constructor(address voteFactory) public { _voteFactory = Nest_3_VoteFactory(voteFactory); _nestAddress = address(_voteFactory.checkAddress("nest")); } /** * @dev Reset voting contract * @param voteFactory Voting contract address */ function changeMapping(address voteFactory) public onlyOwner{ _voteFactory = Nest_3_VoteFactory(voteFactory); _nestAddress = address(_voteFactory.checkAddress("nest")); } /** * @dev Transfer in bonus * @param token Corresponding to lock-up Token */ function switchToEth(address token) public payable { ethMapping[token] = ethMapping[token].add(msg.value); } /** * @dev Transferin bonus - NToken offering fee * @param token Corresponding to lock-up NToken */ function switchToEthForNTokenOffer(address token) public payable { Nest_NToken nToken = Nest_NToken(token); (uint256 createBlock,) = nToken.checkBlockInfo(); uint256 subBlock = block.number.sub(createBlock); uint256 times = subBlock.div(_distributionTime); uint256 distributionValue = times.mul(_distributionSpan); uint256 distribution = _mostDistribution; if (_leastDistribution.add(distributionValue) > _mostDistribution) { distribution = _leastDistribution; } else { distribution = _mostDistribution.sub(distributionValue); } uint256 nestEth = msg.value.mul(distribution).div(100); ethMapping[_nestAddress] = ethMapping[_nestAddress].add(nestEth); ethMapping[token] = ethMapping[token].add(msg.value.sub(nestEth)); } /** * @dev Receive ETH * @param num Receive amount * @param token Correspond to locked Token * @param target Transfer target */ function getETH(uint256 num, address token, address target) public onlyContract { require(num <= ethMapping[token], "Insufficient storage balance"); ethMapping[token] = ethMapping[token].sub(num); address payable addr = target.make_payable(); addr.transfer(num); } /** * @dev Get bonus pool balance * @param token Corresponded locked Token * @return uint256 Bonus pool balance */ function getETHNum(address token) public view returns (uint256) { return ethMapping[token]; } // View NEST address function checkNestAddress() public view returns(address) { return _nestAddress; } // View the highest NEST bonus pool allocation ratio function checkMostDistribution() public view returns(uint256) { return _mostDistribution; } // View the lowest NEST bonus pool allocation ratio function checkLeastDistribution() public view returns(uint256) { return _leastDistribution; } // View the decay time interval of NEST bonus pool allocation ratio function checkDistributionTime() public view returns(uint256) { return _distributionTime; } // View the decay degree of NEST bonus pool allocation ratio function checkDistributionSpan() public view returns(uint256) { return _distributionSpan; } // Modify the highest NEST bonus pool allocation ratio function changeMostDistribution(uint256 num) public onlyOwner { _mostDistribution = num; } // Modify the lowest NEST bonus pool allocation ratio function changeLeastDistribution(uint256 num) public onlyOwner { _leastDistribution = num; } // Modify the decay time interval of NEST bonus pool allocation ratio function changeDistributionTime(uint256 num) public onlyOwner { _distributionTime = num; } // Modify the decay degree of NEST bonus pool allocation ratio function changeDistributionSpan(uint256 num) public onlyOwner { _distributionSpan = num; } // Withdraw ETH function turnOutAllEth(uint256 amount, address target) public onlyOwner { address payable addr = target.make_payable(); addr.transfer(amount); } // Only bonus logic contract modifier onlyContract(){ require(_voteFactory.checkAddress("nest.v3.tokenAbonus") == address(msg.sender), "No authority"); _; } // Administrator only modifier onlyOwner(){ require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); _; } } // Voting factory interface Nest_3_VoteFactory { // Check address function checkAddress(string calldata name) external view returns (address contractAddress); // Check whether the administrator function checkOwners(address man) external view returns (bool); } // NToken interface Nest_NToken { // Increase token function increaseTotal(uint256 value) external; // Query mining information function checkBlockInfo() external view returns(uint256 createBlock, uint256 recentlyUsedBlock); // Query creator function checkOwner() external view returns(address); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library address_make_payable { function make_payable(address x) internal pure returns (address payable) { return address(uint160(x)); } }
File 4 of 4: Nest_3_VoteFactory
pragma solidity 0.6.0; /** * @title Voting factory + mapping * @dev Vote creating method */ contract Nest_3_VoteFactory { using SafeMath for uint256; uint256 _limitTime = 7 days; // Vote duration uint256 _NNLimitTime = 1 days; // NestNode raising time uint256 _circulationProportion = 51; // Proportion of votes to pass uint256 _NNUsedCreate = 10; // The minimum number of NNs to create a voting contract uint256 _NNCreateLimit = 100; // The minimum number of NNs needed to start voting uint256 _emergencyTime = 0; // The emergency state start time uint256 _emergencyTimeLimit = 3 days; // The emergency state duration uint256 _emergencyNNAmount = 1000; // The number of NNs required to switch the emergency state ERC20 _NNToken; // NestNode Token ERC20 _nestToken; // NestToken mapping(string => address) _contractAddress; // Voting contract mapping mapping(address => bool) _modifyAuthority; // Modify permissions mapping(address => address) _myVote; // Personal voting address mapping(address => uint256) _emergencyPerson; // Emergency state personal voting number mapping(address => bool) _contractData; // Voting contract data bool _stateOfEmergency = false; // Emergency state address _destructionAddress; // Destroy contract address event ContractAddress(address contractAddress); /** * @dev Initialization method */ constructor () public { _modifyAuthority[address(msg.sender)] = true; } /** * @dev Reset contract */ function changeMapping() public onlyOwner { _NNToken = ERC20(checkAddress("nestNode")); _destructionAddress = address(checkAddress("nest.v3.destruction")); _nestToken = ERC20(address(checkAddress("nest"))); } /** * @dev Create voting contract * @param implementContract The executable contract address for voting * @param nestNodeAmount Number of NNs to pledge */ function createVote(address implementContract, uint256 nestNodeAmount) public { require(address(tx.origin) == address(msg.sender), "It can't be a contract"); require(nestNodeAmount >= _NNUsedCreate); Nest_3_VoteContract newContract = new Nest_3_VoteContract(implementContract, _stateOfEmergency, nestNodeAmount); require(_NNToken.transferFrom(address(tx.origin), address(newContract), nestNodeAmount), "Authorization transfer failed"); _contractData[address(newContract)] = true; emit ContractAddress(address(newContract)); } /** * @dev Use NEST to vote * @param contractAddress Vote contract address */ function nestVote(address contractAddress) public { require(address(msg.sender) == address(tx.origin), "It can't be a contract"); require(_contractData[contractAddress], "It's not a voting contract"); require(!checkVoteNow(address(msg.sender))); Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); newContract.nestVote(); _myVote[address(tx.origin)] = contractAddress; } /** * @dev Vote using NestNode Token * @param contractAddress Vote contract address * @param NNAmount Amount of NNs to pledge */ function nestNodeVote(address contractAddress, uint256 NNAmount) public { require(address(msg.sender) == address(tx.origin), "It can't be a contract"); require(_contractData[contractAddress], "It's not a voting contract"); Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); require(_NNToken.transferFrom(address(tx.origin), address(newContract), NNAmount), "Authorization transfer failed"); newContract.nestNodeVote(NNAmount); } /** * @dev Excecute contract * @param contractAddress Vote contract address */ function startChange(address contractAddress) public { require(address(msg.sender) == address(tx.origin), "It can't be a contract"); require(_contractData[contractAddress], "It's not a voting contract"); Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); require(_stateOfEmergency == newContract.checkStateOfEmergency()); addSuperManPrivate(address(newContract)); newContract.startChange(); deleteSuperManPrivate(address(newContract)); } /** * @dev Switch emergency state-transfer in NestNode Token * @param amount Amount of NNs to transfer */ function sendNestNodeForStateOfEmergency(uint256 amount) public { require(_NNToken.transferFrom(address(tx.origin), address(this), amount)); _emergencyPerson[address(tx.origin)] = _emergencyPerson[address(tx.origin)].add(amount); } /** * @dev Switch emergency state-transfer out NestNode Token */ function turnOutNestNodeForStateOfEmergency() public { require(_emergencyPerson[address(tx.origin)] > 0); require(_NNToken.transfer(address(tx.origin), _emergencyPerson[address(tx.origin)])); _emergencyPerson[address(tx.origin)] = 0; uint256 nestAmount = _nestToken.balanceOf(address(this)); require(_nestToken.transfer(address(_destructionAddress), nestAmount)); } /** * @dev Modify emergency state */ function changeStateOfEmergency() public { if (_stateOfEmergency) { require(now > _emergencyTime.add(_emergencyTimeLimit)); _stateOfEmergency = false; _emergencyTime = 0; } else { require(_emergencyPerson[address(msg.sender)] > 0); require(_NNToken.balanceOf(address(this)) >= _emergencyNNAmount); _stateOfEmergency = true; _emergencyTime = now; } } /** * @dev Check whether participating in the voting * @param user Address to check * @return bool Whether voting */ function checkVoteNow(address user) public view returns (bool) { if (_myVote[user] == address(0x0)) { return false; } else { Nest_3_VoteContract vote = Nest_3_VoteContract(_myVote[user]); if (vote.checkContractEffective() || vote.checkPersonalAmount(user) == 0) { return false; } return true; } } /** * @dev Check my voting * @param user Address to check * @return address Address recently participated in the voting contract address */ function checkMyVote(address user) public view returns (address) { return _myVote[user]; } // Check the voting time function checkLimitTime() public view returns (uint256) { return _limitTime; } // Check the NestNode raising time function checkNNLimitTime() public view returns (uint256) { return _NNLimitTime; } // Check the voting proportion to pass function checkCirculationProportion() public view returns (uint256) { return _circulationProportion; } // Check the minimum number of NNs to create a voting contract function checkNNUsedCreate() public view returns (uint256) { return _NNUsedCreate; } // Check the minimum number of NNs raised to start a vote function checkNNCreateLimit() public view returns (uint256) { return _NNCreateLimit; } // Check whether in emergency state function checkStateOfEmergency() public view returns (bool) { return _stateOfEmergency; } // Check the start time of the emergency state function checkEmergencyTime() public view returns (uint256) { return _emergencyTime; } // Check the duration of the emergency state function checkEmergencyTimeLimit() public view returns (uint256) { return _emergencyTimeLimit; } // Check the amount of personal pledged NNs function checkEmergencyPerson(address user) public view returns (uint256) { return _emergencyPerson[user]; } // Check the number of NNs required for the emergency function checkEmergencyNNAmount() public view returns (uint256) { return _emergencyNNAmount; } // Verify voting contract data function checkContractData(address contractAddress) public view returns (bool) { return _contractData[contractAddress]; } // Modify voting time function changeLimitTime(uint256 num) public onlyOwner { require(num > 0, "Parameter needs to be greater than 0"); _limitTime = num; } // Modify the NestNode raising time function changeNNLimitTime(uint256 num) public onlyOwner { require(num > 0, "Parameter needs to be greater than 0"); _NNLimitTime = num; } // Modify the voting proportion function changeCirculationProportion(uint256 num) public onlyOwner { require(num > 0, "Parameter needs to be greater than 0"); _circulationProportion = num; } // Modify the minimum number of NNs to create a voting contract function changeNNUsedCreate(uint256 num) public onlyOwner { _NNUsedCreate = num; } // Modify the minimum number of NNs to raised to start a voting function checkNNCreateLimit(uint256 num) public onlyOwner { _NNCreateLimit = num; } // Modify the emergency state duration function changeEmergencyTimeLimit(uint256 num) public onlyOwner { require(num > 0); _emergencyTimeLimit = num.mul(1 days); } // Modify the number of NNs required for emergency state function changeEmergencyNNAmount(uint256 num) public onlyOwner { require(num > 0); _emergencyNNAmount = num; } // Check address function checkAddress(string memory name) public view returns (address contractAddress) { return _contractAddress[name]; } // Add contract mapping address function addContractAddress(string memory name, address contractAddress) public onlyOwner { _contractAddress[name] = contractAddress; } // Add administrator address function addSuperMan(address superMan) public onlyOwner { _modifyAuthority[superMan] = true; } function addSuperManPrivate(address superMan) private { _modifyAuthority[superMan] = true; } // Delete administrator address function deleteSuperMan(address superMan) public onlyOwner { _modifyAuthority[superMan] = false; } function deleteSuperManPrivate(address superMan) private { _modifyAuthority[superMan] = false; } // Delete voting contract data function deleteContractData(address contractAddress) public onlyOwner { _contractData[contractAddress] = false; } // Check whether the administrator function checkOwners(address man) public view returns (bool) { return _modifyAuthority[man]; } // Administrator only modifier onlyOwner() { require(checkOwners(msg.sender), "No authority"); _; } } /** * @title Voting contract */ contract Nest_3_VoteContract { using SafeMath for uint256; Nest_3_Implement _implementContract; // Executable contract Nest_3_TokenSave _tokenSave; // Lock-up contract Nest_3_VoteFactory _voteFactory; // Voting factory contract Nest_3_TokenAbonus _tokenAbonus; // Bonus logic contract ERC20 _nestToken; // NestToken ERC20 _NNToken; // NestNode Token address _miningSave; // Mining pool contract address _implementAddress; // Executable contract address address _destructionAddress; // Destruction contract address uint256 _createTime; // Creation time uint256 _endTime; // End time uint256 _totalAmount; // Total votes uint256 _circulation; // Passed votes uint256 _destroyedNest; // Destroyed NEST uint256 _NNLimitTime; // NestNode raising time uint256 _NNCreateLimit; // Minimum number of NNs to create votes uint256 _abonusTimes; // Period number of used snapshot in emergency state uint256 _allNNAmount; // Total number of NNs bool _effective = false; // Whether vote is effective bool _nestVote = false; // Whether NEST vote can be performed bool _isChange = false; // Whether NEST vote is executed bool _stateOfEmergency; // Whether the contract is in emergency state mapping(address => uint256) _personalAmount; // Number of personal votes mapping(address => uint256) _personalNNAmount; // Number of NN personal votes /** * @dev Initialization method * @param contractAddress Executable contract address * @param stateOfEmergency Whether in emergency state * @param NNAmount Amount of NNs */ constructor (address contractAddress, bool stateOfEmergency, uint256 NNAmount) public { Nest_3_VoteFactory voteFactory = Nest_3_VoteFactory(address(msg.sender)); _voteFactory = voteFactory; _nestToken = ERC20(voteFactory.checkAddress("nest")); _NNToken = ERC20(voteFactory.checkAddress("nestNode")); _implementContract = Nest_3_Implement(address(contractAddress)); _implementAddress = address(contractAddress); _destructionAddress = address(voteFactory.checkAddress("nest.v3.destruction")); _personalNNAmount[address(tx.origin)] = NNAmount; _allNNAmount = NNAmount; _createTime = now; _endTime = _createTime.add(voteFactory.checkLimitTime()); _NNLimitTime = voteFactory.checkNNLimitTime(); _NNCreateLimit = voteFactory.checkNNCreateLimit(); _stateOfEmergency = stateOfEmergency; if (stateOfEmergency) { // If in emergency state, read the last two periods of bonus lock-up and total circulation data _tokenAbonus = Nest_3_TokenAbonus(voteFactory.checkAddress("nest.v3.tokenAbonus")); _abonusTimes = _tokenAbonus.checkTimes().sub(2); require(_abonusTimes > 0); _circulation = _tokenAbonus.checkTokenAllValueHistory(address(_nestToken),_abonusTimes).mul(voteFactory.checkCirculationProportion()).div(100); } else { _miningSave = address(voteFactory.checkAddress("nest.v3.miningSave")); _tokenSave = Nest_3_TokenSave(voteFactory.checkAddress("nest.v3.tokenSave")); _circulation = (uint256(10000000000 ether).sub(_nestToken.balanceOf(address(_miningSave))).sub(_nestToken.balanceOf(address(_destructionAddress)))).mul(voteFactory.checkCirculationProportion()).div(100); } if (_allNNAmount >= _NNCreateLimit) { _nestVote = true; } } /** * @dev NEST voting */ function nestVote() public onlyFactory { require(now <= _endTime, "Voting time exceeded"); require(!_effective, "Vote in force"); require(_nestVote); require(_personalAmount[address(tx.origin)] == 0, "Have voted"); uint256 amount; if (_stateOfEmergency) { // If in emergency state, read the last two periods of bonus lock-up and total circulation data amount = _tokenAbonus.checkTokenSelfHistory(address(_nestToken),_abonusTimes, address(tx.origin)); } else { amount = _tokenSave.checkAmount(address(tx.origin), address(_nestToken)); } _personalAmount[address(tx.origin)] = amount; _totalAmount = _totalAmount.add(amount); ifEffective(); } /** * @dev NEST voting cancellation */ function nestVoteCancel() public { require(address(msg.sender) == address(tx.origin), "It can't be a contract"); require(now <= _endTime, "Voting time exceeded"); require(!_effective, "Vote in force"); require(_personalAmount[address(tx.origin)] > 0, "No vote"); _totalAmount = _totalAmount.sub(_personalAmount[address(tx.origin)]); _personalAmount[address(tx.origin)] = 0; } /** * @dev NestNode voting * @param NNAmount Amount of NNs */ function nestNodeVote(uint256 NNAmount) public onlyFactory { require(now <= _createTime.add(_NNLimitTime), "Voting time exceeded"); require(!_nestVote); _personalNNAmount[address(tx.origin)] = _personalNNAmount[address(tx.origin)].add(NNAmount); _allNNAmount = _allNNAmount.add(NNAmount); if (_allNNAmount >= _NNCreateLimit) { _nestVote = true; } } /** * @dev Withdrawing lock-up NNs */ function turnOutNestNode() public { if (_nestVote) { // Normal NEST voting if (!_stateOfEmergency || !_effective) { // Non-emergency state require(now > _endTime, "Vote unenforceable"); } } else { // NN voting require(now > _createTime.add(_NNLimitTime)); } require(_personalNNAmount[address(tx.origin)] > 0); // Reverting back the NNs require(_NNToken.transfer(address(tx.origin), _personalNNAmount[address(tx.origin)])); _personalNNAmount[address(tx.origin)] = 0; // Destroying NEST Tokens uint256 nestAmount = _nestToken.balanceOf(address(this)); _destroyedNest = _destroyedNest.add(nestAmount); require(_nestToken.transfer(address(_destructionAddress), nestAmount)); } /** * @dev Execute the contract */ function startChange() public onlyFactory { require(!_isChange); _isChange = true; if (_stateOfEmergency) { require(_effective, "Vote unenforceable"); } else { require(_effective && now > _endTime, "Vote unenforceable"); } // Add the executable contract to the administrator list _voteFactory.addSuperMan(address(_implementContract)); // Execute _implementContract.doit(); // Delete the authorization _voteFactory.deleteSuperMan(address(_implementContract)); } /** * @dev check whether the vote is effective */ function ifEffective() private { if (_totalAmount >= _circulation) { _effective = true; } } /** * @dev Check whether the vote is over */ function checkContractEffective() public view returns (bool) { if (_effective || now > _endTime) { return true; } return false; } // Check the executable implement contract address function checkImplementAddress() public view returns (address) { return _implementAddress; } // Check the voting start time function checkCreateTime() public view returns (uint256) { return _createTime; } // Check the voting end time function checkEndTime() public view returns (uint256) { return _endTime; } // Check the current total number of votes function checkTotalAmount() public view returns (uint256) { return _totalAmount; } // Check the number of votes to pass function checkCirculation() public view returns (uint256) { return _circulation; } // Check the number of personal votes function checkPersonalAmount(address user) public view returns (uint256) { return _personalAmount[user]; } // Check the destroyed NEST function checkDestroyedNest() public view returns (uint256) { return _destroyedNest; } // Check whether the contract is effective function checkEffective() public view returns (bool) { return _effective; } // Check whether in emergency state function checkStateOfEmergency() public view returns (bool) { return _stateOfEmergency; } // Check NestNode raising time function checkNNLimitTime() public view returns (uint256) { return _NNLimitTime; } // Check the minimum number of NNs to create a vote function checkNNCreateLimit() public view returns (uint256) { return _NNCreateLimit; } // Check the period number of snapshot used in the emergency state function checkAbonusTimes() public view returns (uint256) { return _abonusTimes; } // Check number of personal votes function checkPersonalNNAmount(address user) public view returns (uint256) { return _personalNNAmount[address(user)]; } // Check the total number of NNs function checkAllNNAmount() public view returns (uint256) { return _allNNAmount; } // Check whether NEST voting is available function checkNestVote() public view returns (bool) { return _nestVote; } // Check whether it has been excecuted function checkIsChange() public view returns (bool) { return _isChange; } // Vote Factory contract only modifier onlyFactory() { require(address(_voteFactory) == address(msg.sender), "No authority"); _; } } // Executable contract interface Nest_3_Implement { // Execute function doit() external; } // NEST lock-up contract interface Nest_3_TokenSave { // Check lock-up amount function checkAmount(address sender, address token) external view returns (uint256); } // Bonus logic contract interface Nest_3_TokenAbonus { // Check NEST circulation snapshot function checkTokenAllValueHistory(address token, uint256 times) external view returns (uint256); // Check NEST user balance snapshot function checkTokenSelfHistory(address token, uint256 times, address user) external view returns (uint256); // Check bonus ledger period function checkTimes() external view returns (uint256); } // Erc20 contract interface ERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }