编译器
0.8.19+commit.7dd6d404
文件 1 的 8:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 8:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from, address to, uint256 amount) external returns (bool);
}
文件 3 的 8:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 4 的 8:IQWN.sol
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
pragma solidity 0.8.19;
interface IQWN is IERC20Metadata {
function mint(address to_, uint256 amount_) external;
function burnFrom(address account_, uint256 amount_) external;
function burn(uint256 amount_) external;
function uniswapV2Pair() external view returns (address);
}
文件 5 的 8:IUniswapV2Router02.sol
pragma solidity 0.8.19;
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
}
文件 6 的 8:IWETH.sol
pragma solidity >=0.5.0;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function transferFrom(
address from,
address to,
uint value
) external returns (bool);
function withdraw(uint) external;
}
文件 7 的 8:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 8 的 8:Treasury.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interface/IQWN.sol";
import "./interface/IWETH.sol";
import "./interface/IUniswapV2Router02.sol";
contract QWNTreasury is Ownable {
IUniswapV2Router02 public immutable uniswapV2Router;
address public immutable QWN;
address public immutable WETH;
address public immutable uniswapV2Pair;
address public distributor;
uint256 public constant BACKING = 0.0001 ether;
uint256 public constant TIME_TO_WAIT = 1 days;
uint256 public constant MAX_REMOVAL = 10;
uint256 public lastRemoval;
constructor(address _QWN, address _WETH) {
QWN = _QWN;
WETH = _WETH;
uniswapV2Pair = IQWN(QWN).uniswapV2Pair();
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
uniswapV2Router = _uniswapV2Router;
}
receive() external payable {}
function mintQWN(address _to, uint256 _amount) external {
require(msg.sender == distributor, "msg.sender is not distributor");
IQWN(QWN).mint(_to, _amount);
}
function excessReserves() external view returns (uint256 value_) {
uint256 _balance = IERC20(WETH).balanceOf(address(this));
uint256 _value = (_balance * 1e9) / BACKING;
if (IERC20(QWN).totalSupply() > _value) return 0;
return (_value - IERC20(QWN).totalSupply());
}
function redeemQWN(uint256 _amount) external {
IQWN(QWN).burnFrom(msg.sender, _amount);
IERC20(WETH).transfer(msg.sender, (_amount * BACKING) / 1e9);
}
function wrapETH() external {
uint256 ethBalance_ = address(this).balance;
if (ethBalance_ > 0) IWETH(WETH).deposit{value: ethBalance_}();
}
function setDistributor(address _distributor) external onlyOwner {
require(distributor == address(0), "distributor already set");
distributor = _distributor;
}
function removeLiquidity(uint256 _amount) external onlyOwner {
uint256 balance = IERC20(uniswapV2Pair).balanceOf(address(this));
require(
_amount <= (balance * MAX_REMOVAL) / 100,
"Removing more than 10% of liquidity"
);
require(
block.timestamp > lastRemoval + TIME_TO_WAIT,
"Removed before 1 day lock"
);
lastRemoval = block.timestamp;
IERC20(uniswapV2Pair).approve(address(uniswapV2Router), _amount);
uniswapV2Router.removeLiquidityETHSupportingFeeOnTransferTokens(
QWN,
_amount,
0,
0,
address(this),
block.timestamp
);
_burnQWN();
}
function withdrawStuckToken(
uint256 _amount,
address _token
) external onlyOwner {
require(_token != WETH, "Can not withdraw WETH");
require(_token != uniswapV2Pair, "Can not withdraw LP");
IERC20(_token).transfer(msg.sender, _amount);
}
function _burnQWN() internal {
uint256 balance = IERC20(QWN).balanceOf(address(this));
IQWN(QWN).burn(balance);
}
}
{
"compilationTarget": {
"contracts/Treasury.sol": "QWNTreasury"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_QWN","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"BACKING","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REMOVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QWN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_TO_WAIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"excessReserves","outputs":[{"internalType":"uint256","name":"value_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRemoval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintQWN","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeemQWN","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_distributor","type":"address"}],"name":"setDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawStuckToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]