// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {PoolInitParams, PoolSettlement} from "./PoolTypes.sol";
import {IUnlocker} from "./interfaces/IUnlocker.sol";
/// @title Pool — Community Pool escrow + pledger ledger.
/// @notice Forked from Virtuals' Genesis (MIT). One Pool is deployed per launch
/// by PoolFactory. Pledgers commit $VIRTUAL until the pool FILLS (hits
/// `reserveAmount`) or the time window closes — whichever comes first.
/// The operator (via the factory) then either:
/// • settleSuccess — the INSTANT it fills (no need to wait out the
/// window): launch the token (prebuy `reserveAmount` $VIRT via the
/// launcher, supply lands here), refund over-subscribed $VIRT 1:1,
/// and record each pledger's pro-rata token claim (pull); or
/// • settleFailed — if still unfilled at the deadline, refund 1:1.
///
/// @dev Fork deltas vs Genesis: (1) launch is abstracted behind IPoolLauncher
/// instead of a hardcoded AgentFactoryV3 call; (2) the per-wallet cap is
/// CUMULATIVE (Genesis capped per-tx); (3) the agent stack (points, cores,
/// TBA, DAO) is stripped; (4) non-upgradeable (constructor, immutables).
/// The dev's 8.5% is NOT handled here at all — it is a separate Virtuals
/// TokenTable vesting schedule (recipient = the dev's vault) that never
/// enters this Pool. This Pool only claims + distributes the pledger 76.5%;
/// `sweep()` is just leftover-dust / stray-token recovery.
contract Pool is ReentrancyGuard {
using SafeERC20 for IERC20;
/// @notice Grace period after endTime before pledgers may self-refund an
/// unsettled pool (operator-inaction backstop).
uint256 public constant SELF_REFUND_GRACE = 7 days;
/// @notice Longer backstop for a FUNDED pool the operator abandoned. Only
/// after this (well past any real launch) can a filled pool be
/// self-refunded — so one pledger can't force-fail a funded launch
/// during the normal grace window.
uint256 public constant ABANDON_GRACE = 30 days;
/// @notice Upper bounds on metadata + the unlocker claim batch (defense in
/// depth: keep the launch draft/display sane and bound claim gas).
uint256 public constant MAX_NAME_BYTES = 64;
uint256 public constant MAX_TICKER_BYTES = 16;
uint256 public constant MAX_CLAIM_IDS = 50;
// ---- immutable config ----
uint256 public immutable poolId;
address public immutable factory;
IERC20 public immutable virtualToken;
address public immutable devRecipient;
uint256 public immutable reserveAmount;
uint256 public immutable maxContribution;
uint256 public immutable minContribution;
uint256 public immutable tokenTotalSupply;
uint256 public immutable tokenLpSupply;
// ---- metadata + window (window mutable via resetWindow, only before start) ----
string public name;
string public ticker;
uint256 public startTime;
uint256 public endTime;
// ---- pledger ledger ----
mapping(address => uint256) public pledged; // $VIRT committed per wallet
mapping(address => uint256) public claimable; // launched-token claim per wallet
mapping(address => bool) public allocated; // recorded in settleSuccess (monotonic — list once across batches)
address[] public participants;
uint256 public totalPledged;
uint256 public refundedCountOnFail;
uint256 public totalClaimable; // launched tokens recorded as claimable but not yet pulled
uint256 public releasedForLaunch; // $VIRT released to fund the off-chain prebuy (<= reserveAmount)
// ---- H1: pro-rata refund denominator ----
// The sum of pledges still owed a failure-path refund, FROZEN at the first
// refund and decremented (by the FULL pledge) as each pledger is paid. It is
// the denominator for pro-rata-of-remaining-balance refunds so that a funded-
// then-abandoned pool (where releaseForLaunch already drained up to
// `reserveAmount` from the escrow) splits the residual $VIRT fairly instead
// of paying first-come 1:1 and stranding later callers. `refundFrozen` marks
// whether the snapshot has been taken (so `outstandingPledged == 0` is not
// mistaken for "uninitialised").
uint256 public outstandingPledged;
bool public refundFrozen;
// ---- M1: over-subscription pull-refund ----
// Per-wallet over-subscription entitlement recorded at settleSuccess so an
// over-subscribed pledger can self-serve their excess $VIRT if the operator
// omitted them from the settleSuccess refund batch. Pulled exactly once.
mapping(address => bool) public overRefundClaimed; // wallet has pulled its over-sub
bool public overFrozen; // over-sub denominator snapshot taken
uint256 public overTotalPledged; // totalPledged frozen at first over-refund pull
uint256 public overResidual; // (totalPledged - reserveAmount) frozen at first pull
// ---- outcome ----
address public token; // launched token address (0 until success)
bool public isFailed;
bool public isCancelled;
event Pledged(address indexed user, uint256 amount);
event Launched(address indexed token);
event LaunchFunded(address indexed to, uint256 amount);
event Refunded(address indexed user, uint256 amount);
event OverRefunded(address indexed user, uint256 amount);
event Claimed(address indexed user, uint256 amount);
event Succeeded();
event Failed();
event Cancelled();
event WindowReset(uint256 startTime, uint256 endTime);
event Swept(address indexed to, address indexed token, uint256 amount);
modifier onlyFactory() {
require(msg.sender == factory, "not factory");
_;
}
constructor(PoolInitParams memory p) {
require(p.poolId > 0, "bad id");
require(
p.factory != address(0) && p.virtualToken != address(0) && p.devRecipient != address(0),
"zero addr"
);
require(p.endTime > p.startTime && p.endTime > block.timestamp, "bad window");
require(p.reserveAmount > 0 && p.maxContribution > 0, "bad amount");
require(p.minContribution > 0 && p.minContribution <= p.maxContribution, "bad min");
require(p.tokenLpSupply > 0 && p.tokenTotalSupply >= p.tokenLpSupply, "bad supply");
require(
bytes(p.name).length > 0 && bytes(p.name).length <= MAX_NAME_BYTES
&& bytes(p.ticker).length > 0 && bytes(p.ticker).length <= MAX_TICKER_BYTES,
"bad meta"
);
poolId = p.poolId;
factory = p.factory;
virtualToken = IERC20(p.virtualToken);
devRecipient = p.devRecipient;
reserveAmount = p.reserveAmount;
maxContribution = p.maxContribution;
minContribution = p.minContribution;
tokenTotalSupply = p.tokenTotalSupply;
tokenLpSupply = p.tokenLpSupply;
name = p.name;
ticker = p.ticker;
startTime = p.startTime;
endTime = p.endTime;
}
// ---- pledging (permissionless) ----
/// @notice Commit `amount` $VIRTUAL to the pool. Cumulative per-wallet cap.
/// @dev Pledging LOCKS the instant the pool fills (`reserveReached()`): the
/// crossing pledge that hits/crosses the target is the last accepted
/// (its excess is refunded at settlement), and the pool can then TGE
/// immediately — no waiting for the window to elapse. This clean cutoff
/// also means no pledge can race the settle tx and end up stranded.
function pledge(uint256 amount) external nonReentrant {
require(
isStarted() && !isEnded() && !reserveReached() && token == address(0) && !isFailed && !isCancelled,
"not active"
);
require(amount >= minContribution, "below min");
require(pledged[msg.sender] + amount <= maxContribution, "exceeds cap");
if (pledged[msg.sender] == 0) participants.push(msg.sender);
pledged[msg.sender] += amount;
totalPledged += amount;
virtualToken.safeTransferFrom(msg.sender, address(this), amount);
emit Pledged(msg.sender, amount);
}
// ---- settlement: success ----
/// @notice Launch the token (first call only) and apply a batch of refunds +
/// token-claim records. Callable multiple times to settle large
/// pools across several txs; the launch happens exactly once.
function settleSuccess(address launchedToken, PoolSettlement calldata s) external onlyFactory nonReentrant {
// Instant-on-fill: settle as soon as the target is hit — NO isEnded()
// gate. A filled pool's window may still be open; pledging is already
// locked (pledge requires !reserveReached), so the state is stable.
// The success path is only valid on a pool that actually hit its target
// — mutually exclusive with the refund paths (claimRefund/refundSelf
// require !reserveReached). Without this, an operator slip could
// force-succeed an under-filled pool and permanently trap pledger $VIRT
// (no refund path once token is set).
require(reserveReached(), "not fillable");
require(!isCancelled, "cancelled");
require(!isFailed, "failed");
require(s.refundAddresses.length == s.refundAmounts.length, "refund len");
require(s.distributeAddresses.length == s.distributeAmounts.length, "distribute len");
// The launch happens off-chain (operator: Virtuals API + preLaunch); the
// pledger supply is delivered into this contract via the TokenTable
// unlocker claim BEFORE this call. First call records the launched token;
// later batches must reuse it. The over-allocation guard below ensures
// recorded claims never exceed the supply actually held here.
if (token == address(0)) {
require(launchedToken != address(0), "zero token");
token = launchedToken;
emit Launched(launchedToken);
} else {
require(launchedToken == token, "token mismatch");
}
// Refund over-subscribed $VIRT (decrement ledger before transfer).
for (uint256 i; i < s.refundAddresses.length; ++i) {
address u = s.refundAddresses[i];
// Over-subscription is returned via EITHER this PUSH path OR
// claimOverRefund's PULL, never both. Reject a wallet that already PULLED
// (its overRefundClaimed is set): settlement is batchable and pulls are
// permissionless, so a stale (pre-pull) refund batch could otherwise push
// a wallet its over-sub a SECOND time (audit: high, pull-then-push
// double-refund). Failing loud forces the operator to recompute the batch
// against fresh on-chain state instead of silently mis-splitting.
require(!overRefundClaimed[u], "over-refunded");
uint256 a = s.refundAmounts[i];
require(pledged[u] >= a, "refund > pledged");
// Mark so the wallet can NEVER also PULL the same residual via
// claimOverRefund (push-then-pull is blocked by its identical
// overRefundClaimed guard). The two paths are now mutually exclusive per
// wallet in BOTH directions. Operator invariant: push a wallet its EXACT
// fair over-sub share or omit it entirely for the pull path — a partial
// push consumes the wallet's one over-sub entitlement.
overRefundClaimed[u] = true;
pledged[u] -= a;
totalPledged -= a;
virtualToken.safeTransfer(u, a);
emit Refunded(u, a);
}
// Refunds may only return the over-subscription (everything pledged above
// the reserve); they must never eat into the reserve principal. This keeps
// the sweep $VIRT floor (totalPledged - reserveAmount) from underflowing.
require(totalPledged >= reserveAmount, "refunded into reserve");
// Record token claims (pull model). Each recipient is listed exactly
// once across all batches (revert on re-list), and the running total of
// recorded claims can never exceed the launched supply held here — so
// the contract itself guarantees every claim() can be satisfied.
for (uint256 i; i < s.distributeAddresses.length; ++i) {
address u = s.distributeAddresses[i];
// Monotonic list-once guard: `allocated` is never cleared (unlike
// claimable, which claim() zeroes), so a recipient cannot be
// re-recorded across batches even after they have already claimed.
require(!allocated[u], "duplicate recipient");
// Defense-in-depth: only a wallet that still holds a live pledge can
// be allocated tokens. Blocks a token claim for an address that
// already pulled its $VIRT back via refundSelf (would otherwise
// double-dip: $VIRT refund + launched tokens).
require(pledged[u] > 0, "not a live pledger");
allocated[u] = true;
claimable[u] = s.distributeAmounts[i];
totalClaimable += s.distributeAmounts[i];
}
require(totalClaimable <= IERC20(token).balanceOf(address(this)), "over-allocated");
emit Succeeded();
}
/// @notice Release up to `reserveAmount` $VIRT to fund the off-chain prebuy
/// (launchFee + initialPurchase). Operator-gated via the factory and
/// bounded by reserveAmount, so it can never reach the
/// over-subscription refunds (everything pledged above the reserve).
/// Only on a filled pool, before settlement — no isEnded() gate, so
/// the prebuy can be funded the instant the pool fills.
function releaseForLaunch(address to, uint256 amount) external onlyFactory nonReentrant {
require(reserveReached(), "not fillable");
require(token == address(0) && !isFailed && !isCancelled, "settled");
require(to != address(0), "zero addr");
// ONCE-ONLY: the launch funds the prebuy exactly once. Without this, a
// launch orchestration that spent (preLaunch) then threw before being
// checkpointed off-chain could be re-run, calling releaseForLaunch a second
// time — a partial double-spend whenever 2*amount <= reserveAmount.
require(releasedForLaunch == 0, "already released");
require(releasedForLaunch + amount <= reserveAmount, "exceeds reserve");
releasedForLaunch += amount;
virtualToken.safeTransfer(to, amount);
emit LaunchFunded(to, amount);
}
/// @notice Claim this pool's IMMEDIATE pledger allocation from the TokenTable
/// unlocker into the pool itself, so settleSuccess can distribute it.
/// Operator-gated via the factory; the pool is the recipient, so it
/// claims to itself. `actualIds` come from the off-chain tokenomics
/// lookup. settleSuccess's over-allocation guard then bounds claims
/// to whatever actually landed here.
function claimUnlocked(address unlocker, uint256[] calldata actualIds, uint256 batchId)
external
onlyFactory
nonReentrant
{
// Pre-launch only (mirrors releaseForLaunch's token==0 gate): the pledger
// supply is pulled in BEFORE settleSuccess records `token`, so pinning to
// the pre-launch phase also closes any post-settlement reachability.
require(token == address(0), "settled");
require(unlocker != address(0) && actualIds.length > 0 && actualIds.length <= MAX_CLAIM_IDS, "bad args");
// The unlocker is operator-supplied; never let it be aimed at the pool
// itself or the staked $VIRT (a mis-pointed claim could touch funds the
// escrow guards are protecting). (token is 0 here, so no token clause.)
require(unlocker != address(this) && unlocker != address(virtualToken), "bad unlocker");
address[] memory tos = new address[](actualIds.length);
for (uint256 i; i < actualIds.length; ++i) {
tos[i] = address(this);
}
IUnlocker(unlocker).claim(actualIds, tos, batchId, "");
}
/// @notice Pledger pulls their launched-token allocation. Open after success.
function claim(address user) external nonReentrant {
require(token != address(0), "not launched");
uint256 amount = claimable[user];
require(amount > 0, "nothing to claim");
claimable[user] = 0;
totalClaimable -= amount;
IERC20(token).safeTransfer(user, amount);
emit Claimed(user, amount);
}
/// @notice Pledger-pull for over-subscribed $VIRT that the operator did not
/// return via the settleSuccess refund batch (M1: an omitted pledger
/// otherwise has no self-service path post-success — fund-trap).
/// @dev Open only after success (`token != 0`); NOT gated against the launched-
/// token claim() — a pledger can pull both their tokens and their excess
/// $VIRT independently, in either order. The over-subscription basis is
/// frozen on the first pull: `overResidual = totalPledged - reserveAmount`
/// over `overTotalPledged = totalPledged`, so each wallet's entitlement is
/// `pledged[u] * overResidual / overTotalPledged`. The sum of all
/// entitlements is <= `overResidual` (floor division only ever rounds
/// DOWN, leaving wei-dust in the pool), so paying them out can never push
/// `totalPledged` below `reserveAmount` — the sweep $VIRT floor invariant
/// (`totalPledged >= reserveAmount`) is preserved. One pull per wallet
/// (overRefundClaimed guard) prevents double-refund. A wallet already
/// refunded via the settleSuccess PUSH path is also marked overRefundClaimed
/// there, so push and pull are mutually exclusive per wallet. Because the two
/// paths decrement the shared residual independently and the frozen basis can
/// lag later push batches, the pull is additionally CAPPED at the live
/// headroom (`totalPledged - reserveAmount`) so it can never breach the
/// reserve floor or revert on insufficient balance. Decrements
/// `pledged[u]`/`totalPledged` exactly like the settleSuccess refund loop.
function claimOverRefund() external nonReentrant {
require(token != address(0), "not launched");
require(!overRefundClaimed[msg.sender], "already refunded");
if (!overFrozen) {
overFrozen = true;
overTotalPledged = totalPledged;
// totalPledged >= reserveAmount is an invariant established by
// settleSuccess ("refunded into reserve" guard), so this never underflows.
overResidual = totalPledged - reserveAmount;
}
overRefundClaimed[msg.sender] = true;
if (overResidual == 0 || overTotalPledged == 0) {
// Exact fill — nothing over-subscribed. Mark claimed (idempotent) and
// return without moving funds so a no-op pull can't be spammed for gas.
emit OverRefunded(msg.sender, 0);
return;
}
uint256 p = pledged[msg.sender];
require(p > 0, "nothing pledged");
uint256 amount = (p * overResidual) / overTotalPledged;
// Reserve-floor cap. The push-refund path (settleSuccess) and this pull share
// the same over-sub residual but decrement it independently, and the frozen
// basis (overTotalPledged/overResidual) can lag later push batches that shrank
// the balance. Capping the pull at the LIVE headroom above the reserve
// guarantees totalPledged can never drop below reserveAmount (no insolvency /
// no draining reserve principal) and the transfer never reverts on
// insufficient balance — a best-effort backstop that pays what remains (down
// to 0) instead of bricking the caller (audit: high).
uint256 headroom = totalPledged > reserveAmount ? totalPledged - reserveAmount : 0;
if (amount > headroom) amount = headroom;
if (amount > 0) {
// Decrement the ledger before transfer (mirrors the settleSuccess refund
// loop). The cap above keeps totalPledged >= reserveAmount.
pledged[msg.sender] = p - amount;
totalPledged -= amount;
virtualToken.safeTransfer(msg.sender, amount);
}
emit OverRefunded(msg.sender, amount);
}
// ---- settlement: failure ----
/// @notice Freeze the pro-rata refund denominator on the first failure-path
/// refund. After freezing, `outstandingPledged` is the sum of pledges
/// still owed a refund and is decremented by each refunded pledge's
/// FULL amount — so `pledged[u] * balanceOf(this) / outstandingPledged`
/// distributes the residual $VIRT pro-rata across all remaining
/// pledgers. On a never-funded pool `releasedForLaunch == 0`, the
/// escrow still holds every pledged $VIRT, so balance == outstanding
/// and the ratio degenerates to 1:1 (legitimate filled-but-unreleased
/// abandon and ordinary unfilled-pool refunds are unchanged).
function _freezeRefundDenominator() internal {
if (!refundFrozen) {
refundFrozen = true;
outstandingPledged = totalPledged;
}
}
/// @notice Pro-rata-of-remaining-balance refund for `pledge` against the
/// frozen denominator. Caller MUST have already frozen the
/// denominator. Decrements `outstandingPledged` by the full pledge so
/// the ratio stays consistent across batched/sequential refunds.
function _proRataRefund(uint256 pledge_) internal returns (uint256 amount) {
// outstandingPledged is >= pledge_ here: it was frozen to totalPledged and
// is only ever reduced by previously-refunded pledges, and every live
// pledge is part of that frozen sum.
uint256 bal = virtualToken.balanceOf(address(this));
amount = (pledge_ * bal) / outstandingPledged;
outstandingPledged -= pledge_;
}
/// @notice Refund pledgers when the pool didn't fill (or was funded then
/// abandoned). Batched by index; when every participant is refunded
/// the pool is marked failed. Pays PRO-RATA of the remaining $VIRT
/// balance (degenerates to 1:1 when nothing was released for launch),
/// so a funded-then-abandoned pool whose reserve was already drained
/// splits the residual fairly instead of paying early callers in full
/// and stranding later ones (H1 bank-run insolvency).
function settleFailed(uint256[] calldata participantIndexes) external onlyFactory nonReentrant {
require(isEnded(), "not ended");
require(!isCancelled && !isFailed, "done");
require(token == address(0), "launched");
// A pool that hit its target is a success candidate, not a failure: never
// force-fail a filled pool here. (refundSelf still guards the genuinely
// abandoned funded case behind ABANDON_GRACE.)
require(!reserveReached(), "filled");
_freezeRefundDenominator();
for (uint256 i; i < participantIndexes.length; ++i) {
require(participantIndexes[i] < participants.length, "index oob");
address u = participants[participantIndexes[i]];
uint256 a = pledged[u];
if (a > 0) {
refundedCountOnFail++;
pledged[u] = 0;
totalPledged -= a;
uint256 pay = _proRataRefund(a);
if (pay > 0) virtualToken.safeTransfer(u, pay);
emit Refunded(u, pay);
}
}
if (refundedCountOnFail == participants.length) {
isFailed = true;
emit Failed();
}
}
/// @notice Pull your $VIRT back the moment an under-filled pool's window
/// closes — no operator, no grace. Gated on the pool NOT reaching
/// its target, so it can never refund a funded pool that is due to
/// launch (the griefing vector refundSelf's grace guards against).
/// Primary refund path; settleFailed (push) and refundSelf (grace
/// backstop for a funded-but-abandoned pool) remain available.
function claimRefund() external nonReentrant {
require(isEnded(), "not ended");
require(!reserveReached(), "filled");
require(token == address(0) && !isCancelled, "settled");
uint256 a = pledged[msg.sender];
require(a > 0, "nothing to refund");
refundedCountOnFail++;
// Freeze the pro-rata denominator to the FULL pre-refund totalPledged BEFORE
// decrementing the ledger — otherwise the first refunder's own pledge is
// excluded from the denominator (over-paying them, stranding later pledgers,
// and dividing by zero when they are the sole/last refunder). settleFailed
// freezes before its loop for exactly this reason.
_freezeRefundDenominator();
pledged[msg.sender] = 0;
totalPledged -= a;
// Pro-rata of the remaining balance for ledger consistency with the other
// failure paths. This path is gated on !reserveReached, and
// releaseForLaunch requires reserveReached, so releasedForLaunch is always
// 0 here => balance == outstandingPledged => exact 1:1 (unchanged behavior).
uint256 pay = _proRataRefund(a);
if (pay > 0) virtualToken.safeTransfer(msg.sender, pay);
emit Refunded(msg.sender, pay);
if (refundedCountOnFail == participants.length) {
isFailed = true;
emit Failed();
}
}
/// @notice Operator-inaction backstop: after the window + a grace period, if
/// the pool never launched and wasn't cancelled, any pledger can
/// reclaim their own $VIRT. Permissionless — bounds the risk of a
/// lost/idle operator key locking pledger funds.
function refundSelf() external nonReentrant {
require(token == address(0) && !isCancelled, "settled");
// Under-filled pools refund after the short grace; a FUNDED pool must
// wait the long abandon window, so a single pledger can't force-fail a
// funded launch during the normal grace (settleSuccess stays open).
uint256 grace = reserveReached() ? ABANDON_GRACE : SELF_REFUND_GRACE;
require(block.timestamp >= endTime + grace, "too early");
uint256 a = pledged[msg.sender];
require(a > 0, "nothing pledged");
refundedCountOnFail++;
// Freeze the pro-rata denominator to the FULL pre-refund totalPledged BEFORE
// decrementing the ledger (see claimRefund/settleFailed): otherwise the first
// refunder's own pledge is excluded from the denominator — over-paying them,
// stranding later pledgers, and dividing by zero when they are the sole/last
// refunder.
_freezeRefundDenominator();
pledged[msg.sender] = 0;
totalPledged -= a;
// Pro-rata of the remaining balance. On a funded-then-abandoned pool the
// reserve was already released for the prebuy (releasedForLaunch > 0), so
// the escrow holds LESS than the sum of pledges; paying 1:1 here let early
// callers drain the residual and stranded later pledgers (H1). Pro-rata of
// balance / outstandingPledged splits what remains fairly and degenerates
// to exact 1:1 on a never-released pool (releasedForLaunch == 0).
uint256 pay = _proRataRefund(a);
if (pay > 0) virtualToken.safeTransfer(msg.sender, pay);
emit Refunded(msg.sender, pay);
if (refundedCountOnFail == participants.length) {
isFailed = true;
emit Failed();
}
}
// ---- admin (factory-gated; factory itself role-gates the operator) ----
/// @notice Cancel before the window opens (e.g. spam/duplicate pool).
function cancel() external onlyFactory {
// Cancellable while no funds are at stake: before end and with zero
// pledged — covers pre-start and started-but-empty (spam) pools.
require(totalPledged == 0 && !isEnded() && !isFailed && !isCancelled, "not cancellable");
isCancelled = true;
emit Cancelled();
}
/// @notice Reschedule the window before it opens.
function resetWindow(uint256 newStart, uint256 newEnd) external onlyFactory {
require(!isStarted() && !isFailed && !isCancelled, "started");
require(newEnd > newStart && newEnd > block.timestamp, "bad window");
startTime = newStart;
endTime = newEnd;
emit WindowReset(newStart, newEnd);
}
/// @notice Sweep leftover assets after the pool is FINALIZED — rounding dust
/// and any stray tokens. (The dev's 8.5% is vested on Virtuals'
/// TokenTable and never enters this Pool.) Never drains escrowed $VIRT
/// before settlement, never sweeps reserve principal that wasn't
/// released for the prebuy, and never moves launched tokens still owed
/// to pledgers via claimable[].
function sweep(address to, address tkn, uint256 amount) external onlyFactory nonReentrant {
require(token != address(0) || isFailed || isCancelled, "not finalized");
require(to != address(0) && tkn != address(0), "zero addr");
if (tkn == token) {
require(IERC20(tkn).balanceOf(address(this)) - amount >= totalClaimable, "owed to pledgers");
} else if (tkn == address(virtualToken) && token != address(0)) {
// Post-launch, keep enough $VIRT to cover BOTH outstanding
// over-subscription refunds AND any reserve principal that was never
// released to fund the prebuy. Flooring at totalPledged -
// releasedForLaunch (>= the old totalPledged - reserveAmount, since
// releasedForLaunch <= reserveAmount) means admin sweep can never
// touch pledger principal still sitting in the pool — only true
// rounding dust below the floor. Saturating subtraction so a recovery
// path never underflow-reverts.
uint256 owed = totalPledged > releasedForLaunch ? totalPledged - releasedForLaunch : 0;
require(IERC20(tkn).balanceOf(address(this)) - amount >= owed, "owed to pledgers");
}
IERC20(tkn).safeTransfer(to, amount);
emit Swept(to, tkn, amount);
}
// ---- views ----
function isStarted() public view returns (bool) {
return block.timestamp >= startTime;
}
function isEnded() public view returns (bool) {
return block.timestamp >= endTime;
}
/// @notice Whether the off-chain success threshold (the raise target) is met.
function reserveReached() public view returns (bool) {
return totalPledged >= reserveAmount;
}
function participantCount() external view returns (uint256) {
return participants.length;
}
function participantsPaginated(uint256 startIndex, uint256 pageSize)
external
view
returns (address[] memory page)
{
uint256 len = participants.length;
if (startIndex >= len) return new address[](0);
uint256 end = startIndex + pageSize;
if (end > len) end = len;
page = new address[](end - startIndex);
for (uint256 i; i < page.length; ++i) {
page[i] = participants[startIndex + i];
}
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "p",
"type": "tuple",
"components": [
{
"name": "poolId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "factory",
"type": "address",
"internalType": "address"
},
{
"name": "virtualToken",
"type": "address",
"internalType": "address"
},
{
"name": "name",
"type": "string",
"internalType": "string"
},
{
"name": "ticker",
"type": "string",
"internalType": "string"
},
{
"name": "devRecipient",
"type": "address",
"internalType": "address"
},
{
"name": "startTime",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "endTime",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "reserveAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maxContribution",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minContribution",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokenTotalSupply",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tokenLpSupply",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct PoolInitParams"
}
],
"stateMutability": "nonpayable"
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "Cancelled",
"type": "event",
"inputs": [],
"anonymous": false
},
{
"name": "Claimed",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Failed",
"type": "event",
"inputs": [],
"anonymous": false
},
{
"name": "LaunchFunded",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Launched",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OverRefunded",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Pledged",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Refunded",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Succeeded",
"type": "event",
"inputs": [],
"anonymous": false
},
{
"name": "Swept",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "WindowReset",
"type": "event",
"inputs": [
{
"name": "startTime",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "endTime",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ABANDON_GRACE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_CLAIM_IDS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_NAME_BYTES",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_TICKER_BYTES",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "SELF_REFUND_GRACE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "allocated",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "cancel",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claim",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimOverRefund",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimRefund",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimUnlocked",
"type": "function",
"inputs": [
{
"name": "unlocker",
"type": "address",
"internalType": "address"
},
{
"name": "actualIds",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "batchId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "claimable",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "devRecipient",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "endTime",
"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": "isCancelled",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "isEnded",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "isFailed",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "isStarted",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "maxContribution",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "minContribution",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "outstandingPledged",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "overFrozen",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "overRefundClaimed",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "overResidual",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "overTotalPledged",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "participantCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "participants",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "participantsPaginated",
"type": "function",
"inputs": [
{
"name": "startIndex",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "pageSize",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "page",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"name": "pledge",
"type": "function",
"inputs": [
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "pledged",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "poolId",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "refundFrozen",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "refundSelf",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "refundedCountOnFail",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "releaseForLaunch",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "releasedForLaunch",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "reserveAmount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "reserveReached",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "resetWindow",
"type": "function",
"inputs": [
{
"name": "newStart",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "newEnd",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settleFailed",
"type": "function",
"inputs": [
{
"name": "participantIndexes",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "settleSuccess",
"type": "function",
"inputs": [
{
"name": "launchedToken",
"type": "address",
"internalType": "address"
},
{
"name": "s",
"type": "tuple",
"components": [
{
"name": "refundAddresses",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "refundAmounts",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "distributeAddresses",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "distributeAmounts",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"internalType": "struct PoolSettlement"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "startTime",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "sweep",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "tkn",
"type": "address",
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "ticker",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "token",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "tokenLpSupply",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "tokenTotalSupply",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "totalClaimable",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "totalPledged",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "virtualToken",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IERC20"
}
],
"stateMutability": "view"
}
]0x6080806040526004361015610012575f80fd5b5f905f3560e01c9081630429c6071461236c5750806306fdde03146122b25780631e83409a146121da5780631f514c52146121965780632d92467b14612179578063310eb2cb146120a15780633197cbb61461208457806335c1d34914612042578063362f04c014612025578063380ef4511461197f5780633e0dc34e14611945578063402914f51461190d5780634225e5bb146118d05780634838ed19146118b35780634a47e36b146118795780634b09b72a1461183f578063544736e61461181f57806354bdc6e91461180257806355468ba4146117e557806362c06767146114ef578063680c60c7146114d45780636b81e11b1461149c5780637326c9c01461119f57806373309a751461118257806378e97925146111655780638ba47bdd146110675780638d3d65761461102d57806390d9adfd14610f0357806392a677b014610ee657806395ee122114610ec15780639879eea814610c445780639b7f48d814610c00578063a052d99314610bc0578063a4fd6f5614610ba0578063a5a2070514610b85578063aaffadf314610b4b578063b5545a3c14610986578063c45a015514610942578063cc7bc06614610905578063d0d4161c146108e3578063d78c23be14610712578063e53fd97b146106f5578063ea8a1af0146105fb578063f0b08aa5146105de578063f2d5f296146105c3578063f41633401461059e578063f4400b691461034b578063f7abab9e14610310578063f804fd4a146102ed578063f9762f4d146102b8578063fc0c546a1461028f5763ff9a81441461025a575f80fd5b3461028c5761028861027461026e3661244f565b90612a39565b604051918291602083526020830190612496565b0390f35b80fd5b503461028c578060031936011261028c576012546040516001600160a01b039091168152602090f35b503461028c578060031936011261028c576102d1612ae4565b6102d96127ff565b60015f80516020612c648339815191525580f35b503461028c578060031936011261028c57602060ff600f54166040519015158152f35b503461028c578060031936011261028c5760206040517f0000000000000000000000000000000000000000033b2e3c9fd0803ce80000008152f35b50346104e0576003196060368201126104e0576103666123f0565b9067ffffffffffffffff906024358281116104e057610389903690600401612465565b90939091906001600160a01b039081906103c6337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5758416146125bd565b6103ce612ae4565b6103dc82601254161561252e565b169081151580610595575b8061058a575b1561055a5730821415908161052d575b50156104f95761040c83612788565b925f5b8181106104e45750813b156104e057604051633ac1db0960e01b81526080600482015260848101829052956001600160fb1b0382116104e057602087945f610475819860a483968a9860051b8091838b0137880160a08982030160248a01520190612496565b604435604487015285810392830160648701525201925af180156104d5576104ad575b8260015f80516020612c648339815191525580f35b90809250116104c1576040525f8080610498565b634e487b7160e01b5f52604160045260245ffd5b6040513d5f823e3d90fd5b5f80fd5b600190306104f282886127ba565b520161040f565b60405162461bcd60e51b815260206004820152600c60248201526b3130b2103ab73637b1b5b2b960a11b6044820152606490fd5b90507f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31168114155f6103fd565b60405162461bcd60e51b8152602060048201526008602482015267626164206172677360c01b6044820152606490fd5b5060328411156103ed565b508315156103e7565b346104e0575f3660031901126104e057602060ff60125460a01c166040519015158152f35b346104e0575f3660031901126104e057602060405160328152f35b346104e0575f3660031901126104e0576020601054604051908152f35b346104e0575f3660031901126104e05761063f337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5756001600160a01b0316146125bd565b60085415806106ea575b806106da575b806106ca575b15610693576012805460ff60a81b1916600160a81b1790557f63b958841f79ab97cb5456da181454b9932c0e15a3b17f1cbd27e2a8bc6104375f80a1005b60405162461bcd60e51b815260206004820152600f60248201526e6e6f742063616e63656c6c61626c6560881b6044820152606490fd5b5060ff60125460a81c1615610655565b5060ff60125460a01c161561064f565b506003544210610649565b346104e0575f3660031901126104e0576020600954604051908152f35b346104e05760403660031901126104e05761072b6123f0565b602435906001600160a01b03610764337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5758316146125bd565b61076c612ae4565b6008549061079d7f00000000000000000000000000000000000000000000065a4da25d3016c00000809310156125f7565b6107ba6012548281161590816108d3575b816108c4575b5061252e565b8216926107c884151561268c565b600b54918261088c576107db8284612564565b116108555761083b817fdf72705ce432638520ab777f5c9cd76ac0deffbc7c6b8d77493d3808ade3a5589461081282602096612564565b600b557f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31612b13565b604051908152a260015f80516020612c6483398151915255005b60405162461bcd60e51b815260206004820152600f60248201526e65786365656473207265736572766560881b6044820152606490fd5b60405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e481c995b19585cd95960821b6044820152606490fd5b60ff915060a81c1615866107b4565b905060ff8160a01c1615906107ae565b346104e0575f3660031901126104e057602060ff600d54166040519015158152f35b346104e05760203660031901126104e0576001600160a01b036109266123f0565b165f52600e602052602060ff60405f2054166040519015158152f35b346104e0575f3660031901126104e0576040517f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5756001600160a01b03168152602090f35b346104e0575f3660031901126104e05761099e612ae4565b6109ac600354421015612703565b6109d96008547f00000000000000000000000000000000000000000000065a4da25d3016c000001161273b565b6012546109f7906001600160a01b038116159081610b3c575061252e565b335f52600460205260405f20548015610b0357610a4690610a196009546125af565b600955610a24612b91565b335f5260046020525f6040812055610a3e8160085461250d565b600855612bb2565b80610ad3575b6040519081527fd7dee2702d63ad89917b6a4da9981c90c4d24f8c2bdfd64c604ecae57d8d065160203392a260095460075414610a97575b60015f80516020612c6483398151915255005b6012805460ff60a01b1916600160a01b1790557f625a40e68d9554793bf647bf32e4885e7f15bd1bfac262906cc7d26f376f20a25f80a1610a84565b610afe81337f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31612b13565b610a4c565b60405162461bcd60e51b81526020600482015260116024820152701b9bdd1a1a5b99c81d1bc81c99599d5b99607a1b6044820152606490fd5b60ff915060a81c1615826107b4565b346104e0575f3660031901126104e05760206040517f0000000000000000000000000000000000000000000000000de0b6b3a76400008152f35b346104e0575f3660031901126104e057602060405160108152f35b346104e0575f3660031901126104e0576020600354421015604051908152f35b346104e0575f3660031901126104e0576020600854604051907f00000000000000000000000000000000000000000000065a4da25d3016c0000011158152f35b346104e0575f3660031901126104e0576040517f000000000000000000000000384d92776496bce2c6f08d5b8e015eae498e78b36001600160a01b03168152602090f35b346104e0576020806003193601126104e05760043567ffffffffffffffff81116104e057610c76903690600401612465565b916001600160a01b03610cac337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5758316146125bd565b610cb4612ae4565b600390610cc5600354421015612703565b60125460ff8160a81c161580610eb3575b15610e88578116610e5857600891610d116008547f00000000000000000000000000000000000000000000065a4da25d3016c000001161273b565b610d19612b91565b5f5b868110610d405760095460075414610a975760015f80516020612c6483398151915255005b610d4b818888612668565b356007541115610e27578083610d6d610d676001948b8b612668565b35612406565b905490851b1c16805f526004875260405f20548781610d90575b50505001610d1b565b610de27fd7dee2702d63ad89917b6a4da9981c90c4d24f8c2bdfd64c604ecae57d8d0651926009610dc181546125af565b9055845f52600483525f6040812055610ddb818b5461250d565b8a55612bb2565b80610df7575b604051908152a2888087610d87565b610e2281857f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31612b13565b610de8565b60405162461bcd60e51b815260048101869052600960248201526834b73232bc1037b7b160b91b6044820152606490fd5b60405162461bcd60e51b81526004810184905260086024820152671b185d5b98da195960c21b6044820152606490fd5b60405162461bcd60e51b81526004808201869052602482015263646f6e6560e01b6044820152606490fd5b5060ff8160a01c1615610cd6565b346104e0575f3660031901126104e057602060ff60125460a81c166040519015158152f35b346104e0575f3660031901126104e0576020600c54604051908152f35b346104e057610f113661244f565b610f45337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5756001600160a01b0316146125bd565b60025442108061101d575b8061100d575b15610fde5781811180610fd5575b15610fa357816040917f50d926d13f7e01d114aa79ad3d8eb3dc4e0d60d51713f8634e9a4a088e0a45b5936002558060035582519182526020820152a1005b60405162461bcd60e51b815260206004820152600a6024820152696261642077696e646f7760b01b6044820152606490fd5b50428111610f64565b60405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b6044820152606490fd5b5060ff60125460a81c1615610f56565b5060ff60125460a01c1615610f50565b346104e0575f3660031901126104e05760206040517f00000000000000000000000000000000000000000000001043561a88293000008152f35b346104e0575f3660031901126104e0576040515f9060018054908160011c906001831692831561115b575b60209384841081146111475783865290811561112757506001146110cd575b610288846110c181880382612387565b604051918291826123a9565b60015f9081529294507fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8284106111145750505081610288936110c192820101936110b1565b80548585018701529285019281016110f8565b60ff1916858501525050151560051b82010191506110c1816102886110b1565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611092565b346104e0575f3660031901126104e0576020600254604051908152f35b346104e0575f3660031901126104e0576020600b54604051908152f35b346104e0576020806003193601126104e057600435906111bd612ae4565b60025442101580611491575b80611466575b80611453575b80611443575b80611433575b15611402577f0000000000000000000000000000000000000000000000000de0b6b3a764000082106113d257335f52600481526112228260405f2054612564565b7f00000000000000000000000000000000000000000000001043561a8829300000106113a057335f526004815260405f20541561135b575b335f526004815260405f20611270838254612564565b905561127e82600854612564565b6008557f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31604051906323b872dd60e01b5f52336004523060245283604452825f60648180855af160015f511481161561133c575b826040525f6060521561131e57837f2726ce6e3b7987cbbb10c5a55b44725526c540fbba590cfc20afab691fa45edf846040519283523392a260015f80516020612c6483398151915255005b635274afe760e01b82526001600160a01b0316600482015260249150fd5b600181151661135257813b15153d1516166112d2565b823d5f823e3d90fd5b600754680100000000000000008110156104c15780600161137f9201600755612406565b81546001600160a01b0360039290921b91821b19163390911b17905561125a565b6064906040519062461bcd60e51b82526004820152600b60248201526a065786365656473206361760ac1b6044820152fd5b6064906040519062461bcd60e51b8252600482015260096024820152683132b637bb9036b4b760b91b6044820152fd5b6064906040519062461bcd60e51b82526004820152600a6024820152696e6f742061637469766560b01b6044820152fd5b5060ff60125460a81c16156111e1565b5060ff60125460a01c16156111db565b506012546001600160a01b0316156111d5565b506008547f00000000000000000000000000000000000000000000065a4da25d3016c00000116111cf565b5060035442106111c9565b346104e05760203660031901126104e0576001600160a01b036114bd6123f0565b165f526004602052602060405f2054604051908152f35b346104e0575f3660031901126104e057602060405160408152f35b346104e05760603660031901126104e0576115086123f0565b6001600160a01b0360243581811692908390036104e05760443590611550837f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5751633146125bd565b611558612ae4565b60125483811693841580159283916117d6575b81156117c8575b501561179357808316948515158061178a575b61158e9061268c565b8603611658575050906040516370a0823160e01b8152306004820152602081602481885afa9081156104d5575f91611622575b5090611608817f7b09c29f9106defeccc9ac3b823f3aad0b470d120e5df7aed033b5c43a4bf718946116026115f88360209761250d565b600a5411156126c4565b87612b13565b604051908152a360015f80516020612c6483398151915255005b9190506020823d602011611650575b8161163e60209383612387565b810103126104e05790516116086115c1565b3d9150611631565b7f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c311685149081611782575b506116b7575b816116087f7b09c29f9106defeccc9ac3b823f3aad0b470d120e5df7aed033b5c43a4bf71893602093611602565b600854600b548082111561177a576116ce9161250d565b6040516370a0823160e01b8152306004820152602081602481895afa9081156104d5575f91611742575b508360209361173782946117307f7b09c29f9106defeccc9ac3b823f3aad0b470d120e5df7aed033b5c43a4bf718986116089661250d565b10156126c4565b935050509150611689565b90506020939193813d602011611772575b8161176060209383612387565b810103126104e05751909290836116f8565b3d9150611753565b50505f6116ce565b905085611683565b50861515611585565b60405162461bcd60e51b815260206004820152600d60248201526c1b9bdd08199a5b985b1a5e9959609a1b6044820152606490fd5b60ff915060a81c1687611572565b905060ff8160a01c169061156b565b346104e0575f3660031901126104e0576020600854604051908152f35b346104e0575f3660031901126104e0576020601154604051908152f35b346104e0575f3660031901126104e0576020600254421015604051908152f35b346104e0575f3660031901126104e05760206040517f00000000000000000000000000000000000000000000065a4da25d3016c000008152f35b346104e0575f3660031901126104e05760206040517f0000000000000000000000000000000000000000007c13bc4b2c133c560000008152f35b346104e0575f3660031901126104e0576020600a54604051908152f35b346104e05760203660031901126104e0576001600160a01b036118f16123f0565b165f526006602052602060ff60405f2054166040519015158152f35b346104e05760203660031901126104e0576001600160a01b0361192e6123f0565b165f526005602052602060405f2054604051908152f35b346104e0575f3660031901126104e05760206040517f000000000000000000000000000000000000000000000000000000000000009b8152f35b346104e0576003196040368201126104e0576119996123f0565b602480359267ffffffffffffffff84116104e05760809084360301126104e0576119ed337f0000000000000000000000008059985b13a2aadef884e8b01fe3ce147352b5756001600160a01b0316146125bd565b6119f5612ae4565b60085491611a267f00000000000000000000000000000000000000000000065a4da25d3016c00000809410156125f7565b6012549060ff8260a81c16611ff55760ff8260a01c16611fc857611a4d6004860180612632565b9050611a5e84870187600401612632565b91905003611f9757611a766044860186600401612632565b9050611a886064870187600401612632565b91905003611f62576001600160a01b03821680611f1a57506001600160a01b0316908115611ee9576001600160a01b03191681176012557fb900795bb40f8a7bc484866009ca19ebf7b277001a839428e1b8e1a21d8e216c5f80a25b5f5b611af36004850180612632565b9050811015611c7d57611b1b611b1682611b106004880180612632565b90612668565b612678565b6001600160a01b0381165f908152600e602052604090205460ff16611c4957611b4d82611b1085880188600401612632565b359060018060a01b0381165f5260046020528160405f205410611c1257907fd7dee2702d63ad89917b6a4da9981c90c4d24f8c2bdfd64c604ecae57d8d0651602060019493858060a01b0381165f52600e825260405f208660ff198254161790556004825260405f20611bc185825461250d565b9055611bcf8460085461250d565b600855611bfd84827f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31612b13565b604051938452858060a01b031692a201611ae6565b60405162461bcd60e51b8152602060048201526010818601526f1c99599d5b99080f881c1b195919d95960821b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d818501526c1bdd995c8b5c99599d5b991959609a1b6044820152606490fd5b50919060085410611ead575f5b611c9a6044830183600401612632565b9050811015611dc85780611cc9611b16611cba6044860186600401612632565b6001600160a01b039491612668565b16805f52600660209080825260ff60405f205416611d8e57825f526004825260405f205415611d55578291600591600195945f52815260405f208560ff19825416179055611d2184611b106064890189600401612632565b35925f525260405f2055611d3f81611b106064860186600401612632565b35611d4d600a918254612564565b905501611c8a565b60405162461bcd60e51b815260048101839052601281880152713737ba1030903634bb3290383632b233b2b960711b6044820152606490fd5b60405162461bcd60e51b81526004810183905260138188015272191d5c1b1a58d85d19481c9958da5c1a595b9d606a1b6044820152606490fd5b600a546012546040516370a0823160e01b8152306004820152859290916020908390859082906001600160a01b03165afa9182156104d5575f92611e79575b5011611e44577f318ba0c588a4bde325b55ebf926bfa606b77d9971ac5fc7250a615885daf9d5c5f80a160015f80516020612c6483398151915255005b606490600e6040519162461bcd60e51b8352602060048401528201526d1bdd995c8b585b1b1bd8d85d195960921b6044820152fd5b9091506020813d602011611ea5575b81611e9560209383612387565b810103126104e057519083611e07565b3d9150611e88565b60405162461bcd60e51b81526020600482015260158184015274726566756e64656420696e746f207265736572766560581b6044820152606490fd5b60405162461bcd60e51b815260206004820152600a81850152693d32b937903a37b5b2b760b11b6044820152606490fd5b6001600160a01b0391909116149050611ae457606490600e6040519162461bcd60e51b8352602060048401528201526d0e8ded6cadc40dad2e6dac2e8c6d60931b6044820152fd5b60405162461bcd60e51b815260206004820152600e818501526d3234b9ba3934b13aba32903632b760911b6044820152606490fd5b60405162461bcd60e51b815260206004820152600a81850152693932b33ab732103632b760b11b6044820152606490fd5b60405162461bcd60e51b8152602060048201526006818501526519985a5b195960d21b6044820152606490fd5b60405162461bcd60e51b8152602060048201526009818501526818d85b98d95b1b195960ba1b6044820152606490fd5b346104e0575f3660031901126104e0576020600754604051908152f35b346104e05760203660031901126104e0576004356007548110156104e05761206b602091612406565b905460405160039290921b1c6001600160a01b03168152f35b346104e0575f3660031901126104e0576020600354604051908152f35b346104e0575f3660031901126104e0576120b9612ae4565b6012546120d7906001600160a01b038116159081610b3c575061252e565b6008547f00000000000000000000000000000000000000000000065a4da25d3016c000001161216d5761211062278d005b600354612564565b421061213c57335f526004602052610a4660405f2054612131811515612571565b610a196009546125af565b60405162461bcd60e51b8152602060048201526009602482015268746f6f206561726c7960b81b6044820152606490fd5b61211062093a80612108565b346104e0575f3660031901126104e057602060405162278d008152f35b346104e0575f3660031901126104e0576040517f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c316001600160a01b03168152602090f35b346104e05760203660031901126104e0576121f36123f0565b6121fb612ae4565b6012546001600160a01b03919061221590831615156124d2565b81811691825f52600560205260405f2054801561227a5761083b817fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a94602094875f52600586525f604081205561226e83600a5461250d565b600a5560125416612b13565b60405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606490fd5b346104e0575f3660031901126104e0576040515f905f5460018160011c9060018316928315612362575b602093848410811461114757838652908115611127575060011461230a57610288846110c181880382612387565b5f8080529294507f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b82841061234f5750505081610288936110c192820101936110b1565b8054858501870152928501928101612333565b91607f16916122dc565b346104e0575f3660031901126104e0578062093a8060209252f35b90601f8019910116810190811067ffffffffffffffff8211176104c157604052565b602080825282518183018190529093925f5b8281106123dc57505060409293505f838284010152601f8019910116010190565b8181018601518482016040015285016123bb565b600435906001600160a01b03821682036104e057565b60075481101561243b5760075f527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801905f90565b634e487b7160e01b5f52603260045260245ffd5b60409060031901126104e0576004359060243590565b9181601f840112156104e05782359167ffffffffffffffff83116104e0576020808501948460051b0101116104e057565b9081518082526020808093019301915f5b8281106124b5575050505090565b83516001600160a01b0316855293810193928101926001016124a7565b156124d957565b60405162461bcd60e51b815260206004820152600c60248201526b1b9bdd081b185d5b98da195960a21b6044820152606490fd5b9190820391821161251a57565b634e487b7160e01b5f52601160045260245ffd5b1561253557565b60405162461bcd60e51b81526020600482015260076024820152661cd95d1d1b195960ca1b6044820152606490fd5b9190820180921161251a57565b1561257857565b60405162461bcd60e51b815260206004820152600f60248201526e1b9bdd1a1a5b99c81c1b195919d959608a1b6044820152606490fd5b5f19811461251a5760010190565b156125c457565b60405162461bcd60e51b815260206004820152600b60248201526a6e6f7420666163746f727960a81b6044820152606490fd5b156125fe57565b60405162461bcd60e51b815260206004820152600c60248201526b6e6f742066696c6c61626c6560a01b6044820152606490fd5b903590601e19813603018212156104e0570180359067ffffffffffffffff82116104e057602001918160051b360383136104e057565b919081101561243b5760051b0190565b356001600160a01b03811681036104e05790565b1561269357565b60405162461bcd60e51b81526020600482015260096024820152683d32b9379030b2323960b91b6044820152606490fd5b156126cb57565b60405162461bcd60e51b815260206004820152601060248201526f6f77656420746f20706c65646765727360801b6044820152606490fd5b1561270a57565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd08195b99195960ba1b6044820152606490fd5b1561274257565b60405162461bcd60e51b8152602060048201526006602482015265199a5b1b195960d21b6044820152606490fd5b67ffffffffffffffff81116104c15760051b60200190565b9061279282612770565b61279f6040519182612387565b82815280926127b0601f1991612770565b0190602036910137565b805182101561243b5760209160051b010190565b8181029291811591840414171561251a57565b81156127eb570490565b634e487b7160e01b5f52601260045260245ffd5b601254612816906001600160a01b031615156124d2565b335f526020600e8152604060ff815f205416612a0357600f5460ff8116156129be575b50335f52600e8252805f20600160ff1982541617905560115491821580156129b4575b61298657335f526004815261288c612883835f20549461287d861515612571565b856127ce565b601054906127e1565b916008547f00000000000000000000000000000000000000000000065a4da25d3016c000008082115f1461297e576128c39161250d565b808411612956575b508293837ff4bace1d5aba9137ba0e05251376501b45c5caeea0fdce658630b61ae6363dca94612901575b5050519283523392a2565b61290a9161250d565b335f5260048352815f20556129218460085461250d565b60085561294f84337f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c31612b13565b5f846128f6565b92507ff4bace1d5aba9137ba0e05251376501b45c5caeea0fdce658630b61ae6363dca6128cb565b50505f6128c3565b91507ff4bace1d5aba9137ba0e05251376501b45c5caeea0fdce658630b61ae6363dca9051915f83523392a2565b506010541561285c565b60019060ff191617600f556129fa600854806010557f00000000000000000000000000000000000000000000065a4da25d3016c000009061250d565b6011555f612839565b60649250519062461bcd60e51b82526004820152601060248201526f185b1c9958591e481c99599d5b99195960821b6044820152fd5b91906007549081841015612ab95783612a6d92612a59612a689383612564565b90808211612ab1575b5061250d565b612788565b915f5b8351811015612aad5780612a8e612a8960019385612564565b612406565b838060a01b0391549060031b1c16612aa682876127ba565b5201612a70565b5050565b90505f612a62565b505090506040516020810181811067ffffffffffffffff8211176104c1576040525f81525f36813790565b5f80516020612c648339815191526002815414612b015760029055565b604051633ee5aeb560e01b8152600490fd5b60405163a9059cbb60e01b5f9081526001600160a01b039384166004526024949094529260209060448180855af160015f5114811615612b72575b8360405215612b5c57505050565b635274afe760e01b835216600482015260249150fd5b6001811516612b8857813b15153d151616612b4e565b833d5f823e3d90fd5b600d5460ff811615612ba05750565b60ff1916600117600d55600854600c55565b6040516370a0823160e01b81523060048201529091906020816024817f000000000000000000000000c6911796042b15d7fa4f6cde69e245ddcd3d9c316001600160a01b03165afa9081156104d5575f91612c2f575b50612c16612c2a91846127ce565b92612c24600c5480956127e1565b9361250d565b600c55565b90506020813d602011612c5b575b81612c4a60209383612387565b810103126104e05751612c16612c08565b3d9150612c3d56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220142978689ad1ccd65c13f852ff60d7af3a0553b999c400f80b45afb17718e72c64736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| VIRTUAL | 1,802 | $0.561 | $1,011.39 | |
| DIH | 1 | $0.0000102 | $0 |
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x606137…be7142 | 15 days agoSat, 01 Aug 2026 07:49:31 UTC | 0xd7dee2…0651 | [0] 0x000000000000…7ce106cf data: 0x000000000000000000…29300000 |
| 0x14d09a…c4e8d9 | 15 days agoSat, 01 Aug 2026 07:47:50 UTC | 0xd7dee2…0651 | [0] 0x000000000000…a5fb9529 data: 0x000000000000000000…29300000 |
| 0xc583d4…2a5510 | 20 days agoMon, 27 Jul 2026 00:27:12 UTC | 0xd7dee2…0651 | [0] 0x000000000000…728a4951 data: 0x000000000000000000…29300000 |
| 0xb3daa9…7136e1 | 20 days agoMon, 27 Jul 2026 00:24:27 UTC | 0xd7dee2…0651 | [0] 0x000000000000…8b2e4985 data: 0x000000000000000000…29300000 |
| 0xab1c8a…532e87 | 21 days agoSat, 25 Jul 2026 23:31:47 UTC | 0xd7dee2…0651 | [0] 0x000000000000…2d9e05bb data: 0x000000000000000000…29300000 |
| 0x507232…88393e | 21 days agoSat, 25 Jul 2026 23:31:03 UTC | 0xd7dee2…0651 | [0] 0x000000000000…fd37369a data: 0x000000000000000000…29300000 |
| 0x47da38…e48a6b | 22 days agoSat, 25 Jul 2026 10:33:13 UTC | 0xd7dee2…0651 | [0] 0x000000000000…efcd2adb data: 0x000000000000000000…451c0000 |
| 0x44d831…1d44c5 | 22 days agoSat, 25 Jul 2026 06:34:28 UTC | 0xd7dee2…0651 | [0] 0x000000000000…a7acb4a2 data: 0x000000000000000000…29300000 |
| 0xa9cfe6…2fc76b | 23 days agoThu, 23 Jul 2026 23:30:37 UTC | 0xd7dee2…0651 | [0] 0x000000000000…016613d3 data: 0x000000000000000000…27a00000 |
| 0xa73baa…43397a | 24 days agoThu, 23 Jul 2026 17:06:21 UTC | 0xd7dee2…0651 | [0] 0x000000000000…cb66a8c3 data: 0x000000000000000000…314c0000 |
| 0x9667cb…d0e0cc | 24 days agoThu, 23 Jul 2026 16:14:10 UTC | 0xd7dee2…0651 | [0] 0x000000000000…b6c08a95 data: 0x000000000000000000…29300000 |
| 0x3a0bdd…fbaf49 | 24 days agoThu, 23 Jul 2026 14:54:13 UTC | 0xd7dee2…0651 | [0] 0x000000000000…b01b9949 data: 0x000000000000000000…44f40000 |
| 0xa02262…1364b1 | 24 days agoThu, 23 Jul 2026 14:54:09 UTC | 0xd7dee2…0651 | [0] 0x000000000000…1feec319 data: 0x000000000000000000…29300000 |
| 0x8325d8…1c756e | 24 days agoThu, 23 Jul 2026 14:52:56 UTC | 0xd7dee2…0651 | [0] 0x000000000000…f6436fdf data: 0x000000000000000000…29300000 |
| 0x8f1718…3f13f6 | 24 days agoThu, 23 Jul 2026 14:49:38 UTC | 0xd7dee2…0651 | [0] 0x000000000000…24aa4839 data: 0x000000000000000000…29300000 |
| 0x6318b1…bcdb33 | 24 days agoThu, 23 Jul 2026 14:15:26 UTC | 0xd7dee2…0651 | [0] 0x000000000000…0870b884 data: 0x000000000000000000…29300000 |
| 0x310f23…a5bc1a | 24 days agoThu, 23 Jul 2026 13:58:03 UTC | 0xd7dee2…0651 | [0] 0x000000000000…dd3f435d data: 0x000000000000000000…6d5c0000 |
| 0x328331…bdd8c9 | 24 days agoThu, 23 Jul 2026 13:06:27 UTC | 0xd7dee2…0651 | [0] 0x000000000000…28b7a584 data: 0x000000000000000000…27a00000 |
| 0x475e18…dfb5c9 | 24 days agoThu, 23 Jul 2026 11:16:11 UTC | 0xd7dee2…0651 | [0] 0x000000000000…d41e2b31 data: 0x000000000000000000…04f60000 |
| 0x9166cd…ed6308 | 24 days agoThu, 23 Jul 2026 09:30:32 UTC | 0xd7dee2…0651 | [0] 0x000000000000…e463b14a data: 0x000000000000000000…29300000 |
| 0x5c0930…f41647 | 24 days agoThu, 23 Jul 2026 04:04:05 UTC | 0xd7dee2…0651 | [0] 0x000000000000…ae7197c5 data: 0x000000000000000000…29300000 |
| 0x53f00c…f63ec0 | 24 days agoThu, 23 Jul 2026 00:47:14 UTC | 0xd7dee2…0651 | [0] 0x000000000000…7e3dfbfc data: 0x000000000000000000…89e80000 |
| 0x7b42b7…7ecbe4 | 24 days agoThu, 23 Jul 2026 00:42:19 UTC | 0xd7dee2…0651 | [0] 0x000000000000…13665345 data: 0x000000000000000000…bbd40000 |
| 0x92ba46…fa9dbb | 24 days agoThu, 23 Jul 2026 00:17:42 UTC | 0xd7dee2…0651 | [0] 0x000000000000…bc07e9d5 data: 0x000000000000000000…29300000 |
| 0xdadf8e…926f84 | 24 days agoThu, 23 Jul 2026 00:16:27 UTC | 0xd7dee2…0651 | [0] 0x000000000000…a2f7b92c data: 0x000000000000000000…29300000 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x606137…be7142 | claimRefund | 24,872,399 | 15 days agoSat, 01 Aug 2026 07:49:31 UTC | 0x56cb…06cf | IN | Pool | $0.000 ETH | 0.00000135 | |
| 0x14d09a…c4e8d9 | claimRefund | 24,871,390 | 15 days agoSat, 01 Aug 2026 07:47:50 UTC | 0x9f84…9529 | IN | Pool | $0.000 ETH | 0.00000136 | |
| 0xc583d4…2a5510 | claimRefund | 20,300,988 | 20 days agoMon, 27 Jul 2026 00:27:12 UTC | 0xf4b8…4951 | IN | Pool | $0.000 ETH | 0.00000314 | |
| 0xb3daa9…7136e1 | claimRefund | 20,299,349 | 20 days agoMon, 27 Jul 2026 00:24:27 UTC | 0xcbcb…4985 | IN | Pool | $0.000 ETH | 0.00000316 | |
| 0xab1c8a…532e87 | claimRefund | 19,406,508 | 21 days agoSat, 25 Jul 2026 23:31:47 UTC | 0xd3cb…05bb | IN | Pool | $0.000 ETH | 0.00000473 | |
| 0x507232…88393e | claimRefund | 19,406,076 | 21 days agoSat, 25 Jul 2026 23:31:03 UTC | 0x13a5…369a | IN | Pool | $0.000 ETH | 0.00000475 | |
| 0x47da38…e48a6b | claimRefund | 18,940,896 | 22 days agoSat, 25 Jul 2026 10:33:13 UTC | 0x34e6…2adb | IN | Pool | $0.000 ETH | 0.00000568 | |
| 0x44d831…1d44c5 | claimRefund | 18,798,458 | 22 days agoSat, 25 Jul 2026 06:34:28 UTC | 0xc4d7…b4a2 | IN | Pool | $0.000 ETH | 0.00000625 | |
| 0xa9cfe6…2fc76b | claimRefund | 17,683,871 | 23 days agoThu, 23 Jul 2026 23:30:37 UTC | 0x9a1e…13d3 | IN | Pool | $0.000 ETH | 0.00000832 | |
| 0xa73baa…43397a | claimRefund | 17,453,820 | 24 days agoThu, 23 Jul 2026 17:06:21 UTC | 0x0b3f…a8c3 | IN | Pool | $0.000 ETH | 0.00000787 | |
| 0x9667cb…d0e0cc | claimRefund | 17,422,568 | 24 days agoThu, 23 Jul 2026 16:14:10 UTC | 0xae40…8a95 | IN | Pool | $0.000 ETH | 0.00000773 | |
| 0x3a0bdd…fbaf49 | claimRefund | 17,374,715 | 24 days agoThu, 23 Jul 2026 14:54:13 UTC | 0x80d5…9949 | IN | Pool | $0.000 ETH | 0.00000768 | |
| 0xa02262…1364b1 | claimRefund | 17,374,676 | 24 days agoThu, 23 Jul 2026 14:54:09 UTC | 0xfabf…c319 | IN | Pool | $0.000 ETH | 0.00000754 | |
| 0x8325d8…1c756e | claimRefund | 17,373,935 | 24 days agoThu, 23 Jul 2026 14:52:56 UTC | 0x76fc…6fdf | IN | Pool | $0.000 ETH | 0.00000763 | |
| 0x8f1718…3f13f6 | claimRefund | 17,371,964 | 24 days agoThu, 23 Jul 2026 14:49:38 UTC | 0x25c7…4839 | IN | Pool | $0.000 ETH | 0.00000755 | |
| 0x6318b1…bcdb33 | claimRefund | 17,351,482 | 24 days agoThu, 23 Jul 2026 14:15:26 UTC | 0xa146…b884 | IN | Pool | $0.000 ETH | 0.00000751 | |
| 0x310f23…a5bc1a | claimRefund | 17,341,078 | 24 days agoThu, 23 Jul 2026 13:58:03 UTC | 0x8f77…435d | IN | Pool | $0.000 ETH | 0.00000748 | |
| 0x328331…bdd8c9 | claimRefund | 17,310,181 | 24 days agoThu, 23 Jul 2026 13:06:27 UTC | 0x88be…a584 | IN | Pool | $0.000 ETH | 0.00000720 | |
| 0x475e18…dfb5c9 | claimRefund | 17,244,243 | 24 days agoThu, 23 Jul 2026 11:16:11 UTC | 0x347d…2b31 | IN | Pool | $0.000 ETH | 0.00000700 | |
| 0x9166cd…ed6308 | claimRefund | 17,181,028 | 24 days agoThu, 23 Jul 2026 09:30:32 UTC | 0x0b94…b14a | IN | Pool | $0.000 ETH | 0.00000699 | |
| 0x5c0930…f41647 | claimRefund | 16,985,657 | 24 days agoThu, 23 Jul 2026 04:04:05 UTC | 0x7fe0…97c5 | IN | Pool | $0.000 ETH | 0.00000654 | |
| 0x53f00c…f63ec0 | claimRefund | 16,867,826 | 24 days agoThu, 23 Jul 2026 00:47:14 UTC | 0xbf2a…fbfc | IN | Pool | $0.000 ETH | 0.00000635 | |
| 0x7b42b7…7ecbe4 | claimRefund | 16,864,888 | 24 days agoThu, 23 Jul 2026 00:42:19 UTC | 0xb58a…5345 | IN | Pool | $0.000 ETH | 0.00000633 | |
| 0x92ba46…fa9dbb | claimRefund | 16,850,166 | 24 days agoThu, 23 Jul 2026 00:17:42 UTC | 0x4753…e9d5 | IN | Pool | $0.000 ETH | 0.00000633 | |
| 0xdadf8e…926f84 | claimRefund | 16,849,417 | 24 days agoThu, 23 Jul 2026 00:16:27 UTC | 0x46e2…b92c | IN | Pool | $0.000 ETH | 0.00000635 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x60613730…be7142 | Transfer | 24,872,399 | 15 days agoSat, 01 Aug 2026 07:49:31 UTC | 0x070a…defc | OUT | 0x56cb…06cf | $168.38300 VIRTUAL | ||
| 0x14d09a23…c4e8d9 | Transfer | 24,871,390 | 15 days agoSat, 01 Aug 2026 07:47:50 UTC | 0x070a…defc | OUT | 0x9f84…9529 | $168.38300 VIRTUAL | ||
| 0xc583d493…2a5510 | Transfer | 20,300,988 | 20 days agoMon, 27 Jul 2026 00:27:12 UTC | 0x070a…defc | OUT | 0xf4b8…4951 | $168.38300 VIRTUAL | ||
| 0xb3daa958…7136e1 | Transfer | 20,299,349 | 20 days agoMon, 27 Jul 2026 00:24:27 UTC | 0x070a…defc | OUT | 0xcbcb…4985 | $168.38300 VIRTUAL | ||
| 0xab1c8a0c…532e87 | Transfer | 19,406,508 | 21 days agoSat, 25 Jul 2026 23:31:47 UTC | 0x070a…defc | OUT | 0xd3cb…05bb | $168.38300 VIRTUAL | ||
| 0x507232c7…88393e | Transfer | 19,406,076 | 21 days agoSat, 25 Jul 2026 23:31:03 UTC | 0x070a…defc | OUT | 0x13a5…369a | $168.38300 VIRTUAL | ||
| 0x47da3804…e48a6b | Transfer | 18,940,896 | 22 days agoSat, 25 Jul 2026 10:33:13 UTC | 0x070a…defc | OUT | 0x34e6…2adb | $17.4031 VIRTUAL | ||
| 0x44d831a6…1d44c5 | Transfer | 18,798,458 | 22 days agoSat, 25 Jul 2026 06:34:28 UTC | 0x070a…defc | OUT | 0xc4d7…b4a2 | $168.38300 VIRTUAL | ||
| 0xa9cfe62f…2fc76b | Transfer | 17,683,871 | 23 days agoThu, 23 Jul 2026 23:30:37 UTC | 0x070a…defc | OUT | 0x9a1e…13d3 | $22.4540 VIRTUAL | ||
| 0xa73baa36…43397a | Transfer | 17,453,820 | 24 days agoThu, 23 Jul 2026 17:06:21 UTC | 0x070a…defc | OUT | 0x0b3f…a8c3 | $6.1711 VIRTUAL | ||
| 0x9667cb21…d0e0cc | Transfer | 17,422,568 | 24 days agoThu, 23 Jul 2026 16:14:10 UTC | 0x070a…defc | OUT | 0xae40…8a95 | $168.38300 VIRTUAL | ||
| 0x3a0bddf6…fbaf49 | Transfer | 17,374,715 | 24 days agoThu, 23 Jul 2026 14:54:13 UTC | 0x070a…defc | OUT | 0x80d5…9949 | $2.815 VIRTUAL | ||
| 0xa022624c…1364b1 | Transfer | 17,374,676 | 24 days agoThu, 23 Jul 2026 14:54:09 UTC | 0x070a…defc | OUT | 0xfabf…c319 | $168.38300 VIRTUAL | ||
| 0x8325d843…1c756e | Transfer | 17,373,935 | 24 days agoThu, 23 Jul 2026 14:52:56 UTC | 0x070a…defc | OUT | 0x76fc…6fdf | $168.38300 VIRTUAL | ||
| 0x8f1718bb…3f13f6 | Transfer | 17,371,964 | 24 days agoThu, 23 Jul 2026 14:49:38 UTC | 0x070a…defc | OUT | 0x25c7…4839 | $168.38300 VIRTUAL | ||
| 0x6318b165…bcdb33 | Transfer | 17,351,482 | 24 days agoThu, 23 Jul 2026 14:15:26 UTC | 0x070a…defc | OUT | 0xa146…b884 | $168.38300 VIRTUAL | ||
| 0x310f234f…a5bc1a | Transfer | 17,341,078 | 24 days agoThu, 23 Jul 2026 13:58:03 UTC | 0x070a…defc | OUT | 0x8f77…435d | $98.22175 VIRTUAL | ||
| 0x32833180…bdd8c9 | Transfer | 17,310,181 | 24 days agoThu, 23 Jul 2026 13:06:27 UTC | 0x070a…defc | OUT | 0x88be…a584 | $22.4540 VIRTUAL | ||
| 0xf39927cf…cfa558 | Transfer | 17,308,300 | 24 days agoThu, 23 Jul 2026 13:03:19 UTC | 0xcaf7…5d11 | IN | 0x070a…defc | $0.001 DIH | ||
| 0x475e18fc…dfb5c9 | Transfer | 17,244,243 | 24 days agoThu, 23 Jul 2026 11:16:11 UTC | 0x070a…defc | OUT | 0x347d…2b31 | $3.546.3 VIRTUAL | ||
| 0x9166cd98…ed6308 | Transfer | 17,181,028 | 24 days agoThu, 23 Jul 2026 09:30:32 UTC | 0x070a…defc | OUT | 0x0b94…b14a | $168.38300 VIRTUAL | ||
| 0x5c0930fb…f41647 | Transfer | 16,985,657 | 24 days agoThu, 23 Jul 2026 04:04:05 UTC | 0x070a…defc | OUT | 0x7fe0…97c5 | $168.38300 VIRTUAL | ||
| 0x53f00ca0…f63ec0 | Transfer | 16,867,826 | 24 days agoThu, 23 Jul 2026 00:47:14 UTC | 0x070a…defc | OUT | 0xbf2a…fbfc | $5.6110 VIRTUAL | ||
| 0x7b42b79e…7ecbe4 | Transfer | 16,864,888 | 24 days agoThu, 23 Jul 2026 00:42:19 UTC | 0x070a…defc | OUT | 0xb58a…5345 | $70.16125 VIRTUAL | ||
| 0x92ba464e…fa9dbb | Transfer | 16,850,166 | 24 days agoThu, 23 Jul 2026 00:17:42 UTC | 0x070a…defc | OUT | 0x4753…e9d5 | $168.38300 VIRTUAL |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 12,385,139 | 30 days agoFri, 17 Jul 2026 19:52:46 UTC | 0x8f1acf…378bd3 | CREATE | createPool | 0x8059…b575 | IN | 0x070a…defc | 0 ETH |