Contract detail
LiquidityLauncher
LiquidityLauncher is a verified Robinhood Chain smart contract at 0x7cb6f233…6fc91fcd with 1 indexed transactions.
- Address type
- Smart contract
- Transactions
- 1
- First indexed block
- #28620336
- Latest indexed block
- #28620336
- Emitted events
- 1
- Verification
- Verified
- Compiler
- v0.8.26+commit.8a97fa7a
- Verification match
- partial
- Creation transaction
- 0x51502e1b…98f140bc
- Created at block
- #28619969
- Language
- solidity
- EVM version
- cancun
- License
- none
- Compiler optimization
- Enabled · 200 runs
Related activity
Transactions
| Transaction | Block | From | To | Value (wei) |
|---|---|---|---|---|
| 0xc6750c29…21d0ef65 | #28620336 | 0x6e9ac64d…cd2516b9 | 0x7cb6f233…6fc91fcd | 0 |
Verified contract
Contract source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Multicall} from "./Multicall.sol";
import {IAllowanceTransfer, Permit2Forwarder} from "./Permit2Forwarder.sol";
import {IStrategy} from "./interfaces/IStrategy.sol";
import {INativeStrategy} from "./interfaces/INativeStrategy.sol";
import {ILiquidityLauncher} from "./interfaces/ILiquidityLauncher.sol";
import {ITokenFactory} from "@uniswap/uerc20-factory/src/interfaces/ITokenFactory.sol";
import {Distribution} from "./types/Distribution.sol";
/// @title LiquidityLauncher
/// @notice A contract that allows users to create tokens and distribute them via one or more strategies
/// @custom:security-contact security@uniswap.org
contract LiquidityLauncher is ILiquidityLauncher, Multicall, Permit2Forwarder {
using SafeERC20 for IERC20;
constructor(IAllowanceTransfer _permit2) Permit2Forwarder(_permit2) {}
/// @inheritdoc ILiquidityLauncher
function createToken(
address factory,
string calldata name,
string calldata symbol,
uint8 decimals,
uint128 initialSupply,
address recipient,
bytes calldata tokenData
) external payable override returns (address tokenAddress) {
if (recipient == address(0)) {
revert RecipientCannotBeZeroAddress();
}
tokenAddress = ITokenFactory(factory)
.createToken(name, symbol, decimals, initialSupply, recipient, tokenData, getGraffiti(msg.sender));
emit TokenCreated(tokenAddress);
}
/// @inheritdoc ILiquidityLauncher
function depositToken(address token, uint160 amount) external payable override {
// Pulls tokens from msg.sender via permit2 so the deposit can be batched with `distributeToken`
// in a single multicall (preceded by a `permit` call for first-time approvals).
permit2.transferFrom(msg.sender, address(this), amount, token);
}
/// @inheritdoc ILiquidityLauncher
function distributeToken(address token, Distribution calldata distribution, bytes32 salt)
external
payable
override
{
// Approve the strategy to pull `distribution.amount` from this contract. The strategy is
// expected to consume the full allowance via `safeTransferFrom` inside `initializeDistribution`.
IERC20(token).forceApprove(distribution.strategy, distribution.amount);
IStrategy(distribution.strategy)
.initializeDistribution(
token, distribution.amount, distribution.configData, keccak256(abi.encode(msg.sender, salt))
);
// Reject strategies that pull less than the full approved amount.
if (IERC20(token).allowance(address(this), distribution.strategy) != 0) revert AllowanceNotFullyConsumed();
emit TokenDistributed(token, distribution.strategy, distribution.amount);
}
/// @inheritdoc ILiquidityLauncher
function distributeWithNative(address strategy, bytes calldata configData, bytes32 salt, uint256 nativeAmount)
external
payable
{
INativeStrategy(strategy).initializeWithNative{value: nativeAmount}(
configData, keccak256(abi.encode(msg.sender, salt))
);
emit TokenDistributed(address(0), strategy, nativeAmount);
}
/// @inheritdoc ILiquidityLauncher
function getGraffiti(address originalCreator) public pure returns (bytes32 graffiti) {
graffiti = keccak256(abi.encode(originalCreator));
}
}