// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Governable} from "./Governable.sol";
import {GridMining} from "./GridMining.sol";
/// @title AutoMiner — multi-round subscription + batched executor
/// @notice Users pre-fund N rounds; a keeper EOA deploys for them each
/// round via `GridMining.deployFor`. Dual fee: a bps commission
/// + a flat per-round floor that guarantees the keeper's gas is
/// covered on micro-stakes. See `docs/TOKENOMICS.md` (fees).
/// @dev Deviates from the doc's inline `transfer` to the executor:
/// fees ACCRUE to `executorAccrued` and the keeper pulls them
/// via `withdrawExecutorFees`. This removes an external call
/// from the hot batch loop (cheaper, no per-iteration reentrancy
/// surface).
contract AutoMiner is Governable, Pausable, ReentrancyGuard {
uint256 public constant BPS_DENOMINATOR = 10_000;
/// @dev Freeze keys (see Governable).
bytes32 public constant KEY_EXECUTOR = keccak256("AUTOMINER_EXECUTOR");
bytes32 public constant KEY_FEES = keccak256("AUTOMINER_FEES");
bytes32 public constant KEY_MIN_GAS = keccak256("AUTOMINER_MIN_GAS");
uint8 public constant STRATEGY_ALL = 0;
uint8 public constant STRATEGY_SELECT = 1;
uint8 public constant GRID_SIZE = 25;
struct Config {
uint8 strategyId;
uint8 numBlocks;
bool active;
uint16 feeSnapshot; // executorFeeBps at subscribe time
uint32 blockMask; // for STRATEGY_SELECT
uint128 amountPerBlock; // wei sent to GridMining per block
uint64 numRounds;
uint64 roundsCompleted;
uint128 depositRemaining; // wei
// F-016: snapshot the flat fee at subscribe time so a later
// `setFees` cannot retroactively eat into existing subscriptions.
uint128 flatSnapshot;
// F-024: snapshot GridMining's admin fee (bps) at subscribe time so
// gross-up can be computed correctly during execution.
uint16 adminFeeSnapshot;
}
GridMining public immutable gridMining;
mapping(address => Config) public configs;
address[] public activeUsers;
mapping(address => uint256) public activeUserIndex; // 1-based; 0 = not active
address public executor;
uint16 public executorFeeBps = 80; // 0.8% (TOKENOMICS.md §2)
uint128 public executorFlatFee = 0.00004e18; // per executed round (~$0.07 @ ETH$1732). Calibré sur le gas L2 4663 MESURÉ (2026-07-08) : une exécution auto coûte ~0.0000056 ETH (1 bloc) à ~0.000033 ETH (25 blocs, grille pleine) @ baseFee 0.02 gwei → 0.00004 couvre le pire cas à gas normal + marge, tout en restant une légère surcharge (le vrai profit qui scale = executorFeeBps 0.8%). Réglable via setFees (non freezé S1).
// Bail below this much gasleft BEFORE marking/attempting a user's deploy.
// MUST exceed the worst-case single deployFor (a STRATEGY_ALL 25-block
// deploy measures ~1.67M gas). The old 250k let the loop mark a user and
// then OOM inside deployFor's try/catch — the swallowed revert left the
// user marked _executedThisRound while the round stayed empty, and an
// empty round's rollEmptyRound keeps the same round id, so the per-round
// dedup deadlocked the round forever (Auto never deployed). 1.9M guarantees
// even an all-blocks deploy completes once the loop decides to attempt it.
// Owner-tunable via setMinGasForBatch for already-deployed instances.
uint64 public minGasForBatch = 1_900_000;
uint256 public executorAccrued; // pull-based keeper payout
/// @dev F-017: dedup users in the same `executeBatch` AND across
/// multiple `executeBatch` calls in the same betting WINDOW.
/// Without this, a duplicate-entry attack would charge a user the
/// flat fee N times per round despite GridMining accepting only
/// the first `deployFor`.
/// Audit #3: keyed on the window `(roundId, startTime)`, NOT the round
/// id alone. `GridMining.rollEmptyRound()` renews an empty round's
/// betting window (new `startTime`) while KEEPING the id, so a
/// round-id key left a subscriber marked-and-skipped for every rolled
/// window of that id (frozen out until a manual deploy advanced the
/// id). `startTime` changes on every window (initial open + each roll),
/// so the window key is unique per betting window.
mapping(bytes32 => mapping(address => bool)) internal _executedThisRound;
/// @dev F-015: pull-pattern refund destination when a payable.call
/// refund fails inside `executeBatch`. Users withdraw via
/// `withdrawRefund()`.
mapping(address => uint256) public pendingRefund;
event Subscribed(
address indexed user,
uint8 strategyId,
uint32 blockMask,
uint128 amountPerBlock,
uint64 numRounds,
uint128 totalDeposit
);
event Unsubscribed(address indexed user, uint128 refunded);
event Deactivated(address indexed user, uint128 refunded);
event RefundFailed(address indexed user, uint128 amount);
event ExecutedFor(address indexed user, uint256 cost);
event ExecutionFailed(address indexed user);
/// @dev Emitted when a deploy is skipped for a reason the subscriber did
/// NOT cause (round full / betting closed / game paused). Nothing is
/// charged — like every failed deploy.
event ExecutionSkipped(address indexed user);
event BatchStopped(uint256 stoppedAtIndex, uint256 gasLeft);
event FeesChanged(uint16 bps, uint128 flat);
event ExecutorChanged(address indexed previous, address indexed current);
event MinGasForBatchChanged(uint64 previous, uint64 current);
event ExecutorFeesWithdrawn(address indexed to, uint256 amount);
error AlreadySubscribed();
error NotSubscribed();
error NotExecutor();
error InvalidStrategy();
error InvalidBlockMask();
error ZeroRounds();
error ZeroAmount();
error WrongDeposit(uint256 sent, uint256 required);
error ZeroAddress();
error TransferFailed();
constructor(address initialOwner, GridMining gridMining_, address executor_)
Governable(initialOwner)
{
if (address(gridMining_) == address(0)) revert ZeroAddress();
gridMining = gridMining_;
executor = executor_;
}
// ---------------------------------------------------------------
// Subscribe
// ---------------------------------------------------------------
function subscribe(uint8 strategyId, uint32 blockMask, uint128 amountPerBlock, uint64 numRounds)
external
payable
whenNotPaused
nonReentrant
{
if (configs[msg.sender].active) revert AlreadySubscribed();
if (numRounds == 0) revert ZeroRounds();
if (amountPerBlock == 0) revert ZeroAmount();
uint8 numBlocks = _numBlocks(strategyId, blockMask);
uint16 adminFeeSnapshot = uint16(gridMining.ADMIN_FEE_BPS());
uint256 required = _perRoundCost(amountPerBlock, numBlocks, executorFeeBps, adminFeeSnapshot) * numRounds;
if (msg.value != required) revert WrongDeposit(msg.value, required);
configs[msg.sender] = Config({
strategyId: strategyId,
numBlocks: numBlocks,
active: true,
feeSnapshot: executorFeeBps,
blockMask: blockMask,
amountPerBlock: amountPerBlock,
numRounds: numRounds,
roundsCompleted: 0,
depositRemaining: uint128(msg.value),
flatSnapshot: executorFlatFee, // F-016
adminFeeSnapshot: adminFeeSnapshot // F-024
});
activeUsers.push(msg.sender);
activeUserIndex[msg.sender] = activeUsers.length; // 1-based
emit Subscribed(msg.sender, strategyId, blockMask, amountPerBlock, numRounds, uint128(msg.value));
}
function unsubscribe() external nonReentrant {
Config storage c = configs[msg.sender];
if (!c.active) revert NotSubscribed();
uint128 refund = c.depositRemaining;
_deactivate(msg.sender);
if (refund > 0) {
(bool ok,) = payable(msg.sender).call{value: refund}("");
// Unsubscribe is user-initiated: refund failure is a hard
// revert so the caller knows nothing happened.
if (!ok) revert TransferFailed();
}
emit Unsubscribed(msg.sender, refund);
}
// ---------------------------------------------------------------
// Execute
// ---------------------------------------------------------------
function executeBatch(address[] calldata users) external whenNotPaused nonReentrant {
if (msg.sender != executor) revert NotExecutor();
// F-017 + audit #3: derive the per-WINDOW dedup key once. `startTime`
// changes on the initial open AND on every `rollEmptyRound`, so
// (roundId, startTime) uniquely identifies this betting window and a
// rolled empty round no longer keeps subscribers frozen.
uint64 currentRid = gridMining.currentRoundId();
bytes32 windowKey =
keccak256(abi.encodePacked(currentRid, gridMining.getRound(currentRid).startTime));
for (uint256 i = 0; i < users.length; i++) {
if (gasleft() < minGasForBatch) {
emit BatchStopped(i, gasleft());
break;
}
address user = users[i];
Config storage c = configs[user];
if (!c.active) continue;
// F-017: skip if this user already had a deploy attempt in
// the current GridMining round (within this batch OR across
// multiple batches in the same round). Prevents a duplicate-
// entry attack that would multi-charge the flat fee.
if (_executedThisRound[windowKey][user]) continue;
_executedThisRound[windowKey][user] = true;
// F-016: use the flat fee snapshotted at subscribe.
uint256 flat = uint256(c.flatSnapshot);
uint256 base = uint256(c.amountPerBlock) * c.numBlocks;
// F-024: Gross up base for GridMining's admin fee so the net
// remainder (after fee skim) meets the per-block minimum.
uint256 grossBase = _grossUpForAdminFee(base, c.adminFeeSnapshot);
uint256 bpsFee = (grossBase * c.feeSnapshot) / BPS_DENOMINATOR;
uint256 thisRoundCost = grossBase + bpsFee + flat;
if (c.depositRemaining < thisRoundCost) {
// F-015: refund any leftover (smaller than one round's
// cost) before deactivating. The leftover used to be
// silently zeroed.
_deactivateAndRefund(user);
continue;
}
// F-018: do NOT advance roundsCompleted / depositRemaining
// until success. On failure, NOTHING is charged (see the catch
// below) — the keeper absorbs the wasted gas.
uint8[] memory ids = _expandBlocks(c.strategyId, c.blockMask, c.numBlocks);
try gridMining.deployFor{value: grossBase}(user, ids) {
c.depositRemaining -= uint128(thisRoundCost);
c.roundsCompleted += 1;
executorAccrued += bpsFee + flat;
emit ExecutedFor(user, thisRoundCost);
if (c.roundsCompleted >= c.numRounds) _deactivateAndRefund(user);
} catch (bytes memory err) {
bytes4 reason = err.length >= 4 ? bytes4(err) : bytes4(0);
// Blameless reverts: the round filled up, betting had closed
// before the keeper's tx landed, or the game itself is paused —
// the subscriber caused none of these (a griefer can fill the
// per-round miner cap, the keeper can run late, and a pause is
// owner-initiated: no subscriber money may move during one).
// Charging the flat fee here would let an attacker drain
// subscribers one fee per round for deploys that never
// happened. So charge NOTHING; the user is skipped for this
// round (kept marked so the keeper doesn't waste gas retrying
// a still-doomed deploy) and gets a fresh attempt next round
// under a new dedup key.
if (
reason == GridMining.RoundMinerCapReached.selector
|| reason == GridMining.BettingClosed.selector
|| reason == Pausable.EnforcedPause.selector
) {
emit ExecutionSkipped(user);
} else {
// Any OTHER (unexpected) revert: still charge NOTHING — the
// keeper absorbs the wasted gas. A failed deploy must never
// cost the subscriber a fee, whatever the cause. We surface
// ExecutionFailed (vs the normal skip) only so ops can
// investigate the unexpected reason.
emit ExecutionFailed(user);
}
}
}
}
function withdrawExecutorFees() external nonReentrant {
if (msg.sender != executor) revert NotExecutor();
uint256 amount = executorAccrued;
executorAccrued = 0;
if (amount > 0) {
(bool ok,) = payable(executor).call{value: amount}("");
if (!ok) revert TransferFailed();
}
emit ExecutorFeesWithdrawn(executor, amount);
}
// ---------------------------------------------------------------
// Views
// ---------------------------------------------------------------
function quoteSubscribe(uint8 strategyId, uint32 blockMask, uint128 amountPerBlock, uint64 numRounds)
external
view
returns (uint256 totalCost)
{
uint8 numBlocks = _numBlocks(strategyId, blockMask);
uint16 adminFeeBps = uint16(gridMining.ADMIN_FEE_BPS());
return _perRoundCost(amountPerBlock, numBlocks, executorFeeBps, adminFeeBps) * numRounds;
}
function configOf(address user) external view returns (Config memory) {
return configs[user];
}
function activeUserCount() external view returns (uint256) {
return activeUsers.length;
}
// ---------------------------------------------------------------
// Admin
// ---------------------------------------------------------------
function setExecutor(address newExecutor) external onlyOwner notFrozen(KEY_EXECUTOR) {
emit ExecutorChanged(executor, newExecutor);
executor = newExecutor;
}
function setFees(uint16 bps, uint128 flat) external onlyOwner notFrozen(KEY_FEES) {
require(bps <= BPS_DENOMINATOR, "bps too high");
executorFeeBps = bps;
executorFlatFee = flat;
emit FeesChanged(bps, flat);
}
function setMinGasForBatch(uint64 newMin) external onlyOwner notFrozen(KEY_MIN_GAS) {
emit MinGasForBatchChanged(minGasForBatch, newMin);
minGasForBatch = newMin;
}
/// @notice Emergency stop. Gates `subscribe` (new money in) and
/// `executeBatch` (deposits flowing into the game). Exits stay
/// open: `unsubscribe`, `withdrawRefund` and
/// `withdrawExecutorFees` are deliberately NOT gated, so a pause
/// can never trap funds.
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
// ---------------------------------------------------------------
// Internal
// ---------------------------------------------------------------
function _perRoundCost(uint128 amountPerBlock, uint8 numBlocks, uint16 feeBps, uint16 adminFeeBps)
internal
view
returns (uint256)
{
uint256 base = uint256(amountPerBlock) * numBlocks;
// Gross up base so that after GridMining's admin fee skim, the
// net remainder meets GridMining's per-block minimum.
uint256 grossBase = _grossUpForAdminFee(base, adminFeeBps);
uint256 bpsFee = (grossBase * feeBps) / BPS_DENOMINATOR;
return grossBase + bpsFee + executorFlatFee;
}
function _numBlocks(uint8 strategyId, uint32 blockMask) internal pure returns (uint8) {
if (strategyId == STRATEGY_ALL) {
return GRID_SIZE;
} else if (strategyId == STRATEGY_SELECT) {
uint8 count = _popcount(blockMask);
if (count == 0 || count > GRID_SIZE) revert InvalidBlockMask();
// Reject any bit above block 25.
if (blockMask >> GRID_SIZE != 0) revert InvalidBlockMask();
return count;
}
revert InvalidStrategy();
}
function _popcount(uint32 x) internal pure returns (uint8 c) {
for (; x != 0; x &= x - 1) {
c++;
}
}
/// @dev Computes the gross amount needed such that after GridMining's
/// admin fee skim, the net remainder matches `base`. Uses ceil
/// division to ensure the net is never short of the minimum.
/// Formula: (base * BPS + (BPS - adminFeeBps) - 1) / (BPS - adminFeeBps)
function _grossUpForAdminFee(uint256 base, uint16 adminFeeBps) internal pure returns (uint256) {
uint256 grossDen = BPS_DENOMINATOR - uint256(adminFeeBps);
return (base * BPS_DENOMINATOR + grossDen - 1) / grossDen;
}
function _expandBlocks(uint8 strategyId, uint32 blockMask, uint8 numBlocks)
internal
pure
returns (uint8[] memory ids)
{
ids = new uint8[](numBlocks);
if (strategyId == STRATEGY_ALL) {
for (uint8 i = 0; i < GRID_SIZE; i++) {
ids[i] = i + 1;
}
} else {
uint8 j;
for (uint8 i = 0; i < GRID_SIZE; i++) {
if (blockMask & (uint32(1) << i) != 0) {
ids[j++] = i + 1;
}
}
}
}
function _deactivate(address user) internal {
Config storage c = configs[user];
c.active = false;
c.depositRemaining = 0;
uint256 idx = activeUserIndex[user]; // 1-based
if (idx != 0) {
uint256 lastIdx = activeUsers.length;
address last = activeUsers[lastIdx - 1];
activeUsers[idx - 1] = last;
activeUserIndex[last] = idx;
activeUsers.pop();
activeUserIndex[user] = 0;
}
}
/// @dev F-015: variant for executeBatch — refunds any leftover deposit
/// to the user BEFORE clearing state. Refund failure is swallowed
/// (parked on `pendingRefund[user]` for later pull) so a single
/// griefing user can't brick the batch for the others.
function _deactivateAndRefund(address user) internal {
Config storage c = configs[user];
uint128 refund = c.depositRemaining;
_deactivate(user); // clears state, frees up the array slot
if (refund > 0) {
(bool ok,) = payable(user).call{value: refund}("");
if (!ok) {
pendingRefund[user] += refund;
emit RefundFailed(user, refund);
return;
}
}
emit Deactivated(user, refund);
}
/// @notice F-015: pull a refund parked by a failed auto-deactivate.
function withdrawRefund() external nonReentrant returns (uint256 amount) {
amount = pendingRefund[msg.sender];
if (amount == 0) return 0;
pendingRefund[msg.sender] = 0;
(bool ok,) = payable(msg.sender).call{value: amount}("");
if (!ok) revert TransferFailed();
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "initialOwner",
"type": "address",
"internalType": "address"
},
{
"name": "gridMining_",
"type": "address",
"internalType": "contract GridMining"
},
{
"name": "executor_",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AboveMax",
"type": "error",
"inputs": [
{
"name": "requested",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "max",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "AlreadySubscribed",
"type": "error",
"inputs": []
},
{
"name": "BelowMin",
"type": "error",
"inputs": [
{
"name": "requested",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "min",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "EnforcedPause",
"type": "error",
"inputs": []
},
{
"name": "ExpectedPause",
"type": "error",
"inputs": []
},
{
"name": "InvalidBlockMask",
"type": "error",
"inputs": []
},
{
"name": "InvalidStrategy",
"type": "error",
"inputs": []
},
{
"name": "NotExecutor",
"type": "error",
"inputs": []
},
{
"name": "NotSubscribed",
"type": "error",
"inputs": []
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ParamIsFrozen",
"type": "error",
"inputs": [
{
"name": "key",
"type": "bytes32",
"internalType": "bytes32"
}
]
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "TransferFailed",
"type": "error",
"inputs": []
},
{
"name": "WrongDeposit",
"type": "error",
"inputs": [
{
"name": "sent",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "required",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "ZeroAmount",
"type": "error",
"inputs": []
},
{
"name": "ZeroRounds",
"type": "error",
"inputs": []
},
{
"name": "BatchStopped",
"type": "event",
"inputs": [
{
"name": "stoppedAtIndex",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "gasLeft",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Deactivated",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "refunded",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
}
],
"anonymous": false
},
{
"name": "ExecutedFor",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "cost",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ExecutionFailed",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "ExecutionSkipped",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "ExecutorChanged",
"type": "event",
"inputs": [
{
"name": "previous",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "current",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "ExecutorFeesWithdrawn",
"type": "event",
"inputs": [
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeesChanged",
"type": "event",
"inputs": [
{
"name": "bps",
"type": "uint16",
"indexed": false,
"internalType": "uint16"
},
{
"name": "flat",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
}
],
"anonymous": false
},
{
"name": "MinGasForBatchChanged",
"type": "event",
"inputs": [
{
"name": "previous",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "current",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferStarted",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "ParamFrozen",
"type": "event",
"inputs": [
{
"name": "key",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "Paused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RefundFailed",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
}
],
"anonymous": false
},
{
"name": "Subscribed",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "strategyId",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "blockMask",
"type": "uint32",
"indexed": false,
"internalType": "uint32"
},
{
"name": "amountPerBlock",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
},
{
"name": "numRounds",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
},
{
"name": "totalDeposit",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
}
],
"anonymous": false
},
{
"name": "Unpaused",
"type": "event",
"inputs": [
{
"name": "account",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Unsubscribed",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "refunded",
"type": "uint128",
"indexed": false,
"internalType": "uint128"
}
],
"anonymous": false
},
{
"name": "BPS_DENOMINATOR",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "GRID_SIZE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "KEY_EXECUTOR",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "KEY_FEES",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "KEY_MIN_GAS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "STRATEGY_ALL",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "STRATEGY_SELECT",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "activeUserCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "activeUserIndex",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "activeUsers",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "configOf",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "strategyId",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "numBlocks",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "active",
"type": "bool",
"internalType": "bool"
},
{
"name": "feeSnapshot",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "blockMask",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "amountPerBlock",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "numRounds",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "roundsCompleted",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "depositRemaining",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "flatSnapshot",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "adminFeeSnapshot",
"type": "uint16",
"internalType": "uint16"
}
],
"internalType": "struct AutoMiner.Config"
}
],
"stateMutability": "view"
},
{
"name": "configs",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "strategyId",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "numBlocks",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "active",
"type": "bool",
"internalType": "bool"
},
{
"name": "feeSnapshot",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "blockMask",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "amountPerBlock",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "numRounds",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "roundsCompleted",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "depositRemaining",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "flatSnapshot",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "adminFeeSnapshot",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "executeBatch",
"type": "function",
"inputs": [
{
"name": "users",
"type": "address[]",
"internalType": "address[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "executor",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "executorAccrued",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "executorFeeBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "executorFlatFee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint128",
"internalType": "uint128"
}
],
"stateMutability": "view"
},
{
"name": "freezeParam",
"type": "function",
"inputs": [
{
"name": "key",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "gridMining",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract GridMining"
}
],
"stateMutability": "view"
},
{
"name": "minGasForBatch",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "paramFrozen",
"type": "function",
"inputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "pause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "paused",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingRefund",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "quoteSubscribe",
"type": "function",
"inputs": [
{
"name": "strategyId",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "blockMask",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "amountPerBlock",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "numRounds",
"type": "uint64",
"internalType": "uint64"
}
],
"outputs": [
{
"name": "totalCost",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setExecutor",
"type": "function",
"inputs": [
{
"name": "newExecutor",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFees",
"type": "function",
"inputs": [
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "flat",
"type": "uint128",
"internalType": "uint128"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMinGasForBatch",
"type": "function",
"inputs": [
{
"name": "newMin",
"type": "uint64",
"internalType": "uint64"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "subscribe",
"type": "function",
"inputs": [
{
"name": "strategyId",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "blockMask",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "amountPerBlock",
"type": "uint128",
"internalType": "uint128"
},
{
"name": "numRounds",
"type": "uint64",
"internalType": "uint64"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unpause",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unsubscribe",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "withdrawExecutorFees",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "withdrawRefund",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "amount",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
}
]0x60a0346200019f57601f6200243d38819003918201601f19168301916001600160401b03831184841017620001a3578084926060946040528339810103126200019f576200004d81620001b7565b602082015190916001600160a01b038083169290918382036200019f57620000796040849201620001b7565b94168015620001875760018060a01b0319908160015416600155805f54928316175f558360405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055600754600880546001600160c01b031916721cfde000000000000000000000246139ca800017905593156200017857506080526001600160b01b0319909116911617600560a41b176007556040516122709081620001cd823960805181818161047c01528181610654015281816107e501528181610ee001528181610f3f0152818161119c01526112240152f35b63d92e233d60e01b8152600490fd5b604051631e4fbdf760e01b81525f6004820152602490fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200019f5756fe6080806040526004361015610012575f80fd5b5f3560e01c90816229f07a14611cd15750806305573a0714611c97578063110f887414611c5c5780631294a32614611c385780631909145214611a5e5780631a29bb5414611a225780631c3c0ea81461196457806331c004e6146118355780633f4ba83a146117cc5780634c3e1176146117b157806357db7eaf1461177757806359a1d69c146117485780635bbf378314610e505780635c975abb14610e2e578063715018a614610dcb578063728e9ecc14610dae57806378a4715a14610d9157806379ba509714610d0c5780637fc4eda814610cf1578063803ae51814610caf57806382094f7a14610c755780638456cb5914610c1c5780638da5cb5b14610bf557806399d82c5f14610bb9578063a6c0ee3a14610b93578063b02e37ea14610776578063bb488c9b146106c5578063c34c08e51461069d578063d07b807314610683578063d24a67bc1461063f578063df3bb1cb146105e6578063e1a45218146105ca578063e30c3978146105a2578063f2fde38b14610531578063f318d0f21461044a578063f9a02f711461034e578063fcae44841461028e5763fce89878146101bd575f80fd5b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f52600460205261016060405f2080549061ffff906001600160801b03600182015460026001600160401b0393015492826040519660ff8116885260ff8160081c16602089015260ff8160101c1615156040890152868160181c16606089015263ffffffff8160281c16608089015260481c1660a087015280821660c08701528160401c1660e086015260801c610100850152811661012084015260801c16610140820152f35b5f80fd5b3461028a575f36600319011261028a576102a6611e88565b335f52600460205260405f2060ff815460101c161561033c576001015460801c6102cf3361212a565b80610314575b6040519081527f9d2620b94600a50652cca89233142c3b2cbafed08290ff3e95ba74429f06851160203392a260015f8051602061221b83398151915255005b5f80808084335af1610324611dd2565b506102d5575b6040516312171d8360e31b8152600490fd5b60405163046fcd8560e31b8152600490fd5b3461028a57602036600319011261028a576001600160401b036004358181169182820361028a5761037d611eb7565b7fe715e7482ca0d8bb3cff26570cbfd14e8bcf015bc2e7cfc8e84cfc18b757e83f5f81905260026020527ff0e8fb31f1343baefc2670c4067a056aa22460a16d542084d93986a8c9009a5c5460ff16610432575060407f0b0e4888e02853e0886c7212d705e051f19507074d6ae65ff8f1b826be4719d491600854948251918660801c1682526020820152a167ffffffffffffffff60801b1990911660809190911b67ffffffffffffffff60801b1617600855005b602490604051906374ca98b160e01b82526004820152fd5b3461028a5761046561045b36611d40565b9293919093612041565b604051635612b12b60e11b815292906020846004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa938415610526575f946104ec575b60206104e4856001600160401b036104dc89888861ffff8093169260075460a01c16916120da565b911690611e68565b604051908152f35b935091906020843d60201161051e575b8161050960209383611db1565b8101031261028a5792519290916104dc6104b4565b3d91506104fc565b6040513d5f823e3d90fd5b3461028a57602036600319011261028a576004356001600160a01b038181169182900361028a57610560611eb7565b816bffffffffffffffffffffffff60a01b60015416176001555f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b3461028a575f36600319011261028a576001546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a5760206040516127108152f35b3461028a57602036600319011261028a57600435610602611eb7565b805f52600260205260405f20600160ff198254161790557fe92e44bc964ea5b6cb7a437f0ea8cf145b3db2993f35919b6a113a9beabc80eb5f80a2005b3461028a575f36600319011261028a576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461028a575f36600319011261028a5760206040515f8152f35b3461028a575f36600319011261028a576007546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a576106dd611e88565b6007546001600160a01b0390811690338290036107645760095480925f60095581610747575b507fee8488ff43f1d22d9b0d661f4da06e396b336308f970b4d375257d565887dfac6020836007541692604051908152a260015f8051602061221b83398151915255005b5f80809381935af1610757611dd2565b501561032a578183610703565b6040516361968ebb60e11b8152600490fd5b61077f36611d40565b9091610789611eca565b610791611e88565b335f52600460205260ff60405f205460101c16610b81576001600160401b03821615610b6f576001600160801b03831615610b5d576107d08185612041565b604051635612b12b60e11b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610526575f91610b2b575b5061ffff908160075460a01c1661084a6001600160401b03871661084585851684888c6120da565b611e68565b803403610b0d57506001600160801b03600854169060ff6040519561086e87611d95565b818b16875216602086015260016040860152606085015263ffffffff851660808501526001600160801b03871660a08501526001600160401b03861660c08501525f60e08501526001600160801b03341661010085015261012084015216610140820152335f526004602052600260405f2060ff83511681549061ff00602086015160081b1662ff00006040870151151560101b1664ffff000000606088015160181b169168ffffffff0000000000608089015160281b169378ffffffffffffffffffffffffffffffff00000000000000000060a08a015160481b169566ffffffffffffff60c81b1617171717171781556109ec600182016001600160401b0360c0860151166001600160401b03198254161781556109bd6001600160401b0360e087015116829067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b61010085015181546001600160801b031660809190911b6fffffffffffffffffffffffffffffffff1916179055565b01906001600160801b036101208201511682549161014061ffff60801b91015160801b169171ffffffffffffffffffffffffffffffffffff1916171790556005549268010000000000000000841015610af95763ffffffff6001600160801b0392610a86610a688760016001600160401b039901600555611cf7565b81546001600160a01b0360039290921b91821b19163390911b179055565b600554335f52600660205260405f205560ff604051971687521660208601521660408401521660608201526001600160801b03341660808201527f9bc4441f718d89a32f5daf028fab66a39b121b568982c1ebd8ab91a36a19703c60a03392a260015f8051602061221b83398151915255005b634e487b7160e01b5f52604160045260245ffd5b604490604051906305897f0960e01b82523460048301526024820152fd5b90506020813d602011610b55575b81610b4660209383611db1565b8101031261028a57518661081d565b3d9150610b39565b604051631f2a200560e01b8152600490fd5b60405163065e270360e51b8152600490fd5b604051632fec509960e11b8152600490fd5b3461028a575f36600319011261028a5760206001600160801b0360085416604051908152f35b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f52600b602052602060405f2054604051908152f35b3461028a575f36600319011261028a575f546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a57610c34611eb7565b610c3c611eca565b600160ff1960035416176003557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b3461028a575f36600319011261028a5760206040517f45e220f5697f4355417727ad14267e66ff254ec466b7d1eb6cff2ea5e673f77f8152f35b3461028a57602036600319011261028a5760043560055481101561028a57610cd8602091611cf7565b905460405160039290921b1c6001600160a01b03168152f35b3461028a575f36600319011261028a57602060405160198152f35b3461028a575f36600319011261028a576001546001600160a01b033381831603610d79576bffffffffffffffffffffffff60a01b8092166001555f549133908316175f553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b60405163118cdaa760e01b8152336004820152602490fd5b3461028a575f36600319011261028a576020600954604051908152f35b3461028a575f36600319011261028a576020600554604051908152f35b3461028a575f36600319011261028a57610de3611eb7565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461028a575f36600319011261028a57602060ff600354166040519015158152f35b3461028a57602036600319011261028a576001600160401b036004351161028a5736602360043501121561028a576001600160401b03600435600401351161028a573660246004356004013560051b60043501011161028a57610eb1611eca565b610eb9611e88565b6007546001600160a01b0316330361076457604051639cbe5efd60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610526575f9161170e575b5060405163144d022960e01b81526001600160401b038216600482015261022080826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa918215610526575f926115c6575b505051906040519060208201926001600160401b0360c01b809260c01b16845260c01b16602882015260108152604081018181106001600160401b03821117610af9576040525190205f905b600435600401358210610fe4575b60015f8051602061221b83398151915255005b5a6001600160401b0360085460801c161161158e57600435600583901b01602401356001600160a01b038116900361028a5760018060a01b0360248360051b600435010135165f52600460205260405f209160ff835460101c161561158457815f52600a8060205260405f2060018060a01b0360248460051b600435010135165f5260205260ff60405f20541661157957825f5260205260405f2060018060a01b0360248360051b600435010135165f5260205260405f20600160ff1982541617905560028301548354916127106110ef6110d160ff8660081c166001600160801b038760481c16611e68565b6110e461ffff91828760801c1690611ee8565b9560181c1685611e68565b049161110d6001600160801b0382166111088587611e7b565b611e7b565b9586600182015460801c1061155b5780549560ff8760081c169661114961113389611ff3565b986111416040519a8b611db1565b808a52611ff3565b601f19013660208a013760ff81166114e757505f5b60ff81166019811015611190578160019160ff61118561117e829661200a565b928d61202d565b91169052011661115e565b5050969193959092945b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b1561028a576040518092630a4a60c560e21b82526044820160018060a01b0360248a60051b6004350101351660048401526040602484015281518091526020606484019201905f905b8082106114c857505f94928490039284925090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190816114b1575b506113755750505060019150611269611dd2565b80519060048210908161136c57602001516001600160e01b03199283821692611357575b505090505b63ffffffff60e01b16639e61674760e01b8114908115611346575b8115611335575b50156112f957818060a01b0360248260051b600435010135167f31b740a2126076f8e62e316ade07cb0677888045ed02c91f40ef96cf33c848c05f80a25b0190610fc3565b818060a01b0360248260051b600435010135167f0cddc7f3a22f81520638293af12599a9ad1cc7a1a0b41c4e49b85d3ed8fdafad5f80a26112f2565b63d93c066560e01b149050846112b4565b6348d51aad60e11b811491506112ad565b8391925060040360031b1b161680858061128d565b5050505f611292565b6001600160801b038116600183015460801c036001600160801b03811161149d576113b89060018401906001600160801b0382549181199060801b169116179055565b60016001600160401b038184015460401c1601926001600160401b03841161149d576001956001600160801b036114209261141989978888019067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b1690611e7b565b61142d6009918254611e7b565b90556040519081527f136bd939f0776bdd0c5d89bb45ba62e96b6e8b0b6dbedd1ed3c8644397e4cb2d6020848060a01b0360248760051b6004350101351692a201546001600160401b038082169160401c16106112f25761149860248260051b600435010135611f40565b6112f2565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b038111610af95760405287611255565b9193509160208060019260ff875116815201940192018593929161120e565b949290969593915f975f5b60ff8116601981101561154957600163ffffffff911b8960281c161661151e575b60010160ff166114f2565b6115278161200a565b6115308b61201c565b9a60ff1661153e908b61202d565b9060ff169052611513565b5050989397509390945094909461119a565b5050915050600191925061149860248260051b600435010135611f40565b5060019192506112f2565b60019192506112f2565b5060407f8f1403bec0a17defea3a808da2ff7a763f2d127d0f930b27fcc8ff9ef9e216ce915a82519182526020820152a18080610fd1565b9080925081813d8311611707575b6115de8183611db1565b8101031261028a576040519182018281106001600160401b03821117610af95760405261160a81611e47565b825261161860208201611e47565b602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201519060ff8216820361028a5783015261012081810151906001600160a01b038216820361028a57830152610140611697818301611e5b565b908301526101606116a9818301611e5b565b908301526101806116bb818301611e5b565b908301526101a06116cd818301611e5b565b908301526101c06116df818301611e5b565b908301526101e080820151908301526116fc610200809201611e47565b908201528280610f77565b503d6115d4565b90506020813d602011611740575b8161172960209383611db1565b8101031261028a5761173a90611e47565b81610f18565b3d915061171c565b3461028a57602036600319011261028a576004355f526002602052602060ff60405f2054166040519015158152f35b3461028a575f36600319011261028a5760206040517fe715e7482ca0d8bb3cff26570cbfd14e8bcf015bc2e7cfc8e84cfc18b757e83f8152f35b3461028a575f36600319011261028a57602060405160018152f35b3461028a575f36600319011261028a576117e4611eb7565b60035460ff8116156118235760ff19166003557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b604051638dfc202b60e01b8152600490fd5b3461028a57604036600319011261028a5760043561ffff81169081810361028a57602435916001600160801b03831680930361028a57611873611eb7565b7fdca2fbbcd19b1d32f2606e8bd7494c8b0a3db58da0461d005d6a7af7b1def6795f81905260026020527f84339fb3848a68d79582ac1624c6502e246055f0b59a17379ba7232a0c3bb8e15460ff1661043257506127108111611930577fc4f1b19e28c7452ef005df1e28d41f0896abff20264d65837fa9e8385823835f926040926007549061ffff60a01b9060a01b169061ffff60a01b191617600755806001600160801b0319600854161760085582519182526020820152a1005b60405162461bcd60e51b815260206004820152600c60248201526b0c4e0e640e8dede40d0d2ced60a31b6044820152606490fd5b3461028a57602036600319011261028a576004356001600160a01b038181169182900361028a57611993611eb7565b7f45e220f5697f4355417727ad14267e66ff254ec466b7d1eb6cff2ea5e673f77f5f81905260026020527f331a62cd40d41535b190b54364366a5e8a6f4abcf01ece4911d8a4e875aa5a905460ff166104325750816007549182167f54a57d849b9d8af1a8883dad9184e599aa67ef60814f6c91db7f864abd4325fc5f80a36001600160a01b03191617600755005b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f526006602052602060405f2054604051908152f35b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f610140604051611a9481611d95565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015201525f52600460205261016060405f2061ffff610140604051611af181611d95565b82600285549560ff8716845260ff8760081c16602085015260ff8760101c1615156040850152828760181c16606085015263ffffffff8760281c1660808501526001600160801b038760481c1660a085015260018101546001600160401b03811660c08601526001600160401b038160401c1660e086015260801c61010085015201546001600160801b03811661012084015260801c168282015260ff6040519416845260ff602082015116602085015260408101511515604085015282606082015116606085015263ffffffff60808201511660808501526001600160801b0360a08201511660a08501526001600160401b0360c08201511660c08501526001600160401b0360e08201511660e08501526001600160801b03610100820151166101008501526001600160801b0361012082015116610120850152015116610140820152f35b3461028a575f36600319011261028a57602061ffff60075460a01c16604051908152f35b3461028a575f36600319011261028a57611c74611e88565b6020611c7e611e10565b60015f8051602061221b83398151915255604051908152f35b3461028a575f36600319011261028a5760206040517fdca2fbbcd19b1d32f2606e8bd7494c8b0a3db58da0461d005d6a7af7b1def6798152f35b3461028a575f36600319011261028a576020906001600160401b0360085460801c168152f35b600554811015611d2c5760055f527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001905f90565b634e487b7160e01b5f52603260045260245ffd5b608090600319011261028a5760043560ff8116810361028a579060243563ffffffff8116810361028a57906044356001600160801b038116810361028a57906064356001600160401b038116810361028a5790565b61016081019081106001600160401b03821117610af957604052565b90601f801991011681019081106001600160401b03821117610af957604052565b3d15611e0b573d906001600160401b038211610af95760405191611e00601f8201601f191660200184611db1565b82523d5f602084013e565b606090565b335f52600b60205260405f20908154918215611e41575f90555f80808085335af1611e39611dd2565b501561032a57565b505f9150565b51906001600160401b038216820361028a57565b5190811515820361028a57565b8181029291811591840414171561149d57565b9190820180921161149d57565b5f8051602061221b8339815191526002815414611ea55760029055565b604051633ee5aeb560e01b8152600490fd5b5f546001600160a01b03163303610d7957565b60ff60035416611ed657565b60405163d93c066560e01b8152600490fd5b9061ffff16612710908082039282841161149d578281029080820484149015171561149d5783611f1791611e7b565b5f1981019290831161149d5714611f2c570490565b634e487b7160e01b5f52601260045260245ffd5b60018060a01b03811690815f526004602052611f66600160405f20015460801c9161212a565b80611f99575b60207fd351722477b8e6ec7fae918455c0994811e4e33d78a66798032434926412a88791604051908152a2565b5f80808084865af1611fa9611dd2565b50611f6c5760207f17afee8249f5e1d6dfa478ca1a3ce83d4c5117fa14bf2d6b12ef5ef1ddd9913c91835f52600b825260405f20611fe8828254611e7b565b9055604051908152a2565b6001600160401b038111610af95760051b60200190565b60ff60019116019060ff821161149d57565b60ff1660ff811461149d5760010190565b8051821015611d2c5760209160051b010190565b60ff1680612050575050601990565b60011461206957604051632711b74d60e11b8152600490fd5b805f915b63ffffffff81166120b6575060ff821680159081156120ab575b506120995760191c607f166120995790565b6040516373e5e94560e11b8152600490fd5b60199150115f612087565b916120c09061201c565b9163ffffffff8082165f19019190821161149d571661206d565b9161271061211561ffff61210d6121279761210860ff9861211c986001600160801b039a8b91169116611e68565b611ee8565b931683611e68565b0490611e7b565b906008541690611e7b565b90565b60018060a01b0380911690815f526004602052600160405f2062ff0000198154168155016001600160801b038154169055600660205260405f20548061216f57505050565b6005545f19919082810190811161149d5761218a8491611cf7565b90549060031b1c1682820182811161149d57816121a96121c792611cf7565b90919060018060a01b038084549260031b9316831b921b1916179055565b5f52600660205260405f205560055480156122065701906121e782611cf7565b909182549160031b1b191690556005555f5260066020525f6040812055565b634e487b7160e01b5f52603160045260245ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203aa66543d8b4fe7677e4b426efdec40de211a5c0570dd9136e90660d2351af9464736f6c63430008180033000000000000000000000000cc0fd2a3de622f58450565b3374c1ad11f7e3c7000000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e70000000000000000000000004011239ff8ff805b4c5e8bec9cf7a5ad43db7bca
0x6080806040526004361015610012575f80fd5b5f3560e01c90816229f07a14611cd15750806305573a0714611c97578063110f887414611c5c5780631294a32614611c385780631909145214611a5e5780631a29bb5414611a225780631c3c0ea81461196457806331c004e6146118355780633f4ba83a146117cc5780634c3e1176146117b157806357db7eaf1461177757806359a1d69c146117485780635bbf378314610e505780635c975abb14610e2e578063715018a614610dcb578063728e9ecc14610dae57806378a4715a14610d9157806379ba509714610d0c5780637fc4eda814610cf1578063803ae51814610caf57806382094f7a14610c755780638456cb5914610c1c5780638da5cb5b14610bf557806399d82c5f14610bb9578063a6c0ee3a14610b93578063b02e37ea14610776578063bb488c9b146106c5578063c34c08e51461069d578063d07b807314610683578063d24a67bc1461063f578063df3bb1cb146105e6578063e1a45218146105ca578063e30c3978146105a2578063f2fde38b14610531578063f318d0f21461044a578063f9a02f711461034e578063fcae44841461028e5763fce89878146101bd575f80fd5b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f52600460205261016060405f2080549061ffff906001600160801b03600182015460026001600160401b0393015492826040519660ff8116885260ff8160081c16602089015260ff8160101c1615156040890152868160181c16606089015263ffffffff8160281c16608089015260481c1660a087015280821660c08701528160401c1660e086015260801c610100850152811661012084015260801c16610140820152f35b5f80fd5b3461028a575f36600319011261028a576102a6611e88565b335f52600460205260405f2060ff815460101c161561033c576001015460801c6102cf3361212a565b80610314575b6040519081527f9d2620b94600a50652cca89233142c3b2cbafed08290ff3e95ba74429f06851160203392a260015f8051602061221b83398151915255005b5f80808084335af1610324611dd2565b506102d5575b6040516312171d8360e31b8152600490fd5b60405163046fcd8560e31b8152600490fd5b3461028a57602036600319011261028a576001600160401b036004358181169182820361028a5761037d611eb7565b7fe715e7482ca0d8bb3cff26570cbfd14e8bcf015bc2e7cfc8e84cfc18b757e83f5f81905260026020527ff0e8fb31f1343baefc2670c4067a056aa22460a16d542084d93986a8c9009a5c5460ff16610432575060407f0b0e4888e02853e0886c7212d705e051f19507074d6ae65ff8f1b826be4719d491600854948251918660801c1682526020820152a167ffffffffffffffff60801b1990911660809190911b67ffffffffffffffff60801b1617600855005b602490604051906374ca98b160e01b82526004820152fd5b3461028a5761046561045b36611d40565b9293919093612041565b604051635612b12b60e11b815292906020846004817f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03165afa938415610526575f946104ec575b60206104e4856001600160401b036104dc89888861ffff8093169260075460a01c16916120da565b911690611e68565b604051908152f35b935091906020843d60201161051e575b8161050960209383611db1565b8101031261028a5792519290916104dc6104b4565b3d91506104fc565b6040513d5f823e3d90fd5b3461028a57602036600319011261028a576004356001600160a01b038181169182900361028a57610560611eb7565b816bffffffffffffffffffffffff60a01b60015416176001555f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b3461028a575f36600319011261028a576001546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a5760206040516127108152f35b3461028a57602036600319011261028a57600435610602611eb7565b805f52600260205260405f20600160ff198254161790557fe92e44bc964ea5b6cb7a437f0ea8cf145b3db2993f35919b6a113a9beabc80eb5f80a2005b3461028a575f36600319011261028a576040517f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03168152602090f35b3461028a575f36600319011261028a5760206040515f8152f35b3461028a575f36600319011261028a576007546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a576106dd611e88565b6007546001600160a01b0390811690338290036107645760095480925f60095581610747575b507fee8488ff43f1d22d9b0d661f4da06e396b336308f970b4d375257d565887dfac6020836007541692604051908152a260015f8051602061221b83398151915255005b5f80809381935af1610757611dd2565b501561032a578183610703565b6040516361968ebb60e11b8152600490fd5b61077f36611d40565b9091610789611eca565b610791611e88565b335f52600460205260ff60405f205460101c16610b81576001600160401b03821615610b6f576001600160801b03831615610b5d576107d08185612041565b604051635612b12b60e11b81526020816004817f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03165afa908115610526575f91610b2b575b5061ffff908160075460a01c1661084a6001600160401b03871661084585851684888c6120da565b611e68565b803403610b0d57506001600160801b03600854169060ff6040519561086e87611d95565b818b16875216602086015260016040860152606085015263ffffffff851660808501526001600160801b03871660a08501526001600160401b03861660c08501525f60e08501526001600160801b03341661010085015261012084015216610140820152335f526004602052600260405f2060ff83511681549061ff00602086015160081b1662ff00006040870151151560101b1664ffff000000606088015160181b169168ffffffff0000000000608089015160281b169378ffffffffffffffffffffffffffffffff00000000000000000060a08a015160481b169566ffffffffffffff60c81b1617171717171781556109ec600182016001600160401b0360c0860151166001600160401b03198254161781556109bd6001600160401b0360e087015116829067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b61010085015181546001600160801b031660809190911b6fffffffffffffffffffffffffffffffff1916179055565b01906001600160801b036101208201511682549161014061ffff60801b91015160801b169171ffffffffffffffffffffffffffffffffffff1916171790556005549268010000000000000000841015610af95763ffffffff6001600160801b0392610a86610a688760016001600160401b039901600555611cf7565b81546001600160a01b0360039290921b91821b19163390911b179055565b600554335f52600660205260405f205560ff604051971687521660208601521660408401521660608201526001600160801b03341660808201527f9bc4441f718d89a32f5daf028fab66a39b121b568982c1ebd8ab91a36a19703c60a03392a260015f8051602061221b83398151915255005b634e487b7160e01b5f52604160045260245ffd5b604490604051906305897f0960e01b82523460048301526024820152fd5b90506020813d602011610b55575b81610b4660209383611db1565b8101031261028a57518661081d565b3d9150610b39565b604051631f2a200560e01b8152600490fd5b60405163065e270360e51b8152600490fd5b604051632fec509960e11b8152600490fd5b3461028a575f36600319011261028a5760206001600160801b0360085416604051908152f35b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f52600b602052602060405f2054604051908152f35b3461028a575f36600319011261028a575f546040516001600160a01b039091168152602090f35b3461028a575f36600319011261028a57610c34611eb7565b610c3c611eca565b600160ff1960035416176003557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b3461028a575f36600319011261028a5760206040517f45e220f5697f4355417727ad14267e66ff254ec466b7d1eb6cff2ea5e673f77f8152f35b3461028a57602036600319011261028a5760043560055481101561028a57610cd8602091611cf7565b905460405160039290921b1c6001600160a01b03168152f35b3461028a575f36600319011261028a57602060405160198152f35b3461028a575f36600319011261028a576001546001600160a01b033381831603610d79576bffffffffffffffffffffffff60a01b8092166001555f549133908316175f553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b60405163118cdaa760e01b8152336004820152602490fd5b3461028a575f36600319011261028a576020600954604051908152f35b3461028a575f36600319011261028a576020600554604051908152f35b3461028a575f36600319011261028a57610de3611eb7565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461028a575f36600319011261028a57602060ff600354166040519015158152f35b3461028a57602036600319011261028a576001600160401b036004351161028a5736602360043501121561028a576001600160401b03600435600401351161028a573660246004356004013560051b60043501011161028a57610eb1611eca565b610eb9611e88565b6007546001600160a01b0316330361076457604051639cbe5efd60e01b81526020816004817f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03165afa908115610526575f9161170e575b5060405163144d022960e01b81526001600160401b038216600482015261022080826024817f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03165afa918215610526575f926115c6575b505051906040519060208201926001600160401b0360c01b809260c01b16845260c01b16602882015260108152604081018181106001600160401b03821117610af9576040525190205f905b600435600401358210610fe4575b60015f8051602061221b83398151915255005b5a6001600160401b0360085460801c161161158e57600435600583901b01602401356001600160a01b038116900361028a5760018060a01b0360248360051b600435010135165f52600460205260405f209160ff835460101c161561158457815f52600a8060205260405f2060018060a01b0360248460051b600435010135165f5260205260ff60405f20541661157957825f5260205260405f2060018060a01b0360248360051b600435010135165f5260205260405f20600160ff1982541617905560028301548354916127106110ef6110d160ff8660081c166001600160801b038760481c16611e68565b6110e461ffff91828760801c1690611ee8565b9560181c1685611e68565b049161110d6001600160801b0382166111088587611e7b565b611e7b565b9586600182015460801c1061155b5780549560ff8760081c169661114961113389611ff3565b986111416040519a8b611db1565b808a52611ff3565b601f19013660208a013760ff81166114e757505f5b60ff81166019811015611190578160019160ff61118561117e829661200a565b928d61202d565b91169052011661115e565b5050969193959092945b7f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03163b1561028a576040518092630a4a60c560e21b82526044820160018060a01b0360248a60051b6004350101351660048401526040602484015281518091526020606484019201905f905b8082106114c857505f94928490039284925090507f00000000000000000000000088c87c609a13b31c6721a323bd4dc3d28eaf34e76001600160a01b03165af190816114b1575b506113755750505060019150611269611dd2565b80519060048210908161136c57602001516001600160e01b03199283821692611357575b505090505b63ffffffff60e01b16639e61674760e01b8114908115611346575b8115611335575b50156112f957818060a01b0360248260051b600435010135167f31b740a2126076f8e62e316ade07cb0677888045ed02c91f40ef96cf33c848c05f80a25b0190610fc3565b818060a01b0360248260051b600435010135167f0cddc7f3a22f81520638293af12599a9ad1cc7a1a0b41c4e49b85d3ed8fdafad5f80a26112f2565b63d93c066560e01b149050846112b4565b6348d51aad60e11b811491506112ad565b8391925060040360031b1b161680858061128d565b5050505f611292565b6001600160801b038116600183015460801c036001600160801b03811161149d576113b89060018401906001600160801b0382549181199060801b169116179055565b60016001600160401b038184015460401c1601926001600160401b03841161149d576001956001600160801b036114209261141989978888019067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b1690611e7b565b61142d6009918254611e7b565b90556040519081527f136bd939f0776bdd0c5d89bb45ba62e96b6e8b0b6dbedd1ed3c8644397e4cb2d6020848060a01b0360248760051b6004350101351692a201546001600160401b038082169160401c16106112f25761149860248260051b600435010135611f40565b6112f2565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b038111610af95760405287611255565b9193509160208060019260ff875116815201940192018593929161120e565b949290969593915f975f5b60ff8116601981101561154957600163ffffffff911b8960281c161661151e575b60010160ff166114f2565b6115278161200a565b6115308b61201c565b9a60ff1661153e908b61202d565b9060ff169052611513565b5050989397509390945094909461119a565b5050915050600191925061149860248260051b600435010135611f40565b5060019192506112f2565b60019192506112f2565b5060407f8f1403bec0a17defea3a808da2ff7a763f2d127d0f930b27fcc8ff9ef9e216ce915a82519182526020820152a18080610fd1565b9080925081813d8311611707575b6115de8183611db1565b8101031261028a576040519182018281106001600160401b03821117610af95760405261160a81611e47565b825261161860208201611e47565b602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201519060ff8216820361028a5783015261012081810151906001600160a01b038216820361028a57830152610140611697818301611e5b565b908301526101606116a9818301611e5b565b908301526101806116bb818301611e5b565b908301526101a06116cd818301611e5b565b908301526101c06116df818301611e5b565b908301526101e080820151908301526116fc610200809201611e47565b908201528280610f77565b503d6115d4565b90506020813d602011611740575b8161172960209383611db1565b8101031261028a5761173a90611e47565b81610f18565b3d915061171c565b3461028a57602036600319011261028a576004355f526002602052602060ff60405f2054166040519015158152f35b3461028a575f36600319011261028a5760206040517fe715e7482ca0d8bb3cff26570cbfd14e8bcf015bc2e7cfc8e84cfc18b757e83f8152f35b3461028a575f36600319011261028a57602060405160018152f35b3461028a575f36600319011261028a576117e4611eb7565b60035460ff8116156118235760ff19166003557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b604051638dfc202b60e01b8152600490fd5b3461028a57604036600319011261028a5760043561ffff81169081810361028a57602435916001600160801b03831680930361028a57611873611eb7565b7fdca2fbbcd19b1d32f2606e8bd7494c8b0a3db58da0461d005d6a7af7b1def6795f81905260026020527f84339fb3848a68d79582ac1624c6502e246055f0b59a17379ba7232a0c3bb8e15460ff1661043257506127108111611930577fc4f1b19e28c7452ef005df1e28d41f0896abff20264d65837fa9e8385823835f926040926007549061ffff60a01b9060a01b169061ffff60a01b191617600755806001600160801b0319600854161760085582519182526020820152a1005b60405162461bcd60e51b815260206004820152600c60248201526b0c4e0e640e8dede40d0d2ced60a31b6044820152606490fd5b3461028a57602036600319011261028a576004356001600160a01b038181169182900361028a57611993611eb7565b7f45e220f5697f4355417727ad14267e66ff254ec466b7d1eb6cff2ea5e673f77f5f81905260026020527f331a62cd40d41535b190b54364366a5e8a6f4abcf01ece4911d8a4e875aa5a905460ff166104325750816007549182167f54a57d849b9d8af1a8883dad9184e599aa67ef60814f6c91db7f864abd4325fc5f80a36001600160a01b03191617600755005b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f526006602052602060405f2054604051908152f35b3461028a57602036600319011261028a576004356001600160a01b0381169081900361028a575f610140604051611a9481611d95565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015201525f52600460205261016060405f2061ffff610140604051611af181611d95565b82600285549560ff8716845260ff8760081c16602085015260ff8760101c1615156040850152828760181c16606085015263ffffffff8760281c1660808501526001600160801b038760481c1660a085015260018101546001600160401b03811660c08601526001600160401b038160401c1660e086015260801c61010085015201546001600160801b03811661012084015260801c168282015260ff6040519416845260ff602082015116602085015260408101511515604085015282606082015116606085015263ffffffff60808201511660808501526001600160801b0360a08201511660a08501526001600160401b0360c08201511660c08501526001600160401b0360e08201511660e08501526001600160801b03610100820151166101008501526001600160801b0361012082015116610120850152015116610140820152f35b3461028a575f36600319011261028a57602061ffff60075460a01c16604051908152f35b3461028a575f36600319011261028a57611c74611e88565b6020611c7e611e10565b60015f8051602061221b83398151915255604051908152f35b3461028a575f36600319011261028a5760206040517fdca2fbbcd19b1d32f2606e8bd7494c8b0a3db58da0461d005d6a7af7b1def6798152f35b3461028a575f36600319011261028a576020906001600160401b0360085460801c168152f35b600554811015611d2c5760055f527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001905f90565b634e487b7160e01b5f52603260045260245ffd5b608090600319011261028a5760043560ff8116810361028a579060243563ffffffff8116810361028a57906044356001600160801b038116810361028a57906064356001600160401b038116810361028a5790565b61016081019081106001600160401b03821117610af957604052565b90601f801991011681019081106001600160401b03821117610af957604052565b3d15611e0b573d906001600160401b038211610af95760405191611e00601f8201601f191660200184611db1565b82523d5f602084013e565b606090565b335f52600b60205260405f20908154918215611e41575f90555f80808085335af1611e39611dd2565b501561032a57565b505f9150565b51906001600160401b038216820361028a57565b5190811515820361028a57565b8181029291811591840414171561149d57565b9190820180921161149d57565b5f8051602061221b8339815191526002815414611ea55760029055565b604051633ee5aeb560e01b8152600490fd5b5f546001600160a01b03163303610d7957565b60ff60035416611ed657565b60405163d93c066560e01b8152600490fd5b9061ffff16612710908082039282841161149d578281029080820484149015171561149d5783611f1791611e7b565b5f1981019290831161149d5714611f2c570490565b634e487b7160e01b5f52601260045260245ffd5b60018060a01b03811690815f526004602052611f66600160405f20015460801c9161212a565b80611f99575b60207fd351722477b8e6ec7fae918455c0994811e4e33d78a66798032434926412a88791604051908152a2565b5f80808084865af1611fa9611dd2565b50611f6c5760207f17afee8249f5e1d6dfa478ca1a3ce83d4c5117fa14bf2d6b12ef5ef1ddd9913c91835f52600b825260405f20611fe8828254611e7b565b9055604051908152a2565b6001600160401b038111610af95760051b60200190565b60ff60019116019060ff821161149d57565b60ff1660ff811461149d5760010190565b8051821015611d2c5760209160051b010190565b60ff1680612050575050601990565b60011461206957604051632711b74d60e11b8152600490fd5b805f915b63ffffffff81166120b6575060ff821680159081156120ab575b506120995760191c607f166120995790565b6040516373e5e94560e11b8152600490fd5b60199150115f612087565b916120c09061201c565b9163ffffffff8082165f19019190821161149d571661206d565b9161271061211561ffff61210d6121279761210860ff9861211c986001600160801b039a8b91169116611e68565b611ee8565b931683611e68565b0490611e7b565b906008541690611e7b565b90565b60018060a01b0380911690815f526004602052600160405f2062ff0000198154168155016001600160801b038154169055600660205260405f20548061216f57505050565b6005545f19919082810190811161149d5761218a8491611cf7565b90549060031b1c1682820182811161149d57816121a96121c792611cf7565b90919060018060a01b038084549260031b9316831b921b1916179055565b5f52600660205260405f205560055480156122065701906121e782611cf7565b909182549160031b1b191690556005555f5260066020525f6040812055565b634e487b7160e01b5f52603160045260245ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203aa66543d8b4fe7677e4b426efdec40de211a5c0570dd9136e90660d2351af9464736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| DIH | 1 | $0.0000102 | $0 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x114e32c1…0a5e7d | Transfer | 20,574,199 | 21 days agoMon, 27 Jul 2026 08:04:15 UTC | 0xcaf7…5d11 | IN | 0x6b06…41da | $0.001 DIH |
| 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 |
|---|---|---|---|
| 0x30e159…498ef5 | 9 days agoSat, 08 Aug 2026 13:57:41 UTC | 0xee8488…dfac | [0] 0x000000000000…43db7bca data: 0x000000000000000000…00000000 |
| 0x0450b4…1992fc | 9 days agoSat, 08 Aug 2026 13:18:14 UTC | 0xee8488…dfac | [0] 0x000000000000…43db7bca data: 0x000000000000000000…154da814 |
| 0x2fc25f…aaa982 | 35 days agoMon, 13 Jul 2026 19:54:44 UTC | 0x9d2620…8511 | [0] 0x000000000000…7ce39cb4 data: 0x000000000000000000…9f90ae8d |
| 0xfc1e08…80e434 | 35 days agoMon, 13 Jul 2026 19:53:51 UTC | 0x136bd9…cb2d | [0] 0x000000000000…7ce39cb4 data: 0x000000000000000000…35303a2f |
| 0x30328e…39020e | 35 days agoMon, 13 Jul 2026 19:53:08 UTC | 0x136bd9…cb2d | [0] 0x000000000000…7ce39cb4 data: 0x000000000000000000…35303a2f |
| 0x49ada8…55494a | 35 days agoMon, 13 Jul 2026 19:53:05 UTC | 0x9bc444…703c | [0] 0x000000000000…7ce39cb4 data: 0x000000000000000000…09f122eb |
| 0x61ee85…c01417 | 35 days agoMon, 13 Jul 2026 10:11:04 UTC | 0xd35172…a887 | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…00000000 |
| 0x61ee85…c01417 | 35 days agoMon, 13 Jul 2026 10:11:04 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xa8aad2…f81126 | 35 days agoMon, 13 Jul 2026 10:09:56 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x2493da…f8e805 | 35 days agoMon, 13 Jul 2026 10:08:48 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x6294e7…9883b4 | 35 days agoMon, 13 Jul 2026 10:07:40 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x2bb8b9…bf7c4f | 35 days agoMon, 13 Jul 2026 10:06:32 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xbb0de1…19ac1a | 35 days agoMon, 13 Jul 2026 10:05:22 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x5106c9…e3b003 | 35 days agoMon, 13 Jul 2026 10:04:14 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x2e0ea7…949274 | 35 days agoMon, 13 Jul 2026 10:03:06 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x887a11…c7ae47 | 35 days agoMon, 13 Jul 2026 10:01:57 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xa665a9…b6ea03 | 35 days agoMon, 13 Jul 2026 10:00:49 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xfa8490…468c76 | 35 days agoMon, 13 Jul 2026 09:59:41 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x1eb48d…4c0951 | 35 days agoMon, 13 Jul 2026 09:58:33 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xbcd9bf…52cdc4 | 35 days agoMon, 13 Jul 2026 09:57:24 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x2a1a0b…5245e2 | 35 days agoMon, 13 Jul 2026 09:56:16 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x71c2de…47382e | 35 days agoMon, 13 Jul 2026 09:55:06 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xd3a40f…fd81c9 | 35 days agoMon, 13 Jul 2026 09:53:56 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0x8abd30…5613a2 | 35 days agoMon, 13 Jul 2026 09:52:48 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| 0xa917aa…8f58c7 | 35 days agoMon, 13 Jul 2026 09:51:40 UTC | 0x136bd9…cb2d | [0] 0x000000000000…a2e0e87e data: 0x000000000000000000…35303a2f |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x30e159…498ef5 | withdrawExecutorFees | 31,126,873 | 9 days agoSat, 08 Aug 2026 13:57:41 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00000085 | |
| 0x0450b4…1992fc | withdrawExecutorFees | 31,103,260 | 9 days agoSat, 08 Aug 2026 13:18:14 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00000099 | |
| 0x2fc25f…aaa982 | unsubscribe | 8,934,662 | 35 days agoMon, 13 Jul 2026 19:54:44 UTC | 0xc536…9cb4 | IN | AutoMiner | $0.000 ETH | 0.00000256 | |
| 0xfc1e08…80e434 | executeBatch | 8,934,122 | 35 days agoMon, 13 Jul 2026 19:53:51 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008621 | |
| 0x30328e…39020e | executeBatch | 8,933,696 | 35 days agoMon, 13 Jul 2026 19:53:08 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008803 | |
| 0x49ada8…55494a | subscribe | 8,933,663 | 35 days agoMon, 13 Jul 2026 19:53:05 UTC | 0xc536…9cb4 | IN | AutoMiner | $2.810.00147 ETH | 0.00000902 | |
| 0x61ee85…c01417 | executeBatch | 8,584,995 | 35 days agoMon, 13 Jul 2026 10:11:04 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008348 | |
| 0xa8aad2…f81126 | executeBatch | 8,584,320 | 35 days agoMon, 13 Jul 2026 10:09:56 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008329 | |
| 0x2493da…f8e805 | executeBatch | 8,583,644 | 35 days agoMon, 13 Jul 2026 10:08:48 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008331 | |
| 0x6294e7…9883b4 | executeBatch | 8,582,965 | 35 days agoMon, 13 Jul 2026 10:07:40 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008470 | |
| 0x2bb8b9…bf7c4f | executeBatch | 8,582,289 | 35 days agoMon, 13 Jul 2026 10:06:32 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008319 | |
| 0xbb0de1…19ac1a | executeBatch | 8,581,587 | 35 days agoMon, 13 Jul 2026 10:05:22 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008380 | |
| 0x5106c9…e3b003 | executeBatch | 8,580,903 | 35 days agoMon, 13 Jul 2026 10:04:14 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008325 | |
| 0x2e0ea7…949274 | executeBatch | 8,580,229 | 35 days agoMon, 13 Jul 2026 10:03:06 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008444 | |
| 0x887a11…c7ae47 | executeBatch | 8,579,548 | 35 days agoMon, 13 Jul 2026 10:01:57 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008386 | |
| 0xa665a9…b6ea03 | executeBatch | 8,578,868 | 35 days agoMon, 13 Jul 2026 10:00:49 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008364 | |
| 0xfa8490…468c76 | executeBatch | 8,578,189 | 35 days agoMon, 13 Jul 2026 09:59:41 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008330 | |
| 0x1eb48d…4c0951 | executeBatch | 8,577,499 | 35 days agoMon, 13 Jul 2026 09:58:33 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008600 | |
| 0xbcd9bf…52cdc4 | executeBatch | 8,576,822 | 35 days agoMon, 13 Jul 2026 09:57:24 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008407 | |
| 0x2a1a0b…5245e2 | executeBatch | 8,576,144 | 35 days agoMon, 13 Jul 2026 09:56:16 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008384 | |
| 0x71c2de…47382e | executeBatch | 8,575,443 | 35 days agoMon, 13 Jul 2026 09:55:06 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008358 | |
| 0xd3a40f…fd81c9 | executeBatch | 8,574,753 | 35 days agoMon, 13 Jul 2026 09:53:56 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008489 | |
| 0x8abd30…5613a2 | executeBatch | 8,574,070 | 35 days agoMon, 13 Jul 2026 09:52:48 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008389 | |
| 0xa917aa…8f58c7 | executeBatch | 8,573,382 | 35 days agoMon, 13 Jul 2026 09:51:40 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008337 | |
| 0x8239ae…16d8b9 | executeBatch | 8,572,708 | 35 days agoMon, 13 Jul 2026 09:50:32 UTC | 0x4011…7bca | IN | AutoMiner | $0.000 ETH | 0.00008368 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 31,103,260 | 9 days agoSat, 08 Aug 2026 13:18:14 UTC | 0x0450b4…1992fc | CALL | withdrawExecutorFees | 0x6b06…41da | OUT | 0x4011…7bca | 0.00142 ETH |
| 8,471,951 | 35 days agoMon, 13 Jul 2026 07:02:19 UTC | 0x0fa9ff…a13540 | CALL | executeBatch | 0x6b06…41da | OUT | 0x88c8…34e7 | 0.00025 ETH |