Transaction Hash:
Block:
19062429 at Jan-22-2024 12:59:35 PM +UTC
Transaction Fee:
0.001924309561878702 ETH
$4.86
Gas Used:
129,587 Gas / 14.849557146 Gwei
Emitted Events:
148 |
ChaingeWrappedToken.Transfer( from=0xb11814F6e0A67a928B2F8A0BAE32871dCf73d835, to=[Sender] 0x267942a89bd2ed9d31e7ae25e83bfd8c9a1e9e37, value=52631464692 )
|
149 |
ChaingeWrappedToken.Approval( owner=0xb11814F6e0A67a928B2F8A0BAE32871dCf73d835, spender=[Receiver] TokenFarm, value=1674761077778 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x112b0862...41f36C582 | |||||
0x12D800f7...6500F8b07
Miner
| 0.14234904263469914 Eth | 0.14236200133469914 Eth | 0.0000129587 | ||
0x267942a8...c9A1e9E37 |
0.00895652937282738 Eth
Nonce: 155
|
0.007032219810948678 Eth
Nonce: 156
| 0.001924309561878702 | ||
0x52433781...b633c2aB5 |
Execution Trace
TokenFarm.claimRewards( _pid=0 )
-
ChaingeWrappedToken.transferFrom( sender=0xb11814F6e0A67a928B2F8A0BAE32871dCf73d835, recipient=0x267942a89bD2ED9d31E7ae25E83Bfd8c9A1e9E37, amount=52631464692 ) => ( True )
claimRewards[TokenFarm (ln:445)]
poolLength[TokenFarm (ln:446)]
claimableRewards[TokenFarm (ln:452)]
poolLength[TokenFarm (ln:388)]
add[TokenFarm (ln:402)]
transferFrom[TokenFarm (ln:456)]
File 1 of 2: TokenFarm
File 2 of 2: ChaingeWrappedToken
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; library SafeMathInt { int256 private constant MIN_INT256 = int256(1) << 255; int256 private constant MAX_INT256 = ~(int256(1) << 255); function mul(int256 a, int256 b) internal pure returns (int256) { int256 c = a * b; require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256)); require((b == 0) || (c / b == a), 'mul overflow'); return c; } function div(int256 a, int256 b) internal pure returns (int256) { require(b != -1 || a != MIN_INT256); return a / b; } function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), 'sub overflow'); return c; } function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), 'add overflow'); return c; } function abs(int256 a) internal pure returns (int256) { require(a != MIN_INT256, 'abs overflow'); return a < 0 ? -a : a; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, 'SafeMath: subtraction overflow'); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, 'parameter 2 can not be 0'); return a % b; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } } interface IBEP20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); } contract Ownable { address private _owner; event OwnershipRenounced(address indexed previousOwner); event TransferOwnerShip(address indexed previousOwner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); constructor() { _owner = msg.sender; } function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(msg.sender == _owner, 'Not owner'); _; } function renounceOwnership() public onlyOwner { emit OwnershipRenounced(_owner); _owner = address(0); } function transferOwnership(address newOwner) public onlyOwner { emit TransferOwnerShip(newOwner); _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal { require(newOwner != address(0), 'Owner can not be 0'); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } contract TokenFarm is Ownable { using SafeMath for uint256; using SafeMathInt for int256; address public tokenWallet; struct UserInfo { uint256 amount; // How many tokens the user has provided. uint256 stakingTime; // The time at which the user staked tokens. uint256 rewardClaimed; // The amount of reward claimed by the user. } struct PoolInfo { address tokenAddress; address rewardTokenAddress; uint256 maxPoolSize; uint256 currentPoolSize; uint256 maxContribution; uint256 minContribution; uint256 apy; // it is in 1000 times, so 1000 means 100% uint256 emergencyFees; // it is the fees in percentage, final fees is emergencyFees/1000 uint256 minLockDays; uint256 totalRewardsClaimed; // total rewards claimed by the users bool poolType; // true for public staking, false for whitelist staking bool poolActive; } // Info of each pool. PoolInfo[] public poolInfo; uint256 [] public rewardTimes; bool lock_= false; uint256 public totalRewardsClaimed = 0; // Info of each user that stakes tokens. mapping (uint256 => mapping (address => UserInfo)) public userInfo; mapping (uint256 => mapping (address => bool)) public whitelistedAddress; mapping (uint256 => uint256) public rewardAmount; mapping (uint256 => uint256) public rewardCurrentPoolSize; event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); constructor (address _wallet) { require(_wallet != address(0), "Invalid wallet address"); tokenWallet = _wallet; } modifier lock { require(!lock_, "Process is locked"); lock_ = true; _; lock_ = false; } function poolLength() public view returns (uint256) { return poolInfo.length; } function addPool (address _tokenAddress, address _rewardTokenAddress, uint256 _maxPoolSize, uint256 _maxContribution,uint256 _emergencyFee, uint256 _minContribution, uint256 _apy, uint256 _minLockDays, bool _poolType, bool _poolActive) public onlyOwner { poolInfo.push(PoolInfo({ tokenAddress: _tokenAddress, rewardTokenAddress: _rewardTokenAddress, maxPoolSize: _maxPoolSize, currentPoolSize: 0, minContribution: _minContribution, maxContribution: _maxContribution, apy: _apy, emergencyFees: _emergencyFee, minLockDays: _minLockDays, poolType: _poolType, poolActive: _poolActive, totalRewardsClaimed: 0 })); } function updateMaxPoolSize (uint256 _pid, uint256 _maxPoolSize) public onlyOwner{ require (_pid < poolLength(), "Invalid pool ID"); require (_maxPoolSize >= poolInfo[_pid].currentPoolSize, "Cannot reduce the max size below the current pool size"); poolInfo[_pid].maxPoolSize = _maxPoolSize; } function updateMaxContribution (uint256 _pid, uint256 _maxContribution) public onlyOwner{ require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].maxContribution = _maxContribution; } function updateEmergencyFees (uint256 _pid, uint256 _emergencyFees) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); if (poolInfo[_pid].currentPoolSize > 0){ require (_emergencyFees <= poolInfo[_pid].emergencyFees, "You can't increase the emergency fees when people started staking"); } poolInfo[_pid].emergencyFees = _emergencyFees; } function updateRewardToken(address _rewardTokenAddress, uint256 _pid) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].rewardTokenAddress = _rewardTokenAddress; } function updateToken(address _tokenAddress, uint256 _pid) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].tokenAddress = _tokenAddress; } function updateTokenWallet(address _wallet) public onlyOwner { require (_wallet != address(0), "Invalid wallet address"); tokenWallet = _wallet; } function updateMinLockDays (uint256 _pid, uint256 _lockDays) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); require (poolInfo[_pid].currentPoolSize == 0, "Cannot change lock time after people started staking"); poolInfo[_pid].minLockDays = _lockDays; } function updateApy (uint256 _pid, uint256 _apy) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].apy = _apy; } function updatePoolType (uint256 _pid, bool _poolType) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].poolType = _poolType; } function updatePoolActive (uint256 _pid, bool _poolActive) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].poolActive = _poolActive; } function updateMinContribution (uint256 _pid, uint256 _minContribution) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); poolInfo[_pid].minContribution = _minContribution; } function addWhitelist (uint256 _pid, address [] memory _whitelistAddresses) public onlyOwner { require (_pid < poolLength(), "Invalid pool ID"); uint256 length = _whitelistAddresses.length; require (length<= 200, "Can add only 200 wl at a time"); for (uint256 i = 0; i < length; i++){ address _whitelistAddress = _whitelistAddresses[i]; whitelistedAddress[_pid][_whitelistAddress] = true; } } function addReward (uint256 _pid, uint256 _amount) public onlyOwner { rewardTimes.push(block.timestamp); rewardAmount[block.timestamp] = _amount; rewardCurrentPoolSize[block.timestamp] = poolInfo[_pid].currentPoolSize; address _rewardTokenAddress = poolInfo[_pid].rewardTokenAddress; IBEP20 rewardToken = IBEP20 (_rewardTokenAddress); bool success = rewardToken.transferFrom(msg.sender, tokenWallet, _amount); require(success, "Transfer failed"); } function emergencyLock (bool _lock) public onlyOwner { lock_ = _lock; } function stakeTokens (uint256 _pid, uint256 _amount) public lock { require (_pid < poolLength(), "Invalid pool ID"); require (poolInfo[_pid].poolActive, "Pool is not active"); require (_amount >= (userInfo[_pid][msg.sender].amount).add(poolInfo[_pid].minContribution), "Amount is less than min contribution"); require (poolInfo[_pid].currentPoolSize.add(_amount) <= poolInfo[_pid].maxPoolSize, "Staking exceeds max pool size"); require ((userInfo[_pid][msg.sender].amount).add(_amount) <= poolInfo[_pid].maxContribution , "Max Contribution exceeds"); if (poolInfo[_pid].poolType == false){ require (whitelistedAddress[_pid][msg.sender], "You are not whitelisted for this pool"); } // Sending the claimable tokens to the user if (claimableRewards(_pid, msg.sender) > 0){ claimRewards(_pid); } address _tokenAddress = poolInfo[_pid].tokenAddress; IBEP20 token = IBEP20 (_tokenAddress); bool success = token.transferFrom(msg.sender, tokenWallet, _amount); require (success, "Transfer From failed. Please approve the token"); poolInfo[_pid].currentPoolSize = (poolInfo[_pid].currentPoolSize).add(_amount); uint256 _stakingTime = block.timestamp; _amount = _amount.add(userInfo[_pid][msg.sender].amount); uint256 _rewardClaimed = 0; userInfo[_pid][msg.sender] = UserInfo ({ amount: _amount, stakingTime: _stakingTime, rewardClaimed: _rewardClaimed }); } function claimableRewards (uint256 _pid, address _user) public view returns (uint256) { require (_pid < poolLength(), "Invalid pool ID"); uint256 _stakingTime = userInfo[_pid][_user].stakingTime; uint256 lockDays = (block.timestamp - _stakingTime) / 1 days; if(lockDays < poolInfo[_pid].minLockDays) return 0; if (userInfo[_pid][_user].amount == 0) return 0; uint256 _claimableReward = 0; for (uint256 i = 0; i < rewardTimes.length; i++){ uint256 _rewardTime = rewardTimes[i]; uint256 _rewardAmount = rewardAmount[_rewardTime]; uint256 _rewardCurrentPoolSize = rewardCurrentPoolSize[_rewardTime]; if (_rewardTime > _stakingTime){ uint256 _refundValue = ((userInfo[_pid][_user].amount * _rewardAmount) / (_rewardCurrentPoolSize)); _claimableReward = _claimableReward.add(_refundValue); } } if (userInfo[_pid][_user].rewardClaimed >= _claimableReward) return 0; return _claimableReward - userInfo[_pid][_user].rewardClaimed; } function claimableNativeRewards (uint256 _pid, address _user) public view returns (uint256) { require (_pid < poolLength(), "Invalid pool ID"); uint256 lockDays = (block.timestamp - userInfo[_pid][_user].stakingTime) / 1 days; uint256 _refundValue = ((userInfo[_pid][_user].amount * poolInfo[_pid].apy * lockDays) / (1000 * 365)); return _refundValue; } function unstakeTokens (uint256 _pid) public lock { require (_pid < poolLength(), "Invalid pool ID"); require (userInfo[_pid][msg.sender].amount > 0 , "You don't have any staked tokens"); require (userInfo[_pid][msg.sender].stakingTime > 0 , "You don't have any staked tokens"); // check the min lock days is passed or not uint256 lockDays = (block.timestamp - userInfo[_pid][msg.sender].stakingTime) / 1 days; require (lockDays >= poolInfo[_pid].minLockDays, "You can't unstake before min lock days"); address _tokenAddress = poolInfo[_pid].tokenAddress; IBEP20 token = IBEP20 (_tokenAddress); address _rewardTokenAddress = poolInfo[_pid].rewardTokenAddress; IBEP20 rewardToken = IBEP20 (_rewardTokenAddress); uint256 _amount = userInfo[_pid][msg.sender].amount; uint256 _refundValue = claimableRewards(_pid, msg.sender); uint256 _nativeReward = claimableNativeRewards(_pid, msg.sender); userInfo[_pid][msg.sender].rewardClaimed += _refundValue; poolInfo[_pid].currentPoolSize = (poolInfo[_pid].currentPoolSize).sub(userInfo[_pid][msg.sender].amount); poolInfo[_pid].totalRewardsClaimed += _refundValue; userInfo[_pid][msg.sender].amount = 0; userInfo[_pid][msg.sender].rewardClaimed = 0; bool success1 = token.transferFrom(tokenWallet,msg.sender, _amount); bool success2 = token.transferFrom(tokenWallet,msg.sender, _nativeReward); bool success3 = rewardToken.transferFrom(tokenWallet,msg.sender, _refundValue); require(success1 && success2 && success3, "Transfer failed"); } function claimRewards (uint256 _pid) public lock { require (_pid < poolLength(), "Invalid pool ID"); require (userInfo[_pid][msg.sender].amount > 0 , "You don't have any staked tokens"); require (userInfo[_pid][msg.sender].stakingTime > 0 , "You don't have any staked tokens"); address _rewardTokenAddress = poolInfo[_pid].rewardTokenAddress; IBEP20 rewardToken = IBEP20 (_rewardTokenAddress); uint256 _refundValue = claimableRewards(_pid, msg.sender); require(_refundValue > 0, "No rewards to claim"); // check if there is any reward to claim userInfo[_pid][msg.sender].rewardClaimed += _refundValue; poolInfo[_pid].totalRewardsClaimed += _refundValue; bool success = rewardToken.transferFrom(tokenWallet,msg.sender, _refundValue); require(success, "Transfer failed"); } // emergency withdraw function function emergencyWithdraw (uint256 _pid) public lock { require (_pid < poolLength(), "Invalid pool ID"); require (userInfo[_pid][msg.sender].amount > 0 , "You don't have any staked tokens"); require (userInfo[_pid][msg.sender].stakingTime > 0 , "You don't have any staked tokens"); address _tokenAddress = poolInfo[_pid].tokenAddress; IBEP20 token = IBEP20 (_tokenAddress); uint256 _amount = userInfo[_pid][msg.sender].amount; userInfo[_pid][msg.sender].amount = 0; userInfo[_pid][msg.sender].rewardClaimed = 0; poolInfo[_pid].currentPoolSize = (poolInfo[_pid].currentPoolSize).sub(_amount); uint256 afterDeductAmount = _amount.sub((_amount * poolInfo[_pid].emergencyFees) / 1000); bool success = token.transferFrom(tokenWallet,msg.sender, afterDeductAmount); require(success, "Transfer failed"); } // this function is to withdraw BNB sent to this address by mistake function withdrawEth () external onlyOwner returns (bool) { uint256 balance = address(this).balance; (bool success, ) = payable(msg.sender).call{ value: balance }(""); return success; } // this function is to withdraw BEP20 tokens sent to this address by mistake function withdrawBEP20 (address _tokenAddress) external onlyOwner returns (bool) { IBEP20 token = IBEP20(_tokenAddress); uint256 balance = token.balanceOf(address(this)); bool success = token.transfer(msg.sender, balance); return success; } }
File 2 of 2: ChaingeWrappedToken
//SPDX-License-Identifier: MIT pragma solidity =0.6.6; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } interface IERC20 { function totalSupply() external view returns (uint256); 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 Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; return msg.data; } } abstract contract Pausable is Context { event Paused(address account); event Unpaused(address account); bool private _paused; constructor () internal { _paused = false; } function paused() public view returns (bool) { return _paused; } modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; constructor (string memory name_, string memory symbol_, uint8 decimals_) public { _name = name_; _symbol = symbol_; _decimals = decimals_; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns (uint8) { return _decimals; } function totalSupply() public view override returns (uint256) { return _totalSupply; } function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } abstract contract ERC20Pausable is ERC20, Pausable { function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(!paused(), "ERC20Pausable: token transfer while paused"); } } contract ChaingeWrappedToken is ERC20Pausable { address public owner; address public controller; constructor(string memory name, string memory symbol,uint8 decimal) public ERC20(name,symbol, decimal) { owner = msg.sender; controller = msg.sender; } modifier onlyOwner() { require(msg.sender == owner,"only owner"); _; } modifier onlyController() { require(msg.sender == controller || msg.sender == owner ,"only controller"); _; } function pause() public onlyController { _pause(); } function unpause() public onlyController { _unpause(); } function setOwner(address newOwner) public onlyOwner { owner = newOwner; } function setController(address newController) public onlyOwner { controller = newController; } function mint(address account, uint256 amount) public whenNotPaused onlyController { _mint(account, amount); } function burn(address account , uint256 amount) public whenNotPaused onlyController { _burn(account,amount); } }