文件 1 的 1:wBEAR.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function getOwner() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address _owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
abstract contract Auth {
address internal owner;
mapping (address => bool) internal authorizations;
constructor(address _owner) {
owner = _owner;
authorizations[_owner] = true;
}
modifier onlyOwner() {
require(isOwner(msg.sender), "!OWNER"); _;
}
modifier authorized() {
require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
}
function authorize(address adr) public onlyOwner {
authorizations[adr] = true;
}
function unauthorize(address adr) public onlyOwner {
authorizations[adr] = false;
}
function isOwner(address account) public view returns (bool) {
return account == owner;
}
function isAuthorized(address adr) public view returns (bool) {
return authorizations[adr];
}
function transferOwnership(address payable adr) public onlyOwner {
owner = adr;
authorizations[adr] = true;
emit OwnershipTransferred(adr);
}
event OwnershipTransferred(address owner);
}
interface IDEXFactory {
function createPair(
address tokenA,
address tokenB
) external returns (address pair);
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
}
interface IDEXRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
interface IDividendDistributor {
function claimDividend(
address rewardAddress
) external;
}
contract wBEAR is IERC20, Auth, ReentrancyGuard {
using SafeMath for uint256;
uint256 public constant MASK = type(uint128).max;
address BASE = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address DEAD = 0x000000000000000000000000000000000000dEaD;
address ZERO = 0x0000000000000000000000000000000000000000;
address DEAD_NON_CHECKSUM = 0x000000000000000000000000000000000000dEaD;
address BURN = 0x000000000000000000000000000000000000dEaD;
address BEAR = 0xFd1Ce765af87Ac647059323f29a560E386A65492;
address TRACKER = 0xb80e2D2bfA134dA5bDDC69667Ff057dB4be293A5;
address TREASURY = 0xdbc85dF60C8E6cF056FF418EdCA44Be368da85D5;
address REWARD = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
IERC20 bear = IERC20(BEAR);
IDividendDistributor tracker = IDividendDistributor(tracker);
string constant _name = "Wrapped Bear Bucks";
string constant _symbol = "wBEAR";
uint8 constant _decimals = 9;
uint256 constant public maxSupply = 1000000000 * (10 ** _decimals);
uint256 _totalSupply = 0;
mapping (address => uint256) _balances;
mapping (address => mapping (address => uint256)) _allowances;
IDEXRouter public router;
address public pair;
bool public tradingEnabled = true;
bool public canEmergencySweep = true;
bool public hasEmergencySweeped = false;
bool public paused = false;
uint8 public mode = 0;
constructor () Auth(msg.sender) {
approve(BEAR, maxSupply);
_balances[msg.sender] = 0;
emit Transfer(address(0), msg.sender, 0);
}
function isTreasury(address account) public view returns (bool) {
return account == TREASURY;
}
modifier onlyTreasury() {
require(isTreasury(msg.sender), "!TREASURY"); _;
}
modifier onlyOwnerOrTreasury() {
require(isOwner(msg.sender) || isTreasury(msg.sender), "!OWNER && !TREASURY"); _;
}
function mint(
uint256 _amount
) external nonReentrant {
require(!hasEmergencySweeped, "This contract is no longer in use");
require(!paused, "This contract is paused");
require(bear.allowance(msg.sender, address(this)) >= _amount, "wBEAR allowance is too low");
require(maxSupply >= _amount, "The amount exceeds the supply");
bool _transfer = bear.transferFrom(msg.sender, address(this), _amount);
require(_transfer, "Failed to receive tokens");
_totalSupply += _amount;
_balances[msg.sender] += _amount;
emit Transfer(address(this), msg.sender, _amount);
if (mode != 0) {
_autoClaim();
}
}
function redeem(
uint256 _amount
) external nonReentrant {
require(!hasEmergencySweeped, "This contract is no longer in use");
require(!paused, "This contract is paused");
require(_balances[msg.sender] >= _amount, "Your wBEAR balance is too low");
require(_totalSupply >= _amount, "The contract BEAR balance is too low");
bool _transfer = bear.transfer(msg.sender, _amount);
require(_transfer, "Failed to send tokens");
_balances[msg.sender] -= _amount;
_totalSupply -= _amount;
emit Transfer(msg.sender, address(this), _amount);
if (mode != 0) {
_autoClaim();
}
}
function burn(
uint256 _amount
) external nonReentrant {
require(!hasEmergencySweeped, "This contract is no longer in use");
require(!paused, "This contract is paused");
require(_balances[msg.sender] >= _amount, "Your wBEAR balance is too low");
require(_totalSupply >= _amount, "The contract BEAR balance is too low");
bool _transfer = bear.transferFrom(address(this), BURN, _amount);
require(_transfer, "Failed to send tokens");
_balances[msg.sender] -= _amount;
_totalSupply -= _amount;
emit Transfer(msg.sender, address(this), _amount);
if (mode != 0) {
_autoClaim();
}
}
function _autoClaim() private {
if (mode == 1) {
_claimDividend(REWARD);
} else if (mode == 2) {
_claimAndSendDividend(REWARD);
}
}
function _claimDividend(
address _rewardAddress
) private {
tracker.claimDividend(_rewardAddress);
}
function _claimAndSendDividend(
address _rewardAddress
) private {
tracker.claimDividend(_rewardAddress);
IERC20(_rewardAddress).transferFrom(address(this), TREASURY, IERC20(_rewardAddress).balanceOf(address(this)));
}
function claimDividend(
address _rewardAddress
) external onlyTreasury {
tracker.claimDividend(_rewardAddress);
}
function claimAndSendDividend(
address _rewardAddress
) external onlyTreasury {
tracker.claimDividend(_rewardAddress);
IERC20(_rewardAddress).transferFrom(address(this), TREASURY, IERC20(_rewardAddress).balanceOf(address(this)));
}
function disableEmergencySweeping() external onlyOwner {
require(!hasEmergencySweeped, "This contract is no longer in use");
canEmergencySweep = false;
}
function emergencySweepCustom(
address _to,
uint256 _amount,
bool _disable
) external onlyOwner {
require(!hasEmergencySweeped, "This contract is no longer in use");
require(canEmergencySweep, "Emergency sweeping has been disabled");
bear.transfer(_to, _amount);
if (_disable) {
hasEmergencySweeped = true;
}
}
function emergencySweepFull(
address _to
) external onlyOwner {
require(!hasEmergencySweeped, "This contract is no longer in use");
require(canEmergencySweep, "Emergency sweeping has been disabled");
bear.transfer(_to, bear.balanceOf(address(this)));
hasEmergencySweeped = true;
}
function togglePaused(
bool _paused
) external onlyOwner {
paused = _paused;
}
receive() external payable {}
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function getOwner() external view override returns (address) { return owner; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(
address spender,
uint256 amount
) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function approveMax(
address spender
) external returns (bool) {
return approve(spender, _totalSupply);
}
function transfer(
address recipient,
uint256 amount
) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) external override returns (bool) {
if (_allowances[sender][msg.sender] != _totalSupply) {
_allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
}
return _transferFrom(sender, recipient, amount);
}
function _transferFrom(
address sender,
address recipient,
uint256 amount
) internal returns (bool) {
require(tradingEnabled, "Trading is currently disabled");
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return true;
}
function Sweep() external onlyOwner {
uint256 balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
function changeBASE(
address _BASE
) external onlyOwner {
BASE = _BASE;
}
function changeWETH(
address _WETH
) external onlyOwner {
WETH = _WETH;
}
function changeBURN(
address _BURN
) external onlyOwner {
BURN = _BURN;
}
function changeBEAR(
address _BEAR,
bool _approve
) external onlyOwner {
BEAR = _BEAR;
bear = IERC20(_BEAR);
if (_approve) {
approve(BEAR, maxSupply);
}
}
function changeTRACKER(
address _TRACKER
) external onlyOwner {
TRACKER = _TRACKER;
tracker = IDividendDistributor(_TRACKER);
}
function changeTREASURY(
address _TREASURY
) external onlyOwnerOrTreasury {
TREASURY = _TREASURY;
}
function changeREWARD(
address _REWARD
) external onlyOwnerOrTreasury {
REWARD = _REWARD;
}
function setMode(
uint8 _mode
) external onlyOwner {
require(_mode == 0 || _mode == 1 || _mode == 2, "Invalid mode");
mode = _mode;
}
function transferForeignToken(
address _token,
address _to
) external onlyOwner returns (bool _sent) {
if (_token == BEAR) {
require(canEmergencySweep, "Emergency sweeping has been disabled");
}
uint256 _contractBalance = IERC20(_token).balanceOf(address(this));
_sent = IERC20(_token).transfer(_to, _contractBalance);
}
function enableTrading() external authorized {
if (!tradingEnabled) {
tradingEnabled = true;
}
}
function toggleTrading(
bool _enabled
) external authorized {
tradingEnabled = _enabled;
}
function getCirculatingSupply() public view returns (uint256) {
return _totalSupply.sub(balanceOf(DEAD)).sub(balanceOf(ZERO));
}
}