QuiverV4HookDeployer
0x69a4415006d8cd32273d5bac1d62d2b2e196d854
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
11,033 bytes
ABI entries
2
0 read · 2 write
License
none
Contract information
- Address
- 0x69a4415006d8cd32273d5bac1d62d2b2e196d854
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x288BA0FDe7…DED6B5c829
- Creation tx
- 0xcf781e5a39…98008f1005
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (0)
No read functions
The ABI is unavailable or exposes no view functions.
ABI
[
{
"inputs": [
{
"internalType": "contract QuiverV4Hook",
"name": "hook",
"type": "address"
},
{
"internalType": "address",
"name": "launcher",
"type": "address"
},
{
"internalType": "address",
"name": "finalOwner",
"type": "address"
}
],
"name": "configure",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "address",
"name": "poolManager",
"type": "address"
},
{
"internalType": "address",
"name": "positionManager",
"type": "address"
},
{
"internalType": "address",
"name": "universalRouter",
"type": "address"
},
{
"internalType": "address",
"name": "quoter",
"type": "address"
},
{
"internalType": "address",
"name": "gate",
"type": "address"
}
],
"name": "deploy",
"outputs": [
{
"internalType": "contract QuiverV4Hook",
"name": "hook",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;
import { Script, console } from "forge-std/Script.sol";
import { QuiverV4Gate } from "../src/QuiverV4Gate.sol";
import { QuiverV4Hook } from "../src/QuiverV4Hook.sol";
import { QuiverV4PermaLock } from "../src/QuiverV4PermaLock.sol";
import { QuiverV4Launcher } from "../src/QuiverV4Launcher.sol";
contract QuiverV4HookDeployer {
function deploy(
bytes32 salt,
address poolManager,
address positionManager,
address universalRouter,
address quoter,
address gate
) external returns (QuiverV4Hook hook) {
hook = new QuiverV4Hook{ salt: salt }(poolManager, positionManager, universalRouter, quoter, gate);
}
function configure(QuiverV4Hook hook, address launcher, address finalOwner) external {
hook.setLauncher(launcher);
if (finalOwner != address(0)) hook.transferOwnership(finalOwner);
}
}
/// @notice Robinhood mainnet/fork deployment script. It does not broadcast unless explicitly invoked with --broadcast.
contract DeployV2 is Script {
address internal constant POOL_MANAGER = 0x8366a39CC670B4001A1121B8F6A443A643e40951;
address internal constant POSITION_MANAGER = 0x58daec3116aae6D93017bAAea7749052E8a04fA7;
address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
address internal constant WETH9 = 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73;
address internal constant V4_QUOTER = 0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94;
// Latest canonical Robinhood deployment registry address, verified against poolManager() before deployment.
address internal constant UNIVERSAL_ROUTER = 0x06AfBA43Fd06227fA663b0DAecF536f6EaA6bf99;
address internal constant TREASURY = 0x5B274D7675A5e7ceac443Fc3169fe901c4a555D4;
address internal constant OWNER_MAINNET = 0x7De8473b75BD562DDB33DD7d0731987127330304;
address internal constant OWNER_TESTNET = 0xaB526563d1c43F5E63f431D2eb0ab253E46D79D1;
uint256 internal constant MAINNET_CHAIN_ID = 4663;
uint256 internal constant TESTNET_FORK_CHAIN_ID = 44663;
uint160 internal constant REQUIRED_FLAGS = 0x2880;
uint160 internal constant ALL_HOOK_MASK = (1 << 14) - 1;
function run() external {
require(
block.chainid == MAINNET_CHAIN_ID || block.chainid == TESTNET_FORK_CHAIN_ID,
"expected Robinhood mainnet or local fork"
);
address gatekeeper = vm.envAddress("GATEKEEPER_ADDRESS");
uint256 platformFee = vm.envOr("PLATFORM_FEE_BPS", uint256(2_000));
require(platformFee <= 2_500, "platform fee exceeds 25%");
address finalOwner = block.chainid == MAINNET_CHAIN_ID ? OWNER_MAINNET : OWNER_TESTNET;
vm.startBroadcast();
QuiverV4Gate gate = new QuiverV4Gate(UNIVERSAL_ROUTER, WETH9, gatekeeper);
QuiverV4PermaLock permaLock = new QuiverV4PermaLock(POSITION_MANAGER, TREASURY, uint16(platformFee));
QuiverV4HookDeployer hookDeployer = new QuiverV4HookDeployer();
bytes32 salt = _mineHookSalt(address(hookDeployer), address(gate));
QuiverV4Hook hook =
hookDeployer.deploy(salt, POOL_MANAGER, POSITION_MANAGER, UNIVERSAL_ROUTER, V4_QUOTER, address(gate));
QuiverV4Launcher launcher = new QuiverV4Launcher(
POOL_MANAGER,
POSITION_MANAGER,
PERMIT2,
address(hook),
address(gate),
address(permaLock),
UNIVERSAL_ROUTER,
WETH9
);
hookDeployer.configure(hook, address(launcher), finalOwner);
gate.setLauncher(address(launcher));
gate.setHook(address(hook));
if (finalOwner != address(0)) {
gate.transferOwnership(finalOwner);
permaLock.transferOwnership(finalOwner);
launcher.transferOwnership(finalOwner);
}
vm.stopBroadcast();
console.log("QuiverV4Hook:", address(hook));
console.log("QuiverV4Gate:", address(gate));
console.log("QuiverV4PermaLock:", address(permaLock));
console.log("QuiverV4Launcher:", address(launcher));
console.logBytes32(salt);
}
function _mineHookSalt(address deployer, address gate) private pure returns (bytes32 salt) {
bytes32 initCodeHash = keccak256(
abi.encodePacked(
type(QuiverV4Hook).creationCode,
abi.encode(POOL_MANAGER, POSITION_MANAGER, UNIVERSAL_ROUTER, V4_QUOTER, gate)
)
);
for (uint256 i; i < 1_000_000; ++i) {
salt = bytes32(i);
address predicted =
address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initCodeHash)))));
if ((uint160(predicted) & ALL_HOOK_MASK) == REQUIRED_FLAGS) return salt;
}
revert("hook salt not found");
}
}
Chain explorer4076msChain node89ms