文件 1 的 1:YDR_eth_flat.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) {
this;
return msg.data;
}
}
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);
}
interface ILosslessController {
function beforeTransfer(address sender, address recipient, uint256 amount) external;
function beforeTransferFrom(address msgSender, address sender, address recipient, uint256 amount) external;
function beforeApprove(address sender, address spender, uint256 amount) external;
function beforeIncreaseAllowance(address msgSender, address spender, uint256 addedValue) external;
function beforeDecreaseAllowance(address msgSender, address spender, uint256 subtractedValue) external;
function afterApprove(address sender, address spender, uint256 amount) external;
function afterTransfer(address sender, address recipient, uint256 amount) external;
function afterTransferFrom(address msgSender, address sender, address recipient, uint256 amount) external;
function afterIncreaseAllowance(address sender, address spender, uint256 addedValue) external;
function afterDecreaseAllowance(address sender, address spender, uint256 subtractedValue) external;
}
contract LERC20 is Context, IERC20 {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
address public recoveryAdmin;
address private recoveryAdminCanditate;
bytes32 private recoveryAdminKeyHash;
address public admin;
uint256 public timelockPeriod;
uint256 public losslessTurnOffTimestamp;
bool public isLosslessTurnOffProposed;
bool public isLosslessOn = true;
ILosslessController private lossless;
event AdminChanged(address indexed previousAdmin, address indexed newAdmin);
event RecoveryAdminChangeProposed(address indexed candidate);
event RecoveryAdminChanged(address indexed previousAdmin, address indexed newAdmin);
event LosslessTurnOffProposed(uint256 turnOffDate);
event LosslessTurnedOff();
event LosslessTurnedOn();
constructor(uint256 totalSupply_, string memory name_, string memory symbol_, address admin_, address recoveryAdmin_, uint256 timelockPeriod_, address lossless_) {
_name = name_;
_symbol = symbol_;
admin = admin_;
_mint(admin, totalSupply_);
recoveryAdmin = recoveryAdmin_;
timelockPeriod = timelockPeriod_;
lossless = ILosslessController(lossless_);
}
modifier lssAprove(address spender, uint256 amount) {
if (isLosslessOn) {
lossless.beforeApprove(_msgSender(), spender, amount);
_;
lossless.afterApprove(_msgSender(), spender, amount);
} else {
_;
}
}
modifier lssTransfer(address recipient, uint256 amount) {
if (isLosslessOn) {
lossless.beforeTransfer(_msgSender(), recipient, amount);
_;
lossless.afterTransfer(_msgSender(), recipient, amount);
} else {
_;
}
}
modifier lssTransferFrom(address sender, address recipient, uint256 amount) {
if (isLosslessOn) {
lossless.beforeTransferFrom(_msgSender(),sender, recipient, amount);
_;
lossless.afterTransferFrom(_msgSender(), sender, recipient, amount);
} else {
_;
}
}
modifier lssIncreaseAllowance(address spender, uint256 addedValue) {
if (isLosslessOn) {
lossless.beforeIncreaseAllowance(_msgSender(), spender, addedValue);
_;
lossless.afterIncreaseAllowance(_msgSender(), spender, addedValue);
} else {
_;
}
}
modifier lssDecreaseAllowance(address spender, uint256 subtractedValue) {
if (isLosslessOn) {
lossless.beforeDecreaseAllowance(_msgSender(), spender, subtractedValue);
_;
lossless.afterDecreaseAllowance(_msgSender(), spender, subtractedValue);
} else {
_;
}
}
modifier onlyRecoveryAdmin() {
require(_msgSender() == recoveryAdmin, "LERC20: Must be recovery admin");
_;
}
function getAdmin() external view returns (address) {
return admin;
}
function transferOutBlacklistedFunds(address[] calldata from) external {
require(_msgSender() == address(lossless), "LERC20: Only lossless contract");
for (uint i = 0; i < from.length; i++) {
_transfer(from[i], address(lossless), balanceOf(from[i]));
}
}
function setLosslessAdmin(address newAdmin) public onlyRecoveryAdmin {
emit AdminChanged(admin, newAdmin);
admin = newAdmin;
}
function transferRecoveryAdminOwnership(address candidate, bytes32 keyHash) public onlyRecoveryAdmin {
recoveryAdminCanditate = candidate;
recoveryAdminKeyHash = keyHash;
emit RecoveryAdminChangeProposed(candidate);
}
function acceptRecoveryAdminOwnership(bytes memory key) external {
require(_msgSender() == recoveryAdminCanditate, "LERC20: Must be canditate");
require(keccak256(key) == recoveryAdminKeyHash, "LERC20: Invalid key");
emit RecoveryAdminChanged(recoveryAdmin, recoveryAdminCanditate);
recoveryAdmin = recoveryAdminCanditate;
}
function proposeLosslessTurnOff() public onlyRecoveryAdmin {
losslessTurnOffTimestamp = block.timestamp + timelockPeriod;
isLosslessTurnOffProposed = true;
emit LosslessTurnOffProposed(losslessTurnOffTimestamp);
}
function executeLosslessTurnOff() public onlyRecoveryAdmin {
require(isLosslessTurnOffProposed, "LERC20: TurnOff not proposed");
require(losslessTurnOffTimestamp <= block.timestamp, "LERC20: Time lock in progress");
isLosslessOn = false;
isLosslessTurnOffProposed = false;
emit LosslessTurnedOff();
}
function executeLosslessTurnOn() public onlyRecoveryAdmin {
isLosslessTurnOffProposed = false;
isLosslessOn = true;
emit LosslessTurnedOn();
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override lssTransfer(recipient, amount) 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 lssAprove(spender, amount) returns (bool) {
require((amount == 0) || (_allowances[_msgSender()][spender] == 0), "LERC20: Cannot change non zero allowance");
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override lssTransferFrom(sender, recipient, amount) returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "LERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual lssIncreaseAllowance(spender, addedValue) returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual lssDecreaseAllowance(spender, subtractedValue) returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "LERC20: decreased allowance below zero");
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "LERC20: transfer from the zero address");
require(recipient != address(0), "LERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "LERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "LERC20: mint to the zero address");
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "LERC20: approve from the zero address");
require(spender != address(0), "LERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
pragma solidity ^0.8.0;
library UniswapV2Library {
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');
}
function pairFor(bytes32 initCodeHash, address factory, address tokenA, address tokenB) internal pure returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(uint160(uint(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
initCodeHash
)))));
}
}
pragma solidity ^0.8.0;
library UniswapV3Library {
bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
struct PoolKey {
address token0;
address token1;
uint24 fee;
}
function getPoolKey(
address tokenA,
address tokenB,
uint24 fee
) internal pure returns (PoolKey memory) {
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
}
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
require(key.token0 < key.token1);
pool = address(
uint160(
uint256(
keccak256(
abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encode(key.token0, key.token1, key.fee)),
POOL_INIT_CODE_HASH
)
)
)
)
);
}
}
pragma solidity ^0.8.0;
interface IPLPS {
function LiquidityProtection_beforeTokenTransfer(
address _pool, address _from, address _to, uint _amount) external;
function isBlocked(address _pool, address _who) external view returns(bool);
function unblock(address _pool, address _who) external;
}
pragma solidity ^0.8.0;
abstract contract UsingLiquidityProtectionService {
bool private unProtected = false;
IPLPS private plps;
uint64 internal constant HUNDRED_PERCENT = 1e18;
bytes32 internal constant UNISWAP = 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f;
bytes32 internal constant PANCAKESWAP = 0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5;
bytes32 internal constant QUICKSWAP = 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f;
enum UniswapVersion {
V2,
V3
}
enum UniswapV3Fees {
_005,
_03,
_1
}
modifier onlyProtectionAdmin() {
protectionAdminCheck();
_;
}
constructor (address _plps) {
plps = IPLPS(_plps);
}
function LiquidityProtection_setLiquidityProtectionService(IPLPS _plps) external onlyProtectionAdmin() {
plps = _plps;
}
function token_transfer(address from, address to, uint amount) internal virtual;
function token_balanceOf(address holder) internal view virtual returns(uint);
function protectionAdminCheck() internal view virtual;
function uniswapVariety() internal pure virtual returns(bytes32);
function uniswapVersion() internal pure virtual returns(UniswapVersion);
function uniswapFactory() internal pure virtual returns(address);
function counterToken() internal pure virtual returns(address) {
return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
}
function uniswapV3Fee() internal pure virtual returns(UniswapV3Fees) {
return UniswapV3Fees._03;
}
function protectionChecker() internal view virtual returns(bool) {
return ProtectionSwitch_manual();
}
function lps() private view returns(IPLPS) {
return plps;
}
function LiquidityProtection_beforeTokenTransfer(address _from, address _to, uint _amount) internal virtual {
if (protectionChecker()) {
if (unProtected) {
return;
}
lps().LiquidityProtection_beforeTokenTransfer(getLiquidityPool(), _from, _to, _amount);
}
}
function revokeBlocked(address[] calldata _holders, address _revokeTo) external onlyProtectionAdmin() {
require(protectionChecker(), 'UsingLiquidityProtectionService: protection removed');
unProtected = true;
address pool = getLiquidityPool();
for (uint i = 0; i < _holders.length; i++) {
address holder = _holders[i];
if (lps().isBlocked(pool, holder)) {
token_transfer(holder, _revokeTo, token_balanceOf(holder));
}
}
unProtected = false;
}
function LiquidityProtection_unblock(address[] calldata _holders) external onlyProtectionAdmin() {
require(protectionChecker(), 'UsingLiquidityProtectionService: protection removed');
address pool = getLiquidityPool();
for (uint i = 0; i < _holders.length; i++) {
lps().unblock(pool, _holders[i]);
}
}
function disableProtection() external onlyProtectionAdmin() {
unProtected = true;
}
function isProtected() public view returns(bool) {
return not(unProtected);
}
function ProtectionSwitch_manual() internal view returns(bool) {
return isProtected();
}
function ProtectionSwitch_timestamp(uint _timestamp) internal view returns(bool) {
return not(passed(_timestamp));
}
function ProtectionSwitch_block(uint _block) internal view returns(bool) {
return not(blockPassed(_block));
}
function blockPassed(uint _block) internal view returns(bool) {
return _block < block.number;
}
function passed(uint _timestamp) internal view returns(bool) {
return _timestamp < block.timestamp;
}
function not(bool _condition) internal pure returns(bool) {
return !_condition;
}
function feeToUint24(UniswapV3Fees _fee) internal pure returns(uint24) {
if (_fee == UniswapV3Fees._03) return 3000;
if (_fee == UniswapV3Fees._005) return 500;
return 10000;
}
function getLiquidityPool() public view returns(address) {
if (uniswapVersion() == UniswapVersion.V2) {
return UniswapV2Library.pairFor(uniswapVariety(), uniswapFactory(), address(this), counterToken());
}
require(uniswapVariety() == UNISWAP, 'LiquidityProtection: uniswapVariety() can only be UNISWAP for V3.');
return UniswapV3Library.computeAddress(uniswapFactory(),
UniswapV3Library.getPoolKey(address(this), counterToken(), feeToUint24(uniswapV3Fee())));
}
}
pragma solidity ^0.8.0;
contract YDR is LERC20, UsingLiquidityProtectionService(0x5C3fB8fF925996da50f03836FD8734270f5016AC) {
constructor(uint256 totalSupply_, address admin_, address recoveryAdmin_, uint256 timelockPeriod_, address lossless_) LERC20(totalSupply_, "YDragon", "YDR", admin_, recoveryAdmin_, timelockPeriod_, lossless_) {
}
modifier onlyAdmin() {
require(admin == _msgSender(), "YDR: caller is not the admin");
_;
}
function burn(uint256 amount) external onlyAdmin {
_burn(_msgSender(), amount);
}
function token_transfer(address _from, address _to, uint _amount) internal override {
_transfer(_from, _to, _amount);
}
function token_balanceOf(address _holder) internal view override returns(uint) {
return balanceOf(_holder);
}
function protectionAdminCheck() internal view override onlyAdmin {}
function uniswapVariety() internal pure override returns(bytes32) {
return UNISWAP;
}
function uniswapVersion() internal pure override returns(UniswapVersion) {
return UniswapVersion.V3;
}
function uniswapFactory() internal pure override returns(address) {
return 0x1F98431c8aD98523631AE4a59f267346ea31F984;
}
function _beforeTokenTransfer(address _from, address _to, uint _amount) internal override {
super._beforeTokenTransfer(_from, _to, _amount);
LiquidityProtection_beforeTokenTransfer(_from, _to, _amount);
}
function protectionChecker() internal view override returns(bool) {
return ProtectionSwitch_timestamp(1630367999);
}
function counterToken() internal pure override returns(address) {
return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
}
}