编译器
0.8.24+commit.e11b9ed9
文件 1 的 9:GenericErrors.sol
pragma solidity ^0.8.17;
error NotAContract();
文件 2 的 9:IERC20.sol
pragma solidity ^0.8.17;
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);
function decimals() external view returns (uint8);
}
文件 3 的 9:IOwnableTwoSteps.sol
pragma solidity ^0.8.17;
interface IOwnableTwoSteps {
enum Status {
NoOngoingTransfer,
TransferInProgress,
RenouncementInProgress
}
error NoOngoingTransferInProgress();
error NotOwner();
error RenouncementNotInProgress();
error TransferAlreadyInProgress();
error TransferNotInProgress();
error WrongPotentialOwner();
event CancelOwnershipTransfer();
event InitiateOwnershipRenouncement();
event InitiateOwnershipTransfer(address previousOwner, address potentialOwner);
event NewOwner(address newOwner);
}
文件 4 的 9:IWETH.sol
pragma solidity >=0.5.0;
interface IWETH {
function deposit() external payable;
function transfer(address dst, uint256 wad) external returns (bool);
function withdraw(uint256 wad) external;
}
文件 5 的 9:LowLevelERC20Transfer.sol
pragma solidity ^0.8.17;
import {IERC20} from "../interfaces/generic/IERC20.sol";
import {ERC20TransferFail, ERC20TransferFromFail} from "../errors/LowLevelErrors.sol";
import {NotAContract} from "../errors/GenericErrors.sol";
contract LowLevelERC20Transfer {
function _executeERC20TransferFrom(address currency, address from, address to, uint256 amount) internal {
if (currency.code.length == 0) {
revert NotAContract();
}
(bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transferFrom, (from, to, amount)));
if (!status) {
revert ERC20TransferFromFail();
}
if (data.length > 0) {
if (!abi.decode(data, (bool))) {
revert ERC20TransferFromFail();
}
}
}
function _executeERC20DirectTransfer(address currency, address to, uint256 amount) internal {
if (currency.code.length == 0) {
revert NotAContract();
}
(bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transfer, (to, amount)));
if (!status) {
revert ERC20TransferFail();
}
if (data.length > 0) {
if (!abi.decode(data, (bool))) {
revert ERC20TransferFail();
}
}
}
}
文件 6 的 9:LowLevelErrors.sol
pragma solidity ^0.8.17;
error ETHTransferFail();
error ERC20ApprovalFail();
error ERC20TransferFail();
error ERC20TransferFromFail();
error ERC721TransferFromFail();
error ERC1155SafeTransferFromFail();
error ERC1155SafeBatchTransferFromFail();
文件 7 的 9:LowLevelWETH.sol
pragma solidity ^0.8.17;
import {IWETH} from "../interfaces/generic/IWETH.sol";
contract LowLevelWETH {
function _transferETHAndWrapIfFailWithGasLimit(
address _WETH,
address _to,
uint256 _amount,
uint256 _gasLimit
) internal {
bool status;
assembly {
status := call(_gasLimit, _to, _amount, 0, 0, 0, 0)
}
if (!status) {
IWETH(_WETH).deposit{value: _amount}();
IWETH(_WETH).transfer(_to, _amount);
}
}
}
文件 8 的 9:OwnableTwoSteps.sol
pragma solidity ^0.8.17;
import {IOwnableTwoSteps} from "./interfaces/IOwnableTwoSteps.sol";
abstract contract OwnableTwoSteps is IOwnableTwoSteps {
address public owner;
address public potentialOwner;
Status public ownershipStatus;
modifier onlyOwner() {
_onlyOwner();
_;
}
constructor(address _owner) {
owner = _owner;
emit NewOwner(_owner);
}
function cancelOwnershipTransfer() external onlyOwner {
Status _ownershipStatus = ownershipStatus;
if (_ownershipStatus == Status.NoOngoingTransfer) {
revert NoOngoingTransferInProgress();
}
if (_ownershipStatus == Status.TransferInProgress) {
delete potentialOwner;
}
delete ownershipStatus;
emit CancelOwnershipTransfer();
}
function confirmOwnershipRenouncement() external onlyOwner {
if (ownershipStatus != Status.RenouncementInProgress) {
revert RenouncementNotInProgress();
}
delete owner;
delete ownershipStatus;
emit NewOwner(address(0));
}
function confirmOwnershipTransfer() external {
if (ownershipStatus != Status.TransferInProgress) {
revert TransferNotInProgress();
}
if (msg.sender != potentialOwner) {
revert WrongPotentialOwner();
}
owner = msg.sender;
delete ownershipStatus;
delete potentialOwner;
emit NewOwner(msg.sender);
}
function initiateOwnershipTransfer(address newPotentialOwner) external onlyOwner {
if (ownershipStatus != Status.NoOngoingTransfer) {
revert TransferAlreadyInProgress();
}
ownershipStatus = Status.TransferInProgress;
potentialOwner = newPotentialOwner;
emit InitiateOwnershipTransfer(msg.sender, newPotentialOwner);
}
function initiateOwnershipRenouncement() external onlyOwner {
if (ownershipStatus != Status.NoOngoingTransfer) {
revert TransferAlreadyInProgress();
}
ownershipStatus = Status.RenouncementInProgress;
emit InitiateOwnershipRenouncement();
}
function _onlyOwner() private view {
if (msg.sender != owner) revert NotOwner();
}
}
文件 9 的 9:TokenRescuer.sol
pragma solidity 0.8.24;
import {LowLevelERC20Transfer} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC20Transfer.sol";
import {LowLevelWETH} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelWETH.sol";
import {OwnableTwoSteps} from "@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract TokenRescuer is LowLevelERC20Transfer, LowLevelWETH, OwnableTwoSteps {
constructor() OwnableTwoSteps(0x2C64e6Ee1Dd9Fc2a0Db6a6B1aa2c3f163C7A2C78) {}
function withdrawToken(address currency) external onlyOwner {
_executeERC20DirectTransfer({
currency: currency,
to: msg.sender,
amount: IERC20(currency).balanceOf(address(this))
});
}
function withdrawETH() external onlyOwner {
_transferETHAndWrapIfFailWithGasLimit(
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,
msg.sender,
address(this).balance,
gasleft()
);
}
}
{
"compilationTarget": {
"contracts/TokenRescuer.sol": "TokenRescuer"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 888888
},
"remappings": [],
"viaIR": true
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC20TransferFail","type":"error"},{"inputs":[],"name":"NoOngoingTransferInProgress","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"RenouncementNotInProgress","type":"error"},{"inputs":[],"name":"TransferAlreadyInProgress","type":"error"},{"inputs":[],"name":"TransferNotInProgress","type":"error"},{"inputs":[],"name":"WrongPotentialOwner","type":"error"},{"anonymous":false,"inputs":[],"name":"CancelOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[],"name":"InitiateOwnershipRenouncement","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"potentialOwner","type":"address"}],"name":"InitiateOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"inputs":[],"name":"cancelOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmOwnershipRenouncement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initiateOwnershipRenouncement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPotentialOwner","type":"address"}],"name":"initiateOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipStatus","outputs":[{"internalType":"enum IOwnableTwoSteps.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"potentialOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]