// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol";
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {SwapParams} from "@uniswap/v4-core/src/types/PoolOperation.sol";
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
import {ISwapRouter02, IUniswapV2Router02} from "./interfaces/ISwapVenues.sol";
interface IRhmiDistributor {
function registerAsset(address rewardToken) external returns (uint256 assetId);
function distribute(uint256 assetId, uint256 amount) external;
}
/// @title RhmiTreasury
/// @notice Multi-asset custody of the ETH taxes streamed in by RhmiFeeHook.
///
/// Same non-negotiable security property as the audited single-asset base:
/// **there is no withdraw function and the payout destination is immutable**.
/// ETH leaves this contract through exactly one path — a swap into an ACTIVE
/// reward asset on Uniswap v4, v3, or v2, delivered to the `distributor`
/// fixed at deploy. The multisig curates the basket; it never custodies or
/// redirects funds.
contract RhmiTreasury is Ownable2Step, ReentrancyGuard, IUnlockCallback {
enum SwapVenue {
V4,
V3,
V2
}
IPoolManager public immutable poolManager;
address public immutable distributor;
struct RewardAsset {
address token;
SwapVenue venue;
bool active;
// V4: pool fee / tickSpacing / hooks. V2/V3: swapRouter / swapFee tier / WETH.
address swapRouter;
uint24 swapFee;
int24 tickSpacing;
address hooksOrWeth;
// Site/indexer counters.
uint256 ethSpent;
uint256 bought;
}
RewardAsset[] private _assets; // ids are shared 1:1 with the distributor
mapping(address => uint256) private _assetIdPlusOne;
mapping(address => bool) public isKeeper;
uint256 public maxSpendPerCall; // 0 = uncapped
uint256 public buyCooldown;
uint256 public lastBuyAt;
// Site/indexer counters.
uint256 public totalEthReceived;
uint256 public totalEthSpent;
event Received(address indexed from, uint256 amount);
event AssetAdded(
uint256 indexed assetId,
address indexed token,
SwapVenue venue,
address swapRouter,
uint24 swapFee,
int24 tickSpacing,
address hooksOrWeth
);
event AssetDeactivated(uint256 indexed assetId, address indexed token);
event KeeperUpdated(address indexed keeper, bool allowed);
event GuardrailsUpdated(uint256 maxSpendPerCall, uint256 buyCooldown);
event BoughtAndDistributed(uint256 indexed assetId, uint256 ethSpent, uint256 rewardOut);
error ZeroAddress();
error UnknownAsset();
error AssetNotActive();
error IdMismatch();
error OnlyKeeper();
error OnlyPoolManager();
error ZeroMinOut();
error CooldownActive();
error NothingToSpend();
error Slippage(uint256 out, uint256 minOut);
error CooldownTooHigh();
error InvalidRoute();
constructor(
IPoolManager poolManager_,
address distributor_,
address owner_,
uint256 maxSpendPerCall_,
uint256 buyCooldown_
) Ownable(owner_) {
if (address(poolManager_) == address(0) || distributor_ == address(0)) revert ZeroAddress();
poolManager = poolManager_;
distributor = distributor_;
maxSpendPerCall = maxSpendPerCall_;
if (buyCooldown_ > 1 days) revert CooldownTooHigh();
buyCooldown = buyCooldown_;
}
/// @notice Taxes arrive as native ETH from the hook's poolManager.take().
receive() external payable {
totalEthReceived += msg.value;
emit Received(msg.sender, msg.value);
}
// ---- views (contract-native site/indexer surface) ----
function assetCount() external view returns (uint256) {
return _assets.length;
}
function assetAt(uint256 assetId) external view returns (RewardAsset memory) {
if (assetId >= _assets.length) revert UnknownAsset();
return _assets[assetId];
}
function assetIdOf(address token_) external view returns (bool exists, uint256 assetId) {
uint256 idPlusOne = _assetIdPlusOne[token_];
return idPlusOne == 0 ? (false, 0) : (true, idPlusOne - 1);
}
/// @notice Protocol stats in one call: lifetime ETH in/out, current pot,
/// and the full basket with per-asset spend/bought counters.
function stats()
external
view
returns (uint256 ethReceived, uint256 ethSpent, uint256 ethPot, RewardAsset[] memory basket)
{
return (totalEthReceived, totalEthSpent, address(this).balance, _assets);
}
// ---- multisig curation (never touches funds) ----
function setKeeper(address keeper, bool allowed) external onlyOwner {
if (keeper == address(0)) revert ZeroAddress();
isKeeper[keeper] = allowed;
emit KeeperUpdated(keeper, allowed);
}
function setGuardrails(uint256 maxSpendPerCall_, uint256 buyCooldown_) external onlyOwner {
if (buyCooldown_ > 1 days) revert CooldownTooHigh();
maxSpendPerCall = maxSpendPerCall_;
buyCooldown = buyCooldown_;
emit GuardrailsUpdated(maxSpendPerCall_, buyCooldown_);
}
/// @notice Add a reward asset (new id, capped at 8 by the distributor) or
/// reactivate/re-route an existing one (same id and accounting slot).
/// @param venue_ V4 = native v4 pool; V3/V2 = external router + WETH path.
/// @param swapRouter_ V3/V2 router address (zero for V4).
/// @param swapFee_ V4 pool fee or V3 fee tier (ignored for V2).
/// @param tickSpacing_ V4 tick spacing (zero for V2/V3).
/// @param hooksOrWeth_ V4 hooks address or WETH for V2/V3 ETH pairs.
function addRewardAsset(
address token_,
SwapVenue venue_,
address swapRouter_,
uint24 swapFee_,
int24 tickSpacing_,
address hooksOrWeth_
) external onlyOwner returns (uint256 assetId) {
if (token_ == address(0)) revert ZeroAddress();
if (venue_ == SwapVenue.V4) {
if (swapRouter_ != address(0)) revert InvalidRoute();
} else if (swapRouter_ == address(0) || hooksOrWeth_ == address(0)) {
revert InvalidRoute();
}
assetId = IRhmiDistributor(distributor).registerAsset(token_);
uint256 idPlusOne = _assetIdPlusOne[token_];
if (idPlusOne == 0) {
if (assetId != _assets.length) revert IdMismatch();
_assets.push(
RewardAsset({
token: token_,
venue: venue_,
active: true,
swapRouter: swapRouter_,
swapFee: swapFee_,
tickSpacing: tickSpacing_,
hooksOrWeth: hooksOrWeth_,
ethSpent: 0,
bought: 0
})
);
_assetIdPlusOne[token_] = assetId + 1;
} else {
if (idPlusOne - 1 != assetId) revert IdMismatch();
RewardAsset storage a = _assets[assetId];
a.venue = venue_;
a.swapRouter = swapRouter_;
a.swapFee = swapFee_;
a.tickSpacing = tickSpacing_;
a.hooksOrWeth = hooksOrWeth_;
a.active = true;
}
emit AssetAdded(assetId, token_, venue_, swapRouter_, swapFee_, tickSpacing_, hooksOrWeth_);
}
/// @notice Stop NEW buys of an asset (rug/delisting response). Rewards
/// already distributed remain claimable at the distributor forever.
function deactivateRewardAsset(uint256 assetId) external onlyOwner {
if (assetId >= _assets.length) revert UnknownAsset();
_assets[assetId].active = false;
emit AssetDeactivated(assetId, _assets[assetId].token);
}
// ---- the only way ETH ever leaves ----
/// @notice Swap a bounded slice of the held ETH into an ACTIVE reward
/// asset and credit it to the immutable distributor.
function buyAndDistribute(uint256 assetId, uint256 minOut)
external
nonReentrant
returns (uint256 ethSpent, uint256 rewardOut)
{
if (!isKeeper[msg.sender] && msg.sender != owner()) revert OnlyKeeper();
if (assetId >= _assets.length) revert UnknownAsset();
RewardAsset storage a = _assets[assetId];
if (!a.active) revert AssetNotActive();
if (minOut == 0) revert ZeroMinOut();
if (block.timestamp < lastBuyAt + buyCooldown) revert CooldownActive();
ethSpent = address(this).balance;
if (maxSpendPerCall != 0 && ethSpent > maxSpendPerCall) ethSpent = maxSpendPerCall;
if (ethSpent == 0) revert NothingToSpend();
lastBuyAt = block.timestamp;
uint256 distributorBefore = IERC20(a.token).balanceOf(distributor);
if (a.venue == SwapVenue.V4) {
poolManager.unlock(abi.encode(assetId, ethSpent, minOut));
} else if (a.venue == SwapVenue.V3) {
_buyV3(a, ethSpent, minOut);
} else {
_buyV2(a, ethSpent, minOut);
}
rewardOut = IERC20(a.token).balanceOf(distributor) - distributorBefore;
if (rewardOut < minOut) revert Slippage(rewardOut, minOut);
IRhmiDistributor(distributor).distribute(assetId, rewardOut);
totalEthSpent += ethSpent;
a.ethSpent += ethSpent;
a.bought += rewardOut;
emit BoughtAndDistributed(assetId, ethSpent, rewardOut);
}
function unlockCallback(bytes calldata data) external returns (bytes memory) {
if (msg.sender != address(poolManager)) revert OnlyPoolManager();
(uint256 assetId, uint256 spend, uint256 minOut) = abi.decode(data, (uint256, uint256, uint256));
RewardAsset storage a = _assets[assetId];
if (a.venue != SwapVenue.V4) revert InvalidRoute();
PoolKey memory key = PoolKey({
currency0: Currency.wrap(address(0)),
currency1: Currency.wrap(a.token),
fee: a.swapFee,
tickSpacing: a.tickSpacing,
hooks: IHooks(a.hooksOrWeth)
});
BalanceDelta delta = poolManager.swap(
key,
SwapParams({
zeroForOne: true,
amountSpecified: -int256(spend),
sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1
}),
""
);
uint256 out = uint256(uint128(delta.amount1()));
if (out < minOut) revert Slippage(out, minOut);
poolManager.settle{value: spend}();
poolManager.take(Currency.wrap(a.token), distributor, out);
return "";
}
function _buyV3(RewardAsset storage a, uint256 spend, uint256 minOut) private {
ISwapRouter02.ExactInputSingleParams memory params = ISwapRouter02.ExactInputSingleParams({
tokenIn: a.hooksOrWeth,
tokenOut: a.token,
fee: a.swapFee,
recipient: distributor,
amountIn: spend,
amountOutMinimum: minOut,
sqrtPriceLimitX96: 0
});
ISwapRouter02(a.swapRouter).exactInputSingle{value: spend}(params);
}
function _buyV2(RewardAsset storage a, uint256 spend, uint256 minOut) private {
address[] memory path = new address[](2);
path[0] = a.hooksOrWeth;
path[1] = a.token;
IUniswapV2Router02(a.swapRouter).swapExactETHForTokensSupportingFeeOnTransferTokens{value: spend}(
minOut, path, distributor, block.timestamp
);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "poolManager_",
"type": "address",
"internalType": "contract IPoolManager"
},
{
"name": "distributor_",
"type": "address",
"internalType": "address"
},
{
"name": "owner_",
"type": "address",
"internalType": "address"
},
{
"name": "maxSpendPerCall_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "buyCooldown_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AssetNotActive",
"type": "error",
"inputs": []
},
{
"name": "CooldownActive",
"type": "error",
"inputs": []
},
{
"name": "CooldownTooHigh",
"type": "error",
"inputs": []
},
{
"name": "IdMismatch",
"type": "error",
"inputs": []
},
{
"name": "InvalidRoute",
"type": "error",
"inputs": []
},
{
"name": "NothingToSpend",
"type": "error",
"inputs": []
},
{
"name": "OnlyKeeper",
"type": "error",
"inputs": []
},
{
"name": "OnlyPoolManager",
"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": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "Slippage",
"type": "error",
"inputs": [
{
"name": "out",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minOut",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "UnknownAsset",
"type": "error",
"inputs": []
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "ZeroMinOut",
"type": "error",
"inputs": []
},
{
"name": "AssetAdded",
"type": "event",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "venue",
"type": "uint8",
"indexed": false,
"internalType": "enum RhmiTreasury.SwapVenue"
},
{
"name": "swapRouter",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "swapFee",
"type": "uint24",
"indexed": false,
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"indexed": false,
"internalType": "int24"
},
{
"name": "hooksOrWeth",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "AssetDeactivated",
"type": "event",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "BoughtAndDistributed",
"type": "event",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "ethSpent",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "rewardOut",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "GuardrailsUpdated",
"type": "event",
"inputs": [
{
"name": "maxSpendPerCall",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "buyCooldown",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "KeeperUpdated",
"type": "event",
"inputs": [
{
"name": "keeper",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "allowed",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"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": "Received",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "acceptOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "addRewardAsset",
"type": "function",
"inputs": [
{
"name": "token_",
"type": "address",
"internalType": "address"
},
{
"name": "venue_",
"type": "uint8",
"internalType": "enum RhmiTreasury.SwapVenue"
},
{
"name": "swapRouter_",
"type": "address",
"internalType": "address"
},
{
"name": "swapFee_",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing_",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooksOrWeth_",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "assetId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "assetAt",
"type": "function",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "venue",
"type": "uint8",
"internalType": "enum RhmiTreasury.SwapVenue"
},
{
"name": "active",
"type": "bool",
"internalType": "bool"
},
{
"name": "swapRouter",
"type": "address",
"internalType": "address"
},
{
"name": "swapFee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooksOrWeth",
"type": "address",
"internalType": "address"
},
{
"name": "ethSpent",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "bought",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct RhmiTreasury.RewardAsset"
}
],
"stateMutability": "view"
},
{
"name": "assetCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "assetIdOf",
"type": "function",
"inputs": [
{
"name": "token_",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "exists",
"type": "bool",
"internalType": "bool"
},
{
"name": "assetId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "buyAndDistribute",
"type": "function",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minOut",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "ethSpent",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "rewardOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "buyCooldown",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "deactivateRewardAsset",
"type": "function",
"inputs": [
{
"name": "assetId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "distributor",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "isKeeper",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "lastBuyAt",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "maxSpendPerCall",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "pendingOwner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "poolManager",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IPoolManager"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setGuardrails",
"type": "function",
"inputs": [
{
"name": "maxSpendPerCall_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "buyCooldown_",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setKeeper",
"type": "function",
"inputs": [
{
"name": "keeper",
"type": "address",
"internalType": "address"
},
{
"name": "allowed",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "stats",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "ethReceived",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "ethSpent",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "ethPot",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "basket",
"type": "tuple[]",
"components": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "venue",
"type": "uint8",
"internalType": "enum RhmiTreasury.SwapVenue"
},
{
"name": "active",
"type": "bool",
"internalType": "bool"
},
{
"name": "swapRouter",
"type": "address",
"internalType": "address"
},
{
"name": "swapFee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "tickSpacing",
"type": "int24",
"internalType": "int24"
},
{
"name": "hooksOrWeth",
"type": "address",
"internalType": "address"
},
{
"name": "ethSpent",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "bought",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct RhmiTreasury.RewardAsset[]"
}
],
"stateMutability": "view"
},
{
"name": "totalEthReceived",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "totalEthSpent",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unlockCallback",
"type": "function",
"inputs": [
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"stateMutability": "nonpayable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x60c0346101c157601f611d3938819003918201601f19168301916001600160401b038311848410176101c55780849260a0946040528339810103126101c15780516001600160a01b038116918282036101c15761005e602082016101d9565b61006a604083016101d9565b92608060608401519301519360018060a01b03169485156101ae57600180546001600160a01b03199081169091555f80549182168817815560405197916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005515801561019d575b61018e5760805260a05260055562015180811161017f57600655611b4b90816101ee82396080518181816102290152818161058e01526110a8015260a0518181816104210152818161079c015281816109e101528181611005015281816110fd01528181611151015281816111a2015281816113e701526115930152f35b6310c2dd1d60e21b5f5260045ffd5b63d92e233d60e01b5f5260045ffd5b506001600160a01b03821615610101565b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101c15756fe60806040526004361015610055575b3615610018575f80fd5b610024346008546119c1565b6008556040513481527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f8852587460203392a2005b5f803560e01c80631bf5518b1461184e57806327e39977146118315780632cd53845146117c8578063645b00bd146117525780636ba42aaa146117155780636f630c3814610f19578063704fbfe514610efb578063715018a614610e9657806379ba509714610e115780638da5cb5b14610dea5780638e6d34561461092b57806391dd73461461053c57806392d3b8861461051e57806394018d1214610500578063a9a18dda146104e2578063aa9239f514610450578063bfe109281461040b578063d1b9e85314610372578063d80528ae14610258578063dc4c90d314610213578063e30c3978146101ea578063eafe7a74146101cc5763f2fde38b1461015d575061000e565b346101c95760203660031901126101c9576101766118c2565b61017e611aef565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b80fd5b50346101c957806003193601126101c9576020600254604051908152f35b50346101c957806003193601126101c9576001546040516001600160a01b039091168152602090f35b50346101c957806003193601126101c9576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101c957806003193601126101c957600854906009549147916002549267ffffffffffffffff841161035e5793929160208360051b0161029d60405191826119ff565b838152600283526020810193837f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace865b83831061033457505050506040519586956080870193875260208701526040860152608060608601525180915260a0840192915b81811061030f575050500390f35b919350916020610120826103266001948851611925565b019401910191849392610301565b6005602060019261034a859d98999b9c9d611a60565b8152019201920191909897969493986102cd565b634e487b7160e01b82526041600452602482fd5b50346101c95760403660031901126101c95761038c6118c2565b60243590811515809203610407576103a2611aef565b6001600160a01b03169081156103f85760207f786c9db967bf0c6b16c7c91adae8a8c554b15a57d373fa2059607300f4616c0091838552600482526040852060ff1981541660ff8316179055604051908152a280f35b63d92e233d60e01b8352600483fd5b8280fd5b50346101c957806003193601126101c9576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101c95760203660031901126101c9576004359080610100604051610476816119ce565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e082015201526002548210156104d3576101206104c46104be846119a5565b50611a60565b6104d16040518092611925565bf35b63c97d95cf60e01b8152600490fd5b50346101c957806003193601126101c9576020600854604051908152f35b50346101c957806003193601126101c9576020600554604051908152f35b50346101c957806003193601126101c9576020600954604051908152f35b50346101c95760203660031901126101c9576004359067ffffffffffffffff82116101c957366023830112156101c957816004013567ffffffffffffffff8111610918578201366024820111610918577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316903382900361091c5760609084900312610918576044830135926105e2602460648301359201356119a5565b50805460ff8160a01c166003811015610904576108f55760018201549060018060a01b036002840154166040519260a0840184811067ffffffffffffffff8211176108e157604052878452602084019260018060a01b03168352604084019162ffffff8260a01c168352606085019160b81c60020b825260808501908152600160ff1b8a146108cd57604051916060830183811067ffffffffffffffff8211176108b9576040908152600184528b8b0360208086019182526401000276a48684019081529251633cf3645360e21b815298516001600160a01b0390811660048b01529751881660248a0152955162ffffff166044890152915160020b60648801529151851660848701529151151560a4860152905160c48501525190911660e48301526101206101048301526101248201869052816101448188885af180156108ae578590610871575b6001600160801b039150169180831061085a5750604051630476982d60e21b8152849291906020816004818a895af1801561084f57610818575b50546001600160a01b0316833b1561040757606490836040519586948593630b0d9c0960e01b8552600485015260018060a01b037f000000000000000000000000000000000000000000000000000000000000000016602485015260448401525af1801561080d576107f8575b6107f482604051906107e66020836119ff565b8152604051918291826118ee565b0390f35b6108038280926119ff565b6101c957816107d3565b6040513d84823e3d90fd5b92506020833d602011610847575b81610833602093836119ff565b8101031261084357849251610766565b5f80fd5b3d9150610826565b6040513d86823e3d90fd5b6313a30a9560e11b85526004839052602452604484fd5b506020813d6020116108a6575b8161088b602093836119ff565b810103126108a2576001600160801b03905161072c565b8480fd5b3d915061087e565b6040513d87823e3d90fd5b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b89526011600452602489fd5b634e487b7160e01b89526041600452602489fd5b63427282e960e11b8552600485fd5b634e487b7160e01b86526021600452602486fd5b5080fd5b63f655705d60e01b8352600483fd5b50346101c95760c03660031901126101c9576109456118c2565b602435906003821015610407576044356001600160a01b0381169290839003610de6576064359162ffffff831693848403610de257608435948560020b91828703610dde5760a4356001600160a01b0381169490859003610dda576109a8611aef565b6001600160a01b0316958615610dcb5785610da65781610d97575b60405163d312998f60e01b815260048101889052976020896024818d7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1988915610d8c578a99610d58575b50878a52600360205260408a205480610c5a57505050600254808803610c4b578860405191610a47836119ce565b88835260208301610a588982611a54565b604084016001815260608501908682526080860188815260a08701918a835260c08801948c865260e08901968888526101008a0198895268010000000000000000811015610c3457806001610ab092016002556119a5565b999099610c1e575189546001600160a01b0319166001600160a01b0391909116178955516003811015610c085762ffffff60049897969593610b6e9593610afa610b4d948d611a30565b518b5460ff60a81b191690151560a81b60ff60a81b16178b55935160018b01805495516001600160b81b03199096166001600160a01b0392909216919091179190941660a01b62ffffff60a01b16178355565b51815460b89190911b62ffffff60b81b1662ffffff60b81b19909116179055565b516002850180546001600160a01b0319166001600160a01b039290921691909117905551600384015551910155600187018088116108cd57928795927fea5f6163486da4478204171fa2b258a84460d946276ece9bd2aba6dfa875d5c1959260a09560408c8b60209e5260038e5220555b610bec6040518096611918565b8a850152604084015260608301526080820152a3604051908152f35b5050634e487b7160e01b8f52602160045260248ffd5b50505060248f634e487b7160e01b815280600452fd5b50505060248f634e487b7160e01b81526041600452fd5b63039d9f8d60e21b8952600489fd5b5f9a919293949596979a198101908111610d44578903610d3557509360a09360209993899793610d057fea5f6163486da4478204171fa2b258a84460d946276ece9bd2aba6dfa875d5c198610cae8b6119a5565b5092610cba8985611a30565b60018401805460b89390931b62ffffff60b81b1660a09290921b62ffffff60a01b166bffffffffffffffffffffffff8c1b909316861765ffffffffffff60a01b191692909217179055565b6002810180546bffffffffffffffffffffffff891b1686179055805460ff60a81b1916600160a81b179055610bdf565b63039d9f8d60e21b8152600490fd5b634e487b7160e01b82526011600452602482fd5b9098506020813d602011610d84575b81610d74602093836119ff565b810103126108435751975f610a19565b3d9150610d67565b6040513d8c823e3d90fd5b63427282e960e11b8952600489fd5b81158015610dc3575b156109c35763427282e960e11b8952600489fd5b508415610daf565b63d92e233d60e01b8952600489fd5b8880fd5b8780fd5b8580fd5b8380fd5b50346101c957806003193601126101c957546040516001600160a01b039091168152602090f35b50346101c957806003193601126101c957600154336001600160a01b0390911603610e8357600180546001600160a01b0319908116909155815433918116821783556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b63118cdaa760e01b815233600452602490fd5b50346101c957806003193601126101c957610eaf611aef565b600180546001600160a01b03199081169091558154908116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50346101c957806003193601126101c9576020600654604051908152f35b503461084357610f28366118d8565b9160027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054146117065760027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055335f52600460205260ff60405f20541615806116f2575b6116e3576002548210156116d457610fa4826119a5565b509160ff835460a81c16156116c55783156116b657610fc8600754600654906119c1565b42106116a75747916005548015158061169e575b611696575b508215611687574260075583546040516370a0823160e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015290969190811690602088602481855afa9788156115fa575f98611652575b5060a01c60ff16600381101561163e578061137a5750506110a39582604051856020820152866040820152836060820152606081526110896080826119ff565b604051809981926348c8949160e01b8352600483016118ee565b0381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af180156112cb576112d6575b6024949596505b86546040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152909660209288928391165afa9485156112cb578395611297575b508403938411610d445780841061127f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b156101c957604051633b129c8d60e11b815260048101839052602481018490528181604481837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561080d5761126a575b505060046040946111ea856009546119c1565b600955600381016111fc8682546119c1565b90550161120a8382546119c1565b90557ffe677f6d63a37b96e99de329da060ac0781a69b2a47fe0159dfd2e56ad46ec0f848051858152846020820152a260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005582519182526020820152f35b6112758280926119ff565b6101c957806111d7565b6313a30a9560e11b8252600484905260245260449150fd5b9094506020813d6020116112c3575b816112b3602093836119ff565b810103126108435751935f61113d565b3d91506112a6565b6040513d85823e3d90fd5b3d8084893e6112e581896119ff565b870196602081890312610de65780519067ffffffffffffffff82116108a257019680601f89011215610de65787519767ffffffffffffffff8911611366576040519161133b601f8b01601f1916602001846119ff565b89835260208a830101116108a257888592602498999a60208094018483015e010152869594506110dd565b634e487b7160e01b85526041600452602485fd5b6001036114fa575060028501548554600187015460405198926001600160a01b03928316921660e08a0167ffffffffffffffff81118b8210176114e65790889392916040528a5260208a0191825260408a01998160a01c62ffffff168b5260608101600160a01b600190037f00000000000000000000000000000000000000000000000000000000000000001681526080820185815260a08301918883528960c08501526040519d8e966304e45aaf60e01b8852600160a01b600190038651166004890152600160a01b6001900390511660248801525162ffffff166044870152600160a01b6001900390511660648601525160848501525160a4840152600160a01b600190039060c001511660c4830152600160a01b6001900316815a9360e492602095f19687156112cb5760249596976114b7575b506110e4565b6114d89060203d6020116114df575b6114d081836119ff565b810190611a21565b505f6114b1565b503d6114c6565b634e487b7160e01b87526041600452602487fd5b9394956040519461150c6060876119ff565b600286526020860190604036833760018060a01b0360028a01541687511561162a57825286516001101561162a57604087015260018801546001600160a01b031690813b156108435760405163b6f9de9560e01b8152600481018590526080602482015296516084880181905260a4880192889290918a91905f5b818110611605575050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660448401524260648401525f93839003918391905af19485156115fa576024956115e557506110e4565b6115f29193505f906119ff565b5f915f6114b1565b6040513d5f823e3d90fd5b82516001600160a01b031687526020968701968c96508d945090920191600101611587565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b9097506020813d60201161167f575b8161166e602093836119ff565b8101031261084357519660ff611049565b3d9150611661565b630ebd4a6160e01b5f5260045ffd5b92505f610fe1565b50808411610fdc565b63aa9a98df60e01b5f5260045ffd5b630a1c302560e21b5f5260045ffd5b63f611219f60e01b5f5260045ffd5b63c97d95cf60e01b5f5260045ffd5b63c60eb33560e01b5f5260045ffd5b505f546001600160a01b0316331415610f8d565b633ee5aeb560e01b5f5260045ffd5b34610843576020366003190112610843576001600160a01b036117366118c2565b165f526004602052602060ff60405f2054166040519015158152f35b346108435760203660031901126108435760043561176e611aef565b6002548110156116d457611781816119a5565b50805460ff60a81b19169055611796816119a5565b50546001600160a01b0316907f859dd3e79827129b9ab4c4a80bf356e65c5cae291aa20e4dc9e7896cec9ab1cb5f80a3005b34610843576117d6366118d8565b6117de611aef565b62015180811161182257816040917fb31e0c1f8ec0894ed7fc973c277f50f38c512683463309dba53cb2214b8b27d4936005558060065582519182526020820152a1005b6310c2dd1d60e21b5f5260045ffd5b34610843575f366003190112610843576020600754604051908152f35b34610843576020366003190112610843576001600160a01b0361186f6118c2565b165f52600360205260405f205480155f14611898575060405f805b825191151582526020820152f35b5f1981019081116118ae5760409060019061188a565b634e487b7160e01b5f52601160045260245ffd5b600435906001600160a01b038216820361084357565b6040906003190112610843576004359060243590565b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b90600382101561163e5752565b610100809160018060a01b03815116845261194860208201516020860190611918565b60408101511515604085015260018060a01b03606082015116606085015262ffffff608082015116608085015260a081015160020b60a085015260018060a01b0360c08201511660c085015260e081015160e08501520151910152565b60025481101561162a5760025f52600560205f20910201905f90565b919082018092116118ae57565b610120810190811067ffffffffffffffff8211176119eb57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176119eb57604052565b90816020910312610843575190565b90600381101561163e57815460ff60a01b191660a09190911b60ff60a01b16179055565b600382101561163e5752565b90604051611a6d816119ce565b6101006004829460ff815460018060a01b0381168652611a95828260a01c1660208801611a54565b60a81c1615156040850152600181015460018060a01b038116606086015262ffffff8160a01c16608086015260b81c60020b60a085015260018060a01b0360028201541660c0850152600381015460e08501520154910152565b5f546001600160a01b03163303611b0257565b63118cdaa760e01b5f523360045260245ffdfea2646970667358221220683b8cb42136634edbf6cc0f63e1a18bd52c44e2396e6a903b118f6ac4561f2b64736f6c634300081a00330000000000000000000000008366a39cc670b4001a1121b8f6a443a643e40951000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f0000000000000000000000006d806411f16dd3a192d19133c26e1e3b104584a100000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000012c
0x60806040526004361015610055575b3615610018575f80fd5b610024346008546119c1565b6008556040513481527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f8852587460203392a2005b5f803560e01c80631bf5518b1461184e57806327e39977146118315780632cd53845146117c8578063645b00bd146117525780636ba42aaa146117155780636f630c3814610f19578063704fbfe514610efb578063715018a614610e9657806379ba509714610e115780638da5cb5b14610dea5780638e6d34561461092b57806391dd73461461053c57806392d3b8861461051e57806394018d1214610500578063a9a18dda146104e2578063aa9239f514610450578063bfe109281461040b578063d1b9e85314610372578063d80528ae14610258578063dc4c90d314610213578063e30c3978146101ea578063eafe7a74146101cc5763f2fde38b1461015d575061000e565b346101c95760203660031901126101c9576101766118c2565b61017e611aef565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b80fd5b50346101c957806003193601126101c9576020600254604051908152f35b50346101c957806003193601126101c9576001546040516001600160a01b039091168152602090f35b50346101c957806003193601126101c9576040517f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409516001600160a01b03168152602090f35b50346101c957806003193601126101c957600854906009549147916002549267ffffffffffffffff841161035e5793929160208360051b0161029d60405191826119ff565b838152600283526020810193837f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace865b83831061033457505050506040519586956080870193875260208701526040860152608060608601525180915260a0840192915b81811061030f575050500390f35b919350916020610120826103266001948851611925565b019401910191849392610301565b6005602060019261034a859d98999b9c9d611a60565b8152019201920191909897969493986102cd565b634e487b7160e01b82526041600452602482fd5b50346101c95760403660031901126101c95761038c6118c2565b60243590811515809203610407576103a2611aef565b6001600160a01b03169081156103f85760207f786c9db967bf0c6b16c7c91adae8a8c554b15a57d373fa2059607300f4616c0091838552600482526040852060ff1981541660ff8316179055604051908152a280f35b63d92e233d60e01b8352600483fd5b8280fd5b50346101c957806003193601126101c9576040517f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f6001600160a01b03168152602090f35b50346101c95760203660031901126101c9576004359080610100604051610476816119ce565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e082015201526002548210156104d3576101206104c46104be846119a5565b50611a60565b6104d16040518092611925565bf35b63c97d95cf60e01b8152600490fd5b50346101c957806003193601126101c9576020600854604051908152f35b50346101c957806003193601126101c9576020600554604051908152f35b50346101c957806003193601126101c9576020600954604051908152f35b50346101c95760203660031901126101c9576004359067ffffffffffffffff82116101c957366023830112156101c957816004013567ffffffffffffffff8111610918578201366024820111610918577f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409516001600160a01b0316903382900361091c5760609084900312610918576044830135926105e2602460648301359201356119a5565b50805460ff8160a01c166003811015610904576108f55760018201549060018060a01b036002840154166040519260a0840184811067ffffffffffffffff8211176108e157604052878452602084019260018060a01b03168352604084019162ffffff8260a01c168352606085019160b81c60020b825260808501908152600160ff1b8a146108cd57604051916060830183811067ffffffffffffffff8211176108b9576040908152600184528b8b0360208086019182526401000276a48684019081529251633cf3645360e21b815298516001600160a01b0390811660048b01529751881660248a0152955162ffffff166044890152915160020b60648801529151851660848701529151151560a4860152905160c48501525190911660e48301526101206101048301526101248201869052816101448188885af180156108ae578590610871575b6001600160801b039150169180831061085a5750604051630476982d60e21b8152849291906020816004818a895af1801561084f57610818575b50546001600160a01b0316833b1561040757606490836040519586948593630b0d9c0960e01b8552600485015260018060a01b037f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f16602485015260448401525af1801561080d576107f8575b6107f482604051906107e66020836119ff565b8152604051918291826118ee565b0390f35b6108038280926119ff565b6101c957816107d3565b6040513d84823e3d90fd5b92506020833d602011610847575b81610833602093836119ff565b8101031261084357849251610766565b5f80fd5b3d9150610826565b6040513d86823e3d90fd5b6313a30a9560e11b85526004839052602452604484fd5b506020813d6020116108a6575b8161088b602093836119ff565b810103126108a2576001600160801b03905161072c565b8480fd5b3d915061087e565b6040513d87823e3d90fd5b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b89526011600452602489fd5b634e487b7160e01b89526041600452602489fd5b63427282e960e11b8552600485fd5b634e487b7160e01b86526021600452602486fd5b5080fd5b63f655705d60e01b8352600483fd5b50346101c95760c03660031901126101c9576109456118c2565b602435906003821015610407576044356001600160a01b0381169290839003610de6576064359162ffffff831693848403610de257608435948560020b91828703610dde5760a4356001600160a01b0381169490859003610dda576109a8611aef565b6001600160a01b0316958615610dcb5785610da65781610d97575b60405163d312998f60e01b815260048101889052976020896024818d7f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f6001600160a01b03165af1988915610d8c578a99610d58575b50878a52600360205260408a205480610c5a57505050600254808803610c4b578860405191610a47836119ce565b88835260208301610a588982611a54565b604084016001815260608501908682526080860188815260a08701918a835260c08801948c865260e08901968888526101008a0198895268010000000000000000811015610c3457806001610ab092016002556119a5565b999099610c1e575189546001600160a01b0319166001600160a01b0391909116178955516003811015610c085762ffffff60049897969593610b6e9593610afa610b4d948d611a30565b518b5460ff60a81b191690151560a81b60ff60a81b16178b55935160018b01805495516001600160b81b03199096166001600160a01b0392909216919091179190941660a01b62ffffff60a01b16178355565b51815460b89190911b62ffffff60b81b1662ffffff60b81b19909116179055565b516002850180546001600160a01b0319166001600160a01b039290921691909117905551600384015551910155600187018088116108cd57928795927fea5f6163486da4478204171fa2b258a84460d946276ece9bd2aba6dfa875d5c1959260a09560408c8b60209e5260038e5220555b610bec6040518096611918565b8a850152604084015260608301526080820152a3604051908152f35b5050634e487b7160e01b8f52602160045260248ffd5b50505060248f634e487b7160e01b815280600452fd5b50505060248f634e487b7160e01b81526041600452fd5b63039d9f8d60e21b8952600489fd5b5f9a919293949596979a198101908111610d44578903610d3557509360a09360209993899793610d057fea5f6163486da4478204171fa2b258a84460d946276ece9bd2aba6dfa875d5c198610cae8b6119a5565b5092610cba8985611a30565b60018401805460b89390931b62ffffff60b81b1660a09290921b62ffffff60a01b166bffffffffffffffffffffffff8c1b909316861765ffffffffffff60a01b191692909217179055565b6002810180546bffffffffffffffffffffffff891b1686179055805460ff60a81b1916600160a81b179055610bdf565b63039d9f8d60e21b8152600490fd5b634e487b7160e01b82526011600452602482fd5b9098506020813d602011610d84575b81610d74602093836119ff565b810103126108435751975f610a19565b3d9150610d67565b6040513d8c823e3d90fd5b63427282e960e11b8952600489fd5b81158015610dc3575b156109c35763427282e960e11b8952600489fd5b508415610daf565b63d92e233d60e01b8952600489fd5b8880fd5b8780fd5b8580fd5b8380fd5b50346101c957806003193601126101c957546040516001600160a01b039091168152602090f35b50346101c957806003193601126101c957600154336001600160a01b0390911603610e8357600180546001600160a01b0319908116909155815433918116821783556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b63118cdaa760e01b815233600452602490fd5b50346101c957806003193601126101c957610eaf611aef565b600180546001600160a01b03199081169091558154908116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50346101c957806003193601126101c9576020600654604051908152f35b503461084357610f28366118d8565b9160027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054146117065760027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055335f52600460205260ff60405f20541615806116f2575b6116e3576002548210156116d457610fa4826119a5565b509160ff835460a81c16156116c55783156116b657610fc8600754600654906119c1565b42106116a75747916005548015158061169e575b611696575b508215611687574260075583546040516370a0823160e01b81526001600160a01b037f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f8116600483015290969190811690602088602481855afa9788156115fa575f98611652575b5060a01c60ff16600381101561163e578061137a5750506110a39582604051856020820152866040820152836060820152606081526110896080826119ff565b604051809981926348c8949160e01b8352600483016118ee565b0381837f0000000000000000000000008366a39cc670b4001a1121b8f6a443a643e409516001600160a01b03165af180156112cb576112d6575b6024949596505b86546040516370a0823160e01b81526001600160a01b037f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f81166004830152909660209288928391165afa9485156112cb578395611297575b508403938411610d445780841061127f57507f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f6001600160a01b03163b156101c957604051633b129c8d60e11b815260048101839052602481018490528181604481837f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f6001600160a01b03165af1801561080d5761126a575b505060046040946111ea856009546119c1565b600955600381016111fc8682546119c1565b90550161120a8382546119c1565b90557ffe677f6d63a37b96e99de329da060ac0781a69b2a47fe0159dfd2e56ad46ec0f848051858152846020820152a260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005582519182526020820152f35b6112758280926119ff565b6101c957806111d7565b6313a30a9560e11b8252600484905260245260449150fd5b9094506020813d6020116112c3575b816112b3602093836119ff565b810103126108435751935f61113d565b3d91506112a6565b6040513d85823e3d90fd5b3d8084893e6112e581896119ff565b870196602081890312610de65780519067ffffffffffffffff82116108a257019680601f89011215610de65787519767ffffffffffffffff8911611366576040519161133b601f8b01601f1916602001846119ff565b89835260208a830101116108a257888592602498999a60208094018483015e010152869594506110dd565b634e487b7160e01b85526041600452602485fd5b6001036114fa575060028501548554600187015460405198926001600160a01b03928316921660e08a0167ffffffffffffffff81118b8210176114e65790889392916040528a5260208a0191825260408a01998160a01c62ffffff168b5260608101600160a01b600190037f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f1681526080820185815260a08301918883528960c08501526040519d8e966304e45aaf60e01b8852600160a01b600190038651166004890152600160a01b6001900390511660248801525162ffffff166044870152600160a01b6001900390511660648601525160848501525160a4840152600160a01b600190039060c001511660c4830152600160a01b6001900316815a9360e492602095f19687156112cb5760249596976114b7575b506110e4565b6114d89060203d6020116114df575b6114d081836119ff565b810190611a21565b505f6114b1565b503d6114c6565b634e487b7160e01b87526041600452602487fd5b9394956040519461150c6060876119ff565b600286526020860190604036833760018060a01b0360028a01541687511561162a57825286516001101561162a57604087015260018801546001600160a01b031690813b156108435760405163b6f9de9560e01b8152600481018590526080602482015296516084880181905260a4880192889290918a91905f5b818110611605575050507f000000000000000000000000806bc975505cf70b838e57dd1765ec640daaa08f6001600160a01b031660448401524260648401525f93839003918391905af19485156115fa576024956115e557506110e4565b6115f29193505f906119ff565b5f915f6114b1565b6040513d5f823e3d90fd5b82516001600160a01b031687526020968701968c96508d945090920191600101611587565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b9097506020813d60201161167f575b8161166e602093836119ff565b8101031261084357519660ff611049565b3d9150611661565b630ebd4a6160e01b5f5260045ffd5b92505f610fe1565b50808411610fdc565b63aa9a98df60e01b5f5260045ffd5b630a1c302560e21b5f5260045ffd5b63f611219f60e01b5f5260045ffd5b63c97d95cf60e01b5f5260045ffd5b63c60eb33560e01b5f5260045ffd5b505f546001600160a01b0316331415610f8d565b633ee5aeb560e01b5f5260045ffd5b34610843576020366003190112610843576001600160a01b036117366118c2565b165f526004602052602060ff60405f2054166040519015158152f35b346108435760203660031901126108435760043561176e611aef565b6002548110156116d457611781816119a5565b50805460ff60a81b19169055611796816119a5565b50546001600160a01b0316907f859dd3e79827129b9ab4c4a80bf356e65c5cae291aa20e4dc9e7896cec9ab1cb5f80a3005b34610843576117d6366118d8565b6117de611aef565b62015180811161182257816040917fb31e0c1f8ec0894ed7fc973c277f50f38c512683463309dba53cb2214b8b27d4936005558060065582519182526020820152a1005b6310c2dd1d60e21b5f5260045ffd5b34610843575f366003190112610843576020600754604051908152f35b34610843576020366003190112610843576001600160a01b0361186f6118c2565b165f52600360205260405f205480155f14611898575060405f805b825191151582526020820152f35b5f1981019081116118ae5760409060019061188a565b634e487b7160e01b5f52601160045260245ffd5b600435906001600160a01b038216820361084357565b6040906003190112610843576004359060243590565b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b90600382101561163e5752565b610100809160018060a01b03815116845261194860208201516020860190611918565b60408101511515604085015260018060a01b03606082015116606085015262ffffff608082015116608085015260a081015160020b60a085015260018060a01b0360c08201511660c085015260e081015160e08501520151910152565b60025481101561162a5760025f52600560205f20910201905f90565b919082018092116118ae57565b610120810190811067ffffffffffffffff8211176119eb57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176119eb57604052565b90816020910312610843575190565b90600381101561163e57815460ff60a01b191660a09190911b60ff60a01b16179055565b600382101561163e5752565b90604051611a6d816119ce565b6101006004829460ff815460018060a01b0381168652611a95828260a01c1660208801611a54565b60a81c1615156040850152600181015460018060a01b038116606086015262ffffff8160a01c16608086015260b81c60020b60a085015260018060a01b0360028201541660c0850152600381015460e08501520154910152565b5f546001600160a01b03163303611b0257565b63118cdaa760e01b5f523360045260245ffdfea2646970667358221220683b8cb42136634edbf6cc0f63e1a18bd52c44e2396e6a903b118f6ac4561f2b64736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xf68977…de03e9 | 38 days agoFri, 10 Jul 2026 13:41:47 UTC | 0xfe677f…ec0f | [0] 0x000000000000…00000003 data: 0x000000000000000000…648e63be |
| 0x21b85b…8ff7d1 | 38 days agoFri, 10 Jul 2026 13:41:41 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…af12b960 |
| 0x7ba552…d79483 | 38 days agoFri, 10 Jul 2026 13:41:39 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x70c254…d3989b | 38 days agoFri, 10 Jul 2026 13:41:36 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…0ca7a8b7 |
| 0x65c797…7ac353 | 38 days agoFri, 10 Jul 2026 13:41:33 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x427bea…79295a | 38 days agoFri, 10 Jul 2026 13:36:15 UTC | 0xfe677f…ec0f | [0] 0x000000000000…00000003 data: 0x000000000000000000…cc9fd9ef |
| 0x54d79d…ec1080 | 38 days agoFri, 10 Jul 2026 13:32:59 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…281589ab |
| 0x79ec63…c2be40 | 38 days agoFri, 10 Jul 2026 13:32:57 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0xc82357…10c036 | 38 days agoFri, 10 Jul 2026 13:32:54 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…3ad7748b |
| 0xd4bc12…cd5955 | 38 days agoFri, 10 Jul 2026 13:32:51 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x6b6924…587b13 | 38 days agoFri, 10 Jul 2026 13:31:10 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…561a7d41 |
| 0x4f2b7e…595916 | 38 days agoFri, 10 Jul 2026 13:31:07 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x28493f…9653ff | 38 days agoFri, 10 Jul 2026 13:31:04 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…05b558d6 |
| 0x13dd88…b31e4d | 38 days agoFri, 10 Jul 2026 13:31:01 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x552d72…373522 | 38 days agoFri, 10 Jul 2026 13:30:47 UTC | 0xfe677f…ec0f | [0] 0x000000000000…00000002 data: 0x000000000000000000…b93371a9 |
| 0x583cdf…deccf1 | 38 days agoFri, 10 Jul 2026 13:24:29 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…9e950528 |
| 0xaa7738…822617 | 38 days agoFri, 10 Jul 2026 13:24:27 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x050b5d…d21c16 | 38 days agoFri, 10 Jul 2026 13:24:24 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…4a15c49f |
| 0x06bd45…6e1931 | 38 days agoFri, 10 Jul 2026 13:24:16 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0xc6a880…395598 | 38 days agoFri, 10 Jul 2026 13:24:09 UTC | 0xfe677f…ec0f | [0] 0x000000000000…00000001 data: 0x000000000000000000…7cb9e0ef |
| 0xa7f34a…fe930d | 38 days agoFri, 10 Jul 2026 13:19:04 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…0f685ede |
| 0xcf4826…ce14b5 | 38 days agoFri, 10 Jul 2026 13:19:01 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0x5ec355…69d842 | 38 days agoFri, 10 Jul 2026 13:18:58 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…9b330309 |
| 0xa1ea22…b76b64 | 38 days agoFri, 10 Jul 2026 13:18:55 UTC | 0x88a596…5874 | [0] 0x000000000000…43e40951 data: 0x000000000000000000…ad5f8000 |
| 0xe031b3…5fd435 | 38 days agoFri, 10 Jul 2026 13:18:10 UTC | 0xfe677f…ec0f | [0] 0x000000000000…00000000 data: 0x000000000000000000…be80cf7d |
| 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 ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xf68977…de03e9 | buyAndDistribute | 6,123,659 | 38 days agoFri, 10 Jul 2026 13:41:47 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00002616 | |
| 0x427bea…79295a | buyAndDistribute | 6,120,341 | 38 days agoFri, 10 Jul 2026 13:36:15 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00003717 | |
| 0x552d72…373522 | buyAndDistribute | 6,117,077 | 38 days agoFri, 10 Jul 2026 13:30:47 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00004131 | |
| !0xcb372a…76439b | buyAndDistribute | 6,116,345 | 38 days agoFri, 10 Jul 2026 13:29:35 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00004461 | |
| 0xc6a880…395598 | buyAndDistribute | 6,113,101 | 38 days agoFri, 10 Jul 2026 13:24:09 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00003610 | |
| 0xe031b3…5fd435 | buyAndDistribute | 6,109,508 | 38 days agoFri, 10 Jul 2026 13:18:10 UTC | 0x3f96…5bfe | IN | RhmiTreasury | $0.000 ETH | 0.00003907 | |
| 0xb1b10e…3890f3 | addRewardAsset | 6,107,254 | 38 days agoFri, 10 Jul 2026 13:14:25 UTC | 0x6d80…84a1 | IN | RhmiTreasury | $0.000 ETH | 0.00002416 | |
| 0xb8aa02…a63e63 | addRewardAsset | 6,107,227 | 38 days agoFri, 10 Jul 2026 13:14:22 UTC | 0x6d80…84a1 | IN | RhmiTreasury | $0.000 ETH | 0.00002476 | |
| 0xcdcafe…88f660 | addRewardAsset | 6,107,201 | 38 days agoFri, 10 Jul 2026 13:14:20 UTC | 0x6d80…84a1 | IN | RhmiTreasury | $0.000 ETH | 0.00002403 | |
| 0x5356df…78b914 | addRewardAsset | 6,107,173 | 38 days agoFri, 10 Jul 2026 13:14:17 UTC | 0x6d80…84a1 | IN | RhmiTreasury | $0.000 ETH | 0.00002840 | |
| 0x396c56…507f61 | setKeeper | 6,106,651 | 38 days agoFri, 10 Jul 2026 13:13:24 UTC | 0x6d80…84a1 | IN | RhmiTreasury | $0.000 ETH | 0.00000613 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||