├── contracts ├── BlackHole.sol ├── uniswapv2 │ ├── interfaces │ │ ├── IUniswapV2Callee.sol │ │ ├── IWHT.sol │ │ ├── IWETH.sol │ │ ├── IUniswapV2Factory.sol │ │ ├── IERC20.sol │ │ ├── IUniswapV2ERC20.sol │ │ ├── IUniswapV2Router02.sol │ │ ├── IUniswapV2Pair.sol │ │ └── IUniswapV2Router01.sol │ ├── README.md │ ├── libraries │ │ ├── SafeMath.sol │ │ ├── UQ112x112.sol │ │ ├── Math.sol │ │ ├── TransferHelper.sol │ │ └── UniswapV2Library.sol │ ├── UniswapV2Factory.sol │ └── UniswapV2ERC20.sol ├── interfaces │ ├── IBXH.sol │ └── IMasterChefHeco.sol ├── bridge │ ├── OperatorSet.sol │ └── BXHBridge.sol ├── BXH.sol ├── pairhack.sol ├── BXHDaoRefund.sol ├── XToken.sol ├── Repurchase.sol ├── timelock │ └── TeamTimeLock.sol ├── airdrop.sol ├── BXHLPDelegate.sol ├── StarMaking.sol ├── DelegateERC20.sol ├── BXHDao.sol ├── mocks │ └── ERC20Mock.sol └── BXHDaoPool.sol ├── README.md ├── scripts ├── deploy_blackhole.js ├── transferowner_bxhpool.js ├── transferowner_teamlock.js ├── test_deploy_tokens.js ├── deploy_daov3.js ├── deploy_bxhdelegate.js ├── get_factory_codehash.js ├── deploy_bxhDao.js ├── deploy_airdrop.js ├── deploy_bxhtoken.js ├── deploy_xtoken.js ├── deploy_airdropPool.js ├── deploy_RaiseDAO.js ├── deploy_repurchase.js ├── sync_pair.js ├── deploy_starmaking.js ├── deploy_bxhDaoRefund.js ├── deploy_RaiseDAORescure.js ├── deploy_xdaopool.js ├── teamlock_ownertransfer.js ├── deploy_bxhpool.js ├── create_pairs.js ├── deploy_factory.js ├── deploy_router.js ├── mock_tokens.js ├── mock_transfer_tokens.js ├── deploy_teamlock.js ├── deploy_tokens.js ├── mock_tokens_accountsmint.js ├── test_addliquityNative.js ├── attach_tokens.js ├── test_starmaking.js ├── test_raise_dao.js ├── test_v3bxhDaoPool.js └── test_addliquity.js ├── test ├── BXHPool.testreward.js └── TeamTimeLock.testreward.js ├── LICENSE ├── package.json ├── heco └── genesis.json └── hardhat.config.js /contracts/BlackHole.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.12; 3 | 4 | // This is a black hole contract address 5 | // no one can transfer BXH from the contract 6 | contract BlackHole {} -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2Callee.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2Callee { 6 | function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; 7 | } 8 | -------------------------------------------------------------------------------- /contracts/interfaces/IBXH.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | // SPDX-License-Identifier: MIT 4 | pragma solidity ^0.6.12; 5 | 6 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | 8 | 9 | interface IBXH is IERC20 { 10 | function mint(address to, uint256 amount) external returns (bool); 11 | } -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IWHT.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IWHT { 6 | function deposit() external payable; 7 | function transfer(address to, uint value) external returns (bool); 8 | function withdraw(uint) external; 9 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BXH 2 | 3 | https://bxh.com. 4 | 5 | ## Deployed Contracts 6 | 7 | https://github.com/BXHash/contracts 8 | 9 | 10 | ## Docs 11 | 12 | [Development](docs/DEVELOPMENT.md) 13 | 14 | [Deployment](docs/DEPLOYMENT.md) 15 | 16 | [History](docs/HISTORY.md) 17 | 18 | ## License 19 | 20 | MIT -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IWETH { 6 | function deposit() external payable; 7 | function transfer(address to, uint value) external returns (bool); 8 | function withdraw(uint) external; 9 | } 10 | -------------------------------------------------------------------------------- /contracts/interfaces/IMasterChefHeco.sol: -------------------------------------------------------------------------------- 1 | 2 | // SPDX-License-Identifier: MIT 3 | pragma solidity ^0.6.12; 4 | 5 | 6 | 7 | interface IMasterChefHeco { 8 | function pending(uint256 pid, address user) external view returns (uint256); 9 | 10 | function deposit(uint256 pid, uint256 amount) external; 11 | 12 | function withdraw(uint256 pid, uint256 amount) external; 13 | 14 | function emergencyWithdraw(uint256 pid) external; 15 | } -------------------------------------------------------------------------------- /contracts/uniswapv2/README.md: -------------------------------------------------------------------------------- 1 | # Uniswap V2 Area 2 | 3 | Code from [Uniswap V2](https://github.com/Uniswap/uniswap-v2-core/tree/27f6354bae6685612c182c3bc7577e61bc8717e3/contracts) with the following modifications. 4 | 5 | 1. Change contract version to 0.6.12 and do the necessary patching. 6 | 2. Add `migrator` member in `UniswapV2Factory` which can be set by `feeToSetter`. 7 | 3. Allow `migrator` to specify the amount of `liquidity` during the first mint. Disallow first mint if migrator is set. 8 | 9 | To see all diffs: 10 | 11 | ``` 12 | $ git diff 4c4bf551417e3df09a25aa0dbb6941cccbbac11a . 13 | ``` -------------------------------------------------------------------------------- /contracts/uniswapv2/libraries/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) 6 | 7 | library SafeMathUniswap { 8 | function add(uint x, uint y) internal pure returns (uint z) { 9 | require((z = x + y) >= x, 'ds-math-add-overflow'); 10 | } 11 | 12 | function sub(uint x, uint y) internal pure returns (uint z) { 13 | require((z = x - y) <= x, 'ds-math-sub-underflow'); 14 | } 15 | 16 | function mul(uint x, uint y) internal pure returns (uint z) { 17 | require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/uniswapv2/libraries/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 6 | 7 | // range: [0, 2**112 - 1] 8 | // resolution: 1 / 2**112 9 | 10 | library UQ112x112 { 11 | uint224 constant Q112 = 2**112; 12 | 13 | // encode a uint112 as a UQ112x112 14 | function encode(uint112 y) internal pure returns (uint224 z) { 15 | z = uint224(y) * Q112; // never overflows 16 | } 17 | 18 | // divide a UQ112x112 by a uint112, returning a UQ112x112 19 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 20 | z = x / uint224(y); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/uniswapv2/libraries/Math.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for performing various math operations 6 | 7 | library Math { 8 | function min(uint x, uint y) internal pure returns (uint z) { 9 | z = x < y ? x : y; 10 | } 11 | 12 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 13 | function sqrt(uint y) internal pure returns (uint z) { 14 | if (y > 3) { 15 | z = y; 16 | uint x = y / 2 + 1; 17 | while (x < z) { 18 | z = x; 19 | x = (y / x + x) / 2; 20 | } 21 | } else if (y != 0) { 22 | z = 1; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scripts/deploy_blackhole.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BlackHole = await hre.ethers.getContractFactory("BlackHole"); 17 | const blackHold = await BlackHole.deploy(); 18 | await blackHold.deployed(); 19 | console.log("BlackHole deployed to:", blackHold.address); 20 | 21 | } 22 | 23 | // We recommend this pattern to be able to use async/await everywhere 24 | // and properly handle errors. 25 | main() 26 | .then(() => process.exit(0)) 27 | .catch(error => { 28 | console.error(error); 29 | process.exit(1); 30 | }); 31 | -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2Factory { 6 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 7 | 8 | function feeTo() external view returns (address); 9 | function feeToSetter() external view returns (address); 10 | function migrator() external view returns (address); 11 | 12 | function getPair(address tokenA, address tokenB) external view returns (address pair); 13 | function allPairs(uint) external view returns (address pair); 14 | function allPairsLength() external view returns (uint); 15 | 16 | function createPair(address tokenA, address tokenB) external returns (address pair); 17 | 18 | function setFeeTo(address) external; 19 | function setFeeToSetter(address) external; 20 | function setMigrator(address) external; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IERC20Uniswap { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external view returns (string memory); 10 | function symbol() external view returns (string memory); 11 | function decimals() external view returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | } 20 | -------------------------------------------------------------------------------- /test/BXHPool.testreward.js: -------------------------------------------------------------------------------- 1 | const { ethers ,network} = require("hardhat") 2 | const { expect } = require("chai") 3 | const { time } = require("./utilities") 4 | 5 | 6 | describe("BXHPool", function () { 7 | before(async function () { 8 | 9 | const addrs = network.config.bxh.address; 10 | 11 | 12 | this.BXHPool = await ethers.getContractFactory("BXHPool"); 13 | this.bxhpool = await this.BXHPool.attach(addrs.bxhpool); 14 | 15 | console.log("BXHPool attach to:", this.bxhpool.address); 16 | 17 | }) 18 | 19 | beforeEach(async function () { 20 | 21 | }) 22 | 23 | it("should set loop test state variables", async function () { 24 | for(var i=0;i<30;i++){ 25 | var blocknumer = i*7*24*1200; 26 | var peroidreward = await this.bxhpool.rewardV(blocknumer); 27 | var reward = await this.bxhpool.testBXHBlockRewardV(0,blocknumer); 28 | console.log(i+",peroid.reward="+peroidreward+".total="+reward); 29 | } 30 | }) 31 | 32 | 33 | }) 34 | 35 | -------------------------------------------------------------------------------- /scripts/transferowner_bxhpool.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXHPool = await hre.ethers.getContractFactory("BXHPool"); 17 | const bxhpool = await BXHPool.attach(addrs.bxhpool); 18 | 19 | console.log("BXHPool attached to:", bxhpool.address); 20 | 21 | const owner = await bxhpool.owner(); 22 | 23 | // await bxhpool.transferOwnership("0xdEa9d2E81c9bb73c890A822F65118a3651c258D5"); 24 | 25 | 26 | const newowner = await bxhpool.owner(); 27 | 28 | 29 | console.log("BXHPool owner transfer from:%s to %s", owner,newowner); 30 | 31 | } 32 | 33 | // We recommend this pattern to be able to use async/await everywhere 34 | // and properly handle errors. 35 | main() 36 | .then(() => process.exit(0)) 37 | .catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /scripts/transferowner_teamlock.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXHPool = await hre.ethers.getContractFactory("BXHPool"); 17 | const bxhpool = await BXHPool.attach(addrs.bxhpool); 18 | 19 | console.log("BXHPool attached to:", bxhpool.address); 20 | 21 | const owner = await bxhpool.owner(); 22 | 23 | // await bxhpool.transferOwnership("0xdEa9d2E81c9bb73c890A822F65118a3651c258D5"); 24 | 25 | 26 | const newowner = await bxhpool.owner(); 27 | 28 | 29 | console.log("BXHPool owner transfer from:%s to %s", owner,newowner); 30 | 31 | } 32 | 33 | // We recommend this pattern to be able to use async/await everywhere 34 | // and properly handle errors. 35 | main() 36 | .then(() => process.exit(0)) 37 | .catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /scripts/test_deploy_tokens.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | 19 | const accounts = await ethers.getSigners(); 20 | 21 | 22 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 23 | 24 | const husd = await HUSD.attach(addrs.husd); 25 | 26 | console.log("HUSD attached to:", husd.address); 27 | 28 | await husd.issue(accounts[0].address,10000000); 29 | 30 | const balance = await husd.balanceOf(accounts[0].address); 31 | 32 | 33 | console.log("HUSD.balance=:",balance); 34 | 35 | } 36 | 37 | // We recommend this pattern to be able to use async/await everywhere 38 | // and properly handle errors. 39 | main() 40 | .then(() => process.exit(0)) 41 | .catch(error => { 42 | console.error(error); 43 | process.exit(1); 44 | }); 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 BXH 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /contracts/bridge/OperatorSet.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.12; 4 | 5 | import "@openzeppelin/contracts/utils/EnumerableSet.sol"; 6 | 7 | import "@openzeppelin/contracts/access/Ownable.sol"; 8 | 9 | contract OperatorSet is Ownable{ 10 | 11 | EnumerableSet.AddressSet private opSet; 12 | 13 | 14 | constructor() public { 15 | EnumerableSet.add(opSet,msg.sender); 16 | } 17 | 18 | 19 | modifier onlyOperator() { 20 | 21 | require(EnumerableSet.contains(opSet,msg.sender), "wrong operator"); 22 | _; 23 | } 24 | 25 | function addOperator(address opaddr) public onlyOwner { 26 | EnumerableSet.add(opSet,opaddr); 27 | } 28 | 29 | function operatorCount() public view returns (uint256){ 30 | return EnumerableSet.length(opSet); 31 | } 32 | 33 | 34 | function isOperator(address opaddr) public view returns (bool){ 35 | return EnumerableSet.contains(opSet,opaddr); 36 | } 37 | 38 | 39 | function removeOperator(address opaddr) public onlyOwner { 40 | EnumerableSet.remove(opSet,opaddr); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /scripts/deploy_daov3.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | const web3 = require('web3'); 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | 17 | var provider = ethers.provider; 18 | 19 | const BXHDAOPoolV3 = await hre.ethers.getContractFactory("BXHDAOPoolV3"); 20 | 21 | 22 | const pool = await BXHDAOPoolV3.deploy(addrs.bxh,addrs.usdt,6649690,3600,3600); 23 | await pool.deployed(); 24 | console.log("pool deployed to:", pool.address); 25 | 26 | await pool.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 27 | 28 | 29 | // await pool.addRewards(web3.utils.toWei('100000','wei')); 30 | // await pool.addRewards(web3.utils.toWei('100000','wei')); 31 | 32 | } 33 | 34 | // We recommend this pattern to be able to use async/await everywhere 35 | // and properly handle errors. 36 | main() 37 | .then(() => process.exit(0)) 38 | .catch(error => { 39 | console.error(error); 40 | process.exit(1); 41 | }); 42 | -------------------------------------------------------------------------------- /scripts/deploy_bxhdelegate.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | const web3 = require('web3'); 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | 19 | const accounts = await ethers.getSigners(); 20 | 21 | 22 | const BXHLPDelegate = await hre.ethers.getContractFactory("BXHLPDelegate"); 23 | const deLP = await BXHLPDelegate.deploy("0x6BFe4BE4B1A8BFd0154EEe153936aaCcdc886cD7",addrs.bxhpool,69,"0x56146B129017940D06D8e235c02285A3d05D6B7C"); 24 | 25 | await deLP.deployed(); 26 | console.log("deLP deployed to: ",deLP.address); 27 | 28 | await deLP.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 29 | 30 | console.log("ownership : ",deLP.owner()); 31 | 32 | 33 | } 34 | 35 | // We recommend this pattern to be able to use async/await everywhere 36 | // and properly handle errors. 37 | main() 38 | .then(() => process.exit(0)) 39 | .catch(error => { 40 | console.error(error); 41 | process.exit(1); 42 | }); 43 | -------------------------------------------------------------------------------- /scripts/get_factory_codehash.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 21 | // const factory = await UniswapV2Factory.deploy(feeAdrr); 22 | // await factory.deployed(); 23 | 24 | const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 25 | 26 | console.log("factory attached to:", factory.address); 27 | 28 | // await factory.setFeeTo(feeAdrr); 29 | 30 | const pairCodeHash = await factory.pairCodeHash(); 31 | console.log("factory pairCodeHash is:", pairCodeHash); 32 | 33 | 34 | } 35 | 36 | // We recommend this pattern to be able to use async/await everywhere 37 | // and properly handle errors. 38 | main() 39 | .then(() => process.exit(0)) 40 | .catch(error => { 41 | console.error(error); 42 | process.exit(1); 43 | }); 44 | -------------------------------------------------------------------------------- /scripts/deploy_bxhDao.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | const web3 = require('web3'); 8 | 9 | 10 | 11 | 12 | async function main() { 13 | 14 | const addrs = hre.network.config.bxh.address; 15 | 16 | const accounts = await ethers.getSigners(); 17 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 18 | const bxh = await BXH.attach(addrs.bxh); 19 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 20 | console.log("BXH attached to:", bxh.address); 21 | 22 | 23 | const BXHDao = await hre.ethers.getContractFactory("BXHDao"); 24 | ; 25 | const bxhDao = await BXHDao.deploy("BXH-USDT-30",864000,"0x5121b3a0b9d995c7c11a0a6b65d27133633d1332","0x56146B129017940D06D8e235c02285A3d05D6B7C","0x56146B129017940D06D8e235c02285A3d05D6B7C"); 26 | await bxhDao.deployed(); 27 | console.log("BXHDao deployed to:", bxhDao.address); 28 | 29 | 30 | 31 | } 32 | 33 | // We recommend this pattern to be able to use async/await everywhere 34 | // and properly handle errors. 35 | main() 36 | .then(() => process.exit(0)) 37 | .catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bxh/core", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "types": "./types/index.ts", 6 | "description": "Core contracts for the bxh protocol", 7 | "files": [ 8 | "abi", 9 | "artifacts", 10 | "contracts", 11 | "deployments", 12 | "exports", 13 | "types" 14 | ], 15 | "author": "", 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/bxh/bxh.git" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/bxh/bxh/issues" 22 | }, 23 | "homepage": "https://github.com/bxh/bxh#readme", 24 | "keywords": [ 25 | "bxh", 26 | "ethereum", 27 | "hecochain" 28 | ], 29 | "devDependencies": { 30 | "@nomiclabs/hardhat-ethers": "^2.0.1", 31 | "@nomiclabs/hardhat-etherscan": "^2.1.1", 32 | "@nomiclabs/hardhat-truffle5": "^2.0.0", 33 | "@nomiclabs/hardhat-waffle": "^2.0.1", 34 | "@nomiclabs/hardhat-web3": "^2.0.0", 35 | "@openzeppelin/contracts": "^3.4.0", 36 | "chai": "^4.3.3", 37 | "ethereum-waffle": "^3.3.0", 38 | "ethers": "^5.0.31", 39 | "hardhat": "^2.1.1", 40 | "web3": "^1.3.4" 41 | }, 42 | "dependencies": { 43 | "brewchain_provider": "file:../brewchain_provider" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scripts/deploy_airdrop.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 17 | const bxh = await BXH.attach(addrs.bxh); 18 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 19 | console.log("BXH attached to:", bxh.address); 20 | 21 | 22 | const Airdrop = await hre.ethers.getContractFactory("Airdrop"); 23 | const airdrop = await Airdrop.deploy(addrs.usdt,bxh.address); 24 | await airdrop.deployed(); 25 | console.log("Airdrop deployed to:", airdrop.address); 26 | ; 27 | await airdrop.transferOwnership(addrs.owner); 28 | 29 | const newowner = await airdrop.owner(); 30 | 31 | console.log("Airdrop owner transfer from:%s to %s", owner,newowner); 32 | } 33 | 34 | // We recommend this pattern to be able to use async/await everywhere 35 | // and properly handle errors. 36 | main() 37 | .then(() => process.exit(0)) 38 | .catch(error => { 39 | console.error(error); 40 | process.exit(1); 41 | }); 42 | -------------------------------------------------------------------------------- /scripts/deploy_bxhtoken.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | console.log("deploy account: " + accounts[0].address); 21 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 22 | const bxh = await BXH.deploy(); 23 | await bxh.deployed(); 24 | // const bxh = await BXH.attach(addrs.bxh); 25 | console.log("BXH deployed to:", bxh.address); 26 | 27 | // const owner = await bxh.owner(); 28 | 29 | // await bxh.transferOwnership(addrs.owner); 30 | 31 | // await bxh.owner(); 32 | // const newowner = await bxh.owner(); 33 | // console.log("BXH owner transfer from:%s to %s", owner,newowner); 34 | 35 | 36 | } 37 | 38 | // We recommend this pattern to be able to use async/await everywhere 39 | // and properly handle errors. 40 | main() 41 | .then(() => process.exit(0)) 42 | .catch(error => { 43 | console.error(error); 44 | process.exit(1); 45 | }); 46 | -------------------------------------------------------------------------------- /scripts/deploy_xtoken.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | console.log("deploy account: " + accounts[0].address); 21 | const XToken = await hre.ethers.getContractFactory("XToken"); 22 | const xtoken = await XToken.deploy(); 23 | await xtoken.deployed(); 24 | // const bxh = await BXH.attach(addrs.bxh); 25 | console.log("XToken deployed to:", xtoken.address); 26 | 27 | // const owner = await bxh.owner(); 28 | 29 | // await bxh.transferOwnership(addrs.owner); 30 | 31 | // await bxh.owner(); 32 | // const newowner = await bxh.owner(); 33 | // console.log("BXH owner transfer from:%s to %s", owner,newowner); 34 | 35 | 36 | } 37 | 38 | // We recommend this pattern to be able to use async/await everywhere 39 | // and properly handle errors. 40 | main() 41 | .then(() => process.exit(0)) 42 | .catch(error => { 43 | console.error(error); 44 | process.exit(1); 45 | }); 46 | -------------------------------------------------------------------------------- /scripts/deploy_airdropPool.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 17 | const bxh = await BXH.attach(addrs.bxh); 18 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 19 | console.log("BXH attached to:", bxh.address); 20 | 21 | 22 | const AirdropPool = await hre.ethers.getContractFactory("AirdropPool"); 23 | const airdropPool = await AirdropPool.deploy(bxh.address,28800); 24 | await airdropPool.deployed(); 25 | console.log("AirdropPool deployed to:", airdropPool.address); 26 | ; 27 | 28 | await airdropPool.transferOwnership(addrs.owner); 29 | 30 | const newowner = await airdropPool.owner(); 31 | 32 | console.log("AirdropPool owner transfer to %s", newowner); 33 | } 34 | 35 | // We recommend this pattern to be able to use async/await everywhere 36 | // and properly handle errors. 37 | main() 38 | .then(() => process.exit(0)) 39 | .catch(error => { 40 | console.error(error); 41 | process.exit(1); 42 | }); 43 | -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2ERC20 { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external pure returns (string memory); 10 | function symbol() external pure returns (string memory); 11 | function decimals() external pure returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | 20 | function DOMAIN_SEPARATOR() external view returns (bytes32); 21 | function PERMIT_TYPEHASH() external pure returns (bytes32); 22 | function nonces(address owner) external view returns (uint); 23 | 24 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 25 | } -------------------------------------------------------------------------------- /scripts/deploy_RaiseDAO.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const RaiseDAO = await hre.ethers.getContractFactory("RaiseDAO"); 17 | const raiseDao = await RaiseDAO.deploy(); 18 | 19 | await raiseDao.deployed(); 20 | console.log("RaiseDAO deployed to:", raiseDao.address); 21 | 22 | var provider = ethers.provider; 23 | 24 | await raiseDao.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 25 | 26 | blockNumber = await provider.getBlockNumber(); 27 | blockNumber = await provider.getBlockNumber(); 28 | blockNumber = await provider.getBlockNumber(); 29 | 30 | const newowner = await raiseDao.owner(); 31 | 32 | console.log("RaiseDAO owner transfer from:%s to %s", newowner); 33 | 34 | console.log("current blocknumber=",blockNumber); 35 | // raiseDao.initialize(addrs.usdt,hdot,) 36 | 37 | 38 | } 39 | 40 | // We recommend this pattern to be able to use async/await everywhere 41 | // and properly handle errors. 42 | main() 43 | .then(() => process.exit(0)) 44 | .catch(error => { 45 | console.error(error); 46 | process.exit(1); 47 | }); 48 | -------------------------------------------------------------------------------- /scripts/deploy_repurchase.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | 17 | console.log("deploy account=",accounts[0].address); 18 | const Repurchase = await hre.ethers.getContractFactory("Repurchase"); 19 | 20 | const repurchase = await Repurchase.deploy(1000,"0x56146B129017940D06D8e235c02285A3d05D6B7C"); 21 | 22 | // console.log("deploying account=",repurchase); 23 | 24 | await repurchase.deployed(); 25 | console.log("Repurchase deployed to:", repurchase.address); 26 | 27 | 28 | const owner = await repurchase.owner(); 29 | 30 | // await repurchase.transferOwnership(addrs.owner); 31 | 32 | 33 | // const newowner = await repurchase.owner(); 34 | 35 | 36 | // console.log("repurchase owner transfer from:%s to %s", owner,newowner); 37 | 38 | await repurchase.addCaller(accounts[0].address); 39 | 40 | 41 | 42 | 43 | } 44 | 45 | // We recommend this pattern to be able to use async/await everywhere 46 | // and properly handle errors. 47 | main() 48 | .then(() => process.exit(0)) 49 | .catch(error => { 50 | console.error(error); 51 | process.exit(1); 52 | }); 53 | -------------------------------------------------------------------------------- /scripts/sync_pair.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | async function ensurePair(factory,tokenA,tokenB){ 11 | var pairAddr=await factory.getPair(tokenA,tokenB); 12 | if("0x0000000000000000000000000000000000000000"==pairAddr){ 13 | pairAddr=await factory.createPair(tokenA,tokenB); 14 | console.log("create new pair: (%s,%s)=>%s",tokenA,tokenB,pairAddr) 15 | }else{ 16 | console.log("get exist pair: (%s,%s)=>%s",tokenA,tokenB,pairAddr) 17 | } 18 | 19 | 20 | } 21 | 22 | 23 | 24 | 25 | async function main() { 26 | 27 | const accounts = await ethers.getSigners(); 28 | const addrs = hre.network.config.bxh.address; 29 | 30 | const UniswapV2Pair = await hre.ethers.getContractFactory("UniswapV2Pair"); 31 | const pair = await UniswapV2Pair.attach("0x4eb54a306bbed8540e1751260f7e6402b56c860c"); 32 | 33 | var syncresult = await pair.sync(); 34 | 35 | 36 | console.log("syncresult:",syncresult); 37 | 38 | 39 | 40 | 41 | 42 | } 43 | 44 | // We recommend this pattern to be able to use async/await everywhere 45 | // and properly handle errors. 46 | main() 47 | .then(() => process.exit(0)) 48 | .catch(error => { 49 | console.error(error); 50 | process.exit(1); 51 | }); 52 | -------------------------------------------------------------------------------- /scripts/deploy_starmaking.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | const web3 = require('web3'); 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | var provider = ethers.provider; 15 | const accounts = await ethers.getSigners(); 16 | const StarMaking = await hre.ethers.getContractFactory("StarMaking"); 17 | 18 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 19 | const bxh = await BXH.attach(addrs.bxh); 20 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 21 | console.log("BXH attached to:", bxh.address); 22 | 23 | const star = await StarMaking.deploy(addrs.admin,bxh.address); 24 | await star.deployed(); 25 | console.log("StarMaking deployed to:", star.address); 26 | const owner = await star.owner(); 27 | 28 | await star.transferOwnership(addrs.admin); 29 | 30 | 31 | await star.owner(); 32 | const newowner = await star.owner(); 33 | 34 | console.log("StarMaking owner transfer from:%s to %s", owner,newowner); 35 | 36 | } 37 | 38 | // We recommend this pattern to be able to use async/await everywhere 39 | // and properly handle errors. 40 | main() 41 | .then(() => process.exit(0)) 42 | .catch(error => { 43 | console.error(error); 44 | process.exit(1); 45 | }); 46 | -------------------------------------------------------------------------------- /scripts/deploy_bxhDaoRefund.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | const web3 = require('web3'); 8 | 9 | 10 | 11 | 12 | async function main() { 13 | 14 | const addrs = hre.network.config.bxh.address; 15 | 16 | const accounts = await ethers.getSigners(); 17 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 18 | const bxh = await BXH.attach(addrs.bxh); 19 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 20 | console.log("BXH attached to:", bxh.address); 21 | 22 | 23 | const BXHDaoRefund = await hre.ethers.getContractFactory("BXHDaoRefund"); 24 | ; 25 | const bxhDaoRefund = await BXHDaoRefund.deploy(bxh.address,"0x569Ef8E5EbEF3D6807aA9Faf232FAb5272CE65D4",addrs.admin1); 26 | await bxhDaoRefund.deployed(); 27 | console.log("BXHDaoRefund deployed to:", bxhDaoRefund.address); 28 | 29 | await bxhDaoRefund.transferOwnership(addrs.admin1); 30 | 31 | var newowner = await bxhDaoRefund.owner(); 32 | newowner = await bxhDaoRefund.owner(); 33 | console.log("BXHDaoRefund owner to to:", newowner); 34 | 35 | 36 | } 37 | 38 | // We recommend this pattern to be able to use async/await everywhere 39 | // and properly handle errors. 40 | main() 41 | .then(() => process.exit(0)) 42 | .catch(error => { 43 | console.error(error); 44 | process.exit(1); 45 | }); 46 | -------------------------------------------------------------------------------- /scripts/deploy_RaiseDAORescure.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const RaiseDAORescure = await hre.ethers.getContractFactory("RaiseDAORescure"); 17 | const raiseDaoRescure = await RaiseDAORescure.deploy(); 18 | 19 | await raiseDaoRescure.deployed(); 20 | console.log("RaiseDAORescure deployed to:", raiseDaoRescure.address); 21 | 22 | var provider = ethers.provider; 23 | 24 | await raiseDaoRescure.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 25 | 26 | blockNumber = await provider.getBlockNumber(); 27 | blockNumber = await provider.getBlockNumber(); 28 | 29 | 30 | const newowner = await raiseDaoRescure.owner(); 31 | 32 | console.log("RaiseDAO owner transfer from:%s to %s", newowner); 33 | 34 | blockNumber = await provider.getBlockNumber(); 35 | console.log("current blocknumber=",blockNumber); 36 | // raiseDao.initialize(addrs.usdt,hdot,) 37 | 38 | 39 | } 40 | 41 | // We recommend this pattern to be able to use async/await everywhere 42 | // and properly handle errors. 43 | main() 44 | .then(() => process.exit(0)) 45 | .catch(error => { 46 | console.error(error); 47 | process.exit(1); 48 | }); 49 | -------------------------------------------------------------------------------- /scripts/deploy_xdaopool.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | const web3 = require('web3'); 8 | 9 | 10 | 11 | 12 | async function main() { 13 | 14 | const addrs = hre.network.config.bxh.address; 15 | 16 | const accounts = await ethers.getSigners(); 17 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 18 | const bxh = await BXH.attach(addrs.bxh); 19 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 20 | console.log("BXH attached to:", bxh.address); 21 | 22 | 23 | 24 | const XToken = await hre.ethers.getContractFactory("XToken"); 25 | 26 | const xtoken = await XToken.attach(addrs.xtoken); 27 | 28 | 29 | const BXHDAOPool = await hre.ethers.getContractFactory("BXHDAOPool"); 30 | 31 | 32 | const bxhDaoPool = await BXHDAOPool.deploy(xtoken.address,bxh.address,addrs.usdt,1625486400); 33 | await bxhDaoPool.deployed(); 34 | console.log("BXHDAOPool deployed to:", bxhDaoPool.address); 35 | 36 | await bxhDaoPool.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 37 | 38 | // await xtoken.transferOwnership("0x56146B129017940D06D8e235c02285A3d05D6B7C"); 39 | 40 | 41 | } 42 | 43 | // We recommend this pattern to be able to use async/await everywhere 44 | // and properly handle errors. 45 | main() 46 | .then(() => process.exit(0)) 47 | .catch(error => { 48 | console.error(error); 49 | process.exit(1); 50 | }); 51 | -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.6.2; 4 | 5 | import './IUniswapV2Router01.sol'; 6 | 7 | interface IUniswapV2Router02 is IUniswapV2Router01 { 8 | function removeLiquidityHTSupportingFeeOnTransferTokens( 9 | address token, 10 | uint liquidity, 11 | uint amountTokenMin, 12 | uint amountHTMin, 13 | address to, 14 | uint deadline 15 | ) external returns (uint amountHT); 16 | function removeLiquidityHTWithPermitSupportingFeeOnTransferTokens( 17 | address token, 18 | uint liquidity, 19 | uint amountTokenMin, 20 | uint amountHTMin, 21 | address to, 22 | uint deadline, 23 | bool approveMax, uint8 v, bytes32 r, bytes32 s 24 | ) external returns (uint amountHT); 25 | 26 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 27 | uint amountIn, 28 | uint amountOutMin, 29 | address[] calldata path, 30 | address to, 31 | uint deadline 32 | ) external; 33 | function swapExactHTForTokensSupportingFeeOnTransferTokens( 34 | uint amountOutMin, 35 | address[] calldata path, 36 | address to, 37 | uint deadline 38 | ) external payable; 39 | function swapExactTokensForHTSupportingFeeOnTransferTokens( 40 | uint amountIn, 41 | uint amountOutMin, 42 | address[] calldata path, 43 | address to, 44 | uint deadline 45 | ) external; 46 | } -------------------------------------------------------------------------------- /scripts/teamlock_ownertransfer.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 17 | const bxh = await BXH.attach(addrs.bxh); 18 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 19 | console.log("BXH Attach to:", bxh.address); 20 | 21 | 22 | const TeamTimeLock = await hre.ethers.getContractFactory("TeamTimeLock"); 23 | // console.log("reward=",3000*10000*10e18/20736000); 24 | const investTeamLock = await TeamTimeLock.attach(addrs.investTeamLock); 25 | console.log("investTeamLock attached to:", investTeamLock.address); 26 | await investTeamLock.transferOwnership(addrs.owner); 27 | 28 | 29 | const marketTeamLock = await TeamTimeLock.attach(addrs.marketTeamLock); 30 | console.log("marketTeamLock attached to:", marketTeamLock.address); 31 | await marketTeamLock.transferOwnership(addrs.owner); 32 | 33 | const devTeamLock = await TeamTimeLock.attach(addrs.devTeamLock); 34 | console.log("devTeamLock attached to:", devTeamLock.address); 35 | await devTeamLock.transferOwnership(addrs.owner); 36 | 37 | } 38 | 39 | // We recommend this pattern to be able to use async/await everywhere 40 | // and properly handle errors. 41 | main() 42 | .then(() => process.exit(0)) 43 | .catch(error => { 44 | console.error(error); 45 | process.exit(1); 46 | }); 47 | -------------------------------------------------------------------------------- /contracts/uniswapv2/libraries/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.6.0; 4 | 5 | // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false 6 | library TransferHelper { 7 | function safeApprove(address token, address to, uint value) internal { 8 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 9 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 10 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 11 | } 12 | 13 | function safeTransfer(address token, address to, uint value) internal { 14 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 15 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 16 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 17 | } 18 | 19 | function safeTransferFrom(address token, address from, address to, uint value) internal { 20 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 21 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 22 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 23 | } 24 | 25 | function safeTransferHT(address to, uint value) internal { 26 | (bool success,) = to.call{value:value}(new bytes(0)); 27 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/deploy_bxhpool.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | const web3 = require('web3'); 8 | 9 | 10 | 11 | 12 | async function main() { 13 | 14 | const addrs = hre.network.config.bxh.address; 15 | 16 | const accounts = await ethers.getSigners(); 17 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 18 | const bxh = await BXH.attach(addrs.bxh); 19 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 20 | console.log("BXH attached to:", bxh.address); 21 | 22 | 23 | const BXHPool = await hre.ethers.getContractFactory("BXHPool"); 24 | var amount = web3.utils.toWei('100','ether'); 25 | // const bxhpool = await BXHPool.deploy(bxh.address,amount,3196000,970); 26 | 27 | var provider = ethers.provider; 28 | var blocknumber = await provider.getBlockNumber(); 29 | 30 | 31 | // const bxhpool = await BXHPool.deploy(bxh.address,amount,blocknumber,970); 32 | // await bxhpool.deployed(); 33 | const bxhpool = await BXHPool.attach(addrs.bxhpool); 34 | // console.log("BXHPool deployed to:", bxhpool.address); 35 | ; 36 | 37 | await bxh.addMinter(bxhpool.address); 38 | console.log("pool is minter ",await bxh.isMinter(bxhpool.address)); 39 | 40 | 41 | // await bxhpool.transferOwnership(addrs.owner); 42 | 43 | // const newowner = await bxhpool.owner(); 44 | 45 | // console.log("BXHPool owner transfer from:%s to %s", owner,newowner); 46 | 47 | 48 | } 49 | 50 | // We recommend this pattern to be able to use async/await everywhere 51 | // and properly handle errors. 52 | main() 53 | .then(() => process.exit(0)) 54 | .catch(error => { 55 | console.error(error); 56 | process.exit(1); 57 | }); 58 | -------------------------------------------------------------------------------- /scripts/create_pairs.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | async function ensurePair(factory,tokenA,tokenB){ 11 | var pairAddr=await factory.getPair(tokenA,tokenB); 12 | if("0x0000000000000000000000000000000000000000"==pairAddr){ 13 | pairAddr=await factory.createPair(tokenA,tokenB); 14 | console.log("create new pair: (%s,%s)=>%s",tokenA,tokenB,pairAddr) 15 | }else{ 16 | console.log("get exist pair: (%s,%s)=>%s",tokenA,tokenB,pairAddr) 17 | } 18 | 19 | 20 | } 21 | 22 | 23 | 24 | 25 | async function main() { 26 | 27 | const accounts = await ethers.getSigners(); 28 | const addrs = hre.network.config.bxh.address; 29 | 30 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 31 | const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 32 | 33 | await ensurePair(factory,addrs.usdt,addrs.husd); 34 | await ensurePair(factory,addrs.usdt,addrs.wht); 35 | await ensurePair(factory,addrs.usdt,addrs.hbtc); 36 | 37 | await ensurePair(factory,addrs.hbtc,addrs.husd); 38 | await ensurePair(factory,addrs.heth,addrs.husd); 39 | await ensurePair(factory,addrs.wht,addrs.husd); 40 | await ensurePair(factory,addrs.hbtc,addrs.wht); 41 | await ensurePair(factory,addrs.heth,addrs.wht); 42 | 43 | await ensurePair(factory,addrs.hltc,addrs.husd); 44 | await ensurePair(factory,addrs.hdot,addrs.husd); 45 | 46 | await ensurePair(factory,addrs.bxh,addrs.usdt); 47 | await ensurePair(factory,addrs.bxh,addrs.husd); 48 | await ensurePair(factory,addrs.bxh,addrs.wht); 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | } 57 | 58 | // We recommend this pattern to be able to use async/await everywhere 59 | // and properly handle errors. 60 | main() 61 | .then(() => process.exit(0)) 62 | .catch(error => { 63 | console.error(error); 64 | process.exit(1); 65 | }); 66 | -------------------------------------------------------------------------------- /scripts/deploy_factory.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | const web3 = require('web3'); 7 | 8 | 9 | 10 | 11 | 12 | async function main() { 13 | 14 | const feeAdrr = hre.network.config.bxh.address.fee; 15 | console.log("fee to :",feeAdrr); 16 | 17 | const addrs = hre.network.config.bxh.address; 18 | 19 | const accounts = await ethers.getSigners(); 20 | 21 | console.log("deploy account: " + accounts[0].address); 22 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 23 | // const bxh = await BXH.deploy(); 24 | // await bxh.deployed(); 25 | const bxh = await BXH.attach(addrs.bxh); 26 | 27 | console.log("BXH attached to:", bxh.address); 28 | 29 | 30 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 31 | 32 | const usdt = await ERC20Template.attach(addrs.usdt); 33 | Assert.equal("USDT",await usdt.symbol(),"Contract Attach Error"); 34 | console.log("USDT attached to:", usdt.address); 35 | 36 | 37 | const wht = await ERC20Template.attach(hre.network.config.bxh.address.wht); 38 | Assert.equal("WHT",await wht.symbol()); 39 | console.log("WHT attached to:", wht.address); 40 | 41 | 42 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 43 | const factory = await UniswapV2Factory.deploy(accounts[0].address); 44 | await factory.deployed(); 45 | // const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 46 | 47 | console.log("factory deployed to:", factory.address); 48 | 49 | // await factory.setFeeToSetter(accounts[9].address); 50 | await factory.setFeeTo(accounts[11].address); 51 | 52 | // console.log("factory setfee to:", feeAdrr); 53 | 54 | console.log("factory fee to:", await factory.feeTo()); 55 | 56 | } 57 | 58 | // We recommend this pattern to be able to use async/await everywhere 59 | // and properly handle errors. 60 | main() 61 | .then(() => process.exit(0)) 62 | .catch(error => { 63 | console.error(error); 64 | process.exit(1); 65 | }); 66 | -------------------------------------------------------------------------------- /scripts/deploy_router.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | console.log("deploy account: " + accounts[0].address); 21 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 22 | // const bxh = await BXH.deploy(); 23 | // await bxh.deployed(); 24 | const bxh = await BXH.attach(addrs.bxh); 25 | 26 | console.log("BXH attached to:", bxh.address); 27 | 28 | 29 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 30 | 31 | const usdt = await ERC20Template.attach(addrs.usdt); 32 | Assert.equal("USDT",await usdt.symbol(),"Contract Attach Error"); 33 | console.log("USDT attached to:", usdt.address); 34 | 35 | 36 | const wht = await ERC20Template.attach(hre.network.config.bxh.address.wht); 37 | Assert.equal("WHT",await wht.symbol()); 38 | console.log("WHT attached to:", wht.address); 39 | 40 | 41 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 42 | // const factory = await UniswapV2Factory.deploy(feeAdrr); 43 | // await factory.deployed(); 44 | 45 | const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 46 | 47 | console.log("factory attached to:", factory.address); 48 | 49 | // await factory.setFeeTo(feeAdrr); 50 | 51 | const pairCodeHash = await factory.pairCodeHash(); 52 | console.log("factory pairCodeHash is:", pairCodeHash); 53 | 54 | const UniswapV2Router02 = await hre.ethers.getContractFactory("UniswapV2Router02"); 55 | const router = await UniswapV2Router02.deploy(factory.address,wht.address); 56 | await router.deployed(); 57 | console.log("router deployed to:", router.address); 58 | 59 | } 60 | 61 | // We recommend this pattern to be able to use async/await everywhere 62 | // and properly handle errors. 63 | main() 64 | .then(() => process.exit(0)) 65 | .catch(error => { 66 | console.error(error); 67 | process.exit(1); 68 | }); 69 | -------------------------------------------------------------------------------- /scripts/mock_tokens.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | 6 | 7 | 8 | async function main() { 9 | 10 | const accounts = await ethers.getSigners(); 11 | // for (const account of accounts) { 12 | // // const balance = await ethers.provider.getBalance(account.address); 13 | 14 | // // console.log(account.address+",balance="+balance); 15 | // } 16 | 17 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 18 | const usdt = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg USDT Token","USDT",18); 19 | await usdt.deployed(); 20 | console.log("USDT deployed to:", usdt.address); 21 | 22 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 23 | 24 | const husd = await HUSD.deploy("Heco-Peg HUSD Token","HUSD",8); 25 | 26 | await husd.deployed(); 27 | console.log("HUSD deployed to: %s ,%d", husd.address, await husd.decimals()); 28 | 29 | 30 | const hbtc = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HBTC Token","HBTC",18); 31 | await hbtc.deployed(); 32 | console.log("HBTC deployed to:", hbtc.address); 33 | 34 | const eth = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg ETH Token","ETH",18); 35 | await eth.deployed(); 36 | console.log("HETH deployed to:", eth.address); 37 | 38 | const hltc = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HLTC Token","HLTC",18); 39 | await hltc.deployed(); 40 | console.log("HLTC deployed to:", hltc.address); 41 | 42 | const WHT = await hre.ethers.getContractFactory("WHT"); 43 | const wht = await WHT.deploy(); 44 | await wht.deployed(); 45 | console.log("WHT deployed to:", wht.address); 46 | 47 | const hdot = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HDOT Token","HDOT",18); 48 | await hdot.deployed(); 49 | console.log("HDOT deployed to:", hdot.address); 50 | 51 | 52 | 53 | } 54 | 55 | // We recommend this pattern to be able to use async/await everywhere 56 | // and properly handle errors. 57 | main() 58 | .then(() => process.exit(0)) 59 | .catch(error => { 60 | console.error(error); 61 | process.exit(1); 62 | }); 63 | -------------------------------------------------------------------------------- /scripts/mock_transfer_tokens.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | 6 | 7 | 8 | async function main() { 9 | 10 | const accounts = await ethers.getSigners(); 11 | // for (const account of accounts) { 12 | // // const balance = await ethers.provider.getBalance(account.address); 13 | 14 | // // console.log(account.address+",balance="+balance); 15 | // } 16 | 17 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 18 | const usdt = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg USDT Token","USDT",18); 19 | await usdt.deployed(); 20 | console.log("USDT deployed to:", usdt.address); 21 | 22 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 23 | 24 | const husd = await HUSD.deploy("Heco-Peg HUSD Token","HUSD",8); 25 | 26 | await husd.deployed(); 27 | console.log("HUSD deployed to:%s,%d", husd.address, await husd.decimals()); 28 | 29 | 30 | const hbtc = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HBTC Token","HBTC",18); 31 | await hbtc.deployed(); 32 | console.log("HBTC deployed to:", hbtc.address); 33 | 34 | const eth = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg ETH Token","ETH",18); 35 | await eth.deployed(); 36 | console.log("HETH deployed to:", eth.address); 37 | 38 | const hltc = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HLTC Token","HLTC",18); 39 | await hltc.deployed(); 40 | console.log("HLTC deployed to:", hltc.address); 41 | 42 | const WHT = await hre.ethers.getContractFactory("WHT"); 43 | const wht = await WHT.deploy(); 44 | await wht.deployed(); 45 | console.log("WHT deployed to:", wht.address); 46 | 47 | const hdot = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HDOT Token","HDOT",18); 48 | await hdot.deployed(); 49 | console.log("HDOT deployed to:", hdot.address); 50 | 51 | 52 | 53 | } 54 | 55 | // We recommend this pattern to be able to use async/await everywhere 56 | // and properly handle errors. 57 | main() 58 | .then(() => process.exit(0)) 59 | .catch(error => { 60 | console.error(error); 61 | process.exit(1); 62 | }); 63 | -------------------------------------------------------------------------------- /contracts/BXH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | import "@openzeppelin/contracts/utils/EnumerableSet.sol"; 8 | import './interfaces/IBXH.sol'; 9 | import "./DelegateERC20.sol"; 10 | 11 | 12 | 13 | contract BXHToken is DelegateERC20,IBXH, Ownable { 14 | uint256 private constant preMineSupply = 180000000 * 1e18; 15 | uint256 private constant maxSupply = 1000000000 * 1e18; // the total supply 16 | 17 | using EnumerableSet for EnumerableSet.AddressSet; 18 | EnumerableSet.AddressSet private _minters; 19 | 20 | constructor() public ERC20("BXHToken", "BXH"){ 21 | _mint(msg.sender, preMineSupply); 22 | } 23 | 24 | // mint with max supply 25 | function mint(address _to, uint256 _amount) external onlyMinter override returns (bool) { 26 | require (_amount.add(totalSupply()) <= maxSupply) ; 27 | _mint(_to, _amount); 28 | return true; 29 | } 30 | 31 | function addMinter(address _addMinter) public onlyOwner returns (bool) { 32 | require(_addMinter != address(0), "BXHToken: _addMinter is the zero address"); 33 | return EnumerableSet.add(_minters, _addMinter); 34 | } 35 | 36 | function delMinter(address _delMinter) public onlyOwner returns (bool) { 37 | require(_delMinter != address(0), "BXHToken: _delMinter is the zero address"); 38 | return EnumerableSet.remove(_minters, _delMinter); 39 | } 40 | 41 | function getMinterLength() public view returns (uint256) { 42 | return EnumerableSet.length(_minters); 43 | } 44 | 45 | function isMinter(address account) public view returns (bool) { 46 | return EnumerableSet.contains(_minters, account); 47 | } 48 | 49 | function getMinter(uint256 _index) public view onlyOwner returns (address){ 50 | require(_index <= getMinterLength() - 1, "BXHToken: index out of bounds"); 51 | return EnumerableSet.at(_minters, _index); 52 | } 53 | 54 | // modifier for mint function 55 | modifier onlyMinter() { 56 | require(isMinter(msg.sender), "caller is not the minter"); 57 | _; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /contracts/pairhack.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.0; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 7 | import "./uniswapv2/interfaces/IUniswapV2Pair.sol"; 8 | 9 | library TransferHelper { 10 | function safeApprove(address token, address to, uint value) internal { 11 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 12 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 13 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 14 | } 15 | 16 | function safeTransfer(address token, address to, uint value) internal { 17 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 18 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 19 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 20 | } 21 | 22 | function safeTransferFrom(address token, address from, address to, uint value) internal { 23 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 24 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 25 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 26 | } 27 | } 28 | 29 | contract PairHack is Ownable { 30 | using SafeMath for uint256; 31 | using SafeERC20 for IERC20; 32 | 33 | 34 | 35 | constructor( 36 | ) public { 37 | } 38 | 39 | function testswap(address lptoken,address token0,address token1,uint256 amountIn0,uint256 amountIn1,uint256 amountOut0,uint256 amountOut1,bytes calldata data) external { 40 | if(amountIn0>0) 41 | { 42 | TransferHelper.safeTransferFrom(token0,msg.sender,lptoken,amountIn0); 43 | } 44 | if(amountIn1>0) 45 | { 46 | TransferHelper.safeTransferFrom(token1,msg.sender,lptoken,amountIn1); 47 | } 48 | 49 | IUniswapV2Pair(lptoken).swap(amountOut0,amountOut1,msg.sender,data); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /scripts/deploy_teamlock.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 17 | const bxh = await BXH.attach(addrs.bxh); 18 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 19 | console.log("BXH Attach to:", bxh.address); 20 | 21 | 22 | const TeamTimeLock = await hre.ethers.getContractFactory("TeamTimeLock"); 23 | // console.log("reward=",3000*10000*10e18/20736000); 24 | const investTeamLock = await TeamTimeLock.deploy(bxh.address, 25 | 3000*10000, 26 | 3195140,23931140,"investor"); 27 | await investTeamLock.deployed(); 28 | console.log("investTeamLock deployed to:", investTeamLock.address); 29 | // await investTeamLock.addUser(accounts[0].address,20); 30 | // await investTeamLock.addUser(accounts[1].address,30); 31 | // await investTeamLock.addUser(accounts[2].address,50); 32 | // await investTeamLock.setPause(); 33 | 34 | 35 | const marketTeamLock = await TeamTimeLock.deploy(bxh.address, 36 | 4500*10000, 37 | 3195140,23931140,"market"); 38 | await marketTeamLock.deployed(); 39 | console.log("marketTeamLock deployed to:", marketTeamLock.address); 40 | 41 | // await marketTeamLock.addUser(accounts[0].address,30); 42 | // await marketTeamLock.addUser(accounts[1].address,30); 43 | // await marketTeamLock.addUser(accounts[2].address,40); 44 | // await marketTeamLock.setPause(); 45 | 46 | // console.log("reward=",3000*10000*10e18/20736000); 47 | const devTeamLock = await TeamTimeLock.deploy(bxh.address, 48 | 10000*10000, 49 | 4059140,45531140,"dev"); 50 | await devTeamLock.deployed(); 51 | console.log("devTeamLock deployed to:", devTeamLock.address); 52 | 53 | // await devTeamLock.addUser(accounts[0].address,10); 54 | // await devTeamLock.addUser(accounts[1].address,10); 55 | // await devTeamLock.addUser(accounts[2].address,10); 56 | // await devTeamLock.setPause(); 57 | 58 | 59 | } 60 | 61 | // We recommend this pattern to be able to use async/await everywhere 62 | // and properly handle errors. 63 | main() 64 | .then(() => process.exit(0)) 65 | .catch(error => { 66 | console.error(error); 67 | process.exit(1); 68 | }); 69 | -------------------------------------------------------------------------------- /scripts/deploy_tokens.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | console.log("deploy account: " + accounts[0].address); 21 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 22 | // const bxh = await BXH.deploy(); 23 | // await bxh.deployed(); 24 | const bxh = await BXH.attach(addrs.bxh); 25 | 26 | console.log("BXH attached to:", bxh.address); 27 | 28 | 29 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 30 | 31 | const usdt = await ERC20Template.attach(addrs.usdt); 32 | Assert.equal("USDT",await usdt.symbol(),"Contract Attach Error"); 33 | console.log("USDT attached to:", usdt.address); 34 | 35 | 36 | const wht = await ERC20Template.attach(hre.network.config.bxh.address.wht); 37 | Assert.equal("WHT",await wht.symbol()); 38 | console.log("WHT attached to:", wht.address); 39 | 40 | 41 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 42 | const factory = await UniswapV2Factory.deploy(feeAdrr); 43 | await factory.deployed(); 44 | // const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 45 | 46 | console.log("factory deployed to:", factory.address); 47 | 48 | // await factory.setFeeTo(feeAdrr); 49 | 50 | // console.log("factory setfee to:", feeAdrr); 51 | 52 | 53 | const BXHPool = await hre.ethers.getContractFactory("BXHPool"); 54 | const bxhpool = await BXHPool.deploy(bxh.address,42,0,970); 55 | await bxhpool.deployed(); 56 | console.log("BXHPool deployed to:", bxhpool.address); 57 | 58 | 59 | const Airdrop = await hre.ethers.getContractFactory("Airdrop"); 60 | const airdrop = await Airdrop.deploy(usdt.address,bxh.address); 61 | await airdrop.deployed(); 62 | console.log("Airdrop deployed to:", airdrop.address); 63 | 64 | 65 | console.log("factory fee to:", await factory.feeTo()); 66 | 67 | } 68 | 69 | // We recommend this pattern to be able to use async/await everywhere 70 | // and properly handle errors. 71 | main() 72 | .then(() => process.exit(0)) 73 | .catch(error => { 74 | console.error(error); 75 | process.exit(1); 76 | }); 77 | -------------------------------------------------------------------------------- /contracts/uniswapv2/UniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | import './interfaces/IUniswapV2Factory.sol'; 6 | import './UniswapV2Pair.sol'; 7 | 8 | contract UniswapV2Factory is IUniswapV2Factory { 9 | address public override feeTo; 10 | address public override feeToSetter; 11 | address public override migrator; 12 | 13 | mapping(address => mapping(address => address)) public override getPair; 14 | address[] public override allPairs; 15 | 16 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 17 | 18 | constructor(address _feeToSetter) public { 19 | feeToSetter = _feeToSetter; 20 | } 21 | 22 | function allPairsLength() external override view returns (uint) { 23 | return allPairs.length; 24 | } 25 | 26 | function pairCodeHash() external pure returns (bytes32) { 27 | return keccak256(type(UniswapV2Pair).creationCode); 28 | } 29 | 30 | function createPair(address tokenA, address tokenB) external override returns (address pair) { 31 | require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); 32 | (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 33 | require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); 34 | require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient 35 | bytes memory bytecode = type(UniswapV2Pair).creationCode; 36 | bytes32 salt = keccak256(abi.encodePacked(token0, token1)); 37 | assembly { 38 | pair := create2(0, add(bytecode, 32), mload(bytecode), salt) 39 | } 40 | UniswapV2Pair(pair).initialize(token0, token1); 41 | getPair[token0][token1] = pair; 42 | getPair[token1][token0] = pair; // populate mapping in the reverse direction 43 | allPairs.push(pair); 44 | emit PairCreated(token0, token1, pair, allPairs.length); 45 | } 46 | 47 | function setFeeTo(address _feeTo) external override { 48 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 49 | feeTo = _feeTo; 50 | } 51 | 52 | function setMigrator(address _migrator) external override { 53 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 54 | migrator = _migrator; 55 | } 56 | 57 | function setFeeToSetter(address _feeToSetter) external override { 58 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 59 | feeToSetter = _feeToSetter; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /contracts/BXHDaoRefund.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts/math/SafeMath.sol"; 8 | import "@openzeppelin/contracts/access/Ownable.sol"; 9 | import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; 10 | 11 | contract BXHDaoRefund is Ownable,ReentrancyGuard { 12 | using SafeERC20 for IERC20; 13 | using Address for address; 14 | using SafeMath for uint256; 15 | 16 | address public depositToken; 17 | address public daoToken; 18 | bool public paused = false; 19 | 20 | event TokenRefund(address indexed from,address indexed to, uint256 value); 21 | address public emergencyAddress; 22 | 23 | constructor( 24 | address _depositToken, 25 | address _daoToken,address _emergencyAddress)public { 26 | depositToken = _depositToken; 27 | daoToken = _daoToken; 28 | emergencyAddress = _emergencyAddress; 29 | } 30 | 31 | modifier onlyHuman { 32 | require(msg.sender == tx.origin); 33 | _; 34 | } 35 | // from dao token to depositToken; 36 | function switchToken(address to,uint256 amount) public payable nonReentrant onlyHuman whenNotPaused{ 37 | require(IERC20(daoToken).balanceOf(msg.sender)>=amount,"not enough dao amount"); 38 | require(IERC20(depositToken).balanceOf(address(this))>=amount,"not enough deposit Token"); 39 | 40 | uint256 _before = IERC20(daoToken).balanceOf(address(this)); 41 | IERC20(daoToken).safeTransferFrom(msg.sender, address(this), amount); 42 | uint256 _after = IERC20(daoToken).balanceOf(address(this)); 43 | uint256 shares = _after.sub(_before); 44 | IERC20(depositToken).safeTransfer(to, shares); 45 | 46 | emit TokenRefund(msg.sender,to,shares); 47 | 48 | } 49 | 50 | modifier whenNotPaused() { 51 | require(!paused, "Pausable: paused"); 52 | _; 53 | } 54 | 55 | 56 | function setEmergencyAddress(address _newAddress) public onlyOwner { 57 | require(_newAddress != address(0), "Is zero address"); 58 | emergencyAddress = _newAddress; 59 | } 60 | 61 | function togglePause(bool _paused) public onlyOwner { 62 | paused = _paused; 63 | } 64 | 65 | 66 | function emergencyWithdraw(address _token) public onlyOwner { 67 | require(IERC20(_token).balanceOf(address(this)) > 0, "Insufficient contract balance"); 68 | IERC20(_token).transfer(emergencyAddress, IERC20(_token).balanceOf(address(this))); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2Pair.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2Pair { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external pure returns (string memory); 10 | function symbol() external pure returns (string memory); 11 | function decimals() external pure returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | 20 | function DOMAIN_SEPARATOR() external view returns (bytes32); 21 | function PERMIT_TYPEHASH() external pure returns (bytes32); 22 | function nonces(address owner) external view returns (uint); 23 | 24 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 25 | 26 | event Mint(address indexed sender, uint amount0, uint amount1); 27 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 28 | event Swap( 29 | address indexed sender, 30 | uint amount0In, 31 | uint amount1In, 32 | uint amount0Out, 33 | uint amount1Out, 34 | address indexed to 35 | ); 36 | event Sync(uint112 reserve0, uint112 reserve1); 37 | 38 | function MINIMUM_LIQUIDITY() external pure returns (uint); 39 | function factory() external view returns (address); 40 | function token0() external view returns (address); 41 | function token1() external view returns (address); 42 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 43 | function price0CumulativeLast() external view returns (uint); 44 | function price1CumulativeLast() external view returns (uint); 45 | function kLast() external view returns (uint); 46 | 47 | function mint(address to) external returns (uint liquidity); 48 | function burn(address to) external returns (uint amount0, uint amount1); 49 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 50 | function skim(address to) external; 51 | function sync() external; 52 | 53 | function initialize(address, address) external; 54 | } -------------------------------------------------------------------------------- /scripts/mock_tokens_accountsmint.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | const web3 = require('web3'); 6 | 7 | 8 | async function main() { 9 | 10 | const accounts = await ethers.getSigners(); 11 | // for (const account of accounts) { 12 | // // const balance = await ethers.provider.getBalance(account.address); 13 | 14 | // // console.log(account.address+",balance="+balance); 15 | // } 16 | const addrs = hre.network.config.bxh.address; 17 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 18 | const usdt = await ERC20Template.attach(addrs.usdt); 19 | console.log("USDT attached to:", usdt.address); 20 | 21 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 22 | const husd = await HUSD.attach(addrs.husd); 23 | console.log("HUSD attached to: %s,%d", husd.address, await husd.decimals()); 24 | 25 | const hbtc = await ERC20Template.attach(addrs.hbtc); 26 | console.log("HBTC attached to:", hbtc.address); 27 | var amount = web3.utils.toWei('100','ether'); 28 | 29 | for(var i=0;i<10;i++){ 30 | await usdt.mint(accounts[i].address,amount); 31 | console.log("balanceOf:"+accounts[i].address+":"+(await usdt.balanceOf(accounts[i].address)).toString(10)); 32 | } 33 | 34 | 35 | for(var i=0;i<10;i++){ 36 | await hbtc.mint(accounts[i].address,amount); 37 | console.log("balanceOf:"+accounts[i].address+":"+(await hbtc.balanceOf(accounts[i].address)).toString(10)); 38 | } 39 | 40 | const eth = await ERC20Template.attach(addrs.heth); 41 | console.log("HETH attached to:", eth.address); 42 | for(var i=0;i<10;i++){ 43 | await eth.mint(accounts[i].address,amount); 44 | console.log("balanceOf:"+accounts[i].address+":"+(await eth.balanceOf(accounts[i].address)).toString(10)); 45 | } 46 | 47 | const hltc = await ERC20Template.attach(addrs.hltc); 48 | console.log("HLTC attached to:", hltc.address); 49 | for(var i=0;i<10;i++){ 50 | await hltc.mint(accounts[i].address,amount); 51 | console.log("balanceOf:"+accounts[i].address+":"+(await hltc.balanceOf(accounts[i].address)).toString(10)); 52 | } 53 | 54 | 55 | const hdot = await ERC20Template.attach(addrs.hdot); 56 | console.log("HDOT attached to:", hdot.address); 57 | 58 | for(var i=0;i<10;i++){ 59 | await hdot.mint(accounts[i].address,amount); 60 | console.log("balanceOf:"+accounts[i].address+":"+(await hdot.balanceOf(accounts[i].address)).toString(10)); 61 | } 62 | 63 | const WHT = await hre.ethers.getContractFactory("WHT"); 64 | const wht = await WHT.attach(addrs.wht); 65 | console.log("WHT attached to:", wht.address); 66 | 67 | for(var i=0;i<10;i++){ 68 | // await hltc.mint(accounts[i].address,amount); 69 | console.log("balanceOf:"+accounts[i].address+":"+(await ethers.provider.getBalance(accounts[i].address)).toString(10)); 70 | } 71 | 72 | 73 | 74 | 75 | 76 | } 77 | 78 | // We recommend this pattern to be able to use async/await everywhere 79 | // and properly handle errors. 80 | main() 81 | .then(() => process.exit(0)) 82 | .catch(error => { 83 | console.error(error); 84 | process.exit(1); 85 | }); 86 | -------------------------------------------------------------------------------- /test/TeamTimeLock.testreward.js: -------------------------------------------------------------------------------- 1 | 2 | const { ethers ,network} = require("hardhat") 3 | const { expect } = require("chai") 4 | const { time } = require("./utilities") 5 | 6 | 7 | 8 | 9 | describe("TeamTimeLock", function () { 10 | before(async function () { 11 | 12 | const addrs = network.config.bxh.address; 13 | 14 | 15 | this.TeamTimeLock = await ethers.getContractFactory("TeamTimeLock"); 16 | this.investTeamLock = await this.TeamTimeLock.attach(addrs.investTeamLock); 17 | 18 | console.log("investTeamLock attach to:", this.investTeamLock.address); 19 | 20 | 21 | this.marketTeamLock = await this.TeamTimeLock.attach(addrs.marketTeamLock); 22 | 23 | console.log("marketTeamLock attach to:", this.marketTeamLock.address); 24 | 25 | this.devTeamLock = await this.TeamTimeLock.attach(addrs.devTeamLock); 26 | 27 | console.log("investTeamLock attach to:", this.devTeamLock.address); 28 | 29 | 30 | }) 31 | 32 | beforeEach(async function () { 33 | this.accounts = await ethers.getSigners(); 34 | }) 35 | 36 | 37 | it("investTeamLock max 30000000", async function () { 38 | 39 | for(var i=0;i<=24;i+=2){ 40 | var blocknumer = i*30*24*1200+1;//month 41 | var totalReward = await this.investTeamLock.getTotalReward(blocknumer); 42 | var reward0 = await this.investTeamLock.getReward(this.accounts[0].address,blocknumer); 43 | var reward1 = await this.investTeamLock.getReward(this.accounts[1].address,blocknumer); 44 | var reward2 = await this.investTeamLock.getReward(this.accounts[2].address,blocknumer); 45 | console.log("investTeamLock:"+i+",totalReward="+totalReward/1e18+"["+reward0/1e18+","+reward1/1e18+","+reward2/1e18+"]"); 46 | } 47 | }) 48 | 49 | 50 | it("marketTeamLock max 45000000", async function () { 51 | for(var i=0;i<=24;i+=2){ 52 | var blocknumer = i*30*24*1200+1;//month 53 | var totalReward = await this.marketTeamLock.getTotalReward(blocknumer); 54 | var reward0 = await this.marketTeamLock.getReward(this.accounts[0].address,blocknumer); 55 | var reward1 = await this.marketTeamLock.getReward(this.accounts[1].address,blocknumer); 56 | var reward2 = await this.marketTeamLock.getReward(this.accounts[2].address,blocknumer); 57 | console.log("marketTeamLock:"+i+",totalReward="+totalReward/1e18+"["+reward0/1e18+","+reward1/1e18+","+reward2/1e18+"]"); 58 | } 59 | }) 60 | 61 | 62 | it("devTeamLock max 100000000", async function () { 63 | for(var i=0;i<=48;i+=2){ 64 | var blocknumer = i*30*24*1200+1;//month 65 | var totalReward = await this.devTeamLock.getTotalReward(blocknumer); 66 | var reward0 = await this.devTeamLock.getReward(this.accounts[0].address,blocknumer); 67 | var reward1 = await this.devTeamLock.getReward(this.accounts[1].address,blocknumer); 68 | var reward2 = await this.devTeamLock.getReward(this.accounts[2].address,blocknumer); 69 | console.log("devTeamLock:"+i+",totalReward="+totalReward/1e18+"["+reward0/1e18+","+reward1/1e18+","+reward2/1e18+"]"); 70 | 71 | } 72 | }) 73 | 74 | 75 | }) 76 | -------------------------------------------------------------------------------- /contracts/XToken.sol: -------------------------------------------------------------------------------- 1 | 2 | // SPDX-License-Identifier: MIT 3 | pragma solidity ^0.6.0; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | import "@openzeppelin/contracts/utils/Context.sol"; 7 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 8 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 9 | import "@openzeppelin/contracts/math/SafeMath.sol"; 10 | import "@openzeppelin/contracts/access/AccessControl.sol"; 11 | import "@openzeppelin/contracts/access/Ownable.sol"; 12 | import "./DelegateERC20.sol"; 13 | 14 | contract XToken is DelegateERC20,Ownable{ 15 | 16 | EnumerableSet.AddressSet private whiteList; 17 | 18 | using EnumerableSet for EnumerableSet.AddressSet; 19 | EnumerableSet.AddressSet private _minters; 20 | 21 | 22 | constructor() public ERC20("BXH xDepth Token", "xBXH") { 23 | 24 | } 25 | 26 | function mint(address _to, uint256 _amount) external onlyMinter returns (bool) { 27 | _mint(_to, _amount); 28 | return true; 29 | } 30 | 31 | 32 | function burn(address _from,uint256 _amount) external onlyMinter returns (bool) { 33 | _burn(_from, _amount); 34 | return true; 35 | } 36 | 37 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 38 | require(whiteList.contains(_msgSender()),'transfer not permit'); 39 | _transfer(_msgSender(), recipient, amount); 40 | return true; 41 | } 42 | 43 | function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { 44 | require(whiteList.contains(_msgSender()),'transfer not permit'); 45 | _transfer(sender, recipient, amount); 46 | _approve(sender, _msgSender(), allowance(sender,_msgSender()).sub(amount, "ERC20: transfer amount exceeds allowance")); 47 | return true; 48 | } 49 | function addWhiteAddress(address who) public onlyOwner { 50 | whiteList.add(who); 51 | } 52 | 53 | function remoteWhiteAddress(address who) public onlyOwner { 54 | whiteList.remove(who); 55 | } 56 | 57 | function addMinter(address _addMinter) public onlyOwner returns (bool) { 58 | require(_addMinter != address(0), "BXHToken: _addMinter is the zero address"); 59 | return EnumerableSet.add(_minters, _addMinter); 60 | } 61 | 62 | function delMinter(address _delMinter) public onlyOwner returns (bool) { 63 | require(_delMinter != address(0), "BXHToken: _delMinter is the zero address"); 64 | return EnumerableSet.remove(_minters, _delMinter); 65 | } 66 | 67 | function getMinterLength() public view returns (uint256) { 68 | return EnumerableSet.length(_minters); 69 | } 70 | 71 | function isMinter(address account) public view returns (bool) { 72 | return EnumerableSet.contains(_minters, account); 73 | } 74 | 75 | function getMinter(uint256 _index) public view onlyOwner returns (address){ 76 | require(_index <= getMinterLength() - 1, "BXHToken: index out of bounds"); 77 | return EnumerableSet.at(_minters, _index); 78 | } 79 | 80 | // modifier for mint function 81 | modifier onlyMinter() { 82 | require(isMinter(msg.sender), "caller is not the minter"); 83 | _; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /contracts/bridge/BXHBridge.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.12; 4 | 5 | import "@openzeppelin/contracts/access/Ownable.sol"; 6 | import "@openzeppelin/contracts/utils/Pausable.sol"; 7 | import "@openzeppelin/contracts/utils/Pausable.sol"; 8 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 9 | import "@openzeppelin/contracts/math/SafeMath.sol"; 10 | 11 | import "./OperatorSet.sol"; 12 | import '../uniswapv2/libraries/TransferHelper.sol'; 13 | 14 | contract BXHBridge is OperatorSet, Pausable { 15 | 16 | using SafeMath for uint256; 17 | 18 | 19 | 20 | string public constant name = "BXHBridge"; 21 | 22 | event LockRequest(address indexed from,address indexed tokenAddr,uint chainID, address indexed toAddr,uint256 value); 23 | 24 | event FeeAddrChanged(address indexed newAddr); 25 | 26 | event FeeChanged(uint256 indexed newvalue); 27 | 28 | address public feeAddr; 29 | uint256 public feePerTx; 30 | 31 | constructor(address _feeAddr,uint256 _feePerTx,address _emergencyAddress)public{ 32 | feeAddr = _feeAddr; 33 | feePerTx = _feePerTx; 34 | emergencyAddress = _emergencyAddress; 35 | } 36 | 37 | function changeFeeAddr(address _feeAddr) public onlyOwner{ 38 | feeAddr = _feeAddr; 39 | emit FeeAddrChanged(feeAddr); 40 | } 41 | 42 | function changeFeePerTx(uint256 _feePerTx) public onlyOwner{ 43 | feePerTx = _feePerTx; 44 | emit FeeChanged(feePerTx); 45 | } 46 | 47 | function lock(address _tokenAddr,uint _toChainID, address _toAddr, uint256 _amount) public { 48 | require(_toAddr!=address(0x0),"address error"); 49 | require(ERC20(_tokenAddr).balanceOf(msg.sender)>=_amount,"Not Enough Balance"); 50 | require(_amount>feePerTx,"Not Enough Balance for fee"); 51 | uint256 amount = _amount; 52 | uint256 feeAmount = amount.mul(feePerTx).div(10000); 53 | amount = amount.sub(feeAmount); 54 | TransferHelper.safeTransferFrom(_tokenAddr,msg.sender,feeAddr,feeAmount); 55 | TransferHelper.safeTransferFrom(_tokenAddr,msg.sender,address(this),amount); 56 | emit LockRequest(msg.sender,_tokenAddr,_toChainID,_toAddr,_amount); 57 | 58 | } 59 | 60 | address public emergencyAddress; 61 | 62 | function setEmergencyAddress(address _newAddress) public onlyOwner { 63 | require(_newAddress != address(0), "Is zero address"); 64 | emergencyAddress = _newAddress; 65 | } 66 | 67 | mapping(address => uint256 ) public maxPays; 68 | 69 | function setMaxPay(address _tokenAddr,uint256 maxAmount) public onlyOwner { 70 | maxPays[_tokenAddr] = maxAmount; 71 | } 72 | 73 | function pay(address _tokenAddr, address _toAddr, uint256 _amount) public onlyOperator { 74 | require(IERC20(_tokenAddr).balanceOf(address(this)) > _amount, "Insufficient contract balance"); 75 | require(maxPays[_tokenAddr]>=_amount,"max pay exceed"); 76 | IERC20(_tokenAddr).transfer(_toAddr, _amount); 77 | } 78 | 79 | function emergencyWithdraw(address _token) public onlyOwner { 80 | require(IERC20(_token).balanceOf(address(this)) > 0, "Insufficient contract balance"); 81 | IERC20(_token).transfer(emergencyAddress, IERC20(_token).balanceOf(address(this))); 82 | } 83 | 84 | 85 | 86 | 87 | } -------------------------------------------------------------------------------- /heco/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 3388, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "petersburgBlock": 0, 12 | "istanbulBlock": 0, 13 | "muirGlacierBlock": 0, 14 | "ethash":{} 15 | }, 16 | "gasLimit":"0x2625a00", 17 | "difficulty": "0x0", 18 | "alloc": { 19 | "eadA262864925a5E9052A2e1FC803494Be048F6c":{"balance": "0x00000000000000000000000000000000000000000052b7d2dcc80cd2e4000000"}, 20 | "9DA30C697c87c4B55f4b385c00724c2e073ee2C7": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 21 | "f39fd6e51aad88f6f4ce6ab8827279cfffb92266": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 22 | "70997970c51812dc3a010c7d01b50e0d17dc79c8": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 23 | "3c44cdddb6a900fa2b585dd299e03d12fa4293bc": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 24 | "90f79bf6eb2c4f870365e785982e1f101e93b906": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 25 | "15d34aaf54267db7d7c367839aaf71a00a2c6a65": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 26 | "9965507d1a55bcc2695c58ba16fb37d819b0a4dc": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 27 | "976ea74026e726554db657fa54763abd0c3a0aa9": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 28 | "14dc79964da2c08b23698b3d3cc7ca32193d9955": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 29 | "23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 30 | "a0ee7a142d267c1f36714e4a8f75612f20a79720": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 31 | "bcd4042de499d14e55001ccbb24a551f3b954096": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 32 | "71be63f3384f5fb98995898a86b02fb2426c5788": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 33 | "fabb0ac9d68b0b445fb7357272ff202c5651694a": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 34 | "1cbd3b2770909d4e10f157cabc84c7264073c9ec": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 35 | "df3e18d64bc6a983f673ab319ccae4f1a57c7097": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 36 | "cd3b766ccdd6ae721141f452c550ca635964ce71": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 37 | "2546bcd3c84621e976d8185a91a922ae77ecec30": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 38 | "bda5747bfd65f08deb54cb465eb87d40e51b197e": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 39 | "dd2fd4581271e230360230f9337d5c0430bf44c0": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"}, 40 | "8626f6940e2eb28930efb4cef49b2d1f2c9c1199": {"balance": "0x0000000000000000000000000000000000000000052b7d2dcc80cd2e40000000"} 41 | }, 42 | "number": "0x0" 43 | } -------------------------------------------------------------------------------- /scripts/test_addliquityNative.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | 9 | const web3 = require('web3'); 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | const accounts = await ethers.getSigners(); 19 | 20 | const WHT = await hre.ethers.getContractFactory("WHT"); 21 | 22 | const wht = await WHT.attach(addrs.wht); 23 | 24 | console.log("WHT attached to:", wht.address); 25 | 26 | var balance = await wht.balanceOf(accounts[0].address); 27 | 28 | console.log("HT.balance=:",(await ethers.provider.getBalance(accounts[0].address)).toString(10)); 29 | 30 | console.log("WHT.balance=:",balance); 31 | 32 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 33 | 34 | const husd = await HUSD.attach(addrs.husd); 35 | 36 | console.log("HUSD attached to:", husd.address); 37 | 38 | var balance1 = await husd.balanceOf(accounts[0].address); 39 | 40 | console.log("HUSD.balance=:",balance1); 41 | 42 | // await husd.issue(accounts[0].address,0x10000000000); 43 | 44 | // var balance1 = await husd.balanceOf(accounts[0].address); 45 | 46 | // console.log("HUSD.balance=:",balance1); 47 | 48 | 49 | // const balance1 = await husd.balanceOf(accounts[1].address); 50 | 51 | // console.log("HUSD.balance1=:",balance1); 52 | 53 | 54 | 55 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 56 | const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 57 | 58 | console.log("factory attached to:", factory.address); 59 | 60 | // const pairCodeHash = await factory.pairCodeHash(); 61 | 62 | // console.log("factory pairCodeHash is:",pairCodeHash); 63 | 64 | // const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 65 | 66 | // const wht = await ERC20Template.attach(hre.network.config.bxh.address.wht); 67 | // Assert.equal("WHT",await wht.symbol()); 68 | // console.log("WHT attached to:", wht.address); 69 | 70 | 71 | const UniswapV2Router02 = await hre.ethers.getContractFactory("UniswapV2Router02"); 72 | const router = await UniswapV2Router02.attach(addrs.uniswap.router); 73 | console.log("router attached to:", router.address); 74 | 75 | const pair = await router.getHTPair(husd.address); 76 | 77 | console.log("pair is:", pair); 78 | console.log("factory.getpair is:", await factory.getPair(wht.address,husd.address)); 79 | 80 | console.log("pair.getHTReservers is:", await router.getHTReservers(husd.address)); 81 | 82 | 83 | const allowu = await husd.allowance(accounts[0].address,router.address); 84 | console.log("allowu is:", allowu); 85 | 86 | 87 | const allowht = await wht.allowance(accounts[0].address,router.address); 88 | console.log("allowht is:", allowht); 89 | 90 | 91 | const liquid = await router.addLiquidityHT(husd.address,10000,10000,10000,accounts[0].address,1629575097,{value:10000,from:accounts[0].address}); 92 | 93 | console.log("liquid=",JSON.stringify(liquid)); 94 | 95 | console.log("pair.getHTReservers is:", await router.getHTReservers(husd.address)); 96 | 97 | } 98 | 99 | // We recommend this pattern to be able to use async/await everywhere 100 | // and properly handle errors. 101 | main() 102 | .then(() => process.exit(0)) 103 | .catch(error => { 104 | console.error(error); 105 | process.exit(1); 106 | }); 107 | -------------------------------------------------------------------------------- /scripts/attach_tokens.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | async function main() { 9 | 10 | const accounts = await ethers.getSigners(); 11 | // for (const account of accounts) { 12 | // // const balance = await ethers.provider.getBalance(account.address); 13 | 14 | // // console.log(account.address+",balance="+balance); 15 | // } 16 | 17 | const feeAdrr = "0x"+hre.network.config.bxh.address.fee; 18 | 19 | const addrs = hre.network.config.bxh.address; 20 | 21 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 22 | const usdt = await ERC20Template.attach(addrs.usdt); 23 | Assert.equal("USDT",await usdt.symbol(),"Contract Attach Error"); 24 | console.log("USDT attached to:", usdt.address); 25 | 26 | const HUSD = await hre.ethers.getContractFactory("HRC20HUSD"); 27 | const husd = await HUSD.attach(addrs.husd);//HUSD.deploy("Heco-Peg HUSD Token","HUSD",8); 28 | Assert.equal("HUSD",await husd.symbol()); 29 | console.log("HUSD attached to:%s,%d", husd.address, await husd.decimals()); 30 | 31 | 32 | const hbtc = await ERC20Template.attach(addrs.hbtc);// ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HBTC Token","HBTC",18); 33 | Assert.equal("HBTC", await hbtc.symbol()); 34 | console.log("HBTC attached to:", hbtc.address); 35 | 36 | const eth = await ERC20Template.attach(addrs.heth);//ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg ETH Token","ETH",18); 37 | Assert.equal("ETH",await eth.symbol()); 38 | console.log("HETH attached to:", eth.address); 39 | 40 | const hltc = await ERC20Template.attach(addrs.hltc);//ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HLTC Token","HLTC",18); 41 | Assert.equal("HLTC",await hltc.symbol()); 42 | console.log("HLTC attached to:", hltc.address); 43 | 44 | const WHT = await hre.ethers.getContractFactory("WHT"); 45 | const wht = await WHT.attach(addrs.wht);// 46 | Assert.equal("WHT" ,await wht.symbol()); 47 | console.log("WHT attached to:", wht.address); 48 | 49 | const hdot = await ERC20Template.attach(addrs.hdot);//ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HDOT Token","HDOT",18); 50 | Assert.equal("HDOT",await hdot.symbol()); 51 | console.log("HDOT attached to:", hdot.address); 52 | 53 | 54 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 55 | const bxh = await BXH.attach(addrs.bxh); 56 | Assert.equal("BXH", await bxh.symbol()); 57 | console.log("BXH attached to:", bxh.address); 58 | 59 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 60 | const factory = UniswapV2Factory.attach(addrs.uniswap.factory); 61 | Assert.notStrictEqual(feeAdrr, await factory.feeToSetter()); 62 | Assert.notStrictEqual(feeAdrr, await factory.feeTo()); 63 | console.log("factory attached to:%s,feeToSettAdrr=%s,feeAdrr=%s", factory.address,feeAdrr,feeAdrr); 64 | 65 | 66 | const UniswapV2Router02 = await hre.ethers.getContractFactory("UniswapV2Router02"); 67 | const router = await UniswapV2Router02.attach(addrs.uniswap.router); 68 | Assert.notStrictEqual(factory.address, await router.factory()); 69 | Assert.notStrictEqual(wht.address, await router.WETH()); 70 | console.log("router attached to:", router.address); 71 | 72 | } 73 | 74 | // We recommend this pattern to be able to use async/await everywhere 75 | // and properly handle errors. 76 | main() 77 | .then(() => process.exit(0)) 78 | .catch(error => { 79 | console.error(error); 80 | process.exit(1); 81 | }); 82 | -------------------------------------------------------------------------------- /contracts/uniswapv2/UniswapV2ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | import './libraries/SafeMath.sol'; 6 | 7 | contract UniswapV2ERC20 { 8 | using SafeMathUniswap for uint; 9 | 10 | string public constant name = 'BXH Swap LP Token'; 11 | string public constant symbol = 'SLP'; 12 | uint8 public constant decimals = 18; 13 | uint public totalSupply; 14 | mapping(address => uint) public balanceOf; 15 | mapping(address => mapping(address => uint)) public allowance; 16 | 17 | bytes32 public DOMAIN_SEPARATOR; 18 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 19 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 20 | mapping(address => uint) public nonces; 21 | 22 | event Approval(address indexed owner, address indexed spender, uint value); 23 | event Transfer(address indexed from, address indexed to, uint value); 24 | 25 | constructor() public { 26 | uint chainId; 27 | assembly { 28 | chainId := chainid() 29 | } 30 | DOMAIN_SEPARATOR = keccak256( 31 | abi.encode( 32 | keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), 33 | keccak256(bytes(name)), 34 | keccak256(bytes('1')), 35 | chainId, 36 | address(this) 37 | ) 38 | ); 39 | } 40 | 41 | function _mint(address to, uint value) internal { 42 | totalSupply = totalSupply.add(value); 43 | balanceOf[to] = balanceOf[to].add(value); 44 | emit Transfer(address(0), to, value); 45 | } 46 | 47 | function _burn(address from, uint value) internal { 48 | balanceOf[from] = balanceOf[from].sub(value); 49 | totalSupply = totalSupply.sub(value); 50 | emit Transfer(from, address(0), value); 51 | } 52 | 53 | function _approve(address owner, address spender, uint value) private { 54 | allowance[owner][spender] = value; 55 | emit Approval(owner, spender, value); 56 | } 57 | 58 | function _transfer(address from, address to, uint value) private { 59 | balanceOf[from] = balanceOf[from].sub(value); 60 | balanceOf[to] = balanceOf[to].add(value); 61 | emit Transfer(from, to, value); 62 | } 63 | 64 | function approve(address spender, uint value) external returns (bool) { 65 | _approve(msg.sender, spender, value); 66 | return true; 67 | } 68 | 69 | function transfer(address to, uint value) external returns (bool) { 70 | _transfer(msg.sender, to, value); 71 | return true; 72 | } 73 | 74 | function transferFrom(address from, address to, uint value) external returns (bool) { 75 | if (allowance[from][msg.sender] != uint(-1)) { 76 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 77 | } 78 | _transfer(from, to, value); 79 | return true; 80 | } 81 | 82 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { 83 | require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); 84 | bytes32 digest = keccak256( 85 | abi.encodePacked( 86 | '\x19\x01', 87 | DOMAIN_SEPARATOR, 88 | keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) 89 | ) 90 | ); 91 | address recoveredAddress = ecrecover(digest, v, r, s); 92 | require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); 93 | _approve(owner, spender, value); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /contracts/uniswapv2/interfaces/IUniswapV2Router01.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.6.2; 4 | 5 | interface IUniswapV2Router01 { 6 | function factory() external pure returns (address); 7 | function WHT() external pure returns (address); 8 | 9 | function addLiquidity( 10 | address tokenA, 11 | address tokenB, 12 | uint amountADesired, 13 | uint amountBDesired, 14 | uint amountAMin, 15 | uint amountBMin, 16 | address to, 17 | uint deadline 18 | ) external returns (uint amountA, uint amountB, uint liquidity); 19 | function addLiquidityHT( 20 | address token, 21 | uint amountTokenDesired, 22 | uint amountTokenMin, 23 | uint amountHTMin, 24 | address to, 25 | uint deadline 26 | ) external payable returns (uint amountToken, uint amountHT, uint liquidity); 27 | function removeLiquidity( 28 | address tokenA, 29 | address tokenB, 30 | uint liquidity, 31 | uint amountAMin, 32 | uint amountBMin, 33 | address to, 34 | uint deadline 35 | ) external returns (uint amountA, uint amountB); 36 | function removeLiquidityHT( 37 | address token, 38 | uint liquidity, 39 | uint amountTokenMin, 40 | uint amountHTMin, 41 | address to, 42 | uint deadline 43 | ) external returns (uint amountToken, uint amountHT); 44 | function removeLiquidityWithPermit( 45 | address tokenA, 46 | address tokenB, 47 | uint liquidity, 48 | uint amountAMin, 49 | uint amountBMin, 50 | address to, 51 | uint deadline, 52 | bool approveMax, uint8 v, bytes32 r, bytes32 s 53 | ) external returns (uint amountA, uint amountB); 54 | function removeLiquidityHTWithPermit( 55 | address token, 56 | uint liquidity, 57 | uint amountTokenMin, 58 | uint amountHTMin, 59 | address to, 60 | uint deadline, 61 | bool approveMax, uint8 v, bytes32 r, bytes32 s 62 | ) external returns (uint amountToken, uint amountHT); 63 | function swapExactTokensForTokens( 64 | uint amountIn, 65 | uint amountOutMin, 66 | address[] calldata path, 67 | address to, 68 | uint deadline 69 | ) external returns (uint[] memory amounts); 70 | function swapTokensForExactTokens( 71 | uint amountOut, 72 | uint amountInMax, 73 | address[] calldata path, 74 | address to, 75 | uint deadline 76 | ) external returns (uint[] memory amounts); 77 | function swapExactHTForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 78 | external 79 | payable 80 | returns (uint[] memory amounts); 81 | function swapTokensForExactHT(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 82 | external 83 | returns (uint[] memory amounts); 84 | function swapExactTokensForHT(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 85 | external 86 | returns (uint[] memory amounts); 87 | function swapHTForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 88 | external 89 | payable 90 | returns (uint[] memory amounts); 91 | 92 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 93 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 94 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 95 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 96 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 97 | } -------------------------------------------------------------------------------- /contracts/uniswapv2/libraries/UniswapV2Library.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | import '../interfaces/IUniswapV2Pair.sol'; 6 | 7 | import "./SafeMath.sol"; 8 | 9 | library UniswapV2Library { 10 | using SafeMathUniswap for uint; 11 | 12 | // returns sorted token addresses, used to handle return values from pairs sorted in this order 13 | function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { 14 | require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); 15 | (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 16 | require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); 17 | } 18 | 19 | // calculates the CREATE2 address for a pair without making any external calls 20 | function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { 21 | (address token0, address token1) = sortTokens(tokenA, tokenB); 22 | pair = address(uint(keccak256(abi.encodePacked( 23 | hex'ff', 24 | factory, 25 | keccak256(abi.encodePacked(token0, token1)), 26 | hex'c109ad0262416bd34b17cc00feda5fa51c2a97264a7b53e4421343f2d9255531' // init code hash 27 | )))); 28 | } 29 | 30 | // fetches and sorts the reserves for a pair 31 | function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { 32 | (address token0,) = sortTokens(tokenA, tokenB); 33 | (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves(); 34 | (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); 35 | } 36 | 37 | // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset 38 | function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { 39 | require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); 40 | require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 41 | amountB = amountA.mul(reserveB) / reserveA; 42 | } 43 | 44 | // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset 45 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { 46 | require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); 47 | require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 48 | uint amountInWithFee = amountIn.mul(997); 49 | uint numerator = amountInWithFee.mul(reserveOut); 50 | uint denominator = reserveIn.mul(1000).add(amountInWithFee); 51 | amountOut = numerator / denominator; 52 | } 53 | 54 | // given an output amount of an asset and pair reserves, returns a required input amount of the other asset 55 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { 56 | require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); 57 | require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 58 | uint numerator = reserveIn.mul(amountOut).mul(1000); 59 | uint denominator = reserveOut.sub(amountOut).mul(997); 60 | amountIn = (numerator / denominator).add(1); 61 | } 62 | 63 | // performs chained getAmountOut calculations on any number of pairs 64 | function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { 65 | require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); 66 | amounts = new uint[](path.length); 67 | amounts[0] = amountIn; 68 | for (uint i; i < path.length - 1; i++) { 69 | (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); 70 | amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); 71 | } 72 | } 73 | 74 | // performs chained getAmountIn calculations on any number of pairs 75 | function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { 76 | require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); 77 | amounts = new uint[](path.length); 78 | amounts[amounts.length - 1] = amountOut; 79 | for (uint i = path.length - 1; i > 0; i--) { 80 | (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); 81 | amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/Repurchase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.12; 3 | import "@openzeppelin/contracts/access/Ownable.sol"; 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 6 | import "@openzeppelin/contracts/utils/EnumerableSet.sol"; 7 | import './interfaces/IBXH.sol'; 8 | import './uniswapv2/interfaces/IUniswapV2Pair.sol'; 9 | import "./DelegateERC20.sol"; 10 | 11 | contract Repurchase is Ownable { 12 | using SafeMath for uint256; 13 | using SafeERC20 for IERC20; 14 | 15 | using EnumerableSet for EnumerableSet.AddressSet; 16 | EnumerableSet.AddressSet private _caller; 17 | 18 | address public constant USDT = 0xa71EdC38d189767582C38A3145b5873052c3e47a; 19 | address public constant BXH = 0xcBD6Cb9243d8e3381Fea611EF023e17D1B7AeDF0; 20 | address public constant BXH_USDT = 0x8611a52e8AC5E10651DF7C4b58F42536f0bd2e7E; 21 | address public constant blackHoleAddress = 0x456D9eFa4f8039De66C8fD4a6d22953D33C6977d; 22 | address public constant DAOAddress = 0x0Ef67c16904Af312796560dF80E60581C43C4e24; 23 | address public emergencyAddress; 24 | uint256 public amountIn; 25 | 26 | constructor (uint256 _amount, address _emergencyAddress) public { 27 | require(_amount > 0, "Amount must be greater than zero"); 28 | require(_emergencyAddress != address(0), "Is zero address"); 29 | amountIn = _amount; 30 | emergencyAddress = _emergencyAddress; 31 | } 32 | 33 | function setAmountIn(uint256 _newIn) public onlyOwner { 34 | amountIn = _newIn; 35 | } 36 | 37 | function setEmergencyAddress(address _newAddress) public onlyOwner { 38 | require(_newAddress != address(0), "Is zero address"); 39 | emergencyAddress = _newAddress; 40 | } 41 | 42 | function addCaller(address _newCaller) public onlyOwner returns (bool) { 43 | require(_newCaller != address(0), "NewCaller is the zero address"); 44 | return EnumerableSet.add(_caller, _newCaller); 45 | } 46 | 47 | function delCaller(address _delCaller) public onlyOwner returns (bool) { 48 | require(_delCaller != address(0), "DelCaller is the zero address"); 49 | return EnumerableSet.remove(_caller, _delCaller); 50 | } 51 | 52 | function getCallerLength() public view returns (uint256) { 53 | return EnumerableSet.length(_caller); 54 | } 55 | 56 | function isCaller(address _call) public view returns (bool) { 57 | return EnumerableSet.contains(_caller, _call); 58 | } 59 | 60 | function getCaller(uint256 _index) public view returns (address){ 61 | require(_index <= getCallerLength() - 1, "index out of bounds"); 62 | return EnumerableSet.at(_caller, _index); 63 | } 64 | function swapV() external view returns (uint256 amountOut){ 65 | 66 | // require(IERC20(USDT).balanceOf(address(this)) >= amountIn, "Insufficient contract balance"); 67 | uint256 amountHalf = amountIn.div(2); 68 | { 69 | (uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(BXH_USDT).getReserves(); 70 | uint256 amountInWithFee = amountHalf.mul(997); 71 | amountOut = amountHalf.mul(997).mul(reserve0) / reserve1.mul(1000).add(amountInWithFee); 72 | //IERC20(USDT).safeTransfer(BXH_USDT, amountHalf); 73 | // IUniswapV2Pair(BXH_USDT).swap(amountOut, 0, blackHoleAddress, new bytes(0)); 74 | } 75 | } 76 | 77 | function swap() external onlyCaller returns (uint256 amountOut){ 78 | require(IERC20(USDT).balanceOf(address(this)) >= amountIn, "Insufficient contract balance"); 79 | uint256 amountHalf = amountIn.div(2); 80 | { 81 | (uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(BXH_USDT).getReserves(); 82 | uint256 amountInWithFee = amountHalf.mul(997); 83 | amountOut = amountHalf.mul(997).mul(reserve1) / reserve0.mul(1000).add(amountInWithFee); 84 | IERC20(USDT).safeTransfer(BXH_USDT, amountHalf); 85 | IUniswapV2Pair(BXH_USDT).swap(0, amountOut, blackHoleAddress, new bytes(0)); 86 | } 87 | 88 | { 89 | (uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(BXH_USDT).getReserves(); 90 | uint256 amountInWithFee = amountHalf.mul(997); 91 | amountOut = amountHalf.mul(997).mul(reserve1) / reserve0.mul(1000).add(amountInWithFee); 92 | IERC20(USDT).safeTransfer(BXH_USDT, amountHalf); 93 | IUniswapV2Pair(BXH_USDT).swap(0, amountOut, DAOAddress, new bytes(0)); 94 | 95 | } 96 | 97 | } 98 | 99 | modifier onlyCaller() { 100 | require(isCaller(msg.sender), "Not the caller"); 101 | _; 102 | } 103 | 104 | function emergencyWithdraw(address _token) public onlyOwner { 105 | require(IERC20(_token).balanceOf(address(this)) > 0, "Insufficient contract balance"); 106 | IERC20(_token).transfer(emergencyAddress, IERC20(_token).balanceOf(address(this))); 107 | } 108 | } 109 | 110 | -------------------------------------------------------------------------------- /contracts/timelock/TeamTimeLock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.6; 4 | 5 | import '@openzeppelin/contracts/math/SafeMath.sol'; 6 | import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; 7 | import '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; 8 | import "@openzeppelin/contracts/access/Ownable.sol"; 9 | 10 | 11 | contract TeamTimeLock is Ownable{ 12 | using SafeMath for uint256; 13 | using SafeERC20 for IERC20; 14 | 15 | IERC20 public token; 16 | uint256 public blockReward; // Monthly rewards are fixed 17 | uint256 public startBlock; 18 | uint256 public endBlock; 19 | uint256 public rewardDept; // Rewards already withdrawn 20 | //address public beneficiary; 21 | string public introduce; 22 | uint256 public maxReward; 23 | 24 | // Info of each user. 25 | struct UserInfo { 26 | uint256 amount; // How many LP tokens the user has provided. 27 | uint256 rewardDebt; // Reward debt. 28 | } 29 | 30 | mapping(address => UserInfo) userInfos; 31 | uint256 public totalShare; 32 | bool public paused; 33 | 34 | event WithDraw(address indexed operator, address indexed to, uint256 amount); 35 | 36 | constructor( 37 | address _token, 38 | uint256 _maxReward, 39 | uint256 _startBlock, 40 | uint256 _endBlock, 41 | string memory _introduce 42 | ) public { 43 | require(_maxReward > 0, "TimeLock: _maxReward is zero"); 44 | token = IERC20(_token); 45 | maxReward = _maxReward.mul(1e18); 46 | blockReward = maxReward.div(_endBlock.sub(_startBlock)); 47 | startBlock = _startBlock; 48 | endBlock = _endBlock; 49 | rewardDept = 0; 50 | introduce = _introduce; 51 | paused = true; 52 | } 53 | 54 | function initParams(uint256 _maxReward, 55 | uint256 _startBlock, 56 | uint256 _endBlock) public onlyOwner { 57 | require(paused == true, "Benifit has been started"); 58 | 59 | maxReward = _maxReward.mul(1e18); 60 | blockReward = maxReward.div(_endBlock.sub(_startBlock)); 61 | startBlock = _startBlock; 62 | endBlock = _endBlock; 63 | rewardDept = 0; 64 | 65 | } 66 | 67 | 68 | modifier notPause() { 69 | require(paused == false, "Benifit has been suspended"); 70 | _; 71 | } 72 | 73 | 74 | function setPause() public onlyOwner { 75 | paused = !paused; 76 | } 77 | 78 | function addUser(address addr,uint256 amount) public onlyOwner{ 79 | require(paused,"benefit is running"); 80 | 81 | UserInfo storage user = userInfos[addr]; 82 | user.amount = user.amount.add(amount); 83 | totalShare = totalShare.add(amount); 84 | 85 | } 86 | 87 | function removeUser(address addr,uint256 amount) public onlyOwner{ 88 | require(paused,"benefit is running"); 89 | UserInfo storage user = userInfos[addr]; 90 | require(user.amount > 0 , "user not beneficiary"); 91 | totalShare = totalShare.sub(amount); 92 | user.amount = user.amount.sub(amount); 93 | } 94 | 95 | function getBalance() public view returns (uint256) { 96 | return token.balanceOf(address(this)); 97 | } 98 | 99 | 100 | function getCurrentUserReward(address addr) public notPause view returns (uint256) { 101 | uint256 reward = getReward(addr,block.number); 102 | 103 | if(reward <= token.balanceOf(address(this))){ 104 | return reward; 105 | } 106 | 107 | return token.balanceOf(address(this)); 108 | 109 | } 110 | 111 | 112 | 113 | function getTotalReward(uint256 blocknumber) public notPause view returns (uint256) { 114 | if (blocknumber <= startBlock) { 115 | return 0; 116 | } 117 | 118 | uint256 totalReward= blocknumber.sub(startBlock).mul(blockReward); 119 | if(totalReward >= maxReward ){ 120 | return maxReward; 121 | } 122 | return totalReward; 123 | } 124 | 125 | 126 | function getReward(address addr,uint256 blocknumber) public notPause view returns (uint256) { 127 | 128 | UserInfo storage user = userInfos[addr]; 129 | if(user.amount==0){ 130 | return 0; 131 | } 132 | uint256 totalReward=getTotalReward(blocknumber); 133 | uint256 reward = totalReward.mul(user.amount).div(totalShare).sub(user.rewardDebt); 134 | return reward; 135 | } 136 | 137 | 138 | 139 | function withDraw(address beneficiary) notPause external { 140 | UserInfo storage user = userInfos[beneficiary]; 141 | require(user.amount>0,"user amount zero"); 142 | uint256 reward = getCurrentUserReward(beneficiary); 143 | require(reward > 0, "TimeLock: no reward"); 144 | user.rewardDebt = user.rewardDebt.add(reward); 145 | token.safeTransfer(beneficiary, reward); 146 | emit WithDraw(msg.sender, beneficiary, reward); 147 | 148 | } 149 | 150 | 151 | } 152 | -------------------------------------------------------------------------------- /scripts/test_starmaking.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | const web3 = require('web3'); 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | var provider = ethers.provider; 15 | const accounts = await ethers.getSigners(); 16 | const StarMaking = await hre.ethers.getContractFactory("StarMaking"); 17 | // const raiseDao = await RaiseDAO.attach(addrs.raiseDao); 18 | 19 | // console.log("RaiseDAO attach to:", raiseDao.address); 20 | 21 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 22 | 23 | const bxh = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HBTC Token","bxh",18); 24 | await bxh.deployed(); 25 | 26 | console.log("bxh deployed to:", bxh.address); 27 | 28 | const star = await StarMaking.deploy(accounts[0].address,bxh.address); 29 | await star.deployed(); 30 | console.log("StarMaking deployed to:", star.address); 31 | await star.addCaller(accounts[0].address); 32 | 33 | var projectAddrs = []; 34 | var projectNum = 10; 35 | for(var i=0;i process.exit(0)) 154 | .catch(error => { 155 | console.error(error); 156 | process.exit(1); 157 | }); 158 | -------------------------------------------------------------------------------- /contracts/airdrop.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.0; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts/math/SafeMath.sol"; 8 | 9 | library TransferHelper { 10 | function safeApprove(address token, address to, uint value) internal { 11 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 12 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 13 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 14 | } 15 | 16 | function safeTransfer(address token, address to, uint value) internal { 17 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 18 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 19 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 20 | } 21 | 22 | function safeTransferFrom(address token, address from, address to, uint value) internal { 23 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 24 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 25 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 26 | } 27 | } 28 | 29 | contract Airdrop is Ownable { 30 | using SafeMath for uint256; 31 | using SafeERC20 for IERC20; 32 | 33 | struct UserInfo { 34 | uint256 amount; 35 | uint256 rewardDebt; 36 | } 37 | 38 | struct PeriodInfo { 39 | uint256 startBlock; 40 | uint256 endBlock; 41 | uint256 price; 42 | uint256 rewardPerUser; 43 | uint256 totalReward; 44 | uint256 totalAlloc; 45 | uint256 totalRequest; 46 | } 47 | 48 | address public usdt; 49 | address public bxh; 50 | 51 | // Info of each pool. 52 | PeriodInfo[] public peroidInfo; 53 | // Info of each user that tokens. 54 | mapping(uint256 => mapping(address => UserInfo)) public userInfo; 55 | 56 | mapping(uint256 => mapping(address => UserInfo)) public userRequestInfo; 57 | 58 | // Total allocation points. Must be the sum of all allocation points in all pools. 59 | uint256 public totalAllocAmount = 0; 60 | uint256 public totalRewardAmount = 0; 61 | uint256 public currentPeroid = 0; 62 | 63 | event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); 64 | event RequestWithdraw(address indexed user, uint256 indexed pid, uint256 amount); 65 | 66 | event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); 67 | 68 | constructor( 69 | address _usdt, 70 | address _bxh 71 | ) public { 72 | usdt = _usdt; 73 | bxh = _bxh; 74 | } 75 | 76 | function peroidLength() external view returns (uint256) { 77 | return peroidInfo.length; 78 | } 79 | 80 | function newAirdrop(uint256 _startBlock,uint256 _endBlock,uint256 _price,uint256 _rewardPerUser,uint256 _totalReward) public onlyOwner { 81 | //require(block.number > endBlock && _startBlock >= endBlock, "Not finished"); 82 | 83 | TransferHelper.safeTransferFrom(address(bxh), msg.sender, address(this), _totalReward); 84 | 85 | currentPeroid = peroidInfo.length; 86 | 87 | peroidInfo.push(PeriodInfo({ 88 | startBlock : _startBlock, 89 | endBlock : _endBlock, 90 | price : _price, 91 | rewardPerUser: _rewardPerUser, 92 | totalReward: _totalReward, 93 | totalAlloc: 0, 94 | totalRequest: 0 95 | })); 96 | 97 | } 98 | 99 | // Deposit USDT tokens to withdraw bxh; 100 | function withdraw() public onlyOwner { 101 | 102 | require(currentPeroid < peroidInfo.length,"No AirDrops"); 103 | 104 | PeriodInfo storage peroid = peroidInfo[currentPeroid]; 105 | require(block.number >= peroid.startBlock,"Not Started"); 106 | require(block.number <= peroid.endBlock,"AirDrop Peroid Ended"); 107 | require(peroid.totalAlloc.add(peroid.rewardPerUser)= peroid.startBlock,"Not Started"); 129 | require(block.number <= peroid.endBlock,"AirDrop Peroid Ended"); 130 | // require(peroid.totalAlloc.add(peroid.rewardPerUser) UserDelegateInfo) public userDelegateInfos; 34 | 35 | BXHPool public bxhPool; 36 | 37 | uint256 public totalLP; 38 | 39 | uint256 public pid; 40 | constructor( 41 | address _lpToken, 42 | address _bxhPool, 43 | uint256 _pid, 44 | address _emergencyAddress 45 | 46 | )public { 47 | lpToken=_lpToken; 48 | bxhPool = BXHPool(_bxhPool); 49 | pid=_pid; 50 | emergencyAddress=_emergencyAddress; 51 | } 52 | function setPid(uint256 _pid) onlyOwner public { 53 | pid=_pid; 54 | } 55 | 56 | //calc to burn; 57 | function depositLPToken(uint256 _amount) public payable returns(uint256 feeAmount,uint256 amount0,uint256 amount1) { 58 | require(_amount > 0,'deposit token must large than 0'); 59 | uint256 _before = IERC20(lpToken).balanceOf(address(this)); 60 | IERC20(lpToken).safeTransferFrom(msg.sender, address(this), _amount); 61 | uint256 _after = IERC20(lpToken).balanceOf(address(this)); 62 | _amount = _after.sub(_before); 63 | 64 | UserDelegateInfo storage userInfo = userDelegateInfos[msg.sender]; 65 | 66 | (uint112 _reserve0, uint112 _reserve1,) = UniswapV2Pair(lpToken).getReserves(); // gas savings 67 | if(userInfo.lpAmount>0){ 68 | // 69 | uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); 70 | uint rootKLast = Math.sqrt(userInfo.kLast); 71 | if (rootK > rootKLast) { 72 | uint numerator = UniswapV2Pair(lpToken).totalSupply().mul(rootK.sub(rootKLast)); 73 | uint denominator = rootK.mul(2).add(rootKLast); 74 | uint liquidity = numerator / denominator; 75 | // if (liquidity > 0) _mint(feeTo, liquidity); 76 | userInfo.lpShared = userInfo.lpShared.add(liquidity.add(liquidity)); 77 | require(userInfo.lpShared 0,'user lp token must large than 0'); 94 | require( userInfo.lpAmount > userInfo.lpShared,'user lp token must large shared'); 95 | 96 | uint256 lpShared = userInfo.lpShared ; 97 | (uint112 _reserve0, uint112 _reserve1,) = UniswapV2Pair(lpToken).getReserves(); // gas savings 98 | uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); 99 | uint rootKLast = Math.sqrt(userInfo.kLast); 100 | if (rootK > rootKLast) { 101 | uint numerator = UniswapV2Pair(lpToken).totalSupply().mul(rootK.sub(rootKLast)); 102 | uint denominator = rootK.mul(2).add(rootKLast); 103 | uint liquidity = numerator / denominator; 104 | // if (liquidity > 0) _mint(feeTo, liquidity); 105 | lpShared = userInfo.lpShared.add(liquidity.add(liquidity)); 106 | require(lpShared < userInfo.lpAmount,'share K error'); 107 | } 108 | 109 | lpReturn = userInfo.lpAmount.sub(lpShared); 110 | (uint256 totalBxhReturn,) = bxhPool.pending(pid,address(this)); 111 | bxhReturn = totalBxhReturn.mul(lpReturn).div(totalLP); 112 | 113 | } 114 | 115 | function withrawLPToken() public payable returns(uint256 lpReturn,uint256 bxhReturn){ 116 | 117 | UserDelegateInfo storage userInfo = userDelegateInfos[msg.sender]; 118 | require( userInfo.lpAmount > 0,'user lp token must large than 0'); 119 | require( userInfo.lpAmount > userInfo.lpShared,'user lp token must large shared'); 120 | 121 | (uint112 _reserve0, uint112 _reserve1,) = UniswapV2Pair(lpToken).getReserves(); // gas savings 122 | uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); 123 | uint rootKLast = Math.sqrt(userInfo.kLast); 124 | if (rootK > rootKLast) { 125 | uint numerator = UniswapV2Pair(lpToken).totalSupply().mul(rootK.sub(rootKLast)); 126 | uint denominator = rootK.mul(2).add(rootKLast); 127 | uint liquidity = numerator / denominator; 128 | // if (liquidity > 0) _mint(feeTo, liquidity); 129 | userInfo.lpShared = userInfo.lpShared.add(liquidity.add(liquidity)); 130 | require(userInfo.lpShared < userInfo.lpAmount,'share K error'); 131 | } 132 | 133 | lpReturn = userInfo.lpAmount.sub(userInfo.lpShared); 134 | 135 | // require( lpReturn<=UniswapV2Pair(lpToken).balanceOf(address(this)),'contract lp token must large than user lp token'); 136 | 137 | uint256 beforeToken = IERC20(address(bxhPool.bxh())).balanceOf(address(this)); 138 | bxhPool.withdraw(pid,userInfo.lpAmount); 139 | uint256 afterToken = IERC20(address(bxhPool.bxh())).balanceOf(address(this)); 140 | 141 | bxhReturn = afterToken.sub(beforeToken); 142 | 143 | totalLP = totalLP.sub(userInfo.lpAmount); 144 | 145 | userInfo.lpAmount = 0; 146 | userInfo.lpShared = 0; 147 | 148 | IUniswapV2Pair(lpToken).transfer(msg.sender, lpReturn); // send liquidity to pair 149 | IERC20(address(bxhPool.bxh())).transfer(msg.sender,bxhReturn); 150 | 151 | } 152 | 153 | 154 | function setEmergencyAddress(address _newAddress) public onlyOwner { 155 | require(_newAddress != address(0), "Is zero address"); 156 | emergencyAddress = _newAddress; 157 | } 158 | function emergencyWithdraw(address _token) public onlyOwner { 159 | require(IERC20(_token).balanceOf(address(this)) > 0, "Insufficient contract balance"); 160 | IERC20(_token).transfer(emergencyAddress, IERC20(_token).balanceOf(address(this))); 161 | } 162 | 163 | 164 | } -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require("@nomiclabs/hardhat-etherscan"); 3 | 4 | // This is a sample Hardhat task. To learn how to create your own go to 5 | // https://hardhat.org/guides/create-task.html 6 | 7 | require("brewchain_provider"); 8 | 9 | const accounts = { 10 | mnemonic: process.env.MNEMONIC || "test test test test test test test test test test test junk", 11 | initialIndex: 8 12 | // accountsBalance: "990000000000000000000", 13 | } 14 | 15 | task("accounts", "Prints the list of accounts", async () => { 16 | const accounts = await ethers.getSigners(); 17 | 18 | for (const account of accounts) { 19 | console.log(account.address); 20 | } 21 | }); 22 | 23 | // You need to export an object to set up your config 24 | // Go to https://hardhat.org/config/ to learn more 25 | 26 | /** 27 | * @type import('hardhat/config').HardhatUserConfig 28 | */ 29 | module.exports = { 30 | 31 | solidity: { 32 | compilers: [ 33 | { 34 | version: "0.6.12", 35 | settings: { 36 | optimizer: { 37 | enabled: true, 38 | runs: 200, 39 | }, 40 | }, 41 | }, 42 | { 43 | version: "0.5.17", 44 | settings: { 45 | optimizer: { 46 | enabled: true, 47 | runs: 200, 48 | }, 49 | }, 50 | }, 51 | ], 52 | }, 53 | spdxLicenseIdentifier: { 54 | overwrite: false, 55 | runOnCompile: true, 56 | }, 57 | etherscan: { 58 | // Your API key for Etherscan 59 | // Obtain one at https://etherscan.io/ 60 | apiKey:"6IQTZTMD392X2U2SYZBABWDS8KB6D8UD4T" 61 | }, 62 | defaultNetwork: "local", 63 | networks: { 64 | local: { 65 | url: `http://localhost:8545`, 66 | accounts, 67 | bxh:{ 68 | address:{ 69 | fee: "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199", 70 | usdt:"0x2E0716Bb0c304563A9B6fCfDb0F68853E2726ea9", 71 | husd:"0x93BC7B91095b858973E09840B9843f80e0D787c8", 72 | hbtc:"0x6D6d5aB9BC123eA4e158b4DEe3b2FBEcA653d210", 73 | heth:"0x4ce26bB44E7deca7ac251B9A417fd8fc3C9Ddb7f", 74 | hltc:"0xbB84aA7b4ccD3578a45BB3090E9c33709E135F1f", 75 | wht :"0x02894BfC9c0706e79A075034E773665E1DaAc232", 76 | hdot:"0x9bDfE084d23D3d1275AE961e3FD2E82A4d11Cd89", 77 | bxh :"0xa0E9406b961393d90D247B690ecAc709364ADA86", 78 | bxhpool:"0x2De757e2Aade1dEbA57Ee68ca69A5Dc6642551da", 79 | uniswap:{ 80 | factory:"0xBb032F40F0cF21236314ECB438dC38d06F936ec6", 81 | router:"0x0a0B85D9Ee736253348f266665845A915b398097", 82 | }, 83 | delp: "0x9eCdfEDA21F3100466e6695E6f74BBa6EDB19332", 84 | airdrop:"0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9", 85 | investTeamLock:"0xc582Bc0317dbb0908203541971a358c44b1F3766", 86 | marketTeamLock:"0x74Cf9087AD26D541930BaC724B7ab21bA8F00a27", 87 | devTeamLock:"0xA56F946D6398Dd7d9D4D9B337Cf9E0F68982ca5B", 88 | raiseDao:"0x98eDDadCfde04dC22a0e62119617e74a6Bc77313", 89 | } 90 | } 91 | }, 92 | mainnet: { 93 | url: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, 94 | gasPrice: 120 * 1000000000, 95 | chainId: 1, 96 | }, 97 | heco:{ 98 | url: `https://http-mainnet.hecochain.com`, 99 | accounts, 100 | gasPrice: 20*1000000000, 101 | chainId: 128, 102 | loggingEnabled: true, 103 | blockGasLimit:0x280de80, 104 | bxh:{ 105 | address:{ 106 | owner:"0xdEa9d2E81c9bb73c890A822F65118a3651c258D5", 107 | fee: "0xdEa9d2E81c9bb73c890A822F65118a3651c258D5", 108 | admin: "0xdEa9d2E81c9bb73c890A822F65118a3651c258D5", 109 | admin1: "0x56146B129017940D06D8e235c02285A3d05D6B7C", 110 | usdt:"0xa71edc38d189767582c38a3145b5873052c3e47a", 111 | husd:"0x0298c2b32eae4da002a15f36fdf7615bea3da047", 112 | hbtc:"0x66a79d23e58475d2738179ca52cd0b41d73f0bea", 113 | heth:"0x64ff637fb478863b7468bc97d30a5bf3a428a1fd", 114 | hltc:"0xecb56cf772b5c9a6907fb7d32387da2fcbfb63b4", 115 | wht :"0x5545153ccfca01fbd7dd11c0b23ba694d9509a6f", 116 | hdot:"0xa2c49cee16a5e5bdefde931107dc1fae9f7773e3", 117 | bxh :"0xcBD6Cb9243d8e3381Fea611EF023e17D1B7AeDF0", 118 | uniswap:{ 119 | factory:"0xB8617E2FC9dbFd51781B8D281b725976E3B43f9d", 120 | router:"0x00eFB96dBFE641246E961b472C0C3fC472f6a694", 121 | }, 122 | bxhpool: "0x55bf276e2a2e10AEB62c0Ed37D36585cB24d9cC1", 123 | airdrop:"0xcA1530D5282C703bf3c73c6A08794020dae8b397", 124 | airdropPool:"0x0Ef67c16904Af312796560dF80E60581C43C4e24", 125 | investTeamLock:"0xD7B6192601F6e671E42926797a2462a5b6B7b13d", 126 | marketTeamLock:"0xee73ae5C86fd78DbFF1e07a6e9e42D4F1EafDeb0", 127 | devTeamLock:"0x186Dc1ebF9281F98167cfD0A0794B9934587A142", 128 | raiseDao:"0x98eDDadCfde04dC22a0e62119617e74a6Bc77313", 129 | xtoken:"0x11Ca689B3aB2f0d28d95dE62bbbB384C4173c893", 130 | daopool:"0x2f15fD83710aD8E9ea5E1A25ba05942Eaf389307", 131 | daov3:"0x6c9985eB3288f3E89E54ceeE818028aB81e532bC", 132 | 133 | } 134 | }, 135 | }, 136 | hecolocal:{ 137 | url: `http://94.74.87.188:8545`, 138 | accounts, 139 | gasPrice: 0x3b9aca00, 140 | chainId: 3388, 141 | bxh:{ 142 | address:{ 143 | fee: "f39fd6e51aad88f6f4ce6ab8827279cfffb92266", 144 | usdt:"e7f1725E7734CE288F8367e1Bb143E90bb3F0512", 145 | husd:"9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", 146 | hbtc:"Cf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", 147 | heth:"Dc64a140Aa3E981100a9becA4E685f962f0cF6C9", 148 | hltc:"5FC8d32690cc91D4c39d9d3abcBD16989F875707", 149 | wht :"0165878A594ca255338adfa4d48449f69242Eb8F", 150 | hdot:"a513E6E4b8f2a923D98304ec87F64353C4D5C853", 151 | bxh :"1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8", 152 | uniswap:{ 153 | factory:"851356ae760d987E095750cCeb3bC6014560891C", 154 | router:"95401dc811bb5740090279Ba06cfA8fcF6113778", 155 | }, 156 | bxhpool: "4826533B4897376654Bb4d4AD88B7faFD0C98528", 157 | airdrop:"70e0bA845a1A0F2DA3359C97E0285013525FFC49", 158 | investTeamLock:"0x0ed64d01D0B4B655E410EF1441dD677B695639E7", 159 | marketTeamLock:"0xde2Bd2ffEA002b8E84ADeA96e5976aF664115E2c", 160 | devTeamLock:"0xc582Bc0317dbb0908203541971a358c44b1F3766", 161 | 162 | } 163 | }, 164 | }, 165 | brewchain:{ 166 | url:"http://localhost:8000", 167 | accounts, 168 | gasPrice: 20*1000000000, 169 | chainId: 128, 170 | loggingEnabled: true, 171 | blockGasLimit:0x280de80, 172 | bxh:{ 173 | address:{ 174 | fee: "0xD8b60b2d2FEE9bda23ed03a66154077328863c71", 175 | usdt:"0x9BAE23D58C9f528e0Bb517153374538042b4750F", 176 | husd:"0xd3bA38D99DB3649eD337a873B051DB544976F8Bc", 177 | hbtc:"0x04E39BA4c07Aa1A3a45995aF76d8376155Dac229", 178 | heth:"0x16Ab21A0246A31D21E776f739Bade4d0eE985606", 179 | hltc:"0xB563231B650A5391Ff61fb401B0B4d0e68895a90", 180 | wht :"0xd886ab0c60EBB4f344F6316FaB63476265be613B", 181 | hdot:"0x67ac8de54d9a723Fb6dE2954FE1110Ec33bbb52E", 182 | bxh :"0x5CcCBefE4BD2B52A232639cB3eA79e5C2153c970", 183 | uniswap:{ 184 | factory:"0x632701B718480868c3db574B4c69F1415b45a73a", 185 | router: "0x9dD214014CbE19384da60526800aFc7607c26CAF", 186 | }, 187 | bxhpool: "4826533B4897376654Bb4d4AD88B7faFD0C98528", 188 | airdrop:"70e0bA845a1A0F2DA3359C97E0285013525FFC49", 189 | investTeamLock:"0x0ed64d01D0B4B655E410EF1441dD677B695639E7", 190 | marketTeamLock:"0xde2Bd2ffEA002b8E84ADeA96e5976aF664115E2c", 191 | devTeamLock:"0xc582Bc0317dbb0908203541971a358c44b1F3766", 192 | 193 | } 194 | }, 195 | }, 196 | } 197 | }; 198 | 199 | -------------------------------------------------------------------------------- /scripts/test_raise_dao.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | const web3 = require('web3'); 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | const RaiseDAO = await hre.ethers.getContractFactory("RaiseDAO"); 17 | // const raiseDao = await RaiseDAO.attach(addrs.raiseDao); 18 | 19 | // console.log("RaiseDAO attach to:", raiseDao.address); 20 | const raiseDao = await RaiseDAO.deploy(); 21 | await raiseDao.deployed(); 22 | console.log("RaiseDAO deployed to:", raiseDao.address); 23 | 24 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 25 | 26 | const lpToken = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"Heco-Peg HBTC Token","LPSwap",18); 27 | await lpToken.deployed(); 28 | console.log("lpToken deployed to:", lpToken.address); 29 | 30 | const offeringToken = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"offeringToken","OFT",18); 31 | await offeringToken.deployed(); 32 | console.log("HETH deployed to:", offeringToken.address); 33 | 34 | 35 | var provider = ethers.provider; 36 | 37 | var offeringAmount = 100000; 38 | var raisingAmount = 1000; 39 | 40 | 41 | await offeringToken.mint(accounts[0].address,offeringAmount*1000); 42 | 43 | for(var i=0;i setTimeout(r, 2000)); 48 | // console.log("current blocknumber=",blockNumber); 49 | } 50 | var blockNumber = await provider.getBlockNumber(); 51 | console.log("current blocknumber=",blockNumber); 52 | for(var i=0;i process.exit(0)) 207 | .catch(error => { 208 | console.error(error); 209 | process.exit(1); 210 | }); 211 | -------------------------------------------------------------------------------- /scripts/test_v3bxhDaoPool.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | 7 | 8 | const web3 = require('web3'); 9 | 10 | 11 | async function main() { 12 | 13 | const addrs = hre.network.config.bxh.address; 14 | 15 | const accounts = await ethers.getSigners(); 16 | 17 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 18 | 19 | const dtoken = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"deposit token","DToken",18); 20 | await dtoken.deployed(); 21 | console.log("dtoken deployed to:", dtoken.address); 22 | 23 | const bonusToken = await ERC20Template.deploy(accounts[0].address,accounts[0].address,"BonusToken","USDT",18); 24 | await bonusToken.deployed(); 25 | console.log("bonusToken deployed to:", bonusToken.address); 26 | 27 | var provider = ethers.provider; 28 | 29 | const BXHDAOPoolV3 = await hre.ethers.getContractFactory("BXHDAOPoolV3"); 30 | 31 | 32 | for(var i=0;i<10;i++) 33 | { 34 | await dtoken.mint(accounts[i%(accounts.length)].address,web3.utils.toWei('100','ether')); 35 | } 36 | await bonusToken.mint(accounts[0].address,web3.utils.toWei('10000000','ether')); 37 | 38 | var outbalances =async function(){ 39 | for(var i=0;i process.exit(0)) 173 | .catch(error => { 174 | console.error(error); 175 | process.exit(1); 176 | }); 177 | -------------------------------------------------------------------------------- /contracts/StarMaking.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.12; 3 | import "@openzeppelin/contracts/access/Ownable.sol"; 4 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 5 | import "@openzeppelin/contracts/utils/EnumerableSet.sol"; 6 | import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; 7 | 8 | contract StarMaking is Ownable,ReentrancyGuard{ 9 | using SafeMath for uint256; 10 | using SafeERC20 for IERC20; 11 | 12 | using EnumerableSet for EnumerableSet.AddressSet; 13 | EnumerableSet.AddressSet private _caller; 14 | 15 | IERC20 public BXH; 16 | uint8 public constant TOPNUM = 3; 17 | 18 | // vote for project 19 | struct ProjectVotes{ 20 | uint256 voteAmount; //bxh amount 21 | uint256 addressCount;// user address count 22 | uint256 createdBlockNumber;// created log when add to phase 23 | } 24 | 25 | 26 | struct Phase{ 27 | uint256 blockStart; // 28 | uint256 blockEnd; 29 | uint256 blockLocked;//when to release vote coin. 14 days = 403200 30 | uint256 totalVoteAmount; // total vote 31 | uint256 totalAddrCount;//total address 32 | uint256 totalWithdrawAmount;// total amount for withdraw 33 | bool stopped; // is stops? 34 | } 35 | 36 | address public emergencyAddress; 37 | 38 | mapping(uint=>Phase) public phases; //id to phase, id like 20210411, 20210405... 39 | 40 | mapping(uint=>mapping(address=>ProjectVotes)) public projectVotes; // (phaseid =>( project address ==> project vote )) voting logs; 41 | 42 | mapping(address=>mapping(uint256=>mapping(address=>uint256))) public userPhaseProjectVotes; // (useraddr ==> (phaseid ==> project==>vote amount)) voting amount for user in projects; 43 | 44 | mapping(address=>mapping(uint256=>uint256)) public userPhaseVotes; // (useraddr ==> (phaseid ==> vote amount)) voting amount for user; 45 | mapping(address=>mapping(uint256=>bool)) public userPhaseWithdrawed;// (useraddr ==> (phaseid ==> vote amount)) withdraw flag for user; 46 | 47 | mapping(uint => address[]) public phaseProjectList; //(phaseid ==> project address list) project list for phase 48 | 49 | 50 | constructor (address _emergencyAddress,address _bxh) public { 51 | emergencyAddress = _emergencyAddress; 52 | BXH = IERC20(_bxh); 53 | 54 | } 55 | 56 | //manager interface 57 | function setEmergencyAddress(address _newAddress) public onlyOwner { 58 | require(_newAddress != address(0), "Is zero address"); 59 | emergencyAddress = _newAddress; 60 | addCaller(msg.sender); 61 | } 62 | 63 | function addCaller(address _newCaller) public onlyOwner returns (bool) { 64 | require(_newCaller != address(0), "NewCaller is the zero address"); 65 | return EnumerableSet.add(_caller, _newCaller); 66 | } 67 | 68 | function delCaller(address _delCaller) public onlyOwner returns (bool) { 69 | require(_delCaller != address(0), "DelCaller is the zero address"); 70 | return EnumerableSet.remove(_caller, _delCaller); 71 | } 72 | 73 | function getCallerLength() public view returns (uint256) { 74 | return EnumerableSet.length(_caller); 75 | } 76 | 77 | function isCaller(address _call) public view returns (bool) { 78 | return EnumerableSet.contains(_caller, _call); 79 | } 80 | 81 | function getCaller(uint256 _index) public view returns (address){ 82 | require(_index <= getCallerLength() - 1, "index out of bounds"); 83 | return EnumerableSet.at(_caller, _index); 84 | } 85 | 86 | modifier onlyCaller() { 87 | require(isCaller(msg.sender), "Not the caller"); 88 | _; 89 | } 90 | 91 | function emergencyWithdraw(address _token) public onlyOwner { 92 | require(IERC20(_token).balanceOf(address(this)) > 0, "Insufficient contract balance"); 93 | IERC20(_token).transfer(emergencyAddress, IERC20(_token).balanceOf(address(this))); 94 | } 95 | 96 | 97 | 98 | // add phase with parameters; 99 | function addPhase(uint _phaseId,uint256 _blockStart,uint256 _blockEnd,uint _blockLocked) public onlyCaller{ 100 | require(_blockStart > block.number,"cannot add phase before current blocknumber"); 101 | require(_blockEnd > _blockStart,"block end should be larged than block start"); 102 | require(phases[_phaseId].blockStart == 0,"phase id exists"); 103 | if(_blockLocked==0){ 104 | _blockLocked = _blockEnd+403200; 105 | } 106 | phases[_phaseId] = Phase({blockStart:_blockStart,blockEnd:_blockEnd,blockLocked:_blockLocked,totalVoteAmount:0,totalAddrCount:0,totalWithdrawAmount:0,stopped:false}); 107 | } 108 | 109 | 110 | // add phase project , can call multiply times before vote start 111 | function addPhaseProjects(uint _phaseId,address[] memory addrs) public onlyCaller{ 112 | require(phases[_phaseId].blockStart > 0, "phase not found"); 113 | require(phases[_phaseId].blockStart > block.number, "phase already started"); 114 | require(addrs.length> 0,"project none"); 115 | uint length = addrs.length; 116 | uint blocknumber = block.number; 117 | for(uint i=0;i0, "phase not found"); 134 | phases[_phaseId].stopped = stopped; 135 | } 136 | 137 | 138 | // user vote project with bxh amount 139 | function userVoteProject(uint _phaseId,address _projectAddr,uint256 amount) payable public returns (uint256){ 140 | require(phases[_phaseId].blockStart <= block.number, "phase not start"); 141 | require(phases[_phaseId].blockEnd >= block.number, "phase ended"); 142 | require(!phases[_phaseId].stopped,"phase stopped"); 143 | 144 | require(projectVotes[_phaseId][_projectAddr].createdBlockNumber > 0,"project not found in this phase"); 145 | // require(amount>=1e18,"vote amount should large than 1"); 146 | 147 | BXH.safeTransferFrom(msg.sender,address(this),amount); 148 | if(userPhaseVotes[msg.sender][_phaseId]==0){ 149 | phases[_phaseId].totalAddrCount = phases[_phaseId].totalAddrCount.add(1); 150 | projectVotes[_phaseId][_projectAddr].addressCount = projectVotes[_phaseId][_projectAddr].addressCount.add(1); 151 | } 152 | phases[_phaseId].totalVoteAmount = phases[_phaseId].totalVoteAmount.add(amount); 153 | userPhaseVotes[msg.sender][_phaseId] = userPhaseVotes[msg.sender][_phaseId].add(amount); 154 | userPhaseProjectVotes[msg.sender][_phaseId][_projectAddr] = userPhaseProjectVotes[msg.sender][_phaseId][_projectAddr].add(amount); 155 | projectVotes[_phaseId][_projectAddr].voteAmount = projectVotes[_phaseId][_projectAddr].voteAmount.add(amount); 156 | 157 | 158 | return phases[_phaseId].totalVoteAmount; 159 | } 160 | 161 | 162 | function projectCount(uint _phaseId) public view returns (uint256){ 163 | return phaseProjectList[_phaseId].length; 164 | } 165 | 166 | function projectVoteInfo(uint _phaseId,uint _sortedIdx) public view returns (address addr,uint256 voteAmount){ 167 | addr = phaseProjectList[_phaseId][_sortedIdx]; 168 | voteAmount = projectVotes[_phaseId][addr].voteAmount; 169 | } 170 | 171 | 172 | //user withraw vote amount after phase end and lock time . 173 | function userWithdraw(uint _phaseId) nonReentrant public returns (uint256){ 174 | require(phases[_phaseId].blockLocked > 0 && phases[_phaseId].blockLocked <= block.number, "phase withdraw locked"); 175 | require(!userPhaseWithdrawed[msg.sender][_phaseId],"user already withdraw"); 176 | require(!phases[_phaseId].stopped,"phase stopped"); 177 | 178 | uint256 amount = userPhaseVotes[msg.sender][_phaseId]; 179 | require(phases[_phaseId].totalWithdrawAmount.add(amount)<=phases[_phaseId].totalVoteAmount,"phase withdraw exceed max vote Amount"); 180 | userPhaseWithdrawed[msg.sender][_phaseId] = true; 181 | phases[_phaseId].totalWithdrawAmount = phases[_phaseId].totalWithdrawAmount.add(amount); 182 | BXH.transfer(msg.sender,amount); 183 | return amount; 184 | } 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | } -------------------------------------------------------------------------------- /contracts/DelegateERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | 4 | pragma solidity ^0.6.0; 5 | 6 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 7 | pragma experimental ABIEncoderV2; 8 | 9 | abstract contract DelegateERC20 is ERC20 { 10 | // @notice A record of each accounts delegate 11 | mapping (address => address) internal _delegates; 12 | 13 | /// @notice A checkpoint for marking number of votes from a given block 14 | struct Checkpoint { 15 | uint32 fromBlock; 16 | uint256 votes; 17 | } 18 | 19 | /// @notice A record of votes checkpoints for each account, by index 20 | mapping (address => mapping (uint32 => Checkpoint)) public checkpoints; 21 | 22 | /// @notice The number of checkpoints for each account 23 | mapping (address => uint32) public numCheckpoints; 24 | 25 | /// @notice The EIP-712 typehash for the contract's domain 26 | bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); 27 | 28 | /// @notice The EIP-712 typehash for the delegation struct used by the contract 29 | bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); 30 | 31 | /// @notice A record of states for signing / validating signatures 32 | mapping (address => uint) public nonces; 33 | 34 | 35 | // support delegates mint 36 | function _mint(address account, uint256 amount) internal override virtual { 37 | super._mint(account, amount); 38 | 39 | // add delegates to the minter 40 | _moveDelegates(address(0), _delegates[account], amount); 41 | } 42 | 43 | 44 | function _transfer(address sender, address recipient, uint256 amount) internal override virtual { 45 | super._transfer(sender, recipient, amount); 46 | _moveDelegates(_delegates[sender], _delegates[recipient], amount); 47 | } 48 | 49 | 50 | /** 51 | * @notice Delegate votes from `msg.sender` to `delegatee` 52 | * @param delegatee The address to delegate votes to 53 | */ 54 | function delegate(address delegatee) external { 55 | return _delegate(msg.sender, delegatee); 56 | } 57 | 58 | /** 59 | * @notice Delegates votes from signatory to `delegatee` 60 | * @param delegatee The address to delegate votes to 61 | * @param nonce The contract state required to match the signature 62 | * @param expiry The time at which to expire the signature 63 | * @param v The recovery byte of the signature 64 | * @param r Half of the ECDSA signature pair 65 | * @param s Half of the ECDSA signature pair 66 | */ 67 | function delegateBySig( 68 | address delegatee, 69 | uint nonce, 70 | uint expiry, 71 | uint8 v, 72 | bytes32 r, 73 | bytes32 s 74 | ) 75 | external 76 | { 77 | bytes32 domainSeparator = keccak256( 78 | abi.encode( 79 | DOMAIN_TYPEHASH, 80 | keccak256(bytes(name())), 81 | getChainId(), 82 | address(this) 83 | ) 84 | ); 85 | 86 | bytes32 structHash = keccak256( 87 | abi.encode( 88 | DELEGATION_TYPEHASH, 89 | delegatee, 90 | nonce, 91 | expiry 92 | ) 93 | ); 94 | 95 | bytes32 digest = keccak256( 96 | abi.encodePacked( 97 | "\x19\x01", 98 | domainSeparator, 99 | structHash 100 | ) 101 | ); 102 | 103 | address signatory = ecrecover(digest, v, r, s); 104 | require(signatory != address(0), "Token::delegateBySig: invalid signature"); 105 | require(nonce == nonces[signatory]++, "Token::delegateBySig: invalid nonce"); 106 | require(now <= expiry, "Token::delegateBySig: signature expired"); 107 | return _delegate(signatory, delegatee); 108 | } 109 | 110 | /** 111 | * @notice Gets the current votes balance for `account` 112 | * @param account The address to get votes balance 113 | * @return The number of current votes for `account` 114 | */ 115 | function getCurrentVotes(address account) 116 | external 117 | view 118 | returns (uint256) 119 | { 120 | uint32 nCheckpoints = numCheckpoints[account]; 121 | return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; 122 | } 123 | 124 | /** 125 | * @notice Determine the prior number of votes for an account as of a block number 126 | * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. 127 | * @param account The address of the account to check 128 | * @param blockNumber The block number to get the vote balance at 129 | * @return The number of votes the account had as of the given block 130 | */ 131 | function getPriorVotes(address account, uint blockNumber) 132 | external 133 | view 134 | returns (uint256) 135 | { 136 | require(blockNumber < block.number, "Token::getPriorVotes: not yet determined"); 137 | 138 | uint32 nCheckpoints = numCheckpoints[account]; 139 | if (nCheckpoints == 0) { 140 | return 0; 141 | } 142 | 143 | // First check most recent balance 144 | if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { 145 | return checkpoints[account][nCheckpoints - 1].votes; 146 | } 147 | 148 | // Next check implicit zero balance 149 | if (checkpoints[account][0].fromBlock > blockNumber) { 150 | return 0; 151 | } 152 | 153 | uint32 lower = 0; 154 | uint32 upper = nCheckpoints - 1; 155 | while (upper > lower) { 156 | uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow 157 | Checkpoint memory cp = checkpoints[account][center]; 158 | if (cp.fromBlock == blockNumber) { 159 | return cp.votes; 160 | } else if (cp.fromBlock < blockNumber) { 161 | lower = center; 162 | } else { 163 | upper = center - 1; 164 | } 165 | } 166 | return checkpoints[account][lower].votes; 167 | } 168 | 169 | function _delegate(address delegator, address delegatee) 170 | internal 171 | { 172 | address currentDelegate = _delegates[delegator]; 173 | uint256 delegatorBalance = balanceOf(delegator); // balance of underlying balances (not scaled); 174 | _delegates[delegator] = delegatee; 175 | 176 | _moveDelegates(currentDelegate, delegatee, delegatorBalance); 177 | 178 | emit DelegateChanged(delegator, currentDelegate, delegatee); 179 | } 180 | 181 | function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal { 182 | if (srcRep != dstRep && amount > 0) { 183 | if (srcRep != address(0)) { 184 | // decrease old representative 185 | uint32 srcRepNum = numCheckpoints[srcRep]; 186 | uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; 187 | uint256 srcRepNew = srcRepOld.sub(amount); 188 | _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); 189 | } 190 | 191 | if (dstRep != address(0)) { 192 | // increase new representative 193 | uint32 dstRepNum = numCheckpoints[dstRep]; 194 | uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; 195 | uint256 dstRepNew = dstRepOld.add(amount); 196 | _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); 197 | } 198 | } 199 | } 200 | 201 | function _writeCheckpoint( 202 | address delegatee, 203 | uint32 nCheckpoints, 204 | uint256 oldVotes, 205 | uint256 newVotes 206 | ) 207 | internal 208 | { 209 | uint32 blockNumber = safe32(block.number, "Token::_writeCheckpoint: block number exceeds 32 bits"); 210 | 211 | if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { 212 | checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; 213 | } else { 214 | checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); 215 | numCheckpoints[delegatee] = nCheckpoints + 1; 216 | } 217 | 218 | emit DelegateVotesChanged(delegatee, oldVotes, newVotes); 219 | } 220 | 221 | function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { 222 | require(n < 2**32, errorMessage); 223 | return uint32(n); 224 | } 225 | 226 | function getChainId() internal pure returns (uint) { 227 | uint256 chainId; 228 | assembly { chainId := chainid() } 229 | 230 | return chainId; 231 | } 232 | 233 | /// @notice An event thats emitted when an account changes its delegate 234 | event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); 235 | 236 | /// @notice An event thats emitted when a delegate account's vote balance changes 237 | event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); 238 | 239 | } 240 | -------------------------------------------------------------------------------- /scripts/test_addliquity.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const hre = require("hardhat"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | var Assert = require('assert'); 6 | const web3 = require('web3'); 7 | 8 | 9 | 10 | 11 | async function main() { 12 | 13 | const feeAdrr = hre.network.config.bxh.address.fee; 14 | console.log("fee to :",feeAdrr); 15 | 16 | const addrs = hre.network.config.bxh.address; 17 | 18 | 19 | const accounts = await ethers.getSigners(); 20 | 21 | const ERC20Template = await hre.ethers.getContractFactory("ERC20Template"); 22 | const usdt = await ERC20Template.attach(addrs.usdt); 23 | console.log("USDT attached to: ", usdt.address, await usdt.name()); 24 | 25 | const hbtc = await ERC20Template.attach(addrs.hbtc); 26 | console.log("HBTC attached to: ", hbtc.address, await hbtc.name()); 27 | 28 | const WHT = await hre.ethers.getContractFactory("WHT"); 29 | const wht = await WHT.attach(addrs.wht); 30 | console.log("WHT attached to:", wht.address,await wht.name()); 31 | 32 | 33 | const UniswapV2Factory = await hre.ethers.getContractFactory("UniswapV2Factory"); 34 | const factory = await UniswapV2Factory.attach(addrs.uniswap.factory); 35 | console.log("factory attached to:", factory.address); 36 | const pairCodeHash = await factory.pairCodeHash(); 37 | console.log("factory pairCodeHash is:",pairCodeHash); 38 | 39 | 40 | const UniswapV2Router02 = await hre.ethers.getContractFactory("UniswapV2Router02"); 41 | const router = await UniswapV2Router02.attach(addrs.uniswap.router); 42 | console.log("router attached to:", router.address); 43 | 44 | var amount = web3.utils.toWei('100','ether'); 45 | 46 | // for(var i=0;i<10;i++){ 47 | // await usdt.mint(accounts[i].address,amount); 48 | // console.log("balanceOf:"+accounts[i].address+":"+(await usdt.balanceOf(accounts[i].address)).toString(10)); 49 | // } 50 | var pairAddr = await factory.getPair(usdt.address,hbtc.address); 51 | 52 | const UniswapV2Pair = await hre.ethers.getContractFactory("UniswapV2Pair"); 53 | 54 | var pair = UniswapV2Pair.attach(pairAddr); 55 | console.log("pair is:", pair.address); 56 | 57 | 58 | for(var i=0;i<10;i++){ 59 | await hbtc.connect(accounts[i]).approve(router.address,amount); 60 | await wht.connect(accounts[i]).approve(router.address,amount); 61 | await usdt.connect(accounts[i]).approve(router.address,amount); 62 | await pair.connect(accounts[i]).approve(router.address,amount); 63 | const allowbtc = await hbtc.allowance(accounts[i].address,router.address); 64 | const allowht = await wht.allowance(accounts[i].address,router.address); 65 | const allowusdt = await usdt.allowance(accounts[i].address,router.address); 66 | 67 | // console.log("allow:"+accounts[i].address+" is:"+allowbtc.toString(10)+","+allowht.toString(10)+","+allowusdt.toString(10)); 68 | } 69 | 70 | console.log("fee to: ",await factory.feeTo(),accounts[11].address); 71 | var baseA = 1000000; 72 | // var add = await usdt.transferFrom(accounts[0].address,pair.address,1); 73 | // await router.addLiquidity(usdt.address,hbtc.address,50000*baseA,baseA,0,0,accounts[0].address,1621911939); 74 | var add = await router.connect(accounts[2]).addLiquidity(usdt.address,hbtc.address,50000*baseA,baseA,0,0,accounts[2].address,1621911939); 75 | // // var add = await router.quote(50000*baseA,) 76 | var reserves = await pair.getReserves(); 77 | console.log("reserves:",reserves._reserve0.toString(10),reserves._reserve1.toString(10)); 78 | // var swap = await router.connect(accounts[3]).swapExactTokensForTokens(110000,2,[usdt.address,hbtc.address],accounts[3].address,1621911939); 79 | // var swap = await router.connect(accounts[3]).swapExactTokensForTokens(110000,2,[usdt.address,hbtc.address],accounts[3].address,1621911939); 80 | // var swap = await router.connect(accounts[3]).swapExactTokensForTokens(110000,2,[usdt.address,hbtc.address],accounts[3].address,1621911939); 81 | 82 | var reserves = await pair.getReserves(); 83 | console.log("reserves:",reserves._reserve0.toString(10),reserves._reserve1.toString(10)); 84 | 85 | 86 | var liquid=(await pair.balanceOf(accounts[2].address)); 87 | console.log("liquid=",liquid.toString(10)) 88 | 89 | await pair.sync(); 90 | // await pair.skim(accounts[6].address); 91 | 92 | // liquid = 100; 93 | // var remove = await router.connect(accounts[2]).removeLiquidity(usdt.address,hbtc.address,liquid,0,0,accounts[17].address,1621911939); 94 | // console.log("swap.tx:",swap); 95 | 96 | console.log("balance:: usdt.pair.bal=%s,hbtc.pair.bal=%s,usdt.user.bal=%s,hbtc.user.bal=%s,lp=%s", 97 | (await usdt.balanceOf(pairAddr)).toString(10), 98 | (await hbtc.balanceOf(pairAddr)).toString(10), 99 | (await usdt.balanceOf(accounts[0].address)).toString(10), 100 | (await hbtc.balanceOf(accounts[0].address)).toString(10), 101 | (await pair.balanceOf(accounts[2].address)).toString(10) 102 | ); 103 | 104 | console.log("fee.balance:: usdt=%s,hbtc=%s,lp=%s", 105 | (await usdt.balanceOf(accounts[11].address)).toString(10), 106 | (await hbtc.balanceOf(accounts[11].address)).toString(10), 107 | (await pair.balanceOf(accounts[11].address)).toString(10) 108 | ); 109 | 110 | console.log("rm.balance:: usdt=%s,hbtc=%s,lp=%s", 111 | (await usdt.balanceOf(accounts[17].address)).toString(10), 112 | (await hbtc.balanceOf(accounts[17].address)).toString(10), 113 | (await pair.balanceOf(accounts[17].address)).toString(10) 114 | ); 115 | 116 | const BXHPool = await hre.ethers.getContractFactory("BXHPool"); 117 | var amount = web3.utils.toWei('100','ether'); 118 | // const bxhpool = await BXHPool.deploy(bxh.address,amount,3196000,970); 119 | 120 | var provider = ethers.provider; 121 | var blocknumber = await provider.getBlockNumber(); 122 | 123 | // const bxhpool = await BXHPool.deploy(bxh.address,amount,blocknumber,970); 124 | // await bxhpool.deployed(); 125 | const bxhpool = await BXHPool.attach(addrs.bxhpool); 126 | 127 | await bxhpool.add(100,pair.address,true); 128 | 129 | const BXH = await hre.ethers.getContractFactory("BXHToken"); 130 | const bxh = await BXH.attach(addrs.bxh); 131 | Assert.equal("BXH",await bxh.symbol(),"BXH Contract Attach Error"); 132 | console.log("BXH attached to:", bxh.address); 133 | 134 | 135 | if(true){ 136 | 137 | 138 | 139 | 140 | const BXHLPDelegate = await hre.ethers.getContractFactory("BXHLPDelegate"); 141 | const deLP = await BXHLPDelegate.deploy(pair.address,bxhpool.address,0,accounts[18].address); 142 | 143 | await deLP.deployed(); 144 | console.log("deLP deployed to: ",deLP.address); 145 | 146 | // const deLP = BXHLPDelegate.attach(addrs.delp); 147 | // console.log("deLP attach to: ",deLP.address); 148 | 149 | await pair.connect(accounts[2]).approve(deLP.address,amount); 150 | 151 | // await deLP.connect(accounts[2]).depositLPToken(liquid); 152 | console.log("deuser.bxhbalance=",(await bxh.balanceOf(accounts[2].address)).toString(10)); 153 | await deLP.connect(accounts[2]).depositLPToken(liquid); 154 | 155 | var deUserinfo = await deLP.userDelegateInfos(accounts[2].address); 156 | 157 | // await deLP.connect(accounts[2]).withrawLPToken(); 158 | console.log("deuser.lpAmount=",deUserinfo.lpAmount.toString(10)); 159 | console.log("deuser.kLast=",deUserinfo.kLast.toString(10)); 160 | console.log("deuser.lpShared=",deUserinfo.lpShared.toString(10)); 161 | console.log("deuser.bxhbalance=",(await bxh.balanceOf(accounts[2].address)).toString(10)); 162 | // await husd.transfer(pair,1); 163 | await router.connect(accounts[3]).swapExactTokensForTokens(110000,2,[usdt.address,hbtc.address],accounts[3].address,1621911939); 164 | 165 | var reward = await deLP.connect(accounts[2]).pendingBXH(); 166 | console.log("reward:",reward.lpReturn.toString(10),reward.bxhReturn.toString(10)); 167 | 168 | await pair.connect(accounts[2]).approve(deLP.address,amount); 169 | 170 | var reward = await deLP.connect(accounts[2]).pendingBXH(); 171 | console.log("reward:",reward.lpReturn.toString(10),reward.bxhReturn.toString(10)); 172 | 173 | 174 | console.log("deuser.bxhbalance=",(await bxh.balanceOf(accounts[2].address)).toString(10)); 175 | 176 | var v=await deLP.connect(accounts[2]).withrawLPToken(); 177 | 178 | var deUserinfo = await deLP.userDelegateInfos(accounts[2].address); 179 | 180 | console.log("deuser.lpAmount=",deUserinfo.lpAmount.toString(10)); 181 | console.log("deuser.kLast=",deUserinfo.kLast.toString(10)); 182 | console.log("deuser.lpShared=",deUserinfo.lpShared.toString(10)); 183 | console.log("deuser.bxhbalance=",(await bxh.balanceOf(accounts[2].address)).toString(10)); 184 | // bal = await husd.balanceOf(pair); 185 | 186 | // console.log("HUSD.pair2=:",bal); 187 | 188 | 189 | } 190 | 191 | // const vtf = await husd.transferFrom(accounts[0].address,pair,2); 192 | // console.log("transferFrom is:", vv); 193 | 194 | // console.log("HUSD.pair3=:",await husd.balanceOf(accounts[1].address)); 195 | 196 | 197 | // await wht.approve(pair,0x10000); 198 | 199 | // const allowht = await wht.allowance(accounts[0].address,pair); 200 | // console.log("allowu is:", allowht); 201 | 202 | 203 | // const liquid = await router.addLiquidityETH(husd.address,100,100,100,accounts[0].address,1616074467,{value:1,from:accounts[0].address}); 204 | 205 | // console.log("liquid=",JSON.stringify(liquid)); 206 | 207 | 208 | } 209 | 210 | // We recommend this pattern to be able to use async/await everywhere 211 | // and properly handle errors. 212 | main() 213 | .then(() => process.exit(0)) 214 | .catch(error => { 215 | console.error(error); 216 | process.exit(1); 217 | }); 218 | -------------------------------------------------------------------------------- /contracts/BXHDao.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | import "@openzeppelin/contracts/utils/Context.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 8 | import "@openzeppelin/contracts/math/SafeMath.sol"; 9 | 10 | contract BXHDao is IERC20, Context { 11 | using SafeERC20 for IERC20; 12 | using Address for address; 13 | using SafeMath for uint256; 14 | 15 | address public governance; 16 | 17 | address public depositToken; 18 | 19 | mapping(address => uint256) public lockBlocks; 20 | 21 | uint256 public lockTime; 22 | 23 | mapping(address => uint256) private _balances; 24 | 25 | mapping(address => mapping(address => uint256)) private _allowances; 26 | 27 | uint256 private _totalSupply; 28 | 29 | string private _name; 30 | string private _symbol; 31 | uint8 private _decimals; 32 | 33 | mapping(address => bool) public transferLimitTargets; 34 | bool public enableTranferLimit = true; 35 | 36 | bool public allowContract = false; 37 | 38 | bool public openWithdraw = false; 39 | 40 | constructor( 41 | string memory __name, 42 | uint256 _lockTime, 43 | address _depositToken, 44 | address _governance, 45 | address chef 46 | )public { 47 | governance = _governance; 48 | lockTime = _lockTime; 49 | depositToken = _depositToken; 50 | _name = __name; 51 | _symbol = __name; 52 | _decimals = ERC20(depositToken).decimals(); 53 | 54 | enableTranferLimit = true; 55 | transferLimitTargets[chef] = true; 56 | } 57 | 58 | function name() public view returns (string memory) { 59 | return _name; 60 | } 61 | 62 | function symbol() public view returns (string memory) { 63 | return _symbol; 64 | } 65 | 66 | function decimals() public view returns (uint8) { 67 | return _decimals; 68 | } 69 | 70 | modifier onlyHuman { 71 | if (!allowContract) { 72 | require(msg.sender == tx.origin); 73 | _; 74 | } 75 | } 76 | 77 | function setGovernance(address _governance) public { 78 | require(msg.sender == governance, "!governance"); 79 | governance = _governance; 80 | } 81 | 82 | function setDepositToken(address _depositToken) public { 83 | require(msg.sender == governance, "!governance"); 84 | depositToken = _depositToken; 85 | } 86 | 87 | function updateLockTime(uint256 _lt) public { 88 | require(msg.sender == governance, "!governance"); 89 | require(_lt > 0); 90 | lockTime = _lt; 91 | } 92 | 93 | function toggleTransferLimit(bool _e) public { 94 | require(msg.sender == governance, "!governance"); 95 | enableTranferLimit = _e; 96 | } 97 | 98 | function toggleOpenWithdraw(bool _e) public { 99 | require(msg.sender == governance, "!governance"); 100 | openWithdraw = _e; 101 | } 102 | 103 | function toggleAllowContract(bool _b) public { 104 | require(msg.sender == governance, "!governance"); 105 | allowContract = _b; 106 | } 107 | 108 | 109 | function addLimitTarget(address _a) public { 110 | require(msg.sender == governance, "!governance"); 111 | transferLimitTargets[_a] = true; 112 | } 113 | 114 | function removeLimitTarget(address _a) public { 115 | require(msg.sender == governance, "!governance"); 116 | transferLimitTargets[_a] = false; 117 | } 118 | 119 | function deposit(uint256 _amount) public onlyHuman { 120 | require(_amount > 0); 121 | uint256 _before = IERC20(depositToken).balanceOf(address(this)); 122 | IERC20(depositToken).safeTransferFrom(msg.sender, address(this), _amount); 123 | uint256 _after = IERC20(depositToken).balanceOf(address(this)); 124 | _amount = _after.sub(_before); 125 | uint256 shares = _amount; 126 | 127 | uint256 oldAmt = balanceOf(msg.sender); 128 | if (oldAmt == 0) { 129 | lockBlocks[msg.sender] = block.number.add(lockTime); 130 | } else { 131 | uint256 expireBlock = lockBlocks[msg.sender]; 132 | uint256 totalAmt = oldAmt.add(_amount); 133 | uint256 newAmtShare = _amount.mul(lockTime); 134 | if (expireBlock > block.number) { 135 | // (oldAmt * (expireBlock - block.number) + newAmt * lockTime) / (oldAmt + newAmt) 136 | uint256 deltaBlocks = expireBlock.sub(block.number); 137 | uint256 avgLockTime = 138 | oldAmt.mul(deltaBlocks).add(newAmtShare).div(totalAmt); 139 | lockBlocks[msg.sender] = block.number.add(avgLockTime); 140 | } else { 141 | // newAmt * lockTime / (oldAmt + newAmt) 142 | uint256 avgLockTime = newAmtShare.div(totalAmt); 143 | lockBlocks[msg.sender] = block.number.add(avgLockTime); 144 | } 145 | } 146 | 147 | _mint(msg.sender, shares); 148 | } 149 | 150 | function withdrawAll() external onlyHuman { 151 | withdraw(balanceOf(msg.sender)); 152 | } 153 | 154 | function withdraw(uint256 _shares) public onlyHuman { 155 | require(_shares > 0); 156 | if (!openWithdraw) { 157 | require(lockBlocks[msg.sender] < block.number); 158 | } 159 | uint256 r = _shares; 160 | _burn(msg.sender, _shares); 161 | 162 | IERC20(depositToken).safeTransfer(msg.sender, r); 163 | } 164 | 165 | function canWithdraw(address user) public view returns (bool) { 166 | if (openWithdraw) { 167 | return true; 168 | } 169 | return block.number >= lockBlocks[user]; 170 | } 171 | 172 | function totalSupply() public view override returns (uint256) { 173 | return _totalSupply; 174 | } 175 | 176 | function balanceOf(address account) public view override returns (uint256) { 177 | return _balances[account]; 178 | } 179 | 180 | function transfer(address recipient, uint256 amount) 181 | public 182 | override 183 | returns (bool) 184 | { 185 | _transfer(_msgSender(), recipient, amount); 186 | return true; 187 | } 188 | 189 | function allowance(address owner, address spender) 190 | public 191 | view 192 | override 193 | returns (uint256) 194 | { 195 | return _allowances[owner][spender]; 196 | } 197 | 198 | function approve(address spender, uint256 amount) 199 | public 200 | override 201 | returns (bool) 202 | { 203 | _approve(_msgSender(), spender, amount); 204 | return true; 205 | } 206 | 207 | function transferFrom( 208 | address sender, 209 | address recipient, 210 | uint256 amount 211 | ) public override returns (bool) { 212 | _transfer(sender, recipient, amount); 213 | _approve( 214 | sender, 215 | _msgSender(), 216 | _allowances[sender][_msgSender()].sub( 217 | amount, 218 | "ERC20: transfer amount exceeds allowance" 219 | ) 220 | ); 221 | return true; 222 | } 223 | 224 | function increaseAllowance(address spender, uint256 addedValue) 225 | public 226 | returns (bool) 227 | { 228 | _approve( 229 | _msgSender(), 230 | spender, 231 | _allowances[_msgSender()][spender].add(addedValue) 232 | ); 233 | return true; 234 | } 235 | 236 | function decreaseAllowance(address spender, uint256 subtractedValue) 237 | public 238 | returns (bool) 239 | { 240 | _approve( 241 | _msgSender(), 242 | spender, 243 | _allowances[_msgSender()][spender].sub( 244 | subtractedValue, 245 | "ERC20: decreased allowance below zero" 246 | ) 247 | ); 248 | return true; 249 | } 250 | 251 | function _transfer( 252 | address sender, 253 | address recipient, 254 | uint256 amount 255 | ) internal { 256 | require(sender != address(0), "ERC20: transfer from the zero address"); 257 | require(recipient != address(0), "ERC20: transfer to the zero address"); 258 | 259 | if (enableTranferLimit) { 260 | require(transferLimitTargets[sender]|| transferLimitTargets[recipient], "limit transfer targets"); 261 | } 262 | 263 | _balances[sender] = _balances[sender].sub( 264 | amount, 265 | "ERC20: transfer amount exceeds balance" 266 | ); 267 | _balances[recipient] = _balances[recipient].add(amount); 268 | emit Transfer(sender, recipient, amount); 269 | } 270 | 271 | function _mint(address account, uint256 amount) internal { 272 | require(account != address(0), "ERC20: mint to the zero address"); 273 | 274 | _totalSupply = _totalSupply.add(amount); 275 | _balances[account] = _balances[account].add(amount); 276 | emit Transfer(address(0), account, amount); 277 | } 278 | 279 | function _burn(address account, uint256 amount) internal { 280 | require(account != address(0), "ERC20: burn from the zero address"); 281 | 282 | _balances[account] = _balances[account].sub( 283 | amount, 284 | "ERC20: burn amount exceeds balance" 285 | ); 286 | _totalSupply = _totalSupply.sub(amount); 287 | emit Transfer(account, address(0), amount); 288 | } 289 | 290 | function _approve( 291 | address owner, 292 | address spender, 293 | uint256 amount 294 | ) internal { 295 | require(owner != address(0), "ERC20: approve from the zero address"); 296 | require(spender != address(0), "ERC20: approve to the zero address"); 297 | 298 | _allowances[owner][spender] = amount; 299 | emit Approval(owner, spender, amount); 300 | } 301 | 302 | function _burnFrom(address account, uint256 amount) internal { 303 | _burn(account, amount); 304 | _approve( 305 | account, 306 | _msgSender(), 307 | _allowances[account][_msgSender()].sub( 308 | amount, 309 | "ERC20: burn amount exceeds allowance" 310 | ) 311 | ); 312 | } 313 | } -------------------------------------------------------------------------------- /contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | /** 3 | *Submitted for verification at hecoinfo.com on 2021-02-03 4 | */ 5 | 6 | pragma solidity ^0.6.6; 7 | 8 | library SafeMath { 9 | 10 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 11 | uint256 c = a + b; 12 | require(c >= a, "SafeMath: addition overflow"); 13 | 14 | return c; 15 | } 16 | 17 | 18 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 19 | return sub(a, b, "SafeMath: subtraction overflow"); 20 | } 21 | 22 | 23 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 24 | require(b <= a, errorMessage); 25 | uint256 c = a - b; 26 | 27 | return c; 28 | } 29 | 30 | 31 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 32 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 33 | // benefit is lost if 'b' is also tested. 34 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 35 | if (a == 0) { 36 | return 0; 37 | } 38 | 39 | uint256 c = a * b; 40 | require(c / a == b, "SafeMath: multiplication overflow"); 41 | 42 | return c; 43 | } 44 | 45 | 46 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 47 | return div(a, b, "SafeMath: division by zero"); 48 | } 49 | 50 | 51 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 52 | require(b > 0, errorMessage); 53 | uint256 c = a / b; 54 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 55 | 56 | return c; 57 | } 58 | 59 | 60 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 61 | return mod(a, b, "SafeMath: modulo by zero"); 62 | } 63 | 64 | 65 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 66 | require(b != 0, errorMessage); 67 | return a % b; 68 | } 69 | } 70 | 71 | 72 | interface IERC20 { 73 | 74 | function totalSupply() external view returns (uint256); 75 | 76 | function balanceOf(address account) external view returns (uint256); 77 | 78 | function transfer(address recipient, uint256 amount) external returns (bool); 79 | 80 | function allowance(address owner, address spender) external view returns (uint256); 81 | 82 | function approve(address spender, uint256 amount) external returns (bool); 83 | 84 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 85 | 86 | event Transfer(address indexed from, address indexed to, uint256 value); 87 | 88 | event Approval(address indexed owner, address indexed spender, uint256 value); 89 | } 90 | abstract contract Context { 91 | function _msgSender() internal view virtual returns (address payable) { 92 | return msg.sender; 93 | } 94 | 95 | function _msgData() internal view virtual returns (bytes memory) { 96 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 97 | return msg.data; 98 | } 99 | } 100 | 101 | 102 | abstract contract Pausable is Context { 103 | 104 | event Paused(address account); 105 | 106 | 107 | event Unpaused(address account); 108 | 109 | bool private _paused; 110 | 111 | constructor () internal { 112 | _paused = false; 113 | } 114 | 115 | 116 | function paused() public view returns (bool) { 117 | return _paused; 118 | } 119 | 120 | 121 | modifier whenNotPaused() { 122 | require(!_paused, "Pausable: paused"); 123 | _; 124 | } 125 | 126 | 127 | modifier whenPaused() { 128 | require(_paused, "Pausable: not paused"); 129 | _; 130 | } 131 | 132 | 133 | function _pause() internal virtual whenNotPaused { 134 | _paused = true; 135 | emit Paused(_msgSender()); 136 | } 137 | 138 | 139 | function _unpause() internal virtual whenPaused { 140 | _paused = false; 141 | emit Unpaused(_msgSender()); 142 | } 143 | } 144 | contract ERC20 is Context, IERC20 { 145 | using SafeMath for uint256; 146 | 147 | mapping (address => uint256) private _balances; 148 | 149 | mapping (address => mapping (address => uint256)) private _allowances; 150 | 151 | uint256 private _totalSupply; 152 | 153 | string private _name; 154 | string private _symbol; 155 | uint8 private _decimals; 156 | 157 | constructor (string memory name_, string memory symbol_) public { 158 | _name = name_; 159 | _symbol = symbol_; 160 | _decimals = 18; 161 | } 162 | 163 | function name() public view returns (string memory) { 164 | return _name; 165 | } 166 | 167 | 168 | function symbol() public view returns (string memory) { 169 | return _symbol; 170 | } 171 | 172 | 173 | function decimals() public view returns (uint8) { 174 | return _decimals; 175 | } 176 | 177 | 178 | function totalSupply() public view override returns (uint256) { 179 | return _totalSupply; 180 | } 181 | 182 | 183 | function balanceOf(address account) public view override returns (uint256) { 184 | return _balances[account]; 185 | } 186 | 187 | 188 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 189 | _transfer(_msgSender(), recipient, amount); 190 | return true; 191 | } 192 | 193 | 194 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 195 | return _allowances[owner][spender]; 196 | } 197 | 198 | 199 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 200 | _approve(_msgSender(), spender, amount); 201 | return true; 202 | } 203 | 204 | 205 | function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { 206 | _transfer(sender, recipient, amount); 207 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 208 | return true; 209 | } 210 | 211 | 212 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 213 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 214 | return true; 215 | } 216 | 217 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 218 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 219 | return true; 220 | } 221 | 222 | function _transfer(address sender, address recipient, uint256 amount) internal virtual { 223 | require(sender != address(0), "ERC20: transfer from the zero address"); 224 | require(recipient != address(0), "ERC20: transfer to the zero address"); 225 | 226 | _beforeTokenTransfer(sender, recipient, amount); 227 | 228 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 229 | _balances[recipient] = _balances[recipient].add(amount); 230 | emit Transfer(sender, recipient, amount); 231 | } 232 | 233 | 234 | function _mint(address account, uint256 amount) internal virtual { 235 | require(account != address(0), "ERC20: mint to the zero address"); 236 | 237 | _beforeTokenTransfer(address(0), account, amount); 238 | 239 | _totalSupply = _totalSupply.add(amount); 240 | _balances[account] = _balances[account].add(amount); 241 | emit Transfer(address(0), account, amount); 242 | } 243 | 244 | 245 | function _burn(address account, uint256 amount) internal virtual { 246 | require(account != address(0), "ERC20: burn from the zero address"); 247 | 248 | _beforeTokenTransfer(account, address(0), amount); 249 | 250 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 251 | _totalSupply = _totalSupply.sub(amount); 252 | emit Transfer(account, address(0), amount); 253 | } 254 | 255 | function _approve(address owner, address spender, uint256 amount) internal virtual { 256 | require(owner != address(0), "ERC20: approve from the zero address"); 257 | require(spender != address(0), "ERC20: approve to the zero address"); 258 | 259 | _allowances[owner][spender] = amount; 260 | emit Approval(owner, spender, amount); 261 | } 262 | 263 | function _setupDecimals(uint8 decimals_) internal { 264 | _decimals = decimals_; 265 | } 266 | 267 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } 268 | } 269 | abstract contract ERC20Pausable is ERC20, Pausable { 270 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { 271 | super._beforeTokenTransfer(from, to, amount); 272 | 273 | require(!paused(), "ERC20Pausable: token transfer while paused"); 274 | } 275 | } 276 | contract ERC20Template is ERC20Pausable { 277 | address factory; 278 | address _operator; 279 | address _pauser; 280 | constructor(address operator,address pauser,string memory name, string memory symbol,uint8 decimal) public ERC20(name,symbol) { 281 | _operator = operator; 282 | _pauser=pauser; 283 | _setupDecimals(decimal); 284 | factory=msg.sender; 285 | } 286 | 287 | 288 | modifier onlyFactory(){ 289 | require(msg.sender==factory,"only Factory"); 290 | _; 291 | } 292 | modifier onlyOperator(){ 293 | require(msg.sender == _operator,"not allowed"); 294 | _; 295 | } 296 | modifier onlyPauser(){ 297 | require(msg.sender == _pauser,"not allowed"); 298 | _; 299 | } 300 | 301 | function pause() public onlyPauser{ 302 | _pause(); 303 | } 304 | 305 | function unpause() public onlyPauser{ 306 | _unpause(); 307 | } 308 | 309 | function changeUser(address new_operator, address new_pauser) public onlyFactory{ 310 | _pauser=new_pauser; 311 | _operator=new_operator; 312 | } 313 | 314 | function mint(address account, uint256 amount) public whenNotPaused onlyOperator { 315 | _mint(account, amount); 316 | } 317 | function burn(address account , uint256 amount) public whenNotPaused onlyOperator { 318 | _burn(account,amount); 319 | } 320 | } -------------------------------------------------------------------------------- /contracts/BXHDaoPool.sol: -------------------------------------------------------------------------------- 1 | 2 | // SPDX-License-Identifier: MIT 3 | pragma solidity ^0.6.0; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | import "@openzeppelin/contracts/utils/Context.sol"; 7 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 8 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 9 | import "@openzeppelin/contracts/math/SafeMath.sol"; 10 | import "@openzeppelin/contracts/access/AccessControl.sol"; 11 | import "@openzeppelin/contracts/access/Ownable.sol"; 12 | import "./DelegateERC20.sol"; 13 | import "./XToken.sol"; 14 | import "@openzeppelin/contracts/access/Ownable.sol"; 15 | 16 | contract BXHDAOPool is Ownable{ 17 | 18 | struct UnlockRequest { 19 | uint256 amount; 20 | uint256 unlockTimestamp; 21 | } 22 | 23 | struct UserInfo { 24 | uint256 amount; 25 | uint256 lastRewardedEpoch; 26 | } 27 | 28 | struct SharesAndRewardsInfo { 29 | uint256 activeShares; 30 | uint256 pendingSharesToAdd; 31 | uint256 pendingSharesToReduce; 32 | uint256 rewards; 33 | uint256 claimedRewards; 34 | uint256 lastUpdatedEpochFlag; 35 | } 36 | 37 | uint256 public epochLength; 38 | 39 | uint256 public startTime; 40 | 41 | uint256 public lockingLength; 42 | 43 | SharesAndRewardsInfo public sharesAndRewardsInfo; 44 | 45 | mapping(address => UserInfo) public userInfo; 46 | 47 | mapping(address => UnlockRequest[]) public userUnlockRequests; 48 | 49 | ERC20 public BonusToken; 50 | 51 | ERC20 public dToken; 52 | 53 | XToken public xToken; 54 | 55 | constructor(address xAddress,address dAddress,address bAddress,uint256 _startTime) public { 56 | epochLength = 30 days; 57 | xToken = XToken(xAddress); 58 | dToken = ERC20(dAddress); 59 | BonusToken = ERC20(bAddress); 60 | lockingLength = 7 days; 61 | startTime = _startTime; 62 | } 63 | 64 | function setStartTime(uint256 _startTime) public onlyOwner { 65 | startTime = _startTime; 66 | } 67 | 68 | function setLockingParams(uint256 _epochLength,uint256 _lockingLength) public onlyOwner { 69 | epochLength = _epochLength; 70 | lockingLength = _lockingLength; 71 | } 72 | 73 | 74 | function _relock(uint256 index) private { 75 | UserInfo storage user = userInfo[msg.sender]; 76 | UnlockRequest[] storage reqs = userUnlockRequests[msg.sender]; 77 | user.amount = SafeMath.add(user.amount, reqs[index].amount); 78 | sharesAndRewardsInfo.pendingSharesToAdd = SafeMath.add(sharesAndRewardsInfo.pendingSharesToAdd, reqs[index].amount) ; 79 | require(xToken.mint(msg.sender, reqs[index].amount), "stake mint failed"); 80 | 81 | _deleteRequestAt(index); 82 | } 83 | 84 | function _deleteRequestAt(uint256 index) private { 85 | UnlockRequest[] storage reqs = userUnlockRequests[msg.sender]; 86 | for (uint256 i = index; i < reqs.length - 1; i++) { 87 | reqs[i] = reqs[i + 1]; 88 | } 89 | reqs.pop(); 90 | } 91 | 92 | function _claim(address _user) private { 93 | UserInfo storage user = userInfo[_user]; 94 | uint256 rewards = pendingReward(_user); 95 | if (rewards > 0) { 96 | sharesAndRewardsInfo.claimedRewards = SafeMath.add(sharesAndRewardsInfo.claimedRewards, rewards); 97 | require(BonusToken.transfer(_user, rewards), "_claim transfer failed"); 98 | } 99 | user.lastRewardedEpoch = currentEpoch(); 100 | } 101 | 102 | function _updateSharesAndRewardsInfo() private { 103 | if (sharesAndRewardsInfo.lastUpdatedEpochFlag < currentEpoch()) { 104 | sharesAndRewardsInfo.activeShares = 105 | SafeMath.sub( 106 | SafeMath.add(sharesAndRewardsInfo.activeShares, sharesAndRewardsInfo.pendingSharesToAdd), 107 | sharesAndRewardsInfo.pendingSharesToReduce 108 | ); 109 | sharesAndRewardsInfo.pendingSharesToAdd = 0; 110 | sharesAndRewardsInfo.pendingSharesToReduce = 0; 111 | sharesAndRewardsInfo.rewards = BonusToken.balanceOf(address(this)); 112 | sharesAndRewardsInfo.lastUpdatedEpochFlag = currentEpoch(); 113 | sharesAndRewardsInfo.claimedRewards = 0; 114 | } 115 | } 116 | 117 | function shareAmount() public view returns(uint256) { 118 | if (sharesAndRewardsInfo.lastUpdatedEpochFlag < currentEpoch()) { 119 | return SafeMath.sub( 120 | SafeMath.add(sharesAndRewardsInfo.activeShares, sharesAndRewardsInfo.pendingSharesToAdd), 121 | sharesAndRewardsInfo.pendingSharesToReduce 122 | ); 123 | } else { 124 | return sharesAndRewardsInfo.activeShares; 125 | } 126 | } 127 | 128 | function rewardsAmount() public view returns(uint256) { 129 | if (sharesAndRewardsInfo.lastUpdatedEpochFlag < currentEpoch()) { 130 | return BonusToken.balanceOf(address(this)); 131 | } else { 132 | return sharesAndRewardsInfo.rewards; 133 | } 134 | } 135 | 136 | function currentEpoch() public view returns(uint256) { 137 | if (block.timestamp < startTime) return 0; 138 | uint256 period = SafeMath.sub(block.timestamp, startTime); 139 | return SafeMath.div(period, epochLength); 140 | } 141 | 142 | function pendingReward(address who) public view returns (uint256) { 143 | if (currentEpoch() == 0) return 0; 144 | 145 | UserInfo storage user = userInfo[who]; 146 | uint256 totalAmount = shareAmount(); 147 | if (totalAmount != 0 && user.lastRewardedEpoch < currentEpoch()) { 148 | uint256 BonusTokenBalance = BonusToken.balanceOf(address(this)); 149 | uint256 myRewardsAmount = SafeMath.div(SafeMath.mul(user.amount, rewardsAmount()), totalAmount); 150 | // If rewards is larger than BonusToken Balance, then all BonusToken will be the rewards. 151 | // But it is unlikely BonusTokenBalance be less than myRewardsAmount. 152 | return BonusTokenBalance < myRewardsAmount ? BonusTokenBalance : myRewardsAmount; 153 | } else { 154 | return 0; 155 | } 156 | } 157 | 158 | function _unlockingAmount(address who) public view returns (uint256) { 159 | UnlockRequest[] memory reqs = userUnlockRequests[who]; 160 | uint256 sum = 0; 161 | for (uint256 i = 0; i < reqs.length; i++) { 162 | sum += reqs[i].amount; 163 | } 164 | return sum; 165 | } 166 | 167 | function lockRequestCount(address who) public view returns (uint256) { 168 | return userUnlockRequests[who].length; 169 | } 170 | 171 | function unlockableAmount(address who) public view returns (uint256) { 172 | UserInfo memory user = userInfo[who]; 173 | if (user.amount <= xToken.balanceOf(who)) { 174 | return user.amount; 175 | } else { 176 | return xToken.balanceOf(who); 177 | } 178 | } 179 | 180 | function unstakableAmount(address who) public view returns (uint256) { 181 | UnlockRequest[] memory reqs = userUnlockRequests[who]; 182 | uint256 sum = 0; 183 | for (uint256 i = 0; i < reqs.length; i++) { 184 | if (block.timestamp - reqs[i].unlockTimestamp > lockingLength) { 185 | sum += reqs[i].amount; 186 | } 187 | } 188 | return sum; 189 | } 190 | 191 | function claimedRewards() public view returns (uint256) { 192 | if (sharesAndRewardsInfo.lastUpdatedEpochFlag < currentEpoch()) { 193 | return 0; 194 | } else { 195 | return sharesAndRewardsInfo.claimedRewards; 196 | } 197 | } 198 | 199 | function donateBonusToken(uint256 amount) public { 200 | _updateSharesAndRewardsInfo(); 201 | require(BonusToken.transferFrom(msg.sender, address(this), amount), "donateBonusToken transferFrom failed"); 202 | } 203 | 204 | function stake(uint256 _amount) public { 205 | require(_amount > 0); 206 | _updateSharesAndRewardsInfo(); 207 | _claim(msg.sender); 208 | 209 | UserInfo storage user = userInfo[msg.sender]; 210 | require(dToken.transferFrom(msg.sender, address(this), _amount), "stake transferFrom failed"); 211 | user.amount = SafeMath.add(user.amount, _amount) ; 212 | sharesAndRewardsInfo.pendingSharesToAdd = SafeMath.add(sharesAndRewardsInfo.pendingSharesToAdd, _amount); 213 | require(xToken.mint(msg.sender, _amount), "stake mint failed"); 214 | } 215 | 216 | function unlock(uint256 _amount) public { 217 | require(unlockableAmount(msg.sender) >= _amount, "unlock over unlockableAmount"); 218 | 219 | _updateSharesAndRewardsInfo(); 220 | _claim(msg.sender); 221 | 222 | sharesAndRewardsInfo.pendingSharesToReduce = SafeMath.add(sharesAndRewardsInfo.pendingSharesToReduce, _amount); 223 | UserInfo storage user = userInfo[msg.sender]; 224 | user.amount = SafeMath.sub(user.amount, _amount); 225 | userUnlockRequests[msg.sender].push(UnlockRequest({ 226 | amount: _amount, 227 | unlockTimestamp: block.timestamp 228 | })); 229 | require(xToken.burn(msg.sender, _amount), "unlock burn failed"); 230 | } 231 | 232 | function relock(uint256 index) public { 233 | _updateSharesAndRewardsInfo(); 234 | _claim(msg.sender); 235 | 236 | _relock(index); 237 | } 238 | 239 | function relockAll() public { 240 | _updateSharesAndRewardsInfo(); 241 | _claim(msg.sender); 242 | 243 | uint256 reqsN = userUnlockRequests[msg.sender].length; 244 | for (uint256 i = reqsN - 1; i > 0; i--) { 245 | _relock(i); 246 | } 247 | _relock(0); 248 | } 249 | 250 | function unStake() public { 251 | _updateSharesAndRewardsInfo(); 252 | _claim(msg.sender); 253 | 254 | UnlockRequest[] storage reqs = userUnlockRequests[msg.sender]; 255 | uint256 amount = unstakableAmount(msg.sender); 256 | require(amount != 0, "no available deposit token"); 257 | dToken.transfer(msg.sender, amount); 258 | for (uint256 iPlusOne = reqs.length; iPlusOne > 0; iPlusOne--) { 259 | uint256 i = iPlusOne - 1; 260 | if (block.timestamp - reqs[i].unlockTimestamp > lockingLength) { 261 | _deleteRequestAt(i); 262 | } 263 | } 264 | } 265 | 266 | function claim(address _user) public { 267 | _updateSharesAndRewardsInfo(); 268 | _claim(_user); 269 | } 270 | 271 | } --------------------------------------------------------------------------------