ArchrLauncher
0x54db23feb1652a1c5294af7859ef09465f83f387
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
8,256 bytes
ABI entries
32
13 read · 6 write
License
none
Contract information
- Address
- 0x54db23feb1652a1c5294af7859ef09465f83f387
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x9008C9eE6e…13083680c6
- Creation tx
- 0x07aafe352c…3594a0b311
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (13)
FEE() → uint24
LP_BPS() → uint256
MAX_USABLE_TICK() → int24
MIN_USABLE_TICK() → int24
NPM() → address
SUPPLY() → uint256
TICK_SPACING() → int24
WETH() → address
launched() → bool
onERC721Received(address, address, uint256, bytes) → bytes4
owner() → address
pendingOwner() → address
renounceOwnership()
Events (3)
LaunchedOwnershipTransferStartedOwnershipTransferred
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_npm",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyLaunched",
"type": "error"
},
{
"inputs": [],
"name": "BadTick",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "PoolPrecreated",
"type": "error"
},
{
"inputs": [],
"name": "RenounceDisabled",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"inputs": [],
"name": "ZeroDeployer",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "pool",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "lpTokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "deployer",
"type": "address"
}
],
"name": "Launched",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferStarted",
"type": "event"
},
{
"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": "FEE",
"outputs": [
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LP_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_USABLE_TICK",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MIN_USABLE_TICK",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NPM",
"outputs": [
{
"internalType": "contract INonfungiblePositionManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TICK_SPACING",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "WETH",
"outputs": [
{
"internalType": "contract IWETH9",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "acceptOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "collect",
"outputs": [
{
"internalType": "uint256",
"name": "a0",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "a1",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "int24",
"name": "launchTick",
"type": "int24"
},
{
"internalType": "address",
"name": "deployer",
"type": "address"
}
],
"name": "launch",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "pool",
"type": "address"
},
{
"internalType": "uint256",
"name": "lpTokenId",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "launched",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "onERC721Received",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "sweepEth",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "t",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "sweepToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20 as IERC20OZ} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {TickMath} from "./lib/TickMath.sol";
import {RedditToken} from "./RedditToken.sol";
import {IERC20} from "./interfaces/IERC20.sol";
import {IWETH9} from "./interfaces/IWETH9.sol";
import {INonfungiblePositionManager} from "./interfaces/INonfungiblePositionManager.sol";
import {IUniswapV3Pool} from "./interfaces/IUniswapV3Pool.sol";
contract ArchrLauncher is Ownable2Step, IERC721Receiver {
using SafeERC20 for IERC20OZ;
INonfungiblePositionManager public immutable NPM;
IWETH9 public constant WETH = IWETH9(0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73);
uint24 public constant FEE = 10000;
int24 public constant TICK_SPACING = 200;
int24 public constant MIN_USABLE_TICK = -887200;
int24 public constant MAX_USABLE_TICK = 887200;
uint256 public constant SUPPLY = 1_000_000_000e18;
uint256 public constant LP_BPS = 7000;
bool public launched;
event Launched(address indexed token, address indexed pool, uint256 lpTokenId, address deployer);
error BadTick();
error AlreadyLaunched();
error PoolPrecreated();
error RenounceDisabled();
error ZeroDeployer();
constructor(address _npm) Ownable(msg.sender) {
NPM = INonfungiblePositionManager(_npm);
}
function launch(bytes32 salt, int24 launchTick, address deployer)
external
onlyOwner
returns (address token, address pool, uint256 lpTokenId)
{
if (launched) revert AlreadyLaunched();
if (deployer == address(0)) revert ZeroDeployer();
if (launchTick % TICK_SPACING != 0 || launchTick <= MIN_USABLE_TICK || launchTick >= MAX_USABLE_TICK) {
revert BadTick();
}
launched = true;
token = address(new RedditToken{salt: salt}("Archr", "ARCHR"));
require(token > address(WETH), "token must sort above WETH");
(pool, lpTokenId) = _initPoolAndMint(token, launchTick, deployer);
emit Launched(token, pool, lpTokenId, deployer);
}
function _initPoolAndMint(address token, int24 launchTick, address deployer)
internal
returns (address pool, uint256 lpTokenId)
{
pool =
NPM.createAndInitializePoolIfNecessary(address(WETH), token, FEE, TickMath.getSqrtRatioAtTick(launchTick));
(, int24 curTick,,,,,) = IUniswapV3Pool(pool).slot0();
if (curTick != launchTick) revert PoolPrecreated();
uint256 lpAmount = (SUPPLY * LP_BPS) / 10000;
IERC20(token).transfer(deployer, SUPPLY - lpAmount);
IERC20(token).approve(address(NPM), lpAmount);
(lpTokenId,,,) = NPM.mint(
INonfungiblePositionManager.MintParams({
token0: address(WETH),
token1: token,
fee: FEE,
tickLower: MIN_USABLE_TICK,
tickUpper: launchTick,
amount0Desired: 0,
amount1Desired: lpAmount,
amount0Min: 0,
amount1Min: 0,
recipient: address(this),
deadline: block.timestamp
})
);
}
function collect(uint256 id, address to) external onlyOwner returns (uint256 a0, uint256 a1) {
(a0, a1) = NPM.collect(INonfungiblePositionManager.CollectParams(id, to, type(uint128).max, type(uint128).max));
}
function sweepToken(address t, address to) external onlyOwner {
IERC20OZ(t).safeTransfer(to, IERC20OZ(t).balanceOf(address(this)));
}
function sweepEth(address to) external onlyOwner {
(bool ok,) = to.call{value: address(this).balance}("");
require(ok, "ETH transfer failed");
}
function renounceOwnership() public view override onlyOwner {
revert RenounceDisabled();
}
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
receive() external payable {}
}
Chain explorer5092msChain node86ms