// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { ReentrancyGuardTransient } from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
import { IBondingCurve } from "./interfaces/IBondingCurve.sol";
import { IToken } from "./interfaces/IToken.sol";
import { IMigrator } from "./interfaces/IMigrator.sol";
/// @title BondingCurve
/// @notice Per-token virtual-reserve constant-product market with atomic graduation to a
/// downstream pool. Fees accrue to pull-claim buckets; rounding always favours the
/// protocol over the trader.
contract BondingCurve is IBondingCurve, ReentrancyGuardTransient {
using SafeERC20 for IERC20;
using Address for address payable;
/* -------------------------------------------------------------------------- */
/* ERRORS */
/* -------------------------------------------------------------------------- */
error ZeroAddress();
error ZeroAmount();
error Slippage(uint256 expected, uint256 actual);
error CurveGraduated();
error CurveNotGraduated();
error CurveInsolvent();
error TotalFeeTooHigh(uint256 bps);
error InvalidConfig();
error OnlyCreator();
error InvalidSplits();
error RedirectsAlreadyLocked();
error CreatorWindowActive(uint64 endsAt);
/* -------------------------------------------------------------------------- */
/* CONSTANTS */
/* -------------------------------------------------------------------------- */
uint256 public constant BPS = 10_000;
uint256 public constant MAX_FEE_BPS = 200;
/// @inheritdoc IBondingCurve
uint256 public constant override MAX_CREATOR_SPLITS = 10;
/// @dev Bounded gas stipend for ETH payouts: a malicious recipient cannot grief a claim
/// by burning unbounded gas in their receive/fallback.
uint256 private constant _PAYOUT_GAS = 30_000;
/* -------------------------------------------------------------------------- */
/* IMMUTABLES */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
address public immutable override TOKEN;
/// @inheritdoc IBondingCurve
address public immutable override FACTORY;
/// @inheritdoc IBondingCurve
uint256 public immutable override CURVE_SUPPLY;
/// @inheritdoc IBondingCurve
uint256 public immutable override MIGRATION_SUPPLY;
/// @inheritdoc IBondingCurve
uint256 public immutable override GRADUATION_ETH_TARGET;
/// @inheritdoc IBondingCurve
uint256 public immutable override GRADUATION_FEE_WEI;
/// @inheritdoc IBondingCurve
uint256 public immutable override CREATOR_GRADUATION_REWARD_WEI;
/// @inheritdoc IBondingCurve
uint96 public immutable override PROTOCOL_FEE_BPS;
/// @inheritdoc IBondingCurve
uint96 public immutable override CREATOR_FEE_BPS;
/// @inheritdoc IBondingCurve
address public immutable override PROTOCOL_FEE_RECIPIENT;
/// @inheritdoc IBondingCurve
address public immutable override MIGRATOR;
/// @inheritdoc IBondingCurve
bool public immutable override CASHBACK_MODE;
/// @inheritdoc IBondingCurve
uint64 public immutable override CREATOR_WINDOW_END;
/// @inheritdoc IBondingCurve
address public override CREATOR;
/// @dev Initial constant-product `k`. All post-trade reserves satisfy `V_t · V_e ≤ _K`.
uint256 private immutable _K;
/* -------------------------------------------------------------------------- */
/* STATE */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
uint256 public override virtualTokenReserves;
/// @inheritdoc IBondingCurve
uint256 public override virtualEthReserves;
/// @inheritdoc IBondingCurve
uint256 public override realTokensSold;
/// @inheritdoc IBondingCurve
uint256 public override realEthIn;
/// @inheritdoc IBondingCurve
bool public override graduated;
/// @inheritdoc IBondingCurve
uint256 public override creatorOwed;
/// @inheritdoc IBondingCurve
uint256 public override protocolOwed;
CreatorSplit[] private _creatorSplits;
/// @inheritdoc IBondingCurve
bool public override feeRedirectsLocked;
/// @inheritdoc IBondingCurve
bool public override firstBuyDone;
/* -------------------------------------------------------------------------- */
/* CONSTRUCTOR */
/* -------------------------------------------------------------------------- */
struct InitParams {
address token;
address creator;
address factory;
address protocolFeeRecipient;
address migrator;
uint256 virtualTokenReserves;
uint256 virtualEthReserves;
uint256 curveSupply;
uint256 migrationSupply;
uint256 graduationEthTarget;
uint256 graduationFeeWei;
uint256 creatorGraduationRewardWei;
uint96 protocolFeeBps;
uint96 creatorFeeBps;
bool cashbackMode;
/// @dev Window length in seconds; 0 disables the gate. Stored as a duration (not an
/// absolute end timestamp) so the curve's CREATE2 init-code hash is independent
/// of `block.timestamp` and remains vanity-mineable.
uint64 creatorWindowDuration;
}
constructor(InitParams memory p) {
if (
p.token == address(0) || p.creator == address(0) || p.factory == address(0)
|| p.protocolFeeRecipient == address(0) || p.migrator == address(0)
) revert ZeroAddress();
if (
p.virtualTokenReserves == 0 || p.virtualEthReserves == 0 || p.curveSupply == 0 || p.migrationSupply == 0
|| p.graduationEthTarget == 0
) revert InvalidConfig();
// Insolvency guard: V_t < curveSupply would let the curve hit V_t = 0 before fully selling.
if (p.virtualTokenReserves < p.curveSupply) revert InvalidConfig();
uint256 totalBps = uint256(p.protocolFeeBps) + uint256(p.creatorFeeBps);
if (totalBps > MAX_FEE_BPS) revert TotalFeeTooHigh(totalBps);
TOKEN = p.token;
FACTORY = p.factory;
PROTOCOL_FEE_RECIPIENT = p.protocolFeeRecipient;
MIGRATOR = p.migrator;
CURVE_SUPPLY = p.curveSupply;
MIGRATION_SUPPLY = p.migrationSupply;
GRADUATION_ETH_TARGET = p.graduationEthTarget;
GRADUATION_FEE_WEI = p.graduationFeeWei;
CREATOR_GRADUATION_REWARD_WEI = p.creatorGraduationRewardWei;
PROTOCOL_FEE_BPS = p.protocolFeeBps;
CREATOR_FEE_BPS = p.creatorFeeBps;
CREATOR = p.creator;
CASHBACK_MODE = p.cashbackMode;
CREATOR_WINDOW_END = p.creatorWindowDuration == 0 ? 0 : uint64(block.timestamp) + p.creatorWindowDuration;
_K = p.virtualTokenReserves * p.virtualEthReserves;
virtualTokenReserves = p.virtualTokenReserves;
virtualEthReserves = p.virtualEthReserves;
}
/* -------------------------------------------------------------------------- */
/* TRADING */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
function buy(uint256 minTokensOut, address receiver) external payable nonReentrant returns (uint256 tokensOut) {
if (graduated) revert CurveGraduated();
if (msg.value == 0) revert ZeroAmount();
if (receiver == address(0)) revert ZeroAddress();
// First-buy window closes on the EARLIER of (a) the time deadline or (b) the first
// successful buy. `firstBuyDone` is sticky — a later sell does not re-arm the window.
uint64 windowEnd = CREATOR_WINDOW_END;
if (windowEnd != 0 && block.timestamp < windowEnd && !firstBuyDone) {
if (msg.sender != CREATOR) revert CreatorWindowActive(windowEnd);
}
(uint256 tokensDelivered, uint256 ethInUsedForCurve, uint256 ethFee, uint256 ethRefund) =
_simulateBuy(msg.value);
// Reject zero-token deliveries (1-wei dust where the entire input becomes fee).
if (tokensDelivered == 0) revert ZeroAmount();
if (tokensDelivered < minTokensOut) revert Slippage(minTokensOut, tokensDelivered);
tokensOut = tokensDelivered;
virtualEthReserves += ethInUsedForCurve;
virtualTokenReserves = _K / virtualEthReserves;
realTokensSold += tokensDelivered;
realEthIn += ethInUsedForCurve;
if (!firstBuyDone) firstBuyDone = true;
_accrueFees(ethFee);
emit Buy(msg.sender, ethInUsedForCurve, ethFee, tokensDelivered, virtualTokenReserves, virtualEthReserves);
IERC20(TOKEN).safeTransfer(receiver, tokensDelivered);
if (ethRefund != 0) payable(msg.sender).sendValue(ethRefund);
// Atomic graduation: terminal trade pays the migration gas in the same tx.
if (realTokensSold >= CURVE_SUPPLY || realEthIn >= GRADUATION_ETH_TARGET) {
_graduate();
}
}
/// @inheritdoc IBondingCurve
function sell(uint256 tokensIn, uint256 minEthOut, address receiver)
external
nonReentrant
returns (uint256 ethOut)
{
if (graduated) revert CurveGraduated();
if (tokensIn == 0) revert ZeroAmount();
if (receiver == address(0)) revert ZeroAddress();
(uint256 ethDelivered, uint256 ethFee, uint256 ethGross) = _simulateSell(tokensIn);
// Defensive — constant-product math guarantees `ethGross <= realEthIn`.
if (ethGross > realEthIn) revert CurveInsolvent();
if (ethDelivered < minEthOut) revert Slippage(minEthOut, ethDelivered);
ethOut = ethDelivered;
virtualTokenReserves += tokensIn;
virtualEthReserves = _K / virtualTokenReserves;
realTokensSold -= tokensIn;
realEthIn -= ethGross;
_accrueFees(ethFee);
emit Sell(msg.sender, tokensIn, ethFee, ethDelivered, virtualTokenReserves, virtualEthReserves);
IERC20(TOKEN).safeTransferFrom(msg.sender, address(this), tokensIn);
payable(receiver).sendValue(ethDelivered);
}
/* -------------------------------------------------------------------------- */
/* GRADUATION */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
/// @dev Defensive fallback. The terminal {buy} auto-graduates atomically, so this entry
/// reverts in normal flow (`CurveGraduated`). Retained for safety against unexpected
/// states where the threshold is met but graduation didn't run.
function graduate() external nonReentrant {
_graduate();
}
function _graduate() private {
if (graduated) revert CurveGraduated();
if (realTokensSold < CURVE_SUPPLY && realEthIn < GRADUATION_ETH_TARGET) {
revert CurveNotGraduated();
}
graduated = true;
uint256 ethForPool = realEthIn;
uint256 grad = GRADUATION_FEE_WEI;
// Cashback mode opts the creator out of all fee income, including the graduation bonus.
uint256 reward = CASHBACK_MODE ? 0 : CREATOR_GRADUATION_REWARD_WEI;
if (grad + reward > ethForPool) revert InvalidConfig();
ethForPool -= grad + reward;
// Route fee + bonus through the pull-claim buckets so a hostile recipient can't wedge
// graduation itself.
if (grad != 0) protocolOwed += grad;
if (reward != 0) creatorOwed += reward;
IToken(TOKEN).finalizeGraduation();
IERC20(TOKEN).forceApprove(MIGRATOR, MIGRATION_SUPPLY);
(bytes32 poolId, uint256 lpTokenId) = IMigrator(MIGRATOR).migrate{ value: ethForPool }(
TOKEN, CREATOR, MIGRATION_SUPPLY, CREATOR_FEE_BPS, PROTOCOL_FEE_BPS
);
IERC20(TOKEN).forceApprove(MIGRATOR, 0);
emit Graduated(TOKEN, poolId, ethForPool, MIGRATION_SUPPLY, lpTokenId);
}
/* -------------------------------------------------------------------------- */
/* CREATOR ROUTING */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
/// @dev `nonReentrant` is defensive; this function makes no external calls today.
function setCreator(address newCreator) external nonReentrant {
if (msg.sender != CREATOR) revert OnlyCreator();
if (feeRedirectsLocked) revert RedirectsAlreadyLocked();
if (newCreator == address(0)) revert ZeroAddress();
address old = CREATOR;
CREATOR = newCreator;
_lockRedirects();
emit CreatorChanged(old, newCreator);
}
/// @inheritdoc IBondingCurve
function setCreatorSplits(CreatorSplit[] calldata splits) external nonReentrant {
if (msg.sender != CREATOR) revert OnlyCreator();
if (feeRedirectsLocked) revert RedirectsAlreadyLocked();
uint256 n = splits.length;
if (n > MAX_CREATOR_SPLITS) revert InvalidSplits();
delete _creatorSplits;
if (n == 0) {
_lockRedirects();
emit CreatorSplitsChanged(0);
return;
}
uint256 totalBps;
for (uint256 i; i < n; ++i) {
CreatorSplit calldata s = splits[i];
if (s.recipient == address(0) || s.bps == 0) revert InvalidSplits();
totalBps += s.bps;
_creatorSplits.push(s);
}
if (totalBps != BPS) revert InvalidSplits();
_lockRedirects();
emit CreatorSplitsChanged(n);
}
/// @dev One-shot lock; first successful call to {setCreator} or {setCreatorSplits} flips
/// this and both subsequently revert.
function _lockRedirects() private {
if (!feeRedirectsLocked) {
feeRedirectsLocked = true;
emit FeeRedirectsLocked();
}
}
/* -------------------------------------------------------------------------- */
/* FEE CLAIMS */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
function claimCreatorFees() external nonReentrant {
uint256 owed = creatorOwed;
if (owed == 0) return;
creatorOwed = 0;
// Snapshot splits to memory before iterating so a recipient (bounded to _PAYOUT_GAS)
// cannot perturb iteration if the redirect-lock invariant is ever weakened. The
// last-row residual sweep below depends on every CreatorSplit.bps > 0 AND
// Σbps == BPS; both are enforced by setCreatorSplits.
CreatorSplit[] memory splits = _creatorSplits;
uint256 n = splits.length;
uint256 failed;
uint256 distributed;
if (n == 0) {
if (!_trySend(CREATOR, owed)) failed = owed;
} else {
for (uint256 i; i < n; ++i) {
CreatorSplit memory s = splits[i];
uint256 share = (i == n - 1) ? (owed - distributed) : Math.mulDiv(owed, s.bps, BPS);
distributed += share;
if (!_trySend(s.recipient, share)) failed += share;
}
}
if (failed != 0) creatorOwed += failed;
emit CreatorFeesClaimed(owed - failed, failed);
}
/// @inheritdoc IBondingCurve
function claimProtocolFees() external nonReentrant {
uint256 owed = protocolOwed;
if (owed == 0) return;
protocolOwed = 0;
bool ok = _trySend(PROTOCOL_FEE_RECIPIENT, owed);
if (!ok) protocolOwed += owed;
emit ProtocolFeesClaimed(PROTOCOL_FEE_RECIPIENT, owed, ok);
}
/* -------------------------------------------------------------------------- */
/* VIEWS */
/* -------------------------------------------------------------------------- */
/// @inheritdoc IBondingCurve
function quoteBuy(uint256 ethIn) external view returns (uint256 tokensOut, uint256 feePaid) {
if (ethIn == 0) return (0, 0);
(uint256 delivered,, uint256 ethFee,) = _simulateBuy(ethIn);
return (delivered, ethFee);
}
/// @inheritdoc IBondingCurve
function quoteSell(uint256 tokensIn) external view returns (uint256 ethOut, uint256 feePaid) {
if (tokensIn == 0) return (0, 0);
(uint256 delivered, uint256 ethFee,) = _simulateSell(tokensIn);
return (delivered, ethFee);
}
/// @inheritdoc IBondingCurve
function creatorSplitCount() external view returns (uint256) {
return _creatorSplits.length;
}
/// @inheritdoc IBondingCurve
function creatorSplitAt(uint256 i) external view returns (address recipient, uint96 bps) {
CreatorSplit memory s = _creatorSplits[i];
return (s.recipient, s.bps);
}
/* -------------------------------------------------------------------------- */
/* INTERNAL HELPERS */
/* -------------------------------------------------------------------------- */
function _effectiveTotalBps() private view returns (uint256) {
return CASHBACK_MODE ? uint256(PROTOCOL_FEE_BPS) : uint256(PROTOCOL_FEE_BPS) + uint256(CREATOR_FEE_BPS);
}
/// @dev Simulate a buy. `ethAfterFee` is clamped by the smaller of:
/// 1. ETH needed to drain the remaining curve supply
/// 2. ETH needed to reach `GRADUATION_ETH_TARGET`
/// Unused ETH is refunded; fee is re-derived from the consumed amount on partial fills.
function _simulateBuy(uint256 ethIn)
private
view
returns (uint256 tokensDelivered, uint256 ethInUsedForCurve, uint256 ethFee, uint256 ethRefund)
{
uint256 totalBps = _effectiveTotalBps();
ethFee = Math.mulDiv(ethIn, totalBps, BPS, Math.Rounding.Ceil);
uint256 ethAfterFee = ethIn - ethFee;
uint256 remainingCurve = CURVE_SUPPLY - realTokensSold;
uint256 ethCapFromSupply;
if (remainingCurve == 0) {
ethCapFromSupply = 0;
} else {
uint256 vtAtCap = virtualTokenReserves - remainingCurve;
uint256 veAtCap = Math.mulDiv(_K, 1, vtAtCap, Math.Rounding.Ceil);
ethCapFromSupply = veAtCap - virtualEthReserves;
}
uint256 ethCapFromTarget = GRADUATION_ETH_TARGET > realEthIn ? GRADUATION_ETH_TARGET - realEthIn : 0;
uint256 effectiveCap = ethCapFromSupply < ethCapFromTarget ? ethCapFromSupply : ethCapFromTarget;
if (ethAfterFee <= effectiveCap) {
uint256 newVe = virtualEthReserves + ethAfterFee;
uint256 newVt = _K / newVe;
tokensDelivered = virtualTokenReserves - newVt;
return (tokensDelivered, ethAfterFee, ethFee, 0);
}
// Partial fill: snap to the binding cap and refund the unused ETH. Fee is re-derived
// from the consumed amount so traders aren't charged on refunded principal.
ethInUsedForCurve = effectiveCap;
uint256 finalVe = virtualEthReserves + ethInUsedForCurve;
uint256 finalVt = _K / finalVe;
tokensDelivered = virtualTokenReserves - finalVt;
// Defensive — integer division can under-shoot the supply cap by at most 1 unit.
if (tokensDelivered > remainingCurve) tokensDelivered = remainingCurve;
if (totalBps != 0) {
uint256 gross = Math.mulDiv(ethInUsedForCurve, BPS, BPS - totalBps, Math.Rounding.Ceil);
if (gross > ethIn) gross = ethIn;
ethFee = gross - ethInUsedForCurve;
ethRefund = ethIn - gross;
} else {
ethFee = 0;
ethRefund = ethIn - ethInUsedForCurve;
}
}
function _simulateSell(uint256 tokensIn)
private
view
returns (uint256 ethDelivered, uint256 ethFee, uint256 ethGross)
{
uint256 newVt = virtualTokenReserves + tokensIn;
uint256 newVe = _K / newVt;
ethGross = virtualEthReserves - newVe;
uint256 totalBps = _effectiveTotalBps();
ethFee = Math.mulDiv(ethGross, totalBps, BPS, Math.Rounding.Ceil);
ethDelivered = ethGross - ethFee;
}
function _accrueFees(uint256 totalFee) private {
if (totalFee == 0) return;
if (CASHBACK_MODE) {
protocolOwed += totalFee;
emit FeesAccrued(0, totalFee);
return;
}
uint256 totalBps = uint256(PROTOCOL_FEE_BPS) + uint256(CREATOR_FEE_BPS);
if (totalBps == 0) return;
uint256 creatorCut = Math.mulDiv(totalFee, CREATOR_FEE_BPS, totalBps);
uint256 protocolCut = totalFee - creatorCut;
creatorOwed += creatorCut;
protocolOwed += protocolCut;
emit FeesAccrued(creatorCut, protocolCut);
}
function _trySend(address to, uint256 amount) private returns (bool ok) {
if (amount == 0) return true;
(ok,) = payable(to).call{ value: amount, gas: _PAYOUT_GAS }("");
}
/// @dev Reject unsolicited ETH. Contract balance must equal
/// `realEthIn + creatorOwed + protocolOwed` at all times.
receive() external payable {
revert();
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "p",
"type": "tuple",
"components": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "creator",
"type": "address",
"internalType": "address"
},
{
"name": "factory",
"type": "address",
"internalType": "address"
},
{
"name": "protocolFeeRecipient",
"type": "address",
"internalType": "address"
},
{
"name": "migrator",
"type": "address",
"internalType": "address"
},
{
"name": "virtualTokenReserves",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "virtualEthReserves",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "curveSupply",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "migrationSupply",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "graduationEthTarget",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "graduationFeeWei",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "creatorGraduationRewardWei",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "protocolFeeBps",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "creatorFeeBps",
"type": "uint96",
"internalType": "uint96"
},
{
"name": "cashbackMode",
"type": "bool",
"internalType": "bool"
},
{
"name": "creatorWindowDuration",
"type": "uint64",
"internalType": "uint64"
}
],
"internalType": "struct BondingCurve.InitParams"
}
],
"stateMutability": "nonpayable"
},
{
"name": "CreatorWindowActive",
"type": "error",
"inputs": [
{
"name": "endsAt",
"type": "uint64",
"internalType": "uint64"
}
]
},
{
"name": "CurveGraduated",
"type": "error",
"inputs": []
},
{
"name": "CurveInsolvent",
"type": "error",
"inputs": []
},
{
"name": "CurveNotGraduated",
"type": "error",
"inputs": []
},
{
"name": "FailedCall",
"type": "error",
"inputs": []
},
{
"name": "InsufficientBalance",
"type": "error",
"inputs": [
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "InvalidConfig",
"type": "error",
"inputs": []
},
{
"name": "InvalidSplits",
"type": "error",
"inputs": []
},
{
"name": "OnlyCreator",
"type": "error",
"inputs": []
},
{
"name": "RedirectsAlreadyLocked",
"type": "error",
"inputs": []
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "Slippage",
"type": "error",
"inputs": [
{
"name": "expected",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "actual",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "TotalFeeTooHigh",
"type": "error",
"inputs": [
{
"name": "bps",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "ZeroAmount",
"type": "error",
"inputs": []
},
{
"name": "Buy",
"type": "event",
"inputs": [
{
"name": "buyer",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "ethIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "ethFee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "tokensOut",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "virtualTokenReserves",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "virtualEthReserves",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "CreatorChanged",
"type": "event",
"inputs": [
{
"name": "oldCreator",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newCreator",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "CreatorFeesClaimed",
"type": "event",
"inputs": [
{
"name": "totalClaimed",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "failedAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "CreatorSplitsChanged",
"type": "event",
"inputs": [
{
"name": "newLength",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeeRedirectsLocked",
"type": "event",
"inputs": [],
"anonymous": false
},
{
"name": "FeesAccrued",
"type": "event",
"inputs": [
{
"name": "creatorAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "protocolAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Graduated",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "poolId",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "ethSeeded",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "tokensSeeded",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "lpTokenId",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ProtocolFeesClaimed",
"type": "event",
"inputs": [
{
"name": "recipient",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "ok",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "Sell",
"type": "event",
"inputs": [
{
"name": "seller",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokensIn",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "ethFee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "ethOut",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "virtualTokenReserves",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "virtualEthReserves",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "CASHBACK_MODE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "CREATOR",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "CREATOR_FEE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint96",
"internalType": "uint96"
}
],
"stateMutability": "view"
},
{
"name": "CREATOR_GRADUATION_REWARD_WEI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "CREATOR_WINDOW_END",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "CURVE_SUPPLY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "FACTORY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "GRADUATION_ETH_TARGET",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "GRADUATION_FEE_WEI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_CREATOR_SPLITS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_FEE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MIGRATION_SUPPLY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MIGRATOR",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "PROTOCOL_FEE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint96",
"internalType": "uint96"
}
],
"stateMutability": "view"
},
{
"name": "PROTOCOL_FEE_RECIPIENT",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "TOKEN",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "buy",
"type": "function",
"inputs": [
{
"name": "minTokensOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "tokensOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "claimCreatorFees",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimProtocolFees",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "creatorOwed",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "creatorSplitAt",
"type": "function",
"inputs": [
{
"name": "i",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint96",
"internalType": "uint96"
}
],
"stateMutability": "view"
},
{
"name": "creatorSplitCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "feeRedirectsLocked",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "firstBuyDone",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "graduate",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "graduated",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "protocolOwed",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "quoteBuy",
"type": "function",
"inputs": [
{
"name": "ethIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokensOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "feePaid",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "quoteSell",
"type": "function",
"inputs": [
{
"name": "tokensIn",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "ethOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "feePaid",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "realEthIn",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "realTokensSold",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "sell",
"type": "function",
"inputs": [
{
"name": "tokensIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minEthOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "ethOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "setCreator",
"type": "function",
"inputs": [
{
"name": "newCreator",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setCreatorSplits",
"type": "function",
"inputs": [
{
"name": "splits",
"type": "tuple[]",
"components": [
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint96",
"internalType": "uint96"
}
],
"internalType": "struct IBondingCurve.CreatorSplit[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "virtualEthReserves",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "virtualTokenReserves",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x6080806040526004361015610015575b505b5f80fd5b5f3560e01c9081630e5f024214610dae575080631655bc6214610d915780631e4c729214610d57578063249d39e914610d3b5780632753568814610d015780632dd3100014610cbd578063351fee4614610c9d57806338eb46fc14610c635780633f51601814610ba65780633fbfc26214610b8b5780634a7d036914610b6b5780634beb394c14610b4d5780635b1d8d9714610b305780636652a30714610ae55780636ad5566014610ac85780636f96000a14610aab578063730143c614610a6757806374ca191214610a235780637deb60251461072f57806382bfefc8146106eb57806389db9cc3146106ce57806397d5fd08146106945780639ecd747214610650578063a22079a1146105eb578063a64190c4146105c1578063b2a39d09146105a4578063be37822814610561578063cc3cbd2a1461051e578063cd7736b8146104f9578063cd7c99d8146104dc578063d04c6983146102aa578063d3618cca14610278578063d55be8c61461025d578063e4fbb60914610236578063e7c2b77214610214578063ec28f1ee146101f25763f4042bc3146101b8575f61000f565b34610011575f3660031901126100115760206040517f0000000000000000000000000000000000000000000000003782dace9d9000008152f35b34610011575f36600319011261001157602060ff600954166040519015158152f35b34610011575f36600319011261001157602060ff600554166040519015158152f35b34610011575f366003190112610011575f546040516001600160a01b039091168152602090f35b34610011575f36600319011261001157602060405160c88152f35b34610011575f366003190112610011576102906113c1565b610298611942565b5f5f516020611f175f395f51905f525d005b34610011576060366003190112610011576044356001600160a01b038116906024359060043590839003610011576102e06113c1565b60ff600554166104cd5780156104be5782156104af576102ff81611d26565b909193600454908183116104a05780861061048957509061036a9161035361032986600154610e75565b806001557f00000000000000000000000000435c6908d5d9bef207d483df934c0000000000611148565b60025561036285600354610e54565b600355610e54565b600455610376816117a4565b60015460025460408051858152602081019490945283018590526060830191909152608082015233907f20a7fc03b19d7f251cc907f177ff82194c6aebe9a2b47e1cd734dcb6bf772cc29060a090a26040516323b872dd60e01b5f90815233600452306024526044929092527f000000000000000000000000fcae0ce8f0745e36c80faf9cabfb3a633385def16001600160a01b03169160209060648180865af19060015f5114821615610468575b6040525f60605215610456575061043e816020936118dc565b5f5f516020611f175f395f51905f525d604051908152f35b635274afe760e01b5f5260045260245ffd5b90600181151661048057823b15153d15161690610425565b503d5f823e3d90fd5b85906313a30a9560e11b5f5260045260245260445ffd5b63b4dadcb160e01b5f5260045ffd5b63d92e233d60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b63012d60bf60e11b5f5260045ffd5b34610011575f366003190112610011576020600754604051908152f35b34610011575f36600319011261001157602060ff60095460081c166040519015158152f35b34610011575f3660031901126100115760206040516001600160601b037f000000000000000000000000000000000000000000000000000000000000001e168152f35b34610011575f3660031901126100115760206040516001600160601b037f000000000000000000000000000000000000000000000000000000000000005f168152f35b34610011575f366003190112610011576020600254604051908152f35b346100115760203660031901126100115760406105df6004356113ad565b82519182526020820152f35b346100115760203660031901126100115760043567ffffffffffffffff8111610011573660238201121561001157806004013567ffffffffffffffff8111610011573660248260061b840101116100115760246102989261064a6113c1565b0161118e565b34610011575f366003190112610011576040517f0000000000000000000000000c6d60e16da41ab6d8be2e7d308865429e61c6c56001600160a01b03168152602090f35b34610011575f3660031901126100115760206040517f00000000000000000000000000000000000000000000000000038d7ea4c680008152f35b34610011575f366003190112610011576020600854604051908152f35b34610011575f366003190112610011576040517f000000000000000000000000fcae0ce8f0745e36c80faf9cabfb3a633385def16001600160a01b03168152602090f35b6040366003190112610011576024356001600160a01b03811690600435908290036100115761075c6113c1565b60ff600554166104cd5734156104be5781156104af5767ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001680151580610a1a575b80610a0a575b6109e7575b506107bb346115b6565b929384156104be578085106109d05750837f178f20a8980b4e6cdc2c84f3ef670f5047f63638f90a8acc6b724b43f1da778d916108276107fd85600254610e75565b806002557f00000000000000000000000000435c6908d5d9bef207d483df934c0000000000611148565b60015561083682600354610e75565b60035561084584600454610e75565b60045560095460ff8160081c16156109be575b50610862816117a4565b6001546002546040805196875260208701939093529185019290925260608401919091526080830152339160a090a260405163a9059cbb60e01b5f90815260049490945260248390527f000000000000000000000000fcae0ce8f0745e36c80faf9cabfb3a633385def16001600160a01b03169360209060448180885af19060015f51148216156109a6575b60405215610993576020925080610983575b506003547f0000000000000000000000000000000000000000029174957281e12f457b425f11801590610957575b61094a575f5f516020611f175f395f51905f525d604051908152f35b610952611942565b61043e565b506004547f0000000000000000000000000000000000000000000000003782dace9d900000111561092e565b61098d90336118dc565b82610900565b82635274afe760e01b5f5260045260245ffd5b90600181151661048057843b15153d151616906108ee565b61ff0019166101001760095587610858565b84906313a30a9560e11b5f5260045260245260445ffd5b5f546001600160a01b031633146107b1576304d0bf6f60e31b5f5260045260245ffd5b5060ff60095460081c16156107ac565b508042106107a6565b34610011575f36600319011261001157602060405167ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610011575f366003190112610011576040517f00000000000000000000000008285a9982ccf65ec579220a12d274c9451b57e96001600160a01b03168152602090f35b34610011575f366003190112610011576020600454604051908152f35b34610011575f366003190112610011576020600654604051908152f35b34610011576020366003190112610011576040610b0c610b06600435611130565b50610e1e565b6001600160601b03602060018060a01b038351169201511682519182526020820152f35b34610011575f366003190112610011576020600354604051908152f35b346100115760203660031901126100115760406105df600435611113565b34610011575f36600319011261001157610b836113c1565b610298611082565b34610011575f366003190112610011576020604051600a8152f35b34610011576020366003190112610011576004356001600160a01b0381169081900361001157610bd46113c1565b5f546001600160a01b0381169033829003610c545760ff60095416610c455782156104af576001600160a01b03191682175f55610c0f611577565b7f949ac028d12de8dcf4890415d83d29e6dccd033c31dc7a859a9a85fab5a66d775f80a35f5f516020611f175f395f51905f525d005b630605a8c160e41b5f5260045ffd5b6308f78f9960e31b5f5260045ffd5b34610011575f3660031901126100115760206040517f000000000000000000000000000000000000000000000000005543df729c00008152f35b34610011575f36600319011261001157610cb56113c1565b610298610e82565b34610011575f366003190112610011576040517f00000000000000000000000082e927237ff6aaff00d0d9b60e77e495ac7227996001600160a01b03168152602090f35b34610011575f3660031901126100115760206040517f000000000000000000000000000000000000000000a9b9a72d4e9f0da284bda18152f35b34610011575f3660031901126100115760206040516127108152f35b34610011575f3660031901126100115760206040517f0000000000000000000000000000000000000000029174957281e12f457b425f8152f35b34610011575f366003190112610011576020600154604051908152f35b34610011575f366003190112610011576020907f000000000000000000000000000000000000000000000000000000000000000015158152f35b90601f8019910116810190811067ffffffffffffffff821117610e0a57604052565b634e487b7160e01b5f52604160045260245ffd5b906040516040810181811067ffffffffffffffff821117610e0a5760405291546001600160a01b038116835260a01c6020830152565b91908203918211610e6157565b634e487b7160e01b5f52601160045260245ffd5b91908201809211610e6157565b60065490811561107e575f60065560085467ffffffffffffffff8111610e0a5760405190610eb660208260051b0183610de8565b8082526020820160085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee35f915b83831061106157505050508051925f915f9085155f14610f7c5750507f7facfd0cab6f32c453cd4e60308aa6e2471639130a35c64a8255c8b060b3c48a9293509081610f3c60409360018060a01b035f541661151b565b15610f74575b81610f52915b81610f6057610e54565b9082519182526020820152a1565b610f6c82600654610e75565b600655610e54565b905080610f42565b5f198601868111969290915f5b848110610fc65750505050507f7facfd0cab6f32c453cd4e60308aa6e2471639130a35c64a8255c8b060b3c48a92935090610f5281604093610f48565b815181101561104d57889260208260051b8401015193610e6157611013611003918684145f1461103657610ffa818a610e54565b92838092610e75565b95516001600160a01b031661151b565b15611022575b50600101610f89565b61102f9060019298610e75565b9690611019565b610ffa6001600160601b036020880151168a6113f6565b634e487b7160e01b5f52603260045260245ffd5b60016020819261107085610e1e565b815201920192019190610ee5565b9050565b6007548015611110575f6007557f04ec9d62881c2c6c5422426e8001e152a3a62488952d9b15de26038eb14dc1a760407f00000000000000000000000008285a9982ccf65ec579220a12d274c9451b57e96110dd848261151b565b15806110fc575b82519485521560208501526001600160a01b031692a2565b61110885600754610e75565b6007556110e4565b50565b801561112957611122906115b6565b5091929050565b505f905f90565b60085481101561104d5760085f5260205f2001905f90565b8115611152570490565b634e487b7160e01b5f52601260045260245ffd5b356001600160a01b03811681036100115790565b356001600160601b03811681036100115790565b5f546001600160a01b03163303610c545760ff60095416610c4557600a82116112aa576008545f6008558061134d575b508115611317575f92835b838510156112d557600685901b8301946001600160a01b036111ea87611166565b161580156112b9575b6112aa5761121760208701926001600160601b036112108561117a565b1690610e75565b9560085468010000000000000000811015610e0a5780600161123c9201600855611130565b91909161129757600193611272916001600160a01b039061125c90611166565b84546001600160a01b031916911617835561117a565b8154906001600160601b0360a01b9060a01b1690848060a01b031617905501936111c9565b634e487b7160e01b5f525f60045260245ffd5b6355195b2160e01b5f5260045ffd5b506001600160601b036112ce6020880161117a565b16156111f3565b9093506127109150036112aa5760207f29f10a458490fa7f83cf34bbe71a7f399c0bb2fb12abae20e2a8f1c7ac9a44a29161130e611577565b604051908152a1565b5050611321611577565b7f29f10a458490fa7f83cf34bbe71a7f399c0bb2fb12abae20e2a8f1c7ac9a44a260206040515f8152a1565b60085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3017ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee35b8181106113a257506111be565b5f8155600101611395565b8015611129576113bc90611d26565b509091565b5f516020611f175f395f51905f525c6113e75760015f516020611f175f395f51905f525d565b633ee5aeb560e01b5f5260045ffd5b9091905f905f19848209908481029283808410930392808403931461146d5782612710111561145b57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b90915f19838309928083029283808610950394808603951461150b57848311156114f35790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906115189250611148565b90565b8115611570575f918291829182916001600160a01b0316617530f13d15611518573d67ffffffffffffffff8111610e0a5760405190611564601f8201601f191660200183610de8565b81525f60203d92013e90565b5050600190565b60095460ff8116156115865750565b60ff19166001176009557f398ee389daa3d70eda47a279ce50f017bb4f443056572d2945516cce149e38c15f80a1565b906115bf611d5f565b916115ca8382611e0e565b916115d58383610e54565b936116026003547f0000000000000000000000000000000000000000029174957281e12f457b425f610e54565b9485611744575f5b7f0000000000000000000000000000000000000000000000003782dace9d9000006004548082115f1461173c5761164091610e54565b808210156117345750945b858211156117145750508361169661168e61166883600254610e75565b7f00000000000000000000000000435c6908d5d9bef207d483df934c0000000000611148565b600154610e54565b9580871161170c575b5081156117005781612710036127108111610e61576116c1816127108461147a565b926127101461115257611518926116df916127108409151590610e75565b908482116116f8575b6116f29082610e54565b93610e54565b8491506116e8565b61151891505f93610e54565b95505f61169f565b9450945050905061172d61168e61166885600254610e75565b9291905f90565b90509461164b565b50505f611640565b61175086600154610e54565b7f00000000000000000000000000435c6908d5d9bef207d483df934c000000000061177d8260018361147a565b82156111525761179f9260016117969309151590610e75565b60025490610e54565b61160a565b8015611110577f000000000000000000000000000000000000000000000000000000000000000061189b576001600160601b037f000000000000000000000000000000000000000000000000000000000000001e1661182c816001600160601b037f000000000000000000000000000000000000000000000000000000000000005f16610e75565b9182156118965761186b6118647f49086fb5fbe3012e87f1afd31e52bfcb81e75a7804f59744a6eee012b59cd0a0946040948461147a565b8092610e54565b61187782600654610e75565b60065561188681600754610e75565b60075582519182526020820152a1565b505050565b6040816118cb7f49086fb5fbe3012e87f1afd31e52bfcb81e75a7804f59744a6eee012b59cd0a093600754610e75565b6007558151905f82526020820152a1565b81471061192b575f8080938193826040516118f8602082610de8565b526001600160a01b03165af11561190b57565b3d1561191c576040513d5f823e3d90fd5b63d6bda27560e01b5f5260045ffd5b504763cf47918160e01b5f5260045260245260445ffd5b6005545f9060ff81166104cd576003547f0000000000000000000000000000000000000000029174957281e12f457b425f1180611cfb575b611cec5760ff19166001176005556004547f00000000000000000000000000000000000000000000000000038d7ea4c68000907f000000000000000000000000000000000000000000000000000000000000000015611cc5575f905b806119e18385610e75565b11611cb6576119fa906119f48385610e75565b90610e54565b9180611ca1575b5080611c8c575b507f000000000000000000000000fcae0ce8f0745e36c80faf9cabfb3a633385def16001600160a01b031690813b156100115760405163e4f3923560e01b81525f8160048183875af18015611c8157611c6c575b507f0000000000000000000000000c6d60e16da41ab6d8be2e7d308865429e61c6c57f000000000000000000000000000000000000000000a9b9a72d4e9f0da284bda1611aaa818386611e2a565b15611c39575b84546040805163bdc9315960e01b8152600481018790526001600160a01b039283166024820152604481018490526001600160601b037f000000000000000000000000000000000000000000000000000000000000001e811660648301527f000000000000000000000000000000000000000000000000000000000000005f1660848201529691879060a4908290889088165af1928315611c2c5781968294611bee575b50611b60828288611e2a565b15611ba1575b5050916060917fdf9e4d7e38c0b4f9b2b0c31c082370dd912b89a99ebaf6129c106a6b81253f679360405192835260208301526040820152a3565b611bab8187611e77565b15611bda5781611bbb9187611edb565b15611bc65780611b66565b635274afe760e01b81526004859052602490fd5b635274afe760e01b82526004869052602482fd5b965092506040863d604011611c24575b81611c0b60409383610de8565b81010312611c215760208651960151925f611b54565b80fd5b3d9150611bfe565b50604051903d90823e3d90fd5b611c438285611e77565b15611c5857611c53818386611edb565b611ab0575b635274afe760e01b85526004849052602485fd5b611c799193505f90610de8565b5f915f611a5c565b6040513d5f823e3d90fd5b611c9890600654610e75565b6006555f611a08565b611cad90600754610e75565b6007555f611a01565b6306b7c75960e31b5f5260045ffd5b7f000000000000000000000000000000000000000000000000005543df729c0000906119d6565b631cfe57f360e21b5f5260045ffd5b506004547f0000000000000000000000000000000000000000000000003782dace9d9000001161197a565b611d38611668611d4092600154610e75565b600254610e54565b611d51611d4b611d5f565b82611e0e565b90611d5c8282610e54565b92565b7f000000000000000000000000000000000000000000000000000000000000000015611db2576001600160601b037f000000000000000000000000000000000000000000000000000000000000005f1690565b6115186001600160601b037f000000000000000000000000000000000000000000000000000000000000001e166001600160601b037f000000000000000000000000000000000000000000000000000000000000005f16610e75565b61271061151892611e2082828561147a565b9209151590610e75565b92916040519163095ea7b360e01b5f5260018060a01b031660045260245260205f60448180875af19260015f5114841615611e66575b50604052565b3d15903b151516909216915f611e60565b60405163095ea7b360e01b5f9081526001600160a01b03909316600452602483905290929160209060448180875af19260015f5114841615611eb95750604052565b60018492941516611ed2573b15153d151616915f611e60565b833d5f823e3d90fd5b92916040519163095ea7b360e01b5f5260018060a01b031660045260245260205f60448180875af19260015f5114841615611eb9575060405256fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| DIH | 1 | $0.0000102 | $0 | |
| ICAT (ICAT) | ICAT | 999,528,632.279015 | — | — |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x78d1eb…757756 | sell | 11,157,479 | 32 days agoThu, 16 Jul 2026 09:42:19 UTC | 0xc679…c7e2 | IN | BondingCurve | $0.000 ETH | 0.00000512 | |
| 0x6bf487…6605c8 | sell | 11,155,966 | 32 days agoThu, 16 Jul 2026 09:39:48 UTC | 0xae04…8428 | IN | BondingCurve | $0.000 ETH | 0.00000512 | |
| 0xdd5206…226335 | sell | 11,144,322 | 32 days agoThu, 16 Jul 2026 09:20:21 UTC | 0x751d…88db | IN | BondingCurve | $0.000 ETH | 0.00000542 | |
| 0x6dc633…c3d75b | buy | 11,134,822 | 32 days agoThu, 16 Jul 2026 09:04:28 UTC | 0xae04…8428 | IN | BondingCurve | $95.350.05 ETH | 0.00000645 | |
| 0xb7a3d5…f2913a | buy | 11,134,536 | 32 days agoThu, 16 Jul 2026 09:03:59 UTC | 0xc679…c7e2 | IN | BondingCurve | $190.700.1 ETH | 0.00000624 | |
| 0x3b3b0d…e5b409 | buy | 11,133,482 | 32 days agoThu, 16 Jul 2026 09:02:13 UTC | 0x751d…88db | IN | BondingCurve | $66.750.035 ETH | 0.00000624 | |
| 0x743e24…86add2 | sell | 11,131,327 | 32 days agoThu, 16 Jul 2026 08:58:37 UTC | 0x7674…4ee1 | IN | BondingCurve | $0.000 ETH | 0.00000521 | |
| 0xb873c5…f35f2d | buy | 11,128,852 | 32 days agoThu, 16 Jul 2026 08:54:30 UTC | 0x7674…4ee1 | IN | BondingCurve | $190.700.1 ETH | 0.00000631 | |
| 0xb54178…67c11b | sell | 10,712,050 | 32 days agoWed, 15 Jul 2026 21:18:48 UTC | 0x5b11…6acf | IN | BondingCurve | $0.000 ETH | 0.00000550 | |
| 0x756732…92767f | buy | 10,486,558 | 33 days agoWed, 15 Jul 2026 15:04:23 UTC | 0x5b11…6acf | IN | BondingCurve | $57.210.03 ETH | 0.00000603 | |
| 0x351bec…bf2a30 | sell | 10,408,092 | 33 days agoWed, 15 Jul 2026 12:53:41 UTC | 0xf7c3…22c1 | IN | BondingCurve | $0.000 ETH | 0.00000500 | |
| 0x9c7125…7baf07 | sell | 10,392,387 | 33 days agoWed, 15 Jul 2026 12:27:29 UTC | 0xc051…91ee | IN | BondingCurve | $0.000 ETH | 0.00000529 | |
| 0xd71bb4…c902de | sell | 10,384,091 | 33 days agoWed, 15 Jul 2026 12:13:41 UTC | 0xf7c3…22c1 | IN | BondingCurve | $0.000 ETH | 0.00000521 | |
| 0x11fc0c…87adc1 | sell | 10,376,546 | 33 days agoWed, 15 Jul 2026 12:01:08 UTC | 0xc051…91ee | IN | BondingCurve | $0.000 ETH | 0.00000523 | |
| 0xadb21e…49266f | buy | 10,376,351 | 33 days agoWed, 15 Jul 2026 12:00:48 UTC | 0xf7c3…22c1 | IN | BondingCurve | $1,144.220.6 ETH | 0.00000575 | |
| 0xe05dd2…18d1fd | buy | 10,376,348 | 33 days agoWed, 15 Jul 2026 12:00:48 UTC | 0xc051…91ee | IN | BondingCurve | $9.540.005 ETH | 0.00001074 |
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x78d1eb…757756 | 32 days agoThu, 16 Jul 2026 09:42:19 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…211cc7e2 data: 0x000000000000000000…315cefdc |
| 0x78d1eb…757756 | 32 days agoThu, 16 Jul 2026 09:42:19 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…6e020c00 |
| 0x6bf487…6605c8 | 32 days agoThu, 16 Jul 2026 09:39:48 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…bffa8428 data: 0x000000000000000000…a30bf98d |
| 0x6bf487…6605c8 | 32 days agoThu, 16 Jul 2026 09:39:48 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…bf5eed92 |
| 0xdd5206…226335 | 32 days agoThu, 16 Jul 2026 09:20:21 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…b3c288db data: 0x000000000000000000…893cd0e0 |
| 0xdd5206…226335 | 32 days agoThu, 16 Jul 2026 09:20:21 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…ae4626f1 |
| 0x6dc633…c3d75b | 32 days agoThu, 16 Jul 2026 09:04:28 UTC | 0x178f20…778d | [0] 0x000000000000…bffa8428 data: 0x000000000000000000…67c467dc |
| 0x6dc633…c3d75b | 32 days agoThu, 16 Jul 2026 09:04:28 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…8e44b000 |
| 0xb7a3d5…f2913a | 32 days agoThu, 16 Jul 2026 09:03:59 UTC | 0x178f20…778d | [0] 0x000000000000…211cc7e2 data: 0x000000000000000000…5ffb77dc |
| 0xb7a3d5…f2913a | 32 days agoThu, 16 Jul 2026 09:03:59 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…1c896000 |
| 0x3b3b0d…e5b409 | 32 days agoThu, 16 Jul 2026 09:02:13 UTC | 0x178f20…778d | [0] 0x000000000000…b3c288db data: 0x000000000000000000…506997dc |
| 0x3b3b0d…e5b409 | 32 days agoThu, 16 Jul 2026 09:02:13 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…30634800 |
| 0x743e24…86add2 | 32 days agoThu, 16 Jul 2026 08:58:37 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…985e4ee1 data: 0x000000000000000000…315cefdc |
| 0x743e24…86add2 | 32 days agoThu, 16 Jul 2026 08:58:37 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…3f614200 |
| 0xb873c5…f35f2d | 32 days agoThu, 16 Jul 2026 08:54:30 UTC | 0x178f20…778d | [0] 0x000000000000…985e4ee1 data: 0x000000000000000000…40eecfdc |
| 0xb873c5…f35f2d | 32 days agoThu, 16 Jul 2026 08:54:30 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…1c896000 |
| 0xb54178…67c11b | 32 days agoWed, 15 Jul 2026 21:18:48 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…96146acf data: 0x000000000000000000…315cefdc |
| 0xb54178…67c11b | 32 days agoWed, 15 Jul 2026 21:18:48 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…4636c700 |
| 0x756732…92767f | 33 days agoWed, 15 Jul 2026 15:04:23 UTC | 0x178f20…778d | [0] 0x000000000000…96146acf data: 0x000000000000000000…02d57fdc |
| 0x756732…92767f | 33 days agoWed, 15 Jul 2026 15:04:23 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…bbc2d000 |
| 0x351bec…bf2a30 | 33 days agoWed, 15 Jul 2026 12:53:41 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…774822c1 data: 0x000000000000000000…315cefdc |
| 0x351bec…bf2a30 | 33 days agoWed, 15 Jul 2026 12:53:41 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…e1ea8465 |
| 0x9c7125…7baf07 | 33 days agoWed, 15 Jul 2026 12:27:29 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…353691ee data: 0x000000000000000000…81caf410 |
| 0x9c7125…7baf07 | 33 days agoWed, 15 Jul 2026 12:27:29 UTC | 0x49086f…d0a0 | data: 0x000000000000000000…a31f50e7 |
| 0xd71bb4…c902de | 33 days agoWed, 15 Jul 2026 12:13:41 UTC | 0x20a7fc…2cc2 | [0] 0x000000000000…774822c1 data: 0x000000000000000000…94906d9c |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xb04afb3c…3f3b0d | Transfer | 18,583,965 | 23 days agoSat, 25 Jul 2026 00:35:15 UTC | 0xcaf7…5d11 | IN | 0x5e3e…2a04 | $0.001 DIH | ||
| 0x78d1eb4d…757756 | Transfer | 11,157,479 | 32 days agoThu, 16 Jul 2026 09:42:19 UTC | 0xc679…c7e2 | IN | 0x5e3e…2a04 | 67,383,605.055513 ICAT | ICAT (ICAT) | |
| 0x6bf487f8…6605c8 | Transfer | 11,155,966 | 32 days agoThu, 16 Jul 2026 09:39:48 UTC | 0xae04…8428 | IN | 0x5e3e…2a04 | 30,539,784.932094 ICAT | ICAT (ICAT) | |
| 0xdd5206d2…226335 | Transfer | 11,144,322 | 32 days agoThu, 16 Jul 2026 09:20:21 UTC | 0x751d…88db | IN | 0x5e3e…2a04 | 25,829,044.417723 ICAT | ICAT (ICAT) | |
| 0x6dc63386…c3d75b | Transfer | 11,134,822 | 32 days agoThu, 16 Jul 2026 09:04:28 UTC | 0x5e3e…2a04 | OUT | 0xae04…8428 | 30,539,784.932094 ICAT | ICAT (ICAT) | |
| 0xb7a3d5a3…f2913a | Transfer | 11,134,536 | 32 days agoThu, 16 Jul 2026 09:03:59 UTC | 0x5e3e…2a04 | OUT | 0xc679…c7e2 | 67,383,605.055513 ICAT | ICAT (ICAT) | |
| 0x3b3b0d98…e5b409 | Transfer | 11,133,482 | 32 days agoThu, 16 Jul 2026 09:02:13 UTC | 0x5e3e…2a04 | OUT | 0x751d…88db | 25,829,044.417723 ICAT | ICAT (ICAT) | |
| 0x743e2469…86add2 | Transfer | 11,131,327 | 32 days agoThu, 16 Jul 2026 08:58:37 UTC | 0x7674…4ee1 | IN | 0x5e3e…2a04 | 70,638,024.790697 ICAT | ICAT (ICAT) | |
| 0xb873c570…f35f2d | Transfer | 11,128,852 | 32 days agoThu, 16 Jul 2026 08:54:30 UTC | 0x5e3e…2a04 | OUT | 0x7674…4ee1 | 70,638,024.790697 ICAT | ICAT (ICAT) | |
| 0xb54178e0…67c11b | Transfer | 10,712,050 | 32 days agoWed, 15 Jul 2026 21:18:48 UTC | 0x5b11…6acf | IN | 0x5e3e…2a04 | 22,215,610.188741 ICAT | ICAT (ICAT) | |
| 0x75673243…92767f | Transfer | 10,486,558 | 33 days agoWed, 15 Jul 2026 15:04:23 UTC | 0x5e3e…2a04 | OUT | 0x5b11…6acf | 22,215,610.188741 ICAT | ICAT (ICAT) | |
| 0x351becbf…bf2a30 | Transfer | 10,408,092 | 33 days agoWed, 15 Jul 2026 12:53:41 UTC | 0xf7c3…22c1 | IN | 0x5e3e…2a04 | 79,291,369.192094 ICAT | ICAT (ICAT) | |
| 0x9c7125e7…7baf07 | Transfer | 10,392,387 | 33 days agoWed, 15 Jul 2026 12:27:29 UTC | 0xc051…91ee | IN | 0x5e3e…2a04 | 1,414,103.162952 ICAT | ICAT (ICAT) | |
| 0xd71bb4a5…c902de | Transfer | 10,384,091 | 33 days agoWed, 15 Jul 2026 12:13:41 UTC | 0xf7c3…22c1 | IN | 0x5e3e…2a04 | 237,874,107.576283 ICAT | ICAT (ICAT) | |
| 0x11fc0c0e…87adc1 | Transfer | 10,376,546 | 33 days agoWed, 15 Jul 2026 12:01:08 UTC | 0xc051…91ee | IN | 0x5e3e…2a04 | 1,885,470.883936 ICAT | ICAT (ICAT) | |
| 0xadb21ea8…49266f | Transfer | 10,376,351 | 33 days agoWed, 15 Jul 2026 12:00:48 UTC | 0x5e3e…2a04 | OUT | 0xf7c3…22c1 | 317,165,476.768377 ICAT | ICAT (ICAT) | |
| 0xe05dd2bb…18d1fd | Transfer | 10,376,348 | 33 days agoWed, 15 Jul 2026 12:00:48 UTC | 0x5e3e…2a04 | OUT | 0xc051…91ee | 3,770,941.767872 ICAT | ICAT (ICAT) | |
| 0x2b6472df…70cb95 | Transfer | 10,376,086 | 33 days agoWed, 15 Jul 2026 12:00:24 UTC | 0x0000…0000 | IN | 0x5e3e…2a04 | 1,000,000,000.000000 ICAT | ICAT (ICAT) |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 11,157,479 | 32 days agoThu, 16 Jul 2026 09:42:19 UTC | 0x78d1eb…757756 | CALL | sell | 0x5e3e…2a04 | OUT | 0xc679…c7e2 | 0.09272 ETH |
| 11,155,966 | 32 days agoThu, 16 Jul 2026 09:39:48 UTC | 0x6bf487…6605c8 | CALL | sell | 0x5e3e…2a04 | OUT | 0xae04…8428 | 0.04624 ETH |
| 11,144,322 | 32 days agoThu, 16 Jul 2026 09:20:21 UTC | 0xdd5206…226335 | CALL | sell | 0x5e3e…2a04 | OUT | 0x751d…88db | 0.04143 ETH |
| 11,131,327 | 32 days agoThu, 16 Jul 2026 08:58:37 UTC | 0x743e24…86add2 | CALL | sell | 0x5e3e…2a04 | OUT | 0x7674…4ee1 | 0.09751 ETH |
| 10,712,050 | 32 days agoWed, 15 Jul 2026 21:18:48 UTC | 0xb54178…67c11b | CALL | sell | 0x5e3e…2a04 | OUT | 0x5b11…6acf | 0.02925 ETH |
| 10,408,092 | 33 days agoWed, 15 Jul 2026 12:53:41 UTC | 0x351bec…bf2a30 | CALL | sell | 0x5e3e…2a04 | OUT | 0xf7c3…22c1 | 0.11041 ETH |
| 10,392,387 | 33 days agoWed, 15 Jul 2026 12:27:29 UTC | 0x9c7125…7baf07 | CALL | sell | 0x5e3e…2a04 | OUT | 0xc051…91ee | 0.00212 ETH |
| 10,384,091 | 33 days agoWed, 15 Jul 2026 12:13:41 UTC | 0xd71bb4…c902de | CALL | sell | 0x5e3e…2a04 | OUT | 0xf7c3…22c1 | 0.47188 ETH |
| 10,376,546 | 33 days agoWed, 15 Jul 2026 12:01:08 UTC | 0x11fc0c…87adc1 | CALL | sell | 0x5e3e…2a04 | OUT | 0xc051…91ee | 0.00493 ETH |
| 10,376,086 | 33 days agoWed, 15 Jul 2026 12:00:24 UTC | 0x2b6472…70cb95 | CREATE2 | createToken | 0x82e9…2799 | IN | 0x5e3e…2a04 | 0 ETH |