├── Context.sol ├── DividendPayingToken.sol ├── DividendPayingTokenInterface.sol ├── DividendPayingTokenOptionalInterface.sol ├── ERC20.sol ├── IERC20.sol ├── IERC20Metadata.sol ├── IUniswapV2Factory.sol ├── IUniswapV2Pair.sol ├── IUniswapV2Router.sol ├── InfluenceHub.sol ├── IterableMapping.sol ├── Ownable.sol ├── README.md ├── SafeMath.sol ├── SafeMathInt.sol └── SafeMathUint.sol /Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes calldata) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DividendPayingToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "./ERC20.sol"; 6 | import "./SafeMath.sol"; 7 | import "./SafeMathUint.sol"; 8 | import "./SafeMathInt.sol"; 9 | import "./DividendPayingTokenInterface.sol"; 10 | import "./DividendPayingTokenOptionalInterface.sol"; 11 | 12 | 13 | /// @title Dividend-Paying Token 14 | /// @author Roger Wu (https://github.com/roger-wu) 15 | /// @dev A mintable ERC20 token that allows anyone to pay and distribute ether 16 | /// to token holders as dividends and allows token holders to withdraw their dividends. 17 | /// Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code 18 | contract DividendPayingToken is ERC20, DividendPayingTokenInterface, DividendPayingTokenOptionalInterface { 19 | using SafeMath for uint256; 20 | using SafeMathUint for uint256; 21 | using SafeMathInt for int256; 22 | 23 | // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small. 24 | // For more discussion about choosing the value of `magnitude`, 25 | // see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728 26 | uint256 constant internal magnitude = 2**128; 27 | 28 | uint256 internal magnifiedDividendPerShare; 29 | 30 | // About dividendCorrection: 31 | // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with: 32 | // `dividendOf(_user) = dividendPerShare * balanceOf(_user)`. 33 | // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens), 34 | // `dividendOf(_user)` should not be changed, 35 | // but the computed value of `dividendPerShare * balanceOf(_user)` is changed. 36 | // To keep the `dividendOf(_user)` unchanged, we add a correction term: 37 | // `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`, 38 | // where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed: 39 | // `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`. 40 | // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed. 41 | mapping(address => int256) internal magnifiedDividendCorrections; 42 | mapping(address => uint256) internal withdrawnDividends; 43 | 44 | uint256 public totalDividendsDistributed; 45 | 46 | constructor(string memory _name, string memory _symbol) public ERC20(_name, _symbol) { 47 | 48 | } 49 | 50 | /// @dev Distributes dividends whenever ether is paid to this contract. 51 | receive() external payable { 52 | distributeDividends(); 53 | } 54 | 55 | /// @notice Distributes ether to token holders as dividends. 56 | /// @dev It reverts if the total supply of tokens is 0. 57 | /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0. 58 | /// About undistributed ether: 59 | /// In each distribution, there is a small amount of ether not distributed, 60 | /// the magnified amount of which is 61 | /// `(msg.value * magnitude) % totalSupply()`. 62 | /// With a well-chosen `magnitude`, the amount of undistributed ether 63 | /// (de-magnified) in a distribution can be less than 1 wei. 64 | /// We can actually keep track of the undistributed ether in a distribution 65 | /// and try to distribute it in the next distribution, 66 | /// but keeping track of such data on-chain costs much more than 67 | /// the saved ether, so we don't do that. 68 | function distributeDividends() public override payable { 69 | require(totalSupply() > 0); 70 | 71 | if (msg.value > 0) { 72 | magnifiedDividendPerShare = magnifiedDividendPerShare.add( 73 | (msg.value).mul(magnitude) / totalSupply() 74 | ); 75 | emit DividendsDistributed(msg.sender, msg.value); 76 | 77 | totalDividendsDistributed = totalDividendsDistributed.add(msg.value); 78 | } 79 | } 80 | 81 | /// @notice Withdraws the ether distributed to the sender. 82 | /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. 83 | function withdrawDividend() public virtual override { 84 | _withdrawDividendOfUser(msg.sender); 85 | } 86 | 87 | /// @notice Withdraws the ether distributed to the sender. 88 | /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. 89 | function _withdrawDividendOfUser(address payable user) internal returns (uint256) { 90 | uint256 _withdrawableDividend = withdrawableDividendOf(user); 91 | if (_withdrawableDividend > 0) { 92 | withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend); 93 | emit DividendWithdrawn(user, _withdrawableDividend); 94 | (bool success,) = user.call{value: _withdrawableDividend, gas: 3000}(""); 95 | 96 | if(!success) { 97 | withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend); 98 | return 0; 99 | } 100 | 101 | return _withdrawableDividend; 102 | } 103 | 104 | return 0; 105 | } 106 | 107 | 108 | /// @notice View the amount of dividend in wei that an address can withdraw. 109 | /// @param _owner The address of a token holder. 110 | /// @return The amount of dividend in wei that `_owner` can withdraw. 111 | function dividendOf(address _owner) public view override returns(uint256) { 112 | return withdrawableDividendOf(_owner); 113 | } 114 | 115 | /// @notice View the amount of dividend in wei that an address can withdraw. 116 | /// @param _owner The address of a token holder. 117 | /// @return The amount of dividend in wei that `_owner` can withdraw. 118 | function withdrawableDividendOf(address _owner) public view override returns(uint256) { 119 | return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]); 120 | } 121 | 122 | /// @notice View the amount of dividend in wei that an address has withdrawn. 123 | /// @param _owner The address of a token holder. 124 | /// @return The amount of dividend in wei that `_owner` has withdrawn. 125 | function withdrawnDividendOf(address _owner) public view override returns(uint256) { 126 | return withdrawnDividends[_owner]; 127 | } 128 | 129 | 130 | /// @notice View the amount of dividend in wei that an address has earned in total. 131 | /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) 132 | /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude 133 | /// @param _owner The address of a token holder. 134 | /// @return The amount of dividend in wei that `_owner` has earned in total. 135 | function accumulativeDividendOf(address _owner) public view override returns(uint256) { 136 | return magnifiedDividendPerShare.mul(balanceOf(_owner)).toInt256Safe() 137 | .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude; 138 | } 139 | 140 | /// @dev Internal function that transfer tokens from one address to another. 141 | /// Update magnifiedDividendCorrections to keep dividends unchanged. 142 | /// @param from The address to transfer from. 143 | /// @param to The address to transfer to. 144 | /// @param value The amount to be transferred. 145 | function _transfer(address from, address to, uint256 value) internal virtual override { 146 | require(false); 147 | 148 | int256 _magCorrection = magnifiedDividendPerShare.mul(value).toInt256Safe(); 149 | magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from].add(_magCorrection); 150 | magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(_magCorrection); 151 | } 152 | 153 | /// @dev Internal function that mints tokens to an account. 154 | /// Update magnifiedDividendCorrections to keep dividends unchanged. 155 | /// @param account The account that will receive the created tokens. 156 | /// @param value The amount that will be created. 157 | function _mint(address account, uint256 value) internal override { 158 | super._mint(account, value); 159 | 160 | magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account] 161 | .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() ); 162 | } 163 | 164 | /// @dev Internal function that burns an amount of the token of a given account. 165 | /// Update magnifiedDividendCorrections to keep dividends unchanged. 166 | /// @param account The account whose tokens will be burnt. 167 | /// @param value The amount that will be burnt. 168 | function _burn(address account, uint256 value) internal override { 169 | super._burn(account, value); 170 | 171 | magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account] 172 | .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() ); 173 | } 174 | 175 | function _setBalance(address account, uint256 newBalance) internal { 176 | uint256 currentBalance = balanceOf(account); 177 | 178 | if(newBalance > currentBalance) { 179 | uint256 mintAmount = newBalance.sub(currentBalance); 180 | _mint(account, mintAmount); 181 | } else if(newBalance < currentBalance) { 182 | uint256 burnAmount = currentBalance.sub(newBalance); 183 | _burn(account, burnAmount); 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /DividendPayingTokenInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | 6 | /// @title Dividend-Paying Token Interface 7 | /// @author Roger Wu (https://github.com/roger-wu) 8 | /// @dev An interface for a dividend-paying token contract. 9 | interface DividendPayingTokenInterface { 10 | /// @notice View the amount of dividend in wei that an address can withdraw. 11 | /// @param _owner The address of a token holder. 12 | /// @return The amount of dividend in wei that `_owner` can withdraw. 13 | function dividendOf(address _owner) external view returns(uint256); 14 | 15 | /// @notice Distributes ether to token holders as dividends. 16 | /// @dev SHOULD distribute the paid ether to token holders as dividends. 17 | /// SHOULD NOT directly transfer ether to token holders in this function. 18 | /// MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0. 19 | function distributeDividends() external payable; 20 | 21 | /// @notice Withdraws the ether distributed to the sender. 22 | /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer. 23 | /// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0. 24 | function withdrawDividend() external; 25 | 26 | /// @dev This event MUST emit when ether is distributed to token holders. 27 | /// @param from The address which sends ether to this contract. 28 | /// @param weiAmount The amount of distributed ether in wei. 29 | event DividendsDistributed( 30 | address indexed from, 31 | uint256 weiAmount 32 | ); 33 | 34 | /// @dev This event MUST emit when an address withdraws their dividend. 35 | /// @param to The address which withdraws ether from this contract. 36 | /// @param weiAmount The amount of withdrawn ether in wei. 37 | event DividendWithdrawn( 38 | address indexed to, 39 | uint256 weiAmount 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /DividendPayingTokenOptionalInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | 6 | /// @title Dividend-Paying Token Optional Interface 7 | /// @author Roger Wu (https://github.com/roger-wu) 8 | /// @dev OPTIONAL functions for a dividend-paying token contract. 9 | interface DividendPayingTokenOptionalInterface { 10 | /// @notice View the amount of dividend in wei that an address can withdraw. 11 | /// @param _owner The address of a token holder. 12 | /// @return The amount of dividend in wei that `_owner` can withdraw. 13 | function withdrawableDividendOf(address _owner) external view returns(uint256); 14 | 15 | /// @notice View the amount of dividend in wei that an address has withdrawn. 16 | /// @param _owner The address of a token holder. 17 | /// @return The amount of dividend in wei that `_owner` has withdrawn. 18 | function withdrawnDividendOf(address _owner) external view returns(uint256); 19 | 20 | /// @notice View the amount of dividend in wei that an address has earned in total. 21 | /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) 22 | /// @param _owner The address of a token holder. 23 | /// @return The amount of dividend in wei that `_owner` has earned in total. 24 | function accumulativeDividendOf(address _owner) external view returns(uint256); 25 | } 26 | -------------------------------------------------------------------------------- /ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "./IERC20.sol"; 6 | import "./IERC20Metadata.sol"; 7 | import "./Context.sol"; 8 | import "./SafeMath.sol"; 9 | 10 | /** 11 | * @dev Implementation of the {IERC20} interface. 12 | * 13 | * This implementation is agnostic to the way tokens are created. This means 14 | * that a supply mechanism has to be added in a derived contract using {_mint}. 15 | * For a generic mechanism see {ERC20PresetMinterPauser}. 16 | * 17 | * TIP: For a detailed writeup see our guide 18 | * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How 19 | * to implement supply mechanisms]. 20 | * 21 | * We have followed general OpenZeppelin guidelines: functions revert instead 22 | * of returning `false` on failure. This behavior is nonetheless conventional 23 | * and does not conflict with the expectations of ERC20 applications. 24 | * 25 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 26 | * This allows applications to reconstruct the allowance for all accounts just 27 | * by listening to said events. Other implementations of the EIP may not emit 28 | * these events, as it isn't required by the specification. 29 | * 30 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 31 | * functions have been added to mitigate the well-known issues around setting 32 | * allowances. See {IERC20-approve}. 33 | */ 34 | contract ERC20 is Context, IERC20, IERC20Metadata { 35 | using SafeMath for uint256; 36 | 37 | mapping(address => uint256) private _balances; 38 | 39 | mapping(address => mapping(address => uint256)) private _allowances; 40 | 41 | uint256 private _totalSupply; 42 | 43 | string private _name; 44 | string private _symbol; 45 | 46 | /** 47 | * @dev Sets the values for {name} and {symbol}. 48 | * 49 | * The default value of {decimals} is 18. To select a different value for 50 | * {decimals} you should overload it. 51 | * 52 | * All two of these values are immutable: they can only be set once during 53 | * construction. 54 | */ 55 | constructor(string memory name_, string memory symbol_) public { 56 | _name = name_; 57 | _symbol = symbol_; 58 | } 59 | 60 | /** 61 | * @dev Returns the name of the token. 62 | */ 63 | function name() public view virtual override returns (string memory) { 64 | return _name; 65 | } 66 | 67 | /** 68 | * @dev Returns the symbol of the token, usually a shorter version of the 69 | * name. 70 | */ 71 | function symbol() public view virtual override returns (string memory) { 72 | return _symbol; 73 | } 74 | 75 | /** 76 | * @dev Returns the number of decimals used to get its user representation. 77 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 78 | * be displayed to a user as `5,05` (`505 / 10 ** 2`). 79 | * 80 | * Tokens usually opt for a value of 18, imitating the relationship between 81 | * Ether and Wei. This is the value {ERC20} uses, unless this function is 82 | * overridden; 83 | * 84 | * NOTE: This information is only used for _display_ purposes: it in 85 | * no way affects any of the arithmetic of the contract, including 86 | * {IERC20-balanceOf} and {IERC20-transfer}. 87 | */ 88 | function decimals() public view virtual override returns (uint8) { 89 | return 18; 90 | } 91 | 92 | /** 93 | * @dev See {IERC20-totalSupply}. 94 | */ 95 | function totalSupply() public view virtual override returns (uint256) { 96 | return _totalSupply; 97 | } 98 | 99 | /** 100 | * @dev See {IERC20-balanceOf}. 101 | */ 102 | function balanceOf(address account) public view virtual override returns (uint256) { 103 | return _balances[account]; 104 | } 105 | 106 | /** 107 | * @dev See {IERC20-transfer}. 108 | * 109 | * Requirements: 110 | * 111 | * - `recipient` cannot be the zero address. 112 | * - the caller must have a balance of at least `amount`. 113 | */ 114 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 115 | _transfer(_msgSender(), recipient, amount); 116 | return true; 117 | } 118 | 119 | /** 120 | * @dev See {IERC20-allowance}. 121 | */ 122 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 123 | return _allowances[owner][spender]; 124 | } 125 | 126 | /** 127 | * @dev See {IERC20-approve}. 128 | * 129 | * Requirements: 130 | * 131 | * - `spender` cannot be the zero address. 132 | */ 133 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 134 | _approve(_msgSender(), spender, amount); 135 | return true; 136 | } 137 | 138 | /** 139 | * @dev See {IERC20-transferFrom}. 140 | * 141 | * Emits an {Approval} event indicating the updated allowance. This is not 142 | * required by the EIP. See the note at the beginning of {ERC20}. 143 | * 144 | * Requirements: 145 | * 146 | * - `sender` and `recipient` cannot be the zero address. 147 | * - `sender` must have a balance of at least `amount`. 148 | * - the caller must have allowance for ``sender``'s tokens of at least 149 | * `amount`. 150 | */ 151 | function transferFrom( 152 | address sender, 153 | address recipient, 154 | uint256 amount 155 | ) public virtual override returns (bool) { 156 | _transfer(sender, recipient, amount); 157 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 158 | return true; 159 | } 160 | 161 | /** 162 | * @dev Atomically increases the allowance granted to `spender` by the caller. 163 | * 164 | * This is an alternative to {approve} that can be used as a mitigation for 165 | * problems described in {IERC20-approve}. 166 | * 167 | * Emits an {Approval} event indicating the updated allowance. 168 | * 169 | * Requirements: 170 | * 171 | * - `spender` cannot be the zero address. 172 | */ 173 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 174 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 175 | return true; 176 | } 177 | 178 | /** 179 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 180 | * 181 | * This is an alternative to {approve} that can be used as a mitigation for 182 | * problems described in {IERC20-approve}. 183 | * 184 | * Emits an {Approval} event indicating the updated allowance. 185 | * 186 | * Requirements: 187 | * 188 | * - `spender` cannot be the zero address. 189 | * - `spender` must have allowance for the caller of at least 190 | * `subtractedValue`. 191 | */ 192 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 193 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 194 | return true; 195 | } 196 | 197 | /** 198 | * @dev Moves tokens `amount` from `sender` to `recipient`. 199 | * 200 | * This is internal function is equivalent to {transfer}, and can be used to 201 | * e.g. implement automatic token fees, slashing mechanisms, etc. 202 | * 203 | * Emits a {Transfer} event. 204 | * 205 | * Requirements: 206 | * 207 | * - `sender` cannot be the zero address. 208 | * - `recipient` cannot be the zero address. 209 | * - `sender` must have a balance of at least `amount`. 210 | */ 211 | function _transfer( 212 | address sender, 213 | address recipient, 214 | uint256 amount 215 | ) internal virtual { 216 | require(sender != address(0), "ERC20: transfer from the zero address"); 217 | require(recipient != address(0), "ERC20: transfer to the zero address"); 218 | 219 | _beforeTokenTransfer(sender, recipient, amount); 220 | 221 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 222 | _balances[recipient] = _balances[recipient].add(amount); 223 | emit Transfer(sender, recipient, amount); 224 | } 225 | 226 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 227 | * the total supply. 228 | * 229 | * Emits a {Transfer} event with `from` set to the zero address. 230 | * 231 | * Requirements: 232 | * 233 | * - `account` cannot be the zero address. 234 | */ 235 | function _mint(address account, uint256 amount) internal virtual { 236 | require(account != address(0), "ERC20: mint to the zero address"); 237 | 238 | _beforeTokenTransfer(address(0), account, amount); 239 | 240 | _totalSupply = _totalSupply.add(amount); 241 | _balances[account] = _balances[account].add(amount); 242 | emit Transfer(address(0), account, amount); 243 | } 244 | 245 | /** 246 | * @dev Destroys `amount` tokens from `account`, reducing the 247 | * total supply. 248 | * 249 | * Emits a {Transfer} event with `to` set to the zero address. 250 | * 251 | * Requirements: 252 | * 253 | * - `account` cannot be the zero address. 254 | * - `account` must have at least `amount` tokens. 255 | */ 256 | function _burn(address account, uint256 amount) internal virtual { 257 | require(account != address(0), "ERC20: burn from the zero address"); 258 | 259 | _beforeTokenTransfer(account, address(0), amount); 260 | 261 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 262 | _totalSupply = _totalSupply.sub(amount); 263 | emit Transfer(account, address(0), amount); 264 | } 265 | 266 | /** 267 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 268 | * 269 | * This internal function is equivalent to `approve`, and can be used to 270 | * e.g. set automatic allowances for certain subsystems, etc. 271 | * 272 | * Emits an {Approval} event. 273 | * 274 | * Requirements: 275 | * 276 | * - `owner` cannot be the zero address. 277 | * - `spender` cannot be the zero address. 278 | */ 279 | function _approve( 280 | address owner, 281 | address spender, 282 | uint256 amount 283 | ) internal virtual { 284 | require(owner != address(0), "ERC20: approve from the zero address"); 285 | require(spender != address(0), "ERC20: approve to the zero address"); 286 | 287 | _allowances[owner][spender] = amount; 288 | emit Approval(owner, spender, amount); 289 | } 290 | 291 | /** 292 | * @dev Hook that is called before any transfer of tokens. This includes 293 | * minting and burning. 294 | * 295 | * Calling conditions: 296 | * 297 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 298 | * will be to transferred to `to`. 299 | * - when `from` is zero, `amount` tokens will be minted for `to`. 300 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 301 | * - `from` and `to` are never both zero. 302 | * 303 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 304 | */ 305 | function _beforeTokenTransfer( 306 | address from, 307 | address to, 308 | uint256 amount 309 | ) internal virtual {} 310 | } 311 | -------------------------------------------------------------------------------- /IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom( 63 | address sender, 64 | address recipient, 65 | uint256 amount 66 | ) external returns (bool); 67 | 68 | /** 69 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 70 | * another (`to`). 71 | * 72 | * Note that `value` may be zero. 73 | */ 74 | event Transfer(address indexed from, address indexed to, uint256 value); 75 | 76 | /** 77 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 78 | * a call to {approve}. `value` is the new allowance. 79 | */ 80 | event Approval(address indexed owner, address indexed spender, uint256 value); 81 | } 82 | -------------------------------------------------------------------------------- /IERC20Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "./IERC20.sol"; 6 | 7 | /** 8 | * @dev Interface for the optional metadata functions from the ERC20 standard. 9 | * 10 | * _Available since v4.1._ 11 | */ 12 | interface IERC20Metadata is IERC20 { 13 | /** 14 | * @dev Returns the name of the token. 15 | */ 16 | function name() external view returns (string memory); 17 | 18 | /** 19 | * @dev Returns the symbol of the token. 20 | */ 21 | function symbol() external view returns (string memory); 22 | 23 | /** 24 | * @dev Returns the decimals places of the token. 25 | */ 26 | function decimals() external view returns (uint8); 27 | } 28 | -------------------------------------------------------------------------------- /IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 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 | 11 | function getPair(address tokenA, address tokenB) external view returns (address pair); 12 | function allPairs(uint) external view returns (address pair); 13 | function allPairsLength() external view returns (uint); 14 | 15 | function createPair(address tokenA, address tokenB) external returns (address pair); 16 | 17 | function setFeeTo(address) external; 18 | function setFeeToSetter(address) external; 19 | } 20 | -------------------------------------------------------------------------------- /IUniswapV2Pair.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 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 | } 55 | -------------------------------------------------------------------------------- /IUniswapV2Router.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | interface IUniswapV2Router01 { 6 | function factory() external pure returns (address); 7 | function WETH() 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 addLiquidityETH( 20 | address token, 21 | uint amountTokenDesired, 22 | uint amountTokenMin, 23 | uint amountETHMin, 24 | address to, 25 | uint deadline 26 | ) external payable returns (uint amountToken, uint amountETH, 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 removeLiquidityETH( 37 | address token, 38 | uint liquidity, 39 | uint amountTokenMin, 40 | uint amountETHMin, 41 | address to, 42 | uint deadline 43 | ) external returns (uint amountToken, uint amountETH); 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 removeLiquidityETHWithPermit( 55 | address token, 56 | uint liquidity, 57 | uint amountTokenMin, 58 | uint amountETHMin, 59 | address to, 60 | uint deadline, 61 | bool approveMax, uint8 v, bytes32 r, bytes32 s 62 | ) external returns (uint amountToken, uint amountETH); 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 swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 78 | external 79 | payable 80 | returns (uint[] memory amounts); 81 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 82 | external 83 | returns (uint[] memory amounts); 84 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 85 | external 86 | returns (uint[] memory amounts); 87 | function swapETHForExactTokens(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 | } 98 | 99 | 100 | 101 | // pragma solidity >=0.6.2; 102 | 103 | interface IUniswapV2Router02 is IUniswapV2Router01 { 104 | function removeLiquidityETHSupportingFeeOnTransferTokens( 105 | address token, 106 | uint liquidity, 107 | uint amountTokenMin, 108 | uint amountETHMin, 109 | address to, 110 | uint deadline 111 | ) external returns (uint amountETH); 112 | function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( 113 | address token, 114 | uint liquidity, 115 | uint amountTokenMin, 116 | uint amountETHMin, 117 | address to, 118 | uint deadline, 119 | bool approveMax, uint8 v, bytes32 r, bytes32 s 120 | ) external returns (uint amountETH); 121 | 122 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 123 | uint amountIn, 124 | uint amountOutMin, 125 | address[] calldata path, 126 | address to, 127 | uint deadline 128 | ) external; 129 | function swapExactETHForTokensSupportingFeeOnTransferTokens( 130 | uint amountOutMin, 131 | address[] calldata path, 132 | address to, 133 | uint deadline 134 | ) external payable; 135 | function swapExactTokensForETHSupportingFeeOnTransferTokens( 136 | uint amountIn, 137 | uint amountOutMin, 138 | address[] calldata path, 139 | address to, 140 | uint deadline 141 | ) external; 142 | } 143 | -------------------------------------------------------------------------------- /InfluenceHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicensed 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "./DividendPayingToken.sol"; 6 | import "./SafeMath.sol"; 7 | import "./IterableMapping.sol"; 8 | import "./Ownable.sol"; 9 | import "./IUniswapV2Pair.sol"; 10 | import "./IUniswapV2Factory.sol"; 11 | import "./IUniswapV2Router.sol"; 12 | 13 | // Dev: @FreezyEx 14 | //https://github.com/FreezyEx 15 | contract INFLHUB is ERC20, Ownable { 16 | using SafeMath for uint256; 17 | 18 | IUniswapV2Router02 public uniswapV2Router; 19 | address public immutable uniswapV2Pair; 20 | address public immutable deadAddress = 0x000000000000000000000000000000000000dEaD; 21 | 22 | mapping (address => bool) public _isBlacklisted; 23 | 24 | 25 | bool private swapping; 26 | 27 | INFLHUBDividendTracker public dividendTracker; 28 | 29 | address public liquidityWallet; 30 | 31 | uint256 public maxSellTransactionAmount = 1000000000000000 * (10**9); 32 | uint256 public swapTokensAtAmount = 100000000000 * (10**9); 33 | 34 | uint256 public BNBRewardsFee; 35 | uint256 public buyBackFee; 36 | uint256 public marketingFee; 37 | uint256 public totalFees; 38 | 39 | uint256 public buyBackUpperLimit = 1 * 10**15; 40 | bool public buyBackEnabled = true; 41 | bool public swapEnabled = false; 42 | 43 | address payable _marketingWallet; 44 | 45 | // use by default 300,000 gas to process auto-claiming dividends 46 | uint256 public gasForProcessing = 300000; 47 | 48 | mapping (address => bool) private _isExcludedFromFees; 49 | 50 | // store addresses that a automatic market maker pairs. Any transfer *to* these addresses 51 | // could be subject to a maximum transfer amount 52 | mapping (address => bool) public automatedMarketMakerPairs; 53 | 54 | event UpdateDividendTracker(address indexed newAddress, address indexed oldAddress); 55 | 56 | event UpdateUniswapV2Router(address indexed newAddress, address indexed oldAddress); 57 | 58 | event ExcludeFromFees(address indexed account, bool isExcluded); 59 | event ExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded); 60 | 61 | event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value); 62 | 63 | event LiquidityWalletUpdated(address indexed newLiquidityWallet, address indexed oldLiquidityWallet); 64 | 65 | event GasForProcessingUpdated(uint256 indexed newValue, uint256 indexed oldValue); 66 | 67 | event SwapAndLiquify( 68 | uint256 tokensSwapped, 69 | uint256 ethReceived, 70 | uint256 tokensIntoLiqudity 71 | ); 72 | 73 | event SwapETHForTokens( 74 | uint256 amountIn, 75 | address[] path 76 | ); 77 | 78 | event SendDividends( 79 | uint256 tokensSwapped, 80 | uint256 amount 81 | ); 82 | 83 | event ProcessedDividendTracker( 84 | uint256 iterations, 85 | uint256 claims, 86 | uint256 lastProcessedIndex, 87 | bool indexed automatic, 88 | uint256 gas, 89 | address indexed processor 90 | ); 91 | 92 | modifier lockTheSwap { 93 | swapping = true; 94 | _; 95 | swapping = false; 96 | } 97 | 98 | constructor() public ERC20("InfluenceHub", "INFLHUB") { 99 | uint256 _BNBRewardsFee = 3; 100 | uint256 _buyBackFee = 6; 101 | uint256 _marketingFee= 3; 102 | 103 | BNBRewardsFee = _BNBRewardsFee; 104 | buyBackFee = _buyBackFee; 105 | marketingFee = _marketingFee; 106 | totalFees = _BNBRewardsFee.add(_buyBackFee).add(_marketingFee); 107 | 108 | _marketingWallet = 0x0DA6b646f915E75Fd5b965E0ac20f61F78AeD566; 109 | dividendTracker = new INFLHUBDividendTracker(); 110 | 111 | liquidityWallet = owner(); 112 | 113 | 114 | IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E); 115 | // Create a uniswap pair for this new token 116 | address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()) 117 | .createPair(address(this), _uniswapV2Router.WETH()); 118 | 119 | uniswapV2Router = _uniswapV2Router; 120 | uniswapV2Pair = _uniswapV2Pair; 121 | 122 | _setAutomatedMarketMakerPair(_uniswapV2Pair, true); 123 | 124 | // exclude from receiving dividends 125 | dividendTracker.excludeFromDividends(address(dividendTracker)); 126 | dividendTracker.excludeFromDividends(address(this)); 127 | dividendTracker.excludeFromDividends(owner()); 128 | dividendTracker.excludeFromDividends(address(_uniswapV2Router)); 129 | 130 | // exclude from paying fees or having max transaction amount 131 | excludeFromFees(liquidityWallet, true); 132 | excludeFromFees(address(this), true); 133 | 134 | /* 135 | _mint is an internal function in ERC20.sol that is only called here, 136 | and CANNOT be called ever again 137 | */ 138 | _mint(owner(), 1000000000000000 * (10**9)); 139 | } 140 | 141 | receive() external payable { 142 | 143 | } 144 | 145 | function decimals() public view override returns (uint8) { 146 | return 9; 147 | } 148 | 149 | function updateDividendTracker(address newAddress) public onlyOwner { 150 | require(newAddress != address(dividendTracker), "INFLHUB: The dividend tracker already has that address"); 151 | 152 | INFLHUBDividendTracker newDividendTracker = INFLHUBDividendTracker(payable(newAddress)); 153 | 154 | require(newDividendTracker.owner() == address(this), "INFLHUB: The new dividend tracker must be owned by the INFLHUB token contract"); 155 | 156 | newDividendTracker.excludeFromDividends(address(newDividendTracker)); 157 | newDividendTracker.excludeFromDividends(address(this)); 158 | newDividendTracker.excludeFromDividends(owner()); 159 | newDividendTracker.excludeFromDividends(address(uniswapV2Router)); 160 | 161 | emit UpdateDividendTracker(newAddress, address(dividendTracker)); 162 | 163 | dividendTracker = newDividendTracker; 164 | } 165 | 166 | function updateUniswapV2Router(address newAddress) public onlyOwner { 167 | require(newAddress != address(uniswapV2Router), "INFLHUB: The router already has that address"); 168 | emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router)); 169 | uniswapV2Router = IUniswapV2Router02(newAddress); 170 | } 171 | 172 | function excludeFromFees(address account, bool excluded) public onlyOwner { 173 | require(_isExcludedFromFees[account] != excluded, "INFLHUB: Account is already the value of 'excluded'"); 174 | _isExcludedFromFees[account] = excluded; 175 | 176 | emit ExcludeFromFees(account, excluded); 177 | } 178 | 179 | function excludeMultipleAccountsFromFees(address[] calldata accounts, bool excluded) public onlyOwner { 180 | for(uint256 i = 0; i < accounts.length; i++) { 181 | _isExcludedFromFees[accounts[i]] = excluded; 182 | } 183 | 184 | emit ExcludeMultipleAccountsFromFees(accounts, excluded); 185 | } 186 | 187 | 188 | function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner { 189 | require(pair != uniswapV2Pair, "INFLHUB: The PancakeSwap pair cannot be removed from automatedMarketMakerPairs"); 190 | 191 | _setAutomatedMarketMakerPair(pair, value); 192 | } 193 | 194 | function _setAutomatedMarketMakerPair(address pair, bool value) private { 195 | require(automatedMarketMakerPairs[pair] != value, "INFLHUB: Automated market maker pair is already set to that value"); 196 | automatedMarketMakerPairs[pair] = value; 197 | 198 | if(value) { 199 | dividendTracker.excludeFromDividends(pair); 200 | } 201 | 202 | emit SetAutomatedMarketMakerPair(pair, value); 203 | } 204 | 205 | 206 | function updateLiquidityWallet(address newLiquidityWallet) public onlyOwner { 207 | require(newLiquidityWallet != liquidityWallet, "INFLHUB: The liquidity wallet is already this address"); 208 | excludeFromFees(newLiquidityWallet, true); 209 | emit LiquidityWalletUpdated(newLiquidityWallet, liquidityWallet); 210 | liquidityWallet = newLiquidityWallet; 211 | } 212 | 213 | function updateGasForProcessing(uint256 newValue) public onlyOwner { 214 | require(newValue >= 200000 && newValue <= 500000, "INFLHUB: gasForProcessing must be between 200,000 and 500,000"); 215 | require(newValue != gasForProcessing, "INFLHUB: Cannot update gasForProcessing to same value"); 216 | emit GasForProcessingUpdated(newValue, gasForProcessing); 217 | gasForProcessing = newValue; 218 | } 219 | 220 | function updateClaimWait(uint256 claimWait) external onlyOwner { 221 | dividendTracker.updateClaimWait(claimWait); 222 | } 223 | 224 | function getClaimWait() external view returns(uint256) { 225 | return dividendTracker.claimWait(); 226 | } 227 | 228 | function getTotalDividendsDistributed() external view returns (uint256) { 229 | return dividendTracker.totalDividendsDistributed(); 230 | } 231 | 232 | function isExcludedFromFees(address account) public view returns(bool) { 233 | return _isExcludedFromFees[account]; 234 | } 235 | 236 | function withdrawableDividendOf(address account) public view returns(uint256) { 237 | return dividendTracker.withdrawableDividendOf(account); 238 | } 239 | 240 | function dividendTokenBalanceOf(address account) public view returns (uint256) { 241 | return dividendTracker.balanceOf(account); 242 | } 243 | 244 | function getAccountDividendsInfo(address account) 245 | external view returns ( 246 | address, 247 | int256, 248 | int256, 249 | uint256, 250 | uint256, 251 | uint256, 252 | uint256, 253 | uint256) { 254 | return dividendTracker.getAccount(account); 255 | } 256 | 257 | function getAccountDividendsInfoAtIndex(uint256 index) 258 | external view returns ( 259 | address, 260 | int256, 261 | int256, 262 | uint256, 263 | uint256, 264 | uint256, 265 | uint256, 266 | uint256) { 267 | return dividendTracker.getAccountAtIndex(index); 268 | } 269 | 270 | function withdraw(uint256 weiAmount) external onlyOwner { 271 | require(address(this).balance >= weiAmount); 272 | msg.sender.transfer(weiAmount); 273 | } 274 | 275 | function processDividendTracker(uint256 gas) external { 276 | (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) = dividendTracker.process(gas); 277 | emit ProcessedDividendTracker(iterations, claims, lastProcessedIndex, false, gas, tx.origin); 278 | } 279 | 280 | function claim() external { 281 | dividendTracker.processAccount(msg.sender, false); 282 | } 283 | 284 | function getLastProcessedIndex() external view returns(uint256) { 285 | return dividendTracker.getLastProcessedIndex(); 286 | } 287 | 288 | function getNumberOfDividendTokenHolders() external view returns(uint256) { 289 | return dividendTracker.getNumberOfTokenHolders(); 290 | } 291 | 292 | function setMaxSellTxAMount(uint256 amount) external onlyOwner{ 293 | maxSellTransactionAmount = amount; 294 | } 295 | 296 | function setSwapTokensAmt(uint256 amt) external onlyOwner{ 297 | swapTokensAtAmount = amt; 298 | } 299 | 300 | function setBNBRewardsFee(uint256 value) external onlyOwner{ 301 | BNBRewardsFee = value; 302 | } 303 | 304 | function setMarketingFee(uint256 value) external onlyOwner{ 305 | marketingFee = value; 306 | } 307 | 308 | function setMarketingWallet(address newWallet) external onlyOwner{ 309 | _marketingWallet = payable(newWallet); 310 | } 311 | 312 | function addToBlackList(address[] calldata addresses) external onlyOwner { 313 | for (uint256 i; i < addresses.length; ++i) { 314 | _isBlacklisted[addresses[i]] = true; 315 | } 316 | } 317 | 318 | function removeFromBlackList(address account) external onlyOwner { 319 | _isBlacklisted[account] = false; 320 | } 321 | 322 | 323 | function setSwapEnabled(bool value) external onlyOwner{ 324 | swapEnabled = value; 325 | } 326 | 327 | function setBuyBackFee(uint256 value) external onlyOwner{ 328 | buyBackFee = value; 329 | } 330 | 331 | function _transfer( 332 | address from, 333 | address to, 334 | uint256 amount 335 | ) internal override { 336 | require(from != address(0), "ERC20: transfer from the zero address"); 337 | require(to != address(0), "ERC20: transfer to the zero address"); 338 | require(!_isBlacklisted[from] && !_isBlacklisted[to], "This address is blacklisted"); 339 | 340 | if(amount == 0) { 341 | super._transfer(from, to, 0); 342 | return; 343 | } 344 | 345 | if( 346 | !swapping && 347 | automatedMarketMakerPairs[to] && // sells only by detecting transfer to automated market maker pair 348 | from != address(uniswapV2Router) && //router -> pair is removing liquidity which shouldn't have max 349 | !_isExcludedFromFees[to] //no max for those excluded from fees 350 | ) { 351 | require(amount <= maxSellTransactionAmount, "Sell transfer amount exceeds the maxSellTransactionAmount."); 352 | } 353 | 354 | 355 | uint256 contractTokenBalance = balanceOf(address(this)); 356 | bool overMinimumTokenBalance = contractTokenBalance >= swapTokensAtAmount; 357 | if(swapEnabled && !swapping && to == uniswapV2Pair ) { 358 | uint256 balance = address(this).balance; 359 | if (buyBackEnabled && balance > uint256(1 * 10**15)) { 360 | 361 | if (balance > buyBackUpperLimit) 362 | balance = buyBackUpperLimit; 363 | 364 | buyBackTokens(balance.div(100)); 365 | } 366 | 367 | 368 | 369 | if (overMinimumTokenBalance) { 370 | contractTokenBalance = swapTokensAtAmount; 371 | 372 | uint256 swapTokens = contractTokenBalance.mul(marketingFee).div(totalFees); 373 | swapAndSendToMarketing(swapTokens); 374 | 375 | contractTokenBalance = balanceOf(address(this)); 376 | 377 | uint256 buyBackTokens = contractTokenBalance.mul(buyBackFee).div(totalFees); 378 | swapBuyBackTokens(buyBackTokens); 379 | 380 | uint256 sellTokens = balanceOf(address(this)); 381 | swapAndSendDividends(sellTokens); 382 | } 383 | 384 | } 385 | 386 | 387 | bool takeFee = true; 388 | 389 | // if any account belongs to _isExcludedFromFee account then remove the fee 390 | if(_isExcludedFromFees[from] || _isExcludedFromFees[to]) { 391 | takeFee = false; 392 | } 393 | 394 | if(takeFee) { 395 | uint256 fees = amount.mul(totalFees).div(100); 396 | amount = amount.sub(fees); 397 | 398 | super._transfer(from, address(this), fees); 399 | } 400 | 401 | super._transfer(from, to, amount); 402 | 403 | try dividendTracker.setBalance(payable(from), balanceOf(from)) {} catch {} 404 | try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {} 405 | 406 | if(!swapping) { 407 | uint256 gas = gasForProcessing; 408 | 409 | try dividendTracker.process(gas) returns (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) { 410 | emit ProcessedDividendTracker(iterations, claims, lastProcessedIndex, true, gas, tx.origin); 411 | } 412 | catch { 413 | 414 | } 415 | } 416 | } 417 | 418 | function swapAndSendToMarketing(uint256 tokens) private lockTheSwap { 419 | 420 | uint256 initialBalance = address(this).balance; 421 | 422 | swapTokensForEth(tokens); 423 | // how much ETH did we just swap into? 424 | uint256 newBalance = address(this).balance.sub(initialBalance); 425 | _marketingWallet.transfer(newBalance); 426 | } 427 | 428 | function swapTokensForEth(uint256 tokenAmount) private { 429 | 430 | 431 | // generate the uniswap pair path of token -> weth 432 | address[] memory path = new address[](2); 433 | path[0] = address(this); 434 | path[1] = uniswapV2Router.WETH(); 435 | 436 | _approve(address(this), address(uniswapV2Router), tokenAmount); 437 | 438 | // make the swap 439 | uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( 440 | tokenAmount, 441 | 0, // accept any amount of ETH 442 | path, 443 | address(this), 444 | block.timestamp 445 | ); 446 | 447 | } 448 | 449 | function buyBackTokens(uint256 amount) private lockTheSwap{ 450 | if (amount > 0) { 451 | swapETHForTokens(amount); 452 | } 453 | } 454 | 455 | function swapETHForTokens(uint256 amount) private { 456 | // generate the uniswap pair path of token -> weth 457 | address[] memory path = new address[](2); 458 | path[0] = uniswapV2Router.WETH(); 459 | path[1] = address(this); 460 | 461 | // make the swap 462 | uniswapV2Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}( 463 | 0, // accept any amount of Tokens 464 | path, 465 | deadAddress, // Burn address 466 | block.timestamp.add(300) 467 | ); 468 | 469 | emit SwapETHForTokens(amount, path); 470 | } 471 | 472 | function swapBuyBackTokens(uint256 tokens) private lockTheSwap{ 473 | swapTokensForEth(tokens); 474 | } 475 | 476 | function setBuyBackEnabled(bool _enabled) public onlyOwner { 477 | buyBackEnabled = _enabled; 478 | } 479 | 480 | function setBuybackUpperLimit(uint256 buyBackLimit) external onlyOwner() { 481 | buyBackUpperLimit = buyBackLimit * 10**15; 482 | } 483 | 484 | function swapAndSendDividends(uint256 tokens) private lockTheSwap{ 485 | uint256 initialBalance = address(this).balance; 486 | swapTokensForEth(tokens); 487 | uint256 dividends = address(this).balance.sub(initialBalance); 488 | (bool success,) = address(dividendTracker).call{value: dividends}(""); 489 | 490 | if(success) { 491 | emit SendDividends(tokens, dividends); 492 | } 493 | } 494 | } 495 | 496 | contract INFLHUBDividendTracker is DividendPayingToken, Ownable { 497 | using SafeMath for uint256; 498 | using SafeMathInt for int256; 499 | using IterableMapping for IterableMapping.Map; 500 | 501 | IterableMapping.Map private tokenHoldersMap; 502 | uint256 public lastProcessedIndex; 503 | 504 | mapping (address => bool) public excludedFromDividends; 505 | 506 | mapping (address => uint256) public lastClaimTimes; 507 | 508 | uint256 public claimWait; 509 | uint256 public immutable minimumTokenBalanceForDividends; 510 | 511 | event ExcludeFromDividends(address indexed account); 512 | event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue); 513 | 514 | event Claim(address indexed account, uint256 amount, bool indexed automatic); 515 | 516 | constructor() public DividendPayingToken("INFLHUB_Dividend_Tracker", "INFLHUB_Dividend_Tracker") { 517 | claimWait = 3600; 518 | minimumTokenBalanceForDividends = 100000000000 * (10**9); //must hold 100000000000+ tokens 519 | } 520 | 521 | function _transfer(address, address, uint256) internal override { 522 | require(false, "INFLHUB_Dividend_Tracker: No transfers allowed"); 523 | } 524 | 525 | function withdrawDividend() public override { 526 | require(false, "INFLHUB_Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main INFLHUB contract."); 527 | } 528 | 529 | function excludeFromDividends(address account) external onlyOwner { 530 | require(!excludedFromDividends[account]); 531 | excludedFromDividends[account] = true; 532 | 533 | _setBalance(account, 0); 534 | tokenHoldersMap.remove(account); 535 | 536 | emit ExcludeFromDividends(account); 537 | } 538 | 539 | function updateClaimWait(uint256 newClaimWait) external onlyOwner { 540 | require(newClaimWait >= 3600 && newClaimWait <= 86400, "INFLHUB_Dividend_Tracker: claimWait must be updated to between 1 and 24 hours"); 541 | require(newClaimWait != claimWait, "INFLHUB_Dividend_Tracker: Cannot update claimWait to same value"); 542 | emit ClaimWaitUpdated(newClaimWait, claimWait); 543 | claimWait = newClaimWait; 544 | } 545 | 546 | function getLastProcessedIndex() external view returns(uint256) { 547 | return lastProcessedIndex; 548 | } 549 | 550 | function getNumberOfTokenHolders() external view returns(uint256) { 551 | return tokenHoldersMap.keys.length; 552 | } 553 | 554 | 555 | 556 | function getAccount(address _account) 557 | public view returns ( 558 | address account, 559 | int256 index, 560 | int256 iterationsUntilProcessed, 561 | uint256 withdrawableDividends, 562 | uint256 totalDividends, 563 | uint256 lastClaimTime, 564 | uint256 nextClaimTime, 565 | uint256 secondsUntilAutoClaimAvailable) { 566 | account = _account; 567 | 568 | index = tokenHoldersMap.getIndexOfKey(account); 569 | 570 | iterationsUntilProcessed = -1; 571 | 572 | if(index >= 0) { 573 | if(uint256(index) > lastProcessedIndex) { 574 | iterationsUntilProcessed = index.sub(int256(lastProcessedIndex)); 575 | } 576 | else { 577 | uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ? 578 | tokenHoldersMap.keys.length.sub(lastProcessedIndex) : 579 | 0; 580 | 581 | 582 | iterationsUntilProcessed = index.add(int256(processesUntilEndOfArray)); 583 | } 584 | } 585 | 586 | 587 | withdrawableDividends = withdrawableDividendOf(account); 588 | totalDividends = accumulativeDividendOf(account); 589 | 590 | lastClaimTime = lastClaimTimes[account]; 591 | 592 | nextClaimTime = lastClaimTime > 0 ? 593 | lastClaimTime.add(claimWait) : 594 | 0; 595 | 596 | secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp ? 597 | nextClaimTime.sub(block.timestamp) : 598 | 0; 599 | } 600 | 601 | function getAccountAtIndex(uint256 index) 602 | public view returns ( 603 | address, 604 | int256, 605 | int256, 606 | uint256, 607 | uint256, 608 | uint256, 609 | uint256, 610 | uint256) { 611 | if(index >= tokenHoldersMap.size()) { 612 | return (0x0000000000000000000000000000000000000000, -1, -1, 0, 0, 0, 0, 0); 613 | } 614 | 615 | address account = tokenHoldersMap.getKeyAtIndex(index); 616 | 617 | return getAccount(account); 618 | } 619 | 620 | function canAutoClaim(uint256 lastClaimTime) private view returns (bool) { 621 | if(lastClaimTime > block.timestamp) { 622 | return false; 623 | } 624 | 625 | return block.timestamp.sub(lastClaimTime) >= claimWait; 626 | } 627 | 628 | function setBalance(address payable account, uint256 newBalance) external onlyOwner { 629 | if(excludedFromDividends[account]) { 630 | return; 631 | } 632 | 633 | if(newBalance >= minimumTokenBalanceForDividends) { 634 | _setBalance(account, newBalance); 635 | tokenHoldersMap.set(account, newBalance); 636 | } 637 | else { 638 | _setBalance(account, 0); 639 | tokenHoldersMap.remove(account); 640 | } 641 | 642 | processAccount(account, true); 643 | } 644 | 645 | function process(uint256 gas) public returns (uint256, uint256, uint256) { 646 | uint256 numberOfTokenHolders = tokenHoldersMap.keys.length; 647 | 648 | if(numberOfTokenHolders == 0) { 649 | return (0, 0, lastProcessedIndex); 650 | } 651 | 652 | uint256 _lastProcessedIndex = lastProcessedIndex; 653 | 654 | uint256 gasUsed = 0; 655 | 656 | uint256 gasLeft = gasleft(); 657 | 658 | uint256 iterations = 0; 659 | uint256 claims = 0; 660 | 661 | while(gasUsed < gas && iterations < numberOfTokenHolders) { 662 | _lastProcessedIndex++; 663 | 664 | if(_lastProcessedIndex >= tokenHoldersMap.keys.length) { 665 | _lastProcessedIndex = 0; 666 | } 667 | 668 | address account = tokenHoldersMap.keys[_lastProcessedIndex]; 669 | 670 | if(canAutoClaim(lastClaimTimes[account])) { 671 | if(processAccount(payable(account), true)) { 672 | claims++; 673 | } 674 | } 675 | 676 | iterations++; 677 | 678 | uint256 newGasLeft = gasleft(); 679 | 680 | if(gasLeft > newGasLeft) { 681 | gasUsed = gasUsed.add(gasLeft.sub(newGasLeft)); 682 | } 683 | 684 | gasLeft = newGasLeft; 685 | } 686 | 687 | lastProcessedIndex = _lastProcessedIndex; 688 | 689 | return (iterations, claims, lastProcessedIndex); 690 | } 691 | 692 | function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) { 693 | uint256 amount = _withdrawDividendOfUser(account); 694 | 695 | if(amount > 0) { 696 | lastClaimTimes[account] = block.timestamp; 697 | emit Claim(account, amount, automatic); 698 | return true; 699 | } 700 | 701 | return false; 702 | } 703 | } 704 | -------------------------------------------------------------------------------- /IterableMapping.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.2; 3 | 4 | library IterableMapping { 5 | // Iterable mapping from address to uint; 6 | struct Map { 7 | address[] keys; 8 | mapping(address => uint) values; 9 | mapping(address => uint) indexOf; 10 | mapping(address => bool) inserted; 11 | } 12 | 13 | function get(Map storage map, address key) public view returns (uint) { 14 | return map.values[key]; 15 | } 16 | 17 | function getIndexOfKey(Map storage map, address key) public view returns (int) { 18 | if(!map.inserted[key]) { 19 | return -1; 20 | } 21 | return int(map.indexOf[key]); 22 | } 23 | 24 | function getKeyAtIndex(Map storage map, uint index) public view returns (address) { 25 | return map.keys[index]; 26 | } 27 | 28 | 29 | 30 | function size(Map storage map) public view returns (uint) { 31 | return map.keys.length; 32 | } 33 | 34 | function set(Map storage map, address key, uint val) public { 35 | if (map.inserted[key]) { 36 | map.values[key] = val; 37 | } else { 38 | map.inserted[key] = true; 39 | map.values[key] = val; 40 | map.indexOf[key] = map.keys.length; 41 | map.keys.push(key); 42 | } 43 | } 44 | 45 | function remove(Map storage map, address key) public { 46 | if (!map.inserted[key]) { 47 | return; 48 | } 49 | 50 | delete map.inserted[key]; 51 | delete map.values[key]; 52 | 53 | uint index = map.indexOf[key]; 54 | uint lastIndex = map.keys.length - 1; 55 | address lastKey = map.keys[lastIndex]; 56 | 57 | map.indexOf[lastKey] = index; 58 | delete map.indexOf[key]; 59 | 60 | map.keys[index] = lastKey; 61 | map.keys.pop(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.2; 2 | 3 | // SPDX-License-Identifier: MIT License 4 | 5 | import "./Context.sol"; 6 | 7 | contract Ownable is Context { 8 | address private _owner; 9 | 10 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 11 | 12 | /** 13 | * @dev Initializes the contract setting the deployer as the initial owner. 14 | */ 15 | constructor () public { 16 | address msgSender = _msgSender(); 17 | _owner = msgSender; 18 | emit OwnershipTransferred(address(0), msgSender); 19 | } 20 | 21 | /** 22 | * @dev Returns the address of the current owner. 23 | */ 24 | function owner() public view returns (address) { 25 | return _owner; 26 | } 27 | 28 | /** 29 | * @dev Throws if called by any account other than the owner. 30 | */ 31 | modifier onlyOwner() { 32 | require(_owner == _msgSender(), "Ownable: caller is not the owner"); 33 | _; 34 | } 35 | 36 | /** 37 | * @dev Leaves the contract without owner. It will not be possible to call 38 | * `onlyOwner` functions anymore. Can only be called by the current owner. 39 | * 40 | * NOTE: Renouncing ownership will leave the contract without an owner, 41 | * thereby removing any functionality that is only available to the owner. 42 | */ 43 | function renounceOwnership() public virtual onlyOwner { 44 | emit OwnershipTransferred(_owner, address(0)); 45 | _owner = address(0); 46 | } 47 | 48 | /** 49 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 50 | * Can only be called by the current owner. 51 | */ 52 | function transferOwnership(address newOwner) public virtual onlyOwner { 53 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 54 | emit OwnershipTransferred(_owner, newOwner); 55 | _owner = newOwner; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InfluenceHub 2 | Auto-redistribution in BNB + Buyback feature 3 | 4 | A token with auto-redistribution in BNB. The users don't have to do anything. Just hold and wait. 5 | In addition has been added one of the new trend: Buyback feature (Thanks to Everrrise) 6 | -------------------------------------------------------------------------------- /SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | library SafeMath { 6 | /** 7 | * @dev Returns the addition of two unsigned integers, reverting on 8 | * overflow. 9 | * 10 | * Counterpart to Solidity's `+` operator. 11 | * 12 | * Requirements: 13 | * 14 | * - Addition cannot overflow. 15 | */ 16 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 17 | uint256 c = a + b; 18 | require(c >= a, "SafeMath: addition overflow"); 19 | 20 | return c; 21 | } 22 | 23 | /** 24 | * @dev Returns the subtraction of two unsigned integers, reverting on 25 | * overflow (when the result is negative). 26 | * 27 | * Counterpart to Solidity's `-` operator. 28 | * 29 | * Requirements: 30 | * 31 | * - Subtraction cannot overflow. 32 | */ 33 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 34 | return sub(a, b, "SafeMath: subtraction overflow"); 35 | } 36 | 37 | /** 38 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 39 | * overflow (when the result is negative). 40 | * 41 | * Counterpart to Solidity's `-` operator. 42 | * 43 | * Requirements: 44 | * 45 | * - Subtraction cannot overflow. 46 | */ 47 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 48 | require(b <= a, errorMessage); 49 | uint256 c = a - b; 50 | 51 | return c; 52 | } 53 | 54 | /** 55 | * @dev Returns the multiplication of two unsigned integers, reverting on 56 | * overflow. 57 | * 58 | * Counterpart to Solidity's `*` operator. 59 | * 60 | * Requirements: 61 | * 62 | * - Multiplication cannot overflow. 63 | */ 64 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 65 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 66 | // benefit is lost if 'b' is also tested. 67 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 68 | if (a == 0) { 69 | return 0; 70 | } 71 | 72 | uint256 c = a * b; 73 | require(c / a == b, "SafeMath: multiplication overflow"); 74 | 75 | return c; 76 | } 77 | 78 | /** 79 | * @dev Returns the integer division of two unsigned integers. Reverts on 80 | * division by zero. The result is rounded towards zero. 81 | * 82 | * Counterpart to Solidity's `/` operator. Note: this function uses a 83 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 84 | * uses an invalid opcode to revert (consuming all remaining gas). 85 | * 86 | * Requirements: 87 | * 88 | * - The divisor cannot be zero. 89 | */ 90 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 91 | return div(a, b, "SafeMath: division by zero"); 92 | } 93 | 94 | /** 95 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 96 | * division by zero. The result is rounded towards zero. 97 | * 98 | * Counterpart to Solidity's `/` operator. Note: this function uses a 99 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 100 | * uses an invalid opcode to revert (consuming all remaining gas). 101 | * 102 | * Requirements: 103 | * 104 | * - The divisor cannot be zero. 105 | */ 106 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 107 | require(b > 0, errorMessage); 108 | uint256 c = a / b; 109 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 110 | 111 | return c; 112 | } 113 | 114 | /** 115 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 116 | * Reverts when dividing by zero. 117 | * 118 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 119 | * opcode (which leaves remaining gas untouched) while Solidity uses an 120 | * invalid opcode to revert (consuming all remaining gas). 121 | * 122 | * Requirements: 123 | * 124 | * - The divisor cannot be zero. 125 | */ 126 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 127 | return mod(a, b, "SafeMath: modulo by zero"); 128 | } 129 | 130 | /** 131 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 132 | * Reverts with custom message when dividing by zero. 133 | * 134 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 135 | * opcode (which leaves remaining gas untouched) while Solidity uses an 136 | * invalid opcode to revert (consuming all remaining gas). 137 | * 138 | * Requirements: 139 | * 140 | * - The divisor cannot be zero. 141 | */ 142 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 143 | require(b != 0, errorMessage); 144 | return a % b; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /SafeMathInt.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | /* 4 | MIT License 5 | 6 | Copyright (c) 2018 requestnetwork 7 | Copyright (c) 2018 Fragments, Inc. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | pragma solidity ^0.6.2; 29 | 30 | /** 31 | * @title SafeMathInt 32 | * @dev Math operations for int256 with overflow safety checks. 33 | */ 34 | library SafeMathInt { 35 | int256 private constant MIN_INT256 = int256(1) << 255; 36 | int256 private constant MAX_INT256 = ~(int256(1) << 255); 37 | 38 | /** 39 | * @dev Multiplies two int256 variables and fails on overflow. 40 | */ 41 | function mul(int256 a, int256 b) internal pure returns (int256) { 42 | int256 c = a * b; 43 | 44 | // Detect overflow when multiplying MIN_INT256 with -1 45 | require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256)); 46 | require((b == 0) || (c / b == a)); 47 | return c; 48 | } 49 | 50 | /** 51 | * @dev Division of two int256 variables and fails on overflow. 52 | */ 53 | function div(int256 a, int256 b) internal pure returns (int256) { 54 | // Prevent overflow when dividing MIN_INT256 by -1 55 | require(b != -1 || a != MIN_INT256); 56 | 57 | // Solidity already throws when dividing by 0. 58 | return a / b; 59 | } 60 | 61 | /** 62 | * @dev Subtracts two int256 variables and fails on overflow. 63 | */ 64 | function sub(int256 a, int256 b) internal pure returns (int256) { 65 | int256 c = a - b; 66 | require((b >= 0 && c <= a) || (b < 0 && c > a)); 67 | return c; 68 | } 69 | 70 | /** 71 | * @dev Adds two int256 variables and fails on overflow. 72 | */ 73 | function add(int256 a, int256 b) internal pure returns (int256) { 74 | int256 c = a + b; 75 | require((b >= 0 && c >= a) || (b < 0 && c < a)); 76 | return c; 77 | } 78 | 79 | /** 80 | * @dev Converts to absolute value, and fails on overflow. 81 | */ 82 | function abs(int256 a) internal pure returns (int256) { 83 | require(a != MIN_INT256); 84 | return a < 0 ? -a : a; 85 | } 86 | 87 | 88 | function toUint256Safe(int256 a) internal pure returns (uint256) { 89 | require(a >= 0); 90 | return uint256(a); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /SafeMathUint.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | /** 6 | * @title SafeMathUint 7 | * @dev Math operations with safety checks that revert on error 8 | */ 9 | library SafeMathUint { 10 | function toInt256Safe(uint256 a) internal pure returns (int256) { 11 | int256 b = int256(a); 12 | require(b >= 0); 13 | return b; 14 | } 15 | } 16 | --------------------------------------------------------------------------------