├── .gitattributes ├── LICENSE ├── Lib ├── Address.sol ├── AddressPayable.sol ├── SafeERC20.sol └── SafeMath.sol ├── NTokenAuction ├── Nest_NToken_TokenAuction.sol └── Nest_NToken_TokenMapping.sol ├── NTokenOffer └── Nest_NToken_OfferMain.sol ├── NestAbonus ├── ABI │ ├── Nest_3_Abonus_ABI.txt │ ├── Nest_3_Leveling_ABI.txt │ ├── Nest_3_TokenAbonus_ABI.txt │ └── Nest_3_TokenSave_ABI.txt ├── Nest_3_Abonus.sol ├── Nest_3_Leveling.sol ├── Nest_3_TokenAbonus.sol ├── Nest_3_TokenSave.sol └── README.md ├── NestOffer ├── Nest_3_MiningContract.sol ├── Nest_3_OfferMain.sol ├── Nest_3_OfferPrice.sol └── README.md ├── NestToken └── IBNEST.sol ├── NodeAssignment ├── NEST_NodeAssignment.sol ├── NEST_NodeAssignmentData.sol ├── NEST_NodeSave.sol ├── SafeMath.sol └── SuperMan.sol ├── README.md ├── VoteContract └── Nest_3_VoteFactory.sol └── nToken └── nYFI.png /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /Lib/Address.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | library Address { 4 | function isContract(address account) internal view returns (bool) { 5 | bytes32 codehash; 6 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 7 | assembly { codehash := extcodehash(account) } 8 | return (codehash != accountHash && codehash != 0x0); 9 | } 10 | function sendValue(address payable recipient, uint256 amount) internal { 11 | require(address(this).balance >= amount, "Address: insufficient balance"); 12 | (bool success, ) = recipient.call.value(amount)(""); 13 | require(success, "Address: unable to send value, recipient may have reverted"); 14 | } 15 | } -------------------------------------------------------------------------------- /Lib/AddressPayable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | library address_make_payable { 4 | function make_payable(address x) internal pure returns (address payable) { 5 | return address(uint160(x)); 6 | } 7 | } -------------------------------------------------------------------------------- /Lib/SafeERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "./Address.sol"; 4 | import "./SafeMath.sol"; 5 | 6 | library SafeERC20 { 7 | using SafeMath for uint256; 8 | using Address for address; 9 | 10 | function safeTransfer(ERC20 token, address to, uint256 value) internal { 11 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 12 | } 13 | 14 | function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { 15 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 16 | } 17 | 18 | function safeApprove(ERC20 token, address spender, uint256 value) internal { 19 | require((value == 0) || (token.allowance(address(this), spender) == 0), 20 | "SafeERC20: approve from non-zero to non-zero allowance" 21 | ); 22 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 23 | } 24 | 25 | function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal { 26 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 27 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 28 | } 29 | 30 | function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal { 31 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 32 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 33 | } 34 | function callOptionalReturn(ERC20 token, bytes memory data) private { 35 | require(address(token).isContract(), "SafeERC20: call to non-contract"); 36 | (bool success, bytes memory returndata) = address(token).call(data); 37 | require(success, "SafeERC20: low-level call failed"); 38 | if (returndata.length > 0) { 39 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 40 | } 41 | } 42 | } 43 | 44 | interface ERC20 { 45 | function totalSupply() external view returns (uint256); 46 | function balanceOf(address account) external view returns (uint256); 47 | function transfer(address recipient, uint256 amount) external returns (bool); 48 | function allowance(address owner, address spender) external view returns (uint256); 49 | function approve(address spender, uint256 amount) external returns (bool); 50 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 51 | event Transfer(address indexed from, address indexed to, uint256 value); 52 | event Approval(address indexed owner, address indexed spender, uint256 value); 53 | } -------------------------------------------------------------------------------- /Lib/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | library SafeMath { 4 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 5 | uint256 c = a + b; 6 | require(c >= a, "SafeMath: addition overflow"); 7 | 8 | return c; 9 | } 10 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 11 | return sub(a, b, "SafeMath: subtraction overflow"); 12 | } 13 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 14 | require(b <= a, errorMessage); 15 | uint256 c = a - b; 16 | 17 | return c; 18 | } 19 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 20 | if (a == 0) { 21 | return 0; 22 | } 23 | uint256 c = a * b; 24 | require(c / a == b, "SafeMath: multiplication overflow"); 25 | 26 | return c; 27 | } 28 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 29 | return div(a, b, "SafeMath: division by zero"); 30 | } 31 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 32 | require(b > 0, errorMessage); 33 | uint256 c = a / b; 34 | return c; 35 | } 36 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 37 | return mod(a, b, "SafeMath: modulo by zero"); 38 | } 39 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 40 | require(b != 0, errorMessage); 41 | return a % b; 42 | } 43 | } -------------------------------------------------------------------------------- /NTokenAuction/Nest_NToken_TokenAuction.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | import "../Lib/SafeERC20.sol"; 6 | 7 | /** 8 | * @title Auction NToken contract 9 | * @dev Auction for listing and generating NToken 10 | */ 11 | contract Nest_NToken_TokenAuction { 12 | using SafeMath for uint256; 13 | using address_make_payable for address; 14 | using SafeERC20 for ERC20; 15 | 16 | Nest_3_VoteFactory _voteFactory; // Voting contract 17 | Nest_NToken_TokenMapping _tokenMapping; // NToken mapping contract 18 | ERC20 _nestToken; // NestToken 19 | Nest_3_OfferPrice _offerPrice; // Price contract 20 | address _destructionAddress; // Destruction contract address 21 | uint256 _duration = 5 days; // Auction duration 22 | uint256 _minimumNest = 100000 ether; // Minimum auction amount 23 | uint256 _tokenNum = 1; // Auction token number 24 | uint256 _incentiveRatio = 50; // Incentive ratio 25 | uint256 _minimumInterval = 10000 ether; // Minimum auction interval 26 | mapping(address => AuctionInfo) _auctionList; // Auction list 27 | mapping(address => bool) _tokenBlackList; // Auction blacklist 28 | struct AuctionInfo { 29 | uint256 endTime; // End time 30 | uint256 auctionValue; // Auction price 31 | address latestAddress; // Highest auctioneer 32 | uint256 latestAmount; // Lastest auction amount 33 | } 34 | address[] _allAuction; // Auction list array 35 | 36 | /** 37 | * @dev Initialization method 38 | * @param voteFactory Voting contract address 39 | */ 40 | constructor (address voteFactory) public { 41 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 42 | _voteFactory = voteFactoryMap; 43 | _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping"))); 44 | _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest"))); 45 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 46 | _offerPrice = Nest_3_OfferPrice(address(voteFactoryMap.checkAddress("nest.v3.offerPrice"))); 47 | } 48 | 49 | /** 50 | * @dev Reset voting contract 51 | * @param voteFactory Voting contract address 52 | */ 53 | function changeMapping(address voteFactory) public onlyOwner { 54 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 55 | _voteFactory = voteFactoryMap; 56 | _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping"))); 57 | _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest"))); 58 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 59 | _offerPrice = Nest_3_OfferPrice(address(voteFactoryMap.checkAddress("nest.v3.offerPrice"))); 60 | } 61 | 62 | /** 63 | * @dev Initiating auction 64 | * @param token Auction token address 65 | * @param auctionAmount Initial auction amount 66 | */ 67 | function startAnAuction(address token, uint256 auctionAmount) public { 68 | require(_tokenMapping.checkTokenMapping(token) == address(0x0), "Token already exists"); 69 | require(_auctionList[token].endTime == 0, "Token is on sale"); 70 | require(auctionAmount >= _minimumNest, "AuctionAmount less than the minimum auction amount"); 71 | require(_nestToken.transferFrom(address(msg.sender), address(this), auctionAmount), "Authorization failed"); 72 | require(!_tokenBlackList[token]); 73 | // Verification 74 | ERC20 tokenERC20 = ERC20(token); 75 | tokenERC20.safeTransferFrom(address(msg.sender), address(this), 1); 76 | require(tokenERC20.balanceOf(address(this)) >= 1); 77 | tokenERC20.safeTransfer(address(msg.sender), 1); 78 | AuctionInfo memory thisAuction = AuctionInfo(now.add(_duration), auctionAmount, address(msg.sender), auctionAmount); 79 | _auctionList[token] = thisAuction; 80 | _allAuction.push(token); 81 | } 82 | 83 | /** 84 | * @dev Auction 85 | * @param token Auction token address 86 | * @param auctionAmount Auction amount 87 | */ 88 | function continueAuction(address token, uint256 auctionAmount) public { 89 | require(now <= _auctionList[token].endTime && _auctionList[token].endTime != 0, "Auction closed"); 90 | require(auctionAmount > _auctionList[token].auctionValue, "Insufficient auction amount"); 91 | uint256 subAuctionAmount = auctionAmount.sub(_auctionList[token].auctionValue); 92 | require(subAuctionAmount >= _minimumInterval); 93 | uint256 excitation = subAuctionAmount.mul(_incentiveRatio).div(100); 94 | require(_nestToken.transferFrom(address(msg.sender), address(this), auctionAmount), "Authorization failed"); 95 | require(_nestToken.transfer(_auctionList[token].latestAddress, _auctionList[token].auctionValue.add(excitation)), "Transfer failure"); 96 | // Update auction information 97 | _auctionList[token].auctionValue = auctionAmount; 98 | _auctionList[token].latestAddress = address(msg.sender); 99 | _auctionList[token].latestAmount = _auctionList[token].latestAmount.add(subAuctionAmount.sub(excitation)); 100 | } 101 | 102 | /** 103 | * @dev Listing 104 | * @param token Auction token address 105 | */ 106 | function auctionSuccess(address token) public { 107 | Nest_3_TokenAbonus nestAbonus = Nest_3_TokenAbonus(_voteFactory.checkAddress("nest.v3.tokenAbonus")); 108 | uint256 nowTime = now; 109 | uint256 nextTime = nestAbonus.getNextTime(); 110 | uint256 timeLimit = nestAbonus.checkTimeLimit(); 111 | uint256 getAbonusTimeLimit = nestAbonus.checkGetAbonusTimeLimit(); 112 | require(!(nowTime >= nextTime.sub(timeLimit) && nowTime <= nextTime.sub(timeLimit).add(getAbonusTimeLimit)), "Not time to auctionSuccess"); 113 | require(nowTime > _auctionList[token].endTime && _auctionList[token].endTime != 0, "Token is on sale"); 114 | // Initialize NToken 115 | Nest_NToken nToken = new Nest_NToken(strConcat("NToken", getAddressStr(_tokenNum)), strConcat("N", getAddressStr(_tokenNum)), address(_voteFactory), address(_auctionList[token].latestAddress)); 116 | // Auction NEST destruction 117 | require(_nestToken.transfer(_destructionAddress, _auctionList[token].latestAmount), "Transfer failure"); 118 | // Add NToken mapping 119 | _tokenMapping.addTokenMapping(token, address(nToken)); 120 | // Initialize charging parameters 121 | _offerPrice.addPriceCost(token); 122 | _tokenNum = _tokenNum.add(1); 123 | } 124 | 125 | function strConcat(string memory _a, string memory _b) public pure returns (string memory){ 126 | bytes memory _ba = bytes(_a); 127 | bytes memory _bb = bytes(_b); 128 | string memory ret = new string(_ba.length + _bb.length); 129 | bytes memory bret = bytes(ret); 130 | uint k = 0; 131 | for (uint i = 0; i < _ba.length; i++) { 132 | bret[k++] = _ba[i]; 133 | } 134 | for (uint i = 0; i < _bb.length; i++) { 135 | bret[k++] = _bb[i]; 136 | } 137 | return string(ret); 138 | } 139 | 140 | // Convert to 4-digit string 141 | function getAddressStr(uint256 iv) public pure returns (string memory) { 142 | bytes memory buf = new bytes(64); 143 | uint256 index = 0; 144 | do { 145 | buf[index++] = byte(uint8(iv % 10 + 48)); 146 | iv /= 10; 147 | } while (iv > 0 || index < 4); 148 | bytes memory str = new bytes(index); 149 | for(uint256 i = 0; i < index; ++i) { 150 | str[i] = buf[index - i - 1]; 151 | } 152 | return string(str); 153 | } 154 | 155 | // Check auction duration 156 | function checkDuration() public view returns(uint256) { 157 | return _duration; 158 | } 159 | 160 | // Check minimum auction amount 161 | function checkMinimumNest() public view returns(uint256) { 162 | return _minimumNest; 163 | } 164 | 165 | // Check initiated number of auction tokens 166 | function checkAllAuctionLength() public view returns(uint256) { 167 | return _allAuction.length; 168 | } 169 | 170 | // View auctioned token addresses 171 | function checkAuctionTokenAddress(uint256 num) public view returns(address) { 172 | return _allAuction[num]; 173 | } 174 | 175 | // View auction blacklist 176 | function checkTokenBlackList(address token) public view returns(bool) { 177 | return _tokenBlackList[token]; 178 | } 179 | 180 | // View auction token information 181 | function checkAuctionInfo(address token) public view returns(uint256 endTime, uint256 auctionValue, address latestAddress) { 182 | AuctionInfo memory info = _auctionList[token]; 183 | return (info.endTime, info.auctionValue, info.latestAddress); 184 | } 185 | 186 | // View token number 187 | function checkTokenNum() public view returns (uint256) { 188 | return _tokenNum; 189 | } 190 | 191 | // Modify auction duration 192 | function changeDuration(uint256 num) public onlyOwner { 193 | _duration = num.mul(1 days); 194 | } 195 | 196 | // Modify minimum auction amount 197 | function changeMinimumNest(uint256 num) public onlyOwner { 198 | _minimumNest = num; 199 | } 200 | 201 | // Modify auction blacklist 202 | function changeTokenBlackList(address token, bool isBlack) public onlyOwner { 203 | _tokenBlackList[token] = isBlack; 204 | } 205 | 206 | // Administrator only 207 | modifier onlyOwner(){ 208 | require(_voteFactory.checkOwners(msg.sender), "No authority"); 209 | _; 210 | } 211 | 212 | } 213 | 214 | // Bonus logic contract 215 | interface Nest_3_TokenAbonus { 216 | // View next bonus time 217 | function getNextTime() external view returns (uint256); 218 | // View bonus period 219 | function checkTimeLimit() external view returns (uint256); 220 | // View duration of triggering calculation of bonus 221 | function checkGetAbonusTimeLimit() external view returns (uint256); 222 | } 223 | 224 | // voting contract 225 | interface Nest_3_VoteFactory { 226 | // Check address 227 | function checkAddress(string calldata name) external view returns (address contractAddress); 228 | // check whether the administrator 229 | function checkOwners(address man) external view returns (bool); 230 | } 231 | 232 | /** 233 | * @title NToken contract 234 | * @dev Include standard erc20 method, mining method, and mining data 235 | */ 236 | interface IERC20 { 237 | function totalSupply() external view returns (uint256); 238 | function balanceOf(address who) external view returns (uint256); 239 | function allowance(address owner, address spender) external view returns (uint256); 240 | function transfer(address to, uint256 value) external returns (bool); 241 | function approve(address spender, uint256 value) external returns (bool); 242 | function transferFrom(address from, address to, uint256 value) external returns (bool); 243 | event Transfer(address indexed from, address indexed to, uint256 value); 244 | event Approval(address indexed owner, address indexed spender, uint256 value); 245 | } 246 | 247 | contract Nest_NToken is IERC20 { 248 | using SafeMath for uint256; 249 | 250 | mapping (address => uint256) private _balances; // Balance ledger 251 | mapping (address => mapping (address => uint256)) private _allowed; // Approval ledger 252 | uint256 private _totalSupply = 0 ether; // Total supply 253 | string public name; // Token name 254 | string public symbol; // Token symbol 255 | uint8 public decimals = 18; // Precision 256 | uint256 public _createBlock; // Create block number 257 | uint256 public _recentlyUsedBlock; // Recently used block number 258 | Nest_3_VoteFactory _voteFactory; // Voting factory contract 259 | address _bidder; // Owner 260 | 261 | /** 262 | * @dev Initialization method 263 | * @param _name Token name 264 | * @param _symbol Token symbol 265 | * @param voteFactory Voting factory contract address 266 | * @param bidder Successful bidder address 267 | */ 268 | constructor (string memory _name, string memory _symbol, address voteFactory, address bidder) public { 269 | name = _name; 270 | symbol = _symbol; 271 | _createBlock = block.number; 272 | _recentlyUsedBlock = block.number; 273 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 274 | _bidder = bidder; 275 | } 276 | 277 | /** 278 | * @dev Reset voting contract method 279 | * @param voteFactory Voting contract address 280 | */ 281 | function changeMapping (address voteFactory) public onlyOwner { 282 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 283 | } 284 | 285 | /** 286 | * @dev Additional issuance 287 | * @param value Additional issuance amount 288 | */ 289 | function increaseTotal(uint256 value) public { 290 | address offerMain = address(_voteFactory.checkAddress("nest.nToken.offerMain")); 291 | require(address(msg.sender) == offerMain, "No authority"); 292 | _balances[offerMain] = _balances[offerMain].add(value); 293 | _totalSupply = _totalSupply.add(value); 294 | _recentlyUsedBlock = block.number; 295 | } 296 | 297 | /** 298 | * @dev Check the total amount of tokens 299 | * @return Total supply 300 | */ 301 | function totalSupply() override public view returns (uint256) { 302 | return _totalSupply; 303 | } 304 | 305 | /** 306 | * @dev Check address balance 307 | * @param owner Address to be checked 308 | * @return Return the balance of the corresponding address 309 | */ 310 | function balanceOf(address owner) override public view returns (uint256) { 311 | return _balances[owner]; 312 | } 313 | 314 | /** 315 | * @dev Check block information 316 | * @return createBlock Initial block number 317 | * @return recentlyUsedBlock Recently mined and issued block 318 | */ 319 | function checkBlockInfo() public view returns(uint256 createBlock, uint256 recentlyUsedBlock) { 320 | return (_createBlock, _recentlyUsedBlock); 321 | } 322 | 323 | /** 324 | * @dev Check owner's approved allowance to the spender 325 | * @param owner Approving address 326 | * @param spender Approved address 327 | * @return Approved amount 328 | */ 329 | function allowance(address owner, address spender) override public view returns (uint256) { 330 | return _allowed[owner][spender]; 331 | } 332 | 333 | /** 334 | * @dev Transfer method 335 | * @param to Transfer target 336 | * @param value Transfer amount 337 | * @return Whether the transfer is successful 338 | */ 339 | function transfer(address to, uint256 value) override public returns (bool) { 340 | _transfer(msg.sender, to, value); 341 | return true; 342 | } 343 | 344 | /** 345 | * @dev Approval method 346 | * @param spender Approval target 347 | * @param value Approval amount 348 | * @return Whether the approval is successful 349 | */ 350 | function approve(address spender, uint256 value) override public returns (bool) { 351 | require(spender != address(0)); 352 | 353 | _allowed[msg.sender][spender] = value; 354 | emit Approval(msg.sender, spender, value); 355 | return true; 356 | } 357 | 358 | /** 359 | * @dev Transfer tokens when approved 360 | * @param from Transfer-out account address 361 | * @param to Transfer-in account address 362 | * @param value Transfer amount 363 | * @return Whether approved transfer is successful 364 | */ 365 | function transferFrom(address from, address to, uint256 value) override public returns (bool) { 366 | _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); 367 | _transfer(from, to, value); 368 | emit Approval(from, msg.sender, _allowed[from][msg.sender]); 369 | return true; 370 | } 371 | 372 | /** 373 | * @dev Increase the allowance 374 | * @param spender Approval target 375 | * @param addedValue Amount to increase 376 | * @return whether increase is successful 377 | */ 378 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { 379 | require(spender != address(0)); 380 | 381 | _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue); 382 | emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); 383 | return true; 384 | } 385 | 386 | /** 387 | * @dev Decrease the allowance 388 | * @param spender Approval target 389 | * @param subtractedValue Amount to decrease 390 | * @return Whether decrease is successful 391 | */ 392 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { 393 | require(spender != address(0)); 394 | 395 | _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue); 396 | emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); 397 | return true; 398 | } 399 | 400 | /** 401 | * @dev Transfer method 402 | * @param to Transfer target 403 | * @param value Transfer amount 404 | */ 405 | function _transfer(address from, address to, uint256 value) internal { 406 | _balances[from] = _balances[from].sub(value); 407 | _balances[to] = _balances[to].add(value); 408 | emit Transfer(from, to, value); 409 | } 410 | 411 | /** 412 | * @dev Check the creator 413 | * @return Creator address 414 | */ 415 | function checkBidder() public view returns(address) { 416 | return _bidder; 417 | } 418 | 419 | /** 420 | * @dev Transfer creator 421 | * @param bidder New creator address 422 | */ 423 | function changeBidder(address bidder) public { 424 | require(address(msg.sender) == _bidder); 425 | _bidder = bidder; 426 | } 427 | 428 | // Administrator only 429 | modifier onlyOwner(){ 430 | require(_voteFactory.checkOwners(msg.sender)); 431 | _; 432 | } 433 | } 434 | 435 | // NToken mapping contract 436 | interface Nest_NToken_TokenMapping { 437 | // Add mapping 438 | function addTokenMapping(address token, address nToken) external; 439 | function checkTokenMapping(address token) external view returns (address); 440 | } 441 | 442 | // Price contract 443 | interface Nest_3_OfferPrice { 444 | function addPriceCost(address tokenAddress) external; 445 | } 446 | -------------------------------------------------------------------------------- /NTokenAuction/Nest_NToken_TokenMapping.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | /** 4 | * @title NToken mapping contract 5 | * @dev Add, modify and check offering token mapping 6 | */ 7 | contract Nest_NToken_TokenMapping { 8 | 9 | mapping (address => address) _tokenMapping; // Token mapping - offering token => NToken 10 | Nest_3_VoteFactory _voteFactory; // Voting contract 11 | 12 | event TokenMappingLog(address token, address nToken); 13 | 14 | /** 15 | * @dev Initialization method 16 | * @param voteFactory Voting contract address 17 | */ 18 | constructor(address voteFactory) public { 19 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 20 | } 21 | 22 | /** 23 | * @dev Reset voting contract 24 | * @param voteFactory voting contract address 25 | */ 26 | function changeMapping(address voteFactory) public onlyOwner { 27 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 28 | } 29 | 30 | /** 31 | * @dev Add token mapping 32 | * @param token Offering token address 33 | * @param nToken Mining NToken address 34 | */ 35 | function addTokenMapping(address token, address nToken) public { 36 | require(address(msg.sender) == address(_voteFactory.checkAddress("nest.nToken.tokenAuction")), "No authority"); 37 | require(_tokenMapping[token] == address(0x0), "Token already exists"); 38 | _tokenMapping[token] = nToken; 39 | emit TokenMappingLog(token, nToken); 40 | } 41 | 42 | /** 43 | * @dev Change token mapping 44 | * @param token Offering token address 45 | * @param nToken Mining NToken address 46 | */ 47 | function changeTokenMapping(address token, address nToken) public onlyOwner { 48 | _tokenMapping[token] = nToken; 49 | emit TokenMappingLog(token, nToken); 50 | } 51 | 52 | /** 53 | * @dev Check token mapping 54 | * @param token Offering token address 55 | * @return Mining NToken address 56 | */ 57 | function checkTokenMapping(address token) public view returns (address) { 58 | return _tokenMapping[token]; 59 | } 60 | 61 | // Only for administrator 62 | modifier onlyOwner(){ 63 | require(_voteFactory.checkOwners(msg.sender), "No authority"); 64 | _; 65 | } 66 | } 67 | 68 | // Voting contract 69 | interface Nest_3_VoteFactory { 70 | // Check address 71 | function checkAddress(string calldata name) external view returns (address contractAddress); 72 | // Check whether the administrator 73 | function checkOwners(address man) external view returns (bool); 74 | } -------------------------------------------------------------------------------- /NestAbonus/ABI/Nest_3_Abonus_ABI.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "voteFactory", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { 16 | "internalType": "uint256", 17 | "name": "num", 18 | "type": "uint256" 19 | } 20 | ], 21 | "name": "changeDistributionSpan", 22 | "outputs": [], 23 | "stateMutability": "nonpayable", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "uint256", 30 | "name": "num", 31 | "type": "uint256" 32 | } 33 | ], 34 | "name": "changeDistributionTime", 35 | "outputs": [], 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "inputs": [ 41 | { 42 | "internalType": "uint256", 43 | "name": "num", 44 | "type": "uint256" 45 | } 46 | ], 47 | "name": "changeLeastDistribution", 48 | "outputs": [], 49 | "stateMutability": "nonpayable", 50 | "type": "function" 51 | }, 52 | { 53 | "inputs": [ 54 | { 55 | "internalType": "address", 56 | "name": "voteFactory", 57 | "type": "address" 58 | } 59 | ], 60 | "name": "changeMapping", 61 | "outputs": [], 62 | "stateMutability": "nonpayable", 63 | "type": "function" 64 | }, 65 | { 66 | "inputs": [ 67 | { 68 | "internalType": "uint256", 69 | "name": "num", 70 | "type": "uint256" 71 | } 72 | ], 73 | "name": "changeMostDistribution", 74 | "outputs": [], 75 | "stateMutability": "nonpayable", 76 | "type": "function" 77 | }, 78 | { 79 | "inputs": [], 80 | "name": "checkDistributionSpan", 81 | "outputs": [ 82 | { 83 | "internalType": "uint256", 84 | "name": "", 85 | "type": "uint256" 86 | } 87 | ], 88 | "stateMutability": "view", 89 | "type": "function" 90 | }, 91 | { 92 | "inputs": [], 93 | "name": "checkDistributionTime", 94 | "outputs": [ 95 | { 96 | "internalType": "uint256", 97 | "name": "", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [], 106 | "name": "checkLeastDistribution", 107 | "outputs": [ 108 | { 109 | "internalType": "uint256", 110 | "name": "", 111 | "type": "uint256" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [], 119 | "name": "checkMostDistribution", 120 | "outputs": [ 121 | { 122 | "internalType": "uint256", 123 | "name": "", 124 | "type": "uint256" 125 | } 126 | ], 127 | "stateMutability": "view", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [], 132 | "name": "checkNestAddress", 133 | "outputs": [ 134 | { 135 | "internalType": "address", 136 | "name": "", 137 | "type": "address" 138 | } 139 | ], 140 | "stateMutability": "view", 141 | "type": "function" 142 | }, 143 | { 144 | "inputs": [ 145 | { 146 | "internalType": "uint256", 147 | "name": "num", 148 | "type": "uint256" 149 | }, 150 | { 151 | "internalType": "address", 152 | "name": "token", 153 | "type": "address" 154 | }, 155 | { 156 | "internalType": "address", 157 | "name": "target", 158 | "type": "address" 159 | } 160 | ], 161 | "name": "getETH", 162 | "outputs": [], 163 | "stateMutability": "nonpayable", 164 | "type": "function" 165 | }, 166 | { 167 | "inputs": [ 168 | { 169 | "internalType": "address", 170 | "name": "token", 171 | "type": "address" 172 | } 173 | ], 174 | "name": "getETHNum", 175 | "outputs": [ 176 | { 177 | "internalType": "uint256", 178 | "name": "", 179 | "type": "uint256" 180 | } 181 | ], 182 | "stateMutability": "view", 183 | "type": "function" 184 | }, 185 | { 186 | "inputs": [ 187 | { 188 | "internalType": "address", 189 | "name": "token", 190 | "type": "address" 191 | } 192 | ], 193 | "name": "switchToEth", 194 | "outputs": [], 195 | "stateMutability": "payable", 196 | "type": "function" 197 | }, 198 | { 199 | "inputs": [ 200 | { 201 | "internalType": "address", 202 | "name": "token", 203 | "type": "address" 204 | } 205 | ], 206 | "name": "switchToEthForNTokenOffer", 207 | "outputs": [], 208 | "stateMutability": "payable", 209 | "type": "function" 210 | }, 211 | { 212 | "inputs": [ 213 | { 214 | "internalType": "uint256", 215 | "name": "amount", 216 | "type": "uint256" 217 | }, 218 | { 219 | "internalType": "address", 220 | "name": "target", 221 | "type": "address" 222 | } 223 | ], 224 | "name": "turnOutAllEth", 225 | "outputs": [], 226 | "stateMutability": "nonpayable", 227 | "type": "function" 228 | } 229 | ] -------------------------------------------------------------------------------- /NestAbonus/ABI/Nest_3_Leveling_ABI.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "voteFactory", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { 16 | "internalType": "address", 17 | "name": "voteFactory", 18 | "type": "address" 19 | } 20 | ], 21 | "name": "changeMapping", 22 | "outputs": [], 23 | "stateMutability": "nonpayable", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address", 30 | "name": "token", 31 | "type": "address" 32 | } 33 | ], 34 | "name": "checkEthMapping", 35 | "outputs": [ 36 | { 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [ 47 | { 48 | "internalType": "address", 49 | "name": "token", 50 | "type": "address" 51 | } 52 | ], 53 | "name": "switchToEth", 54 | "outputs": [], 55 | "stateMutability": "payable", 56 | "type": "function" 57 | }, 58 | { 59 | "inputs": [ 60 | { 61 | "internalType": "uint256", 62 | "name": "amount", 63 | "type": "uint256" 64 | }, 65 | { 66 | "internalType": "address", 67 | "name": "token", 68 | "type": "address" 69 | }, 70 | { 71 | "internalType": "address", 72 | "name": "target", 73 | "type": "address" 74 | } 75 | ], 76 | "name": "tranEth", 77 | "outputs": [ 78 | { 79 | "internalType": "uint256", 80 | "name": "", 81 | "type": "uint256" 82 | } 83 | ], 84 | "stateMutability": "nonpayable", 85 | "type": "function" 86 | }, 87 | { 88 | "inputs": [ 89 | { 90 | "internalType": "uint256", 91 | "name": "amount", 92 | "type": "uint256" 93 | }, 94 | { 95 | "internalType": "address", 96 | "name": "target", 97 | "type": "address" 98 | } 99 | ], 100 | "name": "turnOutAllEth", 101 | "outputs": [], 102 | "stateMutability": "nonpayable", 103 | "type": "function" 104 | } 105 | ] -------------------------------------------------------------------------------- /NestAbonus/ABI/Nest_3_TokenAbonus_ABI.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "voteFactory", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "anonymous": false, 15 | "inputs": [ 16 | { 17 | "indexed": false, 18 | "internalType": "address", 19 | "name": "tokenAddress", 20 | "type": "address" 21 | }, 22 | { 23 | "indexed": false, 24 | "internalType": "uint256", 25 | "name": "tokenAmount", 26 | "type": "uint256" 27 | } 28 | ], 29 | "name": "GetTokenLog", 30 | "type": "event" 31 | }, 32 | { 33 | "inputs": [ 34 | { 35 | "internalType": "address", 36 | "name": "token", 37 | "type": "address" 38 | } 39 | ], 40 | "name": "allValue", 41 | "outputs": [ 42 | { 43 | "internalType": "uint256", 44 | "name": "", 45 | "type": "uint256" 46 | } 47 | ], 48 | "stateMutability": "view", 49 | "type": "function" 50 | }, 51 | { 52 | "inputs": [ 53 | { 54 | "internalType": "uint256", 55 | "name": "num", 56 | "type": "uint256" 57 | } 58 | ], 59 | "name": "changeExpectedIncrement", 60 | "outputs": [], 61 | "stateMutability": "nonpayable", 62 | "type": "function" 63 | }, 64 | { 65 | "inputs": [ 66 | { 67 | "internalType": "uint256", 68 | "name": "num", 69 | "type": "uint256" 70 | } 71 | ], 72 | "name": "changeExpectedMinimum", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | }, 77 | { 78 | "inputs": [ 79 | { 80 | "internalType": "uint256", 81 | "name": "num", 82 | "type": "uint256" 83 | } 84 | ], 85 | "name": "changeExpectedSpanForNToken", 86 | "outputs": [], 87 | "stateMutability": "nonpayable", 88 | "type": "function" 89 | }, 90 | { 91 | "inputs": [ 92 | { 93 | "internalType": "uint256", 94 | "name": "num", 95 | "type": "uint256" 96 | } 97 | ], 98 | "name": "changeExpectedSpanForNest", 99 | "outputs": [], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [ 105 | { 106 | "internalType": "uint256", 107 | "name": "hour", 108 | "type": "uint256" 109 | } 110 | ], 111 | "name": "changeGetAbonusTimeLimit", 112 | "outputs": [], 113 | "stateMutability": "nonpayable", 114 | "type": "function" 115 | }, 116 | { 117 | "inputs": [ 118 | { 119 | "internalType": "address", 120 | "name": "voteFactory", 121 | "type": "address" 122 | } 123 | ], 124 | "name": "changeMapping", 125 | "outputs": [], 126 | "stateMutability": "nonpayable", 127 | "type": "function" 128 | }, 129 | { 130 | "inputs": [ 131 | { 132 | "internalType": "uint256", 133 | "name": "threshold", 134 | "type": "uint256" 135 | } 136 | ], 137 | "name": "changeSavingLevelOne", 138 | "outputs": [], 139 | "stateMutability": "nonpayable", 140 | "type": "function" 141 | }, 142 | { 143 | "inputs": [ 144 | { 145 | "internalType": "uint256", 146 | "name": "threshold", 147 | "type": "uint256" 148 | } 149 | ], 150 | "name": "changeSavingLevelThree", 151 | "outputs": [], 152 | "stateMutability": "nonpayable", 153 | "type": "function" 154 | }, 155 | { 156 | "inputs": [ 157 | { 158 | "internalType": "uint256", 159 | "name": "num", 160 | "type": "uint256" 161 | } 162 | ], 163 | "name": "changeSavingLevelThreeSub", 164 | "outputs": [], 165 | "stateMutability": "nonpayable", 166 | "type": "function" 167 | }, 168 | { 169 | "inputs": [ 170 | { 171 | "internalType": "uint256", 172 | "name": "threshold", 173 | "type": "uint256" 174 | } 175 | ], 176 | "name": "changeSavingLevelTwo", 177 | "outputs": [], 178 | "stateMutability": "nonpayable", 179 | "type": "function" 180 | }, 181 | { 182 | "inputs": [ 183 | { 184 | "internalType": "uint256", 185 | "name": "num", 186 | "type": "uint256" 187 | } 188 | ], 189 | "name": "changeSavingLevelTwoSub", 190 | "outputs": [], 191 | "stateMutability": "nonpayable", 192 | "type": "function" 193 | }, 194 | { 195 | "inputs": [ 196 | { 197 | "internalType": "uint256", 198 | "name": "hour", 199 | "type": "uint256" 200 | } 201 | ], 202 | "name": "changeTimeLimit", 203 | "outputs": [], 204 | "stateMutability": "nonpayable", 205 | "type": "function" 206 | }, 207 | { 208 | "inputs": [], 209 | "name": "checkExpectedMinimum", 210 | "outputs": [ 211 | { 212 | "internalType": "uint256", 213 | "name": "", 214 | "type": "uint256" 215 | } 216 | ], 217 | "stateMutability": "view", 218 | "type": "function" 219 | }, 220 | { 221 | "inputs": [], 222 | "name": "checkExpectedSpanForNToken", 223 | "outputs": [ 224 | { 225 | "internalType": "uint256", 226 | "name": "", 227 | "type": "uint256" 228 | } 229 | ], 230 | "stateMutability": "view", 231 | "type": "function" 232 | }, 233 | { 234 | "inputs": [], 235 | "name": "checkExpectedSpanForNest", 236 | "outputs": [ 237 | { 238 | "internalType": "uint256", 239 | "name": "", 240 | "type": "uint256" 241 | } 242 | ], 243 | "stateMutability": "view", 244 | "type": "function" 245 | }, 246 | { 247 | "inputs": [], 248 | "name": "checkGetAbonusTimeLimit", 249 | "outputs": [ 250 | { 251 | "internalType": "uint256", 252 | "name": "", 253 | "type": "uint256" 254 | } 255 | ], 256 | "stateMutability": "view", 257 | "type": "function" 258 | }, 259 | { 260 | "inputs": [ 261 | { 262 | "internalType": "address", 263 | "name": "token", 264 | "type": "address" 265 | } 266 | ], 267 | "name": "checkMinimumAbonus", 268 | "outputs": [ 269 | { 270 | "internalType": "uint256", 271 | "name": "", 272 | "type": "uint256" 273 | } 274 | ], 275 | "stateMutability": "view", 276 | "type": "function" 277 | }, 278 | { 279 | "inputs": [], 280 | "name": "checkSavingLevelOne", 281 | "outputs": [ 282 | { 283 | "internalType": "uint256", 284 | "name": "", 285 | "type": "uint256" 286 | } 287 | ], 288 | "stateMutability": "view", 289 | "type": "function" 290 | }, 291 | { 292 | "inputs": [], 293 | "name": "checkSavingLevelThree", 294 | "outputs": [ 295 | { 296 | "internalType": "uint256", 297 | "name": "", 298 | "type": "uint256" 299 | } 300 | ], 301 | "stateMutability": "view", 302 | "type": "function" 303 | }, 304 | { 305 | "inputs": [], 306 | "name": "checkSavingLevelThreeSub", 307 | "outputs": [ 308 | { 309 | "internalType": "uint256", 310 | "name": "", 311 | "type": "uint256" 312 | } 313 | ], 314 | "stateMutability": "view", 315 | "type": "function" 316 | }, 317 | { 318 | "inputs": [], 319 | "name": "checkSavingLevelTwo", 320 | "outputs": [ 321 | { 322 | "internalType": "uint256", 323 | "name": "", 324 | "type": "uint256" 325 | } 326 | ], 327 | "stateMutability": "view", 328 | "type": "function" 329 | }, 330 | { 331 | "inputs": [], 332 | "name": "checkSavingLevelTwoSub", 333 | "outputs": [ 334 | { 335 | "internalType": "uint256", 336 | "name": "", 337 | "type": "uint256" 338 | } 339 | ], 340 | "stateMutability": "view", 341 | "type": "function" 342 | }, 343 | { 344 | "inputs": [ 345 | { 346 | "internalType": "address", 347 | "name": "token", 348 | "type": "address" 349 | } 350 | ], 351 | "name": "checkSnapshot", 352 | "outputs": [ 353 | { 354 | "internalType": "bool", 355 | "name": "", 356 | "type": "bool" 357 | } 358 | ], 359 | "stateMutability": "view", 360 | "type": "function" 361 | }, 362 | { 363 | "inputs": [], 364 | "name": "checkTimeLimit", 365 | "outputs": [ 366 | { 367 | "internalType": "uint256", 368 | "name": "", 369 | "type": "uint256" 370 | } 371 | ], 372 | "stateMutability": "view", 373 | "type": "function" 374 | }, 375 | { 376 | "inputs": [], 377 | "name": "checkTimes", 378 | "outputs": [ 379 | { 380 | "internalType": "uint256", 381 | "name": "", 382 | "type": "uint256" 383 | } 384 | ], 385 | "stateMutability": "view", 386 | "type": "function" 387 | }, 388 | { 389 | "inputs": [ 390 | { 391 | "internalType": "address", 392 | "name": "token", 393 | "type": "address" 394 | }, 395 | { 396 | "internalType": "uint256", 397 | "name": "times", 398 | "type": "uint256" 399 | } 400 | ], 401 | "name": "checkTokenAllValueHistory", 402 | "outputs": [ 403 | { 404 | "internalType": "uint256", 405 | "name": "", 406 | "type": "uint256" 407 | } 408 | ], 409 | "stateMutability": "view", 410 | "type": "function" 411 | }, 412 | { 413 | "inputs": [ 414 | { 415 | "internalType": "address", 416 | "name": "token", 417 | "type": "address" 418 | }, 419 | { 420 | "internalType": "uint256", 421 | "name": "times", 422 | "type": "uint256" 423 | }, 424 | { 425 | "internalType": "address", 426 | "name": "user", 427 | "type": "address" 428 | } 429 | ], 430 | "name": "checkTokenSelfHistory", 431 | "outputs": [ 432 | { 433 | "internalType": "uint256", 434 | "name": "", 435 | "type": "uint256" 436 | } 437 | ], 438 | "stateMutability": "view", 439 | "type": "function" 440 | }, 441 | { 442 | "inputs": [], 443 | "name": "checkeExpectedIncrement", 444 | "outputs": [ 445 | { 446 | "internalType": "uint256", 447 | "name": "", 448 | "type": "uint256" 449 | } 450 | ], 451 | "stateMutability": "view", 452 | "type": "function" 453 | }, 454 | { 455 | "inputs": [ 456 | { 457 | "internalType": "uint256", 458 | "name": "amount", 459 | "type": "uint256" 460 | }, 461 | { 462 | "internalType": "address", 463 | "name": "token", 464 | "type": "address" 465 | } 466 | ], 467 | "name": "depositIn", 468 | "outputs": [], 469 | "stateMutability": "nonpayable", 470 | "type": "function" 471 | }, 472 | { 473 | "inputs": [ 474 | { 475 | "internalType": "address", 476 | "name": "token", 477 | "type": "address" 478 | } 479 | ], 480 | "name": "getAbonus", 481 | "outputs": [], 482 | "stateMutability": "nonpayable", 483 | "type": "function" 484 | }, 485 | { 486 | "inputs": [ 487 | { 488 | "internalType": "address", 489 | "name": "token", 490 | "type": "address" 491 | } 492 | ], 493 | "name": "getInfo", 494 | "outputs": [ 495 | { 496 | "internalType": "uint256", 497 | "name": "nextTime", 498 | "type": "uint256" 499 | }, 500 | { 501 | "internalType": "uint256", 502 | "name": "getAbonusTime", 503 | "type": "uint256" 504 | }, 505 | { 506 | "internalType": "uint256", 507 | "name": "ethNum", 508 | "type": "uint256" 509 | }, 510 | { 511 | "internalType": "uint256", 512 | "name": "tokenValue", 513 | "type": "uint256" 514 | }, 515 | { 516 | "internalType": "uint256", 517 | "name": "myJoinToken", 518 | "type": "uint256" 519 | }, 520 | { 521 | "internalType": "uint256", 522 | "name": "getEth", 523 | "type": "uint256" 524 | }, 525 | { 526 | "internalType": "uint256", 527 | "name": "allowNum", 528 | "type": "uint256" 529 | }, 530 | { 531 | "internalType": "uint256", 532 | "name": "leftNum", 533 | "type": "uint256" 534 | }, 535 | { 536 | "internalType": "bool", 537 | "name": "allowAbonus", 538 | "type": "bool" 539 | } 540 | ], 541 | "stateMutability": "view", 542 | "type": "function" 543 | }, 544 | { 545 | "inputs": [], 546 | "name": "getNextTime", 547 | "outputs": [ 548 | { 549 | "internalType": "uint256", 550 | "name": "", 551 | "type": "uint256" 552 | } 553 | ], 554 | "stateMutability": "view", 555 | "type": "function" 556 | }, 557 | { 558 | "inputs": [ 559 | { 560 | "internalType": "uint256", 561 | "name": "amount", 562 | "type": "uint256" 563 | }, 564 | { 565 | "internalType": "address", 566 | "name": "token", 567 | "type": "address" 568 | } 569 | ], 570 | "name": "takeOut", 571 | "outputs": [], 572 | "stateMutability": "nonpayable", 573 | "type": "function" 574 | }, 575 | { 576 | "stateMutability": "payable", 577 | "type": "receive" 578 | } 579 | ] -------------------------------------------------------------------------------- /NestAbonus/ABI/Nest_3_TokenSave_ABI.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "voteFactory", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { 16 | "internalType": "address", 17 | "name": "voteFactory", 18 | "type": "address" 19 | } 20 | ], 21 | "name": "changeMapping", 22 | "outputs": [], 23 | "stateMutability": "nonpayable", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address", 30 | "name": "sender", 31 | "type": "address" 32 | }, 33 | { 34 | "internalType": "address", 35 | "name": "token", 36 | "type": "address" 37 | } 38 | ], 39 | "name": "checkAmount", 40 | "outputs": [ 41 | { 42 | "internalType": "uint256", 43 | "name": "", 44 | "type": "uint256" 45 | } 46 | ], 47 | "stateMutability": "view", 48 | "type": "function" 49 | }, 50 | { 51 | "inputs": [ 52 | { 53 | "internalType": "uint256", 54 | "name": "num", 55 | "type": "uint256" 56 | }, 57 | { 58 | "internalType": "address", 59 | "name": "token", 60 | "type": "address" 61 | }, 62 | { 63 | "internalType": "address", 64 | "name": "target", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "depositIn", 69 | "outputs": [], 70 | "stateMutability": "nonpayable", 71 | "type": "function" 72 | }, 73 | { 74 | "inputs": [ 75 | { 76 | "internalType": "uint256", 77 | "name": "num", 78 | "type": "uint256" 79 | }, 80 | { 81 | "internalType": "address", 82 | "name": "token", 83 | "type": "address" 84 | }, 85 | { 86 | "internalType": "address", 87 | "name": "target", 88 | "type": "address" 89 | } 90 | ], 91 | "name": "takeOut", 92 | "outputs": [], 93 | "stateMutability": "nonpayable", 94 | "type": "function" 95 | } 96 | ] -------------------------------------------------------------------------------- /NestAbonus/Nest_3_Abonus.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | 6 | /** 7 | * @title ETH bonus pool 8 | * @dev ETH collection and inquiry 9 | */ 10 | contract Nest_3_Abonus { 11 | using address_make_payable for address; 12 | using SafeMath for uint256; 13 | 14 | Nest_3_VoteFactory _voteFactory; // Voting contract 15 | address _nestAddress; // NEST contract address 16 | mapping (address => uint256) ethMapping; // ETH bonus ledger of corresponding tokens 17 | uint256 _mostDistribution = 40; // The highest allocation ratio of NEST bonus pool 18 | uint256 _leastDistribution = 20; // The lowest allocation ratio of NEST bonus pool 19 | uint256 _distributionTime = 1200000; // The decay time interval of NEST bonus pool allocation ratio 20 | uint256 _distributionSpan = 5; // The decay degree of NEST bonus pool allocation ratio 21 | 22 | /** 23 | * @dev Initialization method 24 | * @param voteFactory Voting contract address 25 | */ 26 | constructor(address voteFactory) public { 27 | _voteFactory = Nest_3_VoteFactory(voteFactory); 28 | _nestAddress = address(_voteFactory.checkAddress("nest")); 29 | } 30 | 31 | /** 32 | * @dev Reset voting contract 33 | * @param voteFactory Voting contract address 34 | */ 35 | function changeMapping(address voteFactory) public onlyOwner{ 36 | _voteFactory = Nest_3_VoteFactory(voteFactory); 37 | _nestAddress = address(_voteFactory.checkAddress("nest")); 38 | } 39 | 40 | /** 41 | * @dev Transfer in bonus 42 | * @param token Corresponding to lock-up Token 43 | */ 44 | function switchToEth(address token) public payable { 45 | ethMapping[token] = ethMapping[token].add(msg.value); 46 | } 47 | 48 | /** 49 | * @dev Transferin bonus - NToken offering fee 50 | * @param token Corresponding to lock-up NToken 51 | */ 52 | function switchToEthForNTokenOffer(address token) public payable { 53 | Nest_NToken nToken = Nest_NToken(token); 54 | (uint256 createBlock,) = nToken.checkBlockInfo(); 55 | uint256 subBlock = block.number.sub(createBlock); 56 | uint256 times = subBlock.div(_distributionTime); 57 | uint256 distributionValue = times.mul(_distributionSpan); 58 | uint256 distribution = _mostDistribution; 59 | if (_leastDistribution.add(distributionValue) > _mostDistribution) { 60 | distribution = _leastDistribution; 61 | } else { 62 | distribution = _mostDistribution.sub(distributionValue); 63 | } 64 | uint256 nestEth = msg.value.mul(distribution).div(100); 65 | ethMapping[_nestAddress] = ethMapping[_nestAddress].add(nestEth); 66 | ethMapping[token] = ethMapping[token].add(msg.value.sub(nestEth)); 67 | } 68 | 69 | /** 70 | * @dev Receive ETH 71 | * @param num Receive amount 72 | * @param token Correspond to locked Token 73 | * @param target Transfer target 74 | */ 75 | function getETH(uint256 num, address token, address target) public onlyContract { 76 | require(num <= ethMapping[token], "Insufficient storage balance"); 77 | ethMapping[token] = ethMapping[token].sub(num); 78 | address payable addr = target.make_payable(); 79 | addr.transfer(num); 80 | } 81 | 82 | /** 83 | * @dev Get bonus pool balance 84 | * @param token Corresponded locked Token 85 | * @return uint256 Bonus pool balance 86 | */ 87 | function getETHNum(address token) public view returns (uint256) { 88 | return ethMapping[token]; 89 | } 90 | 91 | // View NEST address 92 | function checkNestAddress() public view returns(address) { 93 | return _nestAddress; 94 | } 95 | 96 | // View the highest NEST bonus pool allocation ratio 97 | function checkMostDistribution() public view returns(uint256) { 98 | return _mostDistribution; 99 | } 100 | 101 | // View the lowest NEST bonus pool allocation ratio 102 | function checkLeastDistribution() public view returns(uint256) { 103 | return _leastDistribution; 104 | } 105 | 106 | // View the decay time interval of NEST bonus pool allocation ratio 107 | function checkDistributionTime() public view returns(uint256) { 108 | return _distributionTime; 109 | } 110 | 111 | // View the decay degree of NEST bonus pool allocation ratio 112 | function checkDistributionSpan() public view returns(uint256) { 113 | return _distributionSpan; 114 | } 115 | 116 | // Modify the highest NEST bonus pool allocation ratio 117 | function changeMostDistribution(uint256 num) public onlyOwner { 118 | _mostDistribution = num; 119 | } 120 | 121 | // Modify the lowest NEST bonus pool allocation ratio 122 | function changeLeastDistribution(uint256 num) public onlyOwner { 123 | _leastDistribution = num; 124 | } 125 | 126 | // Modify the decay time interval of NEST bonus pool allocation ratio 127 | function changeDistributionTime(uint256 num) public onlyOwner { 128 | _distributionTime = num; 129 | } 130 | 131 | // Modify the decay degree of NEST bonus pool allocation ratio 132 | function changeDistributionSpan(uint256 num) public onlyOwner { 133 | _distributionSpan = num; 134 | } 135 | 136 | // Withdraw ETH 137 | function turnOutAllEth(uint256 amount, address target) public onlyOwner { 138 | address payable addr = target.make_payable(); 139 | addr.transfer(amount); 140 | } 141 | 142 | // Only bonus logic contract 143 | modifier onlyContract(){ 144 | require(_voteFactory.checkAddress("nest.v3.tokenAbonus") == address(msg.sender), "No authority"); 145 | _; 146 | } 147 | 148 | // Administrator only 149 | modifier onlyOwner(){ 150 | require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); 151 | _; 152 | } 153 | } 154 | 155 | // Voting factory 156 | interface Nest_3_VoteFactory { 157 | // Check address 158 | function checkAddress(string calldata name) external view returns (address contractAddress); 159 | // Check whether the administrator 160 | function checkOwners(address man) external view returns (bool); 161 | } 162 | 163 | // NToken 164 | interface Nest_NToken { 165 | // Increase token 166 | function increaseTotal(uint256 value) external; 167 | // Query mining information 168 | function checkBlockInfo() external view returns(uint256 createBlock, uint256 recentlyUsedBlock); 169 | // Query creator 170 | function checkOwner() external view returns(address); 171 | function totalSupply() external view returns (uint256); 172 | function balanceOf(address account) external view returns (uint256); 173 | function transfer(address recipient, uint256 amount) external returns (bool); 174 | function allowance(address owner, address spender) external view returns (uint256); 175 | function approve(address spender, uint256 amount) external returns (bool); 176 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 177 | event Transfer(address indexed from, address indexed to, uint256 value); 178 | event Approval(address indexed owner, address indexed spender, uint256 value); 179 | } -------------------------------------------------------------------------------- /NestAbonus/Nest_3_Leveling.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | 6 | /** 7 | * @title Leveling contract 8 | * @dev ETH transfer in and transfer out 9 | */ 10 | contract Nest_3_Leveling { 11 | using address_make_payable for address; 12 | using SafeMath for uint256; 13 | Nest_3_VoteFactory _voteFactory; // Vote contract 14 | mapping (address => uint256) ethMapping; // Corresponded ETH leveling ledger of token 15 | 16 | /** 17 | * @dev Initialization method 18 | * @param voteFactory Voting contract address 19 | */ 20 | constructor (address voteFactory) public { 21 | _voteFactory = Nest_3_VoteFactory(voteFactory); 22 | } 23 | 24 | /** 25 | * @dev Modifying voting contract 26 | * @param voteFactory Voting contract address 27 | */ 28 | function changeMapping(address voteFactory) public onlyOwner { 29 | _voteFactory = Nest_3_VoteFactory(voteFactory); 30 | } 31 | 32 | /** 33 | * @dev Transfer out leveling 34 | * @param amount Transfer-out amount 35 | * @param token Corresponding lock-up token 36 | * @param target Transfer-out target 37 | */ 38 | function tranEth(uint256 amount, address token, address target) public returns (uint256) { 39 | require(address(msg.sender) == address(_voteFactory.checkAddress("nest.v3.tokenAbonus")), "No authority"); 40 | uint256 tranAmount = amount; 41 | if (tranAmount > ethMapping[token]) { 42 | tranAmount = ethMapping[token]; 43 | } 44 | ethMapping[token] = ethMapping[token].sub(tranAmount); 45 | address payable addr = target.make_payable(); 46 | addr.transfer(tranAmount); 47 | return tranAmount; 48 | } 49 | 50 | /** 51 | * @dev Transfer in leveling 52 | * @param token Corresponded locked token 53 | */ 54 | function switchToEth(address token) public payable { 55 | ethMapping[token] = ethMapping[token].add(msg.value); 56 | } 57 | 58 | // Check the leveled amount corresponding to the token 59 | function checkEthMapping(address token) public view returns (uint256) { 60 | return ethMapping[token]; 61 | } 62 | 63 | // Withdraw ETH 64 | function turnOutAllEth(uint256 amount, address target) public onlyOwner { 65 | address payable addr = target.make_payable(); 66 | addr.transfer(amount); 67 | } 68 | 69 | // Administrator only 70 | modifier onlyOwner(){ 71 | require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); 72 | _; 73 | } 74 | } 75 | 76 | // Voting factory 77 | interface Nest_3_VoteFactory { 78 | // Check address 79 | function checkAddress(string calldata name) external view returns (address contractAddress); 80 | // Check whether the administrator 81 | function checkOwners(address man) external view returns (bool); 82 | } -------------------------------------------------------------------------------- /NestAbonus/Nest_3_TokenAbonus.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | 6 | /** 7 | * @title Dividend logic 8 | * @dev Some operations about dividend,logic and asset separation 9 | */ 10 | contract Nest_3_TokenAbonus { 11 | using address_make_payable for address; 12 | using SafeMath for uint256; 13 | 14 | ERC20 _nestContract; 15 | Nest_3_TokenSave _tokenSave; // Lock-up contract 16 | Nest_3_Abonus _abonusContract; // ETH bonus pool 17 | Nest_3_VoteFactory _voteFactory; // Voting contract 18 | Nest_3_Leveling _nestLeveling; // Leveling contract 19 | address _destructionAddress; // Destroy contract address 20 | 21 | uint256 _timeLimit = 168 hours; // Bonus period 22 | uint256 _nextTime = 1596168000; // Next bonus time 23 | uint256 _getAbonusTimeLimit = 60 hours; // During of triggering calculation of bonus 24 | uint256 _times = 0; // Bonus ledger 25 | uint256 _expectedIncrement = 3; // Expected bonus increment ratio 26 | uint256 _expectedSpanForNest = 100000000 ether; // NEST expected bonus increment threshold 27 | uint256 _expectedSpanForNToken = 1000000 ether; // NToken expected bonus increment threshold 28 | uint256 _expectedMinimum = 100 ether; // Expected minimum bonus 29 | uint256 _savingLevelOne = 10; // Saving threshold level 1 30 | uint256 _savingLevelTwo = 20; // Saving threshold level 2 31 | uint256 _savingLevelTwoSub = 100 ether; // Function parameters of savings threshold level 2 32 | uint256 _savingLevelThree = 30; // Function parameters of savings threshold level 3 33 | uint256 _savingLevelThreeSub = 600 ether; // Function parameters of savings threshold level 3 34 | 35 | mapping(address => uint256) _abonusMapping; // Bonus pool snapshot - token address (NEST or NToken) => number of ETH in the bonus pool 36 | mapping(address => uint256) _tokenAllValueMapping; // Number of tokens (circulation) - token address (NEST or NToken) ) => total circulation 37 | mapping(address => mapping(uint256 => uint256)) _tokenAllValueHistory; // NEST or NToken circulation snapshot - token address (NEST or NToken) => number of periods => total circulation 38 | mapping(address => mapping(uint256 => mapping(address => uint256))) _tokenSelfHistory; // Personal lockup - NEST or NToken snapshot token address (NEST or NToken) => period => user address => total circulation 39 | mapping(address => mapping(uint256 => bool)) _snapshot; // Whether snapshot - token address (NEST or NToken) => number of periods => whether to take a snapshot 40 | mapping(uint256 => mapping(address => mapping(address => bool))) _getMapping; // Receiving records - period => token address (NEST or NToken) => user address => whether received 41 | 42 | // Log token address, amount 43 | event GetTokenLog(address tokenAddress, uint256 tokenAmount); 44 | 45 | /** 46 | * @dev Initialization method 47 | * @param voteFactory Voting contract address 48 | */ 49 | constructor (address voteFactory) public { 50 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 51 | _voteFactory = voteFactoryMap; 52 | _nestContract = ERC20(address(voteFactoryMap.checkAddress("nest"))); 53 | _tokenSave = Nest_3_TokenSave(address(voteFactoryMap.checkAddress("nest.v3.tokenSave"))); 54 | address payable addr = address(voteFactoryMap.checkAddress("nest.v3.abonus")).make_payable(); 55 | _abonusContract = Nest_3_Abonus(addr); 56 | address payable levelingAddr = address(voteFactoryMap.checkAddress("nest.v3.leveling")).make_payable(); 57 | _nestLeveling = Nest_3_Leveling(levelingAddr); 58 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 59 | } 60 | 61 | /** 62 | * @dev Modify voting contract 63 | * @param voteFactory Voting contract address 64 | */ 65 | function changeMapping(address voteFactory) public onlyOwner { 66 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 67 | _voteFactory = voteFactoryMap; 68 | _nestContract = ERC20(address(voteFactoryMap.checkAddress("nest"))); 69 | _tokenSave = Nest_3_TokenSave(address(voteFactoryMap.checkAddress("nest.v3.tokenSave"))); 70 | address payable addr = address(voteFactoryMap.checkAddress("nest.v3.abonus")).make_payable(); 71 | _abonusContract = Nest_3_Abonus(addr); 72 | address payable levelingAddr = address(voteFactoryMap.checkAddress("nest.v3.leveling")).make_payable(); 73 | _nestLeveling = Nest_3_Leveling(levelingAddr); 74 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 75 | } 76 | 77 | /** 78 | * @dev Deposit 79 | * @param amount Deposited amount 80 | * @param token Locked token address 81 | */ 82 | function depositIn(uint256 amount, address token) public { 83 | uint256 nowTime = now; 84 | uint256 nextTime = _nextTime; 85 | uint256 timeLimit = _timeLimit; 86 | if (nowTime < nextTime) { 87 | // Bonus triggered 88 | require(!(nowTime >= nextTime.sub(timeLimit) && nowTime <= nextTime.sub(timeLimit).add(_getAbonusTimeLimit))); 89 | } else { 90 | // Bonus not triggered 91 | uint256 times = (nowTime.sub(_nextTime)).div(_timeLimit); 92 | // Calculate the time when bonus should be started 93 | uint256 startTime = _nextTime.add((times).mul(_timeLimit)); 94 | // Calculate the time when bonus should be stopped 95 | uint256 endTime = startTime.add(_getAbonusTimeLimit); 96 | require(!(nowTime >= startTime && nowTime <= endTime)); 97 | } 98 | _tokenSave.depositIn(amount, token, address(msg.sender)); 99 | } 100 | 101 | /** 102 | * @dev Withdrawing 103 | * @param amount Withdrawing amount 104 | * @param token Token address 105 | */ 106 | function takeOut(uint256 amount, address token) public { 107 | require(amount > 0, "Parameter needs to be greater than 0"); 108 | require(amount <= _tokenSave.checkAmount(address(msg.sender), token), "Insufficient storage balance"); 109 | if (token == address(_nestContract)) { 110 | require(!_voteFactory.checkVoteNow(address(tx.origin)), "Voting"); 111 | } 112 | _tokenSave.takeOut(amount, token, address(msg.sender)); 113 | } 114 | 115 | /** 116 | * @dev Receiving 117 | * @param token Receiving token address 118 | */ 119 | function getAbonus(address token) public { 120 | uint256 tokenAmount = _tokenSave.checkAmount(address(msg.sender), token); 121 | require(tokenAmount > 0, "Insufficient storage balance"); 122 | reloadTime(); 123 | reloadToken(token); 124 | uint256 nowTime = now; 125 | require(nowTime >= _nextTime.sub(_timeLimit) && nowTime <= _nextTime.sub(_timeLimit).add(_getAbonusTimeLimit), "Not time to draw"); 126 | require(!_getMapping[_times.sub(1)][token][address(msg.sender)], "Have received"); 127 | _tokenSelfHistory[token][_times.sub(1)][address(msg.sender)] = tokenAmount; 128 | require(_tokenAllValueMapping[token] > 0, "Total flux error"); 129 | uint256 selfNum = tokenAmount.mul(_abonusMapping[token]).div(_tokenAllValueMapping[token]); 130 | require(selfNum > 0, "No limit available"); 131 | _getMapping[_times.sub(1)][token][address(msg.sender)] = true; 132 | _abonusContract.getETH(selfNum, token,address(msg.sender)); 133 | emit GetTokenLog(token, selfNum); 134 | } 135 | 136 | /** 137 | * @dev Update bonus time and stage ledger 138 | */ 139 | function reloadTime() private { 140 | uint256 nowTime = now; 141 | // The current time must exceed the bonus time 142 | if (nowTime >= _nextTime) { 143 | uint256 time = (nowTime.sub(_nextTime)).div(_timeLimit); 144 | uint256 startTime = _nextTime.add((time).mul(_timeLimit)); 145 | uint256 endTime = startTime.add(_getAbonusTimeLimit); 146 | if (nowTime >= startTime && nowTime <= endTime) { 147 | _nextTime = getNextTime(); 148 | _times = _times.add(1); 149 | } 150 | } 151 | } 152 | 153 | /** 154 | * @dev Snapshot of the amount of tokens 155 | * @param token Receiving token address 156 | */ 157 | function reloadToken(address token) private { 158 | if (!_snapshot[token][_times.sub(1)]) { 159 | levelingResult(token); 160 | _abonusMapping[token] = _abonusContract.getETHNum(token); 161 | _tokenAllValueMapping[token] = allValue(token); 162 | _tokenAllValueHistory[token][_times.sub(1)] = allValue(token); 163 | _snapshot[token][_times.sub(1)] = true; 164 | } 165 | } 166 | 167 | /** 168 | * @dev Leveling settlement 169 | * @param token Receiving token address 170 | */ 171 | function levelingResult(address token) private { 172 | uint256 steps; 173 | if (token == address(_nestContract)) { 174 | steps = allValue(token).div(_expectedSpanForNest); 175 | } else { 176 | steps = allValue(token).div(_expectedSpanForNToken); 177 | } 178 | uint256 minimumAbonus = _expectedMinimum; 179 | for (uint256 i = 0; i < steps; i++) { 180 | minimumAbonus = minimumAbonus.add(minimumAbonus.mul(_expectedIncrement).div(100)); 181 | } 182 | uint256 thisAbonus = _abonusContract.getETHNum(token); 183 | if (thisAbonus > minimumAbonus) { 184 | uint256 levelAmount = 0; 185 | if (thisAbonus > 5000 ether) { 186 | levelAmount = thisAbonus.mul(_savingLevelThree).div(100).sub(_savingLevelThreeSub); 187 | } else if (thisAbonus > 1000 ether) { 188 | levelAmount = thisAbonus.mul(_savingLevelTwo).div(100).sub(_savingLevelTwoSub); 189 | } else { 190 | levelAmount = thisAbonus.mul(_savingLevelOne).div(100); 191 | } 192 | if (thisAbonus.sub(levelAmount) < minimumAbonus) { 193 | _abonusContract.getETH(thisAbonus.sub(minimumAbonus), token, address(this)); 194 | _nestLeveling.switchToEth.value(thisAbonus.sub(minimumAbonus))(token); 195 | } else { 196 | _abonusContract.getETH(levelAmount, token, address(this)); 197 | _nestLeveling.switchToEth.value(levelAmount)(token); 198 | } 199 | } else { 200 | uint256 ethValue = _nestLeveling.tranEth(minimumAbonus.sub(thisAbonus), token, address(this)); 201 | _abonusContract.switchToEth.value(ethValue)(token); 202 | } 203 | } 204 | 205 | // 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 206 | 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) { 207 | uint256 nowTime = now; 208 | if (nowTime >= _nextTime.sub(_timeLimit) && nowTime <= _nextTime.sub(_timeLimit).add(_getAbonusTimeLimit) && _times > 0 && _snapshot[token][_times.sub(1)]) { 209 | // Bonus have been triggered, and during the time of this bonus, display snapshot data 210 | allowAbonus = _getMapping[_times.sub(1)][token][address(msg.sender)]; 211 | ethNum = _abonusMapping[token]; 212 | tokenValue = _tokenAllValueMapping[token]; 213 | } else { 214 | // Display real-time data 215 | ethNum = _abonusContract.getETHNum(token); 216 | tokenValue = allValue(token); 217 | allowAbonus = _getMapping[_times][token][address(msg.sender)]; 218 | } 219 | myJoinToken = _tokenSave.checkAmount(address(msg.sender), token); 220 | if (allowAbonus == true) { 221 | getEth = 0; 222 | } else { 223 | getEth = myJoinToken.mul(ethNum).div(tokenValue); 224 | } 225 | nextTime = getNextTime(); 226 | getAbonusTime = nextTime.sub(_timeLimit).add(_getAbonusTimeLimit); 227 | allowNum = ERC20(token).allowance(address(msg.sender), address(_tokenSave)); 228 | leftNum = ERC20(token).balanceOf(address(msg.sender)); 229 | } 230 | 231 | /** 232 | * @dev View next bonus time 233 | * @return Next bonus time 234 | */ 235 | function getNextTime() public view returns (uint256) { 236 | uint256 nowTime = now; 237 | if (_nextTime > nowTime) { 238 | return _nextTime; 239 | } else { 240 | uint256 time = (nowTime.sub(_nextTime)).div(_timeLimit); 241 | return _nextTime.add(_timeLimit.mul(time.add(1))); 242 | } 243 | } 244 | 245 | /** 246 | * @dev View total circulation 247 | * @return Total circulation 248 | */ 249 | function allValue(address token) public view returns (uint256) { 250 | if (token == address(_nestContract)) { 251 | uint256 all = 10000000000 ether; 252 | uint256 leftNum = all.sub(_nestContract.balanceOf(address(_voteFactory.checkAddress("nest.v3.miningSave")))).sub(_nestContract.balanceOf(address(_destructionAddress))); 253 | return leftNum; 254 | } else { 255 | return ERC20(token).totalSupply(); 256 | } 257 | } 258 | 259 | /** 260 | * @dev View bonus period 261 | * @return Bonus period 262 | */ 263 | function checkTimeLimit() public view returns (uint256) { 264 | return _timeLimit; 265 | } 266 | 267 | /** 268 | * @dev View duration of triggering calculation of bonus 269 | * @return Bonus period 270 | */ 271 | function checkGetAbonusTimeLimit() public view returns (uint256) { 272 | return _getAbonusTimeLimit; 273 | } 274 | 275 | /** 276 | * @dev View current lowest expected bonus 277 | * @return Current lowest expected bonus 278 | */ 279 | function checkMinimumAbonus(address token) public view returns (uint256) { 280 | uint256 miningAmount; 281 | if (token == address(_nestContract)) { 282 | miningAmount = allValue(token).div(_expectedSpanForNest); 283 | } else { 284 | miningAmount = allValue(token).div(_expectedSpanForNToken); 285 | } 286 | uint256 minimumAbonus = _expectedMinimum; 287 | for (uint256 i = 0; i < miningAmount; i++) { 288 | minimumAbonus = minimumAbonus.add(minimumAbonus.mul(_expectedIncrement).div(100)); 289 | } 290 | return minimumAbonus; 291 | } 292 | 293 | /** 294 | * @dev Check whether the bonus token is snapshoted 295 | * @param token Token address 296 | * @return Whether snapshoted 297 | */ 298 | function checkSnapshot(address token) public view returns (bool) { 299 | return _snapshot[token][_times.sub(1)]; 300 | } 301 | 302 | /** 303 | * @dev Check the expected bonus incremental ratio 304 | * @return Expected bonus increment ratio 305 | */ 306 | function checkeExpectedIncrement() public view returns (uint256) { 307 | return _expectedIncrement; 308 | } 309 | 310 | /** 311 | * @dev View expected minimum bonus 312 | * @return Expected minimum bonus 313 | */ 314 | function checkExpectedMinimum() public view returns (uint256) { 315 | return _expectedMinimum; 316 | } 317 | 318 | /** 319 | * @dev View savings threshold 320 | * @return Save threshold 321 | */ 322 | function checkSavingLevelOne() public view returns (uint256) { 323 | return _savingLevelOne; 324 | } 325 | function checkSavingLevelTwo() public view returns (uint256) { 326 | return _savingLevelTwo; 327 | } 328 | function checkSavingLevelThree() public view returns (uint256) { 329 | return _savingLevelThree; 330 | } 331 | 332 | /** 333 | * @dev View NEST liquidity snapshot 334 | * @param token Locked token address 335 | * @param times Bonus snapshot period 336 | */ 337 | function checkTokenAllValueHistory(address token, uint256 times) public view returns (uint256) { 338 | return _tokenAllValueHistory[token][times]; 339 | } 340 | 341 | /** 342 | * @dev View personal lock-up NEST snapshot 343 | * @param times Bonus snapshot period 344 | * @param user User address 345 | * @return The number of personal locked NEST snapshots 346 | */ 347 | function checkTokenSelfHistory(address token, uint256 times, address user) public view returns (uint256) { 348 | return _tokenSelfHistory[token][times][user]; 349 | } 350 | 351 | // View the period number of bonus 352 | function checkTimes() public view returns (uint256) { 353 | return _times; 354 | } 355 | 356 | // NEST expected bonus increment threshold 357 | function checkExpectedSpanForNest() public view returns (uint256) { 358 | return _expectedSpanForNest; 359 | } 360 | 361 | // NToken expected bonus increment threshold 362 | function checkExpectedSpanForNToken() public view returns (uint256) { 363 | return _expectedSpanForNToken; 364 | } 365 | 366 | // View the function parameters of savings threshold level 3 367 | function checkSavingLevelTwoSub() public view returns (uint256) { 368 | return _savingLevelTwoSub; 369 | } 370 | 371 | // View the function parameters of savings threshold level 3 372 | function checkSavingLevelThreeSub() public view returns (uint256) { 373 | return _savingLevelThreeSub; 374 | } 375 | 376 | /** 377 | * @dev Update bonus period 378 | * @param hour Bonus period (hours) 379 | */ 380 | function changeTimeLimit(uint256 hour) public onlyOwner { 381 | require(hour > 0, "Parameter needs to be greater than 0"); 382 | _timeLimit = hour.mul(1 hours); 383 | } 384 | 385 | /** 386 | * @dev Update collection period 387 | * @param hour Collection period (hours) 388 | */ 389 | function changeGetAbonusTimeLimit(uint256 hour) public onlyOwner { 390 | require(hour > 0, "Parameter needs to be greater than 0"); 391 | _getAbonusTimeLimit = hour; 392 | } 393 | 394 | /** 395 | * @dev Update expected bonus increment ratio 396 | * @param num Expected bonus increment ratio 397 | */ 398 | function changeExpectedIncrement(uint256 num) public onlyOwner { 399 | require(num > 0, "Parameter needs to be greater than 0"); 400 | _expectedIncrement = num; 401 | } 402 | 403 | /** 404 | * @dev Update expected minimum bonus 405 | * @param num Expected minimum bonus 406 | */ 407 | function changeExpectedMinimum(uint256 num) public onlyOwner { 408 | require(num > 0, "Parameter needs to be greater than 0"); 409 | _expectedMinimum = num; 410 | } 411 | 412 | /** 413 | * @dev Update saving threshold 414 | * @param threshold Saving threshold 415 | */ 416 | function changeSavingLevelOne(uint256 threshold) public onlyOwner { 417 | _savingLevelOne = threshold; 418 | } 419 | function changeSavingLevelTwo(uint256 threshold) public onlyOwner { 420 | _savingLevelTwo = threshold; 421 | } 422 | function changeSavingLevelThree(uint256 threshold) public onlyOwner { 423 | _savingLevelThree = threshold; 424 | } 425 | 426 | /** 427 | * @dev Update the function parameters of savings threshold level 2 428 | */ 429 | function changeSavingLevelTwoSub(uint256 num) public onlyOwner { 430 | _savingLevelTwoSub = num; 431 | } 432 | 433 | /** 434 | * @dev Update the function parameters of savings threshold level 3 435 | */ 436 | function changeSavingLevelThreeSub(uint256 num) public onlyOwner { 437 | _savingLevelThreeSub = num; 438 | } 439 | 440 | /** 441 | * @dev Update NEST expected bonus incremental threshold 442 | * @param num Threshold 443 | */ 444 | function changeExpectedSpanForNest(uint256 num) public onlyOwner { 445 | _expectedSpanForNest = num; 446 | } 447 | 448 | /** 449 | * @dev Update NToken expected bonus incremental threshold 450 | * @param num Threshold 451 | */ 452 | function changeExpectedSpanForNToken(uint256 num) public onlyOwner { 453 | _expectedSpanForNToken = num; 454 | } 455 | 456 | receive() external payable { 457 | 458 | } 459 | 460 | // Administrator only 461 | modifier onlyOwner(){ 462 | require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); 463 | _; 464 | } 465 | } 466 | 467 | // NEST and NToken lock-up contracts 468 | interface Nest_3_TokenSave { 469 | function depositIn(uint256 num, address token, address target) external; 470 | function checkAmount(address sender, address token) external view returns(uint256); 471 | function takeOut(uint256 num, address token, address target) external; 472 | } 473 | 474 | // ETH bonus pool 475 | interface Nest_3_Abonus { 476 | function getETH(uint256 num, address token, address target) external; 477 | function getETHNum(address token) external view returns (uint256); 478 | function switchToEth(address token) external payable; 479 | } 480 | 481 | // Leveling contract 482 | interface Nest_3_Leveling { 483 | function tranEth(uint256 amount, address token, address target) external returns (uint256); 484 | function switchToEth(address token) external payable; 485 | } 486 | 487 | // Voting factory contract 488 | interface Nest_3_VoteFactory { 489 | // Check if there is a vote currently participating 490 | function checkVoteNow(address user) external view returns(bool); 491 | // Check address 492 | function checkAddress(string calldata name) external view returns (address contractAddress); 493 | // Check whether the administrator 494 | function checkOwners(address man) external view returns (bool); 495 | } 496 | 497 | // ERC20 contract 498 | interface ERC20 { 499 | function totalSupply() external view returns (uint256); 500 | function balanceOf(address account) external view returns (uint256); 501 | function transfer(address recipient, uint256 amount) external returns (bool); 502 | function allowance(address owner, address spender) external view returns (uint256); 503 | function approve(address spender, uint256 amount) external returns (bool); 504 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 505 | event Transfer(address indexed from, address indexed to, uint256 value); 506 | event Approval(address indexed owner, address indexed spender, uint256 value); 507 | } 508 | -------------------------------------------------------------------------------- /NestAbonus/Nest_3_TokenSave.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | 5 | /** 6 | * @title NEST and NToken lock-up contract 7 | * @dev NEST and NToken deposit and withdrawal 8 | */ 9 | contract Nest_3_TokenSave { 10 | using SafeMath for uint256; 11 | 12 | Nest_3_VoteFactory _voteFactory; // Voting contract 13 | mapping(address => mapping(address => uint256)) _baseMapping; // Ledger token=>user=>amount 14 | 15 | /** 16 | * @dev initialization method 17 | * @param voteFactory Voting contract address 18 | */ 19 | constructor(address voteFactory) public { 20 | _voteFactory = Nest_3_VoteFactory(voteFactory); 21 | } 22 | 23 | /** 24 | * @dev Reset voting contract 25 | * @param voteFactory Voting contract address 26 | */ 27 | function changeMapping(address voteFactory) public onlyOwner { 28 | _voteFactory = Nest_3_VoteFactory(voteFactory); 29 | } 30 | 31 | /** 32 | * @dev Withdrawing 33 | * @param num Withdrawing amount 34 | * @param token Lock-up token address 35 | * @param target Transfer target 36 | */ 37 | function takeOut(uint256 num, address token, address target) public onlyContract { 38 | require(num <= _baseMapping[token][address(target)], "Insufficient storage balance"); 39 | _baseMapping[token][address(target)] = _baseMapping[token][address(target)].sub(num); 40 | ERC20(token).transfer(address(target), num); 41 | } 42 | 43 | /** 44 | * @dev Depositing 45 | * @param num Depositing amount 46 | * @param token Lock-up token address 47 | * @param target Depositing target 48 | */ 49 | function depositIn(uint256 num, address token, address target) public onlyContract { 50 | require(ERC20(token).transferFrom(address(target),address(this),num), "Authorization transfer failed"); 51 | _baseMapping[token][address(target)] = _baseMapping[token][address(target)].add(num); 52 | } 53 | 54 | /** 55 | * @dev Check the amount 56 | * @param sender Check address 57 | * @param token Lock-up token address 58 | * @return uint256 Check address corresponding lock-up limit 59 | */ 60 | function checkAmount(address sender, address token) public view returns(uint256) { 61 | return _baseMapping[token][address(sender)]; 62 | } 63 | 64 | // Administrators only 65 | modifier onlyOwner(){ 66 | require(_voteFactory.checkOwners(address(msg.sender)), "No authority"); 67 | _; 68 | } 69 | 70 | // Only for bonus logic contract 71 | modifier onlyContract(){ 72 | require(_voteFactory.checkAddress("nest.v3.tokenAbonus") == address(msg.sender), "No authority"); 73 | _; 74 | } 75 | } 76 | 77 | // ERC20 contract 78 | interface ERC20 { 79 | function totalSupply() external view returns (uint256); 80 | function balanceOf(address account) external view returns (uint256); 81 | function transfer(address recipient, uint256 amount) external returns (bool); 82 | function allowance(address owner, address spender) external view returns (uint256); 83 | function approve(address spender, uint256 amount) external returns (bool); 84 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 85 | event Transfer(address indexed from, address indexed to, uint256 value); 86 | event Approval(address indexed owner, address indexed spender, uint256 value); 87 | } 88 | 89 | // Voting factory 90 | interface Nest_3_VoteFactory { 91 | // Check address 92 | function checkAddress(string calldata name) external view returns (address contractAddress); 93 | // Check whether the administrator 94 | function checkOwners(address man) external view returns (bool); 95 | } 96 | -------------------------------------------------------------------------------- /NestAbonus/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## NEST Vote Contract(Nest_3_VoteFactory) 4 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/VoteContract/Nest_3_VoteFactory.sol 5 | 6 | contract address(mainnet):0x6Cd5698E8854Fb6879d6B1C694223b389B465dea 7 | 8 | contract address(Ropsten):0xa43f89dE7f9da44aa4d11106D7b829cf6ac0b561 9 | 10 | ### Suggestions 11 | When using the NEST system contract for operations or quer, it is not recommended to set a fixed value for `contract address`. It can be obtained through the `checkAddress` method of the vote contract to dynamically obtain the address of the corresponding contract. Avoid changing the code off-chain after the contract is upgraded. 12 | 13 | ``` 14 | _nestAddress = address(_voteFactory.checkAddress("nest")); 15 | _tokenAbonus = _voteFactory.checkAddress("nest.v3.tokenAbonus"); 16 | ..... 17 | ..... 18 | ..... 19 | ``` 20 | 21 | 22 | ### NEST bonus pool contract(Nest_3_Abonus) 23 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestAbonus/Nest_3_Abonus.sol 24 | 25 | query field:"nest.v3.abonus" 26 | 27 | contract address(mainnet):0x43121397631551357EA511E62163B76e39D44852 28 | 29 | contract address(Ropsten):0x559B1628ee6558EAb5E8a12A8951ecdF6f40EA28 30 | 31 | ### NEST leveling contract(Nest_3_Leveling) 32 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestAbonus/Nest_3_Leveling.sol 33 | 34 | query field:"nest.v3.leveling" 35 | 36 | contract address(mainnet):0xaE2D09D7974a933c6dDC06b8039cF09783f4bAe8 37 | 38 | contract address(Ropsten):0x9e9e49334a4e5506d5DA62e78602547EDf173C67 39 | 40 | ### NEST abonus save contract(Nest_3_TokenSave) 41 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestAbonus/Nest_3_TokenSave.sol 42 | 43 | query field:"nest.v3.tokenSave" 44 | 45 | contract address(mainnet):0x03904F4B9Fb54c61AAf96d0aCDD2e42a46c99102 46 | 47 | contract address(Ropsten):0xdC912578B5e8f24b13E79ab072a1E9C86e659694 48 | 49 | ### NEST bonus logic contract(Nest_3_TokenAbonus) 50 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestAbonus/Nest_3_TokenAbonus.sol 51 | 52 | query field:"nest.v3.tokenAbonus" 53 | 54 | contract address(mainnet):0x19E1d193A448bD13097EFC2aea867468726e67c5 55 | 56 | contract address(Ropsten):0xDE83944619005d5EE4AAB951199748D599fCff44 57 | 58 | ### NEST Token contract(ERC20) 59 | github address:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestToken/IBNEST.sol 60 | 61 | query field:"nest" 62 | 63 | contract address(mainnet):0x04abEdA201850aC0124161F037Efd70c74ddC74C 64 | 65 | contract address(Ropsten):0xf565422eBd4A8976e1e447a849b8B483C68EFD0C 66 | 67 | ## Operations 68 | ### Approval(Approval should be done before depositing Tokens)- Nest_3_TokenSave 69 | Before depositing Nest or NToken,you should call ERC20 Approval method for "NestNode bonus save contract". 70 | 71 | ``` 72 | function approve(address _spender, uint256 _value) public returns (bool) { 73 | allowed[msg.sender][_spender] = _value; 74 | emit Approval(msg.sender, _spender, _value); 75 | return true; 76 | } 77 | ``` 78 | 79 | ### Depositing - Nest_3_TokenAbonus 80 | After the approcal,in non-receiving period ( Monday 0h - Friday 12h),call `depositIn` method in "NEST bonus logic contract"(Nest_3_TokenAbonus),and deposit Tokens。 81 | ``` 82 | function depositIn(uint256 amount, address token) public 83 | ``` 84 | ### Withdrawing - Nest_3_TokenAbonus 85 | In the condition of not participating in voting,withdrawing can be performed at any time. Call `takeOut` method in "NEST bonus logic contract"(Nest_3_TokenAbonus),and withdraw Tokens. 86 | ``` 87 | function takeOut(uint256 amount, address token) public 88 | ``` 89 | ### Getting bonus - Nest_3_TokenAbonus 90 | Receiving period(Friaday 12h~Sunday 24h),call `getAbonus` method in "NEST bonus logic contract"(Nest_3_TokenAbonus),receive bonus of tokens. 91 | 92 | ``` 93 | function getAbonus(address token) public 94 | ``` 95 | ### Checking bonus information - Nest_3_TokenAbonus 96 | input parameter | type | description 97 | ---|---|--- 98 | token | address | NEST or other NToken address 99 | 100 | returned parameter | type | description 101 | ---|---|--- 102 | nextTime | uint256 | Next bonus time 103 | getAbonusTime | uint256 | Deadline to receive bonus in this period 104 | ethNum | uint256 | Amount of ETH in bonus pool 105 | tokenValue | uint256 | circulation of locked Tokens 106 | myJoinToken | uint256 | The amount of my deposited Tokens 107 | getEth | uint256 | The amount of ETH I can receive in this period 108 | allowNum | uint256 | My approved allowance to "NestNode bonus save contract" 109 | leftNum | uint256 | My balance of approved Token (in personal wallet) 110 | allowAbonus | bool | Whether bonus is received in this period(true for received) 111 | 112 | > In non-receiving period or snapshot is not triggered in receiving period, ethNum and tokenValue show real-time data. 113 | 114 | > In receiving period or snapshot is triggered, ethNum and tokenValue show snapshot data. 115 | 116 | > When bonus is not received in this period,getEth returns the amount to receive. When bonus is received, getEth returns 0. 117 | 118 | ``` 119 | 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) 120 | ``` 121 | ### Checking fund amount of leveling savings - Nest_3_Leveling 122 | input parameter | type | description 123 | ---|---|--- 124 | token | address | NEST or other NToken address 125 | 126 | returned parameter | type | description 127 | ---|---|--- 128 | ---| uint256 | leveling savings amount (real-time data) 129 | ``` 130 | function checkEthMapping(address token) public view returns (uint256) 131 | ``` 132 | 133 | ### Checking fund amount of bonus pool - Nest_3_Abonus 134 | input parameter | type | description 135 | ---|---|--- 136 | token | address | NEST or other NToken address 137 | 138 | returned parameter | type | description 139 | ---|---|--- 140 | ---| uint256 | bonus pool amount (real-time data) 141 | ``` 142 | function getETHNum(address token) public view returns (uint256) 143 | ``` 144 | -------------------------------------------------------------------------------- /NestOffer/Nest_3_MiningContract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | 6 | /** 7 | * @title Mining contract 8 | * @dev Mining pool + mining logic 9 | */ 10 | contract Nest_3_MiningContract { 11 | 12 | using address_make_payable for address; 13 | using SafeMath for uint256; 14 | 15 | uint256 _blockAttenuation = 2400000; // Block decay time interval 16 | uint256[10] _attenuationAmount; // Mining decay amount 17 | uint256 _afterMiningAmount = 40 ether; // Stable period mining amount 18 | uint256 _firstBlockNum; // Starting mining block 19 | uint256 _latestMining; // Latest offering block 20 | Nest_3_VoteFactory _voteFactory; // Voting contract 21 | ERC20 _nestContract; // NEST contract address 22 | address _offerFactoryAddress; // Offering contract address 23 | 24 | // Current block, current block mining amount 25 | event OreDrawingLog(uint256 nowBlock, uint256 blockAmount); 26 | 27 | /** 28 | * @dev Initialization method 29 | * @param voteFactory voting contract address 30 | */ 31 | constructor(address voteFactory) public { 32 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 33 | _offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain")); 34 | _nestContract = ERC20(address(_voteFactory.checkAddress("nest"))); 35 | // Initiate mining parameters 36 | _firstBlockNum = 6236588; 37 | _latestMining = block.number; 38 | uint256 blockAmount = 400 ether; 39 | for (uint256 i = 0; i < 10; i ++) { 40 | _attenuationAmount[i] = blockAmount; 41 | blockAmount = blockAmount.mul(8).div(10); 42 | } 43 | } 44 | 45 | /** 46 | * @dev Reset voting contract 47 | * @param voteFactory Voting contract address 48 | */ 49 | function changeMapping(address voteFactory) public onlyOwner { 50 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 51 | _offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain")); 52 | _nestContract = ERC20(address(_voteFactory.checkAddress("nest"))); 53 | } 54 | 55 | /** 56 | * @dev Offering mining 57 | * @return Current block mining amount 58 | */ 59 | function oreDrawing() public returns (uint256) { 60 | require(address(msg.sender) == _offerFactoryAddress, "No authority"); 61 | // Update mining amount list 62 | uint256 miningAmount = changeBlockAmountList(); 63 | // Transfer NEST 64 | if (_nestContract.balanceOf(address(this)) < miningAmount){ 65 | miningAmount = _nestContract.balanceOf(address(this)); 66 | } 67 | if (miningAmount > 0) { 68 | _nestContract.transfer(address(msg.sender), miningAmount); 69 | emit OreDrawingLog(block.number,miningAmount); 70 | } 71 | return miningAmount; 72 | } 73 | 74 | /** 75 | * @dev Update mining amount list 76 | */ 77 | function changeBlockAmountList() private returns (uint256) { 78 | uint256 createBlock = _firstBlockNum; 79 | uint256 recentlyUsedBlock = _latestMining; 80 | uint256 attenuationPointNow = block.number.sub(createBlock).div(_blockAttenuation); 81 | uint256 miningAmount = 0; 82 | uint256 attenuation; 83 | if (attenuationPointNow > 9) { 84 | attenuation = _afterMiningAmount; 85 | } else { 86 | attenuation = _attenuationAmount[attenuationPointNow]; 87 | } 88 | miningAmount = attenuation.mul(block.number.sub(recentlyUsedBlock)); 89 | _latestMining = block.number; 90 | return miningAmount; 91 | } 92 | 93 | /** 94 | * @dev Transfer all NEST 95 | * @param target Transfer target address 96 | */ 97 | function takeOutNest(address target) public onlyOwner { 98 | _nestContract.transfer(address(target),_nestContract.balanceOf(address(this))); 99 | } 100 | 101 | // Check block decay time interval 102 | function checkBlockAttenuation() public view returns(uint256) { 103 | return _blockAttenuation; 104 | } 105 | 106 | // Check latest offering block 107 | function checkLatestMining() public view returns(uint256) { 108 | return _latestMining; 109 | } 110 | 111 | // Check mining amount decay 112 | function checkAttenuationAmount(uint256 num) public view returns(uint256) { 113 | return _attenuationAmount[num]; 114 | } 115 | 116 | // Check NEST balance 117 | function checkNestBalance() public view returns(uint256) { 118 | return _nestContract.balanceOf(address(this)); 119 | } 120 | 121 | // Modify block decay time interval 122 | function changeBlockAttenuation(uint256 blockNum) public onlyOwner { 123 | require(blockNum > 0); 124 | _blockAttenuation = blockNum; 125 | } 126 | 127 | // Modify mining amount decay 128 | function changeAttenuationAmount(uint256 firstAmount, uint256 top, uint256 bottom) public onlyOwner { 129 | uint256 blockAmount = firstAmount; 130 | for (uint256 i = 0; i < 10; i ++) { 131 | _attenuationAmount[i] = blockAmount; 132 | blockAmount = blockAmount.mul(top).div(bottom); 133 | } 134 | } 135 | 136 | // Administrator only 137 | modifier onlyOwner(){ 138 | require(_voteFactory.checkOwners(msg.sender), "No authority"); 139 | _; 140 | } 141 | } 142 | 143 | // Voting contract 144 | interface Nest_3_VoteFactory { 145 | // Check address 146 | function checkAddress(string calldata name) external view returns (address contractAddress); 147 | // Check whether administrator 148 | function checkOwners(address man) external view returns (bool); 149 | } 150 | 151 | // EC20 152 | interface ERC20 { 153 | function totalSupply() external view returns (uint256); 154 | function balanceOf(address account) external view returns (uint256); 155 | function transfer(address recipient, uint256 amount) external returns (bool); 156 | function allowance(address owner, address spender) external view returns (uint256); 157 | function approve(address spender, uint256 amount) external returns (bool); 158 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 159 | event Transfer(address indexed from, address indexed to, uint256 value); 160 | event Approval(address indexed owner, address indexed spender, uint256 value); 161 | } -------------------------------------------------------------------------------- /NestOffer/Nest_3_OfferPrice.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | import "../Lib/AddressPayable.sol"; 5 | import "../Lib/SafeERC20.sol"; 6 | 7 | /** 8 | * @title Price contract 9 | * @dev Price check and call 10 | */ 11 | contract Nest_3_OfferPrice{ 12 | using SafeMath for uint256; 13 | using address_make_payable for address; 14 | using SafeERC20 for ERC20; 15 | 16 | Nest_3_VoteFactory _voteFactory; // Voting contract 17 | ERC20 _nestToken; // NestToken 18 | Nest_NToken_TokenMapping _tokenMapping; // NToken mapping 19 | Nest_3_OfferMain _offerMain; // Offering main contract 20 | Nest_3_Abonus _abonus; // Bonus pool 21 | address _nTokeOfferMain; // NToken offering main contract 22 | address _destructionAddress; // Destruction contract address 23 | address _nTokenAuction; // NToken auction contract address 24 | struct PriceInfo { // Block price 25 | uint256 ethAmount; // ETH amount 26 | uint256 erc20Amount; // Erc20 amount 27 | uint256 frontBlock; // Last effective block 28 | address offerOwner; // Offering address 29 | } 30 | struct TokenInfo { // Token offer information 31 | mapping(uint256 => PriceInfo) priceInfoList; // Block price list, block number => block price 32 | uint256 latestOffer; // Latest effective block 33 | } 34 | uint256 destructionAmount = 0 ether; // Amount of NEST to destroy to call prices 35 | uint256 effectTime = 0 days; // Waiting time to start calling prices 36 | mapping(address => TokenInfo) _tokenInfo; // Token offer information 37 | mapping(address => bool) _blocklist; // Block list 38 | mapping(address => uint256) _addressEffect; // Effective time of address to call prices 39 | mapping(address => bool) _offerMainMapping; // Offering contract mapping 40 | uint256 _priceCost = 0.01 ether; // Call price fee 41 | 42 | // Real-time price token, ETH amount, erc20 amount 43 | event NowTokenPrice(address a, uint256 b, uint256 c); 44 | 45 | /** 46 | * @dev Initialization method 47 | * @param voteFactory Voting contract address 48 | */ 49 | constructor (address voteFactory) public { 50 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 51 | _voteFactory = voteFactoryMap; 52 | _offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain"))); 53 | _nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain")); 54 | _abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus"))); 55 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 56 | _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest"))); 57 | _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping"))); 58 | _nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction")); 59 | _offerMainMapping[address(_offerMain)] = true; 60 | _offerMainMapping[address(_nTokeOfferMain)] = true; 61 | } 62 | 63 | /** 64 | * @dev Modify voting contract 65 | * @param voteFactory Voting contract address 66 | */ 67 | function changeMapping(address voteFactory) public onlyOwner { 68 | Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory)); 69 | _voteFactory = voteFactoryMap; 70 | _offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain"))); 71 | _nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain")); 72 | _abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus"))); 73 | _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction")); 74 | _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest"))); 75 | _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping"))); 76 | _nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction")); 77 | _offerMainMapping[address(_offerMain)] = true; 78 | _offerMainMapping[address(_nTokeOfferMain)] = true; 79 | } 80 | 81 | /** 82 | * @dev Initialize token price charge parameters 83 | * @param tokenAddress Token address 84 | */ 85 | function addPriceCost(address tokenAddress) public { 86 | 87 | } 88 | 89 | /** 90 | * @dev Add price 91 | * @param ethAmount ETH amount 92 | * @param tokenAmount Erc20 amount 93 | * @param endBlock Effective price block 94 | * @param tokenAddress Erc20 address 95 | * @param offerOwner Offering address 96 | */ 97 | function addPrice(uint256 ethAmount, uint256 tokenAmount, uint256 endBlock, address tokenAddress, address offerOwner) public onlyOfferMain{ 98 | // Add effective block price information 99 | TokenInfo storage tokenInfo = _tokenInfo[tokenAddress]; 100 | PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock]; 101 | priceInfo.ethAmount = priceInfo.ethAmount.add(ethAmount); 102 | priceInfo.erc20Amount = priceInfo.erc20Amount.add(tokenAmount); 103 | if (endBlock != tokenInfo.latestOffer) { 104 | // If different block offer 105 | priceInfo.frontBlock = tokenInfo.latestOffer; 106 | tokenInfo.latestOffer = endBlock; 107 | } 108 | } 109 | 110 | /** 111 | * @dev Price modification in taker orders 112 | * @param ethAmount ETH amount 113 | * @param tokenAmount Erc20 amount 114 | * @param tokenAddress Token address 115 | * @param endBlock Block of effective price 116 | */ 117 | function changePrice(uint256 ethAmount, uint256 tokenAmount, address tokenAddress, uint256 endBlock) public onlyOfferMain { 118 | TokenInfo storage tokenInfo = _tokenInfo[tokenAddress]; 119 | PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock]; 120 | priceInfo.ethAmount = priceInfo.ethAmount.sub(ethAmount); 121 | priceInfo.erc20Amount = priceInfo.erc20Amount.sub(tokenAmount); 122 | } 123 | 124 | /** 125 | * @dev Update and check the latest price 126 | * @param tokenAddress Token address 127 | * @return ethAmount ETH amount 128 | * @return erc20Amount Erc20 amount 129 | * @return blockNum Price block 130 | */ 131 | function updateAndCheckPriceNow(address tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) { 132 | require(checkUseNestPrice(address(msg.sender))); 133 | mapping(uint256 => PriceInfo) storage priceInfoList = _tokenInfo[tokenAddress].priceInfoList; 134 | uint256 checkBlock = _tokenInfo[tokenAddress].latestOffer; 135 | while(checkBlock > 0 && (checkBlock >= block.number || priceInfoList[checkBlock].ethAmount == 0)) { 136 | checkBlock = priceInfoList[checkBlock].frontBlock; 137 | } 138 | require(checkBlock != 0); 139 | PriceInfo memory priceInfo = priceInfoList[checkBlock]; 140 | address nToken = _tokenMapping.checkTokenMapping(tokenAddress); 141 | if (nToken == address(0x0)) { 142 | _abonus.switchToEth.value(_priceCost)(address(_nestToken)); 143 | } else { 144 | _abonus.switchToEth.value(_priceCost)(address(nToken)); 145 | } 146 | if (msg.value > _priceCost) { 147 | repayEth(address(msg.sender), msg.value.sub(_priceCost)); 148 | } 149 | emit NowTokenPrice(tokenAddress,priceInfo.ethAmount, priceInfo.erc20Amount); 150 | return (priceInfo.ethAmount,priceInfo.erc20Amount, checkBlock); 151 | } 152 | 153 | /** 154 | * @dev Update and check the latest price-internal use 155 | * @param tokenAddress Token address 156 | * @return ethAmount ETH amount 157 | * @return erc20Amount Erc20 amount 158 | */ 159 | function updateAndCheckPricePrivate(address tokenAddress) public view onlyOfferMain returns(uint256 ethAmount, uint256 erc20Amount) { 160 | mapping(uint256 => PriceInfo) storage priceInfoList = _tokenInfo[tokenAddress].priceInfoList; 161 | uint256 checkBlock = _tokenInfo[tokenAddress].latestOffer; 162 | while(checkBlock > 0 && (checkBlock >= block.number || priceInfoList[checkBlock].ethAmount == 0)) { 163 | checkBlock = priceInfoList[checkBlock].frontBlock; 164 | } 165 | if (checkBlock == 0) { 166 | return (0,0); 167 | } 168 | PriceInfo memory priceInfo = priceInfoList[checkBlock]; 169 | return (priceInfo.ethAmount,priceInfo.erc20Amount); 170 | } 171 | 172 | /** 173 | * @dev Update and check the effective price list 174 | * @param tokenAddress Token address 175 | * @param num Number of prices to check 176 | * @return uint256[] price list 177 | */ 178 | function updateAndCheckPriceList(address tokenAddress, uint256 num) public payable returns (uint256[] memory) { 179 | require(checkUseNestPrice(address(msg.sender))); 180 | mapping(uint256 => PriceInfo) storage priceInfoList = _tokenInfo[tokenAddress].priceInfoList; 181 | // Extract data 182 | uint256 length = num.mul(3); 183 | uint256 index = 0; 184 | uint256[] memory data = new uint256[](length); 185 | uint256 checkBlock = _tokenInfo[tokenAddress].latestOffer; 186 | while(index < length && checkBlock > 0){ 187 | if (checkBlock < block.number && priceInfoList[checkBlock].ethAmount != 0) { 188 | // Add return data 189 | data[index++] = priceInfoList[checkBlock].ethAmount; 190 | data[index++] = priceInfoList[checkBlock].erc20Amount; 191 | data[index++] = checkBlock; 192 | } 193 | checkBlock = priceInfoList[checkBlock].frontBlock; 194 | } 195 | require(length == data.length); 196 | // Allocation 197 | address nToken = _tokenMapping.checkTokenMapping(tokenAddress); 198 | if (nToken == address(0x0)) { 199 | _abonus.switchToEth.value(_priceCost)(address(_nestToken)); 200 | } else { 201 | _abonus.switchToEth.value(_priceCost)(address(nToken)); 202 | } 203 | if (msg.value > _priceCost) { 204 | repayEth(address(msg.sender), msg.value.sub(_priceCost)); 205 | } 206 | return data; 207 | } 208 | 209 | // Activate the price checking function 210 | function activation() public { 211 | _nestToken.safeTransferFrom(address(msg.sender), _destructionAddress, destructionAmount); 212 | _addressEffect[address(msg.sender)] = now.add(effectTime); 213 | } 214 | 215 | // Transfer ETH 216 | function repayEth(address accountAddress, uint256 asset) private { 217 | address payable addr = accountAddress.make_payable(); 218 | addr.transfer(asset); 219 | } 220 | 221 | // Check block price - user account only 222 | function checkPriceForBlock(address tokenAddress, uint256 blockNum) public view returns (uint256 ethAmount, uint256 erc20Amount) { 223 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 224 | TokenInfo storage tokenInfo = _tokenInfo[tokenAddress]; 225 | return (tokenInfo.priceInfoList[blockNum].ethAmount, tokenInfo.priceInfoList[blockNum].erc20Amount); 226 | } 227 | 228 | // Check real-time price - user account only 229 | function checkPriceNow(address tokenAddress) public view returns (uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) { 230 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 231 | mapping(uint256 => PriceInfo) storage priceInfoList = _tokenInfo[tokenAddress].priceInfoList; 232 | uint256 checkBlock = _tokenInfo[tokenAddress].latestOffer; 233 | while(checkBlock > 0 && (checkBlock >= block.number || priceInfoList[checkBlock].ethAmount == 0)) { 234 | checkBlock = priceInfoList[checkBlock].frontBlock; 235 | } 236 | if (checkBlock == 0) { 237 | return (0,0,0); 238 | } 239 | PriceInfo storage priceInfo = priceInfoList[checkBlock]; 240 | return (priceInfo.ethAmount,priceInfo.erc20Amount, checkBlock); 241 | } 242 | 243 | // Check whether the price-checking functions can be called 244 | function checkUseNestPrice(address target) public view returns (bool) { 245 | if (!_blocklist[target] && _addressEffect[target] < now && _addressEffect[target] != 0) { 246 | return true; 247 | } else { 248 | return false; 249 | } 250 | } 251 | 252 | // Check whether the address is in the blocklist 253 | function checkBlocklist(address add) public view returns(bool) { 254 | return _blocklist[add]; 255 | } 256 | 257 | // Check the amount of NEST to destroy to call prices 258 | function checkDestructionAmount() public view returns(uint256) { 259 | return destructionAmount; 260 | } 261 | 262 | // Check the waiting time to start calling prices 263 | function checkEffectTime() public view returns (uint256) { 264 | return effectTime; 265 | } 266 | 267 | // Check call price fee 268 | function checkPriceCost() public view returns (uint256) { 269 | return _priceCost; 270 | } 271 | 272 | // Modify the blocklist 273 | function changeBlocklist(address add, bool isBlock) public onlyOwner { 274 | _blocklist[add] = isBlock; 275 | } 276 | 277 | // Amount of NEST to destroy to call price-checking functions 278 | function changeDestructionAmount(uint256 amount) public onlyOwner { 279 | destructionAmount = amount; 280 | } 281 | 282 | // Modify the waiting time to start calling prices 283 | function changeEffectTime(uint256 num) public onlyOwner { 284 | effectTime = num; 285 | } 286 | 287 | // Modify call price fee 288 | function changePriceCost(uint256 num) public onlyOwner { 289 | _priceCost = num; 290 | } 291 | 292 | // Offering contract only 293 | modifier onlyOfferMain(){ 294 | require(_offerMainMapping[address(msg.sender)], "No authority"); 295 | _; 296 | } 297 | 298 | // Vote administrators only 299 | modifier onlyOwner(){ 300 | require(_voteFactory.checkOwners(msg.sender), "No authority"); 301 | _; 302 | } 303 | } 304 | 305 | // Voting contract 306 | interface Nest_3_VoteFactory { 307 | // Check address 308 | function checkAddress(string calldata name) external view returns (address contractAddress); 309 | // Check whether administrator 310 | function checkOwners(address man) external view returns (bool); 311 | } 312 | 313 | // NToken mapping contract 314 | interface Nest_NToken_TokenMapping { 315 | function checkTokenMapping(address token) external view returns (address); 316 | } 317 | 318 | // NEST offer main contract 319 | interface Nest_3_OfferMain { 320 | function checkTokenAllow(address token) external view returns(bool); 321 | } 322 | 323 | // Bonus pool contract 324 | interface Nest_3_Abonus { 325 | function switchToEth(address token) external payable; 326 | } 327 | -------------------------------------------------------------------------------- /NestOffer/README.md: -------------------------------------------------------------------------------- 1 | ## NEST oracle price checking 2 | 3 | ### Description 4 | > The oracle price data is stored in the pricing contract. The pricing contract provides relating interfaces and implemented the charging logic. The address of pricing contract should be queried from voting contract. 5 | 6 | ### Note 7 | 1. `receive` method must be implemented in the contract for receiving the returned ETH. 8 | 9 | ``` 10 | receive() external payable 11 | ``` 12 | 13 | 2. when calling pricing contract, the address must be obtained via NEST vote contract, in case of ineffectiveness after the address of pricing contract changes. 14 | 15 | ``` 16 | Nest_3_OfferPrice _offerPrice = Nest_3_OfferPrice(address(_voteFactory.checkAddress("nest.v3.offerPrice"))); 17 | ``` 18 | 3. The charging standard for the creation of each ERC20 oracle is the same, but may be modified by voting contract. When calling prices, charging standard may changes, to make sure the success callings , there are two methods. 19 | 20 | > Method1:When calling, pay a larger amount of ETH first, the pricing contract will charge the actual fee according to the rules, the excess ETH will be returned to the calling contract, and the receiving of returned ETH should be handled by the calling contract. The specific amount of ETH paid first can be determined according to the upper limit that you can accept. 21 | 22 | > Method2:Before calling the price, check the corresponding charging standard of ERC20 from the price contract, calculate the fee based on the charging rules, and then call the price. 23 | 24 | ``` 25 | // Check call price fee 26 | function checkPriceCost() public view returns (uint256) { 27 | return _priceCost; 28 | } 29 | ``` 30 | 4. Do not implement methods that can publicly check prices (to prevent proxy prices) within the contract. Any method of calling Nest oracle price data is only for internal use of the contract. If it includes a method of publicly checking the price, the contract will be voted by the community to be added to the price calling blacklist, and the contract will not be able to call the Nest oracle price. 31 | 32 | 5. Make sure the erc20 oracle is created and operated normally. 33 | 34 | ### Price generation instruction 35 | #### Pricing block, validation block, effective price block 36 | 37 | Pricing block number is 1,validation block number is between 2 and 26 (taker order available). When the number exceed 26, the pricing assets can be retrieved and the effective price block is 26. After the 26th block, the effective price in 26th will always be returned. 38 | #### Price calculation with multiple offers in a block 39 | The first offer:10ETH, 2000USDT 40 | 41 | The second offer:100ETH,3000USDT 42 | 43 | The calculation of effective price (weighted average):(10ETH + 100ETH) / (2000USDT + 3000USDT) 44 | 45 | ### Method 46 | 47 | #### Activation 48 | 49 | The authorization should be activated before calling prices 50 | 51 | ##### Activation Instruction 52 | There are two preconditions for using Nest oracle prices 53 | 1. 10000 Nest destructed in activation 54 | 2. wait for 1 day 55 | 56 | Nest is required before activation in the third-party contract, but it does not necessarily transfer first, activation can be combined into one transaction。 57 | 58 | 59 | ``` 60 | function activation() public 61 | ``` 62 | 63 | 64 | #### Calling a single price 65 | input parameter | description 66 | ---|--- 67 | tokenAddress | the erc20 address for checking 68 | 69 | output parameter | description 70 | ---|--- 71 | ethAmount | eth amount(total eth amount of offering) 72 | erc20Amount | erc20 amount(total erc20 amount of offering) 73 | blockNum | effective block number 74 | 75 | ``` 76 | function updateAndCheckPriceNow(address tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) 77 | ``` 78 | 79 | #### Checking history price 80 | input parameter | description 81 | ---|--- 82 | tokenAddress | the erc20 address for checking 83 | num | the amount of prices 84 | 85 | output parameter | description 86 | ---|--- 87 | uint256[] memory | price array 88 | 89 | The length of returned array is 3 * num,a price data consist of 3 numbers, respectively the eth amount, the erc20 amount and the effective block number. 90 | 91 | ``` 92 | function updateAndCheckPriceList(address tokenAddress, uint256 num) public payable returns (uint256[] memory) 93 | ``` 94 | 95 | #### Checking the fee(ETH) for obtaining a price 96 | 97 | output parameter | description 98 | ---|--- 99 | --- | the eth fee for obtaining a price 100 | 101 | ``` 102 | function checkPriceCost() public view returns (uint256) 103 | ``` 104 | 105 | ### Demo 106 | ``` 107 | pragma solidity 0.6.0; 108 | 109 | contract Nest_3_GetPrice { 110 | using SafeMath for uint256; 111 | using SafeERC20 for ERC20; 112 | 113 | // Voting contract 114 | Nest_3_VoteFactory _voteFactory; 115 | 116 | event price(uint256 ethAmount, uint256 tokenAmount, uint256 blockNum, uint256 ethMultiple, uint256 tokenForEth); 117 | event averagePrice(uint256 price); 118 | 119 | /** 120 | * @dev Initialization method 121 | * @param voteFactory Voting contract 122 | */ 123 | constructor (address voteFactory) public { 124 | _voteFactory = Nest_3_VoteFactory(address(voteFactory)); 125 | } 126 | 127 | /** 128 | * @dev Get a single price 129 | * @param token Token address of the price 130 | */ 131 | function getSinglePrice(address token) public payable { 132 | // In consideration of future upgrades, the possibility of upgrading the price contract is not ruled out, and the voting contract must be used to query the price contract address. 133 | Nest_3_OfferPrice _offerPrice = Nest_3_OfferPrice(address(_voteFactory.checkAddress("nest.v3.offerPrice"))); 134 | // Request the latest price, return the eth quantity, token quantity, and effective price block number. Tentative fee. 135 | (uint256 ethAmount, uint256 tokenAmount, uint256 blockNum) = _offerPrice.updateAndCheckPriceNow.value(0.001 ether)(token); 136 | uint256 ethMultiple = ethAmount.div(1 ether); 137 | uint256 tokenForEth = tokenAmount.div(ethMultiple); 138 | // If the eth paid for the price is left, it needs to be processed. 139 | // ........ 140 | 141 | emit price(ethAmount, tokenAmount, blockNum, ethMultiple, tokenForEth); 142 | } 143 | 144 | /** 145 | * @dev Get multiple prices 146 | * @param token The token address of the price 147 | * @param priceNum Get the number of prices, sorted from the latest price 148 | */ 149 | function getBatchPrice(address token, uint256 priceNum) public payable { 150 | // In consideration of future upgrades, the possibility of upgrading the price contract is not ruled out, and the voting contract must be used to query the price contract address. 151 | Nest_3_OfferPrice _offerPrice = Nest_3_OfferPrice(address(_voteFactory.checkAddress("nest.v3.offerPrice"))); 152 | /** 153 | * The returned array is an integer multiple of 3, 3 data is a price data. 154 | * Corresponding respectively, eth quantity, token quantity, effective price block number. 155 | */ 156 | uint256[] memory priceData = _offerPrice.updateAndCheckPriceList.value(0.01 ether)(token, priceNum); 157 | // Data processing 158 | uint256 allTokenForEth = 0; 159 | uint256 priceDataNum = priceData.length.div(3); 160 | for (uint256 i = 0; i < priceData.length;) { 161 | uint256 ethMultiple = priceData[i].div(1 ether); 162 | uint256 tokenForEth = priceData[i.add(1)].div(ethMultiple); 163 | allTokenForEth = allTokenForEth.add(tokenForEth); 164 | i = i.add(3); 165 | } 166 | // Average price 167 | uint256 calculationPrice = allTokenForEth.div(priceDataNum); 168 | // If the eth paid for the price is left, it needs to be processed. 169 | // ........ 170 | 171 | 172 | emit averagePrice(calculationPrice); 173 | } 174 | 175 | /** 176 | * @dev Activate the price checking function 177 | * @param nestAddress NestToken address 178 | * @param nestAmount Destroy Nest quantity 179 | */ 180 | function activation(address nestAddress, uint256 nestAmount) public { 181 | // In consideration of future upgrades, the possibility of upgrading the price contract is not ruled out, and the voting contract must be used to query the price contract address. 182 | Nest_3_OfferPrice _offerPrice = Nest_3_OfferPrice(address(_voteFactory.checkAddress("nest.v3.offerPrice"))); 183 | // Authorize Nest to the price contract, the tentative quantity is 10,000 184 | ERC20(nestAddress).safeApprove(address(_offerPrice), nestAmount); 185 | // Activation 186 | _offerPrice.activation(); 187 | } 188 | 189 | // Receive eth method, must be implemented. 190 | receive() external payable { 191 | 192 | } 193 | 194 | } 195 | 196 | // Voting contract 197 | interface Nest_3_VoteFactory { 198 | // Check address 199 | function checkAddress(string calldata name) external view returns (address contractAddress); 200 | } 201 | 202 | // Pricing contract 203 | interface Nest_3_OfferPrice { 204 | /** 205 | * @dev Activate the price checking function 206 | */ 207 | function activation() external; 208 | 209 | /** 210 | * @dev Update and check the latest price 211 | * @param tokenAddress Token address 212 | * @return ethAmount ETH amount 213 | * @return erc20Amount Erc20 amount 214 | * @return blockNum Price block 215 | */ 216 | function updateAndCheckPriceNow(address tokenAddress) external payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum); 217 | /** 218 | * @dev Update and check the effective price list 219 | * @param tokenAddress Token address 220 | * @param num Number of prices to check 221 | * @return uint256[] price list 222 | */ 223 | function updateAndCheckPriceList(address tokenAddress, uint256 num) external payable returns (uint256[] memory); 224 | /** 225 | * @dev Check the cost of obtaining the price 226 | */ 227 | function checkPriceCost() public view returns (uint256); 228 | } 229 | 230 | 231 | library SafeERC20 { 232 | using SafeMath for uint256; 233 | using Address for address; 234 | 235 | function safeTransfer(ERC20 token, address to, uint256 value) internal { 236 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 237 | } 238 | 239 | function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { 240 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 241 | } 242 | 243 | function safeApprove(ERC20 token, address spender, uint256 value) internal { 244 | require((value == 0) || (token.allowance(address(this), spender) == 0), 245 | "SafeERC20: approve from non-zero to non-zero allowance" 246 | ); 247 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 248 | } 249 | 250 | function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal { 251 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 252 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 253 | } 254 | 255 | function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal { 256 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 257 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 258 | } 259 | function callOptionalReturn(ERC20 token, bytes memory data) private { 260 | require(address(token).isContract(), "SafeERC20: call to non-contract"); 261 | (bool success, bytes memory returndata) = address(token).call(data); 262 | require(success, "SafeERC20: low-level call failed"); 263 | if (returndata.length > 0) { 264 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 265 | } 266 | } 267 | } 268 | 269 | interface ERC20 { 270 | function totalSupply() external view returns (uint256); 271 | function balanceOf(address account) external view returns (uint256); 272 | function transfer(address recipient, uint256 amount) external returns (bool); 273 | function allowance(address owner, address spender) external view returns (uint256); 274 | function approve(address spender, uint256 amount) external returns (bool); 275 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 276 | event Transfer(address indexed from, address indexed to, uint256 value); 277 | event Approval(address indexed owner, address indexed spender, uint256 value); 278 | } 279 | 280 | library SafeMath { 281 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 282 | uint256 c = a + b; 283 | require(c >= a, "SafeMath: addition overflow"); 284 | 285 | return c; 286 | } 287 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 288 | return sub(a, b, "SafeMath: subtraction overflow"); 289 | } 290 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 291 | require(b <= a, errorMessage); 292 | uint256 c = a - b; 293 | 294 | return c; 295 | } 296 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 297 | if (a == 0) { 298 | return 0; 299 | } 300 | uint256 c = a * b; 301 | require(c / a == b, "SafeMath: multiplication overflow"); 302 | 303 | return c; 304 | } 305 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 306 | return div(a, b, "SafeMath: division by zero"); 307 | } 308 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 309 | require(b > 0, errorMessage); 310 | uint256 c = a / b; 311 | return c; 312 | } 313 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 314 | return mod(a, b, "SafeMath: modulo by zero"); 315 | } 316 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 317 | require(b != 0, errorMessage); 318 | return a % b; 319 | } 320 | } 321 | 322 | library Address { 323 | function isContract(address account) internal view returns (bool) { 324 | bytes32 codehash; 325 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 326 | assembly { codehash := extcodehash(account) } 327 | return (codehash != accountHash && codehash != 0x0); 328 | } 329 | function sendValue(address payable recipient, uint256 amount) internal { 330 | require(address(this).balance >= amount, "Address: insufficient balance"); 331 | (bool success, ) = recipient.call.value(amount)(""); 332 | require(success, "Address: unable to send value, recipient may have reverted"); 333 | } 334 | } 335 | ``` 336 | -------------------------------------------------------------------------------- /NestToken/IBNEST.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.1; 2 | 3 | library IterableMapping { 4 | struct itmap 5 | { 6 | mapping(address => IndexValue) data; 7 | KeyFlag[] keys; 8 | uint size; 9 | } 10 | struct IndexValue { uint keyIndex; uint value; } 11 | struct KeyFlag { address key; bool deleted; } 12 | function insert(itmap storage self, address key, uint value) public returns (bool replaced) 13 | { 14 | uint keyIndex = self.data[key].keyIndex; 15 | self.data[key].value = value; 16 | if (keyIndex > 0) 17 | return true; 18 | else 19 | { 20 | keyIndex = self.keys.length++; 21 | self.data[key].keyIndex = keyIndex + 1; 22 | self.keys[keyIndex].key = key; 23 | self.size++; 24 | return false; 25 | } 26 | } 27 | function remove(itmap storage self, address key) public returns (bool success) 28 | { 29 | uint keyIndex = self.data[key].keyIndex; 30 | if (keyIndex == 0) 31 | return false; 32 | delete self.data[key]; 33 | self.keys[keyIndex - 1].deleted = true; 34 | self.size --; 35 | } 36 | function contains(itmap storage self, address key) public view returns (bool) 37 | { 38 | return self.data[key].keyIndex > 0; 39 | } 40 | function iterate_start(itmap storage self) public view returns (uint keyIndex) 41 | { 42 | return iterate_next(self, uint(-1)); 43 | } 44 | function iterate_valid(itmap storage self, uint keyIndex) public view returns (bool) 45 | { 46 | return keyIndex < self.keys.length; 47 | } 48 | function iterate_next(itmap storage self, uint keyIndex) public view returns (uint r_keyIndex) 49 | { 50 | keyIndex++; 51 | while (keyIndex < self.keys.length && self.keys[keyIndex].deleted) 52 | keyIndex++; 53 | return keyIndex; 54 | } 55 | function iterate_get(itmap storage self, uint keyIndex) public view returns (address key, uint value) 56 | { 57 | key = self.keys[keyIndex].key; 58 | value = self.data[key].value; 59 | } 60 | function iterate_getValue(itmap storage self, address key) public view returns (uint value) { 61 | return self.data[key].value; 62 | } 63 | } 64 | 65 | /** 66 | * @title SafeMath 67 | * @dev Math operations with safety checks that throw on error 68 | */ 69 | library SafeMath { 70 | 71 | /** 72 | * @dev Multiplies two numbers, throws on overflow. 73 | */ 74 | function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) { 75 | // Gas optimization: this is cheaper than asserting 'a' not being zero, but the 76 | // benefit is lost if 'b' is also tested. 77 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 78 | if (_a == 0) { 79 | return 0; 80 | } 81 | 82 | c = _a * _b; 83 | assert(c / _a == _b); 84 | return c; 85 | } 86 | 87 | /** 88 | * @dev Integer division of two numbers, truncating the quotient. 89 | */ 90 | function div(uint256 _a, uint256 _b) internal pure returns (uint256) { 91 | assert(_b > 0); // Solidity automatically throws when dividing by 0 92 | uint256 c = _a / _b; 93 | assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold 94 | return _a / _b; 95 | } 96 | 97 | /** 98 | * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). 99 | */ 100 | function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { 101 | assert(_b <= _a); 102 | return _a - _b; 103 | } 104 | 105 | /** 106 | * @dev Adds two numbers, throws on overflow. 107 | */ 108 | function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) { 109 | c = _a + _b; 110 | assert(c >= _a); 111 | return c; 112 | } 113 | } 114 | 115 | /** 116 | * @title ERC20Basic 117 | * @dev Simpler version of ERC20 interface 118 | * See https://github.com/ethereum/EIPs/issues/179 119 | */ 120 | contract ERC20Basic { 121 | function totalSupply() public view returns (uint256); 122 | function balanceOf(address _who) public view returns (uint256); 123 | function transfer(address _to, uint256 _value) public returns (bool); 124 | event Transfer(address indexed from, address indexed to, uint256 value); 125 | } 126 | 127 | 128 | /** 129 | * @title Basic token 130 | * @dev Basic version of StandardToken, with no allowances. 131 | */ 132 | contract BasicToken is ERC20Basic { 133 | using SafeMath for uint256; 134 | IterableMapping.itmap balances; 135 | 136 | uint256 internal totalSupply_; 137 | 138 | /** 139 | * @dev Total number of tokens in existence 140 | */ 141 | function totalSupply() public view returns (uint256) { 142 | return totalSupply_; 143 | } 144 | 145 | /** 146 | * @dev Transfer token for a specified address 147 | * @param _to The address to transfer to. 148 | * @param _value The amount to be transferred. 149 | */ 150 | function transfer(address _to, uint256 _value) public returns (bool) { 151 | 152 | require(_value <= IterableMapping.iterate_getValue(balances, msg.sender)); 153 | require(_to != address(0)); 154 | 155 | IterableMapping.insert(balances, msg.sender, IterableMapping.iterate_getValue(balances, msg.sender).sub(_value)); 156 | IterableMapping.insert(balances, _to, IterableMapping.iterate_getValue(balances, _to).add(_value)); 157 | emit Transfer(msg.sender, _to, _value); 158 | return true; 159 | } 160 | 161 | /** 162 | * @dev Gets the balance of the specified address. 163 | * @param _owner The address to query the the balance of. 164 | * @return An uint256 representing the amount owned by the passed address. 165 | */ 166 | function balanceOf(address _owner) public view returns (uint256) { 167 | return IterableMapping.iterate_getValue(balances, _owner); 168 | } 169 | 170 | } 171 | 172 | 173 | 174 | /** 175 | * @title ERC20 interface 176 | * @dev see https://github.com/ethereum/EIPs/issues/20 177 | */ 178 | contract ERC20 is ERC20Basic { 179 | function allowance(address _owner, address _spender) 180 | public view returns (uint256); 181 | 182 | function transferFrom(address _from, address _to, uint256 _value) 183 | public returns (bool); 184 | 185 | function approve(address _spender, uint256 _value) public returns (bool); 186 | event Approval( 187 | address indexed owner, 188 | address indexed spender, 189 | uint256 value 190 | ); 191 | } 192 | 193 | /** 194 | * @title Standard ERC20 token 195 | * 196 | * @dev Implementation of the basic standard token. 197 | * https://github.com/ethereum/EIPs/issues/20 198 | * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol 199 | */ 200 | contract StandardToken is ERC20, BasicToken { 201 | 202 | mapping (address => mapping (address => uint256)) internal allowed; 203 | 204 | 205 | /** 206 | * @dev Transfer tokens from one address to another 207 | * @param _from address The address which you want to send tokens from 208 | * @param _to address The address which you want to transfer to 209 | * @param _value uint256 the amount of tokens to be transferred 210 | */ 211 | function transferFrom( 212 | address _from, 213 | address _to, 214 | uint256 _value 215 | ) 216 | public 217 | returns (bool) 218 | { 219 | 220 | require(_value <= IterableMapping.iterate_getValue(balances, _from)); 221 | // require(_value <= balances[_from]); 222 | require(_value <= allowed[_from][msg.sender]); 223 | require(_to != address(0)); 224 | 225 | IterableMapping.insert(balances, _from, IterableMapping.iterate_getValue(balances, _from).sub(_value)); 226 | IterableMapping.insert(balances, _to, IterableMapping.iterate_getValue(balances, _to).add(_value)); 227 | // balances[_from] = balances[_from].sub(_value); 228 | // balances[_to] = balances[_to].add(_value); 229 | allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); 230 | emit Transfer(_from, _to, _value); 231 | return true; 232 | } 233 | 234 | /** 235 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. 236 | * Beware that changing an allowance with this method brings the risk that someone may use both the old 237 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this 238 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: 239 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 240 | * @param _spender The address which will spend the funds. 241 | * @param _value The amount of tokens to be spent. 242 | */ 243 | function approve(address _spender, uint256 _value) public returns (bool) { 244 | allowed[msg.sender][_spender] = _value; 245 | emit Approval(msg.sender, _spender, _value); 246 | return true; 247 | } 248 | 249 | /** 250 | * @dev Function to check the amount of tokens that an owner allowed to a spender. 251 | * @param _owner address The address which owns the funds. 252 | * @param _spender address The address which will spend the funds. 253 | * @return A uint256 specifying the amount of tokens still available for the spender. 254 | */ 255 | function allowance( 256 | address _owner, 257 | address _spender 258 | ) 259 | public 260 | view 261 | returns (uint256) 262 | { 263 | return allowed[_owner][_spender]; 264 | } 265 | 266 | /** 267 | * @dev Increase the amount of tokens that an owner allowed to a spender. 268 | * approve should be called when allowed[_spender] == 0. To increment 269 | * allowed value is better to use this function to avoid 2 calls (and wait until 270 | * the first transaction is mined) 271 | * From MonolithDAO Token.sol 272 | * @param _spender The address which will spend the funds. 273 | * @param _addedValue The amount of tokens to increase the allowance by. 274 | */ 275 | function increaseApproval( 276 | address _spender, 277 | uint256 _addedValue 278 | ) 279 | public 280 | returns (bool) 281 | { 282 | allowed[msg.sender][_spender] = ( 283 | allowed[msg.sender][_spender].add(_addedValue)); 284 | emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); 285 | return true; 286 | } 287 | 288 | /** 289 | * @dev Decrease the amount of tokens that an owner allowed to a spender. 290 | * approve should be called when allowed[_spender] == 0. To decrement 291 | * allowed value is better to use this function to avoid 2 calls (and wait until 292 | * the first transaction is mined) 293 | * From MonolithDAO Token.sol 294 | * @param _spender The address which will spend the funds. 295 | * @param _subtractedValue The amount of tokens to decrease the allowance by. 296 | */ 297 | function decreaseApproval( 298 | address _spender, 299 | uint256 _subtractedValue 300 | ) 301 | public 302 | returns (bool) 303 | { 304 | uint256 oldValue = allowed[msg.sender][_spender]; 305 | if (_subtractedValue >= oldValue) { 306 | allowed[msg.sender][_spender] = 0; 307 | } else { 308 | allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); 309 | } 310 | emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); 311 | return true; 312 | } 313 | 314 | } 315 | 316 | contract IBNEST is StandardToken { 317 | 318 | string public name = "NEST"; 319 | string public symbol = "NEST"; 320 | uint8 public decimals = 18; 321 | uint256 public INITIAL_SUPPLY = 10000000000 ether; 322 | 323 | constructor () public { 324 | totalSupply_ = INITIAL_SUPPLY; 325 | IterableMapping.insert(balances, tx.origin, INITIAL_SUPPLY); 326 | } 327 | 328 | function balancesStart() public view returns(uint256) { 329 | return IterableMapping.iterate_start(balances); 330 | } 331 | 332 | function balancesGetBool(uint256 num) public view returns(bool){ 333 | return IterableMapping.iterate_valid(balances, num); 334 | } 335 | 336 | function balancesGetNext(uint256 num) public view returns(uint256) { 337 | return IterableMapping.iterate_next(balances, num); 338 | } 339 | 340 | function balancesGetValue(uint256 num) public view returns(address, uint256) { 341 | address key; 342 | uint256 value; 343 | (key, value) = IterableMapping.iterate_get(balances, num); 344 | return (key, value); 345 | } 346 | 347 | } -------------------------------------------------------------------------------- /NodeAssignment/NEST_NodeAssignment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.10; 2 | 3 | import "./SafeMath.sol"; 4 | 5 | /** 6 | * @title Node assignment contract 7 | */ 8 | contract NEST_NodeAssignment { 9 | 10 | using SafeMath for uint256; 11 | IBMapping mappingContract; // Mapping contract 12 | IBNEST nestContract; // NEST contract 13 | SuperMan supermanContract; // NestNode contract 14 | NEST_NodeSave nodeSave; // NestNode save contract 15 | NEST_NodeAssignmentData nodeAssignmentData; // NestNode data assignment contract 16 | 17 | /** 18 | * @dev Initialization method 19 | * @param map Voting contract address 20 | */ 21 | constructor (address map) public { 22 | mappingContract = IBMapping(map); 23 | nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); 24 | supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode"))); 25 | nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave"))); 26 | nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData"))); 27 | } 28 | 29 | /** 30 | * @dev Reset voting contract 31 | * @param map Voting contract address 32 | */ 33 | function changeMapping(address map) public onlyOwner{ 34 | mappingContract = IBMapping(map); 35 | nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); 36 | supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode"))); 37 | nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave"))); 38 | nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData"))); 39 | } 40 | 41 | /** 42 | * @dev Deposit NEST token 43 | * @param amount Amount of deposited NEST 44 | */ 45 | function bookKeeping(uint256 amount) public { 46 | require(amount > 0); 47 | require(nestContract.transferFrom(address(msg.sender), address(nodeSave), amount)); 48 | nodeAssignmentData.addNest(amount); 49 | } 50 | 51 | // NestNode receive and settlement 52 | function nodeGet() public { 53 | require(address(msg.sender) == address(tx.origin)); 54 | require(supermanContract.balanceOf(address(msg.sender)) > 0); 55 | uint256 allAmount = nodeAssignmentData.checkNodeAllAmount(); 56 | uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender))); 57 | uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500); 58 | require(nestContract.balanceOf(address(nodeSave)) >= getAmount); 59 | nodeSave.turnOut(getAmount,address(msg.sender)); 60 | nodeAssignmentData.addNodeLatestAmount(address(msg.sender),allAmount); 61 | } 62 | 63 | // NestNode transfer settlement 64 | function nodeCount(address fromAdd, address toAdd) public { 65 | require(address(supermanContract) == address(msg.sender)); 66 | require(supermanContract.balanceOf(address(fromAdd)) > 0); 67 | uint256 allAmount = nodeAssignmentData.checkNodeAllAmount(); 68 | uint256 amountFrom = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(fromAdd))); 69 | uint256 getAmountFrom = amountFrom.mul(supermanContract.balanceOf(address(fromAdd))).div(1500); 70 | if (nestContract.balanceOf(address(nodeSave)) >= getAmountFrom) { 71 | nodeSave.turnOut(getAmountFrom,address(fromAdd)); 72 | nodeAssignmentData.addNodeLatestAmount(address(fromAdd),allAmount); 73 | } 74 | uint256 amountTo = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(toAdd))); 75 | uint256 getAmountTo = amountTo.mul(supermanContract.balanceOf(address(toAdd))).div(1500); 76 | if (nestContract.balanceOf(address(nodeSave)) >= getAmountTo) { 77 | nodeSave.turnOut(getAmountTo,address(toAdd)); 78 | nodeAssignmentData.addNodeLatestAmount(address(toAdd),allAmount); 79 | } 80 | } 81 | 82 | // NestNode receivable amount 83 | function checkNodeNum() public view returns (uint256) { 84 | uint256 allAmount = nodeAssignmentData.checkNodeAllAmount(); 85 | uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender))); 86 | uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500); 87 | return getAmount; 88 | } 89 | 90 | // Administrator only 91 | modifier onlyOwner(){ 92 | require(mappingContract.checkOwners(msg.sender)); 93 | _; 94 | } 95 | } 96 | 97 | // Mapping contract 98 | contract IBMapping { 99 | // Check address 100 | function checkAddress(string memory name) public view returns (address contractAddress); 101 | // Check whether an administrator 102 | function checkOwners(address man) public view returns (bool); 103 | } 104 | 105 | // NEST node save contract 106 | contract NEST_NodeSave { 107 | function turnOut(uint256 amount, address to) public returns(uint256); 108 | } 109 | 110 | // NestNode assignment data contract 111 | contract NEST_NodeAssignmentData { 112 | function addNest(uint256 amount) public; 113 | function addNodeLatestAmount(address add ,uint256 amount) public; 114 | function checkNodeAllAmount() public view returns (uint256); 115 | function checkNodeLatestAmount(address add) public view returns (uint256); 116 | } 117 | 118 | // NestNode contract 119 | interface SuperMan { 120 | function totalSupply() external view returns (uint256); 121 | function balanceOf(address who) external view returns (uint256); 122 | function allowance(address owner, address spender) external view returns (uint256); 123 | function transfer(address to, uint256 value) external returns (bool); 124 | function approve(address spender, uint256 value) external returns (bool); 125 | function transferFrom(address from, address to, uint256 value) external returns (bool); 126 | event Transfer(address indexed from, address indexed to, uint256 value); 127 | event Approval(address indexed owner, address indexed spender, uint256 value); 128 | } 129 | 130 | // NEST contract 131 | contract IBNEST { 132 | function totalSupply() public view returns (uint supply); 133 | function balanceOf( address who ) public view returns (uint value); 134 | function allowance( address owner, address spender ) public view returns (uint _allowance); 135 | function transfer( address to, uint256 value) external; 136 | function transferFrom( address from, address to, uint value) public returns (bool ok); 137 | function approve( address spender, uint value ) public returns (bool ok); 138 | event Transfer( address indexed from, address indexed to, uint value); 139 | event Approval( address indexed owner, address indexed spender, uint value); 140 | } -------------------------------------------------------------------------------- /NodeAssignment/NEST_NodeAssignmentData.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.10; 2 | 3 | import "./SafeMath.sol"; 4 | 5 | /** 6 | * @title Guardian node receives data 7 | */ 8 | contract NEST_NodeAssignmentData { 9 | using SafeMath for uint256; 10 | IBMapping mappingContract; 11 | uint256 nodeAllAmount = 9546345842385995696603; 12 | mapping(address => uint256) nodeLatestAmount; 13 | 14 | /** 15 | * @dev Initialization method 16 | * @param map Mapping contract address 17 | */ 18 | constructor (address map) public { 19 | mappingContract = IBMapping(map); 20 | } 21 | 22 | /** 23 | * @dev Change mapping contract 24 | * @param map Mapping contract address 25 | */ 26 | function changeMapping(address map) public onlyOwner{ 27 | mappingContract = IBMapping(map); 28 | } 29 | 30 | // Add nest 31 | function addNest(uint256 amount) public onlyNodeAssignment { 32 | nodeAllAmount = nodeAllAmount.add(amount); 33 | } 34 | 35 | // View cumulative total 36 | function checkNodeAllAmount() public view returns (uint256) { 37 | return nodeAllAmount; 38 | } 39 | 40 | // Record last received quantity 41 | function addNodeLatestAmount(address add ,uint256 amount) public onlyNodeAssignment { 42 | nodeLatestAmount[add] = amount; 43 | } 44 | 45 | // View last received quantity 46 | function checkNodeLatestAmount(address add) public view returns (uint256) { 47 | return nodeLatestAmount[address(add)]; 48 | } 49 | 50 | modifier onlyOwner(){ 51 | require(mappingContract.checkOwners(msg.sender) == true); 52 | _; 53 | } 54 | 55 | modifier onlyNodeAssignment(){ 56 | require(address(msg.sender) == address(mappingContract.checkAddress("nodeAssignment"))); 57 | _; 58 | } 59 | } 60 | 61 | contract IBMapping { 62 | function checkAddress(string memory name) public view returns (address contractAddress); 63 | function checkOwners(address man) public view returns (bool); 64 | } -------------------------------------------------------------------------------- /NodeAssignment/NEST_NodeSave.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.10; 2 | 3 | /** 4 | * @title Guardian node nest storage 5 | */ 6 | contract NEST_NodeSave { 7 | IBMapping mappingContract; 8 | IBNEST nestContract; 9 | 10 | /** 11 | * @dev Initialization method 12 | * @param map Mapping contract address 13 | */ 14 | constructor (address map) public { 15 | mappingContract = IBMapping(address(map)); 16 | nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); 17 | } 18 | 19 | /** 20 | * @dev Change mapping contract 21 | * @param map Mapping contract address 22 | */ 23 | function changeMapping(address map) public onlyOwner { 24 | mappingContract = IBMapping(address(map)); 25 | nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); 26 | } 27 | 28 | /** 29 | * @dev Transfer out nest 30 | * @param amount Transfer out quantity 31 | * @param to Transfer out target 32 | * @return Actual transfer out quantity 33 | */ 34 | function turnOut(uint256 amount, address to) public onlyMiningCalculation returns(uint256) { 35 | uint256 leftNum = nestContract.balanceOf(address(this)); 36 | if (leftNum >= amount) { 37 | nestContract.transfer(to, amount); 38 | return amount; 39 | } else { 40 | return 0; 41 | } 42 | } 43 | 44 | modifier onlyOwner(){ 45 | require(mappingContract.checkOwners(msg.sender) == true); 46 | _; 47 | } 48 | 49 | modifier onlyMiningCalculation(){ 50 | require(address(mappingContract.checkAddress("nodeAssignment")) == msg.sender); 51 | _; 52 | } 53 | 54 | } 55 | 56 | contract IBMapping { 57 | function checkAddress(string memory name) public view returns (address contractAddress); 58 | function checkOwners(address man) public view returns (bool); 59 | } 60 | 61 | contract IBNEST { 62 | function totalSupply() public view returns (uint supply); 63 | function balanceOf( address who ) public view returns (uint value); 64 | function allowance( address owner, address spender ) public view returns (uint _allowance); 65 | 66 | function transfer( address to, uint256 value) external; 67 | function transferFrom( address from, address to, uint value) public returns (bool ok); 68 | function approve( address spender, uint value ) public returns (bool ok); 69 | 70 | event Transfer( address indexed from, address indexed to, uint value); 71 | event Approval( address indexed owner, address indexed spender, uint value); 72 | 73 | function balancesStart() public view returns(uint256); 74 | function balancesGetBool(uint256 num) public view returns(bool); 75 | function balancesGetNext(uint256 num) public view returns(uint256); 76 | function balancesGetValue(uint256 num) public view returns(address, uint256); 77 | } -------------------------------------------------------------------------------- /NodeAssignment/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.10; 2 | /** 3 | * @title SafeMath 4 | * @dev Math operations with safety checks that revert on error 5 | */ 6 | library SafeMath { 7 | int256 constant private INT256_MIN = -2**255; 8 | 9 | /** 10 | * @dev Multiplies two unsigned integers, reverts on overflow. 11 | */ 12 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 13 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 14 | // benefit is lost if 'b' is also tested. 15 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 16 | if (a == 0) { 17 | return 0; 18 | } 19 | 20 | uint256 c = a * b; 21 | require(c / a == b); 22 | 23 | return c; 24 | } 25 | 26 | /** 27 | * @dev Multiplies two signed integers, reverts on overflow. 28 | */ 29 | function mul(int256 a, int256 b) internal pure returns (int256) { 30 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 31 | // benefit is lost if 'b' is also tested. 32 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 33 | if (a == 0) { 34 | return 0; 35 | } 36 | 37 | require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below 38 | 39 | int256 c = a * b; 40 | require(c / a == b); 41 | 42 | return c; 43 | } 44 | 45 | /** 46 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. 47 | */ 48 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 49 | // Solidity only automatically asserts when dividing by 0 50 | require(b > 0); 51 | uint256 c = a / b; 52 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 53 | 54 | return c; 55 | } 56 | 57 | /** 58 | * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. 59 | */ 60 | function div(int256 a, int256 b) internal pure returns (int256) { 61 | require(b != 0); // Solidity only automatically asserts when dividing by 0 62 | require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow 63 | 64 | int256 c = a / b; 65 | 66 | return c; 67 | } 68 | 69 | /** 70 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). 71 | */ 72 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 73 | require(b <= a); 74 | uint256 c = a - b; 75 | 76 | return c; 77 | } 78 | 79 | /** 80 | * @dev Subtracts two signed integers, reverts on overflow. 81 | */ 82 | function sub(int256 a, int256 b) internal pure returns (int256) { 83 | int256 c = a - b; 84 | require((b >= 0 && c <= a) || (b < 0 && c > a)); 85 | 86 | return c; 87 | } 88 | 89 | /** 90 | * @dev Adds two unsigned integers, reverts on overflow. 91 | */ 92 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 93 | uint256 c = a + b; 94 | require(c >= a); 95 | 96 | return c; 97 | } 98 | 99 | /** 100 | * @dev Adds two signed integers, reverts on overflow. 101 | */ 102 | function add(int256 a, int256 b) internal pure returns (int256) { 103 | int256 c = a + b; 104 | require((b >= 0 && c >= a) || (b < 0 && c < a)); 105 | 106 | return c; 107 | } 108 | 109 | /** 110 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), 111 | * reverts when dividing by zero. 112 | */ 113 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 114 | require(b != 0); 115 | return a % b; 116 | } 117 | } -------------------------------------------------------------------------------- /NodeAssignment/SuperMan.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.10; 2 | 3 | import "./SafeMath.sol"; 4 | 5 | /** 6 | * @title ERC20 interface 7 | * @dev see https://github.com/ethereum/EIPs/issues/20 8 | */ 9 | interface IERC20 { 10 | function totalSupply() external view returns (uint256); 11 | 12 | function balanceOf(address who) external view returns (uint256); 13 | 14 | function allowance(address owner, address spender) external view returns (uint256); 15 | 16 | function transfer(address to, uint256 value) external returns (bool); 17 | 18 | function approve(address spender, uint256 value) external returns (bool); 19 | 20 | function transferFrom(address from, address to, uint256 value) external returns (bool); 21 | 22 | event Transfer(address indexed from, address indexed to, uint256 value); 23 | 24 | event Approval(address indexed owner, address indexed spender, uint256 value); 25 | 26 | } 27 | 28 | /** 29 | * @title Standard ERC20 token 30 | * 31 | * @dev Implementation of the basic standard token. 32 | * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md 33 | * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol 34 | * 35 | * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for 36 | * all accounts just by listening to said events. Note that this isn't required by the specification, and other 37 | * compliant implementations may not do it. 38 | */ 39 | contract SuperMan is IERC20 { 40 | using SafeMath for uint256; 41 | 42 | mapping (address => uint256) private _balances; 43 | 44 | mapping (address => mapping (address => uint256)) private _allowed; 45 | 46 | IBMapping mappingContract; //映射合约 47 | 48 | uint256 private _totalSupply = 1500; 49 | string public name = "NestNode"; 50 | string public symbol = "NN"; 51 | uint8 public decimals = 0; 52 | 53 | constructor (address map) public { 54 | _balances[msg.sender] = _totalSupply; 55 | mappingContract = IBMapping(map); 56 | } 57 | 58 | function changeMapping(address map) public onlyOwner{ 59 | mappingContract = IBMapping(map); 60 | } 61 | 62 | /** 63 | * @dev Total number of tokens in existence 64 | */ 65 | function totalSupply() public view returns (uint256) { 66 | return _totalSupply; 67 | } 68 | 69 | /** 70 | * @dev Gets the balance of the specified address. 71 | * @param owner The address to query the balance of. 72 | * @return An uint256 representing the amount owned by the passed address. 73 | */ 74 | function balanceOf(address owner) public view returns (uint256) { 75 | return _balances[owner]; 76 | } 77 | 78 | /** 79 | * @dev Function to check the amount of tokens that an owner allowed to a spender. 80 | * @param owner address The address which owns the funds. 81 | * @param spender address The address which will spend the funds. 82 | * @return A uint256 specifying the amount of tokens still available for the spender. 83 | */ 84 | function allowance(address owner, address spender) public view returns (uint256) { 85 | return _allowed[owner][spender]; 86 | } 87 | 88 | /** 89 | * @dev Transfer token for a specified address 90 | * @param to The address to transfer to. 91 | * @param value The amount to be transferred. 92 | */ 93 | function transfer(address to, uint256 value) public returns (bool) { 94 | _transfer(msg.sender, to, value); 95 | return true; 96 | } 97 | 98 | /** 99 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. 100 | * Beware that changing an allowance with this method brings the risk that someone may use both the old 101 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this 102 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: 103 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 104 | * @param spender The address which will spend the funds. 105 | * @param value The amount of tokens to be spent. 106 | */ 107 | function approve(address spender, uint256 value) public returns (bool) { 108 | require(spender != address(0)); 109 | 110 | _allowed[msg.sender][spender] = value; 111 | emit Approval(msg.sender, spender, value); 112 | return true; 113 | } 114 | 115 | /** 116 | * @dev Transfer tokens from one address to another. 117 | * Note that while this function emits an Approval event, this is not required as per the specification, 118 | * and other compliant implementations may not emit the event. 119 | * @param from address The address which you want to send tokens from 120 | * @param to address The address which you want to transfer to 121 | * @param value uint256 the amount of tokens to be transferred 122 | */ 123 | function transferFrom(address from, address to, uint256 value) public returns (bool) { 124 | _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); 125 | _transfer(from, to, value); 126 | emit Approval(from, msg.sender, _allowed[from][msg.sender]); 127 | return true; 128 | } 129 | 130 | /** 131 | * @dev Increase the amount of tokens that an owner allowed to a spender. 132 | * approve should be called when allowed_[_spender] == 0. To increment 133 | * allowed value is better to use this function to avoid 2 calls (and wait until 134 | * the first transaction is mined) 135 | * From MonolithDAO Token.sol 136 | * Emits an Approval event. 137 | * @param spender The address which will spend the funds. 138 | * @param addedValue The amount of tokens to increase the allowance by. 139 | */ 140 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { 141 | require(spender != address(0)); 142 | 143 | _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue); 144 | emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); 145 | return true; 146 | } 147 | 148 | /** 149 | * @dev Decrease the amount of tokens that an owner allowed to a spender. 150 | * approve should be called when allowed_[_spender] == 0. To decrement 151 | * allowed value is better to use this function to avoid 2 calls (and wait until 152 | * the first transaction is mined) 153 | * From MonolithDAO Token.sol 154 | * Emits an Approval event. 155 | * @param spender The address which will spend the funds. 156 | * @param subtractedValue The amount of tokens to decrease the allowance by. 157 | */ 158 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { 159 | require(spender != address(0)); 160 | 161 | _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue); 162 | emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); 163 | return true; 164 | } 165 | 166 | /** 167 | * @dev Transfer token for a specified addresses 168 | * @param from The address to transfer from. 169 | * @param to The address to transfer to. 170 | * @param value The amount to be transferred. 171 | */ 172 | function _transfer(address from, address to, uint256 value) internal { 173 | require(to != address(0)); 174 | 175 | NEST_NodeAssignment nodeAssignment = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment"))); 176 | nodeAssignment.nodeCount(from, to); 177 | 178 | _balances[from] = _balances[from].sub(value); 179 | _balances[to] = _balances[to].add(value); 180 | emit Transfer(from, to, value); 181 | 182 | 183 | } 184 | 185 | modifier onlyOwner(){ 186 | require(mappingContract.checkOwners(msg.sender) == true); 187 | _; 188 | } 189 | } 190 | 191 | contract IBMapping { 192 | function checkAddress(string memory name) public view returns (address contractAddress); 193 | function checkOwners(address man) public view returns (bool); 194 | } 195 | 196 | contract NEST_NodeAssignment { 197 | function nodeCount(address fromAdd, address toAdd) public; 198 | } 199 | 200 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NEST Oracle 3.0 2 | 3 | ## Intro 4 | 5 | The NEST Oracle 3.0 is a solidity smart contract implementation of NEST Protocol which provide a unique on-chain price oracle through a decentralized mechanism. The original idea was described by the white paper [NEST Protocol: A Distributed Price Oracle Network](https://nestprotocol.org/doc/ennestwhitepaper.pdf) 6 | 7 | ## Contributing 8 | 9 | Thank you for considering to help out with the source code! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! 10 | 11 | If you'd like to contribute to NEST Oracle 3.0, please fork, fix, commit and send a pull request for the developers to review and merge into the main code base! 12 | 13 | ## Contract Interface 14 | 15 | ## Contract Addresses 16 | 17 | Contract | Mapping Parameter | Mainnet Address | Ropsten Address 18 | ---|---|---|--- 19 | NEST Token Contract | nest | 0x04abEdA201850aC0124161F037Efd70c74ddC74C | 0xf565422eBd4A8976e1e447a849b8B483C68EFD0C 20 | NEST Vote Contract | | 0x6Cd5698E8854Fb6879d6B1C694223b389B465dea | 0xa43f89dE7f9da44aa4d11106D7b829cf6ac0b561 21 | Mining Pool Contract | nest.v3.miningSave | 0x2f979C933AEF4fCDdD27C0Fa5C54d8a780555b0a | 0x9A558EC0AfcD19c240A31C6Dd697cb15F576d4Ba 22 | NEST Oracle Offering Contract | nest.v3.offerMain | 0xc83E009c7794e8f6d1954dc13c23A35Fc4D039F6 | 0xFf6ad075D75FA51cdB231da54E6dF007E60C7122 23 | NEST Oracle Pricing Contract | nest.v3.offerPrice | 0x94F36FAa6bB4f74009637292b09C355CcD3e80Eb | 0x96E1374383bAC8c03878274d5870346D0d874C30 24 | NestNode Token Contract | nestNode | 0xC028E81e11F374f7c1A3bE6b8D2a815fa3E96E6e | 0x53698FDAAcfA20e5e3c8E074d6CD50D40712344b 25 | NestNode bonus Assignment Contract | nodeAssignment | 0x39D0f58f5D5BBD636be23a3184Aff16a4D7567CF | 0x02402149022cC9aE6696B428fcC1ffcc968c9078 26 | NestNode bonus Data Contract | nodeAssignmentData | 0xb086F99E36c2c0ef6c051EE9E4d638717BBc6cbC | 0x25Ae4523E5C69d3d4863540E29Bf9f11db3DAbcB 27 | NestNode bonus Save Contract | nestNodeSave | 0x101D8b63A081dFfF2B1364864345b7F071b052ac | 0xE9cd4e7Fd807Ec883E612E66108cea33f406b35C 28 | NEST Leveling Contract | nest.v3.tokenSave | 0x03904F4B9Fb54c61AAf96d0aCDD2e42a46c99102 | 0xdC912578B5e8f24b13E79ab072a1E9C86e659694 29 | NEST Bonus pool Contract | nest.v3.abonus | 0x43121397631551357EA511E62163B76e39D44852 | 0x559B1628ee6558EAb5E8a12A8951ecdF6f40EA28 30 | NEST Leveling Contract | nest.v3.leveling | 0xaE2D09D7974a933c6dDC06b8039cF09783f4bAe8 | 0x9e9e49334a4e5506d5DA62e78602547EDf173C67 31 | NEST Token bonus Contract | nest.v3.tokenAbonus | 0x19E1d193A448bD13097EFC2aea867468726e67c5 | 0xDE83944619005d5EE4AAB951199748D599fCff44 32 | nToken Oracle Offering congtract | nest.nToken.offerMain | 0x1542E790a742333EA6A2F171c5d07A2E7794EEf4 | 0x49665947b3Ac4a75DaD7B8E59701752bEc28Ff66 33 | nToken Oracle Auction contract | nest.nToken.tokenAuction | 0x385111F23A00AED181b0774E6900C846c0336dd4 | 0x31914C7F6dfa3428004b60F6327467c5FFffF681 34 | nToken Mapping Contract | nest.nToken.tokenMapping | 0xF9Dc75762fC000f3fb1cF88E7fcc32f9969BA003 | 0x511fe13ca247ceF81332eE27f743E051991008Cb 35 | NEST Token Destruction address | nest.v3.destruction | 0x0000000000000000000000000000000000000001 | 0x0000000000000000000000000000000000000001 36 | 37 | ### to Nest3.5 38 | 39 | Contract | Address 40 | ---|--- 41 | NEST Vote Contract| 0xb3f9b0Cc0B9e7312724AB2a379a6A5ac5b3b7506 42 | 43 | 44 | ## Discussion 45 | 46 | For any concerns with the protocol, open an issue. 47 | For security concerns, please email security@nestprotocol.org. 48 | -------------------------------------------------------------------------------- /VoteContract/Nest_3_VoteFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.0; 2 | 3 | import "../Lib/SafeMath.sol"; 4 | 5 | /** 6 | * @title Voting factory + mapping 7 | * @dev Vote creating method 8 | */ 9 | contract Nest_3_VoteFactory { 10 | using SafeMath for uint256; 11 | 12 | uint256 _limitTime = 7 days; // Vote duration 13 | uint256 _NNLimitTime = 1 days; // NestNode raising time 14 | uint256 _circulationProportion = 51; // Proportion of votes to pass 15 | uint256 _NNUsedCreate = 10; // The minimum number of NNs to create a voting contract 16 | uint256 _NNCreateLimit = 100; // The minimum number of NNs needed to start voting 17 | uint256 _emergencyTime = 0; // The emergency state start time 18 | uint256 _emergencyTimeLimit = 3 days; // The emergency state duration 19 | uint256 _emergencyNNAmount = 1000; // The number of NNs required to switch the emergency state 20 | ERC20 _NNToken; // NestNode Token 21 | ERC20 _nestToken; // NestToken 22 | mapping(string => address) _contractAddress; // Voting contract mapping 23 | mapping(address => bool) _modifyAuthority; // Modify permissions 24 | mapping(address => address) _myVote; // Personal voting address 25 | mapping(address => uint256) _emergencyPerson; // Emergency state personal voting number 26 | mapping(address => bool) _contractData; // Voting contract data 27 | bool _stateOfEmergency = false; // Emergency state 28 | address _destructionAddress; // Destroy contract address 29 | 30 | event ContractAddress(address contractAddress); 31 | 32 | /** 33 | * @dev Initialization method 34 | */ 35 | constructor () public { 36 | _modifyAuthority[address(msg.sender)] = true; 37 | } 38 | 39 | /** 40 | * @dev Reset contract 41 | */ 42 | function changeMapping() public onlyOwner { 43 | _NNToken = ERC20(checkAddress("nestNode")); 44 | _destructionAddress = address(checkAddress("nest.v3.destruction")); 45 | _nestToken = ERC20(address(checkAddress("nest"))); 46 | } 47 | 48 | /** 49 | * @dev Create voting contract 50 | * @param implementContract The executable contract address for voting 51 | * @param nestNodeAmount Number of NNs to pledge 52 | */ 53 | function createVote(address implementContract, uint256 nestNodeAmount) public { 54 | require(address(tx.origin) == address(msg.sender), "It can't be a contract"); 55 | require(nestNodeAmount >= _NNUsedCreate); 56 | Nest_3_VoteContract newContract = new Nest_3_VoteContract(implementContract, _stateOfEmergency, nestNodeAmount); 57 | require(_NNToken.transferFrom(address(tx.origin), address(newContract), nestNodeAmount), "Authorization transfer failed"); 58 | _contractData[address(newContract)] = true; 59 | emit ContractAddress(address(newContract)); 60 | } 61 | 62 | /** 63 | * @dev Use NEST to vote 64 | * @param contractAddress Vote contract address 65 | */ 66 | function nestVote(address contractAddress) public { 67 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 68 | require(_contractData[contractAddress], "It's not a voting contract"); 69 | require(!checkVoteNow(address(msg.sender))); 70 | Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); 71 | newContract.nestVote(); 72 | _myVote[address(tx.origin)] = contractAddress; 73 | } 74 | 75 | /** 76 | * @dev Vote using NestNode Token 77 | * @param contractAddress Vote contract address 78 | * @param NNAmount Amount of NNs to pledge 79 | */ 80 | function nestNodeVote(address contractAddress, uint256 NNAmount) public { 81 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 82 | require(_contractData[contractAddress], "It's not a voting contract"); 83 | Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); 84 | require(_NNToken.transferFrom(address(tx.origin), address(newContract), NNAmount), "Authorization transfer failed"); 85 | newContract.nestNodeVote(NNAmount); 86 | } 87 | 88 | /** 89 | * @dev Excecute contract 90 | * @param contractAddress Vote contract address 91 | */ 92 | function startChange(address contractAddress) public { 93 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 94 | require(_contractData[contractAddress], "It's not a voting contract"); 95 | Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress); 96 | require(_stateOfEmergency == newContract.checkStateOfEmergency()); 97 | addSuperManPrivate(address(newContract)); 98 | newContract.startChange(); 99 | deleteSuperManPrivate(address(newContract)); 100 | } 101 | 102 | /** 103 | * @dev Switch emergency state-transfer in NestNode Token 104 | * @param amount Amount of NNs to transfer 105 | */ 106 | function sendNestNodeForStateOfEmergency(uint256 amount) public { 107 | require(_NNToken.transferFrom(address(tx.origin), address(this), amount)); 108 | _emergencyPerson[address(tx.origin)] = _emergencyPerson[address(tx.origin)].add(amount); 109 | } 110 | 111 | /** 112 | * @dev Switch emergency state-transfer out NestNode Token 113 | */ 114 | function turnOutNestNodeForStateOfEmergency() public { 115 | require(_emergencyPerson[address(tx.origin)] > 0); 116 | require(_NNToken.transfer(address(tx.origin), _emergencyPerson[address(tx.origin)])); 117 | _emergencyPerson[address(tx.origin)] = 0; 118 | uint256 nestAmount = _nestToken.balanceOf(address(this)); 119 | require(_nestToken.transfer(address(_destructionAddress), nestAmount)); 120 | } 121 | 122 | /** 123 | * @dev Modify emergency state 124 | */ 125 | function changeStateOfEmergency() public { 126 | if (_stateOfEmergency) { 127 | require(now > _emergencyTime.add(_emergencyTimeLimit)); 128 | _stateOfEmergency = false; 129 | _emergencyTime = 0; 130 | } else { 131 | require(_emergencyPerson[address(msg.sender)] > 0); 132 | require(_NNToken.balanceOf(address(this)) >= _emergencyNNAmount); 133 | _stateOfEmergency = true; 134 | _emergencyTime = now; 135 | } 136 | } 137 | 138 | /** 139 | * @dev Check whether participating in the voting 140 | * @param user Address to check 141 | * @return bool Whether voting 142 | */ 143 | function checkVoteNow(address user) public view returns (bool) { 144 | if (_myVote[user] == address(0x0)) { 145 | return false; 146 | } else { 147 | Nest_3_VoteContract vote = Nest_3_VoteContract(_myVote[user]); 148 | if (vote.checkContractEffective() || vote.checkPersonalAmount(user) == 0) { 149 | return false; 150 | } 151 | return true; 152 | } 153 | } 154 | 155 | /** 156 | * @dev Check my voting 157 | * @param user Address to check 158 | * @return address Address recently participated in the voting contract address 159 | */ 160 | function checkMyVote(address user) public view returns (address) { 161 | return _myVote[user]; 162 | } 163 | 164 | // Check the voting time 165 | function checkLimitTime() public view returns (uint256) { 166 | return _limitTime; 167 | } 168 | 169 | // Check the NestNode raising time 170 | function checkNNLimitTime() public view returns (uint256) { 171 | return _NNLimitTime; 172 | } 173 | 174 | // Check the voting proportion to pass 175 | function checkCirculationProportion() public view returns (uint256) { 176 | return _circulationProportion; 177 | } 178 | 179 | // Check the minimum number of NNs to create a voting contract 180 | function checkNNUsedCreate() public view returns (uint256) { 181 | return _NNUsedCreate; 182 | } 183 | 184 | // Check the minimum number of NNs raised to start a vote 185 | function checkNNCreateLimit() public view returns (uint256) { 186 | return _NNCreateLimit; 187 | } 188 | 189 | // Check whether in emergency state 190 | function checkStateOfEmergency() public view returns (bool) { 191 | return _stateOfEmergency; 192 | } 193 | 194 | // Check the start time of the emergency state 195 | function checkEmergencyTime() public view returns (uint256) { 196 | return _emergencyTime; 197 | } 198 | 199 | // Check the duration of the emergency state 200 | function checkEmergencyTimeLimit() public view returns (uint256) { 201 | return _emergencyTimeLimit; 202 | } 203 | 204 | // Check the amount of personal pledged NNs 205 | function checkEmergencyPerson(address user) public view returns (uint256) { 206 | return _emergencyPerson[user]; 207 | } 208 | 209 | // Check the number of NNs required for the emergency 210 | function checkEmergencyNNAmount() public view returns (uint256) { 211 | return _emergencyNNAmount; 212 | } 213 | 214 | // Verify voting contract data 215 | function checkContractData(address contractAddress) public view returns (bool) { 216 | return _contractData[contractAddress]; 217 | } 218 | 219 | // Modify voting time 220 | function changeLimitTime(uint256 num) public onlyOwner { 221 | require(num > 0, "Parameter needs to be greater than 0"); 222 | _limitTime = num; 223 | } 224 | 225 | // Modify the NestNode raising time 226 | function changeNNLimitTime(uint256 num) public onlyOwner { 227 | require(num > 0, "Parameter needs to be greater than 0"); 228 | _NNLimitTime = num; 229 | } 230 | 231 | // Modify the voting proportion 232 | function changeCirculationProportion(uint256 num) public onlyOwner { 233 | require(num > 0, "Parameter needs to be greater than 0"); 234 | _circulationProportion = num; 235 | } 236 | 237 | // Modify the minimum number of NNs to create a voting contract 238 | function changeNNUsedCreate(uint256 num) public onlyOwner { 239 | _NNUsedCreate = num; 240 | } 241 | 242 | // Modify the minimum number of NNs to raised to start a voting 243 | function checkNNCreateLimit(uint256 num) public onlyOwner { 244 | _NNCreateLimit = num; 245 | } 246 | 247 | // Modify the emergency state duration 248 | function changeEmergencyTimeLimit(uint256 num) public onlyOwner { 249 | require(num > 0); 250 | _emergencyTimeLimit = num.mul(1 days); 251 | } 252 | 253 | // Modify the number of NNs required for emergency state 254 | function changeEmergencyNNAmount(uint256 num) public onlyOwner { 255 | require(num > 0); 256 | _emergencyNNAmount = num; 257 | } 258 | 259 | // Check address 260 | function checkAddress(string memory name) public view returns (address contractAddress) { 261 | return _contractAddress[name]; 262 | } 263 | 264 | // Add contract mapping address 265 | function addContractAddress(string memory name, address contractAddress) public onlyOwner { 266 | _contractAddress[name] = contractAddress; 267 | } 268 | 269 | // Add administrator address 270 | function addSuperMan(address superMan) public onlyOwner { 271 | _modifyAuthority[superMan] = true; 272 | } 273 | function addSuperManPrivate(address superMan) private { 274 | _modifyAuthority[superMan] = true; 275 | } 276 | 277 | // Delete administrator address 278 | function deleteSuperMan(address superMan) public onlyOwner { 279 | _modifyAuthority[superMan] = false; 280 | } 281 | function deleteSuperManPrivate(address superMan) private { 282 | _modifyAuthority[superMan] = false; 283 | } 284 | 285 | // Delete voting contract data 286 | function deleteContractData(address contractAddress) public onlyOwner { 287 | _contractData[contractAddress] = false; 288 | } 289 | 290 | // Check whether the administrator 291 | function checkOwners(address man) public view returns (bool) { 292 | return _modifyAuthority[man]; 293 | } 294 | 295 | // Administrator only 296 | modifier onlyOwner() { 297 | require(checkOwners(msg.sender), "No authority"); 298 | _; 299 | } 300 | } 301 | 302 | /** 303 | * @title Voting contract 304 | */ 305 | contract Nest_3_VoteContract { 306 | using SafeMath for uint256; 307 | 308 | Nest_3_Implement _implementContract; // Executable contract 309 | Nest_3_TokenSave _tokenSave; // Lock-up contract 310 | Nest_3_VoteFactory _voteFactory; // Voting factory contract 311 | Nest_3_TokenAbonus _tokenAbonus; // Bonus logic contract 312 | ERC20 _nestToken; // NestToken 313 | ERC20 _NNToken; // NestNode Token 314 | address _miningSave; // Mining pool contract 315 | address _implementAddress; // Executable contract address 316 | address _destructionAddress; // Destruction contract address 317 | uint256 _createTime; // Creation time 318 | uint256 _endTime; // End time 319 | uint256 _totalAmount; // Total votes 320 | uint256 _circulation; // Passed votes 321 | uint256 _destroyedNest; // Destroyed NEST 322 | uint256 _NNLimitTime; // NestNode raising time 323 | uint256 _NNCreateLimit; // Minimum number of NNs to create votes 324 | uint256 _abonusTimes; // Period number of used snapshot in emergency state 325 | uint256 _allNNAmount; // Total number of NNs 326 | bool _effective = false; // Whether vote is effective 327 | bool _nestVote = false; // Whether NEST vote can be performed 328 | bool _isChange = false; // Whether NEST vote is executed 329 | bool _stateOfEmergency; // Whether the contract is in emergency state 330 | mapping(address => uint256) _personalAmount; // Number of personal votes 331 | mapping(address => uint256) _personalNNAmount; // Number of NN personal votes 332 | 333 | /** 334 | * @dev Initialization method 335 | * @param contractAddress Executable contract address 336 | * @param stateOfEmergency Whether in emergency state 337 | * @param NNAmount Amount of NNs 338 | */ 339 | constructor (address contractAddress, bool stateOfEmergency, uint256 NNAmount) public { 340 | Nest_3_VoteFactory voteFactory = Nest_3_VoteFactory(address(msg.sender)); 341 | _voteFactory = voteFactory; 342 | _nestToken = ERC20(voteFactory.checkAddress("nest")); 343 | _NNToken = ERC20(voteFactory.checkAddress("nestNode")); 344 | _implementContract = Nest_3_Implement(address(contractAddress)); 345 | _implementAddress = address(contractAddress); 346 | _destructionAddress = address(voteFactory.checkAddress("nest.v3.destruction")); 347 | _personalNNAmount[address(tx.origin)] = NNAmount; 348 | _allNNAmount = NNAmount; 349 | _createTime = now; 350 | _endTime = _createTime.add(voteFactory.checkLimitTime()); 351 | _NNLimitTime = voteFactory.checkNNLimitTime(); 352 | _NNCreateLimit = voteFactory.checkNNCreateLimit(); 353 | _stateOfEmergency = stateOfEmergency; 354 | if (stateOfEmergency) { 355 | // If in emergency state, read the last two periods of bonus lock-up and total circulation data 356 | _tokenAbonus = Nest_3_TokenAbonus(voteFactory.checkAddress("nest.v3.tokenAbonus")); 357 | _abonusTimes = _tokenAbonus.checkTimes().sub(2); 358 | require(_abonusTimes > 0); 359 | _circulation = _tokenAbonus.checkTokenAllValueHistory(address(_nestToken),_abonusTimes).mul(voteFactory.checkCirculationProportion()).div(100); 360 | } else { 361 | _miningSave = address(voteFactory.checkAddress("nest.v3.miningSave")); 362 | _tokenSave = Nest_3_TokenSave(voteFactory.checkAddress("nest.v3.tokenSave")); 363 | _circulation = (uint256(10000000000 ether).sub(_nestToken.balanceOf(address(_miningSave))).sub(_nestToken.balanceOf(address(_destructionAddress)))).mul(voteFactory.checkCirculationProportion()).div(100); 364 | } 365 | if (_allNNAmount >= _NNCreateLimit) { 366 | _nestVote = true; 367 | } 368 | } 369 | 370 | /** 371 | * @dev NEST voting 372 | */ 373 | function nestVote() public onlyFactory { 374 | require(now <= _endTime, "Voting time exceeded"); 375 | require(!_effective, "Vote in force"); 376 | require(_nestVote); 377 | require(_personalAmount[address(tx.origin)] == 0, "Have voted"); 378 | uint256 amount; 379 | if (_stateOfEmergency) { 380 | // If in emergency state, read the last two periods of bonus lock-up and total circulation data 381 | amount = _tokenAbonus.checkTokenSelfHistory(address(_nestToken),_abonusTimes, address(tx.origin)); 382 | } else { 383 | amount = _tokenSave.checkAmount(address(tx.origin), address(_nestToken)); 384 | } 385 | _personalAmount[address(tx.origin)] = amount; 386 | _totalAmount = _totalAmount.add(amount); 387 | ifEffective(); 388 | } 389 | 390 | /** 391 | * @dev NEST voting cancellation 392 | */ 393 | function nestVoteCancel() public { 394 | require(address(msg.sender) == address(tx.origin), "It can't be a contract"); 395 | require(now <= _endTime, "Voting time exceeded"); 396 | require(!_effective, "Vote in force"); 397 | require(_personalAmount[address(tx.origin)] > 0, "No vote"); 398 | _totalAmount = _totalAmount.sub(_personalAmount[address(tx.origin)]); 399 | _personalAmount[address(tx.origin)] = 0; 400 | } 401 | 402 | /** 403 | * @dev NestNode voting 404 | * @param NNAmount Amount of NNs 405 | */ 406 | function nestNodeVote(uint256 NNAmount) public onlyFactory { 407 | require(now <= _createTime.add(_NNLimitTime), "Voting time exceeded"); 408 | require(!_nestVote); 409 | _personalNNAmount[address(tx.origin)] = _personalNNAmount[address(tx.origin)].add(NNAmount); 410 | _allNNAmount = _allNNAmount.add(NNAmount); 411 | if (_allNNAmount >= _NNCreateLimit) { 412 | _nestVote = true; 413 | } 414 | } 415 | 416 | /** 417 | * @dev Withdrawing lock-up NNs 418 | */ 419 | function turnOutNestNode() public { 420 | if (_nestVote) { 421 | // Normal NEST voting 422 | if (!_stateOfEmergency || !_effective) { 423 | // Non-emergency state 424 | require(now > _endTime, "Vote unenforceable"); 425 | } 426 | } else { 427 | // NN voting 428 | require(now > _createTime.add(_NNLimitTime)); 429 | } 430 | require(_personalNNAmount[address(tx.origin)] > 0); 431 | // Reverting back the NNs 432 | require(_NNToken.transfer(address(tx.origin), _personalNNAmount[address(tx.origin)])); 433 | _personalNNAmount[address(tx.origin)] = 0; 434 | // Destroying NEST Tokens 435 | uint256 nestAmount = _nestToken.balanceOf(address(this)); 436 | _destroyedNest = _destroyedNest.add(nestAmount); 437 | require(_nestToken.transfer(address(_destructionAddress), nestAmount)); 438 | } 439 | 440 | /** 441 | * @dev Execute the contract 442 | */ 443 | function startChange() public onlyFactory { 444 | require(!_isChange); 445 | _isChange = true; 446 | if (_stateOfEmergency) { 447 | require(_effective, "Vote unenforceable"); 448 | } else { 449 | require(_effective && now > _endTime, "Vote unenforceable"); 450 | } 451 | // Add the executable contract to the administrator list 452 | _voteFactory.addSuperMan(address(_implementContract)); 453 | // Execute 454 | _implementContract.doit(); 455 | // Delete the authorization 456 | _voteFactory.deleteSuperMan(address(_implementContract)); 457 | } 458 | 459 | /** 460 | * @dev check whether the vote is effective 461 | */ 462 | function ifEffective() private { 463 | if (_totalAmount >= _circulation) { 464 | _effective = true; 465 | } 466 | } 467 | 468 | /** 469 | * @dev Check whether the vote is over 470 | */ 471 | function checkContractEffective() public view returns (bool) { 472 | if (_effective || now > _endTime) { 473 | return true; 474 | } 475 | return false; 476 | } 477 | 478 | // Check the executable implement contract address 479 | function checkImplementAddress() public view returns (address) { 480 | return _implementAddress; 481 | } 482 | 483 | // Check the voting start time 484 | function checkCreateTime() public view returns (uint256) { 485 | return _createTime; 486 | } 487 | 488 | // Check the voting end time 489 | function checkEndTime() public view returns (uint256) { 490 | return _endTime; 491 | } 492 | 493 | // Check the current total number of votes 494 | function checkTotalAmount() public view returns (uint256) { 495 | return _totalAmount; 496 | } 497 | 498 | // Check the number of votes to pass 499 | function checkCirculation() public view returns (uint256) { 500 | return _circulation; 501 | } 502 | 503 | // Check the number of personal votes 504 | function checkPersonalAmount(address user) public view returns (uint256) { 505 | return _personalAmount[user]; 506 | } 507 | 508 | // Check the destroyed NEST 509 | function checkDestroyedNest() public view returns (uint256) { 510 | return _destroyedNest; 511 | } 512 | 513 | // Check whether the contract is effective 514 | function checkEffective() public view returns (bool) { 515 | return _effective; 516 | } 517 | 518 | // Check whether in emergency state 519 | function checkStateOfEmergency() public view returns (bool) { 520 | return _stateOfEmergency; 521 | } 522 | 523 | // Check NestNode raising time 524 | function checkNNLimitTime() public view returns (uint256) { 525 | return _NNLimitTime; 526 | } 527 | 528 | // Check the minimum number of NNs to create a vote 529 | function checkNNCreateLimit() public view returns (uint256) { 530 | return _NNCreateLimit; 531 | } 532 | 533 | // Check the period number of snapshot used in the emergency state 534 | function checkAbonusTimes() public view returns (uint256) { 535 | return _abonusTimes; 536 | } 537 | 538 | // Check number of personal votes 539 | function checkPersonalNNAmount(address user) public view returns (uint256) { 540 | return _personalNNAmount[address(user)]; 541 | } 542 | 543 | // Check the total number of NNs 544 | function checkAllNNAmount() public view returns (uint256) { 545 | return _allNNAmount; 546 | } 547 | 548 | // Check whether NEST voting is available 549 | function checkNestVote() public view returns (bool) { 550 | return _nestVote; 551 | } 552 | 553 | // Check whether it has been excecuted 554 | function checkIsChange() public view returns (bool) { 555 | return _isChange; 556 | } 557 | 558 | // Vote Factory contract only 559 | modifier onlyFactory() { 560 | require(address(_voteFactory) == address(msg.sender), "No authority"); 561 | _; 562 | } 563 | } 564 | 565 | // Executable contract 566 | interface Nest_3_Implement { 567 | // Execute 568 | function doit() external; 569 | } 570 | 571 | // NEST lock-up contract 572 | interface Nest_3_TokenSave { 573 | // Check lock-up amount 574 | function checkAmount(address sender, address token) external view returns (uint256); 575 | } 576 | 577 | // Bonus logic contract 578 | interface Nest_3_TokenAbonus { 579 | // Check NEST circulation snapshot 580 | function checkTokenAllValueHistory(address token, uint256 times) external view returns (uint256); 581 | // Check NEST user balance snapshot 582 | function checkTokenSelfHistory(address token, uint256 times, address user) external view returns (uint256); 583 | // Check bonus ledger period 584 | function checkTimes() external view returns (uint256); 585 | } 586 | 587 | // Erc20 contract 588 | interface ERC20 { 589 | function totalSupply() external view returns (uint256); 590 | function balanceOf(address account) external view returns (uint256); 591 | function transfer(address recipient, uint256 amount) external returns (bool); 592 | function allowance(address owner, address spender) external view returns (uint256); 593 | function approve(address spender, uint256 amount) external returns (bool); 594 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 595 | event Transfer(address indexed from, address indexed to, uint256 value); 596 | event Approval(address indexed owner, address indexed spender, uint256 value); 597 | } 598 | -------------------------------------------------------------------------------- /nToken/nYFI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NEST-Protocol/NEST-Oracle-V3/c311d5e266edf530db7432810efe8b048e0cefbf/nToken/nYFI.png --------------------------------------------------------------------------------