├── LICENSE ├── Pawswap token ├── wPAW Compound Restake ├── PAWSWAP flexible stake ├── PAWSWAP Shibaswap LP Stake └── PAWSWAP Uni V2 LP Stake /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Pawkishi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pawswap token: -------------------------------------------------------------------------------- 1 | 2 | 3 | // SPDX-License-Identifier: MIT 4 | 5 | // File: @openzeppelin/contracts/token/ERC20/IERC20.sol 6 | 7 | 8 | 9 | pragma solidity ^0.8.0; 10 | 11 | /** 12 | * @dev Interface of the ERC20 standard as defined in the EIP. 13 | */ 14 | interface IERC20 { 15 | /** 16 | * @dev Returns the amount of tokens in existence. 17 | */ 18 | function totalSupply() external view returns (uint256); 19 | 20 | /** 21 | * @dev Returns the amount of tokens owned by `account`. 22 | */ 23 | function balanceOf(address account) external view returns (uint256); 24 | 25 | /** 26 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 27 | * 28 | * Returns a boolean value indicating whether the operation succeeded. 29 | * 30 | * Emits a {Transfer} event. 31 | */ 32 | function transfer(address recipient, uint256 amount) external returns (bool); 33 | 34 | /** 35 | * @dev Returns the remaining number of tokens that `spender` will be 36 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 37 | * zero by default. 38 | * 39 | * This value changes when {approve} or {transferFrom} are called. 40 | */ 41 | function allowance(address owner, address spender) external view returns (uint256); 42 | 43 | /** 44 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 45 | * 46 | * Returns a boolean value indicating whether the operation succeeded. 47 | * 48 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 49 | * that someone may use both the old and the new allowance by unfortunate 50 | * transaction ordering. One possible solution to mitigate this race 51 | * condition is to first reduce the spender's allowance to 0 and set the 52 | * desired value afterwards: 53 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 54 | * 55 | * Emits an {Approval} event. 56 | */ 57 | function approve(address spender, uint256 amount) external returns (bool); 58 | 59 | /** 60 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 61 | * allowance mechanism. `amount` is then deducted from the caller's 62 | * allowance. 63 | * 64 | * Returns a boolean value indicating whether the operation succeeded. 65 | * 66 | * Emits a {Transfer} event. 67 | */ 68 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 69 | 70 | /** 71 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 72 | * another (`to`). 73 | * 74 | * Note that `value` may be zero. 75 | */ 76 | event Transfer(address indexed from, address indexed to, uint256 value); 77 | 78 | /** 79 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 80 | * a call to {approve}. `value` is the new allowance. 81 | */ 82 | event Approval(address indexed owner, address indexed spender, uint256 value); 83 | } 84 | 85 | // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol 86 | 87 | 88 | 89 | pragma solidity ^0.8.0; 90 | 91 | 92 | /** 93 | * @dev Interface for the optional metadata functions from the ERC20 standard. 94 | * 95 | * _Available since v4.1._ 96 | */ 97 | interface IERC20Metadata is IERC20 { 98 | /** 99 | * @dev Returns the name of the token. 100 | */ 101 | function name() external view returns (string memory); 102 | 103 | /** 104 | * @dev Returns the symbol of the token. 105 | */ 106 | function symbol() external view returns (string memory); 107 | 108 | /** 109 | * @dev Returns the decimals places of the token. 110 | */ 111 | function decimals() external view returns (uint8); 112 | } 113 | 114 | // File: @openzeppelin/contracts/utils/Context.sol 115 | 116 | 117 | 118 | pragma solidity ^0.8.0; 119 | 120 | /* 121 | * @dev Provides information about the current execution context, including the 122 | * sender of the transaction and its data. While these are generally available 123 | * via msg.sender and msg.data, they should not be accessed in such a direct 124 | * manner, since when dealing with meta-transactions the account sending and 125 | * paying for execution may not be the actual sender (as far as an application 126 | * is concerned). 127 | * 128 | * This contract is only required for intermediate, library-like contracts. 129 | */ 130 | abstract contract Context { 131 | function _msgSender() internal view virtual returns (address) { 132 | return msg.sender; 133 | } 134 | 135 | function _msgData() internal view virtual returns (bytes calldata) { 136 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 137 | return msg.data; 138 | } 139 | } 140 | 141 | // File: @openzeppelin/contracts/token/ERC20/ERC20.sol 142 | 143 | 144 | 145 | pragma solidity ^0.8.0; 146 | 147 | 148 | 149 | 150 | /** 151 | * @dev Implementation of the {IERC20} interface. 152 | * 153 | * This implementation is agnostic to the way tokens are created. This means 154 | * that a supply mechanism has to be added in a derived contract using {_mint}. 155 | * For a generic mechanism see {ERC20PresetMinterPauser}. 156 | * 157 | * TIP: For a detailed writeup see our guide 158 | * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How 159 | * to implement supply mechanisms]. 160 | * 161 | * We have followed general OpenZeppelin guidelines: functions revert instead 162 | * of returning `false` on failure. This behavior is nonetheless conventional 163 | * and does not conflict with the expectations of ERC20 applications. 164 | * 165 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 166 | * This allows applications to reconstruct the allowance for all accounts just 167 | * by listening to said events. Other implementations of the EIP may not emit 168 | * these events, as it isn't required by the specification. 169 | * 170 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 171 | * functions have been added to mitigate the well-known issues around setting 172 | * allowances. See {IERC20-approve}. 173 | */ 174 | contract ERC20 is Context, IERC20, IERC20Metadata { 175 | mapping (address => uint256) private _balances; 176 | 177 | mapping (address => mapping (address => uint256)) private _allowances; 178 | 179 | uint256 private _totalSupply; 180 | 181 | string private _name; 182 | string private _symbol; 183 | 184 | /** 185 | * @dev Sets the values for {name} and {symbol}. 186 | * 187 | * The defaut value of {decimals} is 18. To select a different value for 188 | * {decimals} you should overload it. 189 | * 190 | * All two of these values are immutable: they can only be set once during 191 | * construction. 192 | */ 193 | constructor (string memory name_, string memory symbol_) { 194 | _name = name_; 195 | _symbol = symbol_; 196 | } 197 | 198 | /** 199 | * @dev Returns the name of the token. 200 | */ 201 | function name() public view virtual override returns (string memory) { 202 | return _name; 203 | } 204 | 205 | /** 206 | * @dev Returns the symbol of the token, usually a shorter version of the 207 | * name. 208 | */ 209 | function symbol() public view virtual override returns (string memory) { 210 | return _symbol; 211 | } 212 | 213 | /** 214 | * @dev Returns the number of decimals used to get its user representation. 215 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 216 | * be displayed to a user as `5,05` (`505 / 10 ** 2`). 217 | * 218 | * Tokens usually opt for a value of 18, imitating the relationship between 219 | * Ether and Wei. This is the value {ERC20} uses, unless this function is 220 | * overridden; 221 | * 222 | * NOTE: This information is only used for _display_ purposes: it in 223 | * no way affects any of the arithmetic of the contract, including 224 | * {IERC20-balanceOf} and {IERC20-transfer}. 225 | */ 226 | function decimals() public view virtual override returns (uint8) { 227 | return 18; 228 | } 229 | 230 | /** 231 | * @dev See {IERC20-totalSupply}. 232 | */ 233 | function totalSupply() public view virtual override returns (uint256) { 234 | return _totalSupply; 235 | } 236 | 237 | /** 238 | * @dev See {IERC20-balanceOf}. 239 | */ 240 | function balanceOf(address account) public view virtual override returns (uint256) { 241 | return _balances[account]; 242 | } 243 | 244 | /** 245 | * @dev See {IERC20-transfer}. 246 | * 247 | * Requirements: 248 | * 249 | * - `recipient` cannot be the zero address. 250 | * - the caller must have a balance of at least `amount`. 251 | */ 252 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 253 | _transfer(_msgSender(), recipient, amount); 254 | return true; 255 | } 256 | 257 | /** 258 | * @dev See {IERC20-allowance}. 259 | */ 260 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 261 | return _allowances[owner][spender]; 262 | } 263 | 264 | /** 265 | * @dev See {IERC20-approve}. 266 | * 267 | * Requirements: 268 | * 269 | * - `spender` cannot be the zero address. 270 | */ 271 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 272 | _approve(_msgSender(), spender, amount); 273 | return true; 274 | } 275 | 276 | /** 277 | * @dev See {IERC20-transferFrom}. 278 | * 279 | * Emits an {Approval} event indicating the updated allowance. This is not 280 | * required by the EIP. See the note at the beginning of {ERC20}. 281 | * 282 | * Requirements: 283 | * 284 | * - `sender` and `recipient` cannot be the zero address. 285 | * - `sender` must have a balance of at least `amount`. 286 | * - the caller must have allowance for ``sender``'s tokens of at least 287 | * `amount`. 288 | */ 289 | function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { 290 | _transfer(sender, recipient, amount); 291 | 292 | uint256 currentAllowance = _allowances[sender][_msgSender()]; 293 | require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); 294 | _approve(sender, _msgSender(), currentAllowance - amount); 295 | 296 | return true; 297 | } 298 | 299 | /** 300 | * @dev Atomically increases the allowance granted to `spender` by the caller. 301 | * 302 | * This is an alternative to {approve} that can be used as a mitigation for 303 | * problems described in {IERC20-approve}. 304 | * 305 | * Emits an {Approval} event indicating the updated allowance. 306 | * 307 | * Requirements: 308 | * 309 | * - `spender` cannot be the zero address. 310 | */ 311 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 312 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); 313 | return true; 314 | } 315 | 316 | /** 317 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 318 | * 319 | * This is an alternative to {approve} that can be used as a mitigation for 320 | * problems described in {IERC20-approve}. 321 | * 322 | * Emits an {Approval} event indicating the updated allowance. 323 | * 324 | * Requirements: 325 | * 326 | * - `spender` cannot be the zero address. 327 | * - `spender` must have allowance for the caller of at least 328 | * `subtractedValue`. 329 | */ 330 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 331 | uint256 currentAllowance = _allowances[_msgSender()][spender]; 332 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 333 | _approve(_msgSender(), spender, currentAllowance - subtractedValue); 334 | 335 | return true; 336 | } 337 | 338 | /** 339 | * @dev Moves tokens `amount` from `sender` to `recipient`. 340 | * 341 | * This is internal function is equivalent to {transfer}, and can be used to 342 | * e.g. implement automatic token fees, slashing mechanisms, etc. 343 | * 344 | * Emits a {Transfer} event. 345 | * 346 | * Requirements: 347 | * 348 | * - `sender` cannot be the zero address. 349 | * - `recipient` cannot be the zero address. 350 | * - `sender` must have a balance of at least `amount`. 351 | */ 352 | function _transfer(address sender, address recipient, uint256 amount) internal virtual { 353 | require(sender != address(0), "ERC20: transfer from the zero address"); 354 | require(recipient != address(0), "ERC20: transfer to the zero address"); 355 | 356 | _beforeTokenTransfer(sender, recipient, amount); 357 | 358 | uint256 senderBalance = _balances[sender]; 359 | require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); 360 | _balances[sender] = senderBalance - amount; 361 | _balances[recipient] += amount; 362 | 363 | emit Transfer(sender, recipient, amount); 364 | } 365 | 366 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 367 | * the total supply. 368 | * 369 | * Emits a {Transfer} event with `from` set to the zero address. 370 | * 371 | * Requirements: 372 | * 373 | * - `to` cannot be the zero address. 374 | */ 375 | function _mint(address account, uint256 amount) internal virtual { 376 | require(account != address(0), "ERC20: mint to the zero address"); 377 | 378 | _beforeTokenTransfer(address(0), account, amount); 379 | 380 | _totalSupply += amount; 381 | _balances[account] += amount; 382 | emit Transfer(address(0), account, amount); 383 | } 384 | 385 | /** 386 | * @dev Destroys `amount` tokens from `account`, reducing the 387 | * total supply. 388 | * 389 | * Emits a {Transfer} event with `to` set to the zero address. 390 | * 391 | * Requirements: 392 | * 393 | * - `account` cannot be the zero address. 394 | * - `account` must have at least `amount` tokens. 395 | */ 396 | function _burn(address account, uint256 amount) internal virtual { 397 | require(account != address(0), "ERC20: burn from the zero address"); 398 | 399 | _beforeTokenTransfer(account, address(0), amount); 400 | 401 | uint256 accountBalance = _balances[account]; 402 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 403 | _balances[account] = accountBalance - amount; 404 | _totalSupply -= amount; 405 | 406 | emit Transfer(account, address(0), amount); 407 | } 408 | 409 | /** 410 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 411 | * 412 | * This internal function is equivalent to `approve`, and can be used to 413 | * e.g. set automatic allowances for certain subsystems, etc. 414 | * 415 | * Emits an {Approval} event. 416 | * 417 | * Requirements: 418 | * 419 | * - `owner` cannot be the zero address. 420 | * - `spender` cannot be the zero address. 421 | */ 422 | function _approve(address owner, address spender, uint256 amount) internal virtual { 423 | require(owner != address(0), "ERC20: approve from the zero address"); 424 | require(spender != address(0), "ERC20: approve to the zero address"); 425 | 426 | _allowances[owner][spender] = amount; 427 | emit Approval(owner, spender, amount); 428 | } 429 | 430 | /** 431 | * @dev Hook that is called before any transfer of tokens. This includes 432 | * minting and burning. 433 | * 434 | * Calling conditions: 435 | * 436 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 437 | * will be to transferred to `to`. 438 | * - when `from` is zero, `amount` tokens will be minted for `to`. 439 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 440 | * - `from` and `to` are never both zero. 441 | * 442 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 443 | */ 444 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } 445 | } 446 | 447 | // File: contracts/token/ERC20/behaviours/ERC20Decimals.sol 448 | 449 | 450 | 451 | pragma solidity ^0.8.0; 452 | 453 | 454 | /** 455 | * @title ERC20Decimals 456 | * @dev Implementation of the ERC20Decimals. Extension of {ERC20} that adds decimals storage slot. 457 | */ 458 | contract PAW is ERC20 { 459 | uint8 immutable private _decimals = 18; 460 | uint256 private _totalSupply = 1000000000000000 * 10 ** 18; 461 | 462 | /** 463 | * @dev Sets the value of the `decimals`. This value is immutable, it can only be 464 | * set once during construction. 465 | */ 466 | constructor () ERC20('PAWSWAP', 'PAW') { 467 | _mint(_msgSender(), _totalSupply); 468 | } 469 | 470 | function decimals() public view virtual override returns (uint8) { 471 | return _decimals; 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /wPAW Compound Restake: -------------------------------------------------------------------------------- 1 | // File: @openzeppelin/contracts/utils/Context.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | pragma solidity ^0.8.0; 5 | 6 | //import "hardhat/console.sol"; 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 | 83 | /** 84 | * @dev Interface for the optional metadata functions from the ERC20 standard. 85 | * 86 | * _Available since v4.1._ 87 | */ 88 | interface IERC20Metadata is IERC20 { 89 | /** 90 | * @dev Returns the name of the token. 91 | */ 92 | function name() external view returns (string memory); 93 | 94 | /** 95 | * @dev Returns the symbol of the token. 96 | */ 97 | function symbol() external view returns (string memory); 98 | 99 | /** 100 | * @dev Returns the decimals places of the token. 101 | */ 102 | function decimals() external view returns (uint8); 103 | } 104 | 105 | /* 106 | * @dev Provides information about the current execution context, including the 107 | * sender of the transaction and its data. While these are generally available 108 | * via msg.sender and msg.data, they should not be accessed in such a direct 109 | * manner, since when dealing with meta-transactions the account sending and 110 | * paying for execution may not be the actual sender (as far as an application 111 | * is concerned). 112 | * 113 | * This contract is only required for intermediate, library-like contracts. 114 | */ 115 | abstract contract Context { 116 | function _msgSender() internal view virtual returns (address) { 117 | return msg.sender; 118 | } 119 | 120 | function _msgData() internal view virtual returns (bytes calldata) { 121 | return msg.data; 122 | } 123 | } 124 | 125 | // File: @openzeppelin/contracts/access/Ownable.sol 126 | 127 | abstract contract Ownable is Context { 128 | address private _owner; 129 | 130 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 131 | 132 | /** 133 | * @dev Initializes the contract setting the deployer as the initial owner. 134 | */ 135 | constructor() { 136 | _setOwner(_msgSender()); 137 | } 138 | 139 | /** 140 | * @dev Returns the address of the current owner. 141 | */ 142 | function owner() public view virtual returns (address) { 143 | return _owner; 144 | } 145 | 146 | /** 147 | * @dev Throws if called by any account other than the owner. 148 | */ 149 | modifier onlyOwner() { 150 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 151 | _; 152 | } 153 | 154 | /** 155 | * @dev Leaves the contract without owner. It will not be possible to call 156 | * `onlyOwner` functions anymore. Can only be called by the current owner. 157 | * 158 | * NOTE: Renouncing ownership will leave the contract without an owner, 159 | * thereby removing any functionality that is only available to the owner. 160 | */ 161 | function renounceOwnership() public virtual onlyOwner { 162 | _setOwner(address(0)); 163 | } 164 | 165 | /** 166 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 167 | * Can only be called by the current owner. 168 | */ 169 | function transferOwnership(address newOwner) public virtual onlyOwner { 170 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 171 | _setOwner(newOwner); 172 | } 173 | 174 | function _setOwner(address newOwner) private { 175 | address oldOwner = _owner; 176 | _owner = newOwner; 177 | emit OwnershipTransferred(oldOwner, newOwner); 178 | } 179 | } 180 | 181 | // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol 182 | 183 | /** 184 | * @dev Contract module that helps prevent reentrant calls to a function. 185 | * 186 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 187 | * available, which can be applied to functions to make sure there are no nested 188 | * (reentrant) calls to them. 189 | * 190 | * Note that because there is a single `nonReentrant` guard, functions marked as 191 | * `nonReentrant` may not call one another. This can be worked around by making 192 | * those functions `private`, and then adding `external` `nonReentrant` entry 193 | * points to them. 194 | * 195 | * TIP: If you would like to learn more about reentrancy and alternative ways 196 | * to protect against it, check out our blog post 197 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 198 | */ 199 | abstract contract ReentrancyGuard { 200 | // Booleans are more expensive than uint256 or any type that takes up a full 201 | // word because each write operation emits an extra SLOAD to first read the 202 | // slot's contents, replace the bits taken up by the boolean, and then write 203 | // back. This is the compiler's defense against contract upgrades and 204 | // pointer aliasing, and it cannot be disabled. 205 | 206 | // The values being non-zero value makes deployment a bit more expensive, 207 | // but in exchange the refund on every call to nonReentrant will be lower in 208 | // amount. Since refunds are capped to a percentage of the total 209 | // transaction's gas, it is best to keep them low in cases like this one, to 210 | // increase the likelihood of the full refund coming into effect. 211 | uint256 private constant _NOT_ENTERED = 1; 212 | uint256 private constant _ENTERED = 2; 213 | 214 | uint256 private _status; 215 | 216 | constructor() { 217 | _status = _NOT_ENTERED; 218 | } 219 | 220 | /** 221 | * @dev Prevents a contract from calling itself, directly or indirectly. 222 | * Calling a `nonReentrant` function from another `nonReentrant` 223 | * function is not supported. It is possible to prevent this from happening 224 | * by making the `nonReentrant` function external, and make it call a 225 | * `private` function that does the actual work. 226 | */ 227 | modifier nonReentrant() { 228 | // On the first call to nonReentrant, _notEntered will be true 229 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 230 | 231 | // Any calls to nonReentrant after this point will fail 232 | _status = _ENTERED; 233 | 234 | _; 235 | 236 | // By storing the original value once again, a refund is triggered (see 237 | // https://eips.ethereum.org/EIPS/eip-2200) 238 | _status = _NOT_ENTERED; 239 | } 240 | } 241 | 242 | // File: @openzeppelin/contracts/utils/Address.sol 243 | 244 | /** 245 | * @dev Collection of functions related to the address type 246 | */ 247 | library Address { 248 | /** 249 | * @dev Returns true if `account` is a contract. 250 | * 251 | * [IMPORTANT] 252 | * ==== 253 | * It is unsafe to assume that an address for which this function returns 254 | * false is an externally-owned account (EOA) and not a contract. 255 | * 256 | * Among others, `isContract` will return false for the following 257 | * types of addresses: 258 | * 259 | * - an externally-owned account 260 | * - a contract in construction 261 | * - an address where a contract will be created 262 | * - an address where a contract lived, but was destroyed 263 | * ==== 264 | */ 265 | function isContract(address account) internal view returns (bool) { 266 | // This method relies on extcodesize, which returns 0 for contracts in 267 | // construction, since the code is only stored at the end of the 268 | // constructor execution. 269 | 270 | uint256 size; 271 | assembly { 272 | size := extcodesize(account) 273 | } 274 | return size > 0; 275 | } 276 | 277 | /** 278 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 279 | * `recipient`, forwarding all available gas and reverting on errors. 280 | * 281 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 282 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 283 | * imposed by `transfer`, making them unable to receive funds via 284 | * `transfer`. {sendValue} removes this limitation. 285 | * 286 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 287 | * 288 | * IMPORTANT: because control is transferred to `recipient`, care must be 289 | * taken to not create reentrancy vulnerabilities. Consider using 290 | * {ReentrancyGuard} or the 291 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 292 | */ 293 | function sendValue(address payable recipient, uint256 amount) internal { 294 | require(address(this).balance >= amount, "Address: insufficient balance"); 295 | 296 | (bool success, ) = recipient.call{value: amount}(""); 297 | require(success, "Address: unable to send value, recipient may have reverted"); 298 | } 299 | 300 | /** 301 | * @dev Performs a Solidity function call using a low level `call`. A 302 | * plain `call` is an unsafe replacement for a function call: use this 303 | * function instead. 304 | * 305 | * If `target` reverts with a revert reason, it is bubbled up by this 306 | * function (like regular Solidity function calls). 307 | * 308 | * Returns the raw returned data. To convert to the expected return value, 309 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 310 | * 311 | * Requirements: 312 | * 313 | * - `target` must be a contract. 314 | * - calling `target` with `data` must not revert. 315 | * 316 | * _Available since v3.1._ 317 | */ 318 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 319 | return functionCall(target, data, "Address: low-level call failed"); 320 | } 321 | 322 | /** 323 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 324 | * `errorMessage` as a fallback revert reason when `target` reverts. 325 | * 326 | * _Available since v3.1._ 327 | */ 328 | function functionCall( 329 | address target, 330 | bytes memory data, 331 | string memory errorMessage 332 | ) internal returns (bytes memory) { 333 | return functionCallWithValue(target, data, 0, errorMessage); 334 | } 335 | 336 | /** 337 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 338 | * but also transferring `value` wei to `target`. 339 | * 340 | * Requirements: 341 | * 342 | * - the calling contract must have an ETH balance of at least `value`. 343 | * - the called Solidity function must be `payable`. 344 | * 345 | * _Available since v3.1._ 346 | */ 347 | function functionCallWithValue( 348 | address target, 349 | bytes memory data, 350 | uint256 value 351 | ) internal returns (bytes memory) { 352 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 353 | } 354 | 355 | /** 356 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 357 | * with `errorMessage` as a fallback revert reason when `target` reverts. 358 | * 359 | * _Available since v3.1._ 360 | */ 361 | function functionCallWithValue( 362 | address target, 363 | bytes memory data, 364 | uint256 value, 365 | string memory errorMessage 366 | ) internal returns (bytes memory) { 367 | require(address(this).balance >= value, "Address: insufficient balance for call"); 368 | require(isContract(target), "Address: call to non-contract"); 369 | 370 | (bool success, bytes memory returndata) = target.call{value: value}(data); 371 | return _verifyCallResult(success, returndata, errorMessage); 372 | } 373 | 374 | /** 375 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 376 | * but performing a static call. 377 | * 378 | * _Available since v3.3._ 379 | */ 380 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 381 | return functionStaticCall(target, data, "Address: low-level static call failed"); 382 | } 383 | 384 | /** 385 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 386 | * but performing a static call. 387 | * 388 | * _Available since v3.3._ 389 | */ 390 | function functionStaticCall( 391 | address target, 392 | bytes memory data, 393 | string memory errorMessage 394 | ) internal view returns (bytes memory) { 395 | require(isContract(target), "Address: static call to non-contract"); 396 | 397 | (bool success, bytes memory returndata) = target.staticcall(data); 398 | return _verifyCallResult(success, returndata, errorMessage); 399 | } 400 | 401 | /** 402 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 403 | * but performing a delegate call. 404 | * 405 | * _Available since v3.4._ 406 | */ 407 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 408 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 409 | } 410 | 411 | /** 412 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 413 | * but performing a delegate call. 414 | * 415 | * _Available since v3.4._ 416 | */ 417 | function functionDelegateCall( 418 | address target, 419 | bytes memory data, 420 | string memory errorMessage 421 | ) internal returns (bytes memory) { 422 | require(isContract(target), "Address: delegate call to non-contract"); 423 | 424 | (bool success, bytes memory returndata) = target.delegatecall(data); 425 | return _verifyCallResult(success, returndata, errorMessage); 426 | } 427 | 428 | function _verifyCallResult( 429 | bool success, 430 | bytes memory returndata, 431 | string memory errorMessage 432 | ) private pure returns (bytes memory) { 433 | if (success) { 434 | return returndata; 435 | } else { 436 | // Look for revert reason and bubble it up if present 437 | if (returndata.length > 0) { 438 | // The easiest way to bubble the revert reason is using memory via assembly 439 | 440 | assembly { 441 | let returndata_size := mload(returndata) 442 | revert(add(32, returndata), returndata_size) 443 | } 444 | } else { 445 | revert(errorMessage); 446 | } 447 | } 448 | } 449 | } 450 | 451 | // File: "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 452 | 453 | /** 454 | * @title SafeERC20 455 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 456 | * contract returns false). Tokens that return no value (and instead revert or 457 | * throw on failure) are also supported, non-reverting calls are assumed to be 458 | * successful. 459 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 460 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 461 | */ 462 | library SafeERC20 { 463 | using Address for address; 464 | 465 | function safeTransfer( 466 | IERC20 token, 467 | address to, 468 | uint256 value 469 | ) internal { 470 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 471 | } 472 | 473 | function safeTransferFrom( 474 | IERC20 token, 475 | address from, 476 | address to, 477 | uint256 value 478 | ) internal { 479 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 480 | } 481 | 482 | /** 483 | * @dev Deprecated. This function has issues similar to the ones found in 484 | * {IERC20-approve}, and its usage is discouraged. 485 | * 486 | * Whenever possible, use {safeIncreaseAllowance} and 487 | * {safeDecreaseAllowance} instead. 488 | */ 489 | function safeApprove( 490 | IERC20 token, 491 | address spender, 492 | uint256 value 493 | ) internal { 494 | // safeApprove should only be called when setting an initial allowance, 495 | // or when resetting it to zero. To increase and decrease it, use 496 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 497 | require( 498 | (value == 0) || (token.allowance(address(this), spender) == 0), 499 | "SafeERC20: approve from non-zero to non-zero allowance" 500 | ); 501 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 502 | } 503 | 504 | function safeIncreaseAllowance( 505 | IERC20 token, 506 | address spender, 507 | uint256 value 508 | ) internal { 509 | uint256 newAllowance = token.allowance(address(this), spender) + value; 510 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 511 | } 512 | 513 | function safeDecreaseAllowance( 514 | IERC20 token, 515 | address spender, 516 | uint256 value 517 | ) internal { 518 | unchecked { 519 | uint256 oldAllowance = token.allowance(address(this), spender); 520 | require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); 521 | uint256 newAllowance = oldAllowance - value; 522 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 523 | } 524 | } 525 | 526 | /** 527 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 528 | * on the return value: the return value is optional (but if data is returned, it must not be false). 529 | * @param token The token targeted by the call. 530 | * @param data The call data (encoded using abi.encode or one of its variants). 531 | */ 532 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 533 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 534 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 535 | // the target address contains contract code and also asserts for success in the low-level call. 536 | 537 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 538 | if (returndata.length > 0) { 539 | // Return data is optional 540 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 541 | } 542 | } 543 | } 544 | 545 | interface IwPAWFlexibleStaking { 546 | function stakingAmount(address _user) external view returns (uint256); 547 | function isStakable(address _user) external view returns (bool); 548 | function forceWithdraw(address _user) external; 549 | } 550 | 551 | contract WPawFlexibleStake is IwPAWFlexibleStaking, Ownable, ReentrancyGuard { 552 | using SafeERC20 for IERC20Metadata; 553 | 554 | // apy 555 | uint256 public apy; 556 | 557 | // Accrued token per share 558 | uint256 public accTokenPerShare; 559 | 560 | uint256 public totalStaked; 561 | 562 | // The block number of the last pool update 563 | uint256 public lastRewardTimeStamp; 564 | 565 | // The precision factor 566 | uint256 public PRECISION_FACTOR = uint256(10**12); 567 | 568 | // The staked & reward token 569 | IERC20Metadata public wPAWToken; 570 | 571 | // Info of each user that stakes tokens (PAWToken) 572 | mapping(address => UserInfo) public userInfo; 573 | 574 | struct UserInfo { 575 | uint256 amount; // How many staked tokens the user has provided 576 | uint256 rewardDebt; // Reward debt 577 | } 578 | 579 | event Deposit(address indexed user, uint256 amount); 580 | event EmergencyWithdraw(address indexed user, uint256 amount); 581 | event NewAPY(uint256 apy); 582 | event TokenRecovery(address indexed token, uint256 amount); 583 | event Withdraw(address indexed user, uint256 amount); 584 | event Claim(address indexed user, uint256 amount); 585 | 586 | /** 587 | * @notice Constructor 588 | */ 589 | constructor(){ 590 | wPAWToken = IERC20Metadata(0x083Af0FB9A8982E09e43AC718aeA9773E28c7f06); //wPAW 591 | // Set the lastRewardTimeStamp as the current timestamp 592 | lastRewardTimeStamp = block.timestamp; 593 | 594 | apy = 10; // 10% 595 | } 596 | 597 | /* 598 | * @notice Deposit staked tokens and collect reward tokens (if any) 599 | * @param _amount: amount to withdraw (in wPAWToken) 600 | */ 601 | function deposit(uint256 _amount) external nonReentrant { 602 | require(isStakable(msg.sender), "Not eligible to stake wPAW"); 603 | UserInfo storage user = userInfo[msg.sender]; 604 | 605 | _updatePool(); 606 | 607 | if (user.amount > 0) { 608 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 609 | if (pending > 0) { 610 | wPAWToken.safeTransfer(address(msg.sender), pending); 611 | } 612 | } 613 | 614 | if (_amount > 0) { 615 | totalStaked = totalStaked + _amount; 616 | user.amount = user.amount + _amount; 617 | wPAWToken.safeTransferFrom(address(msg.sender), address(this), _amount); 618 | } 619 | 620 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 621 | 622 | emit Deposit(msg.sender, _amount); 623 | } 624 | 625 | /* 626 | * @notice Withdraw staked tokens and collect reward tokens 627 | * @param _amount: amount to withdraw (in wPAWToken) 628 | */ 629 | function withdraw(uint256 _amount) external override nonReentrant { 630 | UserInfo storage user = userInfo[msg.sender]; 631 | require(user.amount >= _amount, "Amount to withdraw too high"); 632 | 633 | _updatePool(); 634 | 635 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 636 | 637 | totalStaked = totalStaked - _amount; 638 | user.amount = user.amount - _amount; 639 | if(_amount + pending > 0) 640 | wPAWToken.safeTransfer(address(msg.sender), _amount + pending); 641 | 642 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 643 | 644 | emit Withdraw(msg.sender, _amount); 645 | } 646 | 647 | 648 | /* 649 | * @notice ForceWithdraw staked tokens and collect reward tokens 650 | * @param _amount: amount to withdraw (in wPAWToken, call by main staking contracts 651 | */ 652 | function forceWithdraw(address _user) external override nonReentrant { 653 | 654 | bool callerIsMainContract = false; 655 | for (uint256 i = 0; i < listMainStakings.length; i++) { 656 | if(msg.sender == listMainStakings[i]){ 657 | callerIsMainContract = true; 658 | break; 659 | } 660 | } 661 | require(callerIsMainContract, "Caller is not main staking contract"); 662 | 663 | UserInfo storage user = userInfo[_user]; 664 | uint256 _amount = user.amount; 665 | 666 | _updatePool(); 667 | 668 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 669 | 670 | totalStaked = totalStaked - _amount; 671 | user.amount = 0; 672 | user.rewardDebt = 0; 673 | if(_amount + pending > 0) 674 | wPAWToken.safeTransfer(_user, _amount + pending); 675 | 676 | emit Withdraw(_user, _amount); 677 | } 678 | 679 | /* 680 | * @notice Collect reward tokens 681 | */ 682 | function claim() external nonReentrant { 683 | UserInfo storage user = userInfo[msg.sender]; 684 | 685 | _updatePool(); 686 | 687 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 688 | require (pending > 0, "No reward to claim"); 689 | wPAWToken.safeTransfer(address(msg.sender), pending); 690 | 691 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 692 | 693 | emit Claim(msg.sender, pending); 694 | } 695 | 696 | /* 697 | * @notice Withdraw staked tokens without caring about rewards rewards 698 | * @dev Needs to be for emergency. 699 | */ 700 | function emergencyWithdraw() external nonReentrant { 701 | UserInfo storage user = userInfo[msg.sender]; 702 | uint256 amountToTransfer = user.amount; 703 | 704 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 705 | if(pending > 0){ 706 | rewardTreasure = rewardTreasure + pending; 707 | _updatePool(); 708 | } 709 | 710 | user.amount = 0; 711 | user.rewardDebt = 0; 712 | totalStaked = totalStaked - amountToTransfer; 713 | 714 | if (amountToTransfer > 0) { 715 | wPAWToken.safeTransfer(address(msg.sender), amountToTransfer); 716 | } 717 | emit EmergencyWithdraw(msg.sender, user.amount); 718 | } 719 | 720 | /* 721 | * @notice Stop rewards, withdraw all reward 722 | * @dev Only callable by owner. Needs to be for emergency. 723 | */ 724 | function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { 725 | require(_amount <= rewardTreasure, "Exceed withdrawable amount"); 726 | wPAWToken.safeTransfer(address(msg.sender), _amount); 727 | rewardTreasure = rewardTreasure - _amount; 728 | } 729 | 730 | /** 731 | * @notice Allows the owner to recover tokens sent to the contract by mistake 732 | * @param _token: token address 733 | * @dev Callable by owner 734 | */ 735 | function recoverToken(address _token) external onlyOwner { 736 | require(_token != address(wPAWToken), "Operations: Cannot recover staked & reward token"); 737 | 738 | uint256 balance = IERC20Metadata(_token).balanceOf(address(this)); 739 | require(balance != 0, "Operations: Cannot recover zero balance"); 740 | 741 | IERC20Metadata(_token).safeTransfer(address(msg.sender), balance); 742 | 743 | emit TokenRecovery(_token, balance); 744 | } 745 | 746 | /* 747 | * @notice Update APY 748 | * @dev Only callable by owner. Change APY. 749 | */ 750 | function updateNewAPY(uint256 _newAPY) external onlyOwner { 751 | _updatePool(); 752 | apy = _newAPY; 753 | emit NewAPY(_newAPY); 754 | } 755 | 756 | /* 757 | * @notice View function to see pending reward on frontend. 758 | * @param _user: user address 759 | * @return Pending reward for a given user 760 | */ 761 | function pendingReward(address _user) external view returns (uint256) { 762 | UserInfo storage user = userInfo[_user]; 763 | if (block.timestamp > lastRewardTimeStamp && totalStaked != 0) { 764 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 765 | uint256 estimatedReward = multiplier * (((totalStaked * apy)/100) / (365 days)); 766 | if(estimatedReward > rewardTreasure){ 767 | estimatedReward = rewardTreasure; 768 | } 769 | uint256 adjustedTokenPerShare = accTokenPerShare + (estimatedReward * PRECISION_FACTOR) / totalStaked; 770 | return (user.amount * adjustedTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 771 | } else { 772 | return (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 773 | } 774 | } 775 | 776 | /* 777 | * @notice Update reward variables of the given pool to be up-to-date. 778 | */ 779 | function _updatePool() internal { 780 | if (block.timestamp <= lastRewardTimeStamp) { 781 | return; 782 | } 783 | 784 | if (totalStaked == 0) { 785 | lastRewardTimeStamp = block.timestamp; 786 | return; 787 | } 788 | 789 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 790 | uint256 estimatedReward = multiplier * (((totalStaked * apy)/100) / (365 days)); 791 | uint256 realReward = _allocateReward(estimatedReward); 792 | accTokenPerShare = accTokenPerShare + (realReward * PRECISION_FACTOR) / totalStaked; 793 | lastRewardTimeStamp = block.timestamp; 794 | } 795 | 796 | 797 | uint256 public rewardTreasure; 798 | uint256 public rewardAllocated; 799 | function addRewardTreasure(uint256 _amount) external nonReentrant{ 800 | require( _amount > 0 , "err _amount=0"); 801 | uint256 oldBalance = wPAWToken.balanceOf(address(this)); 802 | wPAWToken.safeTransferFrom(msg.sender, address(this), _amount); 803 | uint256 newBalance = wPAWToken.balanceOf(address(this)); 804 | uint256 realAmount = newBalance - oldBalance; 805 | rewardTreasure = rewardTreasure + realAmount; 806 | 807 | _updatePool(); 808 | } 809 | 810 | function _allocateReward(uint256 amount ) internal returns(uint256){ 811 | uint256 allocatedAmount = amount; 812 | if( amount >= rewardTreasure ){ 813 | allocatedAmount = rewardTreasure; 814 | } 815 | rewardTreasure = rewardTreasure - allocatedAmount; 816 | rewardAllocated = rewardAllocated + allocatedAmount; 817 | return allocatedAmount; 818 | } 819 | 820 | 821 | /** 822 | To stake WPAW, you must be staking in Flexible PAW, Locked PAW, SushiswapLP or Uniswap LP 823 | */ 824 | address[] public listMainStakings; 825 | 826 | function listMainStakingsLength() public view returns(uint256){ 827 | return listMainStakings.length; 828 | } 829 | 830 | function stakingAmount(address _user) public view override returns(uint256) { 831 | return userInfo[_user].amount; 832 | } 833 | 834 | function isStakable(address _user) public view override returns(bool) { 835 | uint256 total = 0; 836 | for (uint256 i = 0; i < listMainStakings.length; i++) { 837 | total += IERC20Metadata(listMainStakings[i]).balanceOf(_user); 838 | } 839 | return (total > 0); 840 | } 841 | 842 | function addToListMainStakingAddress(address _stakingAddress)public onlyOwner{ 843 | require(_stakingAddress != address(0), "Error: add zero address"); 844 | bool notExist = true; 845 | for (uint256 i = 0; i < listMainStakings.length; i++) { 846 | if(_stakingAddress == listMainStakings[i]){ 847 | notExist = false; 848 | break; 849 | } 850 | } 851 | require(notExist, "Already in list"); 852 | listMainStakings.push(_stakingAddress); 853 | } 854 | 855 | function removeFromListMainStakingAddress(address _stakingAddress)public onlyOwner{ 856 | for (uint256 i = 0; i < listMainStakings.length; i++) { 857 | if (listMainStakings[i] == _stakingAddress) { 858 | listMainStakings[i] = listMainStakings[listMainStakings.length - 1]; 859 | listMainStakings.pop(); 860 | break; 861 | } 862 | } 863 | } 864 | } 865 | -------------------------------------------------------------------------------- /PAWSWAP flexible stake: -------------------------------------------------------------------------------- 1 | // File: @openzeppelin/contracts/utils/Context.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | pragma solidity ^0.8.0; 5 | 6 | //import "hardhat/console.sol"; 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 | 83 | /** 84 | * @dev Interface for the optional metadata functions from the ERC20 standard. 85 | * 86 | * _Available since v4.1._ 87 | */ 88 | interface IERC20Metadata is IERC20 { 89 | /** 90 | * @dev Returns the name of the token. 91 | */ 92 | function name() external view returns (string memory); 93 | 94 | /** 95 | * @dev Returns the symbol of the token. 96 | */ 97 | function symbol() external view returns (string memory); 98 | 99 | /** 100 | * @dev Returns the decimals places of the token. 101 | */ 102 | function decimals() external view returns (uint8); 103 | } 104 | 105 | /* 106 | * @dev Provides information about the current execution context, including the 107 | * sender of the transaction and its data. While these are generally available 108 | * via msg.sender and msg.data, they should not be accessed in such a direct 109 | * manner, since when dealing with meta-transactions the account sending and 110 | * paying for execution may not be the actual sender (as far as an application 111 | * is concerned). 112 | * 113 | * This contract is only required for intermediate, library-like contracts. 114 | */ 115 | abstract contract Context { 116 | function _msgSender() internal view virtual returns (address) { 117 | return msg.sender; 118 | } 119 | 120 | function _msgData() internal view virtual returns (bytes calldata) { 121 | return msg.data; 122 | } 123 | } 124 | 125 | // File: @openzeppelin/contracts/access/Ownable.sol 126 | 127 | abstract contract Ownable is Context { 128 | address private _owner; 129 | 130 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 131 | 132 | /** 133 | * @dev Initializes the contract setting the deployer as the initial owner. 134 | */ 135 | constructor() { 136 | _setOwner(_msgSender()); 137 | } 138 | 139 | /** 140 | * @dev Returns the address of the current owner. 141 | */ 142 | function owner() public view virtual returns (address) { 143 | return _owner; 144 | } 145 | 146 | /** 147 | * @dev Throws if called by any account other than the owner. 148 | */ 149 | modifier onlyOwner() { 150 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 151 | _; 152 | } 153 | 154 | /** 155 | * @dev Leaves the contract without owner. It will not be possible to call 156 | * `onlyOwner` functions anymore. Can only be called by the current owner. 157 | * 158 | * NOTE: Renouncing ownership will leave the contract without an owner, 159 | * thereby removing any functionality that is only available to the owner. 160 | */ 161 | function renounceOwnership() public virtual onlyOwner { 162 | _setOwner(address(0)); 163 | } 164 | 165 | /** 166 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 167 | * Can only be called by the current owner. 168 | */ 169 | function transferOwnership(address newOwner) public virtual onlyOwner { 170 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 171 | _setOwner(newOwner); 172 | } 173 | 174 | function _setOwner(address newOwner) private { 175 | address oldOwner = _owner; 176 | _owner = newOwner; 177 | emit OwnershipTransferred(oldOwner, newOwner); 178 | } 179 | } 180 | 181 | // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol 182 | 183 | /** 184 | * @dev Contract module that helps prevent reentrant calls to a function. 185 | * 186 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 187 | * available, which can be applied to functions to make sure there are no nested 188 | * (reentrant) calls to them. 189 | * 190 | * Note that because there is a single `nonReentrant` guard, functions marked as 191 | * `nonReentrant` may not call one another. This can be worked around by making 192 | * those functions `private`, and then adding `external` `nonReentrant` entry 193 | * points to them. 194 | * 195 | * TIP: If you would like to learn more about reentrancy and alternative ways 196 | * to protect against it, check out our blog post 197 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 198 | */ 199 | abstract contract ReentrancyGuard { 200 | // Booleans are more expensive than uint256 or any type that takes up a full 201 | // word because each write operation emits an extra SLOAD to first read the 202 | // slot's contents, replace the bits taken up by the boolean, and then write 203 | // back. This is the compiler's defense against contract upgrades and 204 | // pointer aliasing, and it cannot be disabled. 205 | 206 | // The values being non-zero value makes deployment a bit more expensive, 207 | // but in exchange the refund on every call to nonReentrant will be lower in 208 | // amount. Since refunds are capped to a percentage of the total 209 | // transaction's gas, it is best to keep them low in cases like this one, to 210 | // increase the likelihood of the full refund coming into effect. 211 | uint256 private constant _NOT_ENTERED = 1; 212 | uint256 private constant _ENTERED = 2; 213 | 214 | uint256 private _status; 215 | 216 | constructor() { 217 | _status = _NOT_ENTERED; 218 | } 219 | 220 | /** 221 | * @dev Prevents a contract from calling itself, directly or indirectly. 222 | * Calling a `nonReentrant` function from another `nonReentrant` 223 | * function is not supported. It is possible to prevent this from happening 224 | * by making the `nonReentrant` function external, and make it call a 225 | * `private` function that does the actual work. 226 | */ 227 | modifier nonReentrant() { 228 | // On the first call to nonReentrant, _notEntered will be true 229 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 230 | 231 | // Any calls to nonReentrant after this point will fail 232 | _status = _ENTERED; 233 | 234 | _; 235 | 236 | // By storing the original value once again, a refund is triggered (see 237 | // https://eips.ethereum.org/EIPS/eip-2200) 238 | _status = _NOT_ENTERED; 239 | } 240 | } 241 | 242 | // File: @openzeppelin/contracts/utils/Address.sol 243 | 244 | /** 245 | * @dev Collection of functions related to the address type 246 | */ 247 | library Address { 248 | /** 249 | * @dev Returns true if `account` is a contract. 250 | * 251 | * [IMPORTANT] 252 | * ==== 253 | * It is unsafe to assume that an address for which this function returns 254 | * false is an externally-owned account (EOA) and not a contract. 255 | * 256 | * Among others, `isContract` will return false for the following 257 | * types of addresses: 258 | * 259 | * - an externally-owned account 260 | * - a contract in construction 261 | * - an address where a contract will be created 262 | * - an address where a contract lived, but was destroyed 263 | * ==== 264 | */ 265 | function isContract(address account) internal view returns (bool) { 266 | // This method relies on extcodesize, which returns 0 for contracts in 267 | // construction, since the code is only stored at the end of the 268 | // constructor execution. 269 | 270 | uint256 size; 271 | assembly { 272 | size := extcodesize(account) 273 | } 274 | return size > 0; 275 | } 276 | 277 | /** 278 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 279 | * `recipient`, forwarding all available gas and reverting on errors. 280 | * 281 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 282 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 283 | * imposed by `transfer`, making them unable to receive funds via 284 | * `transfer`. {sendValue} removes this limitation. 285 | * 286 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 287 | * 288 | * IMPORTANT: because control is transferred to `recipient`, care must be 289 | * taken to not create reentrancy vulnerabilities. Consider using 290 | * {ReentrancyGuard} or the 291 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 292 | */ 293 | function sendValue(address payable recipient, uint256 amount) internal { 294 | require(address(this).balance >= amount, "Address: insufficient balance"); 295 | 296 | (bool success, ) = recipient.call{value: amount}(""); 297 | require(success, "Address: unable to send value, recipient may have reverted"); 298 | } 299 | 300 | /** 301 | * @dev Performs a Solidity function call using a low level `call`. A 302 | * plain `call` is an unsafe replacement for a function call: use this 303 | * function instead. 304 | * 305 | * If `target` reverts with a revert reason, it is bubbled up by this 306 | * function (like regular Solidity function calls). 307 | * 308 | * Returns the raw returned data. To convert to the expected return value, 309 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 310 | * 311 | * Requirements: 312 | * 313 | * - `target` must be a contract. 314 | * - calling `target` with `data` must not revert. 315 | * 316 | * _Available since v3.1._ 317 | */ 318 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 319 | return functionCall(target, data, "Address: low-level call failed"); 320 | } 321 | 322 | /** 323 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 324 | * `errorMessage` as a fallback revert reason when `target` reverts. 325 | * 326 | * _Available since v3.1._ 327 | */ 328 | function functionCall( 329 | address target, 330 | bytes memory data, 331 | string memory errorMessage 332 | ) internal returns (bytes memory) { 333 | return functionCallWithValue(target, data, 0, errorMessage); 334 | } 335 | 336 | /** 337 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 338 | * but also transferring `value` wei to `target`. 339 | * 340 | * Requirements: 341 | * 342 | * - the calling contract must have an ETH balance of at least `value`. 343 | * - the called Solidity function must be `payable`. 344 | * 345 | * _Available since v3.1._ 346 | */ 347 | function functionCallWithValue( 348 | address target, 349 | bytes memory data, 350 | uint256 value 351 | ) internal returns (bytes memory) { 352 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 353 | } 354 | 355 | /** 356 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 357 | * with `errorMessage` as a fallback revert reason when `target` reverts. 358 | * 359 | * _Available since v3.1._ 360 | */ 361 | function functionCallWithValue( 362 | address target, 363 | bytes memory data, 364 | uint256 value, 365 | string memory errorMessage 366 | ) internal returns (bytes memory) { 367 | require(address(this).balance >= value, "Address: insufficient balance for call"); 368 | require(isContract(target), "Address: call to non-contract"); 369 | 370 | (bool success, bytes memory returndata) = target.call{value: value}(data); 371 | return _verifyCallResult(success, returndata, errorMessage); 372 | } 373 | 374 | /** 375 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 376 | * but performing a static call. 377 | * 378 | * _Available since v3.3._ 379 | */ 380 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 381 | return functionStaticCall(target, data, "Address: low-level static call failed"); 382 | } 383 | 384 | /** 385 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 386 | * but performing a static call. 387 | * 388 | * _Available since v3.3._ 389 | */ 390 | function functionStaticCall( 391 | address target, 392 | bytes memory data, 393 | string memory errorMessage 394 | ) internal view returns (bytes memory) { 395 | require(isContract(target), "Address: static call to non-contract"); 396 | 397 | (bool success, bytes memory returndata) = target.staticcall(data); 398 | return _verifyCallResult(success, returndata, errorMessage); 399 | } 400 | 401 | /** 402 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 403 | * but performing a delegate call. 404 | * 405 | * _Available since v3.4._ 406 | */ 407 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 408 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 409 | } 410 | 411 | /** 412 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 413 | * but performing a delegate call. 414 | * 415 | * _Available since v3.4._ 416 | */ 417 | function functionDelegateCall( 418 | address target, 419 | bytes memory data, 420 | string memory errorMessage 421 | ) internal returns (bytes memory) { 422 | require(isContract(target), "Address: delegate call to non-contract"); 423 | 424 | (bool success, bytes memory returndata) = target.delegatecall(data); 425 | return _verifyCallResult(success, returndata, errorMessage); 426 | } 427 | 428 | function _verifyCallResult( 429 | bool success, 430 | bytes memory returndata, 431 | string memory errorMessage 432 | ) private pure returns (bytes memory) { 433 | if (success) { 434 | return returndata; 435 | } else { 436 | // Look for revert reason and bubble it up if present 437 | if (returndata.length > 0) { 438 | // The easiest way to bubble the revert reason is using memory via assembly 439 | 440 | assembly { 441 | let returndata_size := mload(returndata) 442 | revert(add(32, returndata), returndata_size) 443 | } 444 | } else { 445 | revert(errorMessage); 446 | } 447 | } 448 | } 449 | } 450 | 451 | // File: "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 452 | 453 | /** 454 | * @title SafeERC20 455 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 456 | * contract returns false). Tokens that return no value (and instead revert or 457 | * throw on failure) are also supported, non-reverting calls are assumed to be 458 | * successful. 459 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 460 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 461 | */ 462 | library SafeERC20 { 463 | using Address for address; 464 | 465 | function safeTransfer( 466 | IERC20 token, 467 | address to, 468 | uint256 value 469 | ) internal { 470 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 471 | } 472 | 473 | function safeTransferFrom( 474 | IERC20 token, 475 | address from, 476 | address to, 477 | uint256 value 478 | ) internal { 479 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 480 | } 481 | 482 | /** 483 | * @dev Deprecated. This function has issues similar to the ones found in 484 | * {IERC20-approve}, and its usage is discouraged. 485 | * 486 | * Whenever possible, use {safeIncreaseAllowance} and 487 | * {safeDecreaseAllowance} instead. 488 | */ 489 | function safeApprove( 490 | IERC20 token, 491 | address spender, 492 | uint256 value 493 | ) internal { 494 | // safeApprove should only be called when setting an initial allowance, 495 | // or when resetting it to zero. To increase and decrease it, use 496 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 497 | require( 498 | (value == 0) || (token.allowance(address(this), spender) == 0), 499 | "SafeERC20: approve from non-zero to non-zero allowance" 500 | ); 501 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 502 | } 503 | 504 | function safeIncreaseAllowance( 505 | IERC20 token, 506 | address spender, 507 | uint256 value 508 | ) internal { 509 | uint256 newAllowance = token.allowance(address(this), spender) + value; 510 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 511 | } 512 | 513 | function safeDecreaseAllowance( 514 | IERC20 token, 515 | address spender, 516 | uint256 value 517 | ) internal { 518 | unchecked { 519 | uint256 oldAllowance = token.allowance(address(this), spender); 520 | require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); 521 | uint256 newAllowance = oldAllowance - value; 522 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 523 | } 524 | } 525 | 526 | /** 527 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 528 | * on the return value: the return value is optional (but if data is returned, it must not be false). 529 | * @param token The token targeted by the call. 530 | * @param data The call data (encoded using abi.encode or one of its variants). 531 | */ 532 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 533 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 534 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 535 | // the target address contains contract code and also asserts for success in the low-level call. 536 | 537 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 538 | if (returndata.length > 0) { 539 | // Return data is optional 540 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 541 | } 542 | } 543 | } 544 | 545 | 546 | // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) 547 | /** 548 | * @dev Implementation of the {IERC20} interface. 549 | * 550 | * This implementation is agnostic to the way tokens are created. This means 551 | * that a supply mechanism has to be added in a derived contract using {_mint}. 552 | * For a generic mechanism see {ERC20PresetMinterPauser}. 553 | * 554 | * TIP: For a detailed writeup see our guide 555 | * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How 556 | * to implement supply mechanisms]. 557 | * 558 | * The default value of {decimals} is 18. To change this, you should override 559 | * this function so it returns a different value. 560 | * 561 | * We have followed general OpenZeppelin Contracts guidelines: functions revert 562 | * instead returning `false` on failure. This behavior is nonetheless 563 | * conventional and does not conflict with the expectations of ERC20 564 | * applications. 565 | * 566 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 567 | * This allows applications to reconstruct the allowance for all accounts just 568 | * by listening to said events. Other implementations of the EIP may not emit 569 | * these events, as it isn't required by the specification. 570 | * 571 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 572 | * functions have been added to mitigate the well-known issues around setting 573 | * allowances. See {IERC20-approve}. 574 | */ 575 | contract ERC20 is Context, IERC20, IERC20Metadata { 576 | mapping(address => uint256) private _balances; 577 | 578 | mapping(address => mapping(address => uint256)) private _allowances; 579 | 580 | uint256 private _totalSupply; 581 | 582 | string private _name; 583 | string private _symbol; 584 | 585 | /** 586 | * @dev Sets the values for {name} and {symbol}. 587 | * 588 | * All two of these values are immutable: they can only be set once during 589 | * construction. 590 | */ 591 | constructor(string memory name_, string memory symbol_) { 592 | _name = name_; 593 | _symbol = symbol_; 594 | } 595 | 596 | /** 597 | * @dev Returns the name of the token. 598 | */ 599 | function name() public view virtual override returns (string memory) { 600 | return _name; 601 | } 602 | 603 | /** 604 | * @dev Returns the symbol of the token, usually a shorter version of the 605 | * name. 606 | */ 607 | function symbol() public view virtual override returns (string memory) { 608 | return _symbol; 609 | } 610 | 611 | /** 612 | * @dev Returns the number of decimals used to get its user representation. 613 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 614 | * be displayed to a user as `5.05` (`505 / 10 ** 2`). 615 | * 616 | * Tokens usually opt for a value of 18, imitating the relationship between 617 | * Ether and Wei. This is the default value returned by this function, unless 618 | * it's overridden. 619 | * 620 | * NOTE: This information is only used for _display_ purposes: it in 621 | * no way affects any of the arithmetic of the contract, including 622 | * {IERC20-balanceOf} and {IERC20-transfer}. 623 | */ 624 | function decimals() public view virtual override returns (uint8) { 625 | return 18; 626 | } 627 | 628 | /** 629 | * @dev See {IERC20-totalSupply}. 630 | */ 631 | function totalSupply() public view virtual override returns (uint256) { 632 | return _totalSupply; 633 | } 634 | 635 | /** 636 | * @dev See {IERC20-balanceOf}. 637 | */ 638 | function balanceOf(address account) public view virtual override returns (uint256) { 639 | return _balances[account]; 640 | } 641 | 642 | /** 643 | * @dev See {IERC20-transfer}. 644 | * 645 | * Requirements: 646 | * 647 | * - `to` cannot be the zero address. 648 | * - the caller must have a balance of at least `amount`. 649 | */ 650 | function transfer(address to, uint256 amount) public virtual override returns (bool) { 651 | address owner = _msgSender(); 652 | _transfer(owner, to, amount); 653 | return true; 654 | } 655 | 656 | /** 657 | * @dev See {IERC20-allowance}. 658 | */ 659 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 660 | return _allowances[owner][spender]; 661 | } 662 | 663 | /** 664 | * @dev See {IERC20-approve}. 665 | * 666 | * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on 667 | * `transferFrom`. This is semantically equivalent to an infinite approval. 668 | * 669 | * Requirements: 670 | * 671 | * - `spender` cannot be the zero address. 672 | */ 673 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 674 | address owner = _msgSender(); 675 | _approve(owner, spender, amount); 676 | return true; 677 | } 678 | 679 | /** 680 | * @dev See {IERC20-transferFrom}. 681 | * 682 | * Emits an {Approval} event indicating the updated allowance. This is not 683 | * required by the EIP. See the note at the beginning of {ERC20}. 684 | * 685 | * NOTE: Does not update the allowance if the current allowance 686 | * is the maximum `uint256`. 687 | * 688 | * Requirements: 689 | * 690 | * - `from` and `to` cannot be the zero address. 691 | * - `from` must have a balance of at least `amount`. 692 | * - the caller must have allowance for ``from``'s tokens of at least 693 | * `amount`. 694 | */ 695 | function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { 696 | address spender = _msgSender(); 697 | _spendAllowance(from, spender, amount); 698 | _transfer(from, to, amount); 699 | return true; 700 | } 701 | 702 | /** 703 | * @dev Atomically increases the allowance granted to `spender` by the caller. 704 | * 705 | * This is an alternative to {approve} that can be used as a mitigation for 706 | * problems described in {IERC20-approve}. 707 | * 708 | * Emits an {Approval} event indicating the updated allowance. 709 | * 710 | * Requirements: 711 | * 712 | * - `spender` cannot be the zero address. 713 | */ 714 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 715 | address owner = _msgSender(); 716 | _approve(owner, spender, allowance(owner, spender) + addedValue); 717 | return true; 718 | } 719 | 720 | /** 721 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 722 | * 723 | * This is an alternative to {approve} that can be used as a mitigation for 724 | * problems described in {IERC20-approve}. 725 | * 726 | * Emits an {Approval} event indicating the updated allowance. 727 | * 728 | * Requirements: 729 | * 730 | * - `spender` cannot be the zero address. 731 | * - `spender` must have allowance for the caller of at least 732 | * `subtractedValue`. 733 | */ 734 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 735 | address owner = _msgSender(); 736 | uint256 currentAllowance = allowance(owner, spender); 737 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 738 | unchecked { 739 | _approve(owner, spender, currentAllowance - subtractedValue); 740 | } 741 | 742 | return true; 743 | } 744 | 745 | /** 746 | * @dev Moves `amount` of tokens from `from` to `to`. 747 | * 748 | * This internal function is equivalent to {transfer}, and can be used to 749 | * e.g. implement automatic token fees, slashing mechanisms, etc. 750 | * 751 | * Emits a {Transfer} event. 752 | * 753 | * Requirements: 754 | * 755 | * - `from` cannot be the zero address. 756 | * - `to` cannot be the zero address. 757 | * - `from` must have a balance of at least `amount`. 758 | */ 759 | function _transfer(address from, address to, uint256 amount) internal virtual { 760 | require(from != address(0), "ERC20: transfer from the zero address"); 761 | require(to != address(0), "ERC20: transfer to the zero address"); 762 | 763 | _beforeTokenTransfer(from, to, amount); 764 | 765 | uint256 fromBalance = _balances[from]; 766 | require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); 767 | unchecked { 768 | _balances[from] = fromBalance - amount; 769 | // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by 770 | // decrementing then incrementing. 771 | _balances[to] += amount; 772 | } 773 | 774 | emit Transfer(from, to, amount); 775 | 776 | _afterTokenTransfer(from, to, amount); 777 | } 778 | 779 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 780 | * the total supply. 781 | * 782 | * Emits a {Transfer} event with `from` set to the zero address. 783 | * 784 | * Requirements: 785 | * 786 | * - `account` cannot be the zero address. 787 | */ 788 | function _mint(address account, uint256 amount) internal virtual { 789 | require(account != address(0), "ERC20: mint to the zero address"); 790 | 791 | _beforeTokenTransfer(address(0), account, amount); 792 | 793 | _totalSupply += amount; 794 | unchecked { 795 | // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. 796 | _balances[account] += amount; 797 | } 798 | emit Transfer(address(0), account, amount); 799 | 800 | _afterTokenTransfer(address(0), account, amount); 801 | } 802 | 803 | /** 804 | * @dev Destroys `amount` tokens from `account`, reducing the 805 | * total supply. 806 | * 807 | * Emits a {Transfer} event with `to` set to the zero address. 808 | * 809 | * Requirements: 810 | * 811 | * - `account` cannot be the zero address. 812 | * - `account` must have at least `amount` tokens. 813 | */ 814 | function _burn(address account, uint256 amount) internal virtual { 815 | require(account != address(0), "ERC20: burn from the zero address"); 816 | 817 | _beforeTokenTransfer(account, address(0), amount); 818 | 819 | uint256 accountBalance = _balances[account]; 820 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 821 | unchecked { 822 | _balances[account] = accountBalance - amount; 823 | // Overflow not possible: amount <= accountBalance <= totalSupply. 824 | _totalSupply -= amount; 825 | } 826 | 827 | emit Transfer(account, address(0), amount); 828 | 829 | _afterTokenTransfer(account, address(0), amount); 830 | } 831 | 832 | /** 833 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 834 | * 835 | * This internal function is equivalent to `approve`, and can be used to 836 | * e.g. set automatic allowances for certain subsystems, etc. 837 | * 838 | * Emits an {Approval} event. 839 | * 840 | * Requirements: 841 | * 842 | * - `owner` cannot be the zero address. 843 | * - `spender` cannot be the zero address. 844 | */ 845 | function _approve(address owner, address spender, uint256 amount) internal virtual { 846 | require(owner != address(0), "ERC20: approve from the zero address"); 847 | require(spender != address(0), "ERC20: approve to the zero address"); 848 | 849 | _allowances[owner][spender] = amount; 850 | emit Approval(owner, spender, amount); 851 | } 852 | 853 | /** 854 | * @dev Updates `owner` s allowance for `spender` based on spent `amount`. 855 | * 856 | * Does not update the allowance amount in case of infinite allowance. 857 | * Revert if not enough allowance is available. 858 | * 859 | * Might emit an {Approval} event. 860 | */ 861 | function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { 862 | uint256 currentAllowance = allowance(owner, spender); 863 | if (currentAllowance != type(uint256).max) { 864 | require(currentAllowance >= amount, "ERC20: insufficient allowance"); 865 | unchecked { 866 | _approve(owner, spender, currentAllowance - amount); 867 | } 868 | } 869 | } 870 | 871 | /** 872 | * @dev Hook that is called before any transfer of tokens. This includes 873 | * minting and burning. 874 | * 875 | * Calling conditions: 876 | * 877 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 878 | * will be transferred to `to`. 879 | * - when `from` is zero, `amount` tokens will be minted for `to`. 880 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 881 | * - `from` and `to` are never both zero. 882 | * 883 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 884 | */ 885 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 886 | 887 | /** 888 | * @dev Hook that is called after any transfer of tokens. This includes 889 | * minting and burning. 890 | * 891 | * Calling conditions: 892 | * 893 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 894 | * has been transferred to `to`. 895 | * - when `from` is zero, `amount` tokens have been minted for `to`. 896 | * - when `to` is zero, `amount` of ``from``'s tokens have been burned. 897 | * - `from` and `to` are never both zero. 898 | * 899 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 900 | */ 901 | function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} 902 | } 903 | 904 | /// @title Dividend-Paying Token 905 | /// @author Roger Wu (https://github.com/roger-wu) 906 | /// @dev A mintable ERC20 token that allows anyone to pay and distribute ether 907 | /// to token holders as dividends and allows token holders to withdraw their dividends. 908 | /// Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code 909 | contract DividendStakingToken is ERC20 { 910 | 911 | constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} 912 | 913 | function _transfer(address from, address to, uint256 value) internal virtual override { 914 | require(false, "Cant transfer dividend token"); 915 | super._transfer(from, to, value); 916 | } 917 | 918 | function _mint(address account, uint256 value) internal override { 919 | super._mint(account, value); 920 | } 921 | 922 | function _burn(address account, uint256 value) internal override { 923 | super._burn(account, value); 924 | } 925 | 926 | function _setDividendBalance(address account, uint256 newBalance) internal { 927 | uint256 currentBalance = balanceOf(account); 928 | 929 | if(newBalance > currentBalance) { 930 | uint256 mintAmount = newBalance - currentBalance; 931 | _mint(account, mintAmount); 932 | } else if(newBalance < currentBalance) { 933 | uint256 burnAmount = currentBalance - newBalance; 934 | _burn(account, burnAmount); 935 | } 936 | } 937 | } 938 | 939 | 940 | interface IwPAWFlexibleStaking { 941 | function stakingAmount(address _user) external view returns (uint256); 942 | function isStakable(address _user) external view returns (bool); 943 | function forceWithdraw(address _user) external; 944 | } 945 | 946 | 947 | contract PawFlexibleStake is Ownable, ReentrancyGuard, DividendStakingToken { 948 | using SafeERC20 for IERC20Metadata; 949 | 950 | // apy 951 | uint256 public apy; 952 | 953 | // Accrued token per share 954 | uint256 public accTokenPerShare; 955 | 956 | uint256 public totalStaked; 957 | 958 | // The block number of the last pool update 959 | uint256 public lastRewardTimeStamp; 960 | 961 | // The precision factor 962 | uint256 public PRECISION_FACTOR = uint256(10**12); 963 | 964 | // The reward token 965 | IERC20Metadata public wPAWToken; 966 | 967 | // The staked token 968 | IERC20Metadata public PAWToken; 969 | 970 | // WPAW Staking 971 | address public WPAWStaking; 972 | 973 | // Info of each user that stakes tokens (PAWToken) 974 | mapping(address => UserInfo) public userInfo; 975 | 976 | struct UserInfo { 977 | uint256 amount; // How many staked tokens the user has provided 978 | uint256 rewardDebt; // Reward debt 979 | } 980 | 981 | event Deposit(address indexed user, uint256 amount); 982 | event EmergencyWithdraw(address indexed user, uint256 amount); 983 | event NewAPY(uint256 apy); 984 | event TokenRecovery(address indexed token, uint256 amount); 985 | event Withdraw(address indexed user, uint256 amount); 986 | event Claim(address indexed user, uint256 amount); 987 | 988 | /** 989 | * @notice Constructor 990 | */ 991 | constructor() DividendStakingToken("Paw Stake Tracker", "stPAWflex") { 992 | PAWToken = IERC20Metadata(0xDc63269eA166b70d4780b3A11F5C825C2b761B01); //PAW 993 | wPAWToken = IERC20Metadata(0x083Af0FB9A8982E09e43AC718aeA9773E28c7f06); //wPAW 994 | // Set the lastRewardTimeStamp as the current timestamp 995 | lastRewardTimeStamp = block.timestamp; 996 | 997 | apy = 3; // 3% 998 | } 999 | 1000 | /* 1001 | * @notice Deposit staked tokens and collect reward tokens (if any) 1002 | * @param _amount: amount to withdraw (in wPAWToken) 1003 | */ 1004 | function deposit(uint256 _amount) external nonReentrant { 1005 | UserInfo storage user = userInfo[msg.sender]; 1006 | 1007 | _updatePool(); 1008 | 1009 | if (user.amount > 0) { 1010 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1011 | if (pending > 0) { 1012 | wPAWToken.safeTransfer(address(msg.sender), pending); 1013 | } 1014 | } 1015 | 1016 | if (_amount > 0) { 1017 | totalStaked = totalStaked + _amount; 1018 | user.amount = user.amount + _amount; 1019 | _setDividendBalance(msg.sender, user.amount); 1020 | PAWToken.safeTransferFrom(address(msg.sender), address(this), _amount); 1021 | } 1022 | 1023 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1024 | 1025 | emit Deposit(msg.sender, _amount); 1026 | } 1027 | 1028 | /* 1029 | * @notice Withdraw staked tokens and collect reward tokens 1030 | * @param _amount: amount to withdraw (in wPAWToken) 1031 | */ 1032 | function withdraw(uint256 _amount) external nonReentrant { 1033 | UserInfo storage user = userInfo[msg.sender]; 1034 | require(user.amount >= _amount, "Amount to withdraw too high"); 1035 | 1036 | _updatePool(); 1037 | 1038 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1039 | 1040 | if (_amount > 0) { 1041 | totalStaked = totalStaked - _amount; 1042 | user.amount = user.amount - _amount; 1043 | _setDividendBalance(msg.sender, user.amount); 1044 | PAWToken.safeTransfer(address(msg.sender), _amount); 1045 | } 1046 | 1047 | if (pending > 0) { 1048 | wPAWToken.safeTransfer(address(msg.sender), pending); 1049 | } 1050 | 1051 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1052 | 1053 | if(user.amount == 0 && WPAWStaking != address(0)){ 1054 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1055 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1056 | { 1057 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1058 | } 1059 | } 1060 | 1061 | emit Withdraw(msg.sender, _amount); 1062 | } 1063 | 1064 | 1065 | /* 1066 | * @notice Collect reward tokens 1067 | */ 1068 | function claim() external nonReentrant { 1069 | UserInfo storage user = userInfo[msg.sender]; 1070 | 1071 | _updatePool(); 1072 | 1073 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1074 | require (pending > 0, "No reward to claim"); 1075 | wPAWToken.safeTransfer(address(msg.sender), pending); 1076 | 1077 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1078 | 1079 | emit Claim(msg.sender, pending); 1080 | } 1081 | 1082 | /* 1083 | * @notice Withdraw staked tokens without caring about rewards rewards 1084 | * @dev Needs to be for emergency. 1085 | */ 1086 | function emergencyWithdraw() external nonReentrant { 1087 | UserInfo storage user = userInfo[msg.sender]; 1088 | uint256 amountToTransfer = user.amount; 1089 | 1090 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1091 | if(pending > 0){ 1092 | rewardTreasure = rewardTreasure + pending; 1093 | _updatePool(); 1094 | } 1095 | 1096 | user.amount = 0; 1097 | user.rewardDebt = 0; 1098 | totalStaked = totalStaked - amountToTransfer; 1099 | 1100 | if (amountToTransfer > 0) { 1101 | PAWToken.safeTransfer(address(msg.sender), amountToTransfer); 1102 | } 1103 | _setDividendBalance(msg.sender, user.amount); 1104 | 1105 | if(user.amount == 0 && WPAWStaking != address(0)){ 1106 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1107 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1108 | { 1109 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1110 | } 1111 | } 1112 | 1113 | emit EmergencyWithdraw(msg.sender, user.amount); 1114 | } 1115 | 1116 | /* 1117 | * @notice Stop rewards, withdraw all reward 1118 | * @dev Only callable by owner. Needs to be for emergency. 1119 | */ 1120 | function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { 1121 | require(_amount <= rewardTreasure, "Exceed withdrawable amount"); 1122 | wPAWToken.safeTransfer(address(msg.sender), _amount); 1123 | rewardTreasure = rewardTreasure - _amount; 1124 | } 1125 | 1126 | /** 1127 | * @notice Allows the owner to recover tokens sent to the contract by mistake 1128 | * @param _token: token address 1129 | * @dev Callable by owner 1130 | */ 1131 | function recoverToken(address _token) external onlyOwner { 1132 | require(_token != address(PAWToken), "Operations: Cannot recover staked token"); 1133 | require(_token != address(wPAWToken), "Operations: Cannot recover reward token"); 1134 | 1135 | uint256 balance = IERC20Metadata(_token).balanceOf(address(this)); 1136 | require(balance != 0, "Operations: Cannot recover zero balance"); 1137 | 1138 | IERC20Metadata(_token).safeTransfer(address(msg.sender), balance); 1139 | 1140 | emit TokenRecovery(_token, balance); 1141 | } 1142 | 1143 | /* 1144 | * @notice Update APY 1145 | * @dev Only callable by owner. Change APY. 1146 | */ 1147 | function updateNewAPY(uint256 _newAPY) external onlyOwner { 1148 | _updatePool(); 1149 | apy = _newAPY; 1150 | emit NewAPY(_newAPY); 1151 | } 1152 | 1153 | /* 1154 | * @notice Set WPAW staking contract 1155 | * @dev Only callable by owner. Change APY. 1156 | */ 1157 | function setWPAWStakingContract(address _wPAWStaking) external onlyOwner { 1158 | WPAWStaking = _wPAWStaking; 1159 | } 1160 | 1161 | /* 1162 | * @notice View function to see pending reward on frontend. 1163 | * @param _user: user address 1164 | * @return Pending reward for a given user 1165 | */ 1166 | function pendingReward(address _user) external view returns (uint256) { 1167 | UserInfo storage user = userInfo[_user]; 1168 | if (block.timestamp > lastRewardTimeStamp && totalStaked != 0) { 1169 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1170 | uint256 estimatedReward = multiplier * (((totalStaked * apy)/100) / (365 days)); 1171 | if(estimatedReward > rewardTreasure){ 1172 | estimatedReward = rewardTreasure; 1173 | } 1174 | uint256 adjustedTokenPerShare = accTokenPerShare + (estimatedReward * PRECISION_FACTOR) / totalStaked; 1175 | return (user.amount * adjustedTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1176 | } else { 1177 | return (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1178 | } 1179 | } 1180 | 1181 | /* 1182 | * @notice Update reward variables of the given pool to be up-to-date. 1183 | */ 1184 | function _updatePool() internal { 1185 | if (block.timestamp <= lastRewardTimeStamp) { 1186 | return; 1187 | } 1188 | 1189 | if (totalStaked == 0) { 1190 | lastRewardTimeStamp = block.timestamp; 1191 | return; 1192 | } 1193 | 1194 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1195 | uint256 estimatedReward = multiplier * (((totalStaked * apy)/100) / (365 days)); 1196 | uint256 realReward = _allocateReward(estimatedReward); 1197 | accTokenPerShare = accTokenPerShare + (realReward * PRECISION_FACTOR) / totalStaked; 1198 | lastRewardTimeStamp = block.timestamp; 1199 | } 1200 | 1201 | 1202 | uint256 public rewardTreasure; 1203 | uint256 public rewardAllocated; 1204 | function addRewardTreasure(uint256 _amount) external nonReentrant{ 1205 | require( _amount > 0 , "err _amount=0"); 1206 | uint256 oldBalance = wPAWToken.balanceOf(address(this)); 1207 | wPAWToken.safeTransferFrom(msg.sender, address(this), _amount); 1208 | uint256 newBalance = wPAWToken.balanceOf(address(this)); 1209 | uint256 realAmount = newBalance - oldBalance; 1210 | rewardTreasure = rewardTreasure + realAmount; 1211 | 1212 | _updatePool(); 1213 | } 1214 | 1215 | function _allocateReward(uint256 amount ) internal returns(uint256){ 1216 | uint256 allocatedAmount = amount; 1217 | if( amount >= rewardTreasure ){ 1218 | allocatedAmount = rewardTreasure; 1219 | } 1220 | rewardTreasure = rewardTreasure - allocatedAmount; 1221 | rewardAllocated = rewardAllocated + allocatedAmount; 1222 | return allocatedAmount; 1223 | } 1224 | } 1225 | -------------------------------------------------------------------------------- /PAWSWAP Shibaswap LP Stake: -------------------------------------------------------------------------------- 1 | // File: @openzeppelin/contracts/utils/Context.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | pragma solidity ^0.8.0; 5 | 6 | //import "hardhat/console.sol"; 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 | 83 | /** 84 | * @dev Interface for the optional metadata functions from the ERC20 standard. 85 | * 86 | * _Available since v4.1._ 87 | */ 88 | interface IERC20Metadata is IERC20 { 89 | /** 90 | * @dev Returns the name of the token. 91 | */ 92 | function name() external view returns (string memory); 93 | 94 | /** 95 | * @dev Returns the symbol of the token. 96 | */ 97 | function symbol() external view returns (string memory); 98 | 99 | /** 100 | * @dev Returns the decimals places of the token. 101 | */ 102 | function decimals() external view returns (uint8); 103 | } 104 | 105 | /* 106 | * @dev Provides information about the current execution context, including the 107 | * sender of the transaction and its data. While these are generally available 108 | * via msg.sender and msg.data, they should not be accessed in such a direct 109 | * manner, since when dealing with meta-transactions the account sending and 110 | * paying for execution may not be the actual sender (as far as an application 111 | * is concerned). 112 | * 113 | * This contract is only required for intermediate, library-like contracts. 114 | */ 115 | abstract contract Context { 116 | function _msgSender() internal view virtual returns (address) { 117 | return msg.sender; 118 | } 119 | 120 | function _msgData() internal view virtual returns (bytes calldata) { 121 | return msg.data; 122 | } 123 | } 124 | 125 | // File: @openzeppelin/contracts/access/Ownable.sol 126 | 127 | abstract contract Ownable is Context { 128 | address private _owner; 129 | 130 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 131 | 132 | /** 133 | * @dev Initializes the contract setting the deployer as the initial owner. 134 | */ 135 | constructor() { 136 | _setOwner(_msgSender()); 137 | } 138 | 139 | /** 140 | * @dev Returns the address of the current owner. 141 | */ 142 | function owner() public view virtual returns (address) { 143 | return _owner; 144 | } 145 | 146 | /** 147 | * @dev Throws if called by any account other than the owner. 148 | */ 149 | modifier onlyOwner() { 150 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 151 | _; 152 | } 153 | 154 | /** 155 | * @dev Leaves the contract without owner. It will not be possible to call 156 | * `onlyOwner` functions anymore. Can only be called by the current owner. 157 | * 158 | * NOTE: Renouncing ownership will leave the contract without an owner, 159 | * thereby removing any functionality that is only available to the owner. 160 | */ 161 | function renounceOwnership() public virtual onlyOwner { 162 | _setOwner(address(0)); 163 | } 164 | 165 | /** 166 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 167 | * Can only be called by the current owner. 168 | */ 169 | function transferOwnership(address newOwner) public virtual onlyOwner { 170 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 171 | _setOwner(newOwner); 172 | } 173 | 174 | function _setOwner(address newOwner) private { 175 | address oldOwner = _owner; 176 | _owner = newOwner; 177 | emit OwnershipTransferred(oldOwner, newOwner); 178 | } 179 | } 180 | 181 | // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol 182 | 183 | /** 184 | * @dev Contract module that helps prevent reentrant calls to a function. 185 | * 186 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 187 | * available, which can be applied to functions to make sure there are no nested 188 | * (reentrant) calls to them. 189 | * 190 | * Note that because there is a single `nonReentrant` guard, functions marked as 191 | * `nonReentrant` may not call one another. This can be worked around by making 192 | * those functions `private`, and then adding `external` `nonReentrant` entry 193 | * points to them. 194 | * 195 | * TIP: If you would like to learn more about reentrancy and alternative ways 196 | * to protect against it, check out our blog post 197 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 198 | */ 199 | abstract contract ReentrancyGuard { 200 | // Booleans are more expensive than uint256 or any type that takes up a full 201 | // word because each write operation emits an extra SLOAD to first read the 202 | // slot's contents, replace the bits taken up by the boolean, and then write 203 | // back. This is the compiler's defense against contract upgrades and 204 | // pointer aliasing, and it cannot be disabled. 205 | 206 | // The values being non-zero value makes deployment a bit more expensive, 207 | // but in exchange the refund on every call to nonReentrant will be lower in 208 | // amount. Since refunds are capped to a percentage of the total 209 | // transaction's gas, it is best to keep them low in cases like this one, to 210 | // increase the likelihood of the full refund coming into effect. 211 | uint256 private constant _NOT_ENTERED = 1; 212 | uint256 private constant _ENTERED = 2; 213 | 214 | uint256 private _status; 215 | 216 | constructor() { 217 | _status = _NOT_ENTERED; 218 | } 219 | 220 | /** 221 | * @dev Prevents a contract from calling itself, directly or indirectly. 222 | * Calling a `nonReentrant` function from another `nonReentrant` 223 | * function is not supported. It is possible to prevent this from happening 224 | * by making the `nonReentrant` function external, and make it call a 225 | * `private` function that does the actual work. 226 | */ 227 | modifier nonReentrant() { 228 | // On the first call to nonReentrant, _notEntered will be true 229 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 230 | 231 | // Any calls to nonReentrant after this point will fail 232 | _status = _ENTERED; 233 | 234 | _; 235 | 236 | // By storing the original value once again, a refund is triggered (see 237 | // https://eips.ethereum.org/EIPS/eip-2200) 238 | _status = _NOT_ENTERED; 239 | } 240 | } 241 | 242 | // File: @openzeppelin/contracts/utils/Address.sol 243 | 244 | /** 245 | * @dev Collection of functions related to the address type 246 | */ 247 | library Address { 248 | /** 249 | * @dev Returns true if `account` is a contract. 250 | * 251 | * [IMPORTANT] 252 | * ==== 253 | * It is unsafe to assume that an address for which this function returns 254 | * false is an externally-owned account (EOA) and not a contract. 255 | * 256 | * Among others, `isContract` will return false for the following 257 | * types of addresses: 258 | * 259 | * - an externally-owned account 260 | * - a contract in construction 261 | * - an address where a contract will be created 262 | * - an address where a contract lived, but was destroyed 263 | * ==== 264 | */ 265 | function isContract(address account) internal view returns (bool) { 266 | // This method relies on extcodesize, which returns 0 for contracts in 267 | // construction, since the code is only stored at the end of the 268 | // constructor execution. 269 | 270 | uint256 size; 271 | assembly { 272 | size := extcodesize(account) 273 | } 274 | return size > 0; 275 | } 276 | 277 | /** 278 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 279 | * `recipient`, forwarding all available gas and reverting on errors. 280 | * 281 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 282 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 283 | * imposed by `transfer`, making them unable to receive funds via 284 | * `transfer`. {sendValue} removes this limitation. 285 | * 286 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 287 | * 288 | * IMPORTANT: because control is transferred to `recipient`, care must be 289 | * taken to not create reentrancy vulnerabilities. Consider using 290 | * {ReentrancyGuard} or the 291 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 292 | */ 293 | function sendValue(address payable recipient, uint256 amount) internal { 294 | require(address(this).balance >= amount, "Address: insufficient balance"); 295 | 296 | (bool success, ) = recipient.call{value: amount}(""); 297 | require(success, "Address: unable to send value, recipient may have reverted"); 298 | } 299 | 300 | /** 301 | * @dev Performs a Solidity function call using a low level `call`. A 302 | * plain `call` is an unsafe replacement for a function call: use this 303 | * function instead. 304 | * 305 | * If `target` reverts with a revert reason, it is bubbled up by this 306 | * function (like regular Solidity function calls). 307 | * 308 | * Returns the raw returned data. To convert to the expected return value, 309 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 310 | * 311 | * Requirements: 312 | * 313 | * - `target` must be a contract. 314 | * - calling `target` with `data` must not revert. 315 | * 316 | * _Available since v3.1._ 317 | */ 318 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 319 | return functionCall(target, data, "Address: low-level call failed"); 320 | } 321 | 322 | /** 323 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 324 | * `errorMessage` as a fallback revert reason when `target` reverts. 325 | * 326 | * _Available since v3.1._ 327 | */ 328 | function functionCall( 329 | address target, 330 | bytes memory data, 331 | string memory errorMessage 332 | ) internal returns (bytes memory) { 333 | return functionCallWithValue(target, data, 0, errorMessage); 334 | } 335 | 336 | /** 337 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 338 | * but also transferring `value` wei to `target`. 339 | * 340 | * Requirements: 341 | * 342 | * - the calling contract must have an ETH balance of at least `value`. 343 | * - the called Solidity function must be `payable`. 344 | * 345 | * _Available since v3.1._ 346 | */ 347 | function functionCallWithValue( 348 | address target, 349 | bytes memory data, 350 | uint256 value 351 | ) internal returns (bytes memory) { 352 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 353 | } 354 | 355 | /** 356 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 357 | * with `errorMessage` as a fallback revert reason when `target` reverts. 358 | * 359 | * _Available since v3.1._ 360 | */ 361 | function functionCallWithValue( 362 | address target, 363 | bytes memory data, 364 | uint256 value, 365 | string memory errorMessage 366 | ) internal returns (bytes memory) { 367 | require(address(this).balance >= value, "Address: insufficient balance for call"); 368 | require(isContract(target), "Address: call to non-contract"); 369 | 370 | (bool success, bytes memory returndata) = target.call{value: value}(data); 371 | return _verifyCallResult(success, returndata, errorMessage); 372 | } 373 | 374 | /** 375 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 376 | * but performing a static call. 377 | * 378 | * _Available since v3.3._ 379 | */ 380 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 381 | return functionStaticCall(target, data, "Address: low-level static call failed"); 382 | } 383 | 384 | /** 385 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 386 | * but performing a static call. 387 | * 388 | * _Available since v3.3._ 389 | */ 390 | function functionStaticCall( 391 | address target, 392 | bytes memory data, 393 | string memory errorMessage 394 | ) internal view returns (bytes memory) { 395 | require(isContract(target), "Address: static call to non-contract"); 396 | 397 | (bool success, bytes memory returndata) = target.staticcall(data); 398 | return _verifyCallResult(success, returndata, errorMessage); 399 | } 400 | 401 | /** 402 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 403 | * but performing a delegate call. 404 | * 405 | * _Available since v3.4._ 406 | */ 407 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 408 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 409 | } 410 | 411 | /** 412 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 413 | * but performing a delegate call. 414 | * 415 | * _Available since v3.4._ 416 | */ 417 | function functionDelegateCall( 418 | address target, 419 | bytes memory data, 420 | string memory errorMessage 421 | ) internal returns (bytes memory) { 422 | require(isContract(target), "Address: delegate call to non-contract"); 423 | 424 | (bool success, bytes memory returndata) = target.delegatecall(data); 425 | return _verifyCallResult(success, returndata, errorMessage); 426 | } 427 | 428 | function _verifyCallResult( 429 | bool success, 430 | bytes memory returndata, 431 | string memory errorMessage 432 | ) private pure returns (bytes memory) { 433 | if (success) { 434 | return returndata; 435 | } else { 436 | // Look for revert reason and bubble it up if present 437 | if (returndata.length > 0) { 438 | // The easiest way to bubble the revert reason is using memory via assembly 439 | 440 | assembly { 441 | let returndata_size := mload(returndata) 442 | revert(add(32, returndata), returndata_size) 443 | } 444 | } else { 445 | revert(errorMessage); 446 | } 447 | } 448 | } 449 | } 450 | 451 | // File: "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 452 | 453 | /** 454 | * @title SafeERC20 455 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 456 | * contract returns false). Tokens that return no value (and instead revert or 457 | * throw on failure) are also supported, non-reverting calls are assumed to be 458 | * successful. 459 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 460 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 461 | */ 462 | library SafeERC20 { 463 | using Address for address; 464 | 465 | function safeTransfer( 466 | IERC20 token, 467 | address to, 468 | uint256 value 469 | ) internal { 470 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 471 | } 472 | 473 | function safeTransferFrom( 474 | IERC20 token, 475 | address from, 476 | address to, 477 | uint256 value 478 | ) internal { 479 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 480 | } 481 | 482 | /** 483 | * @dev Deprecated. This function has issues similar to the ones found in 484 | * {IERC20-approve}, and its usage is discouraged. 485 | * 486 | * Whenever possible, use {safeIncreaseAllowance} and 487 | * {safeDecreaseAllowance} instead. 488 | */ 489 | function safeApprove( 490 | IERC20 token, 491 | address spender, 492 | uint256 value 493 | ) internal { 494 | // safeApprove should only be called when setting an initial allowance, 495 | // or when resetting it to zero. To increase and decrease it, use 496 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 497 | require( 498 | (value == 0) || (token.allowance(address(this), spender) == 0), 499 | "SafeERC20: approve from non-zero to non-zero allowance" 500 | ); 501 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 502 | } 503 | 504 | function safeIncreaseAllowance( 505 | IERC20 token, 506 | address spender, 507 | uint256 value 508 | ) internal { 509 | uint256 newAllowance = token.allowance(address(this), spender) + value; 510 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 511 | } 512 | 513 | function safeDecreaseAllowance( 514 | IERC20 token, 515 | address spender, 516 | uint256 value 517 | ) internal { 518 | unchecked { 519 | uint256 oldAllowance = token.allowance(address(this), spender); 520 | require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); 521 | uint256 newAllowance = oldAllowance - value; 522 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 523 | } 524 | } 525 | 526 | /** 527 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 528 | * on the return value: the return value is optional (but if data is returned, it must not be false). 529 | * @param token The token targeted by the call. 530 | * @param data The call data (encoded using abi.encode or one of its variants). 531 | */ 532 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 533 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 534 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 535 | // the target address contains contract code and also asserts for success in the low-level call. 536 | 537 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 538 | if (returndata.length > 0) { 539 | // Return data is optional 540 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 541 | } 542 | } 543 | } 544 | 545 | 546 | // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) 547 | /** 548 | * @dev Implementation of the {IERC20} interface. 549 | * 550 | * This implementation is agnostic to the way tokens are created. This means 551 | * that a supply mechanism has to be added in a derived contract using {_mint}. 552 | * For a generic mechanism see {ERC20PresetMinterPauser}. 553 | * 554 | * TIP: For a detailed writeup see our guide 555 | * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How 556 | * to implement supply mechanisms]. 557 | * 558 | * The default value of {decimals} is 18. To change this, you should override 559 | * this function so it returns a different value. 560 | * 561 | * We have followed general OpenZeppelin Contracts guidelines: functions revert 562 | * instead returning `false` on failure. This behavior is nonetheless 563 | * conventional and does not conflict with the expectations of ERC20 564 | * applications. 565 | * 566 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 567 | * This allows applications to reconstruct the allowance for all accounts just 568 | * by listening to said events. Other implementations of the EIP may not emit 569 | * these events, as it isn't required by the specification. 570 | * 571 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 572 | * functions have been added to mitigate the well-known issues around setting 573 | * allowances. See {IERC20-approve}. 574 | */ 575 | contract ERC20 is Context, IERC20, IERC20Metadata { 576 | mapping(address => uint256) private _balances; 577 | 578 | mapping(address => mapping(address => uint256)) private _allowances; 579 | 580 | uint256 private _totalSupply; 581 | 582 | string private _name; 583 | string private _symbol; 584 | 585 | /** 586 | * @dev Sets the values for {name} and {symbol}. 587 | * 588 | * All two of these values are immutable: they can only be set once during 589 | * construction. 590 | */ 591 | constructor(string memory name_, string memory symbol_) { 592 | _name = name_; 593 | _symbol = symbol_; 594 | } 595 | 596 | /** 597 | * @dev Returns the name of the token. 598 | */ 599 | function name() public view virtual override returns (string memory) { 600 | return _name; 601 | } 602 | 603 | /** 604 | * @dev Returns the symbol of the token, usually a shorter version of the 605 | * name. 606 | */ 607 | function symbol() public view virtual override returns (string memory) { 608 | return _symbol; 609 | } 610 | 611 | /** 612 | * @dev Returns the number of decimals used to get its user representation. 613 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 614 | * be displayed to a user as `5.05` (`505 / 10 ** 2`). 615 | * 616 | * Tokens usually opt for a value of 18, imitating the relationship between 617 | * Ether and Wei. This is the default value returned by this function, unless 618 | * it's overridden. 619 | * 620 | * NOTE: This information is only used for _display_ purposes: it in 621 | * no way affects any of the arithmetic of the contract, including 622 | * {IERC20-balanceOf} and {IERC20-transfer}. 623 | */ 624 | function decimals() public view virtual override returns (uint8) { 625 | return 18; 626 | } 627 | 628 | /** 629 | * @dev See {IERC20-totalSupply}. 630 | */ 631 | function totalSupply() public view virtual override returns (uint256) { 632 | return _totalSupply; 633 | } 634 | 635 | /** 636 | * @dev See {IERC20-balanceOf}. 637 | */ 638 | function balanceOf(address account) public view virtual override returns (uint256) { 639 | return _balances[account]; 640 | } 641 | 642 | /** 643 | * @dev See {IERC20-transfer}. 644 | * 645 | * Requirements: 646 | * 647 | * - `to` cannot be the zero address. 648 | * - the caller must have a balance of at least `amount`. 649 | */ 650 | function transfer(address to, uint256 amount) public virtual override returns (bool) { 651 | address owner = _msgSender(); 652 | _transfer(owner, to, amount); 653 | return true; 654 | } 655 | 656 | /** 657 | * @dev See {IERC20-allowance}. 658 | */ 659 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 660 | return _allowances[owner][spender]; 661 | } 662 | 663 | /** 664 | * @dev See {IERC20-approve}. 665 | * 666 | * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on 667 | * `transferFrom`. This is semantically equivalent to an infinite approval. 668 | * 669 | * Requirements: 670 | * 671 | * - `spender` cannot be the zero address. 672 | */ 673 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 674 | address owner = _msgSender(); 675 | _approve(owner, spender, amount); 676 | return true; 677 | } 678 | 679 | /** 680 | * @dev See {IERC20-transferFrom}. 681 | * 682 | * Emits an {Approval} event indicating the updated allowance. This is not 683 | * required by the EIP. See the note at the beginning of {ERC20}. 684 | * 685 | * NOTE: Does not update the allowance if the current allowance 686 | * is the maximum `uint256`. 687 | * 688 | * Requirements: 689 | * 690 | * - `from` and `to` cannot be the zero address. 691 | * - `from` must have a balance of at least `amount`. 692 | * - the caller must have allowance for ``from``'s tokens of at least 693 | * `amount`. 694 | */ 695 | function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { 696 | address spender = _msgSender(); 697 | _spendAllowance(from, spender, amount); 698 | _transfer(from, to, amount); 699 | return true; 700 | } 701 | 702 | /** 703 | * @dev Atomically increases the allowance granted to `spender` by the caller. 704 | * 705 | * This is an alternative to {approve} that can be used as a mitigation for 706 | * problems described in {IERC20-approve}. 707 | * 708 | * Emits an {Approval} event indicating the updated allowance. 709 | * 710 | * Requirements: 711 | * 712 | * - `spender` cannot be the zero address. 713 | */ 714 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 715 | address owner = _msgSender(); 716 | _approve(owner, spender, allowance(owner, spender) + addedValue); 717 | return true; 718 | } 719 | 720 | /** 721 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 722 | * 723 | * This is an alternative to {approve} that can be used as a mitigation for 724 | * problems described in {IERC20-approve}. 725 | * 726 | * Emits an {Approval} event indicating the updated allowance. 727 | * 728 | * Requirements: 729 | * 730 | * - `spender` cannot be the zero address. 731 | * - `spender` must have allowance for the caller of at least 732 | * `subtractedValue`. 733 | */ 734 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 735 | address owner = _msgSender(); 736 | uint256 currentAllowance = allowance(owner, spender); 737 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 738 | unchecked { 739 | _approve(owner, spender, currentAllowance - subtractedValue); 740 | } 741 | 742 | return true; 743 | } 744 | 745 | /** 746 | * @dev Moves `amount` of tokens from `from` to `to`. 747 | * 748 | * This internal function is equivalent to {transfer}, and can be used to 749 | * e.g. implement automatic token fees, slashing mechanisms, etc. 750 | * 751 | * Emits a {Transfer} event. 752 | * 753 | * Requirements: 754 | * 755 | * - `from` cannot be the zero address. 756 | * - `to` cannot be the zero address. 757 | * - `from` must have a balance of at least `amount`. 758 | */ 759 | function _transfer(address from, address to, uint256 amount) internal virtual { 760 | require(from != address(0), "ERC20: transfer from the zero address"); 761 | require(to != address(0), "ERC20: transfer to the zero address"); 762 | 763 | _beforeTokenTransfer(from, to, amount); 764 | 765 | uint256 fromBalance = _balances[from]; 766 | require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); 767 | unchecked { 768 | _balances[from] = fromBalance - amount; 769 | // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by 770 | // decrementing then incrementing. 771 | _balances[to] += amount; 772 | } 773 | 774 | emit Transfer(from, to, amount); 775 | 776 | _afterTokenTransfer(from, to, amount); 777 | } 778 | 779 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 780 | * the total supply. 781 | * 782 | * Emits a {Transfer} event with `from` set to the zero address. 783 | * 784 | * Requirements: 785 | * 786 | * - `account` cannot be the zero address. 787 | */ 788 | function _mint(address account, uint256 amount) internal virtual { 789 | require(account != address(0), "ERC20: mint to the zero address"); 790 | 791 | _beforeTokenTransfer(address(0), account, amount); 792 | 793 | _totalSupply += amount; 794 | unchecked { 795 | // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. 796 | _balances[account] += amount; 797 | } 798 | emit Transfer(address(0), account, amount); 799 | 800 | _afterTokenTransfer(address(0), account, amount); 801 | } 802 | 803 | /** 804 | * @dev Destroys `amount` tokens from `account`, reducing the 805 | * total supply. 806 | * 807 | * Emits a {Transfer} event with `to` set to the zero address. 808 | * 809 | * Requirements: 810 | * 811 | * - `account` cannot be the zero address. 812 | * - `account` must have at least `amount` tokens. 813 | */ 814 | function _burn(address account, uint256 amount) internal virtual { 815 | require(account != address(0), "ERC20: burn from the zero address"); 816 | 817 | _beforeTokenTransfer(account, address(0), amount); 818 | 819 | uint256 accountBalance = _balances[account]; 820 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 821 | unchecked { 822 | _balances[account] = accountBalance - amount; 823 | // Overflow not possible: amount <= accountBalance <= totalSupply. 824 | _totalSupply -= amount; 825 | } 826 | 827 | emit Transfer(account, address(0), amount); 828 | 829 | _afterTokenTransfer(account, address(0), amount); 830 | } 831 | 832 | /** 833 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 834 | * 835 | * This internal function is equivalent to `approve`, and can be used to 836 | * e.g. set automatic allowances for certain subsystems, etc. 837 | * 838 | * Emits an {Approval} event. 839 | * 840 | * Requirements: 841 | * 842 | * - `owner` cannot be the zero address. 843 | * - `spender` cannot be the zero address. 844 | */ 845 | function _approve(address owner, address spender, uint256 amount) internal virtual { 846 | require(owner != address(0), "ERC20: approve from the zero address"); 847 | require(spender != address(0), "ERC20: approve to the zero address"); 848 | 849 | _allowances[owner][spender] = amount; 850 | emit Approval(owner, spender, amount); 851 | } 852 | 853 | /** 854 | * @dev Updates `owner` s allowance for `spender` based on spent `amount`. 855 | * 856 | * Does not update the allowance amount in case of infinite allowance. 857 | * Revert if not enough allowance is available. 858 | * 859 | * Might emit an {Approval} event. 860 | */ 861 | function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { 862 | uint256 currentAllowance = allowance(owner, spender); 863 | if (currentAllowance != type(uint256).max) { 864 | require(currentAllowance >= amount, "ERC20: insufficient allowance"); 865 | unchecked { 866 | _approve(owner, spender, currentAllowance - amount); 867 | } 868 | } 869 | } 870 | 871 | /** 872 | * @dev Hook that is called before any transfer of tokens. This includes 873 | * minting and burning. 874 | * 875 | * Calling conditions: 876 | * 877 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 878 | * will be transferred to `to`. 879 | * - when `from` is zero, `amount` tokens will be minted for `to`. 880 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 881 | * - `from` and `to` are never both zero. 882 | * 883 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 884 | */ 885 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 886 | 887 | /** 888 | * @dev Hook that is called after any transfer of tokens. This includes 889 | * minting and burning. 890 | * 891 | * Calling conditions: 892 | * 893 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 894 | * has been transferred to `to`. 895 | * - when `from` is zero, `amount` tokens have been minted for `to`. 896 | * - when `to` is zero, `amount` of ``from``'s tokens have been burned. 897 | * - `from` and `to` are never both zero. 898 | * 899 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 900 | */ 901 | function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} 902 | } 903 | 904 | /// @title Dividend-Paying Token 905 | /// @author Roger Wu (https://github.com/roger-wu) 906 | /// @dev A mintable ERC20 token that allows anyone to pay and distribute ether 907 | /// to token holders as dividends and allows token holders to withdraw their dividends. 908 | /// Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code 909 | contract DividendStakingToken is ERC20 { 910 | 911 | constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} 912 | 913 | function _transfer(address from, address to, uint256 value) internal virtual override { 914 | require(false, "Cant transfer dividend token"); 915 | super._transfer(from, to, value); 916 | } 917 | 918 | function _mint(address account, uint256 value) internal override { 919 | super._mint(account, value); 920 | } 921 | 922 | function _burn(address account, uint256 value) internal override { 923 | super._burn(account, value); 924 | } 925 | 926 | function _setDividendBalance(address account, uint256 newBalance) internal { 927 | uint256 currentBalance = balanceOf(account); 928 | 929 | if(newBalance > currentBalance) { 930 | uint256 mintAmount = newBalance - currentBalance; 931 | _mint(account, mintAmount); 932 | } else if(newBalance < currentBalance) { 933 | uint256 burnAmount = currentBalance - newBalance; 934 | _burn(account, burnAmount); 935 | } 936 | } 937 | } 938 | 939 | interface IwPAWFlexibleStaking { 940 | function stakingAmount(address _user) external view returns (uint256); 941 | function isStakable(address _user) external view returns (bool); 942 | function forceWithdraw(address _user) external; 943 | } 944 | 945 | contract PawShibaLPStake is Ownable, ReentrancyGuard, DividendStakingToken { 946 | using SafeERC20 for IERC20Metadata; 947 | 948 | // Accrued token per share 949 | uint256 public accTokenPerShare; 950 | 951 | uint256 public totalStaked; 952 | 953 | // The block number of the last pool update 954 | uint256 public lastRewardTimeStamp; 955 | 956 | // reward tokens created per second. 957 | uint256 public rewardPerTimeStamp; 958 | 959 | // The precision factor 960 | uint256 public PRECISION_FACTOR = uint256(10**12); 961 | 962 | //PAW 963 | IERC20Metadata public PAWToken; 964 | 965 | // The reward token 966 | IERC20Metadata public wPAWToken; 967 | 968 | // The staked token 969 | IERC20Metadata public lpToken; 970 | 971 | // WPAW Staking 972 | address public WPAWStaking; 973 | 974 | // Info of each user that stakes tokens (lpToken) 975 | mapping(address => UserInfo) public userInfo; 976 | 977 | struct UserInfo { 978 | uint256 amount; // How many staked tokens the user has provided 979 | uint256 rewardDebt; // Reward debt 980 | } 981 | 982 | event Deposit(address indexed user, uint256 amount); 983 | event EmergencyWithdraw(address indexed user, uint256 amount); 984 | event NewRewardPerTimeStamp(uint256 rewardPerTimeStamp); 985 | event TokenRecovery(address indexed token, uint256 amount); 986 | event Withdraw(address indexed user, uint256 amount); 987 | event Claim(address indexed user, uint256 amount); 988 | 989 | /** 990 | * @notice Constructor 991 | */ 992 | constructor() DividendStakingToken("Paw Stake Tracker", "stPAWsslp") { 993 | lpToken = IERC20Metadata(0x0dBa3dfeE43d9B6450C716c58fdAE8D3BE37FdC9); //ShibaSwap PAW-ETH 994 | PAWToken = IERC20Metadata(0xDc63269eA166b70d4780b3A11F5C825C2b761B01); //PAW 995 | wPAWToken = IERC20Metadata(0xFF9E32AaF15953EC3F69FE899D220A705ce06dD0); //wPAW 996 | // Set the lastRewardTimeStamp as the current timestamp 997 | lastRewardTimeStamp = block.timestamp; 998 | 999 | rewardPerTimeStamp = 1 * (10**(wPAWToken.decimals())); // at the beginning, start with 1 wPAW per second 1000 | } 1001 | 1002 | /* 1003 | * @notice Deposit staked tokens and collect reward tokens (if any) 1004 | * @param _amount: amount to withdraw (in wPAWToken) 1005 | */ 1006 | function deposit(uint256 _amount) external nonReentrant { 1007 | UserInfo storage user = userInfo[msg.sender]; 1008 | 1009 | _updatePool(); 1010 | 1011 | if (user.amount > 0) { 1012 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1013 | if (pending > 0) { 1014 | wPAWToken.safeTransfer(address(msg.sender), pending); 1015 | } 1016 | } 1017 | 1018 | if (_amount > 0) { 1019 | totalStaked = totalStaked + _amount; 1020 | user.amount = user.amount + _amount; 1021 | _setDividendBalance(msg.sender, user.amount); 1022 | lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); 1023 | } 1024 | 1025 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1026 | 1027 | emit Deposit(msg.sender, _amount); 1028 | } 1029 | 1030 | /* 1031 | * @notice Withdraw staked tokens and collect reward tokens 1032 | * @param _amount: amount to withdraw (in wPAWToken) 1033 | */ 1034 | function withdraw(uint256 _amount) external nonReentrant { 1035 | UserInfo storage user = userInfo[msg.sender]; 1036 | require(user.amount >= _amount, "Amount to withdraw too high"); 1037 | 1038 | _updatePool(); 1039 | 1040 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1041 | 1042 | if (_amount > 0) { 1043 | totalStaked = totalStaked - _amount; 1044 | user.amount = user.amount - _amount; 1045 | _setDividendBalance(msg.sender, user.amount); 1046 | lpToken.safeTransfer(address(msg.sender), _amount); 1047 | } 1048 | 1049 | if (pending > 0) { 1050 | wPAWToken.safeTransfer(address(msg.sender), pending); 1051 | } 1052 | 1053 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1054 | 1055 | if(user.amount == 0 && WPAWStaking != address(0)){ 1056 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1057 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1058 | { 1059 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1060 | } 1061 | } 1062 | 1063 | emit Withdraw(msg.sender, _amount); 1064 | } 1065 | 1066 | 1067 | /* 1068 | * @notice Collect reward tokens 1069 | */ 1070 | function claim() external nonReentrant { 1071 | UserInfo storage user = userInfo[msg.sender]; 1072 | 1073 | _updatePool(); 1074 | 1075 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1076 | require (pending > 0, "No reward to claim"); 1077 | wPAWToken.safeTransfer(address(msg.sender), pending); 1078 | 1079 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1080 | 1081 | emit Claim(msg.sender, pending); 1082 | } 1083 | 1084 | /* 1085 | * @notice Withdraw staked tokens without caring about rewards rewards 1086 | * @dev Needs to be for emergency. 1087 | */ 1088 | function emergencyWithdraw() external nonReentrant { 1089 | UserInfo storage user = userInfo[msg.sender]; 1090 | uint256 amountToTransfer = user.amount; 1091 | 1092 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1093 | if(pending > 0){ 1094 | rewardTreasure = rewardTreasure + pending; 1095 | _updatePool(); 1096 | } 1097 | 1098 | user.amount = 0; 1099 | user.rewardDebt = 0; 1100 | totalStaked = totalStaked - amountToTransfer; 1101 | 1102 | if (amountToTransfer > 0) { 1103 | lpToken.safeTransfer(address(msg.sender), amountToTransfer); 1104 | } 1105 | _setDividendBalance(msg.sender, user.amount); 1106 | 1107 | if(user.amount == 0 && WPAWStaking != address(0)){ 1108 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1109 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1110 | { 1111 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1112 | } 1113 | } 1114 | 1115 | emit EmergencyWithdraw(msg.sender, user.amount); 1116 | } 1117 | 1118 | /* 1119 | * @notice Stop rewards, withdraw all reward 1120 | * @dev Only callable by owner. Needs to be for emergency. 1121 | */ 1122 | function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { 1123 | require(_amount <= rewardTreasure, "Exceed withdrawable amount"); 1124 | wPAWToken.safeTransfer(address(msg.sender), _amount); 1125 | rewardTreasure = rewardTreasure - _amount; 1126 | 1127 | _updatePool(); 1128 | } 1129 | 1130 | /** 1131 | * @notice Allows the owner to recover tokens sent to the contract by mistake 1132 | * @param _token: token address 1133 | * @dev Callable by owner 1134 | */ 1135 | function recoverToken(address _token) external onlyOwner { 1136 | require(_token != address(lpToken), "Operations: Cannot recover staked token"); 1137 | require(_token != address(wPAWToken), "Operations: Cannot recover reward token"); 1138 | 1139 | uint256 balance = IERC20Metadata(_token).balanceOf(address(this)); 1140 | require(balance != 0, "Operations: Cannot recover zero balance"); 1141 | 1142 | IERC20Metadata(_token).safeTransfer(address(msg.sender), balance); 1143 | 1144 | emit TokenRecovery(_token, balance); 1145 | } 1146 | 1147 | /* 1148 | * @notice Update reward per second 1149 | * @dev Only callable by owner. 1150 | * @param _rewardPerTimeStamp: the reward per second 1151 | */ 1152 | function updateRewardPerTimeStamp(uint256 _rewardPerTimeStamp) external onlyOwner { 1153 | _updatePool(); 1154 | rewardPerTimeStamp = _rewardPerTimeStamp; 1155 | emit NewRewardPerTimeStamp(_rewardPerTimeStamp); 1156 | } 1157 | 1158 | /* 1159 | * @notice Set WPAW staking contract 1160 | * @dev Only callable by owner. Change APY. 1161 | */ 1162 | function setWPAWStakingContract(address _wPAWStaking) external onlyOwner { 1163 | WPAWStaking = _wPAWStaking; 1164 | } 1165 | 1166 | /* 1167 | * @notice View function to see pending reward on frontend. 1168 | * @param _user: user address 1169 | * @return Pending reward for a given user 1170 | */ 1171 | function pendingReward(address _user) external view returns (uint256) { 1172 | UserInfo storage user = userInfo[_user]; 1173 | if (block.timestamp > lastRewardTimeStamp && totalStaked != 0) { 1174 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1175 | uint256 estimatedReward = multiplier * rewardPerTimeStamp; 1176 | if(estimatedReward > rewardTreasure){ 1177 | estimatedReward = rewardTreasure; 1178 | } 1179 | uint256 adjustedTokenPerShare = accTokenPerShare + (estimatedReward * PRECISION_FACTOR) / totalStaked; 1180 | return (user.amount * adjustedTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1181 | } else { 1182 | return (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1183 | } 1184 | } 1185 | 1186 | /* 1187 | * @notice Update reward variables of the given pool to be up-to-date. 1188 | */ 1189 | function _updatePool() internal { 1190 | if (block.timestamp <= lastRewardTimeStamp) { 1191 | return; 1192 | } 1193 | 1194 | if (totalStaked == 0) { 1195 | lastRewardTimeStamp = block.timestamp; 1196 | return; 1197 | } 1198 | 1199 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1200 | uint256 estimatedReward = multiplier * rewardPerTimeStamp; 1201 | uint256 realReward = _allocateReward(estimatedReward); 1202 | accTokenPerShare = accTokenPerShare + (realReward * PRECISION_FACTOR) / totalStaked; 1203 | lastRewardTimeStamp = block.timestamp; 1204 | } 1205 | 1206 | 1207 | uint256 public rewardTreasure; 1208 | uint256 public rewardAllocated; 1209 | function addRewardTreasure(uint256 _amount) external nonReentrant{ 1210 | require( _amount > 0 , "err _amount=0"); 1211 | uint256 oldBalance = wPAWToken.balanceOf(address(this)); 1212 | wPAWToken.safeTransferFrom(msg.sender, address(this), _amount); 1213 | uint256 newBalance = wPAWToken.balanceOf(address(this)); 1214 | uint256 realAmount = newBalance - oldBalance; 1215 | rewardTreasure = rewardTreasure + realAmount; 1216 | 1217 | _updatePool(); 1218 | } 1219 | 1220 | function _allocateReward(uint256 amount ) internal returns(uint256){ 1221 | uint256 allocatedAmount = amount; 1222 | if( amount >= rewardTreasure ){ 1223 | allocatedAmount = rewardTreasure; 1224 | } 1225 | rewardTreasure = rewardTreasure - allocatedAmount; 1226 | rewardAllocated = rewardAllocated + allocatedAmount; 1227 | return allocatedAmount; 1228 | } 1229 | 1230 | function estimateAPY() external view returns(uint256){ 1231 | if(totalStaked == 0) 1232 | return 0; 1233 | 1234 | uint256 PAWEquivalentOfTotalLPStaking = ((2 * PAWToken.balanceOf(address(lpToken))) * totalStaked) / lpToken.totalSupply(); 1235 | return (rewardPerTimeStamp * (365 days) * 100) / PAWEquivalentOfTotalLPStaking; 1236 | 1237 | } 1238 | } 1239 | -------------------------------------------------------------------------------- /PAWSWAP Uni V2 LP Stake: -------------------------------------------------------------------------------- 1 | // File: @openzeppelin/contracts/utils/Context.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | pragma solidity ^0.8.0; 5 | 6 | //import "hardhat/console.sol"; 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 | 83 | /** 84 | * @dev Interface for the optional metadata functions from the ERC20 standard. 85 | * 86 | * _Available since v4.1._ 87 | */ 88 | interface IERC20Metadata is IERC20 { 89 | /** 90 | * @dev Returns the name of the token. 91 | */ 92 | function name() external view returns (string memory); 93 | 94 | /** 95 | * @dev Returns the symbol of the token. 96 | */ 97 | function symbol() external view returns (string memory); 98 | 99 | /** 100 | * @dev Returns the decimals places of the token. 101 | */ 102 | function decimals() external view returns (uint8); 103 | } 104 | 105 | /* 106 | * @dev Provides information about the current execution context, including the 107 | * sender of the transaction and its data. While these are generally available 108 | * via msg.sender and msg.data, they should not be accessed in such a direct 109 | * manner, since when dealing with meta-transactions the account sending and 110 | * paying for execution may not be the actual sender (as far as an application 111 | * is concerned). 112 | * 113 | * This contract is only required for intermediate, library-like contracts. 114 | */ 115 | abstract contract Context { 116 | function _msgSender() internal view virtual returns (address) { 117 | return msg.sender; 118 | } 119 | 120 | function _msgData() internal view virtual returns (bytes calldata) { 121 | return msg.data; 122 | } 123 | } 124 | 125 | // File: @openzeppelin/contracts/access/Ownable.sol 126 | 127 | abstract contract Ownable is Context { 128 | address private _owner; 129 | 130 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 131 | 132 | /** 133 | * @dev Initializes the contract setting the deployer as the initial owner. 134 | */ 135 | constructor() { 136 | _setOwner(_msgSender()); 137 | } 138 | 139 | /** 140 | * @dev Returns the address of the current owner. 141 | */ 142 | function owner() public view virtual returns (address) { 143 | return _owner; 144 | } 145 | 146 | /** 147 | * @dev Throws if called by any account other than the owner. 148 | */ 149 | modifier onlyOwner() { 150 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 151 | _; 152 | } 153 | 154 | /** 155 | * @dev Leaves the contract without owner. It will not be possible to call 156 | * `onlyOwner` functions anymore. Can only be called by the current owner. 157 | * 158 | * NOTE: Renouncing ownership will leave the contract without an owner, 159 | * thereby removing any functionality that is only available to the owner. 160 | */ 161 | function renounceOwnership() public virtual onlyOwner { 162 | _setOwner(address(0)); 163 | } 164 | 165 | /** 166 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 167 | * Can only be called by the current owner. 168 | */ 169 | function transferOwnership(address newOwner) public virtual onlyOwner { 170 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 171 | _setOwner(newOwner); 172 | } 173 | 174 | function _setOwner(address newOwner) private { 175 | address oldOwner = _owner; 176 | _owner = newOwner; 177 | emit OwnershipTransferred(oldOwner, newOwner); 178 | } 179 | } 180 | 181 | // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol 182 | 183 | /** 184 | * @dev Contract module that helps prevent reentrant calls to a function. 185 | * 186 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 187 | * available, which can be applied to functions to make sure there are no nested 188 | * (reentrant) calls to them. 189 | * 190 | * Note that because there is a single `nonReentrant` guard, functions marked as 191 | * `nonReentrant` may not call one another. This can be worked around by making 192 | * those functions `private`, and then adding `external` `nonReentrant` entry 193 | * points to them. 194 | * 195 | * TIP: If you would like to learn more about reentrancy and alternative ways 196 | * to protect against it, check out our blog post 197 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 198 | */ 199 | abstract contract ReentrancyGuard { 200 | // Booleans are more expensive than uint256 or any type that takes up a full 201 | // word because each write operation emits an extra SLOAD to first read the 202 | // slot's contents, replace the bits taken up by the boolean, and then write 203 | // back. This is the compiler's defense against contract upgrades and 204 | // pointer aliasing, and it cannot be disabled. 205 | 206 | // The values being non-zero value makes deployment a bit more expensive, 207 | // but in exchange the refund on every call to nonReentrant will be lower in 208 | // amount. Since refunds are capped to a percentage of the total 209 | // transaction's gas, it is best to keep them low in cases like this one, to 210 | // increase the likelihood of the full refund coming into effect. 211 | uint256 private constant _NOT_ENTERED = 1; 212 | uint256 private constant _ENTERED = 2; 213 | 214 | uint256 private _status; 215 | 216 | constructor() { 217 | _status = _NOT_ENTERED; 218 | } 219 | 220 | /** 221 | * @dev Prevents a contract from calling itself, directly or indirectly. 222 | * Calling a `nonReentrant` function from another `nonReentrant` 223 | * function is not supported. It is possible to prevent this from happening 224 | * by making the `nonReentrant` function external, and make it call a 225 | * `private` function that does the actual work. 226 | */ 227 | modifier nonReentrant() { 228 | // On the first call to nonReentrant, _notEntered will be true 229 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 230 | 231 | // Any calls to nonReentrant after this point will fail 232 | _status = _ENTERED; 233 | 234 | _; 235 | 236 | // By storing the original value once again, a refund is triggered (see 237 | // https://eips.ethereum.org/EIPS/eip-2200) 238 | _status = _NOT_ENTERED; 239 | } 240 | } 241 | 242 | // File: @openzeppelin/contracts/utils/Address.sol 243 | 244 | /** 245 | * @dev Collection of functions related to the address type 246 | */ 247 | library Address { 248 | /** 249 | * @dev Returns true if `account` is a contract. 250 | * 251 | * [IMPORTANT] 252 | * ==== 253 | * It is unsafe to assume that an address for which this function returns 254 | * false is an externally-owned account (EOA) and not a contract. 255 | * 256 | * Among others, `isContract` will return false for the following 257 | * types of addresses: 258 | * 259 | * - an externally-owned account 260 | * - a contract in construction 261 | * - an address where a contract will be created 262 | * - an address where a contract lived, but was destroyed 263 | * ==== 264 | */ 265 | function isContract(address account) internal view returns (bool) { 266 | // This method relies on extcodesize, which returns 0 for contracts in 267 | // construction, since the code is only stored at the end of the 268 | // constructor execution. 269 | 270 | uint256 size; 271 | assembly { 272 | size := extcodesize(account) 273 | } 274 | return size > 0; 275 | } 276 | 277 | /** 278 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 279 | * `recipient`, forwarding all available gas and reverting on errors. 280 | * 281 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 282 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 283 | * imposed by `transfer`, making them unable to receive funds via 284 | * `transfer`. {sendValue} removes this limitation. 285 | * 286 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 287 | * 288 | * IMPORTANT: because control is transferred to `recipient`, care must be 289 | * taken to not create reentrancy vulnerabilities. Consider using 290 | * {ReentrancyGuard} or the 291 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 292 | */ 293 | function sendValue(address payable recipient, uint256 amount) internal { 294 | require(address(this).balance >= amount, "Address: insufficient balance"); 295 | 296 | (bool success, ) = recipient.call{value: amount}(""); 297 | require(success, "Address: unable to send value, recipient may have reverted"); 298 | } 299 | 300 | /** 301 | * @dev Performs a Solidity function call using a low level `call`. A 302 | * plain `call` is an unsafe replacement for a function call: use this 303 | * function instead. 304 | * 305 | * If `target` reverts with a revert reason, it is bubbled up by this 306 | * function (like regular Solidity function calls). 307 | * 308 | * Returns the raw returned data. To convert to the expected return value, 309 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 310 | * 311 | * Requirements: 312 | * 313 | * - `target` must be a contract. 314 | * - calling `target` with `data` must not revert. 315 | * 316 | * _Available since v3.1._ 317 | */ 318 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 319 | return functionCall(target, data, "Address: low-level call failed"); 320 | } 321 | 322 | /** 323 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 324 | * `errorMessage` as a fallback revert reason when `target` reverts. 325 | * 326 | * _Available since v3.1._ 327 | */ 328 | function functionCall( 329 | address target, 330 | bytes memory data, 331 | string memory errorMessage 332 | ) internal returns (bytes memory) { 333 | return functionCallWithValue(target, data, 0, errorMessage); 334 | } 335 | 336 | /** 337 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 338 | * but also transferring `value` wei to `target`. 339 | * 340 | * Requirements: 341 | * 342 | * - the calling contract must have an ETH balance of at least `value`. 343 | * - the called Solidity function must be `payable`. 344 | * 345 | * _Available since v3.1._ 346 | */ 347 | function functionCallWithValue( 348 | address target, 349 | bytes memory data, 350 | uint256 value 351 | ) internal returns (bytes memory) { 352 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 353 | } 354 | 355 | /** 356 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 357 | * with `errorMessage` as a fallback revert reason when `target` reverts. 358 | * 359 | * _Available since v3.1._ 360 | */ 361 | function functionCallWithValue( 362 | address target, 363 | bytes memory data, 364 | uint256 value, 365 | string memory errorMessage 366 | ) internal returns (bytes memory) { 367 | require(address(this).balance >= value, "Address: insufficient balance for call"); 368 | require(isContract(target), "Address: call to non-contract"); 369 | 370 | (bool success, bytes memory returndata) = target.call{value: value}(data); 371 | return _verifyCallResult(success, returndata, errorMessage); 372 | } 373 | 374 | /** 375 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 376 | * but performing a static call. 377 | * 378 | * _Available since v3.3._ 379 | */ 380 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 381 | return functionStaticCall(target, data, "Address: low-level static call failed"); 382 | } 383 | 384 | /** 385 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 386 | * but performing a static call. 387 | * 388 | * _Available since v3.3._ 389 | */ 390 | function functionStaticCall( 391 | address target, 392 | bytes memory data, 393 | string memory errorMessage 394 | ) internal view returns (bytes memory) { 395 | require(isContract(target), "Address: static call to non-contract"); 396 | 397 | (bool success, bytes memory returndata) = target.staticcall(data); 398 | return _verifyCallResult(success, returndata, errorMessage); 399 | } 400 | 401 | /** 402 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 403 | * but performing a delegate call. 404 | * 405 | * _Available since v3.4._ 406 | */ 407 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 408 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 409 | } 410 | 411 | /** 412 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 413 | * but performing a delegate call. 414 | * 415 | * _Available since v3.4._ 416 | */ 417 | function functionDelegateCall( 418 | address target, 419 | bytes memory data, 420 | string memory errorMessage 421 | ) internal returns (bytes memory) { 422 | require(isContract(target), "Address: delegate call to non-contract"); 423 | 424 | (bool success, bytes memory returndata) = target.delegatecall(data); 425 | return _verifyCallResult(success, returndata, errorMessage); 426 | } 427 | 428 | function _verifyCallResult( 429 | bool success, 430 | bytes memory returndata, 431 | string memory errorMessage 432 | ) private pure returns (bytes memory) { 433 | if (success) { 434 | return returndata; 435 | } else { 436 | // Look for revert reason and bubble it up if present 437 | if (returndata.length > 0) { 438 | // The easiest way to bubble the revert reason is using memory via assembly 439 | 440 | assembly { 441 | let returndata_size := mload(returndata) 442 | revert(add(32, returndata), returndata_size) 443 | } 444 | } else { 445 | revert(errorMessage); 446 | } 447 | } 448 | } 449 | } 450 | 451 | // File: "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 452 | 453 | /** 454 | * @title SafeERC20 455 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 456 | * contract returns false). Tokens that return no value (and instead revert or 457 | * throw on failure) are also supported, non-reverting calls are assumed to be 458 | * successful. 459 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 460 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 461 | */ 462 | library SafeERC20 { 463 | using Address for address; 464 | 465 | function safeTransfer( 466 | IERC20 token, 467 | address to, 468 | uint256 value 469 | ) internal { 470 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 471 | } 472 | 473 | function safeTransferFrom( 474 | IERC20 token, 475 | address from, 476 | address to, 477 | uint256 value 478 | ) internal { 479 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 480 | } 481 | 482 | /** 483 | * @dev Deprecated. This function has issues similar to the ones found in 484 | * {IERC20-approve}, and its usage is discouraged. 485 | * 486 | * Whenever possible, use {safeIncreaseAllowance} and 487 | * {safeDecreaseAllowance} instead. 488 | */ 489 | function safeApprove( 490 | IERC20 token, 491 | address spender, 492 | uint256 value 493 | ) internal { 494 | // safeApprove should only be called when setting an initial allowance, 495 | // or when resetting it to zero. To increase and decrease it, use 496 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 497 | require( 498 | (value == 0) || (token.allowance(address(this), spender) == 0), 499 | "SafeERC20: approve from non-zero to non-zero allowance" 500 | ); 501 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 502 | } 503 | 504 | function safeIncreaseAllowance( 505 | IERC20 token, 506 | address spender, 507 | uint256 value 508 | ) internal { 509 | uint256 newAllowance = token.allowance(address(this), spender) + value; 510 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 511 | } 512 | 513 | function safeDecreaseAllowance( 514 | IERC20 token, 515 | address spender, 516 | uint256 value 517 | ) internal { 518 | unchecked { 519 | uint256 oldAllowance = token.allowance(address(this), spender); 520 | require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); 521 | uint256 newAllowance = oldAllowance - value; 522 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 523 | } 524 | } 525 | 526 | /** 527 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 528 | * on the return value: the return value is optional (but if data is returned, it must not be false). 529 | * @param token The token targeted by the call. 530 | * @param data The call data (encoded using abi.encode or one of its variants). 531 | */ 532 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 533 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 534 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 535 | // the target address contains contract code and also asserts for success in the low-level call. 536 | 537 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 538 | if (returndata.length > 0) { 539 | // Return data is optional 540 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 541 | } 542 | } 543 | } 544 | 545 | 546 | // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) 547 | /** 548 | * @dev Implementation of the {IERC20} interface. 549 | * 550 | * This implementation is agnostic to the way tokens are created. This means 551 | * that a supply mechanism has to be added in a derived contract using {_mint}. 552 | * For a generic mechanism see {ERC20PresetMinterPauser}. 553 | * 554 | * TIP: For a detailed writeup see our guide 555 | * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How 556 | * to implement supply mechanisms]. 557 | * 558 | * The default value of {decimals} is 18. To change this, you should override 559 | * this function so it returns a different value. 560 | * 561 | * We have followed general OpenZeppelin Contracts guidelines: functions revert 562 | * instead returning `false` on failure. This behavior is nonetheless 563 | * conventional and does not conflict with the expectations of ERC20 564 | * applications. 565 | * 566 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 567 | * This allows applications to reconstruct the allowance for all accounts just 568 | * by listening to said events. Other implementations of the EIP may not emit 569 | * these events, as it isn't required by the specification. 570 | * 571 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 572 | * functions have been added to mitigate the well-known issues around setting 573 | * allowances. See {IERC20-approve}. 574 | */ 575 | contract ERC20 is Context, IERC20, IERC20Metadata { 576 | mapping(address => uint256) private _balances; 577 | 578 | mapping(address => mapping(address => uint256)) private _allowances; 579 | 580 | uint256 private _totalSupply; 581 | 582 | string private _name; 583 | string private _symbol; 584 | 585 | /** 586 | * @dev Sets the values for {name} and {symbol}. 587 | * 588 | * All two of these values are immutable: they can only be set once during 589 | * construction. 590 | */ 591 | constructor(string memory name_, string memory symbol_) { 592 | _name = name_; 593 | _symbol = symbol_; 594 | } 595 | 596 | /** 597 | * @dev Returns the name of the token. 598 | */ 599 | function name() public view virtual override returns (string memory) { 600 | return _name; 601 | } 602 | 603 | /** 604 | * @dev Returns the symbol of the token, usually a shorter version of the 605 | * name. 606 | */ 607 | function symbol() public view virtual override returns (string memory) { 608 | return _symbol; 609 | } 610 | 611 | /** 612 | * @dev Returns the number of decimals used to get its user representation. 613 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 614 | * be displayed to a user as `5.05` (`505 / 10 ** 2`). 615 | * 616 | * Tokens usually opt for a value of 18, imitating the relationship between 617 | * Ether and Wei. This is the default value returned by this function, unless 618 | * it's overridden. 619 | * 620 | * NOTE: This information is only used for _display_ purposes: it in 621 | * no way affects any of the arithmetic of the contract, including 622 | * {IERC20-balanceOf} and {IERC20-transfer}. 623 | */ 624 | function decimals() public view virtual override returns (uint8) { 625 | return 18; 626 | } 627 | 628 | /** 629 | * @dev See {IERC20-totalSupply}. 630 | */ 631 | function totalSupply() public view virtual override returns (uint256) { 632 | return _totalSupply; 633 | } 634 | 635 | /** 636 | * @dev See {IERC20-balanceOf}. 637 | */ 638 | function balanceOf(address account) public view virtual override returns (uint256) { 639 | return _balances[account]; 640 | } 641 | 642 | /** 643 | * @dev See {IERC20-transfer}. 644 | * 645 | * Requirements: 646 | * 647 | * - `to` cannot be the zero address. 648 | * - the caller must have a balance of at least `amount`. 649 | */ 650 | function transfer(address to, uint256 amount) public virtual override returns (bool) { 651 | address owner = _msgSender(); 652 | _transfer(owner, to, amount); 653 | return true; 654 | } 655 | 656 | /** 657 | * @dev See {IERC20-allowance}. 658 | */ 659 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 660 | return _allowances[owner][spender]; 661 | } 662 | 663 | /** 664 | * @dev See {IERC20-approve}. 665 | * 666 | * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on 667 | * `transferFrom`. This is semantically equivalent to an infinite approval. 668 | * 669 | * Requirements: 670 | * 671 | * - `spender` cannot be the zero address. 672 | */ 673 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 674 | address owner = _msgSender(); 675 | _approve(owner, spender, amount); 676 | return true; 677 | } 678 | 679 | /** 680 | * @dev See {IERC20-transferFrom}. 681 | * 682 | * Emits an {Approval} event indicating the updated allowance. This is not 683 | * required by the EIP. See the note at the beginning of {ERC20}. 684 | * 685 | * NOTE: Does not update the allowance if the current allowance 686 | * is the maximum `uint256`. 687 | * 688 | * Requirements: 689 | * 690 | * - `from` and `to` cannot be the zero address. 691 | * - `from` must have a balance of at least `amount`. 692 | * - the caller must have allowance for ``from``'s tokens of at least 693 | * `amount`. 694 | */ 695 | function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { 696 | address spender = _msgSender(); 697 | _spendAllowance(from, spender, amount); 698 | _transfer(from, to, amount); 699 | return true; 700 | } 701 | 702 | /** 703 | * @dev Atomically increases the allowance granted to `spender` by the caller. 704 | * 705 | * This is an alternative to {approve} that can be used as a mitigation for 706 | * problems described in {IERC20-approve}. 707 | * 708 | * Emits an {Approval} event indicating the updated allowance. 709 | * 710 | * Requirements: 711 | * 712 | * - `spender` cannot be the zero address. 713 | */ 714 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 715 | address owner = _msgSender(); 716 | _approve(owner, spender, allowance(owner, spender) + addedValue); 717 | return true; 718 | } 719 | 720 | /** 721 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 722 | * 723 | * This is an alternative to {approve} that can be used as a mitigation for 724 | * problems described in {IERC20-approve}. 725 | * 726 | * Emits an {Approval} event indicating the updated allowance. 727 | * 728 | * Requirements: 729 | * 730 | * - `spender` cannot be the zero address. 731 | * - `spender` must have allowance for the caller of at least 732 | * `subtractedValue`. 733 | */ 734 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 735 | address owner = _msgSender(); 736 | uint256 currentAllowance = allowance(owner, spender); 737 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 738 | unchecked { 739 | _approve(owner, spender, currentAllowance - subtractedValue); 740 | } 741 | 742 | return true; 743 | } 744 | 745 | /** 746 | * @dev Moves `amount` of tokens from `from` to `to`. 747 | * 748 | * This internal function is equivalent to {transfer}, and can be used to 749 | * e.g. implement automatic token fees, slashing mechanisms, etc. 750 | * 751 | * Emits a {Transfer} event. 752 | * 753 | * Requirements: 754 | * 755 | * - `from` cannot be the zero address. 756 | * - `to` cannot be the zero address. 757 | * - `from` must have a balance of at least `amount`. 758 | */ 759 | function _transfer(address from, address to, uint256 amount) internal virtual { 760 | require(from != address(0), "ERC20: transfer from the zero address"); 761 | require(to != address(0), "ERC20: transfer to the zero address"); 762 | 763 | _beforeTokenTransfer(from, to, amount); 764 | 765 | uint256 fromBalance = _balances[from]; 766 | require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); 767 | unchecked { 768 | _balances[from] = fromBalance - amount; 769 | // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by 770 | // decrementing then incrementing. 771 | _balances[to] += amount; 772 | } 773 | 774 | emit Transfer(from, to, amount); 775 | 776 | _afterTokenTransfer(from, to, amount); 777 | } 778 | 779 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 780 | * the total supply. 781 | * 782 | * Emits a {Transfer} event with `from` set to the zero address. 783 | * 784 | * Requirements: 785 | * 786 | * - `account` cannot be the zero address. 787 | */ 788 | function _mint(address account, uint256 amount) internal virtual { 789 | require(account != address(0), "ERC20: mint to the zero address"); 790 | 791 | _beforeTokenTransfer(address(0), account, amount); 792 | 793 | _totalSupply += amount; 794 | unchecked { 795 | // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. 796 | _balances[account] += amount; 797 | } 798 | emit Transfer(address(0), account, amount); 799 | 800 | _afterTokenTransfer(address(0), account, amount); 801 | } 802 | 803 | /** 804 | * @dev Destroys `amount` tokens from `account`, reducing the 805 | * total supply. 806 | * 807 | * Emits a {Transfer} event with `to` set to the zero address. 808 | * 809 | * Requirements: 810 | * 811 | * - `account` cannot be the zero address. 812 | * - `account` must have at least `amount` tokens. 813 | */ 814 | function _burn(address account, uint256 amount) internal virtual { 815 | require(account != address(0), "ERC20: burn from the zero address"); 816 | 817 | _beforeTokenTransfer(account, address(0), amount); 818 | 819 | uint256 accountBalance = _balances[account]; 820 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 821 | unchecked { 822 | _balances[account] = accountBalance - amount; 823 | // Overflow not possible: amount <= accountBalance <= totalSupply. 824 | _totalSupply -= amount; 825 | } 826 | 827 | emit Transfer(account, address(0), amount); 828 | 829 | _afterTokenTransfer(account, address(0), amount); 830 | } 831 | 832 | /** 833 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 834 | * 835 | * This internal function is equivalent to `approve`, and can be used to 836 | * e.g. set automatic allowances for certain subsystems, etc. 837 | * 838 | * Emits an {Approval} event. 839 | * 840 | * Requirements: 841 | * 842 | * - `owner` cannot be the zero address. 843 | * - `spender` cannot be the zero address. 844 | */ 845 | function _approve(address owner, address spender, uint256 amount) internal virtual { 846 | require(owner != address(0), "ERC20: approve from the zero address"); 847 | require(spender != address(0), "ERC20: approve to the zero address"); 848 | 849 | _allowances[owner][spender] = amount; 850 | emit Approval(owner, spender, amount); 851 | } 852 | 853 | /** 854 | * @dev Updates `owner` s allowance for `spender` based on spent `amount`. 855 | * 856 | * Does not update the allowance amount in case of infinite allowance. 857 | * Revert if not enough allowance is available. 858 | * 859 | * Might emit an {Approval} event. 860 | */ 861 | function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { 862 | uint256 currentAllowance = allowance(owner, spender); 863 | if (currentAllowance != type(uint256).max) { 864 | require(currentAllowance >= amount, "ERC20: insufficient allowance"); 865 | unchecked { 866 | _approve(owner, spender, currentAllowance - amount); 867 | } 868 | } 869 | } 870 | 871 | /** 872 | * @dev Hook that is called before any transfer of tokens. This includes 873 | * minting and burning. 874 | * 875 | * Calling conditions: 876 | * 877 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 878 | * will be transferred to `to`. 879 | * - when `from` is zero, `amount` tokens will be minted for `to`. 880 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 881 | * - `from` and `to` are never both zero. 882 | * 883 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 884 | */ 885 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 886 | 887 | /** 888 | * @dev Hook that is called after any transfer of tokens. This includes 889 | * minting and burning. 890 | * 891 | * Calling conditions: 892 | * 893 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 894 | * has been transferred to `to`. 895 | * - when `from` is zero, `amount` tokens have been minted for `to`. 896 | * - when `to` is zero, `amount` of ``from``'s tokens have been burned. 897 | * - `from` and `to` are never both zero. 898 | * 899 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 900 | */ 901 | function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} 902 | } 903 | 904 | /// @title Dividend-Paying Token 905 | /// @author Roger Wu (https://github.com/roger-wu) 906 | /// @dev A mintable ERC20 token that allows anyone to pay and distribute ether 907 | /// to token holders as dividends and allows token holders to withdraw their dividends. 908 | /// Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code 909 | contract DividendStakingToken is ERC20 { 910 | 911 | constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} 912 | 913 | function _transfer(address from, address to, uint256 value) internal virtual override { 914 | require(false, "Cant transfer dividend token"); 915 | super._transfer(from, to, value); 916 | } 917 | 918 | function _mint(address account, uint256 value) internal override { 919 | super._mint(account, value); 920 | } 921 | 922 | function _burn(address account, uint256 value) internal override { 923 | super._burn(account, value); 924 | } 925 | 926 | function _setDividendBalance(address account, uint256 newBalance) internal { 927 | uint256 currentBalance = balanceOf(account); 928 | 929 | if(newBalance > currentBalance) { 930 | uint256 mintAmount = newBalance - currentBalance; 931 | _mint(account, mintAmount); 932 | } else if(newBalance < currentBalance) { 933 | uint256 burnAmount = currentBalance - newBalance; 934 | _burn(account, burnAmount); 935 | } 936 | } 937 | } 938 | 939 | interface IwPAWFlexibleStaking { 940 | function stakingAmount(address _user) external view returns (uint256); 941 | function isStakable(address _user) external view returns (bool); 942 | function forceWithdraw(address _user) external; 943 | } 944 | 945 | contract PawUniLPStake is Ownable, ReentrancyGuard, DividendStakingToken { 946 | using SafeERC20 for IERC20Metadata; 947 | 948 | // Accrued token per share 949 | uint256 public accTokenPerShare; 950 | 951 | uint256 public totalStaked; 952 | 953 | // The block number of the last pool update 954 | uint256 public lastRewardTimeStamp; 955 | 956 | // reward tokens created per second. 957 | uint256 public rewardPerTimeStamp; 958 | 959 | // The precision factor 960 | uint256 public PRECISION_FACTOR = uint256(10**12); 961 | 962 | // The reward token 963 | IERC20Metadata public PAWToken; 964 | 965 | // The reward token 966 | IERC20Metadata public wPAWToken; 967 | 968 | // The staked token 969 | IERC20Metadata public lpToken; 970 | 971 | // WPAW Staking 972 | address public WPAWStaking; 973 | 974 | // Info of each user that stakes tokens (lpToken) 975 | mapping(address => UserInfo) public userInfo; 976 | 977 | struct UserInfo { 978 | uint256 amount; // How many staked tokens the user has provided 979 | uint256 rewardDebt; // Reward debt 980 | } 981 | 982 | event Deposit(address indexed user, uint256 amount); 983 | event EmergencyWithdraw(address indexed user, uint256 amount); 984 | event NewRewardPerTimeStamp(uint256 rewardPerTimeStamp); 985 | event TokenRecovery(address indexed token, uint256 amount); 986 | event Withdraw(address indexed user, uint256 amount); 987 | event Claim(address indexed user, uint256 amount); 988 | 989 | /** 990 | * @notice Constructor 991 | */ 992 | constructor() DividendStakingToken("Paw Stake Tracker", "stPAWunilp") { 993 | lpToken = IERC20Metadata(0x428B03cCd51ee4FCFf7DF6c7DEaE4139A4B347eD); //UniSwap v2 PAW-ETH 994 | PAWToken = IERC20Metadata(0xDc63269eA166b70d4780b3A11F5C825C2b761B01); //PAW 995 | wPAWToken = IERC20Metadata(0xFF9E32AaF15953EC3F69FE899D220A705ce06dD0); //wPAW 996 | // Set the lastRewardTimeStamp as the current timestamp 997 | lastRewardTimeStamp = block.timestamp; 998 | 999 | rewardPerTimeStamp = 1 * (10**(wPAWToken.decimals())); // at the beginning, start with 1 wPAW per second 1000 | } 1001 | 1002 | /* 1003 | * @notice Deposit staked tokens and collect reward tokens (if any) 1004 | * @param _amount: amount to withdraw (in wPAWToken) 1005 | */ 1006 | function deposit(uint256 _amount) external nonReentrant { 1007 | UserInfo storage user = userInfo[msg.sender]; 1008 | 1009 | _updatePool(); 1010 | 1011 | if (user.amount > 0) { 1012 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1013 | if (pending > 0) { 1014 | wPAWToken.safeTransfer(address(msg.sender), pending); 1015 | } 1016 | } 1017 | 1018 | if (_amount > 0) { 1019 | totalStaked = totalStaked + _amount; 1020 | user.amount = user.amount + _amount; 1021 | _setDividendBalance(msg.sender, user.amount); 1022 | lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); 1023 | } 1024 | 1025 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1026 | 1027 | emit Deposit(msg.sender, _amount); 1028 | } 1029 | 1030 | /* 1031 | * @notice Withdraw staked tokens and collect reward tokens 1032 | * @param _amount: amount to withdraw (in wPAWToken) 1033 | */ 1034 | function withdraw(uint256 _amount) external nonReentrant { 1035 | UserInfo storage user = userInfo[msg.sender]; 1036 | require(user.amount >= _amount, "Amount to withdraw too high"); 1037 | 1038 | _updatePool(); 1039 | 1040 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1041 | 1042 | if (_amount > 0) { 1043 | totalStaked = totalStaked - _amount; 1044 | user.amount = user.amount - _amount; 1045 | _setDividendBalance(msg.sender, user.amount); 1046 | lpToken.safeTransfer(address(msg.sender), _amount); 1047 | } 1048 | 1049 | if (pending > 0) { 1050 | wPAWToken.safeTransfer(address(msg.sender), pending); 1051 | } 1052 | 1053 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1054 | 1055 | if(user.amount == 0 && WPAWStaking != address(0)){ 1056 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1057 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1058 | { 1059 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1060 | } 1061 | } 1062 | 1063 | emit Withdraw(msg.sender, _amount); 1064 | } 1065 | 1066 | 1067 | /* 1068 | * @notice Collect reward tokens 1069 | */ 1070 | function claim() external nonReentrant { 1071 | UserInfo storage user = userInfo[msg.sender]; 1072 | 1073 | _updatePool(); 1074 | 1075 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1076 | require (pending > 0, "No reward to claim"); 1077 | wPAWToken.safeTransfer(address(msg.sender), pending); 1078 | 1079 | user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR; 1080 | 1081 | emit Claim(msg.sender, pending); 1082 | } 1083 | 1084 | /* 1085 | * @notice Withdraw staked tokens without caring about rewards rewards 1086 | * @dev Needs to be for emergency. 1087 | */ 1088 | function emergencyWithdraw() external nonReentrant { 1089 | UserInfo storage user = userInfo[msg.sender]; 1090 | uint256 amountToTransfer = user.amount; 1091 | 1092 | uint256 pending = (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1093 | if(pending > 0){ 1094 | rewardTreasure = rewardTreasure + pending; 1095 | _updatePool(); 1096 | } 1097 | 1098 | user.amount = 0; 1099 | user.rewardDebt = 0; 1100 | totalStaked = totalStaked - amountToTransfer; 1101 | 1102 | if (amountToTransfer > 0) { 1103 | lpToken.safeTransfer(address(msg.sender), amountToTransfer); 1104 | } 1105 | _setDividendBalance(msg.sender, user.amount); 1106 | 1107 | if(user.amount == 0 && WPAWStaking != address(0)){ 1108 | if(IwPAWFlexibleStaking(WPAWStaking).stakingAmount(msg.sender) > 0 1109 | && !IwPAWFlexibleStaking(WPAWStaking).isStakable(msg.sender)) 1110 | { 1111 | IwPAWFlexibleStaking(WPAWStaking).forceWithdraw(msg.sender); 1112 | } 1113 | } 1114 | 1115 | emit EmergencyWithdraw(msg.sender, user.amount); 1116 | } 1117 | 1118 | /* 1119 | * @notice Stop rewards, withdraw all reward 1120 | * @dev Only callable by owner. Needs to be for emergency. 1121 | */ 1122 | function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { 1123 | require(_amount <= rewardTreasure, "Exceed withdrawable amount"); 1124 | wPAWToken.safeTransfer(address(msg.sender), _amount); 1125 | rewardTreasure = rewardTreasure - _amount; 1126 | 1127 | _updatePool(); 1128 | } 1129 | 1130 | /** 1131 | * @notice Allows the owner to recover tokens sent to the contract by mistake 1132 | * @param _token: token address 1133 | * @dev Callable by owner 1134 | */ 1135 | function recoverToken(address _token) external onlyOwner { 1136 | require(_token != address(lpToken), "Operations: Cannot recover staked token"); 1137 | require(_token != address(wPAWToken), "Operations: Cannot recover reward token"); 1138 | 1139 | uint256 balance = IERC20Metadata(_token).balanceOf(address(this)); 1140 | require(balance != 0, "Operations: Cannot recover zero balance"); 1141 | 1142 | IERC20Metadata(_token).safeTransfer(address(msg.sender), balance); 1143 | 1144 | emit TokenRecovery(_token, balance); 1145 | } 1146 | 1147 | /* 1148 | * @notice Update reward per second 1149 | * @dev Only callable by owner. 1150 | * @param _rewardPerTimeStamp: the reward per second 1151 | */ 1152 | function updateRewardPerTimeStamp(uint256 _rewardPerTimeStamp) external onlyOwner { 1153 | _updatePool(); 1154 | rewardPerTimeStamp = _rewardPerTimeStamp; 1155 | emit NewRewardPerTimeStamp(_rewardPerTimeStamp); 1156 | } 1157 | 1158 | /* 1159 | * @notice Set WPAW staking contract 1160 | * @dev Only callable by owner. Change APY. 1161 | */ 1162 | function setWPAWStakingContract(address _wPAWStaking) external onlyOwner { 1163 | WPAWStaking = _wPAWStaking; 1164 | } 1165 | 1166 | /* 1167 | * @notice View function to see pending reward on frontend. 1168 | * @param _user: user address 1169 | * @return Pending reward for a given user 1170 | */ 1171 | function pendingReward(address _user) external view returns (uint256) { 1172 | UserInfo storage user = userInfo[_user]; 1173 | if (block.timestamp > lastRewardTimeStamp && totalStaked != 0) { 1174 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1175 | uint256 estimatedReward = multiplier * rewardPerTimeStamp; 1176 | if(estimatedReward > rewardTreasure){ 1177 | estimatedReward = rewardTreasure; 1178 | } 1179 | uint256 adjustedTokenPerShare = accTokenPerShare + (estimatedReward * PRECISION_FACTOR) / totalStaked; 1180 | return (user.amount * adjustedTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1181 | } else { 1182 | return (user.amount * accTokenPerShare) / PRECISION_FACTOR - user.rewardDebt; 1183 | } 1184 | } 1185 | 1186 | /* 1187 | * @notice Update reward variables of the given pool to be up-to-date. 1188 | */ 1189 | function _updatePool() internal { 1190 | if (block.timestamp <= lastRewardTimeStamp) { 1191 | return; 1192 | } 1193 | 1194 | if (totalStaked == 0) { 1195 | lastRewardTimeStamp = block.timestamp; 1196 | return; 1197 | } 1198 | 1199 | uint256 multiplier = block.timestamp - lastRewardTimeStamp; 1200 | uint256 estimatedReward = multiplier * rewardPerTimeStamp; 1201 | uint256 realReward = _allocateReward(estimatedReward); 1202 | accTokenPerShare = accTokenPerShare + (realReward * PRECISION_FACTOR) / totalStaked; 1203 | lastRewardTimeStamp = block.timestamp; 1204 | } 1205 | 1206 | 1207 | uint256 public rewardTreasure; 1208 | uint256 public rewardAllocated; 1209 | function addRewardTreasure(uint256 _amount) external nonReentrant{ 1210 | require( _amount > 0 , "err _amount=0"); 1211 | uint256 oldBalance = wPAWToken.balanceOf(address(this)); 1212 | wPAWToken.safeTransferFrom(msg.sender, address(this), _amount); 1213 | uint256 newBalance = wPAWToken.balanceOf(address(this)); 1214 | uint256 realAmount = newBalance - oldBalance; 1215 | rewardTreasure = rewardTreasure + realAmount; 1216 | 1217 | _updatePool(); 1218 | } 1219 | 1220 | function _allocateReward(uint256 amount ) internal returns(uint256){ 1221 | uint256 allocatedAmount = amount; 1222 | if( amount >= rewardTreasure ){ 1223 | allocatedAmount = rewardTreasure; 1224 | } 1225 | rewardTreasure = rewardTreasure - allocatedAmount; 1226 | rewardAllocated = rewardAllocated + allocatedAmount; 1227 | return allocatedAmount; 1228 | } 1229 | 1230 | function estimateAPY() external view returns(uint256){ 1231 | if(totalStaked == 0) 1232 | return 0; 1233 | 1234 | uint256 PAWEquivalentOfTotalLPStaking = ((2 * PAWToken.balanceOf(address(lpToken))) * totalStaked) / lpToken.totalSupply(); 1235 | return (rewardPerTimeStamp * (365 days) * 100) / PAWEquivalentOfTotalLPStaking; 1236 | 1237 | } 1238 | } 1239 | --------------------------------------------------------------------------------